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