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

Defined functions

close_crnt defined in line 312; used 5 times
get_id defined in line 276; used 1 times
  • in line 62
lower defined in line 533; used 3 times
spawn defined in line 410; used 2 times
spew defined in line 196; used 2 times

Defined variables

sccsid defined in line 2; never used
Last modified: 1986-03-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1777
Valid CSS Valid XHTML 1.0 Strict