]> diplodocus.org Git - nmh/blob - docs/historical/mh-jun-1982/Extras/resp.c
Updated documentation and comments about sendmail/pipe.
[nmh] / docs / historical / mh-jun-1982 / Extras / resp.c
1 #ifdef COMMENT
2 Proprietary Rand Corporation, 1981.
3 Further distribution of this software
4 subject to the terms of the Rand
5 license agreement.
6 #endif
7
8 #include "mh.h"
9 #include "/rnd/borden/h/iobuf.h"
10 #include "/rnd/borden/h/signals.h"
11 #define NOUSE 0
12
13 /* #define TEST 1 */
14
15 char draft[],
16 sysed[],
17
18 char *anyl[] {
19 "no", 0,
20 "yes", 0,
21 "list", 0,
22 0
23 };
24 char *aleqs[] {
25 "list", 0, /* 0 */
26 "edit [<editor>]", 0, /* 1 */
27 "quit [delete]", 0, /* 2 */
28 "send [verbose]", 0, /* 3 */
29 0
30 };
31
32 int *vec[MAXARGS], fout, anot;
33 int ccme 1;
34 char *maildir;
35 struct msgs *mp;
36 char *ed;
37 int inplace; /* preserve links in anno */
38
39 struct swit switches[] {
40 "annotate", 0, /* 0 */
41 "noannotate", 0, /* 1 */
42 "ccme", -1, /* 2 */
43 "noccme", -1, /* 3 */
44 "editor editor", 0, /* 4 */
45 "inplace", 0, /* 5 */
46 "noinplace", 0, /* 6 */
47 "help", 4, /* 7 */
48 0, 0
49 };
50
51 main(argc, argv)
52 char *argv[];
53 {
54 char *folder, *nfolder, *msg;
55 register char *cp, *ap;
56 register int cur;
57 char *arguments[50], **argp;
58
59 fout = dup(1);
60 #ifdef NEWS
61 m_news();
62 #endif
63 msg = anot = folder = 0;
64
65 ap = cp = argv[0];
66 while(*cp)
67 if(*cp++ == '/')
68 ap = cp;
69 if((cp = m_find(ap)) != -1) {
70 ap = brkstring(cp = getcpy(cp), " ", "\n");
71 ap = copyip(ap, arguments);
72 } else
73 ap = arguments;
74 copyip(argv+1, ap);
75 argp = arguments;
76 while(cp = *argp++) {
77 if(*cp == '-')
78 switch(smatch(++cp, switches)) {
79 case -2:ambigsw(cp, switches); /* ambiguous */
80 goto leave;
81 /* unknown */
82 case -1:printf("resp: -%s unknown\n", cp);
83 goto leave;
84 case 0: anot = 1; continue; /* -annotate */
85 case 1: anot = 0; continue; /* -noannotate */
86 case 2: ccme = 1; continue; /* -ccme */
87 case 3: ccme = 0; continue; /* -noccme */
88 case 4: if(!(ed = *argp++)) { /* -editor */
89 printf("resp: Missing argument for %s switch\n", argp[-2]);
90 goto leave;
91 }
92 continue;
93 case 5: inplace = 1; continue; /* -inplace */
94 case 6: inplace = 0; continue; /* -noinplace */
95 /* -help */
96 case 7: help("resp [+folder] [msg] [switches]",
97 switches);
98 goto leave;
99 }
100 if(*cp == '+') {
101 if(folder) {
102 printf("Only one folder at a time.\n");
103 goto leave;
104 } else
105 folder = cp + 1;
106 } else if(msg) {
107 printf("Only one message per response.\n");
108 goto leave;
109 } else
110 msg = cp;
111 }
112 if(!msg)
113 msg = "cur";
114 if(!folder)
115 folder = m_getfolder();
116 maildir = getcpy(m_maildir(folder));
117 if(chdir(maildir) < 0) {
118 printf("Can't chdir to: "); flush();
119 perror(maildir);
120 goto leave;
121 }
122 if(!(mp = m_gmsg(folder))) {
123 printf("Can't read folder!?\n");
124 goto leave;
125 }
126 if(mp->hghmsg == 0) {
127 printf("No messages in \"%s\".\n", folder);
128 goto leave;
129 }
130 if(!m_convert(msg))
131 goto leave;
132 if(mp->numsel == 0) {
133 printf("resp: shark's fin soup\n"); /* never get here */
134 goto leave;
135 }
136 if(mp->numsel > 1) {
137 printf("Only one message at a time.\n");
138 goto leave;
139 }
140 m_replace(pfolder, folder);
141 if(mp->lowsel != mp->curmsg)
142 m_setcur(mp->lowsel);
143 repl(getcpy(m_name(mp->lowsel)));
144 leave:
145 m_update();
146 flush();
147 }
148
149
150 repl(msg)
151 {
152 register char *cp;
153 register int i,j;
154 struct iobuf in;
155 char name[NAMESZ], field[512], *replto, *from, *cc, *sub, *date, *to;
156 char *drft, *msgid;
157 int state, out, status, intr;
158 int pid, wpid;
159 char **argp, *address;
160
161 if(fopen(msg, &in) < 0) {
162 printf("Can't open \"%s\"\n", msg);
163 return;
164 }
165 drft = m_maildir(draft);
166 if((out = open(drft, 0)) >= 0) {
167 cp = concat("\"", drft, "\" exists; delete? ", 0);
168 while((i = gans(cp, anyl)) == 2)
169 showfile(drft);
170 if(!i)
171 return;
172 free(cp);
173 close(out);
174 }
175 if((out = creat(drft, m_gmprot())) < 0) {
176 printf("Can't create \"%s\".\n", drft);
177 return;
178 }
179
180 state = FLD;
181 replto = msgid = to = from = cc = sub = date = 0;
182
183 for(;;) {
184
185 switch(state = m_getfld(state, name, field, sizeof field, &in)) {
186
187 case FLD:
188 case FLDEOF:
189 case FLDPLUS:
190 if(uleq(name, "from"))
191 from = niceadd(field, from);
192 if(uleq(name, "cc"))
193 cc = niceadd(field, cc);
194 if(uleq(name, "subject"))
195 sub = niceadd(field, sub);
196 if(uleq(name, "date"))
197 date = niceadd(field, date);
198 if(uleq(name, "to"))
199 to = niceadd(field, to);
200 if(uleq(name, "message-id"))
201 msgid = niceadd(field, msgid);
202 if(uleq(name, "reply-to"))
203 replto = niceadd(field, replto);
204 /* if(uleq(name, "sender"))
205 sender = niceadd(field, sender); */
206 if(state == FLDEOF)
207 goto done;
208 break;
209
210 case BODY:
211 case BODYEOF:
212 case FILEEOF:
213 goto done;
214
215 default:
216 printf("getfld returned %d\n", state);
217 return;
218 }
219
220 }
221
222 done:
223
224 /* if(!(address = addr(sender)))
225 if(!(address = addr(from)))
226 address = addr(replto);
227 */
228 address = (replto ? addr(replto) : addr(from));
229 if(!ccme)
230 to = 0;
231 if(!(from || replto || to)) {
232 printf("No one to respond to!!!\n");
233 return;
234 }
235 close(in.b_fildes);
236 if(replto)
237 rtrim(replto);
238 if(from)
239 rtrim(from);
240 type(out, "To: "); /* To: */
241 if(cp = (replto ? replto : from))
242 type(out, cp);
243 if(to) {
244 if(cp)
245 type(out, ",\n ");
246 if(address)
247 to = fix(to, address);
248 type(out, to);
249 }
250 if(cc) { /* cc */
251 type(out, "cc: ");
252 if(address)
253 cc = fix(cc, address);
254 type(out, cc);
255 }
256 if(sub) { /* Subject: Re: */
257 type(out, "Subject: ");
258 if(*sub == ' ') sub++;
259 if((sub[0] != 'R' && sub[0] != 'r') ||
260 (sub[1] != 'E' && sub[1] != 'e') ||
261 sub[2] != ':')
262 type(out, "Re: ");
263 type(out, sub);
264 } /* In-response-to: */
265 type(out, "In-response-to: Message from ");
266 type(out, from);
267 if(date) {
268 date[length(date)-1] = '.';
269 if(*date == ' ') date++;
270 type(out, ", ");
271 type(out, date);
272 }
273 type(out, "\n");
274 if(msgid) {
275 type(out, " ");
276 if(*msgid == ' ') msgid++;
277 type(out, msgid);
278 }
279 type(out, "\t\t");
280 type(out, maildir);
281 type(out, "/");
282 type(out, msg);
283 type(out, "\n----------\n");
284 close(out);
285
286 if(m_edit(&ed, drft, NOUSE, msg) < 0)
287 return;
288 #ifdef TEST
289 printf("!! Test Version of SEND Being Run !!\n");
290 printf(" Send verbose !\n\n");
291 #endif
292
293 for(;;) {
294 if(!(argp = getans("\nWhat now? ", aleqs))) {
295 unlink("@");
296 return;
297 }
298 switch(smatch(*argp, aleqs)) {
299 case 0: showfile(drft); /* list */
300 break;
301 case 1: if(*++argp) /* edit */
302 ed = *argp;
303 if(m_edit(&ed, drft, NOUSE, msg) == -1)
304 return;
305 break;
306 case 2: if(*++argp && *argp[0] == 'd') /* quit */
307 if(unlink(drft) == -1) {
308 printf("Can't unlink %s ", drft);
309 perror("");
310 }
311 return;
312 case 3: if(*++argp) cp = *argp; else cp = ""; /* send */
313
314 if(!mp->msgflags&READONLY) { /* annotate first */
315 if(anot > 0) {
316 while((pid = fork()) == -1) sleep(5);
317 if(pid) {
318 while(wpid=wait()!= -1 && wpid!= pid);
319 if(stat(drft, field) == -1)
320 annotate(msg, "Responded", "");
321 return;
322 }
323 }
324 }
325 if(!m_send(cp, drft))
326 return;
327 default:printf("resp: illegal option\n"); /*##*/
328 break;
329 }