Annotation of 43BSDTahoe/new/rn/ng.c, revision 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.