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

unix.superglobalmegacorp.com

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