|
|
1.1 root 1: /* $Header: respond.c,v 4.3.1.4 85/05/23 17:24:49 lwall Exp $
2: *
3: * $Log: respond.c,v $
4: * Revision 4.3.1.4 85/05/23 17:24:49 lwall
5: * Now allows 'r' and 'f' on null articles.
6: *
7: * Revision 4.3.1.3 85/05/15 14:42:32 lwall
8: * Removed duplicate include of intrp.h.
9: *
10: * Revision 4.3.1.2 85/05/14 08:55:15 lwall
11: * Default for normal/mailbox question was applied to wrong buffer.
12: *
13: * Revision 4.3.1.1 85/05/10 11:37:33 lwall
14: * Branch for patches.
15: *
16: * Revision 4.3 85/05/01 11:47:04 lwall
17: * Baseline for release with 4.3bsd.
18: *
19: */
20:
21: #include "EXTERN.h"
22: #include "common.h"
23: #include "intrp.h"
24: #include "head.h"
25: #include "term.h"
26: #include "ng.h"
27: #include "util.h"
28: #include "rn.h"
29: #include "artio.h"
30: #include "final.h"
31: #include "INTERN.h"
32: #include "respond.h"
33:
34: static char nullart[] = "\nNull article\n";
35:
36: void
37: respond_init()
38: {
39: ;
40: }
41:
42: int
43: save_article()
44: {
45: bool use_pref;
46: register char *s, *c;
47: char altbuf[CBUFLEN];
48: int iter;
49: bool interactive = (buf[1] == FINISHCMD);
50:
51: if (!finish_command(interactive)) /* get rest of command */
52: return SAVE_ABORT;
53: use_pref = isupper(*buf);
54: #ifdef ASYNC_PARSE
55: parse_maybe(art);
56: #endif
57: savefrom = (*buf=='w' || *buf=='W' ? htype[PAST_HEADER].ht_minpos : 0);
58: if (artopen(art) == Nullfp) {
59: #ifdef VERBOSE
60: IF(verbose)
61: fputs("\n\
62: Saving null articles is not very productive! :-)\n\
63: ",stdout) FLUSH;
64: ELSE
65: #endif
66: #ifdef TERSE
67: fputs(nullart,stdout) FLUSH;
68: #endif
69: return SAVE_DONE;
70: }
71: if (chdir(cwd)) {
72: printf(nocd,cwd) FLUSH;
73: sig_catcher(0);
74: }
75: if (savedest)
76: free(savedest);
77: if ((s = index(buf,'|')) != Nullch) {
78: /* is it a pipe command? */
79: s++; /* skip the | */
80: while (*s == ' ') s++;
81: safecpy(altbuf,filexp(s),sizeof altbuf);
82: savedest = altbuf;
83: interp(cmd_buf, (sizeof cmd_buf), getval("PIPESAVER",PIPESAVER));
84: /* then set up for command */
85: resetty(); /* restore tty state */
86: if (use_pref) /* use preferred shell? */
87: doshell(Nullch,cmd_buf);
88: /* do command with it */
89: else
90: doshell(sh,cmd_buf); /* do command with sh */
91: noecho(); /* and stop echoing */
92: crmode(); /* and start cbreaking */
93: savedest = savestr(savedest);
94: }
95: else { /* normal save */
96: bool there, mailbox;
97: char *savename = getval("SAVENAME",SAVENAME);
98:
99: s = buf+1; /* skip s or S */
100: if (*s == '-') { /* if they are confused, skip - also */
101: #ifdef VERBOSE
102: IF(verbose)
103: fputs("Warning: '-' ignored. This isn't readnews.\n",stdout)
104: FLUSH;
105: ELSE
106: #endif
107: #ifdef TERSE
108: fputs("'-' ignored.\n",stdout) FLUSH;
109: #endif
110: s++;
111: }
112: for (; *s == ' '; s++); /* skip spaces */
113: safecpy(altbuf,filexp(s),sizeof altbuf);
114: s = altbuf;
115: if (! index(s,'/')) {
116: interp(buf, (sizeof buf), getval("SAVEDIR",SAVEDIR));
117: if (makedir(buf,MD_DIR)) /* ensure directory exists */
118: strcpy(buf,cwd);
119: if (*s) {
120: for (c = buf; *c; c++) ;
121: *c++ = '/';
122: strcpy(c,s); /* add filename */
123: }
124: s = buf;
125: }
126: for (iter = 0;
127: (there = stat(s,&filestat) >= 0) &&
128: (filestat.st_mode & S_IFDIR);
129: iter++) { /* is it a directory? */
130:
131: c = (s+strlen(s));
132: *c++ = '/'; /* put a slash before filename */
133: interp(c, s==buf?(sizeof buf):(sizeof altbuf),
134: iter ? "News" : savename );
135: /* generate a default name somehow or other */
136: if (index(c,'/')) { /* yikes, a '/' in the filename */
137: makedir(s,MD_FILE);
138: }
139: }
140: if (*s != '/') { /* relative path? */
141: c = (s==buf ? altbuf : buf);
142: sprintf(c, "%s/%s", cwd, s);
143: s = c; /* absolutize it */
144: }
145: s = savedest = savestr(s); /* doesn't move any more */
146: /* make it handy for %b */
147: if (!there) {
148: if (mbox_always)
149: mailbox = TRUE;
150: else if (norm_always)
151: mailbox = FALSE;
152: else {
153: char *dflt = (instr(savename,"%a") ? "nyq" : "ynq");
154:
155: sprintf(cmd_buf,
156: "\nFile %s doesn't exist--\n use mailbox format? [%s] ",
157: s,dflt);
158: reask_save:
159: in_char(cmd_buf);
160: putchar('\n') FLUSH;
161: setdef(buf,dflt);
162: #ifdef VERIFY
163: printcmd();
164: #endif
165: if (*buf == 'h') {
166: #ifdef VERBOSE
167: IF(verbose)
168: printf("\n\
169: Type y to create %s as a mailbox.\n\
170: Type n to create it as a normal file.\n\
171: Type q to abort the save.\n\
172: ",s) FLUSH;
173: ELSE
174: #endif
175: #ifdef TERSE
176: fputs("\n\
177: y to create mailbox.\n\
178: n to create normal file.\n\
179: q to abort.\n\
180: ",stdout) FLUSH;
181: #endif
182: goto reask_save;
183: }
184: else if (*buf == 'n') {
185: mailbox = FALSE;
186: }
187: else if (*buf == 'y') {
188: mailbox = TRUE;
189: }
190: else if (*buf == 'q') {
191: goto s_bomb;
192: }
193: else {
194: fputs(hforhelp,stdout) FLUSH;
195: settle_down();
196: goto reask_save;
197: }
198: }
199: }
200: else if (filestat.st_mode & S_IFCHR)
201: mailbox = FALSE;
202: else {
203: int tmpfd;
204:
205: tmpfd = open(s,0);
206: if (tmpfd == -1)
207: mailbox = FALSE;
208: else {
209: read(tmpfd,buf,LBUFLEN);
210: c = buf;
211: if (!isspace(MBOXCHAR))
212: while (isspace(*c))
213: c++;
214: mailbox = (*c == MBOXCHAR);
215: close(tmpfd);
216: }
217: }
218:
219: safecpy(cmd_buf, filexp(mailbox ?
220: getval("MBOXSAVER",MBOXSAVER) :
221: getval("NORMSAVER",NORMSAVER) ), sizeof cmd_buf);
222: /* format the command */
223: resetty(); /* make terminal behave */
224: if (doshell(use_pref?Nullch:SH,cmd_buf))
225: fputs("Not saved",stdout);
226: else
227: printf("%s to %s %s",
228: there?"Appended":"Saved",
229: mailbox?"mailbox":"file",
230: s);
231: if (interactive)
232: putchar('\n') FLUSH;
233: noecho(); /* make terminal do what we want */
234: crmode();
235: }
236: s_bomb:
237: #ifdef SERVER
238: if (chdir(spool)) {
239: #else
240: if (chdir(spool) || chdir(ngdir)) {
241: #endif
242: printf(nocd,ngdir) FLUSH;
243: sig_catcher(0);
244: }
245: return SAVE_DONE;
246: }
247:
248: int
249: cancel_article()
250: {
251: char *artid_buf;
252: char *ngs_buf;
253: char *from_buf;
254: char *reply_buf;
255: int myuid = getuid();
256: int r = -1;
257:
258: if (artopen(art) == Nullfp) {
259: #ifdef VERBOSE
260: IF(verbose)
261: fputs("\n\
262: Cancelling null articles is your idea of fun? :-)\n\
263: ",stdout) FLUSH;
264: ELSE
265: #endif
266: #ifdef TERSE
267: fputs(nullart,stdout) FLUSH;
268: #endif
269: return r;
270: }
271: reply_buf = fetchlines(art,REPLY_LINE);
272: from_buf = fetchlines(art,FROM_LINE);
273: artid_buf = fetchlines(art,ARTID_LINE);
274: ngs_buf = fetchlines(art,NGS_LINE);
275: if (!instr(from_buf,sitename) ||
276: (!instr(from_buf,logname) &&
277: !instr(reply_buf,logname) &&
278: #ifdef NEWSADMIN
279: myuid != newsuid &&
280: #endif
281: myuid != ROOTID ) )
282: #ifdef VERBOSE
283: IF(verbose)
284: fputs("You can't cancel someone else's article\n",stdout)
285: FLUSH;
286: ELSE
287: #endif
288: #ifdef TERSE
289: fputs("Not your article\n",stdout) FLUSH;
290: #endif
291: else {
292: tmpfp = fopen(headname,"w"); /* open header file */
293: if (tmpfp == Nullfp) {
294: printf(cantcreate,headname) FLUSH;
295: goto no_cancel;
296: }
297: interp(buf, (sizeof buf), getval("CANCELHEADER",CANCELHEADER));
298: fputs(buf,tmpfp);
299: fclose(tmpfp);
300: r = doshell(sh,filexp(getval("CANCEL",CANCEL)));
301: }
302: no_cancel:
303: free(artid_buf);
304: free(ngs_buf);
305: free(from_buf);
306: free(reply_buf);
307: return r;
308: }
309:
310: void
311: reply()
312: {
313: bool incl_body = (*buf == 'R');
314: char *maildoer = savestr(filexp(getval("MAILPOSTER",MAILPOSTER)));
315:
316: artopen(art);
317: tmpfp = fopen(headname,"w"); /* open header file */
318: if (tmpfp == Nullfp) {
319: printf(cantcreate,headname) FLUSH;
320: goto no_reply;
321: }
322: interp(buf, (sizeof buf), getval("MAILHEADER",MAILHEADER));
323: fputs(buf,tmpfp);
324: if (!instr(maildoer,"%h"))
325: #ifdef VERBOSE
326: IF(verbose)
327: printf("\n%s\n(Above lines saved in file %s)\n",buf,headname)
328: FLUSH;
329: ELSE
330: #endif
331: #ifdef TERSE
332: printf("\n%s\n(Header in %s)\n",buf,headname) FLUSH;
333: #endif
334: if (incl_body && artfp != Nullfp) {
335: interp(buf, (sizeof buf), getval("YOUSAID",YOUSAID));
336: fprintf(tmpfp,"%s\n",buf);
337: #ifdef ASYNC_PARSE
338: parse_maybe(art);
339: #endif
340: fseek(artfp,(long)htype[PAST_HEADER].ht_minpos,0);
341: while (fgets(buf,LBUFLEN,artfp) != Nullch) {
342: fprintf(tmpfp,"%s%s",indstr,buf);
343: }
344: fprintf(tmpfp,"\n");
345: }
346: fclose(tmpfp);
347: interp(cmd_buf, (sizeof cmd_buf), maildoer);
348: invoke(cmd_buf,origdir);
349: UNLINK(headname); /* kill the header file */
350: no_reply:
351: free(maildoer);
352: }
353:
354: void
355: followup()
356: {
357: bool incl_body = (*buf == 'F');
358:
359: artopen(art);
360: tmpfp = fopen(headname,"w");
361: if (tmpfp == Nullfp) {
362: printf(cantcreate,headname) FLUSH;
363: return;
364: }
365: interp(buf, (sizeof buf), getval("NEWSHEADER",NEWSHEADER));
366: fprintf(tmpfp,"%s",buf);
367: if (incl_body && artfp != Nullfp) {
368: #ifdef VERBOSE
369: if (verbose)
370: fputs("\n\
371: (Be sure to double-check the attribution against the signature, and\n\
372: trim the quoted article down as much as possible.)\n\
373: ",stdout) FLUSH;
374: #endif
375: interp(buf, (sizeof buf), getval("ATTRIBUTION",ATTRIBUTION));
376: fprintf(tmpfp,"%s\n",buf);
377: #ifdef ASYNC_PARSE
378: parse_maybe(art);
379: #endif
380: fseek(artfp,(long)htype[PAST_HEADER].ht_minpos,0);
381: while (fgets(buf,LBUFLEN,artfp) != Nullch) {
382: fprintf(tmpfp,"%s%s",indstr,buf);
383: }
384: fprintf(tmpfp,"\n");
385: }
386: fclose(tmpfp);
387: safecpy(cmd_buf,filexp(getval("NEWSPOSTER",NEWSPOSTER)),sizeof cmd_buf);
388: invoke(cmd_buf,origdir);
389: UNLINK(headname);
390: }
391:
392: void
393: invoke(cmd,dir)
394: char *cmd,*dir;
395: {
396: if (chdir(dir)) {
397: printf(nocd,dir) FLUSH;
398: return;
399: }
400: #ifdef VERBOSE
401: IF(verbose)
402: printf("\n(leaving cbreak mode; cwd=%s)\nInvoking command: %s\n\n",
403: dir,cmd) FLUSH;
404: ELSE
405: #endif
406: #ifdef TERSE
407: printf("\n(-cbreak; cwd=%s)\nInvoking: %s\n\n",dir,cmd) FLUSH;
408: #endif
409: resetty(); /* make terminal well-behaved */
410: doshell(sh,cmd); /* do the command */
411: noecho(); /* set no echo */
412: crmode(); /* and cbreak mode */
413: #ifdef VERBOSE
414: IF(verbose)
415: fputs("\n(re-entering cbreak mode)\n",stdout) FLUSH;
416: ELSE
417: #endif
418: #ifdef TERSE
419: fputs("\n(+cbreak)\n",stdout) FLUSH;
420: #endif
421: #ifdef SERVER
422: if (chdir(spool)) {
423: #else
424: if (chdir(spool) || chdir(ngdir)) {
425: #endif
426: printf(nocd,ngdir) FLUSH;
427: sig_catcher(0);
428: }
429: }
430:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.