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