1: #include "parms.h" 2: #include "structs.h" 3: #include <sys/types.h> 4: #include <sys/stat.h> 5: 6: #ifdef RCSIDENT 7: static char rcsid[] = "$Header: readem.c,v 1.8 87/07/01 13:47:53 paul Exp $"; 8: #endif RCSIDENT 9: 10: 11: /* 12: * this particular collection of junk handles the basic idea 13: * of what to do when you are showing a note. 14: * It displays the note, and then manages to collect enough info 15: * from the terminal to either progress to the next note or 16: * show some of the responses. 17: * 18: * original author : rob kolstad 19: * modified : ray essick may 22, 1981 20: * modified (again): Ray Essick December 1981 21: * modified (more): Ray Essick, February 1982 22: * added MODERATED: Rich $alz, August 1985 23: * added LOCAL and YorN: Rich $alz, August 1985 24: * 25: */ 26: static char YES[] = "YES"; 27: static char NO[] = "NO "; 28: #define YorN(c) ((c) != 0 ? YES : NO) 29: 30: readem (io, readnum, firstdis, resp) 31: struct io_f *io; 32: int *firstdis; 33: { 34: struct note_f note; 35: struct resp_f rsprec; 36: struct io_f io2; 37: FILE * txtfile; 38: int rrecnum, 39: roffset; 40: char tonf[WDLEN + 1]; /* for forwarding */ 41: char ntitle[TITLEN + 20]; /* scratch space */ 42: char nfsave[WDLEN + 1]; /* path name for 's' and 'S' */ 43: int c; /* input char */ 44: char *p, 45: *q; /* scratch pointers */ 46: int replot; /* whether to change what's on the screen */ 47: int toresp; /* init entry as resp */ 48: int forward; /* scroll forward/backward on deleted note */ 49: int toauth, /* send to author */ 50: znum, /* forward as resp to this note */ 51: znote, 52: zresp, /* scratch for asearch */ 53: i, 54: j, 55: wtext; /* send mail with text */ 56: char cmdline[CMDLEN]; /* leggo brand build-a-command */ 57: int retcode; 58: 59: 60: replot = 1; /* first pass always writes to the screen */ 61: retcode = -1; /* init so grabs character */ 62: forward = 1; /* default to scroll forward */ 63: toresp = (resp != 0); /* for entry */ 64: while (1) 65: { 66: x (readnum < 0, "readem: given bad readnum"); 67: if (readnum > io -> descr.d_nnote) 68: readnum = io -> descr.d_nnote; 69: if (readnum == 0 && io -> descr.d_plcy == 0) /* empty notesfile */ 70: return 0; /* so back to the index */ 71: getnrec (io, readnum, ¬e); 72: if (note.n_stat & DELETED) 73: if (forward) 74: goto nextnt; /* forward scroll */ 75: else 76: goto prevnote; /* backward scroll */ 77: if (toresp) 78: { 79: toresp = 0; 80: goto showit; 81: } 82: if (replot) 83: retcode = dspnote (io, ¬e, readnum); /* show the note if we need new one */ 84: replot = 1; /* reset later if don't want replot */ 85: forward = 1; 86: if (retcode < 0) 87: { 88: input: at (0, 1); 89: #ifdef PROMPT 90: printf (PROMPT); /* let him know we're ready */ 91: #endif PROMPT 92: c = gchar (); 93: printf ("\10 \10"); /* Kurt wants this to go away */ 94: } 95: else 96: { 97: c = retcode; 98: retcode = (-1); /* make sure don't loop! */ 99: } 100: switch (c) 101: { 102: case '?': /* if he doesn't know what to type */ 103: case 'h': 104: help (RDMHLP); /* print the pseudo-man page */ 105: goto showit; 106: 107: case 'D': /* delete this note/response */ 108: if (resp) /* check to see if his note */ 109: { 110: if ((rsprec.r_auth[roffset].aid & UIDMASK) != globuid) 111: { 112: at (0, PROMPTMSGX); 113: printf ("Not your response"); 114: replot = 0; 115: continue; 116: } 117: } 118: else 119: { 120: if ((note.n_auth.aid & UIDMASK) != globuid) 121: { 122: at (0, PROMPTMSGX); 123: printf ("Not your note"); 124: replot = 0; 125: continue; 126: } 127: if (readnum == 0) 128: { 129: at (0, PROMPTMSGX); 130: printf ("Use 'Z' to delete policy"); 131: replot = 0; 132: continue; 133: } 134: } 135: 136: at (0, 1); 137: if (askyn ("Delete? (y/n): \b\b") == 'n') 138: goto showit; 139: printf ("\r \r"); 140: 141: locknf (io, DSCRLOCK); /* CRITICAL section */ 142: getnrec (io, readnum, ¬e); /* this should catch most */ 143: getdscr (io, &io -> descr); /* and an up to date descriptor */ 144: if (resp) /* go about deleting it */ 145: { 146: if (resp == note.n_nresp && inorder (&io -> descr.d_lstxmit, &rsprec.r_when[roffset])) 147: { 148: delresp (io, readnum, rrecnum, roffset, 0); 149: note.n_nresp--; /* adjust note response count */ 150: unlocknf (io, DSCRLOCK); /* must free up the lock */ 151: break; /* show next response */ 152: } 153: else 154: { 155: at (0, PROMPTMSGX); 156: printf ("Can't delete: networked, or not last response"); 157: replot = 0; 158: unlocknf (io, DSCRLOCK); /* release lock here too */ 159: continue; 160: } 161: } 162: else /* its a note */ 163: { 164: if (note.n_nresp || inorder (¬e.n_date, &io -> descr.d_lstxmit)) 165: { 166: at (0, PROMPTMSGX); 167: printf ("Can't delete; note has responses or is networked"); 168: replot = 0; 169: unlocknf (io, DSCRLOCK); /* release the lock */ 170: continue; 171: } 172: delnote (io, readnum++, 0); 173: resp = 0; 174: unlocknf (io, DSCRLOCK); /* release the lock */ 175: continue; 176: } 177: 178: case 'E': /* edit an article */ 179: if (resp) /* check to see if his note */ 180: { 181: if ((rsprec.r_auth[roffset].aid & UIDMASK) != globuid) 182: { 183: at (0, PROMPTMSGX); 184: printf ("Not your response"); 185: replot = 0; 186: continue; 187: } 188: } 189: else 190: { 191: if ((note.n_auth.aid & UIDMASK) != globuid) 192: { 193: at (0, PROMPTMSGX); 194: printf ("Not your note"); 195: replot = 0; 196: continue; 197: } 198: if (readnum == 0) 199: { 200: at (0, PROMPTMSGX); 201: printf ("Sorry, E doesn't work for policy notes yet"); 202: replot = 0; 203: continue; 204: } 205: } 206: 207: locknf (io, DSCRLOCK); /* CRITICAL section */ 208: getnrec (io, readnum, ¬e); /* this should catch most */ 209: getdscr (io, &io -> descr); /* and an up to date descriptor */ 210: if (resp) /* go about deleting it */ 211: { 212: if (resp == note.n_nresp && inorder (&io -> descr.d_lstxmit, &rsprec.r_when[roffset])) 213: { 214: delresp (io, readnum, rrecnum, roffset, 0); 215: note.n_nresp--; /* adjust note response count */ 216: unlocknf (io, DSCRLOCK); /* must free up the lock */ 217: sprintf (nfsave, "/tmp/nfe%d", getpid ()); 218: /* build scr file */ 219: x ((txtfile = fopen (nfsave, "w")) == NULL, "readem: scrfile"); 220: x (chmod (nfsave, 0666) < 0, "readem: chmod"); 221: pageout (io, &rsprec.r_addr[roffset], txtfile); 222: /* dump it */ 223: fclose (txtfile); /* also flushes it */ 224: x ((txtfile = fopen (nfsave, "r")) == NULL, "readem: edit reopen"); 225: resp = addresp (io, txtfile, readnum, EDIT); 226: getnrec (io, readnum, ¬e); /* up to date */ 227: /* add it back in ! */ 228: x (unlink (nfsave) < 0, "readem: edit unlink"); 229: break; /* show next response */ 230: } 231: else 232: { 233: at (0, PROMPTMSGX); 234: printf ("Can't edit: networked, or not last response"); 235: replot = 0; 236: unlocknf (io, DSCRLOCK); /* release lock here too */ 237: continue; 238: } 239: } 240: else /* its a note */ 241: { 242: if (note.n_nresp || inorder (¬e.n_date, &io -> descr.d_lstxmit)) 243: { 244: at (0, PROMPTMSGX); 245: printf ("Can't edit; note has responses or is networked"); 246: replot = 0; 247: unlocknf (io, DSCRLOCK); /* release the lock */ 248: continue; 249: } 250: delnote (io, readnum++, 0); 251: resp = 0; 252: unlocknf (io, DSCRLOCK); /* release the lock */ 253: sprintf (nfsave, "/tmp/nfe%d", getpid ()); 254: /* build scr file */ 255: x ((txtfile = fopen (nfsave, "w")) == NULL, "readem: scrfile"); 256: x (chmod (nfsave, 0666) < 0, "readem: chmod"); 257: pageout (io, ¬e.n_addr, txtfile); 258: /* dump it */ 259: fclose (txtfile); /* also flushes it */ 260: x ((txtfile = fopen (nfsave, "r")) == NULL, "readem: edit reopen"); 261: znum = addnote (io, txtfile, "Edit note text:", 262: "Note title: ", ¬e.ntitle, EDIT); 263: x (unlink (nfsave) < 0, "readem: edit unlink"); 264: if (znum > 0) 265: readnum = znum; /* this is the one */ 266: continue; 267: } 268: 269: case 'Z': /* zap notes/responses - directors only */ 270: /* kills any note/response */ 271: getdscr (io, &io -> descr); /* up to date descriptor */ 272: if (allow (io, DRCTOK) == 0) 273: { 274: at (0, PROMPTMSGX); 275: printf ("Not a director"); 276: replot = 0; 277: continue; 278: } 279: 280: at (0, 1); 281: if (askyn ("Delete? (y/n): \b\b") == 'n') 282: goto showit; /* replotter */ 283: printf ("\r \r"); 284: /* 285: * should log the deletion here, so the "meta-director" can 286: * watch for fascist directors preying on the peasants. 287: */ 288: if (readnum == 0) /* deleting policy */ 289: { 290: locknf (io, DSCRLOCK); /* lock us up */ 291: getdscr (io, &io -> descr); /* grab up-to-date */ 292: io -> descr.d_plcy = 0; /* its gone now */ 293: putdscr (io, &io -> descr); /* replace descriptor */ 294: unlocknf (io, DSCRLOCK); 295: return 0; /* back to the index */ 296: } 297: if (resp) /* delete a response */ 298: { 299: delresp (io, readnum, rrecnum, roffset, 1); 300: /* kill it */ 301: note.n_nresp--; /* and response count */ 302: break; /* display next response */ 303: } 304: else 305: delnote (io, readnum++, 1); 306: continue; 307: 308: case 'r': /* replot the current note/response */ 309: case '\f': /* everyone else uses ^L, might as well */ 310: showit: /* come here to refill screen */ 311: if (replot == 0) 312: continue; /* screen appears fine */ 313: if (resp) 314: break; /* show him the response */ 315: else 316: { 317: replot = 1; /* make sure it gets done */ 318: continue; 319: } 320: 321: nextnt: 322: case '\r': /* wants the next note */ 323: case '\n': 324: if (readnum == 0) 325: return 0; /* policy leaves */ 326: if (++readnum > io -> descr.d_nnote) 327: { 328: *firstdis = io -> descr.d_nnote; 329: return 0; 330: } 331: resp = 0; /* reset response index */ 332: continue; 333: 334: case 'm': /* mail a note/response via Unix mail */ 335: toauth = 0; 336: wtext = 0; /* to others and no text */ 337: goto sendmail; 338: case 'M': /* same as 'm' but with text */ 339: toauth = 0; 340: wtext = 1; /* to others with text */ 341: goto sendmail; 342: /* mail to author, possibly with text. */ 343: case 'P': 344: case 'p': 345: #ifdef NO_Pp_FOR_MODERATED 346: /* some people may want this */ 347: if (io -> d_descr.d_stat & MODERATED) 348: { 349: at (0, 10); 350: printf ("Moderated; use 'm' or 'M' command\n"); 351: continue; 352: } 353: #endif NO_Pp_FOR_MODERATED 354: toauth = 1; 355: wtext = c == 'P'; /* to author with text */ 356: sendmail: /* jump to here once set mail parms */ 357: if (resp) 358: { 359: strcpy (ntitle, "Re: "); /* prefix */ 360: strcat (ntitle, note.ntitle); /* append title */ 361: mailit (io, &rsprec.r_addr[roffset], &rsprec.r_auth[roffset], 362: &rsprec.r_when[roffset], ntitle, toauth, wtext); 363: break; 364: } 365: else 366: { 367: strncpy (ntitle, note.ntitle, TITLEN); 368: mailit (io, ¬e.n_addr, ¬e.n_auth, 369: ¬e.n_date, ntitle, toauth, wtext); 370: } 371: goto showit; /* replot current page */ 372: 373: case '!': /* wants to fork a shell */ 374: gshell (); 375: goto showit; 376: 377: case 'q': /* quit this, maybe whole system */ 378: #ifdef K_KEY 379: case 'k': 380: #endif K_KEY 381: return QUITSEQ; 382: 383: case '\04': 384: return QUITFAST; /* leave totally */ 385: 386: case 'z': /* total exit w/update */ 387: return QUITUPD; 388: 389: case 'Q': /* exit system without updating sequencer */ 390: #ifdef K_KEY 391: case 'K': 392: #endif K_KEY 393: return QUITNOSEQ; 394: 395: case 'i': /* go back to note index */ 396: *firstdis = readnum; 397: return 0; 398: 399: case '\b': 400: case '-': /* display previous response */ 401: if (resp <= 0) 402: goto prevnote; /* '-' at base note */ 403: if (--resp) 404: break; /* show the previous response */ 405: continue; /* show him the base note */ 406: 407: prevnote: /* display previous note */ 408: if (readnum == 0) 409: return 0; /* policy leaves */ 410: forward = 0; /* set to scroll backwards on deleted note */ 411: if (--readnum < 1) 412: { 413: readnum = 1; /* zero is policy, so stop at 1 */ 414: forward = 1; /* bounce off bottom end */ 415: continue; /* go hunt for the right note */ 416: } 417: resp = 0; 418: continue; 419: 420: case 'x': 421: case 'X': 422: if (readnum == 0) 423: return 0; /* policy leaves */ 424: retcode = tsearch (io, readnum - 1, c == 'x'); 425: /* look it up */ 426: if (retcode <= 0) 427: replot = 0; 428: else 429: { 430: readnum = retcode; 431: resp = 0; 432: } 433: goto showit; 434: 435: case 'a': 436: case 'A': /* author search from current spot */ 437: if (readnum == 0) 438: return 0; /* not from policy ! */ 439: znote = readnum; 440: zresp = resp; 441: if (zresp == 0) 442: znote--; 443: else 444: zresp++; /* select 'next' */ 445: retcode = asearch (io, &znote, &zresp, (c == 'a')); 446: /* look */ 447: if (retcode < 0) 448: { 449: replot = 0; 450: goto showit; /* didn't want anything */ 451: } 452: if (retcode == 0) 453: { 454: replot = 0; 455: } 456: else 457: { 458: readnum = znote; 459: resp = zresp; /* set returned values */ 460: getnrec (io, readnum, ¬e); /* grab right descriptor */ 461: } 462: goto showit; /* and display them */ 463: 464: case 'd': /* toggle a notes director status */ 465: if (allow (io, DRCTOK) == 0) 466: { /* tell him what's up */ 467: at (0, PROMPTMSGX); 468: printf ( 469: "Anonymous: %s Networked: %s Moderated: %s Local: %s", 470: YorN (io -> descr.d_stat & ANONOK), 471: YorN (io -> descr.d_stat & NETWRKD), 472: YorN (io -> descr.d_stat & MODERATED), 473: YorN (io -> descr.d_stat & LOCAL)); 474: replot = 0; /* leave on screen */ 475: goto showit; 476: } 477: if (resp == 0) /* toggle a note */ 478: { 479: locknf (io, DSCRLOCK); 480: getnrec (io, readnum, ¬e); 481: if (note.n_stat & DIRMES) 482: note.n_stat &= NOT DIRMES; 483: else 484: note.n_stat |= DIRMES; 485: putnrec (io, readnum, ¬e); /* replace */ 486: unlocknf (io, DSCRLOCK); 487: goto showit; 488: } 489: else /* toggle a response */ 490: { 491: locknf (io, DSCRLOCK); /* this locks the resp index too */ 492: getrrec (io, rrecnum, &rsprec); /* grab that block */ 493: if (rsprec.r_stat[roffset] & DIRMES) 494: rsprec.r_stat[roffset] &= NOT DIRMES; 495: else 496: rsprec.r_stat[roffset] |= DIRMES; 497: putrrec (io, rrecnum, &rsprec); /* replace */ 498: unlocknf (io, DSCRLOCK); 499: goto showit; /* and redisplay */ 500: } 501: 502: case 'e': /* allow him to edit his title */ 503: if (readnum == 0) 504: continue; /* don't touch */ 505: if (resp) 506: goto badkey; /* bell and reinput */ 507: else 508: { 509: if (allow (io, DRCTOK) == 0 && 510: (globuid != (note.n_auth.aid & UIDMASK) || 511: /* check uid */ 512: strcmp (System, note.n_id.sys) != 0)) 513: /* other sys */ 514: { 515: at (0, PROMPTMSGX); 516: printf ("Not your note"); 517: replot = 0; 518: continue; 519: } 520: at (0, 1); 521: printf ("New Title: "); 522: if ((i = gline (ntitle, TITLEN - 1)) == 1) 523: /* glom onto a title */ 524: continue; /* empty title, leave alone */ 525: strclean (ntitle); /* zip controls */ 526: locknf (io, DSCRLOCK); 527: getnrec (io, readnum, ¬e); /* well, update it */ 528: strncpy (note.ntitle, ntitle, TITLEN); 529: note.ntitle[TITLEN - 1] = '\0'; /* null for sure */ 530: putnrec (io, readnum, ¬e); /* and replace */ 531: unlocknf (io, DSCRLOCK); 532: goto showit; /* replot the message */ 533: } 534: 535: case 't': /* talk to the author of a note */ 536: if (resp) 537: talkto (&rsprec.r_auth[roffset]); 538: else 539: talkto (¬e.n_auth); 540: goto showit; /* and replot the current message */ 541: 542: case 'W': /* write a response with the text */ 543: case 'w': /* let him write a response */ 544: getdscr (io, &io -> descr); /* get up to date */ 545: 546: if (io -> descr.d_stat & MODERATED) 547: { 548: wtext = c == 'W'; 549: toauth = MODERATED; /* toauth distinguishes m/w */ 550: goto sendmail; 551: } 552: 553: if (allow (io, RESPOK) == 0) 554: { 555: at (0, PROMPTMSGX); 556: printf ("Sorry, you are not allowed to write"); 557: replot = 0; 558: continue; /* back to key processing */ 559: } 560: if (readnum == 0) 561: { 562: at (0, PROMPTMSGX); 563: printf ("No responses allowed to policy note"); 564: replot = 0; 565: continue; /* no responses to policy note */ 566: } 567: 568: if (c == 'w') 569: txtfile = NULL; /* no preface text */ 570: else 571: { 572: sprintf (cmdline, "/tmp/nfx%d", getpid ()); 573: x ((txtfile = fopen (cmdline, "w")) == NULL, "readem: bad scrfile"); 574: x (chmod (cmdline, 0666) < 0, "readem: chmod failed"); 575: if (resp) 576: { 577: preptxt (io, txtfile, &rsprec.r_auth[roffset], 578: &rsprec.r_when[roffset], &rsprec.r_addr[roffset], NULL); 579: } 580: else 581: { 582: preptxt (io, txtfile, ¬e.n_auth, ¬e.n_date, ¬e.n_addr, note.ntitle); 583: } 584: fclose (txtfile); 585: x ((txtfile = fopen (cmdline, "r")) == NULL, "readem: reopen"); 586: } 587: zresp = addresp (io, txtfile, readnum, EDIT);/* put it in */ 588: if (zresp > 0) 589: getnrec (io, readnum, ¬e); /* update descriptor */ 590: 591: if (txtfile != NULL) 592: { 593: fclose (txtfile); /* toss out scratch */ 594: x (unlink (cmdline) < 0, "readem: couldnt unlink scratch"); 595: } 596: if (zresp) 597: resp = zresp; /* show the new */ 598: goto showit; 599: 600: case 'B': /* bitch, bitch, bitch */ 601: if (init (&io2, GRIPES) < 0) /* check gripe file */ 602: { 603: at (0, PROMPTMSGX); 604: printf ("No gripe file"); 605: replot = 0; 606: } 607: else 608: { 609: addnote (&io2, NULL, "Edit Gripe text:", "Gripe Header: ", NULL, EDIT); 610: /* let him put the note in */ 611: finish (&io2); /* close up the gripe file */ 612: } 613: goto showit; 614: 615: case 'C': /* copy to other notesfile with editing */ 616: case 'c': /* copy to other notefile without editing */ 617: if (c == 'C') 618: wtext = 1; 619: else 620: wtext = 0; /* determine which */ 621: while (1) 622: { 623: printf ("\nCopy to: "); 624: if (gline (tonf, NNLEN) == 1) 625: goto showit; /* gave up */ 626: if (init (&io2, tonf) >= 0) 627: break; 628: printf ("Can't find notesfile %s\n", tonf); 629: } 630: sprintf (cmdline, "/tmp/nfx%d", getpid ()); 631: x ((txtfile = fopen (cmdline, "w")) == NULL, "readem:creat scratch failed"); 632: x (chmod (cmdline, 0666) < 0, "readem: chmod failed"); 633: if (resp) 634: { 635: preptxt (io, txtfile, &rsprec.r_auth[roffset], 636: &rsprec.r_when[roffset], &rsprec.r_addr[roffset], NULL); 637: } 638: else 639: { 640: preptxt (io, txtfile, ¬e.n_auth, ¬e.n_date, ¬e.n_addr, note.ntitle); 641: } 642: fclose (txtfile); /* close it */ 643: x ((txtfile = fopen (cmdline, "r")) == NULL, "readem: couldnt reopen"); 644: c = 'n'; /* default to note */ 645: if (allow (&io2, WRITOK) && allow (&io2, READOK) && allow (&io2, RESPOK)) 646: c = askyn ("Copy as Response (y/n)? "); 647: if (c == 'n' && allow (&io2, WRITOK)) 648: if (!resp && wtext == 0) /* use old title */ 649: addnote (&io2, txtfile, NULL, NULL, note.ntitle, wtext); 650: else 651: addnote (&io2, txtfile, "Edit copied text:", "Copy Title: ", NULL, wtext); 652: else 653: if (c == 'y') 654: { 655: if (znum = limindx (&io2)) 656: addresp (&io2, txtfile, znum, wtext); 657: } 658: else 659: { 660: printf ("You haven't permission"); 661: c = 'b'; /* leave message */ 662: } 663: if (strcmp (io -> nf, io2.nf) == 0) /* if was this notefile */ 664: getdscr (io, &io -> descr); /* get new descriptor */ 665: finish (&io2); /* close up that notefile */ 666: if (txtfile != NULL) 667: { 668: fclose (txtfile); /* throw it away */ 669: x (unlink (cmdline) < 0, "readem: couldnt unlink scratch"); 670: } 671: if (c == 'b') 672: { 673: replot = 0; 674: continue; /* leave on screen */ 675: } 676: else 677: goto showit; /* redo the screen */ 678: 679: case 'f': /* Forward (copy) string to other notefile w/o edit */ 680: case 'F': /* Forward (copy) string to other notefile w/edit */ 681: if (resp) 682: { 683: at (0, PROMPTMSGX); 684: printf ("f/F only allowed from base note"); 685: replot = 0; 686: continue; 687: } 688: if (c == 'F') 689: wtext = 1; 690: else 691: wtext = 0; /* determine which */ 692: while (1) 693: { 694: printf ("\nForward to: "); 695: if (gline (tonf, NNLEN) == 1) 696: goto showit; /* gave up */ 697: if (init (&io2, tonf) >= 0) 698: break; 699: printf ("Can't find notesfile %s\n", tonf); 700: } 701: sprintf (cmdline, "/tmp/nfx%d", getpid ()); 702: x ((txtfile = fopen (cmdline, "w")) == NULL, "readem:creat scratch failed"); 703: x (chmod (cmdline, 0666) < 0, "readem: chmod failed"); 704: preptxt (io, txtfile, ¬e.n_auth, ¬e.n_date, ¬e.n_addr, note.ntitle); 705: fclose (txtfile); /* close it */ 706: x ((txtfile = fopen (cmdline, "r")) == NULL, "readem: couldnt reopen"); 707: c = 'n'; 708: if (allow (&io2, WRITOK)) 709: { 710: if (wtext == 0) 711: znum = addnote (&io2, txtfile, NULL, NULL, note.ntitle, NOEDIT); 712: else 713: znum = addnote (&io2, txtfile, "Edit copy text:", "Copy Title:", NULL, EDIT); 714: fclose (txtfile); 715: x ((txtfile = fopen (cmdline, "w")) == NULL, "readem:creat scratch failed"); 716: for (i = 1; i <= note.n_nresp; i++) 717: { 718: if (wtext) /* if editing */ 719: printf ("Forwarding response %d of %d", 720: i, note.n_nresp); /* \n by addresp() below */ 721: if (lrsp (io, readnum, i, &rsprec, &roffset, &rrecnum) == -1) 722: continue; /* hit end of chain */ 723: preptxt (io, txtfile, &rsprec.r_auth[roffset], 724: &rsprec.r_when[roffset], &rsprec.r_addr[roffset], NULL); 725: fclose (txtfile); 726: x ((txtfile = fopen (cmdline, "r")) == NULL, "readem:creat scratch failed"); 727: addresp (&io2, txtfile, znum, wtext); 728: fclose (txtfile); 729: x ((txtfile = fopen (cmdline, "w")) == NULL, "readem:creat scratch failed"); 730: } 731: } 732: else 733: { 734: printf ("You haven't permission"); 735: c = 'b'; /* leave message */ 736: } 737: if (strcmp (io -> nf, io2.nf) == 0) /* if was this notefile */ 738: getdscr (io, &io -> descr); /* get new descriptor */ 739: finish (&io2); /* close up that notefile */ 740: if (txtfile != NULL) 741: { 742: fclose (txtfile); /* throw it away */ 743: x (unlink (cmdline) < 0, "readem: couldnt unlink scratch"); 744: } 745: if (c == 'b') 746: { 747: replot = 0; 748: continue; /* leave on screen */ 749: } 750: else 751: goto showit; /* redo the screen */ 752: 753: 754: case 'N': /* go to an archive */ 755: sprintf (tonf, "%s/%s", ARCHDIR, io -> nf);/* build dest */ 756: goto donest; /* share common code */ 757: 758: 759: case 'n': /* nest notesfiles - a stack */ 760: at (-1, 10); 761: printf (" New notesfile: "); 762: printf (" \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); 763: if (gline (tonf, NNLEN) == 1) 764: goto showit; /* forget it, replot */ 765: donest: /* used by N */ 766: closenf (io); /* save fids */ 767: if ((i = control (tonf, NOSEQ)) == -1) /* do the other */ 768: sleep (1); /* some error there */ 769: if (opennf (io, 0) < 0) 770: { 771: at (0, PROMPTMSGX); 772: printf ("Couldn't reopen notesfile %s", io -> fullname); 773: fflush (stdout); 774: sleep (2); 775: return QUITNOSEQ; /* don't update */ 776: } 777: if (i == QUITFAST) /* he in a hurry? */ 778: return QUITFAST; /* oblige him */ 779: goto showit; /* redisplay page */ 780: 781: case 's': /* place text at end of 'nfsave' */ 782: case 'S': /* place the whole string */ 783: at (-1, 1); 784: printf ("File name: \b\b\b\b\b\b\b\b\b\b\b\b"); 785: znum = gline (nfsave, WDLEN); 786: at (-1, 1); 787: printf ("%*s", znum + 11, " "); /* overwrite */ 788: if (znum == 1) /* no file */ 789: { 790: at (0, PROMPTMSGX); /* tell him didn't do */ 791: printf ("No Text Saved"); 792: replot = 0; 793: continue; 794: } 795: p = q = nfsave; /* kill leading spaces */ 796: while (*p == ' ') 797: p++; /* skip them */ 798: for (; *p; p++, q++) 799: *q = *p; /* move down */ 800: *q = '\0'; /* terminate */ 801: for (--q;; q--) /* strip trailing */ 802: { 803: if (*q != ' ') 804: break; 805: *q = '\0'; /* strip trailing */ 806: } 807: if (nfsave[0] == '|') /* pipe */ 808: { 809: p = "Pipe"; 810: } 811: else 812: { 813: struct stat sb; /* hold stat result */ 814: 815: if (stat (nfsave, &sb) == 0) /* find it? */ 816: p = "Appended"; 817: else 818: p = "New File"; /* prolly new */ 819: } 820: if (c == 's') /* save single page */ 821: { 822: if (resp) 823: { 824: znum = savtxt (io, nfsave, &rsprec.r_auth[roffset], 825: &rsprec.r_when[roffset], &rsprec.r_addr[roffset], (char *) NULL); 826: } 827: else 828: { 829: znum = savtxt (io, nfsave, ¬e.n_auth, ¬e.n_date, ¬e.n_addr, note.ntitle); 830: } 831: } 832: else /* save whole string */ 833: { 834: znum = savtxt (io, nfsave, ¬e.n_auth, ¬e.n_date, ¬e.n_addr, note.ntitle); 835: 836: for (i = 1; i <= note.n_nresp; i++) 837: { 838: if (lrsp (io, readnum, i, &rsprec, &roffset, &rrecnum) == -1) 839: continue; /* hit end of chain */ 840: znum += savtxt (io, nfsave, &rsprec.r_auth[roffset], 841: &rsprec.r_when[roffset], &rsprec.r_addr[roffset], (char *) NULL); 842: } 843: } 844: at (0, PROMPTMSGX); 845: printf ("Saved %d lines in \"%s\" [%s]", znum, nfsave, p); 846: replot = 0; /* dont erase it */ 847: continue; /* don't replot */ 848: 849: case 'j': /* goto next note/resp */ 850: case 'l': 851: if (readnum == 0) 852: return 0; /* policy returns */ 853: if (resp == note.n_nresp) 854: goto findnext; /* at end of the responses for this note */ 855: if ((resp = nxtresp (io, readnum, resp, &io -> stime)) > 0) 856: break; /* go show it */ 857: else 858: goto findnext; /* try next note ! */ 859: 860: findnext: 861: case 'J': /* next unread note */ 862: case 'L': /* like J */ 863: if (readnum == 0) 864: return 0; /* policy note returns */ 865: resp = 0; 866: if ((readnum = nxtnote (io, readnum, &io -> stime)) > 0) 867: continue; 868: else 869: { 870: if (c == 'L' || c == 'l') /* leave */ 871: return QUITSEQ; /* and update... */ 872: *firstdis = io -> descr.d_nnote; /* last index page */ 873: return 0; /* and show it */ 874: } 875: 876: case '+': 877: case ';': 878: case ' ': 879: if (readnum == 0) 880: return 0; /* such is the fate of policy notes */ 881: resp++; 882: if (resp > note.n_nresp) 883: goto nextnt; 884: break; 885: 886: case '*': /* skip to last note */ 887: resp = note.n_nresp; 888: break; /* and show it */ 889: 890: case '=': /* go back to the base note */ 891: resp = 0; /* reset index into responses */ 892: continue; 893: 894: case '1': /* skip n responses */ 895: case '2': 896: case '3': 897: case '4': 898: case '5': 899: case '6': 900: case '7': 901: case '8': 902: case '9': 903: if (note.n_nresp < 1) 904: goto nextnt; 905: resp += c - '0'; /* let him skip all over responses */ 906: if (resp > note.n_nresp) 907: resp = note.n_nresp; /* dont go past end */ 908: break; 909: 910: 911: default: /* something we haven't covered */ 912: badkey: /* so can jump down here */ 913: printf ("\07"); 914: replot = 0; /* leave whatever is up on the screen */ 915: continue; 916: } 917: if (resp > note.n_nresp) 918: resp = note.n_nresp; /* set to the end */ 919: if (resp == 0) 920: continue; /* wound up at base note */ 921: if (lrsp (io, readnum, resp, &rsprec, &roffset, &rrecnum) == -1) 922: { 923: getnrec (io, readnum, ¬e); /* get a new descriptor */ 924: goto showit; /* dropped something */ 925: } 926: retcode = dspresp (io, ¬e, &rsprec, roffset, resp, readnum); 927: /* show the darn thing */ 928: replot = 0; /* leave the response on the screen */ 929: } 930: }