|
|
1.1 root 1: /*
2: * rfuncs2 - more routines needed by readr.
3: */
4:
5: #ifdef SCCSID
6: static char *SccsId = "@(#)rfuncs2.c 1.27 6/7/85";
7: #endif /* SCCSID */
8:
9: /*LINTLIBRARY*/
10:
11: #include "rparams.h"
12:
13: static char lbuf[BUFLEN*2];
14:
15: FILE *popen();
16:
17: /*
18: * Match title.
19: */
20: titmat(h, titlist)
21: register struct hbuf *h;
22: register char *titlist;
23: {
24: register char *p;
25:
26: while (*titlist != '\0') {
27:
28: if (strcmp(titlist, h->ident) == 0)
29: return TRUE;
30: for (p = h->title; *p != '\0'; p++)
31: if (prefix(p, titlist)) {
32: return TRUE;
33: }
34: while (*titlist++ != '\0')
35: ;
36: }
37: return FALSE;
38: }
39:
40:
41: /*
42: * Save the news item in the user's file.
43: * Allow files with first character as '|' to write article
44: * to program across a pipe.
45: */
46:
47: #define PIPECHAR '|'
48:
49: save(file, to)
50: register char *file, *to;
51: {
52: register FILE *ufp, *hfp;
53: #ifdef u370
54: static struct hbuf hh;
55: #else /* !u370 */
56: struct hbuf hh;
57: #endif /* !u370 */
58: int isprogram = 0;
59: int isnew = 1;
60: register int i;
61:
62: for(i=0;i<NUNREC;i++)
63: hh.unrec[i] = NULL;
64:
65: if ((hfp = fopen(file, "r")) == NULL) {
66: fprintf(stderr, "Can't get article.\n");
67: return;
68: }
69: if (hread(&hh, hfp, TRUE) == NULL) {
70: fprintf(stderr, "Article is garbled.\n");
71: return;
72: }
73: ufp = fopen(to, "r");
74: if (ufp != NULL) {
75: (void) fclose(ufp);
76: isnew = 0;
77: }
78: (void) setgid(gid);
79: (void) setuid(uid);
80: (void) umask(savmask);
81:
82: if (*to == PIPECHAR) {
83: if ((ufp = popen (&to[1], "w")) == NULL) {
84: fprintf(stderr,"Cannot execute %s\n", &to[1]);
85: return;
86: }
87: isprogram++;
88: } else if ((ufp = fopen(to, "a")) == NULL) {
89: fprintf(stderr,"Cannot append to %s.\n", to);
90: return;
91: }
92: /*
93: * V7MAIL code is here to conform to V7 mail format.
94: * If you need a different format to be able to
95: * use your local mail command (such as four ^A's
96: * on the end of articles) substitute it here.
97: */
98: #ifdef MMDF
99: if (!isprogram)
100: fprintf(ufp, "\001\001\001\001\n"); /* MMDF message header */
101: #endif /* MMDF */
102: #ifdef V7MAIL
103: hh.subtime = cgtdate(hh.subdate);
104: fprintf(ufp, "From %s %s",
105: #ifdef INTERNET
106: hh.from,
107: #else
108: hh.path,
109: #endif
110: ctime(&hh.subtime));
111: #endif
112: hprint(&hh, ufp, 2);
113: #ifdef V7MAIL
114: tprint(hfp, ufp, TRUE);
115: putc('\n', ufp); /* force blank line at end (ugh) */
116: #else
117: tprint(hfp, ufp, FALSE);
118: #endif
119: (void) fclose(hfp);
120: #ifdef MMDF
121: if (!isprogram)
122: fprintf(ufp, "\001\001\001\001\n"); /* MMDF message header */
123: #endif /* MMDF */
124: if (isprogram)
125: (void) pclose (ufp);
126: else
127: (void) fclose(ufp);
128: if (!isprogram)
129: printf("%s: %s\n", to, isnew ? "New file" : "Appended");
130: }
131:
132:
133: /*
134: * Print out the rest of the article.
135: */
136: tprint(ifp, ofp, checkfrom)
137: register FILE *ifp, *ofp;
138: int checkfrom;
139: {
140: while ((fgets(bfr, sizeof bfr, ifp)) != NULL && !SigTrap) {
141: if (checkfrom && strncmp(bfr, "From ", 5) == 0)
142: putc('>', ofp);
143: (void) fputs(bfr, ofp);
144: }
145: if (SigTrap)
146: qfflush(ofp);
147: (void) fflush(ofp);
148: fprintf(ofp, (SigTrap ? "\n\n" : "\n"));
149: SigTrap = FALSE;
150: }
151:
152:
153: /*
154: * Print the file header.
155: */
156: hprint(hp, ofp, verbose)
157: register struct hbuf *hp;
158: int verbose;
159: register FILE *ofp;
160: {
161: register char *p1, *p2;
162: char fname[BUFLEN];
163: char *tailpath();
164:
165: fname[0] = '\0'; /* init name holder */
166:
167: if (verbose == 2) {
168: lhwrite(hp, ofp);
169: return;
170: }
171:
172: if (lflag || eflag) {
173: char buf1[80], buf2[200];
174: char *cp;
175:
176: (void) strcpy(bfr, groupdir);
177: for (cp=bfr; *cp; cp++)
178: if (*cp == '/')
179: *cp = '.';
180: (void) sprintf(buf1, "%s/%ld", bfr, bit);
181: (void) sprintf(buf2, "%-20s %s", buf1, hp->title);
182: fprintf(ofp, "%.76s\n", buf2);
183: return;
184: }
185:
186: p1 = index(hp->from, '('); /* Find the sender's full name. */
187: if (p1 == NULL && hp->path[0])
188: p1 = index(hp->path, '(');
189: if (p1 != NULL) {
190: strcpy(fname, p1+1);
191: p2 = index(fname, ')');
192: if (p2 != NULL)
193: *p2 = '\0';
194: }
195:
196: fprintf(ofp, "Subject: %s\n", hp->title);
197: if (!hflag && hp->summary[0])
198: fprintf(ofp, "Summary: %s\n", hp->summary);
199: if (!hflag && hp->keywords[0])
200: fprintf(ofp, "Keywords: %s\n", hp->keywords);
201: if (verbose) {
202: fprintf(ofp, "From: %s\n", hp->from);
203: fprintf(ofp, "Path: %s\n", hp->path);
204: if (hp->organization[0])
205: fprintf(ofp, "Organization: %s\n", hp->organization);
206: }
207: else {
208: if (p1 != NULL)
209: *--p1 = '\0'; /* bump over the '(' */
210: #ifdef INTERNET
211: /*
212: * Prefer Path line if it's in internet format, or if we don't
213: * understand internet format here, or if there is no reply-to.
214: */
215: fprintf(ofp, "From: %s", hp->from);
216: #else
217: fprintf(ofp, "Path: %s", tailpath(hp));
218: #endif
219: if (fname[0] || hp->organization[0]) {
220: if (fname[0] == '\0') {
221: (void) strcpy(fname,hp->from);
222: p2 = index(fname,'@');
223: if (p2)
224: *p2 = '\0';
225: }
226: fprintf(ofp, " (%s", fname);
227: if (hp->organization[0] && !hflag)
228: fprintf(ofp, " @ %s", hp->organization);
229: fprintf(ofp, ")");
230: }
231: fprintf(ofp, "\n");
232: if (p1 != NULL)
233: *p1 = ' ';
234: }
235:
236: if (verbose) {
237: fprintf(ofp, "Newsgroups: %s\n", hp->nbuf);
238: fprintf(ofp, "Date: %s\n", hp->subdate);
239: if (hp->sender[0])
240: fprintf(ofp, "Sender: %s\n", hp->sender);
241: if (hp->replyto[0])
242: fprintf(ofp, "Reply-To: %s\n", hp->replyto);
243: if (hp->followto[0])
244: fprintf(ofp, "Followup-To: %s\n", hp->followto);
245: }
246: else if (index(hp->nbuf, ',') || strcmp(groupdir, "junk") == 0)
247: fprintf(ofp, "Newsgroups: %s\n", hp->nbuf);
248:
249: if (pflag || ofp != stdout)
250: putc('\n', ofp);
251: }
252:
253:
254: /*
255: * If ofp != stdout, close it and run the script in coptbuf.
256: */
257: cout(ofp)
258: FILE *ofp;
259: {
260: register char *p, *q, *r;
261:
262: if (ofp == stdout || ofp == NULL)
263: return;
264: (void) fclose(ofp);
265: p = coptbuf;
266: q = lbuf;
267: while ((*q = *p++) != '\0')
268: if (*q++ == FMETA) {
269: q--;
270: r = outfile;
271: while ((*q++ = *r++) != '\0')
272: ;
273: q--;
274: }
275: fwait(fsubr(ushell, lbuf, (char *)NULL));
276: (void) unlink(outfile);
277: }
278:
279:
280: cdump(ofp)
281: register FILE *ofp;
282: {
283: if (ofp == stdout)
284: return;
285: fclose(ofp);
286: unlink(outfile);
287: }
288:
289:
290: /*
291: * Quiet 'flush'.
292: * Empty (without fflush()) the buffer for stream fp.
293: */
294: /* ARGSUSED */
295: qfflush(fp)
296: FILE *fp;
297: {
298: /* Alas, stdio does not permit this */
299: }
300:
301:
302: /*
303: * Count the number of remaining lines in file fp.
304: * Do not move the file pointer.
305: */
306: linecnt(fp)
307: FILE *fp;
308: {
309: long curpos;
310: register int nlines = 0;
311: register int c;
312:
313: if (fp == NULL)
314: return 0;
315: curpos = ftell(fp);
316: while ((c = getc(fp)) != EOF)
317: if (c == '\n')
318: nlines++;
319: (void) fseek(fp, curpos, 0);
320: return nlines;
321: }
322:
323:
324: /*
325: * Transmit file to system.
326: */
327: transmit(sp, file)
328: register struct srec *sp;
329: char *file;
330: {
331: register FILE *ifp, *ofp;
332: register int c, i;
333: #ifdef u370
334: static struct hbuf hh;
335: #else /* !u370 */
336: struct hbuf hh;
337: #endif /* !u370 */
338: char TRANS[BUFLEN];
339:
340: #ifdef DEBUG
341: fprintf(stderr, "xmit %s to %s using %s\n", file, sp->s_name, sp->s_xmit);
342: #endif
343: bzero((char *)&hh, sizeof hh);
344: ifp = xfopen(file, "r");
345: if (hread(&hh, ifp, TRUE) == NULL)
346: return;
347: strcpy(TRANS, "/tmp/trXXXXXX");
348: ofp = xfopen(mktemp(TRANS), "w");
349: if (index(sp->s_flags, 'A') == NULL)
350: hwrite(&hh, ofp);
351: else {
352: #ifdef OLD
353: fprintf(ofp, "A%s\n%s\n%s!%s\n%s\n%s\n", oident(hh.ident), hh.nbuf, FULLSYSNAME,
354: hh.path, hh.subdate, hh.title);
355: #else /* !OLD */
356: logerr("Must have OLD defined to use A flag for xmit");
357: unlink(TRANS);
358: return;
359: #endif /* !OLD */
360: }
361: while ((c = getc(ifp)) != EOF)
362: putc(c, ofp);
363: (void) fclose(ifp);
364: (void) fclose(ofp);
365: for (i=0;i<NUNREC;i++)
366: if (hh.unrec[i] != NULL)
367: free(hh.unrec[i]);
368: if (*sp->s_xmit == '\0' || strpbrk(sp->s_flags, "FUMH"))
369: (void) sprintf(bfr, DFTXMIT, sp->s_name, TRANS);
370: else
371: (void) sprintf(bfr, "(%s) < %s", sp->s_xmit, TRANS);
372: #ifdef DEBUG
373: fprintf(stderr, "%s\n", bfr);
374: #endif
375: (void) system(bfr);
376: (void) unlink(TRANS);
377: }
378:
379:
380: /*
381: * Cancel the article whose header is in hp, by posting a control message
382: * to cancel it. The scope of the control message depends on who would
383: * really be willing to cancel it. It is sent as far as it will do any good.
384: * notauthor is true iff the person posting this article is not the
385: * real author of the article being cancelled.
386: */
387: cancel(ofp, hp, notauthor)
388: FILE *ofp;
389: struct hbuf *hp;
390: int notauthor;
391: {
392: int pid;
393:
394: fflush(ofp);
395: pid = fork();
396: if (pid < 0) {
397: perror("readnews: cancel");
398: return 0;
399: }
400: if (pid > 0)
401: return 0;
402: if (notauthor)
403: (void) sprintf(bfr, "%s/%s -t 'cmsg cancel %s' -n %s -d local < /dev/null",
404: LIB, "inews", hp->ident, hp->nbuf);
405: else {
406: if (hp->distribution[0] == '\0')
407: (void) sprintf(bfr, "%s/%s -t 'cmsg cancel %s' -n %s < /dev/null",
408: LIB, "inews", hp->ident, hp->nbuf);
409: else
410: (void) sprintf(bfr, "%s/%s -t 'cmsg cancel %s' -n %s -d %s < /dev/null",
411: LIB, "inews", hp->ident, hp->nbuf, hp->distribution);
412: }
413: execl("/bin/sh", "sh", "-c", bfr, (char *) 0);
414: perror(bfr);
415: for ( ; ; )
416: exit(1);
417: }
418:
419:
420: dash(num, ofp)
421: register int num;
422: register FILE *ofp;
423: {
424: register int i;
425:
426: for (i = 0; i < num; i++)
427: putc('-', ofp);
428: putc('\n', ofp);
429: }
430:
431:
432: help(ofp)
433: register FILE *ofp;
434: {
435: register FILE *fp;
436: register int c;
437: char temp[BUFLEN];
438:
439: if (cflag) {
440: oneline:
441: fprintf(ofp, "(n)ext re(p)rint (w)rite (q)uit (r)eply\
442: (c)ancel -[n] +[n] (f)ollowup (N)ext (U)nsubscribe (v)ersion\n");
443: return;
444: }
445: (void) sprintf(temp, "%s/%s", LIB, "help");
446: if ((fp = fopen(temp, "r")) == NULL) {
447: fprintf(ofp, "No help file.\n");
448: goto oneline;
449: }
450: while ((c = getc(fp)) != EOF && !SigTrap)
451: putc(c, ofp);
452: (void) fclose(fp);
453: }
454:
455:
456: pout(ofp)
457: FILE *ofp;
458: {
459: register char *p, *q, *r;
460:
461: p = PAGER;
462: q = lbuf;
463: while ((*q = *p++) != '\0')
464: if (*q++ == FMETA) {
465: q--;
466: r = filename;
467: while ((*q++ = *r++) != '\0')
468: ;
469: q--;
470: }
471: fwait(fsubr(ushell, lbuf, (char *)NULL));
472: fprintf(ofp, "\n");
473: }
474:
475: /*
476: * Print a very brief version of the date in question.
477: */
478: char *
479: briefdate(datestr)
480: char *datestr;
481: {
482: time_t dt, now;
483: char *tmstr;
484: char *wkday, *monthdate, *timeofday;
485: static char rbuf[20];
486:
487: dt = cgtdate(datestr);
488: tmstr = ctime(&dt);
489:
490: wkday = tmstr; tmstr[3] = '\0';
491: monthdate = tmstr+4; tmstr[10] = '\0';
492: timeofday = tmstr+11; tmstr[16] = '\0';
493:
494: (void) time(&now);
495: if (now - dt < 7 * DAYS)
496: (void) strcpy(rbuf, wkday);
497: else
498: (void) strcpy(rbuf, monthdate);
499: (void) strcat(rbuf, " ");
500: (void) strcat(rbuf, timeofday);
501: return rbuf;
502: }
503:
504: /*
505: * Return TRUE iff stdout is /dev/null.
506: */
507: ignoring()
508: {
509: struct stat ss, ns;
510:
511: if (fstat(1, &ss) < 0)
512: return FALSE;
513: if (stat("/dev/null", &ns) < 0)
514: return FALSE;
515: if (ss.st_dev == ns.st_dev && ss.st_rdev == ns.st_rdev)
516: return TRUE;
517: return FALSE;
518: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.