Annotation of 43BSD/contrib/nntp/rrn/ng.c, revision 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.