1: #ifndef lint
   2: static char *sccsid = "@(#)misc.c	1.25	(Berkeley) 2/6/88";
   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[MAXBUFLEN];
  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: #ifndef NDBM
  89: # ifndef DBM
  90: #  ifndef USGHIST
  91: #   define USGHIST
  92: #  endif not USGHIST
  93: # endif not DBM
  94: #endif not DBM
  95: 
  96: char *
  97: gethistent(msg_id)
  98:     char        *msg_id;
  99: {
 100:     char        line[MAXBUFLEN];
 101:     char        *tmp;
 102:     register char   *cp;
 103:     long        ltmp;
 104:     static char path[MAXPATHLEN];
 105: #ifdef USGHIST
 106:     char        *histfile();
 107:     register int    len;
 108: #else not USGHIST
 109: #ifdef DBM
 110:     static int  dbopen = 0;
 111:     datum       fetch();
 112: #else not DBM
 113:     static DBM  *db = NULL; /* History file, dbm version */
 114: #endif DBM
 115:     datum        key, content;
 116: #endif USGHIST
 117:     static FILE *hfp = NULL;    /* history file, text version */
 118: 
 119:     for (cp = msg_id; *cp != '\0'; ++cp)
 120:         if (isupper(*cp))
 121:             *cp = tolower(*cp);
 122: 
 123: #ifdef USGHIST
 124:     hfp = fopen(histfile(msg_id), "r");
 125:     if (hfp == NULL) {
 126: #ifdef SYSLOG
 127:         syslog(LOG_ERR, "gethistent: histfile: %m");
 128: #endif SYSLOG
 129:         return (NULL);
 130:     }
 131: 
 132:     len = strlen(msg_id);
 133:     while (fgets(line, sizeof (line), hfp))
 134:         if (!strncasecmp(msg_id, line, len))
 135:             break;
 136: 
 137:     if (feof(hfp)) {
 138:         (void) fclose(hfp);
 139:         return (NULL);
 140:     }
 141: #else not USGHIST
 142: #ifdef DBM
 143:     if (!dbopen) {
 144:         if (dbminit(historyfile) < 0) {
 145: #ifdef SYSLOG
 146:             syslog(LOG_ERR, "openartbyid: dbminit %s: %m",
 147:                 historyfile);
 148: #endif SYSLOG
 149:             return (NULL);
 150:         } else
 151:             dbopen = 1;
 152:     }
 153: #else   /* ndbm */
 154:     if (db == NULL) {
 155:         db = dbm_open(historyfile, O_RDONLY, 0);
 156:         if (db == NULL) {
 157: #ifdef SYSLOG
 158:             syslog(LOG_ERR, "openartbyid: dbm_open %s: %m",
 159:                 historyfile);
 160: #endif SYSLOG
 161:             return (NULL);
 162:         }
 163:     }
 164: #endif DBM
 165: 
 166:     key.dptr = msg_id;
 167:     key.dsize = strlen(msg_id) + 1;
 168: 
 169: #ifdef DBM
 170:     content = fetch(key);
 171: #else   /* ndbm */
 172:     content = dbm_fetch(db, key);
 173: #endif DBM
 174:     if (content.dptr == NULL)
 175:         return (NULL);
 176: 
 177:     if (hfp == NULL) {
 178:         hfp = fopen(historyfile, "r");
 179:         if (hfp == NULL) {
 180: #ifdef SYSLOG
 181:             syslog(LOG_ERR, "message: fopen %s: %m",
 182:                 historyfile);
 183: #endif SYSLOG
 184:             return (NULL);
 185:         }
 186:     }
 187: 
 188:     bcopy(content.dptr, (char *)&ltmp, sizeof (long));
 189:     if (fseek(hfp, ltmp, 0) < 0) {
 190: #ifdef SYSLOG
 191:         syslog(LOG_ERR, "message: fseek: %m");
 192: #endif SYSLOG
 193:         return (NULL);
 194:     }
 195: 
 196:     (void) fgets(line, sizeof(line), hfp);
 197: #endif USGHIST
 198: 
 199:     if ((cp = index(line, '\n')) != NULL)
 200:         *cp = '\0';
 201:     cp = index(line, '\t');
 202:     if (cp != NULL)
 203:         cp = index(cp+1, '\t');
 204:     if (cp == NULL) {
 205: #ifdef SYSLOG
 206:         syslog(LOG_ERR,
 207:         "message: malformed line in history file at %ld bytes, id %s",
 208:             ltmp, msg_id);
 209: #endif SYSLOG
 210:         return (NULL);
 211:     }
 212:     tmp = cp+1;
 213: 
 214:     if ((cp = index(tmp, ' ')) != NULL)
 215:         *cp = '\0';
 216: 
 217:     while ((cp = index(tmp, '.')) != NULL)
 218:         *cp = '/';
 219: 
 220:     (void) strcpy(path, spooldir);
 221:     (void) strcat(path, "/");
 222:     (void) strcat(path, tmp);
 223: 
 224:     return (path);
 225: }
 226: 
 227: /*
 228:  * openartbyid -- open an article by message-id.
 229:  *
 230:  *	Arguments:	"msg_id" is the message-id of the article
 231:  *			to open.
 232:  *
 233:  *	Returns:	File pointer to opened article, or NULL if
 234:  *			the article was not in the history file or
 235:  *			could not be opened.
 236:  *
 237:  *	Side effects:	Opens article.
 238:  */
 239: 
 240: FILE *
 241: openartbyid(msg_id)
 242:     char    *msg_id;
 243: {
 244:     char    *path;
 245: 
 246:     path = gethistent(msg_id);
 247:     if (path != NULL)
 248:         return (fopen(path, "r"));
 249:     else
 250:         return (NULL);
 251: }
 252: 
 253: 
 254: /*
 255:  * check_ngperm -- check to see if they're allowed to see this
 256:  * article by matching Newsgroups: and Distribution: line.
 257:  *
 258:  *	Parameters:	"fp" is the file pointer of this article.
 259:  *
 260:  *	Returns:	0 if they're not allowed to see it.
 261:  *			1 if they are.
 262:  *
 263:  *	Side effects:	None.
 264:  */
 265: 
 266: check_ngperm(fp)
 267:     register FILE   *fp;
 268: {
 269:     char        buf[MAXBUFLEN];
 270:     register char   *cp;
 271:     static char **ngarray;
 272:     int     ngcount;
 273: 
 274:     if (ngpermcount == 0)
 275:         return (1);
 276: 
 277:     while (fgets(buf, sizeof (buf), fp) != NULL) {
 278:         if (buf[0] == '\n')     /* End of header */
 279:             break;
 280:         if (buf[0] != 'N' && buf[0] != 'n')
 281:             continue;
 282:         cp = index(buf, '\n');
 283:         if (cp)
 284:             *cp = '\0';
 285:         cp = index(buf, ':');
 286:         if (cp == NULL)
 287:             continue;
 288:         *cp = '\0';
 289:         if (!strcasecmp(buf, "newsgroups")) {
 290:             ngcount = get_nglist(&ngarray, cp+2);
 291:             break;
 292:         }
 293:     }
 294: 
 295:     (void) rewind(fp);
 296: 
 297:     if (ngcount == 0)   /* Either no newgroups or null entry */
 298:         return (1);
 299: 
 300:     return (ngmatch(s1strneql, ALLBUT,
 301:         ngpermlist, ngpermcount, ngarray, ngcount));
 302: }
 303: 
 304: 
 305: /*
 306:  * spew -- spew out the contents of a file to stdout, doing
 307:  * the necessary cr-lf additions at the end.  Finish with
 308:  * a "." on a line by itself, and an fflush(stdout).
 309:  *
 310:  *	Parameters:	"how" tells what part of the file we
 311:  *			want spewed:
 312:  *				ARTICLE   The entire thing.
 313:  *				HEAD	  Just the first part.
 314:  *				BODY	  Just the second part.
 315:  *			"fp" is the open file to spew from.
 316:  *
 317:  *	Returns:	Nothing.
 318:  *
 319:  *	Side effects:	Changes current position in file.
 320:  */
 321: 
 322: spew(fp, how)
 323:     FILE        *fp;
 324:     int     how;
 325: {
 326:     char        line[NNTP_STRLEN];
 327:     register char   *cp;
 328: 
 329: #ifdef LOG
 330:     ++arts_acsd;
 331: #endif
 332: 
 333:     if (how == STAT) {
 334:         (void) fflush(stdout);
 335:         return;
 336:     }
 337: 
 338:     while (fgets(line, sizeof(line)-6, fp) != NULL && *line != '\n') {
 339:         if (how == BODY)    /* We need to skip this anyway */
 340:             continue;
 341:         cp = index(line, '\n');
 342:         if (cp != NULL)
 343:             *cp = '\0';
 344:         if (*line == '.')
 345:             putchar('.');
 346:         putline(line);
 347:         if (cp == NULL) {
 348:             for (;;) {
 349:                 if ((fgets(line, sizeof(line)-6, fp) == NULL)
 350:                     || (index(line, '\n') != NULL))
 351:                     break;
 352:             }
 353:         }
 354:     }
 355: 
 356:     if (how == HEAD) {
 357:         putchar('.');
 358:         putchar('\r');
 359:         putchar('\n');
 360:         (void) fflush(stdout);
 361:         return;
 362:     } else if (how == ARTICLE) {
 363:         putchar('\r');
 364:         putchar('\n');
 365:     }
 366: 
 367:     while (fgets(line, sizeof(line)-6, fp) != NULL) {
 368:         cp = index(line, '\n');
 369:         if (cp != NULL)
 370:             *cp = '\0';
 371:         if (*line == '.')
 372:             putchar('.');
 373:         putline(line);
 374: 
 375:         if (cp == NULL) {
 376:             for (;;) {
 377:                 if ((fgets(line, sizeof(line)-6, fp) == NULL)
 378:                     || (index(line, '\n') != NULL))
 379:                     break;
 380:             }
 381:         }
 382:     }
 383:     putchar('.');
 384:     putchar('\r');
 385:     putchar('\n');
 386:     (void) fflush(stdout);
 387: }
 388: 
 389: 
 390: /*
 391:  * get_id -- get the message id of the current article.
 392:  *
 393:  *	Parameters:	"art_fp" is a pointer to the open file.
 394:  *			"id" is space for the message ID.
 395:  *
 396:  *	Returns:	Nothing.
 397:  *
 398:  *	Side effects:	Seeks and rewinds on "art_fp".
 399:  *			Changes space pointed to by "id".
 400:  */
 401: 
 402: get_id(art_fp, id)
 403:     register FILE   *art_fp;
 404:     char        *id;
 405: {
 406:     char        line[MAXBUFLEN];
 407:     register char   *cp;
 408: 
 409:     while (fgets(line, sizeof(line), art_fp) != NULL) {
 410:         if (*line == '\n')
 411:             break;
 412:         if (*line == 'M' || *line == 'm') { /* "Message-ID" */
 413:             if ((cp = index(line, ' ')) != NULL) {
 414:                 *cp = '\0';
 415:                 if (!strcasecmp(line, "Message-ID:")) {
 416:                     (void) strcpy(id, cp + 1);
 417:                     if ((cp = index(id, '\n')) != NULL)
 418:                         *cp = '\0';
 419:                     (void) rewind(art_fp);
 420:                     return;
 421:                 }
 422:             }
 423:         }
 424:     }
 425:     (void) rewind(art_fp);
 426:     (void) strcpy(id, "<0>");
 427: }
 428: 
 429: 
 430: /*
 431:  * close_crnt -- close the current article file pointer, if it's
 432:  *	open.
 433:  *
 434:  *	Parameters:	None.
 435:  *
 436:  *	Returns:	Nothing.
 437:  *
 438:  *	Side effects:	Closes "art_fp" if it's open; sets "art_fp" to NULL.
 439:  */
 440: 
 441: close_crnt()
 442: {
 443:     if (art_fp != NULL)
 444:         (void) fclose(art_fp);
 445:     art_fp = NULL;
 446: }
 447: 
 448: 
 449: /*
 450:  * findart -- find an article number in the article array.
 451:  *
 452:  *	Parameters:	"artname" is a string containing
 453:  *			the name of the article.
 454:  *
 455:  *	Returns:	An index into "art_array",
 456:  *			or -1 if "artname" isn't in "art_array".
 457:  *
 458:  *	Side effects:	None.
 459:  *
 460:  *	Improvement:	Replace this linear search with a binary one.
 461:  */
 462: 
 463: findart(artname)
 464:     char        *artname;
 465: {
 466:     register int    i, artnum;
 467: 
 468:     artnum = atoi(artname);
 469: 
 470:     for (i = 0; i < num_arts; ++i)
 471:         if (art_array[i] == artnum)
 472:             return(i);
 473: 
 474:     return (-1);
 475: }
 476: 
 477: 
 478: /*
 479:  * get_distlist -- return a nicely set up array of distribution groups
 480:  * along with a count, when given an NNTP-spec distribution list
 481:  * in the form <dist1,dist2,...,distn>.
 482:  *
 483:  *	Parameters:		"array" is storage for our array,
 484:  *				set to point at some static data.
 485:  *				"list" is the NNTP distribution list.
 486:  *
 487:  *	Returns:		Number of distributions found.
 488:  *				-1 on error.
 489:  *
 490:  *	Side effects:		Changes static data area.
 491:  */
 492: 
 493: get_distlist(array, list)
 494:     char        ***array;
 495:     char        *list;
 496: {
 497:     char        *cp;
 498:     int     distcount;
 499:     static char **dist_list = (char **) NULL;
 500: 
 501:     if (list[0] != '<')
 502:         return (-1);
 503: 
 504:     cp = index(list + 1, '>');
 505:     if (cp != NULL)
 506:         *cp = '\0';
 507:     else
 508:         return (-1);
 509: 
 510:     for (cp = list + 1; *cp != '\0'; ++cp)
 511:         if (*cp == ',')
 512:             *cp = ' ';
 513:     distcount = parsit(list + 1, &dist_list);
 514:     *array = dist_list;
 515:     return (distcount);
 516: }
 517: 
 518: 
 519: /*
 520:  * lower -- convert a character to lower case, if it's upper case.
 521:  *
 522:  *	Parameters:	"c" is the character to be
 523:  *			converted.
 524:  *
 525:  *	Returns:	"c" if the character is not
 526:  *			upper case, otherwise the lower
 527:  *			case eqivalent of "c".
 528:  *
 529:  *	Side effects:	None.
 530:  */
 531: 
 532: char
 533: lower(c)
 534:     register char   c;
 535: {
 536:     if (isascii(c) && isupper(c))
 537:         c = c - 'A' + 'a';
 538:     return (c);
 539: }
 540: 
 541: 
 542: /* the following is from news 2.11 */
 543: 
 544: #ifdef USG
 545: /*
 546: ** Generate the appropriate history subfile name
 547: */
 548: char *
 549: histfile(hline)
 550: char *hline;
 551: {
 552:     char chr;   /* least significant digit of article number */
 553:     static char subfile[BUFSIZ];
 554: 
 555:     chr = findhfdigit(hline);
 556:     sprintf(subfile, "%s.d/%c", HISTORY_FILE, chr);
 557:     return subfile;
 558: }
 559: 
 560: findhfdigit(fn)
 561: char *fn;
 562: {
 563:     register char *p;
 564:     register int chr;
 565: 
 566:     p = index(fn, '@');
 567:     if (p != NULL && p > fn)
 568:         chr = *(p - 1);
 569:     else
 570:         chr = '0';
 571:     if (!isdigit(chr))
 572:         chr = '0';
 573:     return chr;
 574: }
 575: bcopy(s, d, l)
 576:     register char *s, *d;
 577:     register int l;
 578: {
 579:     while (l-- > 0)
 580:         *d++ = *s++;
 581: }
 582: 
 583: bcmp(s1, s2, l)
 584:     register char *s1, *s2;
 585:     register int l;
 586: {
 587:     if (l == 0)
 588:         return (0);
 589: 
 590:     do
 591:         if (*s1++ != *s2++)
 592:             break;
 593:     while (--l);
 594: 
 595:     return (l);
 596: }
 597: 
 598: bzero(p, l)
 599:     register char *p;
 600:     register int l;
 601: {
 602:     while (l-- > 0)
 603:         *p++ = 0;
 604: }
 605: 
 606: dup2(x,y)
 607: int x,y;
 608: {
 609:     close(y);
 610:     return(fcntl(x, F_DUPFD,y ));
 611: }
 612: #endif USG

Defined functions

bcmp defined in line 583; never used
bcopy defined in line 575; used 3 times
bzero defined in line 598; used 1 times
check_ngperm defined in line 266; used 1 times
close_crnt defined in line 441; used 5 times
dup2 defined in line 606; used 11 times
findhfdigit defined in line 560; used 1 times
get_id defined in line 402; used 1 times
  • in line 64
gethistent defined in line 96; used 3 times
histfile defined in line 548; used 2 times
lower defined in line 532; never used
spew defined in line 322; used 2 times

Defined variables

sccsid defined in line 2; never used

Defined macros

USGHIST defined in line 91; used 5 times
Last modified: 1988-02-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4902
Valid CSS Valid XHTML 1.0 Strict