|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.