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