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.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: }

Defined functions

getngdir defined in line 531; used 4 times
main defined in line 58; never used
rn_init defined in line 52; used 2 times
set_ngname defined in line 516; used 5 times

Defined variables

myngdir defined in line 528; used 4 times
ngdirlen defined in line 529; used 1 times
rnid defined in line 11; used 1 times
Last modified: 1989-04-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3689
Valid CSS Valid XHTML 1.0 Strict