1: /*  rn -- new readnews program
   2:  *
   3:  *  From: lwall@sdcrdcf.UUCP (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: }

Defined functions

main defined in line 55; never used
rn_init defined in line 49; used 2 times

Defined variables

myngdir defined in line 525; used 4 times
ngdirlen defined in line 526; used 1 times
rnid defined in line 11; used 1 times
Last modified: 1986-03-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2184
Valid CSS Valid XHTML 1.0 Strict