|
|
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: * funcs - functions used by many programs ! 16: */ ! 17: ! 18: #ifdef SCCSID ! 19: static char *SccsId = "@(#)funcs.c 2.36 10/7/87"; ! 20: #endif /* SCCSID */ ! 21: ! 22: /*LINTLIBRARY*/ ! 23: ! 24: #include "params.h" ! 25: #include <errno.h> ! 26: #if defined(USG) || defined(BSD4_2) || defined(BSD4_1C) ! 27: #include <fcntl.h> ! 28: #endif /* !v7 */ ! 29: ! 30: extern char *Progname; ! 31: ! 32: /* ! 33: * News group matching. ! 34: * ! 35: * nglist is a list of newsgroups. ! 36: * sublist is a list of subscriptions. ! 37: * sublist may have "meta newsgroups" in it. ! 38: * All fields are NGDELIM separated, ! 39: * and there is an NGDELIM at the end of each argument. ! 40: * ! 41: * Currently implemented glitches: ! 42: * sublist uses 'all' like shell uses '*', and '.' like shell '/'. ! 43: * If subscription X matches Y, it also matches Y.anything. ! 44: */ ! 45: ngmatch(nglist, sublist) ! 46: register char *nglist, *sublist; ! 47: { ! 48: register char *n, *s; ! 49: register int rc; ! 50: ! 51: rc = FALSE; ! 52: for (n = nglist; *n != '\0' && rc == FALSE;) { ! 53: for (s = sublist; *s != '\0';) { ! 54: if (*s != NEGCHAR) ! 55: rc = rc || ptrncmp(s, n); ! 56: else ! 57: rc = rc && !ptrncmp(s+1, n); ! 58: while (*s++ != NGDELIM && *s != '\0') ! 59: ; ! 60: } ! 61: while (*n++ != NGDELIM && *n != '\0') ! 62: ; ! 63: } ! 64: return rc; ! 65: } ! 66: ! 67: /* ! 68: * Compare two newsgroups for equality. ! 69: * The first one may be a "meta" newsgroup. ! 70: */ ! 71: ptrncmp(ng1, ng2) ! 72: register char *ng1, *ng2; ! 73: { ! 74: while (*ng1 != NGDELIM && *ng1 != '\0') { ! 75: if (ng1[0]=='a' && ng1[1]=='l' && ng1[2]=='l') { ! 76: ng1 += 3; ! 77: while (*ng2 != NGDELIM && *ng2 != '.' && *ng2 != '\0') ! 78: if (ptrncmp(ng1, ng2++)) ! 79: return(TRUE); ! 80: return ptrncmp(ng1, ng2); ! 81: } else if (*ng1++ != *ng2++) ! 82: return FALSE; ! 83: } ! 84: return *ng2 == '.' || *ng2 == NGDELIM || *ng2 == '\0'; ! 85: } ! 86: ! 87: /* ! 88: * Exec the shell. ! 89: * This version resets uid, gid, and umask. ! 90: * Called with fsubr(ushell, s, NULL) ! 91: */ ! 92: /* ARGSUSED */ ! 93: ushell(s, dummy) ! 94: char *s, *dummy; ! 95: { ! 96: (void) umask(savmask); ! 97: (void) setgid(gid); ! 98: (void) setuid(uid); ! 99: xshell(s); ! 100: } ! 101: ! 102: /* ! 103: * Exec the shell. ! 104: */ ! 105: ! 106: #ifdef lint ! 107: char **environ; ! 108: #else /* !lint */ ! 109: extern char **environ; ! 110: #endif /* !lint */ ! 111: ! 112: xshell(s) ! 113: char *s; ! 114: { ! 115: char *env[100], **envp; ! 116: char a[BUFLEN + 2]; ! 117: extern char filename[]; ! 118: /* set $A */ ! 119: (void) sprintf(a, "A=%s", filename); ! 120: env[0] = a; ! 121: for (envp = env + 1 ; *environ != NULL && envp < env + 98 ; environ++) ! 122: if ((*environ)[0] != 'A' || (*environ)[1] != '=') ! 123: *envp++ = *environ; ! 124: *envp = NULL; ! 125: ! 126: execle(SHELL, SHELL, "-c", s, (char *)0, env); ! 127: xerror("No shell!"); ! 128: } ! 129: ! 130: /* ! 131: * Fork and call a subroutine with two args. ! 132: * Return pid without waiting. ! 133: */ ! 134: fsubr(f, s1, s2) ! 135: int (*f)(); ! 136: char *s1, *s2; ! 137: { ! 138: register int pid; ! 139: ! 140: /* this may NOT be a vfork */ ! 141: while ((pid = fork()) == -1) ! 142: sleep((unsigned)1); ! 143: if (pid == 0) { ! 144: (*f)(s1, s2); ! 145: exit(0); ! 146: } ! 147: return pid; ! 148: } ! 149: ! 150: /* ! 151: * Wait on a child process. ! 152: */ ! 153: fwait(pid) ! 154: register int pid; ! 155: { ! 156: register int w; ! 157: int status; ! 158: int (*onhup)(), (*onint)(); ! 159: ! 160: onint = signal(SIGINT, SIG_IGN); ! 161: onhup = signal(SIGHUP, SIG_IGN); ! 162: while ((w = wait(&status)) != pid && w != -1) ! 163: ; ! 164: if (w == -1) ! 165: status = -1; ! 166: (void) signal(SIGINT, onint); ! 167: (void) signal(SIGHUP, onhup); ! 168: return status; ! 169: } ! 170: ! 171: /* ! 172: * Strip trailing newlines, blanks, and tabs from 's'. ! 173: * Return TRUE if newline was found, else FALSE. ! 174: */ ! 175: nstrip(s) ! 176: register char *s; ! 177: { ! 178: register char *p; ! 179: register int rc; ! 180: ! 181: rc = FALSE; ! 182: p = s; ! 183: while (*p) ! 184: if (*p++ == '\n') ! 185: rc = TRUE; ! 186: while (--p >= s && (*p == '\n' || *p == ' ' || *p == '\t')); ! 187: *++p = '\0'; ! 188: return rc; ! 189: } ! 190: ! 191: /* ! 192: * Local open routine. ! 193: */ ! 194: FILE * ! 195: xfopen(name, fmode) ! 196: register char *name, *fmode; ! 197: { ! 198: register FILE *fp; ! 199: char *fname; ! 200: extern int errno; ! 201: ! 202: if ((fp = fopen(name, fmode)) == NULL) { ! 203: #ifdef IHCC ! 204: /* ! 205: * IHCC users only see the "filename" that was in trouble, ! 206: * not the whole path. (for security!) ! 207: */ ! 208: fname = rindex(name, '/') + 1; ! 209: #else ! 210: fname = name; ! 211: #endif ! 212: xerror("Cannot open %s (%s): %s", fname, fmode, errmsg(errno)); ! 213: } ! 214: /* kludge for setuid not being honored for root */ ! 215: if ((uid == 0) && (duid != 0) && ((*fmode == 'a') || (*fmode == 'w'))) ! 216: (void) chown(name, duid, dgid); ! 217: return fp; ! 218: } ! 219: ! 220: char * ! 221: errmsg(code) ! 222: int code; ! 223: { ! 224: extern int sys_nerr; ! 225: extern char *sys_errlist[]; ! 226: static char ebuf[6+5+1]; ! 227: ! 228: if (code > sys_nerr) { ! 229: (void) sprintf(ebuf, "Error %d", code); ! 230: return ebuf; ! 231: } else ! 232: return sys_errlist[code]; ! 233: } ! 234: /* From UC Berkeley @(#)strcasecmp.c 1.3 (Berkeley) 8/3/87 */ ! 235: ! 236: /* ! 237: * This array is designed for mapping upper and lower case letter ! 238: * together for a case independent comparison. The mappings are ! 239: * based upon ascii character sequences. ! 240: */ ! 241: char charmap[] = { ! 242: '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', ! 243: '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', ! 244: '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', ! 245: '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', ! 246: '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', ! 247: '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', ! 248: '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', ! 249: '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', ! 250: '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', ! 251: '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', ! 252: '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', ! 253: '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', ! 254: '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', ! 255: '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', ! 256: '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', ! 257: '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', ! 258: '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', ! 259: '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', ! 260: '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', ! 261: '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', ! 262: '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', ! 263: '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', ! 264: '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', ! 265: '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', ! 266: '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347', ! 267: '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', ! 268: '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', ! 269: '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337', ! 270: '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', ! 271: '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', ! 272: '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', ! 273: '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', ! 274: }; ! 275: ! 276: strcasecmp(s1, s2) ! 277: register char *s1, *s2; ! 278: { ! 279: register char *cm = charmap; ! 280: ! 281: while (cm[*s1] == cm[*s2++]) ! 282: if (*s1++ == '\0') ! 283: return 0; ! 284: return cm[*s1] - cm[*--s2]; ! 285: } ! 286: ! 287: strncasecmp(s1, s2, n) ! 288: register char *s1, *s2; ! 289: register int n; ! 290: { ! 291: register char *cm = charmap; ! 292: ! 293: while (--n >= 0 && cm[*s1] == cm[*s2++]) ! 294: if (*s1++ == '\0') ! 295: return 0; ! 296: return n < 0 ? 0 : cm[*s1] - cm[*--s2]; ! 297: } ! 298: ! 299: prefix(full, pref) ! 300: register char *full, *pref; ! 301: { ! 302: register char *cm = charmap; ! 303: ! 304: while (*pref != '\0') { ! 305: if (cm[*full++] != cm[*pref++]) ! 306: return FALSE; ! 307: } ! 308: return TRUE; ! 309: } ! 310: ! 311: char * ! 312: dirname(ngname) ! 313: char *ngname; ! 314: { ! 315: static char rbuf[BUFLEN]; ! 316: register char *p; ! 317: ! 318: (void) sprintf(rbuf, "%s/%s", SPOOL, ngname); ! 319: ! 320: for (p=rbuf+strlen(SPOOL); *p; p++) ! 321: if (*p == '.') ! 322: *p = '/'; ! 323: return rbuf; ! 324: } ! 325: ! 326: /* ! 327: * Return TRUE iff ngname is a valid newsgroup name ! 328: */ ! 329: validng(ngname) ! 330: char *ngname; ! 331: { ! 332: register FILE *fp; ! 333: register char *p, *q; ! 334: char abuf[BUFLEN]; ! 335: ! 336: fp = xfopen(ACTIVE, "r"); ! 337: while(fgets(abuf, BUFLEN, fp) != NULL) { ! 338: p = abuf; ! 339: q = ngname; ! 340: while (*p++ == *q++) ! 341: ; ! 342: if (*--q == '\0' && *--p == ' ') { ! 343: (void) fclose(fp); ! 344: return TRUE; ! 345: } ! 346: } ! 347: (void) fclose(fp); ! 348: return FALSE; ! 349: } ! 350: ! 351: /* VARARGS1 */ ! 352: xerror(message, arg1, arg2, arg3) ! 353: char *message; ! 354: long arg1, arg2, arg3; ! 355: { ! 356: char buffer[LBUFLEN]; ! 357: ! 358: fflush(stdout); ! 359: (void) sprintf(buffer, message, arg1, arg2, arg3); ! 360: logerr(buffer); ! 361: xxit(1); ! 362: } ! 363: ! 364: /* VARARGS1 */ ! 365: log(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) ! 366: char *fmt; ! 367: long a1, a2, a3, a4, a5, a6, a7, a8, a9; ! 368: { ! 369: _dolog(0, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); ! 370: } ! 371: ! 372: /* VARARGS1 */ ! 373: logerr(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) ! 374: char *fmt; ! 375: long a1, a2, a3, a4, a5, a6, a7, a8, a9; ! 376: { ! 377: _dolog(1, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); ! 378: } ! 379: ! 380: char *lfsuffix[] = { ! 381: "log", ! 382: "errlog", ! 383: NULL, ! 384: }; ! 385: ! 386: /* ! 387: * Log the given message, with printf strings and parameters allowed, ! 388: * on the log file, if it can be written. The date and an attempt at ! 389: * figuring out the remote system name are also logged. ! 390: */ ! 391: /* VARARGS1 */ ! 392: _dolog(which, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) ! 393: char *fmt; ! 394: long a1, a2, a3, a4, a5, a6, a7, a8, a9; ! 395: { ! 396: FILE *logfile; ! 397: register char *p, *logtime; ! 398: int i; ! 399: char logfname[BUFLEN]; /* the log file */ ! 400: char rmtsys[BUFLEN]; ! 401: char msg[LBUFLEN]; ! 402: time_t t; ! 403: ! 404: (void) strcpy(rmtsys, header.path); ! 405: p = index(rmtsys, '!'); ! 406: if (p == NULL) ! 407: p = index(rmtsys, ':'); ! 408: if (p) ! 409: *p = 0; ! 410: else { ! 411: p = rindex(rmtsys, '@'); ! 412: if (p) ! 413: (void) strcpy(rmtsys, p+1); ! 414: else ! 415: (void) strcpy(rmtsys, "local"); ! 416: } ! 417: ! 418: (void) time(&t); ! 419: logtime = ctime(&t); ! 420: logtime[16] = 0; ! 421: logtime += 4; ! 422: ! 423: ! 424: (void) sprintf(msg, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); ! 425: ! 426: if (which) ! 427: fprintf(stderr,"%s: %s\n", Progname, msg); ! 428: ! 429: for (i=0; i<=which;i++) { ! 430: (void) sprintf(logfname, "%s/%s", LIB, lfsuffix[i]); ! 431: ! 432: if (access(logfname, 0) == 0 && (logfile = fopen(logfname, "a")) != NULL) { ! 433: #if defined(USG) || defined(BSD4_2) || defined(BSD4_1C) ! 434: int flags; ! 435: flags = fcntl(fileno(logfile), F_GETFL, 0); ! 436: (void) fcntl(fileno(logfile), F_SETFL, flags|O_APPEND); ! 437: #else /* v7 */ ! 438: (void) lseek(fileno(logfile), 0L, 2); ! 439: #endif /* v7 */ ! 440: if (i) ! 441: fprintf(logfile, "%s\t%s\t%s: %s\n", logtime, ! 442: header.ident[0] ? header.ident : username, Progname, msg); ! 443: else ! 444: fprintf(logfile, "%s\t%s\t%s\n", logtime, ! 445: rmtsys, msg); ! 446: (void) fclose(logfile); ! 447: } ! 448: } ! 449: } ! 450: #ifdef VMS ! 451: ! 452: /* ! 453: * vmslink allows simulation of file linking under VMS. ! 454: */ ! 455: vmslink(infile,outfile) ! 456: char *infile, *outfile; ! 457: { ! 458: FILE *fp; ! 459: ! 460: if (access(outfile,0) == 0) { ! 461: errno = EEXIST; ! 462: return -1; ! 463: } ! 464: ! 465: fp = fopen(outfile, "w"); ! 466: if (fp == NULL) { ! 467: errno = EACCES; ! 468: return -1; ! 469: } ! 470: ! 471: (void) fprintf(fp, "%s", infile); ! 472: (void) fclose(fp); ! 473: ! 474: return 0; ! 475: } ! 476: ! 477: /* ! 478: * vmsdelete deletes all revisions of a file. It attempts to ! 479: * appear as unlink(2) under conventional Unix in other respects. ! 480: */ ! 481: vmsdelete(file) ! 482: char *file; ! 483: { ! 484: int i; ! 485: ! 486: i = unlink(file); ! 487: if (i != 0) ! 488: return i; ! 489: ! 490: i = errno; ! 491: while (unlink(file) == 0) ! 492: ; ! 493: errno = i; ! 494: ! 495: return 0; ! 496: } ! 497: ! 498: /* ! 499: * Convert a Unix file to a VMS fixed record format file by ! 500: * executing the 'unixtovms' command. ! 501: */ ! 502: unixtovms(file) ! 503: char *file; ! 504: { ! 505: char buf[BUFLEN]; ! 506: sprintf(buf, "exec /etc/unixtovms %s", file); ! 507: return system(buf); ! 508: } ! 509: ! 510: /* ! 511: * Convert a VMS fixed record format file to a Unix file by ! 512: * executing the 'vmstounix' command. ! 513: */ ! 514: vmstounix(file) ! 515: char *file; ! 516: { ! 517: char buf[BUFLEN]; ! 518: sprintf(buf,"exec /etc/vmstounix %s", file); ! 519: return system(buf); ! 520: } ! 521: #endif /* VMS */ ! 522: ! 523: #if !defined(BSD4_2) && !defined(BSD4_1C) ! 524: /* ! 525: * make a directory. Also make sure that the directory is owned ! 526: * by the right userid ! 527: */ ! 528: mkdir(path, perm) ! 529: char *path; ! 530: int perm; ! 531: { ! 532: int pid, status; ! 533: #ifdef USG ! 534: char parent[200]; ! 535: char *p; ! 536: struct stat sbuf; ! 537: ! 538: /* ! 539: * Make parent directory writable, because we will ! 540: * be creating a directory owned by the real user, ! 541: * rather than by news. ! 542: */ ! 543: (void) strcpy(parent, path); ! 544: if (p = rindex(parent, '/')) { ! 545: *p = '\0'; ! 546: if (stat(parent, &sbuf) == 0) ! 547: (void) chmod(parent, 0777); ! 548: else ! 549: return -1; ! 550: } else ! 551: return -1; ! 552: #endif ! 553: ! 554: if (pid=vfork()) { ! 555: status = fwait(pid); ! 556: #if defined(USG) && !defined(CHEAP) ! 557: if (pid=vfork()) ! 558: (void) fwait(pid); ! 559: else { ! 560: setgid(gid); ! 561: setuid(uid); ! 562: if (chown(path, duid, dgid) == 0) ! 563: (void) chmod(path, perm&(~N_UMASK)); ! 564: _exit(0); ! 565: } ! 566: #endif /* USG && !CHEAP */ ! 567: } else { ! 568: (void) setgid(dgid); ! 569: if (setuid(duid) < 0) ! 570: (void) umask(0); ! 571: else ! 572: (void) umask(perm&N_UMASK); ! 573: (void) execlp("mkdir", "mkdir", path, (char *)NULL); ! 574: perror(path); ! 575: _exit(1); ! 576: } ! 577: #ifdef USG ! 578: (void) chmod(parent, sbuf.st_mode); /* Restore mode of parent */ ! 579: #endif ! 580: return status; ! 581: } ! 582: #endif /* !BSD4_2 && ! BSD4_1C */ ! 583: #ifndef USG ! 584: char * ! 585: strpbrk(str, chars) ! 586: register char *str, *chars; ! 587: { ! 588: register char *cp; ! 589: ! 590: do { ! 591: cp = chars - 1; ! 592: while (*++cp) { ! 593: if (*str == *cp) ! 594: return str; ! 595: } ! 596: } while (*str++); ! 597: return NULL; ! 598: } ! 599: #endif /* !USG */ ! 600: ! 601: #ifdef FASCIST ! 602: /* ! 603: * This routine checks to see if the posting user is allowed to ! 604: * post to the given newsgroup. If the username is not in the file ! 605: * $LIBDIR/authorized then the default in the symbol FASCIST is used. ! 606: * ! 607: * Format of the call: ! 608: * fascist(user, newgroups) ! 609: * ! 610: * Returns: ! 611: * FALSE, if authorized ! 612: * TRUE, if not ! 613: * ! 614: * Format of the file "authorized" is: ! 615: * user:allowed groups ! 616: * ! 617: * Example: ! 618: * root:net.all,mod.all ! 619: * naughty_person:junk,net.politics ! 620: * operator:!net.all,general,test,mod.unix ! 621: * ! 622: * An open environment could have FASCIST set to "all" ! 623: * and then individual entries could be made in the authorized file ! 624: * to prevent certain individuals from posting to such a wide ! 625: * area. ! 626: * ! 627: * Note that a distribution of "all" does NOT mean to allow postings ! 628: * only to local groups -- "all" includes "all.all". ! 629: * Use "all,!all.all" to get this behavior ! 630: * ! 631: * Eugene Spafford spaf@gatech May 22, 1985 ! 632: */ ! 633: ! 634: fascist(user, newsgroups) ! 635: register char *user, *newsgroups; ! 636: { ! 637: FILE *facfd; ! 638: char facuser[BUFLEN], facgroups[BUFLEN], factemp[BUFLEN]; ! 639: register char *facptr; ! 640: ! 641: /* First, open the necessary file...$LIBDIR/authorized and see if there ! 642: * is an entry for this user ! 643: */ ! 644: ! 645: (void) strncpy(facgroups, FASCIST, BUFLEN); ! 646: sprintf(factemp, "%s/%s", LIB, "authorized"); ! 647: facfd = fopen(factemp, "r"); ! 648: ! 649: if (facfd != NULL) { /* If no such file, we go with the global default */ ! 650: while (fscanf(facfd, "%[^:]:%s\n", facuser, factemp) != EOF) ! 651: { ! 652: if (feof(facfd)) ! 653: break; ! 654: if (strncmp(facuser, user, BUFLEN) == 0) { ! 655: (void) strcat(facgroups, ","); ! 656: (void) strcat(facgroups, factemp); ! 657: break; ! 658: } ! 659: } ! 660: fclose (facfd); ! 661: } ! 662: #ifdef DEBUG ! 663: fprintf(stderr, "facgroups = %s\n", facgroups); ! 664: fprintf(stderr, "newsgroups = %s\n", newsgroups); ! 665: #endif /* DEBUG */ ! 666: ! 667: /* We step through the newsgroups being posted to and check each against ! 668: * the restriction list. *ALL* posted groups must match the restriction ! 669: * list or we don't allow the posting. ! 670: */ ! 671: ! 672: while (*newsgroups != '\0') { ! 673: facptr = factemp; ! 674: while (*newsgroups != '\0' && *newsgroups != NGDELIM) ! 675: *facptr++ = *newsgroups++; ! 676: *facptr = '\0'; ! 677: if (*newsgroups == NGDELIM) ! 678: newsgroups++; ! 679: ! 680: #ifdef DEBUG ! 681: fprintf(stderr, "Checking newsgroup '%s'\n", factemp); ! 682: #endif ! 683: ! 684: if (ngmatch(factemp, facgroups) == FALSE) ! 685: return TRUE; ! 686: } ! 687: ! 688: /* must be okay -- return */ ! 689: #ifdef DEBUG ! 690: fprintf (stderr, "Newsgroups approved for this poster.\n"); ! 691: #endif /* DEBUG */ ! 692: return FALSE; ! 693: } ! 694: #endif /* FASCIST */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.