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