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