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: }

Defined functions

findex defined in line 520; used 1 times
findrcline defined in line 471; used 1 times
getuser defined in line 401; used 5 times
main defined in line 41; never used
makehimask defined in line 506; used 3 times
nchk defined in line 223; used 1 times
ngcat defined in line 332; used 5 times
ngdel defined in line 439; used 1 times
ngmatch defined in line 358; used 1 times
nstrip defined in line 420; used 1 times
ptrncmp defined in line 382; used 4 times
xerror defined in line 318; used 10 times
xxit defined in line 534; never used
yep defined in line 289; used 4 times

Defined variables

Progname defined in line 22; never used
SHELL defined in line 38; used 1 times
  • in line 37
SccsId defined in line 19; never used
argvrc defined in line 33; used 3 times
bfr defined in line 26; used 10 times
coptbuf defined in line 35; never used
datebuf defined in line 35; never used
header defined in line 34; used 13 times
line defined in line 28; used 22 times
mode defined in line 36; never used
narggrp defined in line 31; used 6 times
newsrc defined in line 33; used 5 times
nflag defined in line 30; used 5 times
optbuf defined in line 27; never used
rcbuf defined in line 33; used 25 times
rcline defined in line 33; used 12 times
verbose defined in line 29; used 8 times
Last modified: 1986-01-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2217
Valid CSS Valid XHTML 1.0 Strict