|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)misc.c 1.20 (Berkeley) 10/15/87"; ! 3: #endif ! 4: ! 5: #include "../common/conf.h" ! 6: ! 7: #include "common.h" ! 8: ! 9: /* ! 10: * open_valid_art -- determine if a given article name is valid; ! 11: * if it is, return a file pointer to the open article, ! 12: * along with a unique id of the article. ! 13: * ! 14: * Parameters: "artname" is a string containing the ! 15: * name of the article. ! 16: * "id" is space for us to put the article ! 17: * id in. ! 18: * ! 19: * Returns: File pointer to the open article if the ! 20: * article is valid; NULL otherwise ! 21: * ! 22: * Side effects: None. ! 23: */ ! 24: ! 25: FILE * ! 26: open_valid_art(artname, id) ! 27: char *artname; ! 28: char *id; ! 29: { ! 30: static int crnt_art_num; ! 31: static char crnt_art_id[MAX_STRLEN]; ! 32: int fd; ! 33: struct stat statbuf; ! 34: ! 35: if (art_fp != NULL) { ! 36: if (crnt_art_num == atoi(artname)) { ! 37: if (fseek(art_fp, (long) 0, 0) < 0) ! 38: close_crnt(); ! 39: else { ! 40: (void) strcpy(id, crnt_art_id); ! 41: return (art_fp); ! 42: } ! 43: } else ! 44: close_crnt(); ! 45: } ! 46: ! 47: art_fp = fopen(artname, "r"); ! 48: ! 49: if (art_fp == NULL) ! 50: return (NULL); ! 51: ! 52: fd = fileno(art_fp); ! 53: ! 54: if (fstat(fd, &statbuf) < 0) { ! 55: close_crnt(); ! 56: return (NULL); ! 57: } ! 58: ! 59: if ((statbuf.st_mode & S_IFREG) != S_IFREG) { ! 60: close_crnt(); ! 61: return (NULL); ! 62: } ! 63: ! 64: get_id(art_fp, id); ! 65: (void) strcpy(crnt_art_id, id); ! 66: crnt_art_num = atoi(artname); ! 67: return (art_fp); ! 68: } ! 69: ! 70: ! 71: /* ! 72: * gethistent -- return the path name of an article if it's ! 73: * in the history file. ! 74: * ! 75: * Parameters: "msg_id" is the message ID of the ! 76: * article, enclosed in <>'s. ! 77: * ! 78: * Returns: A char pointer to a static data area ! 79: * containing the full pathname of the ! 80: * article, or NULL if the message-id is not ! 81: * in thef history file. ! 82: * ! 83: * Side effects: opens dbm database ! 84: * (only once, keeps it open after that). ! 85: * Converts "msg_id" to lower case. ! 86: */ ! 87: ! 88: char * ! 89: gethistent(msg_id) ! 90: char *msg_id; ! 91: { ! 92: char line[MAX_STRLEN]; ! 93: char *tmp; ! 94: register char *cp; ! 95: long ltmp; ! 96: static char path[MAX_STRLEN]; ! 97: #ifdef DBM ! 98: static int dbopen = 0; ! 99: datum fetch(); ! 100: #else ! 101: static DBM *db = NULL; /* History file, dbm version */ ! 102: #endif ! 103: static FILE *hfp = NULL; /* history file, text version */ ! 104: datum key, content; ! 105: ! 106: #ifdef DBM ! 107: if (!dbopen) { ! 108: if (dbminit(historyfile) < 0) { ! 109: #ifdef SYSLOG ! 110: syslog(LOG_ERR, "openartbyid: dbminit %s: %m", ! 111: historyfile); ! 112: #endif SYSLOG ! 113: return (NULL); ! 114: } else ! 115: dbopen = 1; ! 116: } ! 117: #else /* ndbm */ ! 118: if (db == NULL) { ! 119: db = dbm_open(historyfile, O_RDONLY, 0); ! 120: if (db == NULL) { ! 121: #ifdef SYSLOG ! 122: syslog(LOG_ERR, "openartbyid: dbm_open %s: %m", ! 123: historyfile); ! 124: #endif SYSLOG ! 125: return (NULL); ! 126: } ! 127: } ! 128: #endif DBM ! 129: ! 130: for (cp = msg_id; *cp != '\0'; ++cp) ! 131: if (isupper(*cp)) ! 132: *cp = tolower(*cp); ! 133: ! 134: key.dptr = msg_id; ! 135: key.dsize = strlen(msg_id) + 1; ! 136: ! 137: #ifdef DBM ! 138: content = fetch(key); ! 139: #else /* ndbm */ ! 140: content = dbm_fetch(db, key); ! 141: #endif DBM ! 142: if (content.dptr == NULL) ! 143: return (NULL); ! 144: ! 145: if (hfp == NULL) { ! 146: hfp = fopen(historyfile, "r"); ! 147: if (hfp == NULL) { ! 148: #ifdef SYSLOG ! 149: syslog(LOG_ERR, "message: fopen %s: %m", ! 150: historyfile); ! 151: #endif SYSLOG ! 152: return (NULL); ! 153: } ! 154: } ! 155: ! 156: bcopy(content.dptr, (char *)<mp, sizeof (long)); ! 157: if (fseek(hfp, ltmp, 0) < 0) { ! 158: #ifdef SYSLOG ! 159: syslog(LOG_ERR, "message: fseek: %m"); ! 160: #endif SYSLOG ! 161: return (NULL); ! 162: } ! 163: ! 164: (void) fgets(line, sizeof(line), hfp); ! 165: if ((cp = index(line, '\n')) != NULL) ! 166: *cp = '\0'; ! 167: cp = index(line, '\t'); ! 168: if (cp != NULL) ! 169: cp = index(cp+1, '\t'); ! 170: if (cp == NULL) { ! 171: #ifdef SYSLOG ! 172: syslog(LOG_ERR, ! 173: "message: malformed line in history file at %ld bytes, id %s", ! 174: ltmp, msg_id); ! 175: #endif SYSLOG ! 176: return (NULL); ! 177: } ! 178: tmp = cp+1; ! 179: ! 180: if ((cp = index(tmp, ' ')) != NULL) ! 181: *cp = '\0'; ! 182: ! 183: while ((cp = index(tmp, '.')) != NULL) ! 184: *cp = '/'; ! 185: ! 186: (void) strcpy(path, spooldir); ! 187: (void) strcat(path, "/"); ! 188: (void) strcat(path, tmp); ! 189: ! 190: return (path); ! 191: } ! 192: ! 193: /* ! 194: * openartbyid -- open an article by message-id. ! 195: * ! 196: * Arguments: "msg_id" is the message-id of the article ! 197: * to open. ! 198: * ! 199: * Returns: File pointer to opened article, or NULL if ! 200: * the article was not in the history file or ! 201: * could not be opened. ! 202: * ! 203: * Side effects: Opens article. ! 204: */ ! 205: ! 206: FILE * ! 207: openartbyid(msg_id) ! 208: char *msg_id; ! 209: { ! 210: char *path; ! 211: ! 212: path = gethistent(msg_id); ! 213: if (path != NULL) ! 214: return (fopen(path, "r")); ! 215: else ! 216: return (NULL); ! 217: } ! 218: ! 219: ! 220: /* ! 221: * check_ngperm -- check to see if they're allowed to see this ! 222: * article by matching Newsgroups: and Distribution: line. ! 223: * ! 224: * Parameters: "fp" is the file pointer of this article. ! 225: * ! 226: * Returns: 0 if they're not allowed to see it. ! 227: * 1 if they are. ! 228: * ! 229: * Side effects: None. ! 230: */ ! 231: ! 232: check_ngperm(fp) ! 233: register FILE *fp; ! 234: { ! 235: char buf[MAX_STRLEN]; ! 236: register char *cp; ! 237: static char **ngarray; ! 238: int ngcount; ! 239: ! 240: if (ngpermcount == 0) ! 241: return (1); ! 242: ! 243: while (fgets(buf, sizeof (buf), fp) != NULL) { ! 244: if (buf[0] == '\n') /* End of header */ ! 245: break; ! 246: if (buf[0] != 'N' && buf[0] != 'n') ! 247: continue; ! 248: cp = index(buf, '\n'); ! 249: if (cp) ! 250: *cp = '\0'; ! 251: cp = index(buf, ':'); ! 252: if (cp == NULL) ! 253: continue; ! 254: *cp = '\0'; ! 255: if (streql(buf, "newsgroups")) { ! 256: ngcount = get_nglist(&ngarray, cp+2); ! 257: break; ! 258: } ! 259: } ! 260: ! 261: (void) rewind(fp); ! 262: ! 263: if (ngcount == 0) /* Either no newgroups or null entry */ ! 264: return (1); ! 265: ! 266: return (ngmatch(strneql, ALLBUT, ! 267: ngpermlist, ngpermcount, ngarray, ngcount)); ! 268: } ! 269: ! 270: ! 271: /* ! 272: * spew -- spew out the contents of a file to stdout, doing ! 273: * the necessary cr-lf additions at the end. Finish with ! 274: * a "." on a line by itself, and an fflush(stdout). ! 275: * ! 276: * Parameters: "how" tells what part of the file we ! 277: * want spewed: ! 278: * ARTICLE The entire thing. ! 279: * HEAD Just the first part. ! 280: * BODY Just the second part. ! 281: * "fp" is the open file to spew from. ! 282: * ! 283: * Returns: Nothing. ! 284: * ! 285: * Side effects: Changes current position in file. ! 286: */ ! 287: ! 288: spew(fp, how) ! 289: FILE *fp; ! 290: int how; ! 291: { ! 292: char line[MAX_STRLEN]; ! 293: register char *cp; ! 294: ! 295: #ifdef LOG ! 296: ++arts_acsd; ! 297: #endif ! 298: ! 299: if (how == STAT) { ! 300: (void) fflush(stdout); ! 301: return; ! 302: } ! 303: ! 304: while (fgets(line, sizeof(line)-6, fp) != NULL && *line != '\n') { ! 305: if (how == BODY) /* We need to skip this anyway */ ! 306: continue; ! 307: cp = index(line, '\n'); ! 308: if (cp != NULL) ! 309: *cp = '\0'; ! 310: if (*line == '.') ! 311: putchar('.'); ! 312: putline(line); ! 313: if (cp == NULL) { ! 314: for (;;) { ! 315: if ((fgets(line, sizeof(line)-6, fp) == NULL) ! 316: || (index(line, '\n') != NULL)) ! 317: break; ! 318: } ! 319: } ! 320: } ! 321: ! 322: if (how == HEAD) { ! 323: putchar('.'); ! 324: putchar('\r'); ! 325: putchar('\n'); ! 326: (void) fflush(stdout); ! 327: return; ! 328: } else if (how == ARTICLE) { ! 329: putchar('\r'); ! 330: putchar('\n'); ! 331: } ! 332: ! 333: while (fgets(line, sizeof(line)-6, fp) != NULL) { ! 334: cp = index(line, '\n'); ! 335: if (cp != NULL) ! 336: *cp = '\0'; ! 337: if (*line == '.') ! 338: putchar('.'); ! 339: putline(line); ! 340: ! 341: if (cp == NULL) { ! 342: for (;;) { ! 343: if ((fgets(line, sizeof(line)-6, fp) == NULL) ! 344: || (index(line, '\n') != NULL)) ! 345: break; ! 346: } ! 347: } ! 348: } ! 349: putchar('.'); ! 350: putchar('\r'); ! 351: putchar('\n'); ! 352: (void) fflush(stdout); ! 353: } ! 354: ! 355: ! 356: /* ! 357: * get_id -- get the message id of the current article. ! 358: * ! 359: * Parameters: "art_fp" is a pointer to the open file. ! 360: * "id" is space for the message ID. ! 361: * ! 362: * Returns: Nothing. ! 363: * ! 364: * Side effects: Seeks and rewinds on "art_fp". ! 365: * Changes space pointed to by "id". ! 366: */ ! 367: ! 368: get_id(art_fp, id) ! 369: register FILE *art_fp; ! 370: char *id; ! 371: { ! 372: char line[MAX_STRLEN]; ! 373: register char *cp; ! 374: ! 375: while (fgets(line, sizeof(line), art_fp) != NULL) { ! 376: if (*line == '\n') ! 377: break; ! 378: if (*line == 'M' || *line == 'm') { /* "Message-ID" */ ! 379: if ((cp = index(line, ' ')) != NULL) { ! 380: *cp = '\0'; ! 381: if (streql(line, "Message-ID:")) { ! 382: (void) strcpy(id, cp + 1); ! 383: if ((cp = index(id, '\n')) != NULL) ! 384: *cp = '\0'; ! 385: (void) rewind(art_fp); ! 386: return; ! 387: } ! 388: } ! 389: } ! 390: } ! 391: (void) rewind(art_fp); ! 392: (void) strcpy(id, "<0>"); ! 393: } ! 394: ! 395: ! 396: /* ! 397: * close_crnt -- close the current article file pointer, if it's ! 398: * open. ! 399: * ! 400: * Parameters: None. ! 401: * ! 402: * Returns: Nothing. ! 403: * ! 404: * Side effects: Closes "art_fp" if it's open; sets "art_fp" to NULL. ! 405: */ ! 406: ! 407: close_crnt() ! 408: { ! 409: if (art_fp != NULL) ! 410: (void) fclose(art_fp); ! 411: art_fp = NULL; ! 412: } ! 413: ! 414: ! 415: /* ! 416: * findart -- find an article number in the article array. ! 417: * ! 418: * Parameters: "artname" is a string containing ! 419: * the name of the article. ! 420: * ! 421: * Returns: An index into "art_array", ! 422: * or -1 if "artname" isn't in "art_array". ! 423: * ! 424: * Side effects: None. ! 425: * ! 426: * Improvement: Replace this linear search with a binary one. ! 427: */ ! 428: ! 429: findart(artname) ! 430: char *artname; ! 431: { ! 432: register int i, artnum; ! 433: ! 434: artnum = atoi(artname); ! 435: ! 436: for (i = 0; i < num_arts; ++i) ! 437: if (art_array[i] == artnum) ! 438: return(i); ! 439: ! 440: return (-1); ! 441: } ! 442: ! 443: ! 444: /* ! 445: * get_distlist -- return a nicely set up array of distribution groups ! 446: * along with a count, when given an NNTP-spec distribution list ! 447: * in the form <dist1,dist2,...,distn>. ! 448: * ! 449: * Parameters: "array" is storage for our array, ! 450: * set to point at some static data. ! 451: * "list" is the NNTP distribution list. ! 452: * ! 453: * Returns: Number of distributions found. ! 454: * -1 on error. ! 455: * ! 456: * Side effects: Changes static data area. ! 457: */ ! 458: ! 459: get_distlist(array, list) ! 460: char ***array; ! 461: char *list; ! 462: { ! 463: char *cp; ! 464: int distcount; ! 465: static char **dist_list = (char **) NULL; ! 466: ! 467: if (list[0] != '<') ! 468: return (-1); ! 469: ! 470: cp = index(list + 1, '>'); ! 471: if (cp != NULL) ! 472: *cp = '\0'; ! 473: else ! 474: return (-1); ! 475: ! 476: for (cp = list + 1; *cp != '\0'; ++cp) ! 477: if (*cp == ',') ! 478: *cp = ' '; ! 479: distcount = parsit(list + 1, &dist_list); ! 480: *array = dist_list; ! 481: return (distcount); ! 482: } ! 483: ! 484: ! 485: /* ! 486: * streql -- determine if two strings are equal, ignoring case. ! 487: * ! 488: * Parameters: "a" and "b" are the pointers ! 489: * to characters to be compared. ! 490: * ! 491: * Returns: 1 if the strings are equal, 0 otherwise. ! 492: * ! 493: * Side effects: None. ! 494: */ ! 495: ! 496: streql(a, b) ! 497: register char *a, *b; ! 498: { ! 499: char lower(); ! 500: ! 501: while (lower(*a) == lower(*b)) { ! 502: if (*a == '\0') ! 503: return (1); ! 504: a++; ! 505: b++; ! 506: } ! 507: return (0); ! 508: } ! 509: ! 510: ! 511: /* ! 512: * lower -- convert a character to lower case, if it's upper case. ! 513: * ! 514: * Parameters: "c" is the character to be ! 515: * converted. ! 516: * ! 517: * Returns: "c" if the character is not ! 518: * upper case, otherwise the lower ! 519: * case eqivalent of "c". ! 520: * ! 521: * Side effects: None. ! 522: */ ! 523: ! 524: char lower(c) ! 525: register char c; ! 526: { ! 527: if (isascii(c) && isupper(c)) ! 528: c = c - 'A' + 'a'; ! 529: return (c); ! 530: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.