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