|
|
1.1 ! root 1: /* rn -- new readnews program ! 2: * ! 3: * From: [email protected] (Larry Wall) ! 4: * Organization: System Development Corporation, Santa Monica ! 5: * ! 6: * begun: 01/14/83 ! 7: * 1.0: 04/08/83 ! 8: * 2.0: 09/01/83 ! 9: */ ! 10: ! 11: static char rnid[] = "@(#)$Header: rn.c,v 4.3.1.3 85/05/16 16:47:10 lwall Exp $"; ! 12: ! 13: /* $Log: rn.c,v $ ! 14: * Revision 4.3.1.3 85/05/16 16:47:10 lwall ! 15: * Catchup confirmation didn't grok -t. ! 16: * ! 17: * Revision 4.3.1.2 85/05/13 09:34:53 lwall ! 18: * Fixed default after do_newsgroup() returns from Q command. ! 19: * ! 20: * Revision 4.3.1.1 85/05/10 11:38:08 lwall ! 21: * Branch for patches. ! 22: * ! 23: * Revision 4.3 85/05/01 11:47:56 lwall ! 24: * Baseline for release with 4.3bsd. ! 25: * ! 26: */ ! 27: ! 28: #include "INTERN.h" ! 29: #include "common.h" ! 30: #include "rn.h" ! 31: #include "EXTERN.h" ! 32: #include "rcstuff.h" ! 33: #include "term.h" ! 34: #include "final.h" ! 35: #include "ngdata.h" ! 36: #include "util.h" ! 37: #include "only.h" ! 38: #include "ngsrch.h" ! 39: #include "help.h" ! 40: #include "last.h" ! 41: #include "init.h" ! 42: #include "intrp.h" ! 43: #include "rcln.h" ! 44: #include "sw.h" ! 45: #include "addng.h" ! 46: #include "ng.h" ! 47: #include "INTERN.h" ! 48: ! 49: void ! 50: rn_init() ! 51: { ! 52: ; ! 53: } ! 54: ! 55: void ! 56: main(argc,argv) ! 57: int argc; ! 58: char *argv[]; ! 59: { ! 60: bool foundany = initialize(argc,argv); ! 61: register char *s; ! 62: bool oh_for_the_good_old_days = FALSE; ! 63: ! 64: if (maxngtodo) ! 65: starthere = 0; ! 66: else if (!foundany) { /* nothing to do? */ ! 67: #ifdef VERBOSE ! 68: if (verbose) ! 69: fputs("\ ! 70: No unread news in subscribed-to newsgroups. To subscribe to a new\n\ ! 71: newsgroup use the g<newsgroup> command.\n\ ! 72: ",stdout) FLUSH; ! 73: #endif ! 74: starthere = nextrcline; ! 75: } ! 76: ! 77: /* loop through all unread news */ ! 78: ! 79: { ! 80: char promptbuf[80]; ! 81: bool special = FALSE; /* temporarily allow newsgroup */ ! 82: /* with no unread news? */ ! 83: bool retry; /* cycle back to top of list? */ ! 84: NG_NUM recent_ng = 0; ! 85: ! 86: current_ng = 0; ! 87: do { ! 88: retry = FALSE; ! 89: if (findlast) { ! 90: findlast = FALSE; ! 91: starthere = 0; ! 92: if (*lastngname) { ! 93: if ((ng = find_ng(lastngname)) == nextrcline) ! 94: ng = 0; ! 95: else { ! 96: set_ngname(lastngname); ! 97: set_toread(ng); ! 98: if (toread[ng] <= TR_NONE) ! 99: ng = 0; ! 100: } ! 101: } ! 102: } ! 103: else { ! 104: ng = starthere; ! 105: starthere = 0; ! 106: } ! 107: while (ng <= nextrcline) { /* for each newsgroup */ ! 108: mode = 'n'; ! 109: if (ng >= nextrcline) { /* after the last newsgroup? */ ! 110: ng = nextrcline; /* force it to 1 after */ ! 111: #ifdef ONLY ! 112: if (maxngtodo) { ! 113: if (retry) ! 114: #ifdef VERBOSE ! 115: IF(verbose) ! 116: printf("\nRestriction %s%s still in effect.\n", ! 117: ngtodo[0], ! 118: maxngtodo > 1 ? ", etc." : nullstr) FLUSH; ! 119: ELSE ! 120: #endif ! 121: #ifdef TERSE ! 122: fputs("\n(\"Only\" mode.)\n",stdout) FLUSH; ! 123: #endif ! 124: else { ! 125: #ifdef VERBOSE ! 126: IF(verbose) ! 127: fputs("\nNo articles under restriction.", ! 128: stdout) FLUSH; ! 129: ELSE ! 130: #endif ! 131: #ifdef TERSE ! 132: fputs("\nNo \"only\" articles.",stdout) FLUSH; ! 133: #endif ! 134: end_only(); /* release the restriction */ ! 135: retry = TRUE; ! 136: } ! 137: } ! 138: #endif ! 139: dfltcmd = (retry ? "npq" : "qnp"); ! 140: #ifdef VERBOSE ! 141: IF(verbose) ! 142: sprintf(promptbuf, ! 143: "\n******** End of newsgroups--what next? [%s] ", ! 144: dfltcmd); ! 145: ELSE ! 146: #endif ! 147: #ifdef TERSE ! 148: sprintf(promptbuf, ! 149: "\n**** End--next? [%s] ", dfltcmd); ! 150: #endif ! 151: } ! 152: else { ! 153: bool shoe_fits; /* newsgroup matches restriction? */ ! 154: ! 155: if (toread[ng] >= TR_NONE) { /* recalc toread? */ ! 156: set_ngname(rcline[ng]); ! 157: if (shoe_fits = (special || inlist(ngname))) ! 158: set_toread(ng); ! 159: if (paranoid) { ! 160: recent_ng = current_ng; ! 161: current_ng = ng; ! 162: cleanup_rc(); ! 163: /* this may move newsgroups around */ ! 164: ng = current_ng; ! 165: set_ngname(rcline[ng]); ! 166: } ! 167: } ! 168: if (toread[ng] < (maxngtodo||special ? TR_NONE : TR_ONE) || !shoe_fits) { ! 169: /* unwanted newsgroup? */ ! 170: ng++; /* then skip it */ ! 171: continue; ! 172: } ! 173: dfltcmd = "ynq"; ! 174: #ifdef VERBOSE ! 175: IF(verbose) ! 176: sprintf(promptbuf, ! 177: "\n******** %3ld unread article%c in %s--read now? [%s] ", ! 178: (long)toread[ng], (toread[ng]==TR_ONE ? ' ' : 's'), ! 179: ngname, dfltcmd); /* format prompt string */ ! 180: ELSE ! 181: #endif ! 182: #ifdef TERSE ! 183: sprintf(promptbuf, ! 184: "\n**** %3ld in %s--read? [%s] ", ! 185: (long)toread[ng], ! 186: ngname,dfltcmd); /* format prompt string */ ! 187: #endif ! 188: } ! 189: special = FALSE; /* go back to normal mode */ ! 190: if (ng != current_ng) { ! 191: recent_ng = current_ng; ! 192: /* remember previous newsgroup */ ! 193: current_ng = ng; /* remember current newsgroup */ ! 194: } ! 195: reask_newsgroup: ! 196: unflush_output(); /* disable any ^O in effect */ ! 197: fputs(promptbuf,stdout) FLUSH;/* print prompt */ ! 198: fflush(stdout); ! 199: reinp_newsgroup: ! 200: eat_typeahead(); ! 201: getcmd(buf); ! 202: if (errno || *buf == '\f') { ! 203: putchar('\n') FLUSH; /* if return from stop signal */ ! 204: goto reask_newsgroup; /* give them a prompt again */ ! 205: } ! 206: setdef(buf,dfltcmd); ! 207: #ifdef VERIFY ! 208: printcmd(); ! 209: #endif ! 210: switch (*buf) { ! 211: case 'p': /* find previous unread newsgroup */ ! 212: do { ! 213: if (ng <= 0) ! 214: break; ! 215: ng--; ! 216: if (toread[ng] == TR_NONE) ! 217: set_toread(ng); ! 218: } while (toread[ng] <= TR_NONE); ! 219: break; ! 220: case 'P': /* goto previous newsgroup */ ! 221: do { ! 222: if (ng <= 0) ! 223: break; ! 224: ng--; ! 225: } while (toread[ng] < TR_NONE); ! 226: special = TRUE; /* don't skip it if toread==0 */ ! 227: break; ! 228: case '-': ! 229: ng = recent_ng; /* recall previous newsgroup */ ! 230: special = TRUE; /* don't skip it if toread==0 */ ! 231: break; ! 232: case 'q': case 'Q': case 'x': /* quit? */ ! 233: oh_for_the_good_old_days = (*buf == 'x'); ! 234: putchar('\n') FLUSH; ! 235: ng = nextrcline+1; /* satisfy */ ! 236: retry = FALSE; /* loop conditions */ ! 237: break; ! 238: case '^': ! 239: putchar('\n') FLUSH; ! 240: ng = 0; ! 241: break; ! 242: case 'n': case '+': /* find next unread newsgroup */ ! 243: if (ng == nextrcline) { ! 244: putchar('\n') FLUSH; ! 245: retry = TRUE; ! 246: } ! 247: else if (toread[ng] > TR_NONE) ! 248: retry = TRUE; ! 249: ng++; ! 250: break; ! 251: case 'N': /* goto next newsgroup */ ! 252: ng++; ! 253: special = TRUE; /* and don't skip it if toread==0 */ ! 254: break; ! 255: case '1': /* goto 1st newsgroup */ ! 256: ng = 0; ! 257: special = TRUE; /* and don't skip it if toread==0 */ ! 258: break; ! 259: case '$': ! 260: ng = nextrcline; /* goto last newsgroup */ ! 261: retry = TRUE; ! 262: break; ! 263: case 'L': ! 264: list_newsgroups(); ! 265: goto reask_newsgroup; ! 266: case '/': case '?': /* scan for newsgroup pattern */ ! 267: #ifdef NGSEARCH ! 268: switch (ng_search(buf,TRUE)) { ! 269: case NGS_ABORT: ! 270: goto reinp_newsgroup; ! 271: case NGS_INTR: ! 272: #ifdef VERBOSE ! 273: IF(verbose) ! 274: fputs("\n(Interrupted)\n",stdout) FLUSH; ! 275: ELSE ! 276: #endif ! 277: #ifdef TERSE ! 278: fputs("\n(Intr)\n",stdout) FLUSH; ! 279: #endif ! 280: ng = current_ng; ! 281: goto reask_newsgroup; ! 282: case NGS_FOUND: ! 283: special = TRUE; /* don't skip it if toread==0 */ ! 284: break; ! 285: case NGS_NOTFOUND: ! 286: #ifdef VERBOSE ! 287: IF(verbose) ! 288: fputs("\n\nNot found--use g to add newsgroups\n", ! 289: stdout) FLUSH; ! 290: ELSE ! 291: #endif ! 292: #ifdef TERSE ! 293: fputs("\n\nNot found\n",stdout) FLUSH; ! 294: #endif ! 295: goto reask_newsgroup; ! 296: } ! 297: #else ! 298: notincl("/"); ! 299: #endif ! 300: break; ! 301: case 'm': ! 302: #ifndef RELOCATE ! 303: notincl("m"); ! 304: break; ! 305: #endif ! 306: case 'g': /* goto named newsgroup */ ! 307: if (!finish_command(FALSE)) ! 308: /* if they didn't finish command */ ! 309: goto reinp_newsgroup; /* go try something else */ ! 310: for (s = buf+1; *s == ' '; s++); ! 311: /* skip leading spaces */ ! 312: if (!*s) ! 313: strcpy(s,ngname); ! 314: #ifdef RELOCATE ! 315: if (!get_ng(s,*buf=='m')) /* try to find newsgroup */ ! 316: #else ! 317: if (!get_ng(s,FALSE)) /* try to find newsgroup */ ! 318: #endif ! 319: ng = current_ng;/* if not found, go nowhere */ ! 320: special = TRUE; /* don't skip it if toread==0 */ ! 321: break; ! 322: #ifdef DEBUGGING ! 323: case 'D': ! 324: printf("\nTries: %d Hits: %d\n", ! 325: softtries,softtries-softmisses) FLUSH; ! 326: goto reask_newsgroup; ! 327: #endif ! 328: case '!': /* shell escape */ ! 329: if (escapade()) /* do command */ ! 330: goto reinp_newsgroup; ! 331: /* if rubbed out, re input */ ! 332: goto reask_newsgroup; ! 333: case Ctl('k'): /* edit global KILL file */ ! 334: edit_kfile(); ! 335: goto reask_newsgroup; ! 336: case 'c': /* catch up */ ! 337: #ifdef CATCHUP ! 338: reask_catchup: ! 339: #ifdef VERBOSE ! 340: IF(verbose) ! 341: in_char("\nDo you really want to mark everything as read? [yn] "); ! 342: ELSE ! 343: #endif ! 344: #ifdef TERSE ! 345: in_char("\nReally? [ynh] "); ! 346: #endif ! 347: putchar('\n') FLUSH; ! 348: setdef(buf,"y"); ! 349: if (*buf == 'h') { ! 350: #ifdef VERBOSE ! 351: printf("Type y or SP to mark all articles as read.\n"); ! 352: printf("Type n to leave articles marked as they are.\n"); ! 353: #else ! 354: printf("y or SP to mark all read.\n"); ! 355: printf("n to forget it.\n"); ! 356: #endif ! 357: goto reask_catchup; ! 358: } ! 359: else if (*buf!=' ' && *buf!='y' && *buf!='n' && *buf!='q') { ! 360: printf(hforhelp); ! 361: settle_down(); ! 362: goto reask_catchup; ! 363: } else if ( (*buf == ' ' || *buf == 'y') && ng<nextrcline ) ! 364: catch_up(ng); ! 365: else ! 366: retry = TRUE; ! 367: ng++; ! 368: #else ! 369: notincl("c"); ! 370: #endif ! 371: break; ! 372: case 'u': /* unsubscribe */ ! 373: if (ng < nextrcline && toread[ng] >= TR_NONE) { ! 374: /* unsubscribable? */ ! 375: printf(unsubto,rcline[ng]) FLUSH; ! 376: rcchar[ng] = NEGCHAR; ! 377: /* unsubscribe to (from?) it */ ! 378: toread[ng] = TR_UNSUB; ! 379: /* and make line invisible */ ! 380: ng++; /* do an automatic 'n' */ ! 381: } ! 382: break; ! 383: case 'h': { /* help */ ! 384: int cmd; ! 385: ! 386: if ((cmd = help_ng()) > 0) ! 387: pushchar(cmd); ! 388: goto reask_newsgroup; ! 389: } ! 390: case 'a': ! 391: #ifndef FINDNEWNG ! 392: notincl("a"); ! 393: goto reask_newsgroup; ! 394: #else ! 395: /* FALL THROUGH */ ! 396: #endif ! 397: case 'o': ! 398: #ifdef ONLY ! 399: { ! 400: #ifdef FINDNEWNG ! 401: bool doscan = (*buf == 'a'); ! 402: #endif ! 403: ! 404: if (!finish_command(TRUE)) /* get rest of command */ ! 405: goto reinp_newsgroup; /* if rubbed out, try something else */ ! 406: end_only(); ! 407: if (buf[1]) { ! 408: bool minusd = instr(buf+1,"-d") != Nullch; ! 409: ! 410: sw_list(buf+1); ! 411: if (minusd) ! 412: cwd_check(); ! 413: putchar('\n') FLUSH; ! 414: #ifdef FINDNEWNG ! 415: if (doscan && maxngtodo) ! 416: scanactive(); ! 417: #endif ! 418: } ! 419: ng = 0; /* simulate ^ */ ! 420: retry = FALSE; ! 421: break; ! 422: } ! 423: #else ! 424: notincl("o"); ! 425: goto reask_newsgroup; ! 426: #endif ! 427: case '&': ! 428: if (switcheroo()) /* get rest of command */ ! 429: goto reinp_newsgroup; /* if rubbed out, try something else */ ! 430: goto reask_newsgroup; ! 431: case 'l': { /* list other newsgroups */ ! 432: if (!finish_command(TRUE)) /* get rest of command */ ! 433: goto reinp_newsgroup; /* if rubbed out, try something else */ ! 434: for (s = buf+1; *s == ' '; s++); ! 435: /* skip leading spaces */ ! 436: sprintf(cmd_buf,"%s '%s'",filexp(NEWSGROUPS),s); ! 437: resetty(); ! 438: if (doshell(sh,cmd_buf)) ! 439: #ifdef VERBOSE ! 440: IF(verbose) ! 441: fputs(" (Error from newsgroups program)\n", ! 442: stdout) FLUSH; ! 443: ELSE ! 444: #endif ! 445: #ifdef TERSE ! 446: fputs("(Error)\n",stdout) FLUSH; ! 447: #endif ! 448: noecho(); ! 449: crmode(); ! 450: goto reask_newsgroup; ! 451: } ! 452: case '.': case '=': ! 453: case 'y': case 'Y': /* do normal thing */ ! 454: if (ng >= nextrcline) { ! 455: fputs("\nNot on a newsgroup.",stdout) FLUSH; ! 456: goto reask_newsgroup; ! 457: } ! 458: if (*buf == '=') ! 459: s = savestr("="); ! 460: else if (*buf == '.') { /* start command? */ ! 461: if (!finish_command(FALSE)) /* get rest of command */ ! 462: goto reinp_newsgroup; ! 463: s = savestr(buf+1); ! 464: /* do_newsgroup will free it */ ! 465: } ! 466: else ! 467: s = Nullch; ! 468: if (toread[ng]) ! 469: retry = TRUE; ! 470: switch (do_newsgroup(s)) { ! 471: case NG_ERROR: ! 472: case NG_NORM: ! 473: ng++; ! 474: break; ! 475: case NG_ASK: ! 476: dfltcmd = "ynq"; ! 477: goto reask_newsgroup; ! 478: case NG_MINUS: ! 479: ng = recent_ng; /* recall previous newsgroup */ ! 480: special = TRUE; /* don't skip it if toread==0 */ ! 481: break; ! 482: } ! 483: break; ! 484: #ifdef STRICTCR ! 485: case '\n': ! 486: fputs(badcr,stdout) FLUSH; ! 487: goto reask_newsgroup; ! 488: #endif ! 489: case 'v': ! 490: printf("\n%s\n",rnid) FLUSH; ! 491: goto reask_newsgroup; ! 492: default: ! 493: printf("\n%s",hforhelp) FLUSH; ! 494: settle_down(); ! 495: goto reask_newsgroup; ! 496: } ! 497: } ! 498: } while (retry); ! 499: } ! 500: ! 501: /* now write .newsrc back out */ ! 502: ! 503: write_rc(); ! 504: ! 505: if (oh_for_the_good_old_days) ! 506: get_old_rc(); ! 507: ! 508: finalize(0); /* and exit */ ! 509: } ! 510: ! 511: /* set current newsgroup */ ! 512: ! 513: void ! 514: set_ngname(what) ! 515: char *what; ! 516: { ! 517: int len = strlen(what)+1; ! 518: ! 519: growstr(&ngname,&ngnlen,len); ! 520: strcpy(ngname,what); ! 521: growstr(&ngdir,&ngdlen,len); ! 522: strcpy(ngdir,getngdir(ngname)); ! 523: } ! 524: ! 525: static char *myngdir; ! 526: static int ngdirlen = 0; ! 527: ! 528: char * ! 529: getngdir(ngnam) ! 530: char *ngnam; ! 531: { ! 532: register char *s; ! 533: ! 534: growstr(&myngdir,&ngdirlen,strlen(ngnam)+1); ! 535: strcpy(myngdir,ngnam); ! 536: for (s = myngdir; *s; s++) ! 537: if (*s == '.') ! 538: *s = '/'; ! 539: return myngdir; ! 540: } ! 541:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.