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

1.1       root        1: /* $Header: ng.c,v 4.3.1.3 85/05/16 16:48:09 lwall Exp $
                      2:  *
                      3:  * $Log:       ng.c,v $
                      4:  * Revision 4.3.1.3  85/05/16  16:48:09  lwall
                      5:  * Fixed unsubsubscribe.
                      6:  * 
                      7:  * Revision 4.3.1.2  85/05/13  09:29:28  lwall
                      8:  * Added CUSTOMLINES option.
                      9:  * 
                     10:  * Revision 4.3.1.1  85/05/10  11:36:00  lwall
                     11:  * Branch for patches.
                     12:  * 
                     13:  * Revision 4.3  85/05/01  11:43:43  lwall
                     14:  * Baseline for release with 4.3bsd.
                     15:  * 
                     16:  */
                     17: 
                     18: #include "EXTERN.h"
                     19: #include "common.h"
                     20: #include "rn.h"
                     21: #include "term.h"
                     22: #include "final.h"
                     23: #include "util.h"
                     24: #include "artsrch.h"
                     25: #include "cheat.h"
                     26: #include "help.h"
                     27: #include "kfile.h"
                     28: #include "rcstuff.h"
                     29: #include "head.h"
                     30: #include "artstate.h"
                     31: #include "bits.h"
                     32: #include "art.h"
                     33: #include "artio.h"
                     34: #include "ngstuff.h"
                     35: #include "intrp.h"
                     36: #include "respond.h"
                     37: #include "ngdata.h"
                     38: #include "backpage.h"
                     39: #include "rcln.h"
                     40: #include "last.h"
                     41: #include "search.h"
                     42: #include "server.h"
                     43: #include "INTERN.h"
                     44: #include "ng.h"
                     45: #include "artstate.h"                  /* somebody has to do it */
                     46: 
                     47: /* art_switch() return values */
                     48: 
                     49: #define AS_NORM 0
                     50: #define AS_INP 1
                     51: #define AS_ASK 2
                     52: #define AS_CLEAN 3
                     53: 
                     54: ART_NUM recent_art = 0;                /* previous article # for '-' command */
                     55: ART_NUM curr_art = 0;                /* current article # */
                     56: int exit_code = NG_NORM;
                     57: 
                     58: void
                     59: ng_init()
                     60: {
                     61: 
                     62: #ifdef KILLFILES
                     63:     open_kfile(KF_GLOBAL);
                     64: #endif
                     65: #ifdef CUSTOMLINES
                     66:     init_compex(&hide_compex);
                     67:     init_compex(&page_compex);
                     68: #endif
                     69: }
                     70: 
                     71: /* do newsgroup on line ng with name ngname */
                     72: 
                     73: /* assumes that we are chdir'ed to SPOOL, and assures that that is
                     74:  * still true upon return, but chdirs to SPOOL/ngname in between
                     75:  *
                     76:  * If you can understand this routine, you understand most of the program.
                     77:  * The basic structure is:
                     78:  *     for each desired article
                     79:  *             for each desired page
                     80:  *                     for each line on page
                     81:  *                             if we need another line from file
                     82:  *                                     get it
                     83:  *                                     if it's a header line
                     84:  *                                             do special things
                     85:  *                             for each column on page
                     86:  *                                     put out a character
                     87:  *                             end loop
                     88:  *                     end loop
                     89:  *             end loop
                     90:  *     end loop
                     91:  *
                     92:  *     (Actually, the pager is in another routine.)
                     93:  *
                     94:  * The chief problem is deciding what is meant by "desired".  Most of
                     95:  * the messiness of this routine is due to the fact that people want
                     96:  * to do unstructured things all the time.  I have used a few judicious
                     97:  * goto's where I thought it improved readability.  The rest of the messiness
                     98:  * arises from trying to be both space and time efficient.  Have fun.
                     99:  */
                    100: 
                    101: int
                    102: do_newsgroup(start_command)
                    103: char *start_command;                   /* command to fake up first */
                    104: {
                    105: #ifdef SERVER
                    106:     char ser_line[256];
                    107:     char artname[32];
                    108:     static long our_pid;
                    109: #endif
                    110:     char oldmode = mode;
                    111:     register long i;                   /* scratch */
                    112:     int skipstate;                     /* how many unavailable articles */
                    113:                                        /*   have we skipped already? */
                    114:     
                    115:     char *whatnext = "%sWhat next? [%s]";
                    116: 
                    117: #ifdef SERVER
                    118:     if (our_pid == 0)          /* Agreed, this is gross */
                    119:        our_pid = getpid();
                    120: #endif
                    121: 
                    122: #ifdef ARTSEARCH
                    123:     srchahead = (scanon && ((ART_NUM)toread[ng]) >= scanon ? -1 : 0);
                    124:                                        /* did they say -S? */
                    125: #endif
                    126:     
                    127:     mode = 'a';
                    128:     recent_art = curr_art = 0;
                    129:     exit_code = NG_NORM;
                    130: #ifndef SERVER
                    131:     if (eaccess(ngdir,5)) {            /* directory read protected? */
                    132:        if (eaccess(ngdir,0)) {
                    133: #ifdef VERBOSE
                    134:            IF(verbose)
                    135:                printf("\nNewsgroup %s does not have a spool directory!\n",
                    136:                    ngname) FLUSH;
                    137:            ELSE
                    138: #endif
                    139: #ifdef TERSE
                    140:                printf("\nNo spool for %s!\n",ngname) FLUSH;
                    141: #endif
                    142: #ifdef CATCHUP
                    143:            catch_up(ng);
                    144: #endif
                    145:            toread[ng] = TR_NONE;
                    146:        }
                    147:        else {
                    148: #ifdef VERBOSE
                    149:            IF(verbose)
                    150:                printf("\nNewsgroup %s is not currently accessible.\n",
                    151:                    ngname) FLUSH;
                    152:            ELSE
                    153: #endif
                    154: #ifdef TERSE
                    155:                printf("\n%s not readable.\n",ngname) FLUSH;
                    156: #endif
                    157:            toread[ng] = TR_NONE;       /* make this newsgroup invisible */
                    158:                                        /* (temporarily) */
                    159:        }
                    160:        mode = oldmode;
                    161:        return -1;
                    162:     }
                    163: 
                    164:     /* chdir to newsgroup subdirectory */
                    165: 
                    166:     if (chdir(ngdir)) {
                    167:        printf(nocd,ngdir) FLUSH;
                    168:        mode = oldmode;
                    169:        return -1;
                    170:     }
                    171: #else  /* SERVER */
                    172:     sprintf(ser_line, "GROUP %s", ngname);
                    173:     put_server(ser_line);
                    174:     if (get_server(ser_line, sizeof(ser_line)) < 0) {
                    175:        fprintf(stderr, "rrn: Unexpected close of server socket.\n");
                    176:        finalize(1);
                    177:     }
                    178:     if (*ser_line != CHAR_OK)
                    179:        return (-1);
                    180: #endif /* SERVER */
                    181: 
                    182: #ifdef CACHESUBJ
                    183:     subj_list = Null(char **);         /* no subject list till needed */
                    184: #endif
                    185:     
                    186:     /* initialize control bitmap */
                    187: 
                    188:     if (initctl()) {
                    189:        mode = oldmode;
                    190:        return -1;
                    191:     }
                    192: 
                    193:     /* FROM HERE ON, RETURN THRU CLEANUP OR WE ARE SCREWED */
                    194:     
                    195:     in_ng = TRUE;                      /* tell the world we are here */
                    196:     forcelast = TRUE;                  /* if 0 unread, do not bomb out */
                    197:     art=firstart;
                    198:     
                    199:     /* remember what newsgroup we were in for sake of posterity */
                    200: 
                    201:     writelast();
                    202: 
                    203:     /* see if there are any special searches to do */
                    204: 
                    205: #ifdef KILLFILES
                    206:     open_kfile(KF_LOCAL);
                    207: #ifdef VERBOSE
                    208:     IF(verbose)
                    209:        kill_unwanted(firstart,"Looking for articles to kill...\n\n",TRUE);
                    210:     ELSE
                    211: #endif
                    212: #ifdef TERSE
                    213:        kill_unwanted(firstart,"Killing...\n\n",TRUE);
                    214: #endif
                    215: #endif
                    216:     
                    217:     /* do they want a special top line? */
                    218: 
                    219:     firstline = getval("FIRSTLINE",Nullch);
                    220: 
                    221:     /* custom line suppression, custom page ending */
                    222: 
                    223: #ifdef CUSTOMLINES
                    224:     if (hideline = getval("HIDELINE",Nullch))
                    225:        compile(&hide_compex,hideline,TRUE,TRUE);
                    226:     if (pagestop = getval("PAGESTOP",Nullch))
                    227:        compile(&page_compex,pagestop,TRUE,TRUE);
                    228: #endif
                    229: 
                    230:     /* now read each unread article */
                    231: 
                    232:     rc_changed = doing_ng = TRUE;      /* enter the twilight zone */
                    233:     skipstate = 0;                     /* we have not skipped anything (yet) */
                    234:     checkcount = 0;                    /* do not checkpoint for a while */
                    235:     do_fseek = FALSE;                  /* start 1st article at top */
                    236:     if (art > lastart)
                    237:        art=firstart;                   /* init the for loop below */
                    238:     for (; art<=lastart+1; ) {         /* for each article */
                    239: 
                    240:        /* do we need to "grow" the newsgroup? */
                    241: 
                    242:        if (art > lastart || forcegrow)
                    243:            grow_ctl();
                    244:        check_first(art);               /* make sure firstart is still 1st */
                    245:        if (start_command) {            /* fake up an initial command? */
                    246:            prompt = whatnext;
                    247:            strcpy(buf,start_command);
                    248:            free(start_command);
                    249:            start_command = Nullch;
                    250:            art = lastart+1;
                    251:            goto article_level;
                    252:        }
                    253:        if (art>lastart) {              /* are we off the end still? */
                    254:            ART_NUM ucount = 0;         /* count of unread articles left */
                    255: 
                    256:            for (i=firstart; i<=lastart; i++)
                    257:                if (!(ctl_read(i)))
                    258:                    ucount++;           /* count the unread articles */
                    259: #ifdef DEBUGGING
                    260:            /*NOSTRICT*/
                    261:            if (debug && ((ART_NUM)toread[ng]) != ucount)
                    262:                printf("(toread=%ld sb %ld)",(long)toread[ng],(long)ucount)
                    263:                  FLUSH;
                    264: #endif
                    265:            /*NOSTRICT*/
                    266:            toread[ng] = (ART_UNREAD)ucount;    /* this is perhaps pointless */
                    267:            art = lastart + 1;          /* keep bitmap references sane */
                    268:            if (art != curr_art) {
                    269:                recent_art = curr_art;
                    270:                                        /* remember last article # (for '-') */
                    271:                curr_art = art;      /* remember this article # */
                    272:            }
                    273:            if (erase_screen)
                    274:                clear();                        /* clear the screen */
                    275:            else
                    276:                fputs("\n\n",stdout) FLUSH;
                    277: #ifdef VERBOSE
                    278:            IF(verbose)
                    279:                printf("End of newsgroup %s.",ngname);
                    280:                                        /* print pseudo-article */
                    281:            ELSE
                    282: #endif
                    283: #ifdef TERSE
                    284:                printf("End of %s",ngname);
                    285: #endif
                    286:            if (ucount) {
                    287:                printf("  (%ld article%s still unread)",
                    288:                    (long)ucount,ucount==1?nullstr:"s");
                    289:            }
                    290:            else {
                    291:                if (!forcelast)
                    292:                    goto cleanup;       /* actually exit newsgroup */
                    293:            }
                    294:            prompt = whatnext;
                    295: #ifdef ARTSEARCH
                    296:            srchahead = 0;              /* no more subject search mode */
                    297: #endif
                    298:            fputs("\n\n",stdout) FLUSH;
                    299:            skipstate = 0;              /* back to none skipped */
                    300:        }
                    301:        else if (!reread && was_read(art)) {
                    302:                                        /* has this article been read? */
                    303:            art++;                      /* then skip it */
                    304:            continue;
                    305:        }
                    306:        else if
                    307:          (!reread && !was_read(art)
                    308:            && artopen(art) == Nullfp) {        /* never read it, & cannot find it? */
                    309:            if (errno != ENOENT) {      /* has it not been deleted? */
                    310: #ifdef VERBOSE
                    311:                IF(verbose)
                    312:                    printf("\n(Article %ld exists but is unreadable.)\n",
                    313:                        (long)art) FLUSH;
                    314:                ELSE
                    315: #endif
                    316: #ifdef TERSE
                    317:                    printf("\n(%ld unreadable.)\n",(long)art) FLUSH;
                    318: #endif
                    319:                skipstate = 0;
                    320:                sleep(2);
                    321:            }
                    322:            switch(skipstate++) {
                    323:            case 0:
                    324:                clear();
                    325: #ifdef VERBOSE
                    326:                IF(verbose)
                    327:                    fputs("Skipping unavailable article",stdout);
                    328:                ELSE
                    329: #endif
                    330: #ifdef TERSE
                    331:                    fputs("Skipping",stdout);
                    332: #endif
                    333:                for (i = just_a_sec/3; i; --i)
                    334:                    putchar(PC);
                    335:                fflush(stdout);
                    336:                sleep(1);
                    337:                break;
                    338:            case 1:
                    339:                fputs("..",stdout);
                    340:                fflush(stdout);
                    341:                break;
                    342:            default:
                    343:                putchar('.');
                    344:                fflush(stdout);
                    345: #ifndef SERVER
                    346: #define READDIR
                    347: #ifdef READDIR
                    348:                {                       /* fast skip patch */
                    349:                    ART_NUM newart;
                    350:                    
                    351:                    if (! (newart=getngmin(".",art)))
                    352:                        newart = lastart+1;
                    353:                    for (i=art; i<newart; i++)
                    354:                        oneless(i);
                    355:                    art = newart - 1;
                    356:                }
                    357: #endif
                    358: #endif
                    359:                break;
                    360:            }
                    361:            oneless(art);               /* mark deleted as read */
                    362:            art++;                      /* try next article */
                    363:            continue;
                    364:        }
                    365:        else {                          /* we have a real live article */
                    366:            skipstate = 0;              /* back to none skipped */
                    367:            if (art != curr_art) {
                    368:                recent_art = curr_art;
                    369:                                        /* remember last article # (for '-') */
                    370:                curr_art = art;      /* remember this article # */
                    371:            }
                    372:            if (!do_fseek) {            /* starting at top of article? */
                    373:                artline = 0;            /* start at the beginning */
                    374:                topline = -1;           /* and remember top line of screen */
                    375:                                        /*  (line # within article file) */
                    376:            }
                    377:            clear();                    /* clear screen */
                    378:            artopen(art);               /* make sure article file is open */
                    379:            if (artfp == Nullfp) {      /* could not find article? */
                    380:                printf("Article %ld of %s is not available.\n\n",
                    381:                    (long)art,ngname) FLUSH;
                    382:                prompt = whatnext;
                    383: #ifdef ARTSEARCH
                    384:                srchahead = 0;
                    385: #endif
                    386:            }
                    387:            else {                      /* found it, so print it */
                    388:                switch (do_article()) {
                    389:                case DA_CLEAN:          /* quit newsgroup */
                    390:                    goto cleanup;
                    391:                case DA_TOEND:          /* do not mark as read */
                    392:                    goto reask_article; 
                    393:                case DA_RAISE:          /* reparse command at end of art */
                    394:                    goto article_level;
                    395:                case DA_NORM:           /* normal end of article */
                    396:                    break;
                    397:                }
                    398:            }
                    399:            mark_as_read(art);           /* mark current article as read */
                    400:            reread = FALSE;
                    401:            do_hiding = TRUE;
                    402: #ifdef ROTATION
                    403:            rotate = FALSE;
                    404: #endif
                    405:        }
                    406: 
                    407: /* if these gotos bother you, think of this as a little state machine */
                    408: 
                    409: reask_article:
                    410: #ifdef MAILCALL
                    411:        setmail();
                    412: #endif
                    413:        setdfltcmd();
                    414: #ifdef CLEAREOL
                    415:        if (erase_screen && can_home_clear)     /* PWP was here */
                    416:            clear_rest();
                    417: #endif CLEAREOL
                    418:        unflush_output();               /* disable any ^O in effect */
                    419:        standout();                     /* enter standout mode */
                    420:        printf(prompt,mailcall,dfltcmd);/* print prompt, whatever it is */
                    421:        un_standout();                  /* leave standout mode */
                    422:        putchar(' ');
                    423:        fflush(stdout);
                    424: reinp_article:
                    425:        eat_typeahead();
                    426: #ifdef PENDING
                    427:        look_ahead();                   /* see what we can do in advance */
                    428:        if (!input_pending())
                    429:            collect_subjects();         /* loads subject cache until */
                    430:                                        /* input is pending */
                    431: #endif
                    432:        getcmd(buf);
                    433:        if (errno || *buf == '\f') {
                    434:            if (LINES < 100 && !int_count)
                    435:                *buf = '\f';            /* on CONT fake up refresh */
                    436:            else {
                    437:                putchar('\n') FLUSH;            /* but only on a crt */
                    438:                goto reask_article;
                    439:            }
                    440:        }
                    441: article_level:
                    442: 
                    443:        /* parse and process article level command */
                    444: 
                    445:        switch (art_switch()) {
                    446:        case AS_INP:                    /* multichar command rubbed out */
                    447:            goto reinp_article;
                    448:        case AS_ASK:                    /* reprompt "End of article..." */
                    449:            goto reask_article;
                    450:        case AS_CLEAN:                  /* exit newsgroup */
                    451:            goto cleanup;
                    452:        case AS_NORM:                   /* display article art */
                    453:            break;
                    454:        }
                    455:     }                                  /* end of article selection loop */
                    456:     
                    457: /* shut down newsgroup */
                    458: 
                    459: cleanup:
                    460: #ifdef KILLFILES
                    461:     kill_unwanted(firstart,"\nCleaning up...\n\n",FALSE);
                    462:                                        /* do cleanup from KILL file, if any */
                    463: #endif
                    464:     in_ng = FALSE;                     /* leave newsgroup state */
                    465:     if (artfp != Nullfp) {             /* article still open? */
                    466:        fclose(artfp);                  /* close it */
                    467:        artfp = Nullfp;                 /* and tell the world */
                    468: #ifdef SERVER
                    469:        sprintf(artname, "/tmp/rrn%ld.%ld", (long) openart, our_pid);
                    470:        UNLINK(artname);
                    471: #endif
                    472:        openart = 0;
                    473:     }
                    474:     putchar('\n') FLUSH;
                    475:     yankback();                                /* do a Y command */
                    476:     restore_ng();                      /* reconstitute .newsrc line */
                    477:     doing_ng = FALSE;                  /* tell sig_catcher to cool it */
                    478:     free(ctlarea);                     /* return the control area */
                    479: #ifdef CACHESUBJ
                    480:     if (subj_list) {
                    481:        for (i=OFFSET(lastart); i>=0; --i)
                    482:            if (subj_list[i])
                    483:                free(subj_list[i]);
                    484: #ifndef lint
                    485:        free((char*)subj_list);
                    486: #endif lint
                    487:     }
                    488: #endif
                    489:     write_rc();                                /* and update .newsrc */
                    490:     rc_changed = FALSE;                        /* tell sig_catcher it is ok */
                    491:     if (chdir(spool)) {
                    492:        printf(nocd,spool) FLUSH;
                    493:        sig_catcher(0);
                    494:     }
                    495: #ifdef KILLFILES
                    496:     if (localkfp) {
                    497:        fclose(localkfp);
                    498:        localkfp = Nullfp;
                    499:     }
                    500: #endif
                    501:     mode = oldmode;
                    502:     return exit_code;
                    503: }                                      /* Whew! */
                    504: 
                    505: /* decide what to do at the end of an article */
                    506: 
                    507: int
                    508: art_switch()
                    509: {
                    510:     register ART_NUM i;
                    511:       
                    512:     setdef(buf,dfltcmd);
                    513: #ifdef VERIFY
                    514:     printcmd();
                    515: #endif
                    516:     switch (*buf) {
                    517:     case 'p':                  /* find previous unread article */
                    518:        do {
                    519:            if (art <= firstart)
                    520:                break;
                    521:            art--;
                    522:        } while (was_read(art) || artopen(art) == Nullfp);
                    523: #ifdef ARTSEARCH
                    524:        srchahead = 0;
                    525: #endif
                    526:        return AS_NORM;
                    527:     case 'P':                  /* goto previous article */
                    528:        if (art > absfirst)
                    529:            art--;
                    530:        else {
                    531: #ifdef VERBOSE
                    532:            IF(verbose)
                    533:                fputs("\n\
                    534: There are no articles prior to this one.\n\
                    535: ",stdout) FLUSH;
                    536:            ELSE
                    537: #endif
                    538: #ifdef TERSE
                    539:                fputs("\nNo previous articles\n",stdout) FLUSH;
                    540: #endif
                    541:            return AS_ASK;
                    542:        }
                    543:        reread = TRUE;
                    544: #ifdef ARTSEARCH
                    545:        srchahead = 0;
                    546: #endif
                    547:        return AS_NORM;
                    548:     case '-':
                    549:        if (recent_art) {
                    550:            art = recent_art;
                    551:            reread = TRUE;
                    552: #ifdef ARTSEARCH
                    553:            srchahead = -(srchahead != 0);
                    554: #endif
                    555:            return AS_NORM;
                    556:        }
                    557:        else {
                    558:            exit_code = NG_MINUS;
                    559:            return AS_CLEAN;
                    560:        }
                    561:     case 'n':          /* find next unread article? */
                    562:        if (art > lastart) {
                    563:            if (toread[ng])
                    564:                art = firstart;
                    565:            else
                    566:                return AS_CLEAN;
                    567:        }
                    568: #ifdef ARTSEARCH
                    569:        else if (scanon && srchahead) {
                    570:            *buf = Ctl('n');
                    571:            goto normal_search;
                    572:        }
                    573: #endif
                    574:        else
                    575:            art++;
                    576: #ifdef ARTSEARCH
                    577:        srchahead = 0;
                    578: #endif
                    579:        return AS_NORM;
                    580:     case 'N':                  /* goto next article */
                    581:        if (art > lastart)
                    582:            art = absfirst;
                    583:        else
                    584:            art++;
                    585:        if (art <= lastart)
                    586:            reread = TRUE;
                    587: #ifdef ARTSEARCH
                    588:        srchahead = 0;
                    589: #endif
                    590:        return AS_NORM;
                    591:     case '$':
                    592:        art = lastart+1;
                    593:        forcelast = TRUE;
                    594: #ifdef ARTSEARCH
                    595:        srchahead = 0;
                    596: #endif
                    597:        return AS_NORM;
                    598:     case '1': case '2': case '3':      /* goto specified article */
                    599:     case '4': case '5': case '6':      /* or do something with a range */
                    600:     case '7': case '8': case '9': case '.':
                    601:        forcelast = TRUE;
                    602:        switch (numnum()) {
                    603:        case NN_INP:
                    604:            return AS_INP;
                    605:        case NN_ASK:
                    606:            return AS_ASK;
                    607:        case NN_REREAD:
                    608:            reread = TRUE;
                    609: #ifdef ARTSEARCH
                    610:            if (srchahead)
                    611:                srchahead = -1;
                    612: #endif
                    613:            break;
                    614:        case NN_NORM:
                    615:            if (was_read(art)) {
                    616:                art = firstart;
                    617:                pad(just_a_sec/3);
                    618:            }
                    619:            else
                    620:                return AS_ASK;
                    621:            break;
                    622:        }
                    623:        return AS_NORM;
                    624:     case Ctl('k'):
                    625:        edit_kfile();
                    626:        return AS_ASK;
                    627:     case 'K':
                    628:     case 'k':
                    629:     case Ctl('n'): case Ctl('p'):
                    630:     case '/': case '?':
                    631: #ifdef ARTSEARCH
                    632: normal_search:
                    633:     {          /* search for article by pattern */
                    634:        char cmd = *buf;
                    635:        
                    636:        reread = TRUE;          /* assume this */
                    637:        switch (art_search(buf, (sizeof buf), TRUE)) {
                    638:        case SRCH_ERROR:
                    639:            return AS_ASK;
                    640:        case SRCH_ABORT:
                    641:            return AS_INP;
                    642:        case SRCH_INTR:
                    643: #ifdef VERBOSE
                    644:            IF(verbose)
                    645:                printf("\n(Interrupted at article %ld)\n",(long)art) FLUSH;
                    646:            ELSE
                    647: #endif
                    648: #ifdef TERSE
                    649:                printf("\n(Intr at %ld)\n",(long)art) FLUSH;
                    650: #endif
                    651:            art = curr_art;
                    652:                            /* restore to current article */
                    653:            return AS_ASK;
                    654:        case SRCH_DONE:
                    655:            fputs("done\n",stdout) FLUSH;
                    656:            pad(just_a_sec/3);  /* 1/3 second */
                    657:            if (srchahead)
                    658:                art = firstart;
                    659:            else
                    660:                art = curr_art;
                    661:            reread = FALSE;
                    662:            return AS_NORM;
                    663:        case SRCH_SUBJDONE:
                    664: #ifdef UNDEF
                    665:            fputs("\n\n\n\nSubject not found.\n",stdout) FLUSH;
                    666:            pad(just_a_sec/3);  /* 1/3 second */
                    667: #endif
                    668:            art = firstart;
                    669:            reread = FALSE;
                    670:            return AS_NORM;
                    671:        case SRCH_NOTFOUND:
                    672:            fputs("\n\n\n\nNot found.\n",stdout) FLUSH;
                    673:            art = curr_art;  /* restore to current article */
                    674:            return AS_ASK;
                    675:        case SRCH_FOUND:
                    676:            if (cmd == Ctl('n') || cmd == Ctl('p'))
                    677:                oldsubject = TRUE;
                    678:            break;
                    679:        }
                    680:        return AS_NORM;
                    681:     }
                    682: #else
                    683:     buf[1] = '\0';
                    684:     notincl(buf);
                    685:     return AS_ASK;
                    686: #endif
                    687:     case 'u':                  /* unsubscribe from this newsgroup? */
                    688:        rcchar[ng] = NEGCHAR;
                    689:        return AS_CLEAN;
                    690:     case 'M':
                    691: #ifdef DELAYMARK
                    692:        if (art <= lastart) {
                    693:            delay_unmark(art);
                    694:            printf("\nArticle %ld will return.\n",(long)art) FLUSH;
                    695:        }
                    696: #else
                    697:        notincl("M");
                    698: #endif
                    699:        return AS_ASK;
                    700:     case 'm':
                    701:        if (art <= lastart) {
                    702:            unmark_as_read(art);
                    703:            printf("\nArticle %ld marked as still unread.\n",(long)art) FLUSH;
                    704:        }
                    705:        return AS_ASK;
                    706:     case 'c':                  /* catch up */
                    707:       reask_catchup:
                    708: #ifdef VERBOSE
                    709:        IF(verbose)
                    710:            in_char("\nDo you really want to mark everything as read? [yn] ");
                    711:        ELSE
                    712: #endif
                    713: #ifdef TERSE
                    714:            in_char("\nReally? [ynh] ");
                    715: #endif
                    716:        putchar('\n') FLUSH;
                    717:        setdef(buf,"y");
                    718: #ifdef VERIFY
                    719:        printcmd();
                    720: #endif
                    721:        if (*buf == 'h') {
                    722: #ifdef VERBOSE
                    723:            IF(verbose)
                    724:                fputs("\
                    725: Type y or SP to mark all articles as read.\n\
                    726: Type n to leave articles marked as they are.\n\
                    727: Type u to mark everything read and unsubscribe.\n\
                    728: ",stdout) FLUSH;
                    729:            ELSE
                    730: #endif
                    731: #ifdef TERSE
                    732:                fputs("\
                    733: y or SP to mark all read.\n\
                    734: n to forget it.\n\
                    735: u to mark all and unsubscribe.\n\
                    736: ",stdout) FLUSH;
                    737: #endif
                    738:            goto reask_catchup;
                    739:        }
                    740:        else if (*buf == 'n' || *buf == 'q') {
                    741:            return AS_ASK;
                    742:        }
                    743:        else if (*buf != 'y' && *buf != 'u') {
                    744:            fputs(hforhelp,stdout) FLUSH;
                    745:            settle_down();
                    746:            goto reask_catchup;
                    747:        }
                    748:        for (i = firstart; i <= lastart; i++) {
                    749:            ctl_set(i);         /* mark as read */
                    750:        }
                    751: #ifdef DELAYMARK
                    752:        if (dmfp)
                    753:            yankback();
                    754: #endif
                    755:        if (*buf == 'u') {
                    756:            rcchar[ng] = NEGCHAR;
                    757:            return AS_CLEAN;
                    758:        }
                    759:        art = lastart+1;
                    760:        forcelast = FALSE;
                    761:        return AS_NORM;
                    762:     case 'Q':
                    763:        exit_code = NG_ASK;
                    764:        /* FALL THROUGH */
                    765:     case 'q':                  /* go back up to newsgroup level? */
                    766:        return AS_CLEAN;
                    767:     case 'j':
                    768:        putchar('\n') FLUSH;
                    769:        if (art <= lastart)
                    770:            mark_as_read(art);
                    771:        return AS_ASK;
                    772:     case 'h': {                        /* help? */
                    773:        int cmd;
                    774: 
                    775:        if ((cmd = help_art()) > 0)
                    776:            pushchar(cmd);
                    777:        return AS_ASK;
                    778:     }
                    779:     case '&':
                    780:        if (switcheroo()) /* get rest of command */
                    781:            return AS_INP;      /* if rubbed out, try something else */
                    782:        return AS_ASK;
                    783:     case '#':
                    784: #ifdef VERBOSE
                    785:        IF(verbose)
                    786:            printf("\nThe last article is %ld.\n",(long)lastart) FLUSH;
                    787:        ELSE
                    788: #endif
                    789: #ifdef TERSE
                    790:            printf("\n%ld\n",(long)lastart) FLUSH;
                    791: #endif
                    792:        return AS_ASK;
                    793:     case '=': {
                    794:        char tmpbuf[256];
                    795:        ART_NUM oldart = art;
                    796:        int cmd;
                    797:        char *subjline = getval("SUBJLINE",Nullch);
                    798: #ifndef CACHESUBJ
                    799:        char *s;
                    800: #endif
                    801:        
                    802:        page_init();
                    803: #ifdef CACHESUBJ
                    804:        if (!subj_list)
                    805:            fetchsubj(art,TRUE,FALSE);
                    806: #endif
                    807:        for (i=firstart; i<=lastart && !int_count; i++) {
                    808: #ifdef CACHESUBJ
                    809:            if (!was_read(i) &&
                    810:              (subj_list[OFFSET(i)] != Nullch || fetchsubj(i,FALSE,FALSE)) &&
                    811:              *subj_list[OFFSET(i)] ) {
                    812:                sprintf(tmpbuf,"%5ld ", i);
                    813:                if (subjline) {
                    814:                    art = i;
                    815:                    interp(tmpbuf + 6, (sizeof tmpbuf) - 6, subjline);
                    816:                }
                    817:                else
                    818:                    safecpy(tmpbuf + 6, subj_list[OFFSET(i)],
                    819:                        (sizeof tmpbuf) - 6);
                    820:                if (cmd = print_lines(tmpbuf,NOMARKING)) {
                    821:                    if (cmd > 0)
                    822:                        pushchar(cmd);
                    823:                    break;
                    824:                }
                    825:            }
                    826: #else
                    827:            if (!was_read(i) && (s = fetchsubj(i,FALSE,FALSE)) && *s) {
                    828:                sprintf(tmpbuf,"%5ld ", i);
                    829:                if (subjline) { /* probably fetches it again! */
                    830:                    art = i;
                    831:                    interp(tmpbuf + 6, (sizeof tmpbuf) - 6, subjline);
                    832:                }
                    833:                else
                    834:                    safecpy(tmpbuf + 6, s, (sizeof tmpbuf) - 6);
                    835:                if (cmd = print_lines(tmpbuf,NOMARKING)) {
                    836:                    if (cmd > 0)
                    837:                        pushchar(cmd);
                    838:                    break;
                    839:                }
                    840:            }
                    841: #endif
                    842:        }
                    843:        int_count = 0;
                    844:        art = oldart;
                    845:        return AS_ASK;
                    846:     }
                    847:     case '^':
                    848:        art = firstart;
                    849: #ifdef ARTSEARCH
                    850:        srchahead = 0;
                    851: #endif
                    852:        return AS_NORM;
                    853: #if defined(CACHESUBJ) && defined(DEBUGGING)
                    854:     case 'D':
                    855:        printf("\nFirst article: %ld\n",(long)firstart) FLUSH;
                    856:        if (!subj_list)
                    857:            fetchsubj(art,TRUE,FALSE);
                    858:        if (subj_list != Null(char **)) {
                    859:            for (i=1; i<=lastart && !int_count; i++) {
                    860:                if (subj_list[OFFSET(i)])
                    861:                    printf("%5ld %c %s\n",
                    862:                        i, (was_read(i)?'y':'n'), subj_list[OFFSET(i)]) FLUSH;
                    863:            }
                    864:        }
                    865:        int_count = 0;
                    866:        return AS_ASK;
                    867: #endif
                    868:     case 'v':
                    869:        if (art <= lastart) {
                    870:            reread = TRUE;
                    871:            do_hiding = FALSE;
                    872:        }
                    873:        return AS_NORM;
                    874: #ifdef ROTATION
                    875:     case Ctl('x'):
                    876: #endif
                    877:     case Ctl('r'):
                    878: #ifdef ROTATION
                    879:        rotate = (*buf==Ctl('x'));
                    880: #endif
                    881:        if (art <= lastart)
                    882:            reread = TRUE;
                    883:        return AS_NORM;
                    884: #ifdef ROTATION
                    885:     case 'X':
                    886:        rotate = !rotate;
                    887:        /* FALL THROUGH */
                    888: #else
                    889:     case Ctl('x'):
                    890:     case 'x':
                    891:     case 'X':
                    892:        notincl("x");
                    893:        return AS_ASK;
                    894: #endif
                    895:     case 'l': case Ctl('l'):           /* refresh screen */
                    896:        if (art <= lastart) {
                    897:            reread = TRUE;
                    898:            clear();
                    899:            do_fseek = TRUE;
                    900:            artline = topline;
                    901:            if (artline < 0)
                    902:                artline = 0;
                    903:        }
                    904:        return AS_NORM;
                    905:     case 'b': case Ctl('b'):           /* back up a page */
                    906:        if (art <= lastart) {
                    907:            ART_LINE target;
                    908: 
                    909:            reread = TRUE;
                    910:            clear();
                    911:            do_fseek = TRUE;
                    912:            target = topline - (LINES - 2);
                    913:            artline = topline;
                    914:            do {
                    915:                artline--;
                    916:            } while (artline >= 0 && artline > target &&
                    917:                vrdary(artline-1) >= 0);
                    918:            topline = artline;
                    919:            if (artline < 0)
                    920:                artline = 0;
                    921:        }
                    922:        return AS_NORM;
                    923:     case '!':                  /* shell escape */
                    924:        if (escapade())
                    925:            return AS_INP;
                    926:        return AS_ASK;
                    927:     case 'C': {
                    928:        cancel_article();
                    929:        return AS_ASK;
                    930:     }
                    931:     case 'R':
                    932:     case 'r': {                        /* reply? */
                    933:        reply();
                    934:        return AS_ASK;
                    935:     }
                    936:     case 'F':
                    937:     case 'f': {                        /* followup command */
                    938:        followup();
                    939:        forcegrow = TRUE;               /* recalculate lastart */
                    940:        return AS_ASK;
                    941:     }
                    942:     case '|':
                    943:     case 'w': case 'W':
                    944:     case 's': case 'S':                /* save command */
                    945:        if (save_article() == SAVE_ABORT)
                    946:            return AS_INP;
                    947:        return AS_ASK;
                    948: #ifdef DELAYMARK
                    949:     case 'Y':                          /* yank back M articles */
                    950:        yankback();
                    951:        art = firstart;                 /* from the beginning */
                    952:        return AS_NORM;                 /* pretend nothing happened */
                    953: #endif
                    954: #ifdef STRICTCR
                    955:     case '\n':
                    956:        fputs(badcr,stdout) FLUSH;
                    957:        return AS_ASK;
                    958: #endif
                    959:     default:
                    960:        printf("\n%s",hforhelp) FLUSH;
                    961:        settle_down();
                    962:        return AS_ASK;
                    963:     }
                    964: }
                    965: 
                    966: #ifdef MAILCALL
                    967: /* see if there is any mail */
                    968: 
                    969: void
                    970: setmail()
                    971: {
                    972:     if (! (mailcount++)) {
                    973:        char *mailfile = filexp(getval("MAILFILE",MAILFILE));
                    974:        
                    975:        if (stat(mailfile,&filestat) < 0 || !filestat.st_size
                    976:            || filestat.st_atime > filestat.st_mtime)
                    977:            mailcall = nullstr;
                    978:        else
                    979:            mailcall = "(Mail) ";
                    980:     }
                    981:     mailcount %= 10;                   /* check every 10 articles */
                    982: }
                    983: #endif
                    984: 
                    985: void
                    986: setdfltcmd()
                    987: {
                    988:     if (toread[ng]) {
                    989: #ifdef ARTSEARCH
                    990:        if (srchahead)
                    991:            dfltcmd = "^Nnpq";
                    992:        else
                    993: #endif
                    994:            dfltcmd = "npq";
                    995:     }
                    996:     else {
                    997:        if (art > lastart)
                    998:            dfltcmd = "qnp";
                    999:        else
                   1000:            dfltcmd = "npq";
                   1001:     }
                   1002: }
                   1003: 

unix.superglobalmegacorp.com

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