Annotation of researchv10dc/cmd/netnews/src/checknews.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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