|
|
1.1 ! root 1: /* $Header: ng.c,v 4.3.1.6 85/09/10 11:03:42 lwall Exp $ ! 2: * ! 3: * $Log: ng.c,v $ ! 4: * Revision 4.3.1.6 85/09/10 11:03:42 lwall ! 5: * Improved %m in in_char(). ! 6: * ! 7: * Revision 4.3.1.5 85/09/05 12:34:37 lwall ! 8: * Catchup command could make unread article count too big. ! 9: * ! 10: * Revision 4.3.1.4 85/07/23 18:19:46 lwall ! 11: * Added MAILCALL environment variable. ! 12: * ! 13: * Revision 4.3.1.3 85/05/16 16:48:09 lwall ! 14: * Fixed unsubsubscribe. ! 15: * ! 16: * Revision 4.3.1.2 85/05/13 09:29:28 lwall ! 17: * Added CUSTOMLINES option. ! 18: * ! 19: * Revision 4.3.1.1 85/05/10 11:36:00 lwall ! 20: * Branch for patches. ! 21: * ! 22: * Revision 4.3 85/05/01 11:43:43 lwall ! 23: * Baseline for release with 4.3bsd. ! 24: * ! 25: */ ! 26: ! 27: #include "EXTERN.h" ! 28: #include "common.h" ! 29: #include "rn.h" ! 30: #include "term.h" ! 31: #include "final.h" ! 32: #include "util.h" ! 33: #include "artsrch.h" ! 34: #include "cheat.h" ! 35: #include "help.h" ! 36: #include "kfile.h" ! 37: #include "rcstuff.h" ! 38: #include "head.h" ! 39: #include "artstate.h" ! 40: #include "bits.h" ! 41: #include "art.h" ! 42: #include "artio.h" ! 43: #include "ngstuff.h" ! 44: #include "intrp.h" ! 45: #include "respond.h" ! 46: #include "ngdata.h" ! 47: #include "backpage.h" ! 48: #include "rcln.h" ! 49: #include "last.h" ! 50: #include "search.h" ! 51: #include "INTERN.h" ! 52: #include "ng.h" ! 53: #include "artstate.h" /* somebody has to do it */ ! 54: ! 55: /* art_switch() return values */ ! 56: ! 57: #define AS_NORM 0 ! 58: #define AS_INP 1 ! 59: #define AS_ASK 2 ! 60: #define AS_CLEAN 3 ! 61: ! 62: ART_NUM recent_art = 0; /* previous article # for '-' command */ ! 63: ART_NUM curr_art = 0; /* current article # */ ! 64: int exit_code = NG_NORM; ! 65: ! 66: void ! 67: ng_init() ! 68: { ! 69: ! 70: #ifdef KILLFILES ! 71: open_kfile(KF_GLOBAL); ! 72: #endif ! 73: #ifdef CUSTOMLINES ! 74: init_compex(&hide_compex); ! 75: init_compex(&page_compex); ! 76: #endif ! 77: } ! 78: ! 79: /* do newsgroup on line ng with name ngname */ ! 80: ! 81: /* assumes that we are chdir'ed to SPOOL, and assures that that is ! 82: * still true upon return, but chdirs to SPOOL/ngname in between ! 83: * ! 84: * If you can understand this routine, you understand most of the program. ! 85: * The basic structure is: ! 86: * for each desired article ! 87: * for each desired page ! 88: * for each line on page ! 89: * if we need another line from file ! 90: * get it ! 91: * if it's a header line ! 92: * do special things ! 93: * for each column on page ! 94: * put out a character ! 95: * end loop ! 96: * end loop ! 97: * end loop ! 98: * end loop ! 99: * ! 100: * (Actually, the pager is in another routine.) ! 101: * ! 102: * The chief problem is deciding what is meant by "desired". Most of ! 103: * the messiness of this routine is due to the fact that people want ! 104: * to do unstructured things all the time. I have used a few judicious ! 105: * goto's where I thought it improved readability. The rest of the messiness ! 106: * arises from trying to be both space and time efficient. Have fun. ! 107: */ ! 108: ! 109: int ! 110: do_newsgroup(start_command) ! 111: char *start_command; /* command to fake up first */ ! 112: { ! 113: char oldmode = mode; ! 114: register long i; /* scratch */ ! 115: int skipstate; /* how many unavailable articles */ ! 116: /* have we skipped already? */ ! 117: ! 118: char *whatnext = "%sWhat next? [%s]"; ! 119: ! 120: #ifdef ARTSEARCH ! 121: srchahead = (scanon && ((ART_NUM)toread[ng]) >= scanon ? -1 : 0); ! 122: /* did they say -S? */ ! 123: #endif ! 124: ! 125: mode = 'a'; ! 126: recent_art = curr_art = 0; ! 127: exit_code = NG_NORM; ! 128: if (eaccess(ngdir,5)) { /* directory read protected? */ ! 129: if (eaccess(ngdir,0)) { ! 130: #ifdef VERBOSE ! 131: IF(verbose) ! 132: printf("\nNewsgroup %s does not have a spool directory!\n", ! 133: ngname) FLUSH; ! 134: ELSE ! 135: #endif ! 136: #ifdef TERSE ! 137: printf("\nNo spool for %s!\n",ngname) FLUSH; ! 138: #endif ! 139: #ifdef CATCHUP ! 140: catch_up(ng); ! 141: #endif ! 142: toread[ng] = TR_NONE; ! 143: } ! 144: else { ! 145: #ifdef VERBOSE ! 146: IF(verbose) ! 147: printf("\nNewsgroup %s is not currently accessible.\n", ! 148: ngname) FLUSH; ! 149: ELSE ! 150: #endif ! 151: #ifdef TERSE ! 152: printf("\n%s not readable.\n",ngname) FLUSH; ! 153: #endif ! 154: toread[ng] = TR_NONE; /* make this newsgroup invisible */ ! 155: /* (temporarily) */ ! 156: } ! 157: mode = oldmode; ! 158: return -1; ! 159: } ! 160: ! 161: /* chdir to newsgroup subdirectory */ ! 162: ! 163: if (chdir(ngdir)) { ! 164: printf(nocd,ngdir) FLUSH; ! 165: mode = oldmode; ! 166: return -1; ! 167: } ! 168: ! 169: #ifdef CACHESUBJ ! 170: subj_list = Null(char **); /* no subject list till needed */ ! 171: #endif ! 172: ! 173: /* initialize control bitmap */ ! 174: ! 175: if (initctl()) { ! 176: mode = oldmode; ! 177: return -1; ! 178: } ! 179: ! 180: /* FROM HERE ON, RETURN THRU CLEANUP OR WE ARE SCREWED */ ! 181: ! 182: in_ng = TRUE; /* tell the world we are here */ ! 183: forcelast = TRUE; /* if 0 unread, do not bomb out */ ! 184: art=firstart; ! 185: ! 186: /* remember what newsgroup we were in for sake of posterity */ ! 187: ! 188: writelast(); ! 189: ! 190: /* see if there are any special searches to do */ ! 191: ! 192: #ifdef KILLFILES ! 193: open_kfile(KF_LOCAL); ! 194: #ifdef VERBOSE ! 195: IF(verbose) ! 196: kill_unwanted(firstart,"Looking for articles to kill...\n\n",TRUE); ! 197: ELSE ! 198: #endif ! 199: #ifdef TERSE ! 200: kill_unwanted(firstart,"Killing...\n\n",TRUE); ! 201: #endif ! 202: #endif ! 203: ! 204: /* do they want a special top line? */ ! 205: ! 206: firstline = getval("FIRSTLINE",Nullch); ! 207: ! 208: /* custom line suppression, custom page ending */ ! 209: ! 210: #ifdef CUSTOMLINES ! 211: if (hideline = getval("HIDELINE",Nullch)) ! 212: compile(&hide_compex,hideline,TRUE,TRUE); ! 213: if (pagestop = getval("PAGESTOP",Nullch)) ! 214: compile(&page_compex,pagestop,TRUE,TRUE); ! 215: #endif ! 216: ! 217: /* now read each unread article */ ! 218: ! 219: rc_changed = doing_ng = TRUE; /* enter the twilight zone */ ! 220: skipstate = 0; /* we have not skipped anything (yet) */ ! 221: checkcount = 0; /* do not checkpoint for a while */ ! 222: do_fseek = FALSE; /* start 1st article at top */ ! 223: if (art > lastart) ! 224: art=firstart; /* init the for loop below */ ! 225: for (; art<=lastart+1; ) { /* for each article */ ! 226: ! 227: /* do we need to "grow" the newsgroup? */ ! 228: ! 229: if (art > lastart || forcegrow) ! 230: grow_ctl(); ! 231: check_first(art); /* make sure firstart is still 1st */ ! 232: if (start_command) { /* fake up an initial command? */ ! 233: prompt = whatnext; ! 234: strcpy(buf,start_command); ! 235: free(start_command); ! 236: start_command = Nullch; ! 237: art = lastart+1; ! 238: goto article_level; ! 239: } ! 240: if (art>lastart) { /* are we off the end still? */ ! 241: ART_NUM ucount = 0; /* count of unread articles left */ ! 242: ! 243: for (i=firstart; i<=lastart; i++) ! 244: if (!(ctl_read(i))) ! 245: ucount++; /* count the unread articles */ ! 246: #ifdef DEBUGGING ! 247: /*NOSTRICT*/ ! 248: if (debug && ((ART_NUM)toread[ng]) != ucount) ! 249: printf("(toread=%ld sb %ld)",(long)toread[ng],(long)ucount) ! 250: FLUSH; ! 251: #endif ! 252: /*NOSTRICT*/ ! 253: toread[ng] = (ART_UNREAD)ucount; /* this is perhaps pointless */ ! 254: art = lastart + 1; /* keep bitmap references sane */ ! 255: if (art != curr_art) { ! 256: recent_art = curr_art; ! 257: /* remember last article # (for '-') */ ! 258: curr_art = art; /* remember this article # */ ! 259: } ! 260: if (erase_screen) ! 261: clear(); /* clear the screen */ ! 262: else ! 263: fputs("\n\n",stdout) FLUSH; ! 264: #ifdef VERBOSE ! 265: IF(verbose) ! 266: printf("End of newsgroup %s.",ngname); ! 267: /* print pseudo-article */ ! 268: ELSE ! 269: #endif ! 270: #ifdef TERSE ! 271: printf("End of %s",ngname); ! 272: #endif ! 273: if (ucount) { ! 274: printf(" (%ld article%s still unread)", ! 275: (long)ucount,ucount==1?nullstr:"s"); ! 276: } ! 277: else { ! 278: if (!forcelast) ! 279: goto cleanup; /* actually exit newsgroup */ ! 280: } ! 281: prompt = whatnext; ! 282: #ifdef ARTSEARCH ! 283: srchahead = 0; /* no more subject search mode */ ! 284: #endif ! 285: fputs("\n\n",stdout) FLUSH; ! 286: skipstate = 0; /* back to none skipped */ ! 287: } ! 288: else if (!reread && was_read(art)) { ! 289: /* has this article been read? */ ! 290: art++; /* then skip it */ ! 291: continue; ! 292: } ! 293: else if ! 294: (!reread && !was_read(art) ! 295: && artopen(art) == Nullfp) { /* never read it, & cannot find it? */ ! 296: if (errno != ENOENT) { /* has it not been deleted? */ ! 297: #ifdef VERBOSE ! 298: IF(verbose) ! 299: printf("\n(Article %ld exists but is unreadable.)\n", ! 300: (long)art) FLUSH; ! 301: ELSE ! 302: #endif ! 303: #ifdef TERSE ! 304: printf("\n(%ld unreadable.)\n",(long)art) FLUSH; ! 305: #endif ! 306: skipstate = 0; ! 307: sleep(2); ! 308: } ! 309: switch(skipstate++) { ! 310: case 0: ! 311: clear(); ! 312: #ifdef VERBOSE ! 313: IF(verbose) ! 314: fputs("Skipping unavailable article",stdout); ! 315: ELSE ! 316: #endif ! 317: #ifdef TERSE ! 318: fputs("Skipping",stdout); ! 319: #endif ! 320: for (i = just_a_sec/3; i; --i) ! 321: putchar(PC); ! 322: fflush(stdout); ! 323: sleep(1); ! 324: break; ! 325: case 1: ! 326: fputs("..",stdout); ! 327: fflush(stdout); ! 328: break; ! 329: default: ! 330: putchar('.'); ! 331: fflush(stdout); ! 332: #define READDIR ! 333: #ifdef READDIR ! 334: { /* fast skip patch */ ! 335: ART_NUM newart; ! 336: ! 337: if (! (newart=getngmin(".",art))) ! 338: newart = lastart+1; ! 339: for (i=art; i<newart; i++) ! 340: oneless(i); ! 341: art = newart - 1; ! 342: } ! 343: #endif ! 344: break; ! 345: } ! 346: oneless(art); /* mark deleted as read */ ! 347: art++; /* try next article */ ! 348: continue; ! 349: } ! 350: else { /* we have a real live article */ ! 351: skipstate = 0; /* back to none skipped */ ! 352: if (art != curr_art) { ! 353: recent_art = curr_art; ! 354: /* remember last article # (for '-') */ ! 355: curr_art = art; /* remember this article # */ ! 356: } ! 357: if (!do_fseek) { /* starting at top of article? */ ! 358: artline = 0; /* start at the beginning */ ! 359: topline = -1; /* and remember top line of screen */ ! 360: /* (line # within article file) */ ! 361: } ! 362: clear(); /* clear screen */ ! 363: artopen(art); /* make sure article file is open */ ! 364: if (artfp == Nullfp) { /* could not find article? */ ! 365: printf("Article %ld of %s is not available.\n\n", ! 366: (long)art,ngname) FLUSH; ! 367: prompt = whatnext; ! 368: #ifdef ARTSEARCH ! 369: srchahead = 0; ! 370: #endif ! 371: } ! 372: else { /* found it, so print it */ ! 373: switch (do_article()) { ! 374: case DA_CLEAN: /* quit newsgroup */ ! 375: goto cleanup; ! 376: case DA_TOEND: /* do not mark as read */ ! 377: goto reask_article; ! 378: case DA_RAISE: /* reparse command at end of art */ ! 379: goto article_level; ! 380: case DA_NORM: /* normal end of article */ ! 381: break; ! 382: } ! 383: } ! 384: mark_as_read(art); /* mark current article as read */ ! 385: reread = FALSE; ! 386: do_hiding = TRUE; ! 387: #ifdef ROTATION ! 388: rotate = FALSE; ! 389: #endif ! 390: } ! 391: ! 392: /* if these gotos bother you, think of this as a little state machine */ ! 393: ! 394: reask_article: ! 395: #ifdef MAILCALL ! 396: setmail(); ! 397: #endif ! 398: setdfltcmd(); ! 399: #ifdef CLEAREOL ! 400: if (erase_screen && can_home_clear) /* PWP was here */ ! 401: clear_rest(); ! 402: #endif CLEAREOL ! 403: unflush_output(); /* disable any ^O in effect */ ! 404: standout(); /* enter standout mode */ ! 405: printf(prompt,mailcall,dfltcmd);/* print prompt, whatever it is */ ! 406: un_standout(); /* leave standout mode */ ! 407: putchar(' '); ! 408: fflush(stdout); ! 409: reinp_article: ! 410: eat_typeahead(); ! 411: #ifdef PENDING ! 412: look_ahead(); /* see what we can do in advance */ ! 413: if (!input_pending()) ! 414: collect_subjects(); /* loads subject cache until */ ! 415: /* input is pending */ ! 416: #endif ! 417: getcmd(buf); ! 418: if (errno || *buf == '\f') { ! 419: if (LINES < 100 && !int_count) ! 420: *buf = '\f'; /* on CONT fake up refresh */ ! 421: else { ! 422: putchar('\n') FLUSH; /* but only on a crt */ ! 423: goto reask_article; ! 424: } ! 425: } ! 426: article_level: ! 427: ! 428: /* parse and process article level command */ ! 429: ! 430: switch (art_switch()) { ! 431: case AS_INP: /* multichar command rubbed out */ ! 432: goto reinp_article; ! 433: case AS_ASK: /* reprompt "End of article..." */ ! 434: goto reask_article; ! 435: case AS_CLEAN: /* exit newsgroup */ ! 436: goto cleanup; ! 437: case AS_NORM: /* display article art */ ! 438: break; ! 439: } ! 440: } /* end of article selection loop */ ! 441: ! 442: /* shut down newsgroup */ ! 443: ! 444: cleanup: ! 445: #ifdef KILLFILES ! 446: kill_unwanted(firstart,"\nCleaning up...\n\n",FALSE); ! 447: /* do cleanup from KILL file, if any */ ! 448: #endif ! 449: in_ng = FALSE; /* leave newsgroup state */ ! 450: if (artfp != Nullfp) { /* article still open? */ ! 451: fclose(artfp); /* close it */ ! 452: artfp = Nullfp; /* and tell the world */ ! 453: openart = 0; ! 454: } ! 455: putchar('\n') FLUSH; ! 456: yankback(); /* do a Y command */ ! 457: restore_ng(); /* reconstitute .newsrc line */ ! 458: doing_ng = FALSE; /* tell sig_catcher to cool it */ ! 459: free(ctlarea); /* return the control area */ ! 460: #ifdef CACHESUBJ ! 461: if (subj_list) { ! 462: for (i=OFFSET(lastart); i>=0; --i) ! 463: if (subj_list[i]) ! 464: free(subj_list[i]); ! 465: #ifndef lint ! 466: free((char*)subj_list); ! 467: #endif lint ! 468: } ! 469: #endif ! 470: write_rc(); /* and update .newsrc */ ! 471: rc_changed = FALSE; /* tell sig_catcher it is ok */ ! 472: if (chdir(spool)) { ! 473: printf(nocd,spool) FLUSH; ! 474: sig_catcher(0); ! 475: } ! 476: #ifdef KILLFILES ! 477: if (localkfp) { ! 478: fclose(localkfp); ! 479: localkfp = Nullfp; ! 480: } ! 481: #endif ! 482: mode = oldmode; ! 483: return exit_code; ! 484: } /* Whew! */ ! 485: ! 486: /* decide what to do at the end of an article */ ! 487: ! 488: int ! 489: art_switch() ! 490: { ! 491: register ART_NUM i; ! 492: ! 493: setdef(buf,dfltcmd); ! 494: #ifdef VERIFY ! 495: printcmd(); ! 496: #endif ! 497: switch (*buf) { ! 498: case 'p': /* find previous unread article */ ! 499: do { ! 500: if (art <= firstart) ! 501: break; ! 502: art--; ! 503: } while (was_read(art) || artopen(art) == Nullfp); ! 504: #ifdef ARTSEARCH ! 505: srchahead = 0; ! 506: #endif ! 507: return AS_NORM; ! 508: case 'P': /* goto previous article */ ! 509: if (art > absfirst) ! 510: art--; ! 511: else { ! 512: #ifdef VERBOSE ! 513: IF(verbose) ! 514: fputs("\n\ ! 515: There are no articles prior to this one.\n\ ! 516: ",stdout) FLUSH; ! 517: ELSE ! 518: #endif ! 519: #ifdef TERSE ! 520: fputs("\nNo previous articles\n",stdout) FLUSH; ! 521: #endif ! 522: return AS_ASK; ! 523: } ! 524: reread = TRUE; ! 525: #ifdef ARTSEARCH ! 526: srchahead = 0; ! 527: #endif ! 528: return AS_NORM; ! 529: case '-': ! 530: if (recent_art) { ! 531: art = recent_art; ! 532: reread = TRUE; ! 533: #ifdef ARTSEARCH ! 534: srchahead = -(srchahead != 0); ! 535: #endif ! 536: return AS_NORM; ! 537: } ! 538: else { ! 539: exit_code = NG_MINUS; ! 540: return AS_CLEAN; ! 541: } ! 542: case 'n': /* find next unread article? */ ! 543: if (art > lastart) { ! 544: if (toread[ng]) ! 545: art = firstart; ! 546: else ! 547: return AS_CLEAN; ! 548: } ! 549: #ifdef ARTSEARCH ! 550: else if (scanon && srchahead) { ! 551: *buf = Ctl('n'); ! 552: goto normal_search; ! 553: } ! 554: #endif ! 555: else ! 556: art++; ! 557: #ifdef ARTSEARCH ! 558: srchahead = 0; ! 559: #endif ! 560: return AS_NORM; ! 561: case 'N': /* goto next article */ ! 562: if (art > lastart) ! 563: art = absfirst; ! 564: else ! 565: art++; ! 566: if (art <= lastart) ! 567: reread = TRUE; ! 568: #ifdef ARTSEARCH ! 569: srchahead = 0; ! 570: #endif ! 571: return AS_NORM; ! 572: case '$': ! 573: art = lastart+1; ! 574: forcelast = TRUE; ! 575: #ifdef ARTSEARCH ! 576: srchahead = 0; ! 577: #endif ! 578: return AS_NORM; ! 579: case '1': case '2': case '3': /* goto specified article */ ! 580: case '4': case '5': case '6': /* or do something with a range */ ! 581: case '7': case '8': case '9': case '.': ! 582: forcelast = TRUE; ! 583: switch (numnum()) { ! 584: case NN_INP: ! 585: return AS_INP; ! 586: case NN_ASK: ! 587: return AS_ASK; ! 588: case NN_REREAD: ! 589: reread = TRUE; ! 590: #ifdef ARTSEARCH ! 591: if (srchahead) ! 592: srchahead = -1; ! 593: #endif ! 594: break; ! 595: case NN_NORM: ! 596: if (was_read(art)) { ! 597: art = firstart; ! 598: pad(just_a_sec/3); ! 599: } ! 600: else ! 601: return AS_ASK; ! 602: break; ! 603: } ! 604: return AS_NORM; ! 605: case Ctl('k'): ! 606: edit_kfile(); ! 607: return AS_ASK; ! 608: case 'K': ! 609: case 'k': ! 610: case Ctl('n'): case Ctl('p'): ! 611: case '/': case '?': ! 612: #ifdef ARTSEARCH ! 613: normal_search: ! 614: { /* search for article by pattern */ ! 615: char cmd = *buf; ! 616: ! 617: reread = TRUE; /* assume this */ ! 618: switch (art_search(buf, (sizeof buf), TRUE)) { ! 619: case SRCH_ERROR: ! 620: return AS_ASK; ! 621: case SRCH_ABORT: ! 622: return AS_INP; ! 623: case SRCH_INTR: ! 624: #ifdef VERBOSE ! 625: IF(verbose) ! 626: printf("\n(Interrupted at article %ld)\n",(long)art) FLUSH; ! 627: ELSE ! 628: #endif ! 629: #ifdef TERSE ! 630: printf("\n(Intr at %ld)\n",(long)art) FLUSH; ! 631: #endif ! 632: art = curr_art; ! 633: /* restore to current article */ ! 634: return AS_ASK; ! 635: case SRCH_DONE: ! 636: fputs("done\n",stdout) FLUSH; ! 637: pad(just_a_sec/3); /* 1/3 second */ ! 638: if (srchahead) ! 639: art = firstart; ! 640: else ! 641: art = curr_art; ! 642: reread = FALSE; ! 643: return AS_NORM; ! 644: case SRCH_SUBJDONE: ! 645: #ifdef UNDEF ! 646: fputs("\n\n\n\nSubject not found.\n",stdout) FLUSH; ! 647: pad(just_a_sec/3); /* 1/3 second */ ! 648: #endif ! 649: art = firstart; ! 650: reread = FALSE; ! 651: return AS_NORM; ! 652: case SRCH_NOTFOUND: ! 653: fputs("\n\n\n\nNot found.\n",stdout) FLUSH; ! 654: art = curr_art; /* restore to current article */ ! 655: return AS_ASK; ! 656: case SRCH_FOUND: ! 657: if (cmd == Ctl('n') || cmd == Ctl('p')) ! 658: oldsubject = TRUE; ! 659: break; ! 660: } ! 661: return AS_NORM; ! 662: } ! 663: #else ! 664: buf[1] = '\0'; ! 665: notincl(buf); ! 666: return AS_ASK; ! 667: #endif ! 668: case 'u': /* unsubscribe from this newsgroup? */ ! 669: rcchar[ng] = NEGCHAR; ! 670: return AS_CLEAN; ! 671: case 'M': ! 672: #ifdef DELAYMARK ! 673: if (art <= lastart) { ! 674: delay_unmark(art); ! 675: printf("\nArticle %ld will return.\n",(long)art) FLUSH; ! 676: } ! 677: #else ! 678: notincl("M"); ! 679: #endif ! 680: return AS_ASK; ! 681: case 'm': ! 682: if (art <= lastart) { ! 683: unmark_as_read(art); ! 684: printf("\nArticle %ld marked as still unread.\n",(long)art) FLUSH; ! 685: } ! 686: return AS_ASK; ! 687: case 'c': /* catch up */ ! 688: reask_catchup: ! 689: #ifdef VERBOSE ! 690: IF(verbose) ! 691: in_char("\nDo you really want to mark everything as read? [yn] ", ! 692: 'C'); ! 693: ELSE ! 694: #endif ! 695: #ifdef TERSE ! 696: in_char("\nReally? [ynh] ", 'C'); ! 697: #endif ! 698: putchar('\n') FLUSH; ! 699: setdef(buf,"y"); ! 700: #ifdef VERIFY ! 701: printcmd(); ! 702: #endif ! 703: if (*buf == 'h') { ! 704: #ifdef VERBOSE ! 705: IF(verbose) ! 706: fputs("\ ! 707: Type y or SP to mark all articles as read.\n\ ! 708: Type n to leave articles marked as they are.\n\ ! 709: Type u to mark everything read and unsubscribe.\n\ ! 710: ",stdout) FLUSH; ! 711: ELSE ! 712: #endif ! 713: #ifdef TERSE ! 714: fputs("\ ! 715: y or SP to mark all read.\n\ ! 716: n to forget it.\n\ ! 717: u to mark all and unsubscribe.\n\ ! 718: ",stdout) FLUSH; ! 719: #endif ! 720: goto reask_catchup; ! 721: } ! 722: else if (*buf == 'n' || *buf == 'q') { ! 723: return AS_ASK; ! 724: } ! 725: else if (*buf != 'y' && *buf != 'u') { ! 726: fputs(hforhelp,stdout) FLUSH; ! 727: settle_down(); ! 728: goto reask_catchup; ! 729: } ! 730: for (i = firstart; i <= lastart; i++) { ! 731: oneless(i); /* mark as read */ ! 732: } ! 733: #ifdef DELAYMARK ! 734: if (dmfp) ! 735: yankback(); ! 736: #endif ! 737: if (*buf == 'u') { ! 738: rcchar[ng] = NEGCHAR; ! 739: return AS_CLEAN; ! 740: } ! 741: art = lastart+1; ! 742: forcelast = FALSE; ! 743: return AS_NORM; ! 744: case 'Q': ! 745: exit_code = NG_ASK; ! 746: /* FALL THROUGH */ ! 747: case 'q': /* go back up to newsgroup level? */ ! 748: return AS_CLEAN; ! 749: case 'j': ! 750: putchar('\n') FLUSH; ! 751: if (art <= lastart) ! 752: mark_as_read(art); ! 753: return AS_ASK; ! 754: case 'h': { /* help? */ ! 755: int cmd; ! 756: ! 757: if ((cmd = help_art()) > 0) ! 758: pushchar(cmd); ! 759: return AS_ASK; ! 760: } ! 761: case '&': ! 762: if (switcheroo()) /* get rest of command */ ! 763: return AS_INP; /* if rubbed out, try something else */ ! 764: return AS_ASK; ! 765: case '#': ! 766: #ifdef VERBOSE ! 767: IF(verbose) ! 768: printf("\nThe last article is %ld.\n",(long)lastart) FLUSH; ! 769: ELSE ! 770: #endif ! 771: #ifdef TERSE ! 772: printf("\n%ld\n",(long)lastart) FLUSH; ! 773: #endif ! 774: return AS_ASK; ! 775: case '=': { ! 776: char tmpbuf[256]; ! 777: ART_NUM oldart = art; ! 778: int cmd; ! 779: char *subjline = getval("SUBJLINE",Nullch); ! 780: #ifndef CACHESUBJ ! 781: char *s; ! 782: #endif ! 783: ! 784: page_init(); ! 785: #ifdef CACHESUBJ ! 786: if (!subj_list) ! 787: fetchsubj(art,TRUE,FALSE); ! 788: #endif ! 789: for (i=firstart; i<=lastart && !int_count; i++) { ! 790: #ifdef CACHESUBJ ! 791: if (!was_read(i) && ! 792: (subj_list[OFFSET(i)] != Nullch || fetchsubj(i,FALSE,FALSE)) && ! 793: *subj_list[OFFSET(i)] ) { ! 794: sprintf(tmpbuf,"%5ld ", i); ! 795: if (subjline) { ! 796: art = i; ! 797: interp(tmpbuf + 6, (sizeof tmpbuf) - 6, subjline); ! 798: } ! 799: else ! 800: safecpy(tmpbuf + 6, subj_list[OFFSET(i)], ! 801: (sizeof tmpbuf) - 6); ! 802: if (cmd = print_lines(tmpbuf,NOMARKING)) { ! 803: if (cmd > 0) ! 804: pushchar(cmd); ! 805: break; ! 806: } ! 807: } ! 808: #else ! 809: if (!was_read(i) && (s = fetchsubj(i,FALSE,FALSE)) && *s) { ! 810: sprintf(tmpbuf,"%5ld ", i); ! 811: if (subjline) { /* probably fetches it again! */ ! 812: art = i; ! 813: interp(tmpbuf + 6, (sizeof tmpbuf) - 6, subjline); ! 814: } ! 815: else ! 816: safecpy(tmpbuf + 6, s, (sizeof tmpbuf) - 6); ! 817: if (cmd = print_lines(tmpbuf,NOMARKING)) { ! 818: if (cmd > 0) ! 819: pushchar(cmd); ! 820: break; ! 821: } ! 822: } ! 823: #endif ! 824: } ! 825: int_count = 0; ! 826: art = oldart; ! 827: return AS_ASK; ! 828: } ! 829: case '^': ! 830: art = firstart; ! 831: #ifdef ARTSEARCH ! 832: srchahead = 0; ! 833: #endif ! 834: return AS_NORM; ! 835: #if defined(CACHESUBJ) && defined(DEBUGGING) ! 836: case 'D': ! 837: printf("\nFirst article: %ld\n",(long)firstart) FLUSH; ! 838: if (!subj_list) ! 839: fetchsubj(art,TRUE,FALSE); ! 840: if (subj_list != Null(char **)) { ! 841: for (i=1; i<=lastart && !int_count; i++) { ! 842: if (subj_list[OFFSET(i)]) ! 843: printf("%5ld %c %s\n", ! 844: i, (was_read(i)?'y':'n'), subj_list[OFFSET(i)]) FLUSH; ! 845: } ! 846: } ! 847: int_count = 0; ! 848: return AS_ASK; ! 849: #endif ! 850: case 'v': ! 851: if (art <= lastart) { ! 852: reread = TRUE; ! 853: do_hiding = FALSE; ! 854: } ! 855: return AS_NORM; ! 856: #ifdef ROTATION ! 857: case Ctl('x'): ! 858: #endif ! 859: case Ctl('r'): ! 860: #ifdef ROTATION ! 861: rotate = (*buf==Ctl('x')); ! 862: #endif ! 863: if (art <= lastart) ! 864: reread = TRUE; ! 865: return AS_NORM; ! 866: #ifdef ROTATION ! 867: case 'X': ! 868: rotate = !rotate; ! 869: /* FALL THROUGH */ ! 870: #else ! 871: case Ctl('x'): ! 872: case 'x': ! 873: case 'X': ! 874: notincl("x"); ! 875: return AS_ASK; ! 876: #endif ! 877: case 'l': case Ctl('l'): /* refresh screen */ ! 878: if (art <= lastart) { ! 879: reread = TRUE; ! 880: clear(); ! 881: do_fseek = TRUE; ! 882: artline = topline; ! 883: if (artline < 0) ! 884: artline = 0; ! 885: } ! 886: return AS_NORM; ! 887: case 'b': case Ctl('b'): /* back up a page */ ! 888: if (art <= lastart) { ! 889: ART_LINE target; ! 890: ! 891: reread = TRUE; ! 892: clear(); ! 893: do_fseek = TRUE; ! 894: target = topline - (LINES - 2); ! 895: artline = topline; ! 896: do { ! 897: artline--; ! 898: } while (artline >= 0 && artline > target && ! 899: vrdary(artline-1) >= 0); ! 900: topline = artline; ! 901: if (artline < 0) ! 902: artline = 0; ! 903: } ! 904: return AS_NORM; ! 905: case '!': /* shell escape */ ! 906: if (escapade()) ! 907: return AS_INP; ! 908: return AS_ASK; ! 909: case 'C': { ! 910: cancel_article(); ! 911: return AS_ASK; ! 912: } ! 913: case 'R': ! 914: case 'r': { /* reply? */ ! 915: reply(); ! 916: return AS_ASK; ! 917: } ! 918: case 'F': ! 919: case 'f': { /* followup command */ ! 920: followup(); ! 921: forcegrow = TRUE; /* recalculate lastart */ ! 922: return AS_ASK; ! 923: } ! 924: case '|': ! 925: case 'w': case 'W': ! 926: case 's': case 'S': /* save command */ ! 927: if (save_article() == SAVE_ABORT) ! 928: return AS_INP; ! 929: return AS_ASK; ! 930: #ifdef DELAYMARK ! 931: case 'Y': /* yank back M articles */ ! 932: yankback(); ! 933: art = firstart; /* from the beginning */ ! 934: return AS_NORM; /* pretend nothing happened */ ! 935: #endif ! 936: #ifdef STRICTCR ! 937: case '\n': ! 938: fputs(badcr,stdout) FLUSH; ! 939: return AS_ASK; ! 940: #endif ! 941: default: ! 942: printf("\n%s",hforhelp) FLUSH; ! 943: settle_down(); ! 944: return AS_ASK; ! 945: } ! 946: } ! 947: ! 948: #ifdef MAILCALL ! 949: /* see if there is any mail */ ! 950: ! 951: void ! 952: setmail() ! 953: { ! 954: if (! (mailcount++)) { ! 955: char *mailfile = filexp(getval("MAILFILE",MAILFILE)); ! 956: ! 957: if (stat(mailfile,&filestat) < 0 || !filestat.st_size ! 958: || filestat.st_atime > filestat.st_mtime) ! 959: mailcall = nullstr; ! 960: else ! 961: mailcall = getval("MAILCALL","(Mail) "); ! 962: } ! 963: mailcount %= 10; /* check every 10 articles */ ! 964: } ! 965: #endif ! 966: ! 967: void ! 968: setdfltcmd() ! 969: { ! 970: if (toread[ng]) { ! 971: #ifdef ARTSEARCH ! 972: if (srchahead) ! 973: dfltcmd = "^Nnpq"; ! 974: else ! 975: #endif ! 976: dfltcmd = "npq"; ! 977: } ! 978: else { ! 979: if (art > lastart) ! 980: dfltcmd = "qnp"; ! 981: else ! 982: dfltcmd = "npq"; ! 983: } ! 984: } ! 985:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.