Annotation of 43BSD/contrib/news/src/checknews.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * This software is Copyright (c) 1986 by Rick Adams.
                      3:  *
                      4:  * Permission is hereby granted to copy, reproduce, redistribute or
                      5:  * otherwise use this software as long as: there is no monetary
                      6:  * profit gained specifically from the use or reproduction or this
                      7:  * software, it is not sold, rented, traded or otherwise marketed, and
                      8:  * this copyright notice is included prominently in any copy
                      9:  * made.
                     10:  *
                     11:  * The author make no claims as to the fitness or correctness of
                     12:  * this software for any use whatsoever, and it is provided as is. 
                     13:  * Any use of this software is at the user's own risk.
                     14:  *
                     15:  * checknews - news checking program
                     16:  */
                     17: 
                     18: #ifdef SCCSID
                     19: static char    *SccsId = "@(#)checknews.c      2.24    1/17/86";
                     20: #endif /* SCCSID */
                     21: 
                     22: char *Progname = "checknews";          /* used by xerror */
                     23: 
                     24: #include "params.h"
                     25: 
                     26: char   bfr[LBUFLEN];                   /* general-use scratch area     */
                     27: char   optbuf[BUFLEN];                 /* NEWSOPTS buffer              */
                     28: int    line = -1, y, e, n, q;
                     29: int    verbose;                        /* For debugging.               */
                     30: int    nflag;                          /* for spec. newsgroup          */
                     31: char   narggrp[BUFLEN];                /* spec newsgroup               */
                     32: FILE   *rcfp, *actfp;
                     33: char   newsrc[BUFLEN],*rcline[LINES],rcbuf[LBUFLEN],*argvrc[LINES];
                     34: struct hbuf header;
                     35: char   coptbuf[BUFLEN],datebuf[BUFLEN];
                     36: int    mode = 1;
                     37: #ifndef SHELL
                     38: char   *SHELL;
                     39: #endif
                     40: 
                     41: main(argc, argv)
                     42: int argc;
                     43: register char **argv;
                     44: {
                     45:        register char *ptr;     /* pointer to rest of buffer            */
                     46:        char *user, *home;
                     47:        struct passwd *pw;
                     48:        struct group *gp;
                     49:        int sflag = 0, optflag = FALSE, space = FALSE;
                     50:        int i;
                     51: 
                     52:        y = 0;
                     53:        n = 0;
                     54:        e = 0;
                     55:        q = 0;
                     56:        nflag = 0;
                     57:        pathinit();
                     58:        if (--argc > 0) {
                     59:                for (argv++; **argv; ++*argv) {
                     60:                        switch(**argv) {
                     61:                        case 'y':
                     62:                                y++;
                     63:                                break;
                     64:                        case 'q':
                     65:                                q++;
                     66:                                break;
                     67:                        case 'v':
                     68:                                verbose++;
                     69:                                break;
                     70:                        case 'n':
                     71:                                n++;
                     72:                                break;
                     73:                        case 'N':
                     74:                                nflag++;
                     75:                                strcpy(narggrp,argv[1]);
                     76:                                strcat(narggrp,",");
                     77:                                break;
                     78:                        case 'e':
                     79:                        case 'f':
                     80:                                e++;
                     81:                                break;
                     82:                        }
                     83:                }
                     84:        }
                     85:        if (!n && !e && !y && !q)
                     86:                y++;
                     87:        if (nflag)
                     88:                argv++;
                     89: 
                     90: #ifndef V6
                     91:        if ((user = getenv("USER")) == NULL)
                     92:                user = getenv("LOGNAME");
                     93:        if ((home = getenv("HOME")) == NULL)
                     94:                home = getenv("LOGDIR");
                     95:        if (user == NULL || home == NULL)
                     96:                getuser();
                     97:        else {
                     98:                username = AllocCpy(user);
                     99:                userhome = AllocCpy(home);
                    100:        }
                    101:        if (ptr = getenv("NEWSOPTS"))
                    102:                strcpy(rcbuf, ptr);
                    103:        else
                    104:                *rcbuf = '\0';
                    105:        if (*rcbuf) {
                    106:                strcat(rcbuf, " \1");
                    107:                ptr = rcbuf;
                    108:                while (*++ptr)
                    109:                        if (isspace(*ptr))
                    110:                                *ptr = '\0';
                    111:                for (ptr = rcbuf;; ptr++) {
                    112:                        if (!*ptr)
                    113:                                continue;
                    114:                        if (*ptr == '\1')
                    115:                                break;
                    116:                        if (++line > LINES)
                    117:                                xerror("Too many options.");
                    118:                        if ((rcline[line] = malloc(strlen(ptr) + 1)) == NULL)
                    119:                                xerror("Not enough memory.");
                    120:                        argvrc[line] = rcline[line];
                    121:                        strcpy(rcline[line], ptr);
                    122:                        while (*ptr)
                    123:                                ptr++;
                    124:                }
                    125:        }
                    126: #else
                    127:        getuser();
                    128: #endif
                    129:        ptr = getenv("NEWSRC");
                    130:        if (ptr == NULL)
                    131:                sprintf(newsrc, "%s/%s", userhome, NEWSRC);
                    132:        else
                    133:                strcpy(newsrc, ptr);
                    134:        if ((rcfp = fopen(newsrc, "r")) != NULL) {
                    135:                while (fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
                    136:                        if (!(space = isspace(*rcbuf)))
                    137:                                optflag = FALSE;
                    138:                        if (!strncmp(rcbuf, "options ", 8))
                    139:                                optflag = TRUE;
                    140:                        if (optflag) {
                    141:                                strcat(rcbuf, "\1");
                    142:                                if (space)
                    143:                                        ptr = rcbuf - 1;
                    144:                                else
                    145:                                        ptr = &rcbuf[7];
                    146:                                while (*++ptr)
                    147:                                        if (isspace(*ptr))
                    148:                                                *ptr = '\0';
                    149:                                if (space)
                    150:                                        ptr = rcbuf;
                    151:                                else
                    152:                                        ptr = &rcbuf[8];
                    153:                                for (;; ptr++) {
                    154:                                        if (!*ptr)
                    155:                                                continue;
                    156:                                        if (*ptr == '\1')
                    157:                                                break;
                    158:                                        if (++line > LINES)
                    159:                                                xerror("Too many options.");
                    160:                                        if ((rcline[line] = malloc(strlen(ptr) + 1)) == NULL)
                    161:                                                xerror("Not enough memory.");
                    162:                                        argvrc[line] = rcline[line];
                    163:                                        strcpy(rcline[line], ptr);
                    164:                                        while (*ptr)
                    165:                                                ptr++;
                    166:                                }
                    167:                        }
                    168:                }
                    169:                fclose(rcfp);
                    170:        }
                    171:        header.nbuf[0] = 0;
                    172:        if (line != -1) {
                    173: #ifdef DEBUG
                    174:                for (i = 0; i <= line; i++)
                    175:                        fprintf(stderr, "options:  %s\n", rcline[i]);
                    176: #endif
                    177:                process(line+2, argvrc);
                    178:                do {
                    179: #ifdef DEBUG
                    180:                        fprintf(stderr, "Freeing %d\n", line);
                    181: #endif
                    182:                        free(rcline[line]);
                    183:                } while (line--);
                    184:        }
                    185: 
                    186:        if (!*header.nbuf) {
                    187:                strcpy(header.nbuf, DFLTSUB);
                    188:                ngcat(header.nbuf);
                    189:        }
                    190:        strcat(header.nbuf, ADMSUB);
                    191:        ngcat(header.nbuf);
                    192:        if (*header.nbuf)
                    193:                lcase(header.nbuf);
                    194:        makehimask(header.nbuf, "junk");
                    195:        makehimask(header.nbuf, "control");
                    196:        makehimask(header.nbuf, "test");
                    197:        if (access(newsrc, 0)) {
                    198:                if (verbose > 1)
                    199:                        printf("No newsrc\n");
                    200:                yep(argv);
                    201:        }
                    202:        if ((rcfp = fopen(newsrc, "r")) == NULL)
                    203:                xerror("Cannot open .newsrc file");
                    204:        while (fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
                    205:                if (!nstrip(rcbuf))
                    206:                        xerror(".newsrc line too long");
                    207:                if (++line >= LINES)
                    208:                        xerror("Too many .newsrc lines");
                    209:                if ((rcline[line] = malloc(strlen(rcbuf)+1)) == NULL)
                    210:                        xerror("Not enough memory");
                    211:                strcpy(rcline[line], rcbuf);
                    212:        }
                    213:        if ((actfp = fopen(ACTIVE, "r")) == NULL)
                    214:                xerror("Cannot open active newsgroups file");
                    215: 
                    216: #ifdef DEBUG
                    217:        fprintf(stderr, "header.nbuf = %s\n", header.nbuf);
                    218: #endif
                    219:        nchk(argv);
                    220:        exit(0);
                    221: }
                    222: 
                    223: nchk(argv)
                    224: char **argv;
                    225: {
                    226:        register int i;
                    227:        register char *ptr;
                    228:        long l;
                    229:        long narts;
                    230:        char saveptr;
                    231:        char aline[100];
                    232: 
                    233: #ifdef DEBUG
                    234:        fprintf(stderr, "nchk()\n");
                    235: #endif
                    236:        while (fgets(aline, sizeof aline, actfp) != NULL) {
                    237:                sscanf(aline, "%s %ld", bfr, &narts);
                    238: #ifdef DEBUG
                    239:                fprintf(stderr, "bfr = '%s'\n", bfr);
                    240: #endif
                    241:                ngcat(bfr);
                    242:                if (!ngmatch(bfr, nflag ? narggrp : header.nbuf))
                    243:                        continue;
                    244:                ngdel(bfr);
                    245:                i = findrcline(bfr);
                    246:                if (i < 0) {
                    247:                        if (verbose>1)
                    248:                                printf("No newsrc line for newsgroup %s\n", bfr);
                    249:                        strcpy(rcbuf, " 0");
                    250:                } else
                    251:                        strcpy(rcbuf, rcline[i]);
                    252:                ptr = rcbuf;
                    253: 
                    254:                if (index(rcbuf, '!') != NULL)
                    255:                        continue;
                    256:                if (index(rcbuf, ',') != NULL) {
                    257:                        if (verbose > 1)
                    258:                                printf("Comma in %s newsrc line\n", bfr);
                    259:                        yep(argv);
                    260:                }
                    261:                while (*ptr)
                    262:                        ptr++;
                    263:                while (!isdigit(*--ptr) && *ptr != ':' && ptr >= rcbuf)
                    264:                        ;
                    265:                if (*ptr == ':')
                    266:                        continue;
                    267:                if (ptr < rcbuf) {
                    268:                        if (verbose > 1)
                    269:                                printf("Ran off beginning of %s newsrc line.\n", bfr);
                    270:                        yep(argv);
                    271:                }
                    272:                while (isdigit(*--ptr))
                    273:                        ;
                    274:                sscanf(++ptr, "%ld", &l);
                    275:                if (narts > l) {
                    276:                        if (verbose) {
                    277:                                printf("News: %s ...\n", bfr);
                    278:                                if (verbose < 2)
                    279:                                        y = 0;
                    280:                        }
                    281:                        yep(argv);
                    282:                }
                    283: contin:;
                    284:        }
                    285:        if (n)
                    286:                printf("No news is good news.\n");
                    287: }
                    288: 
                    289: yep(argv)
                    290: char **argv;
                    291: {
                    292:        if (y) {
                    293:                if (verbose)
                    294:                        printf("There is probably news");
                    295:                else
                    296:                        printf("There is news");
                    297:                if (nflag) {
                    298:                        narggrp[strlen(narggrp)-1] = '.';
                    299:                        printf(" in %s\n",narggrp);
                    300:                }
                    301:                else
                    302:                        printf(".\n");
                    303:        }
                    304:        if (e) {
                    305: #ifdef V6
                    306:                execv("/usr/bin/readnews", argv);
                    307: #else
                    308:                execvp("readnews", argv);
                    309: #endif
                    310:                perror("Cannot exec readnews.");
                    311:        }
                    312:        if (q)
                    313:                exit(1);
                    314:        else
                    315:                exit(0);
                    316: }
                    317: 
                    318: xerror(message, arg1, arg2)
                    319: char *message;
                    320: int arg1, arg2;
                    321: {
                    322:        char buffer[128];
                    323: 
                    324:        sprintf(buffer, message, arg1, arg2);
                    325:        fprintf(stderr, "checknews: %s.\n", buffer);
                    326:        exit(1);
                    327: }
                    328: 
                    329: /*
                    330:  * Append NGDELIM to string.
                    331:  */
                    332: ngcat(s)
                    333: register char *s;
                    334: {
                    335:        if (*s) {
                    336:                while (*s++);
                    337:                s -= 2;
                    338:                if (*s++ == NGDELIM)
                    339:                        return;
                    340:        }
                    341:        *s++ = NGDELIM;
                    342:        *s = '\0';
                    343: }
                    344: 
                    345: /*
                    346:  * News group matching.
                    347:  *
                    348:  * nglist is a list of newsgroups.
                    349:  * sublist is a list of subscriptions.
                    350:  * sublist may have "meta newsgroups" in it.
                    351:  * All fields are NGDELIM separated,
                    352:  * and there is an NGDELIM at the end of each argument.
                    353:  *
                    354:  * Currently implemented glitches:
                    355:  * sublist uses 'all' like shell uses '*', and '.' like shell '/'.
                    356:  * If subscription X matches Y, it also matches Y.anything.
                    357:  */
                    358: ngmatch(nglist, sublist)
                    359: register char *nglist, *sublist;
                    360: {
                    361:        register char *n, *s;
                    362:        register int rc;
                    363: 
                    364:        rc = FALSE;
                    365:        for (n = nglist; *n != '\0' && rc == FALSE;) {
                    366:                for (s = sublist; *s != '\0';) {
                    367:                        if (*s != NEGCHAR)
                    368:                                rc |= ptrncmp(s, n);
                    369:                        else
                    370:                                rc &= ~ptrncmp(s+1, n);
                    371:                        while (*s++ != NGDELIM);
                    372:                }
                    373:                while (*n++ != NGDELIM);
                    374:        }
                    375:        return(rc);
                    376: }
                    377: 
                    378: /*
                    379:  * Compare two newsgroups for equality.
                    380:  * The first one may be a "meta" newsgroup.
                    381:  */
                    382: ptrncmp(ng1, ng2)
                    383: register char *ng1, *ng2;
                    384: {
                    385:        while (*ng1 != NGDELIM) {
                    386:                if (ng1[0]=='a' && ng1[1]=='l' && ng1[2]=='l') {
                    387:                        ng1 += 3;
                    388:                        while (*ng2 != NGDELIM && *ng2 != '.')
                    389:                                if (ptrncmp(ng1, ng2++))
                    390:                                        return(TRUE);
                    391:                        return (ptrncmp(ng1, ng2));
                    392:                } else if (*ng1++ != *ng2++)
                    393:                        return(FALSE);
                    394:        }
                    395:        return (*ng2 == '.' || *ng2 == NGDELIM);
                    396: }
                    397: 
                    398: /*
                    399:  * Get user name and home directory.
                    400:  */
                    401: getuser()
                    402: {
                    403:        static int flag = TRUE;
                    404:        register struct passwd *p;
                    405: 
                    406:        if (flag) {
                    407:                if ((p = getpwuid(getuid())) == NULL)
                    408:                        xerror("Cannot get user's name");
                    409:                if (username == NULL || *username == '\0')
                    410:                        username = AllocCpy(p->pw_name);
                    411:                userhome = AllocCpy(p->pw_dir);
                    412:                flag = FALSE;
                    413:        }
                    414: }
                    415: 
                    416: /*
                    417:  * Strip trailing newlines, blanks, and tabs from 's'.
                    418:  * Return TRUE if newline was found, else FALSE.
                    419:  */
                    420: nstrip(s)
                    421: register char *s;
                    422: {
                    423:        register char *p;
                    424:        register int rc;
                    425: 
                    426:        rc = FALSE;
                    427:        p = s;
                    428:        while (*p)
                    429:                if (*p++ == '\n')
                    430:                        rc = TRUE;
                    431:        while (--p >= s && (*p == '\n' || *p == ' ' || *p == '\t'));
                    432:        *++p = '\0';
                    433:        return(rc);
                    434: }
                    435: 
                    436: /*
                    437:  * Delete trailing NGDELIM.
                    438:  */
                    439: ngdel(s)
                    440: register char *s;
                    441: {
                    442:        if (*s++) {
                    443:                while (*s++);
                    444:                s -= 2;
                    445:                if (*s == NGDELIM)
                    446:                        *s = '\0';
                    447:        }
                    448: }
                    449: 
                    450: lcase(s)
                    451: register char *s;
                    452: {
                    453:        register char *ptr;
                    454: 
                    455:        for (ptr = s; *ptr; ptr++)
                    456:                if (isupper(*ptr))
                    457:                        *ptr = tolower(*ptr);
                    458: }
                    459: 
                    460: /*
                    461:  * finds the line in your .newsrc file (actually the in-core "rcline"
                    462:  * copy of it) and returns the index into the array where it was found.
                    463:  * -1 means it didn't find it.
                    464:  *
                    465:  * We play clever games here to make this faster.  It's inherently
                    466:  * quadratic - we spend lots of CPU time here because we search through
                    467:  * the whole .newsrc for each line.  The "prev" variable remembers where
                    468:  * the last match was found; we start the search there and loop around
                    469:  * to the beginning, in the hopes that the calls will be roughly in order.
                    470:  */
                    471: int
                    472: findrcline(name)
                    473: char *name;
                    474: {
                    475:        register char *p, *ptr;
                    476:        register int cur;
                    477:        register int i;
                    478:        register int top;
                    479:        static int prev = 0;
                    480: 
                    481:        top = line; i = prev;
                    482: loop:
                    483:        for (; i <= top; i++) {
                    484:                for (p = name, ptr = rcline[i]; (cur = *p++); ) {
                    485:                        if (cur != *ptr++)
                    486:                                goto contin2;
                    487:                }
                    488:                if (*ptr != ':' && *ptr != '!')
                    489:                        continue;
                    490:                prev = i;
                    491:                return i;
                    492: contin2:
                    493:                ;
                    494:        }
                    495:        if (i > line && line > prev-1) {
                    496:                i = 0;
                    497:                top = prev-1;
                    498:                goto loop;
                    499:        }
                    500:        return -1;
                    501: }
                    502: 
                    503: /*
                    504:  * Forbid newsgroup ng, unless he asked for it in nbuf.
                    505:  */
                    506: makehimask(nbuf, ng)
                    507: char *nbuf, *ng;
                    508: {
                    509:        if (!findex(nbuf, ng)) {
                    510:                ngcat(nbuf);
                    511:                strcat(nbuf, "!");
                    512:                strcat(nbuf, ng);
                    513:                ngcat(nbuf);
                    514:        }
                    515: }
                    516: 
                    517: /*
                    518:  * Return true if the string searchfor is in string, but not if preceded by !.
                    519:  */
                    520: findex(string, searchfor)
                    521: char *string, *searchfor;
                    522: {
                    523:        register char first;
                    524:        register char *p;
                    525: 
                    526:        first = *searchfor;
                    527:        for (p=index(string, first); p; p = index(p+1, first)) {
                    528:                if (p>string && p[-1] != '!' && strncmp(p, searchfor, strlen(searchfor)) == 0)
                    529:                        return TRUE;
                    530:        }
                    531:        return FALSE;
                    532: }
                    533: 
                    534: xxit(i)
                    535: {
                    536:        exit(i);
                    537: }

unix.superglobalmegacorp.com

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