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