Annotation of 43BSD/contrib/rn/ng.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.