Commit | Line | Data |
---|---|---|
ad787160 C |
1 | /* repl.c - reply to a message */ |
2 | #ifndef lint | |
3 | static char ident[] = "@(#)$Id: repl.c,v 1.8 1992/12/15 00:20:22 jromine Exp $"; | |
4 | #endif /* lint */ | |
5 | ||
6 | #include "../h/mh.h" | |
7 | #include <stdio.h> | |
8 | #include <sys/types.h> | |
9 | #include <sys/stat.h> | |
10 | #ifdef LOCALE | |
11 | #include <locale.h> | |
12 | #endif | |
13 | ||
14 | /* \f */ | |
15 | ||
16 | static struct swit switches[] = { | |
17 | #define ANNOSW 0 | |
18 | "annotate", 0, | |
19 | #define NANNOSW 1 | |
20 | "noannotate", 0, | |
21 | ||
22 | #define CCSW 2 | |
23 | "cc type", 0, | |
24 | #define NCCSW 3 | |
25 | "nocc type", 0, | |
26 | ||
27 | #define DFOLDSW 4 | |
28 | "draftfolder +folder", 0, | |
29 | #define DMSGSW 5 | |
30 | "draftmessage msg", 0, | |
31 | #define NDFLDSW 6 | |
32 | "nodraftfolder", 0, | |
33 | ||
34 | #define EDITRSW 7 | |
35 | "editor editor", 0, | |
36 | #define NEDITSW 8 | |
37 | "noedit", 0, | |
38 | ||
39 | #define FCCSW 9 | |
40 | "fcc folder", 0, | |
41 | ||
42 | #define FILTSW 10 | |
43 | "filter filterfile", 0, | |
44 | #define FORMSW 11 | |
45 | "form formfile", 0, | |
46 | ||
47 | #define FRMTSW 12 | |
48 | "format", -5, | |
49 | #define NFRMTSW 13 | |
50 | "noformat", -7, | |
51 | ||
52 | #define INPLSW 14 | |
53 | "inplace", 0, | |
54 | #define NINPLSW 15 | |
55 | "noinplace", 0, | |
56 | ||
57 | #define QURYSW 16 | |
58 | "query", 0, | |
59 | #define NQURYSW 17 | |
60 | "noquery", 0, | |
61 | ||
62 | #define WHATSW 18 | |
63 | "whatnowproc program", 0, | |
64 | #define NWHATSW 19 | |
65 | "nowhatnowproc", 0, | |
66 | ||
67 | #define WIDTHSW 20 | |
68 | "width columns", 0, | |
69 | ||
70 | #define HELPSW 21 | |
71 | "help", 4, | |
72 | ||
73 | #define FILESW 22 | |
74 | "file file", -4, /* interface from msh */ | |
75 | ||
76 | #ifdef MHE | |
77 | #define BILDSW 23 | |
78 | "build", -5, /* interface from mhe */ | |
79 | #endif /* MHE */ | |
80 | ||
81 | NULL, 0 | |
82 | }; | |
83 | ||
84 | ||
85 | static struct swit ccswitches[] = { | |
86 | #define CTOSW 0 | |
87 | "to", 0, | |
88 | #define CCCSW 1 | |
89 | "cc", 0, | |
90 | #define CMESW 2 | |
91 | "me", 0, | |
92 | #define CALSW 3 | |
93 | "all", 0, | |
94 | ||
95 | NULL, 0 | |
96 | }; | |
97 | ||
98 | /* \f */ | |
99 | ||
100 | static struct swit aqrnl[] = { | |
101 | #define NOSW 0 | |
102 | "quit", 0, | |
103 | #define YESW 1 | |
104 | "replace", 0, | |
105 | #define LISTDSW 2 | |
106 | "list", 0, | |
107 | #define REFILSW 3 | |
108 | "refile +folder", 0, | |
109 | #define NEWSW 4 | |
110 | "new", 0, | |
111 | ||
112 | NULL, 0 | |
113 | }; | |
114 | ||
115 | ||
116 | static struct swit aqrl[] = { | |
117 | "quit", 0, | |
118 | "replace", 0, | |
119 | "list", 0, | |
120 | "refile +folder", 0, | |
121 | ||
122 | NULL, 0 | |
123 | }; | |
124 | ||
125 | /* \f */ | |
126 | ||
127 | #ifndef ATHENA | |
128 | #define CCDFLT 1 | |
129 | #else /* ATHENA */ | |
130 | #define CCDFLT 0 | |
131 | #endif /* ATHENA */ | |
132 | ||
133 | short ccto = CCDFLT; /* global for replsbr */ | |
134 | short cccc = CCDFLT; | |
135 | short ccme = CCDFLT; | |
136 | short format = 1; | |
137 | short outputlinelen = OUTPUTLINELEN; | |
138 | short querysw = 0; | |
139 | ||
140 | char *fcc = NULL; /* global for replsbr */ | |
141 | char *filter = NULL; | |
142 | char *form = NULL; | |
143 | ||
144 | /* \f */ | |
145 | ||
146 | /* ARGSUSED */ | |
147 | ||
148 | main (argc, argv) | |
149 | int argc; | |
150 | char *argv[]; | |
151 | { | |
152 | int i, | |
153 | isdf = 0, | |
154 | anot = 0, | |
155 | inplace = 0, | |
156 | #ifdef MHE | |
157 | buildsw = 0, | |
158 | #endif /* MHE */ | |
159 | nedit = 0, | |
160 | nwhat = 0; | |
161 | char *cp, | |
162 | *cwd, | |
163 | *dp, | |
164 | *maildir, | |
165 | *file = NULL, | |
166 | *folder = NULL, | |
167 | *msg = NULL, | |
168 | *dfolder = NULL, | |
169 | *dmsg = NULL, | |
170 | *ed = NULL, | |
171 | drft[BUFSIZ], | |
172 | buf[100], | |
173 | **ap, | |
174 | **argp, | |
175 | *arguments[MAXARGS]; | |
176 | struct msgs *mp = NULL; | |
177 | struct stat st; | |
178 | FILE *in; | |
179 | ||
180 | #ifdef LOCALE | |
181 | setlocale(LC_ALL, ""); | |
182 | #endif | |
183 | invo_name = r1bindex (argv[0], '/'); | |
184 | if ((cp = m_find (invo_name)) != NULL) { | |
185 | ap = brkstring (cp = getcpy (cp), " ", "\n"); | |
186 | ap = copyip (ap, arguments); | |
187 | } | |
188 | else | |
189 | ap = arguments; | |
190 | (void) copyip (argv + 1, ap); | |
191 | argp = arguments; | |
192 | ||
193 | /* \f */ | |
194 | ||
195 | while (cp = *argp++) { | |
196 | if (*cp == '-') | |
197 | switch (smatch (++cp, switches)) { | |
198 | case AMBIGSW: | |
199 | ambigsw (cp, switches); | |
200 | done (1); | |
201 | case UNKWNSW: | |
202 | adios (NULLCP, "-%s unknown", cp); | |
203 | case HELPSW: | |
204 | (void) sprintf (buf, "%s: [+folder] [msg] [switches]", | |
205 | invo_name); | |
206 | help (buf, switches); | |
207 | done (0); | |
208 | ||
209 | case ANNOSW: | |
210 | anot++; | |
211 | continue; | |
212 | case NANNOSW: | |
213 | anot = 0; | |
214 | continue; | |
215 | ||
216 | case CCSW: | |
217 | if (!(cp = *argp++) || *cp == '-') | |
218 | adios (NULLCP, "missing argument to %s", argp[-2]); | |
219 | docc (cp, 1); | |
220 | continue; | |
221 | case NCCSW: | |
222 | if (!(cp = *argp++) || *cp == '-') | |
223 | adios (NULLCP, "missing argument to %s", argp[-2]); | |
224 | docc (cp, 0); | |
225 | continue; | |
226 | ||
227 | case EDITRSW: | |
228 | if (!(ed = *argp++) || *ed == '-') | |
229 | adios (NULLCP, "missing argument to %s", argp[-2]); | |
230 | nedit = 0; | |
231 | continue; | |
232 | case NEDITSW: | |
233 | nedit++; | |
234 | continue; | |
235 | ||
236 | case WHATSW: | |
237 | if (!(whatnowproc = *argp++) || *whatnowproc == '-') | |
238 | adios (NULLCP, "missing argument to %s", argp[-2]); | |
239 | nwhat = 0; | |
240 | continue; | |
241 | #ifdef MHE | |
242 | case BILDSW: | |
243 | buildsw++; /* fall... */ | |
244 | #endif /* MHE */ | |
245 | case NWHATSW: | |
246 | nwhat++; | |
247 | continue; | |
248 | ||
249 | case FCCSW: | |
250 | if (!(cp = *argp++) || *cp == '-') | |
251 | adios (NULLCP, "missing argument to %s", argp[-2]); | |
252 | dp = NULL; | |
253 | if (*cp == '@') | |
254 | cp = dp = path (cp + 1, TSUBCWF); | |
255 | if (fcc) | |
256 | fcc = add (", ", fcc); | |
257 | fcc = add (cp, fcc); | |
258 | if (dp) | |
259 | free (dp); | |
260 | continue; | |
261 | ||
262 | case FILESW: | |
263 | if (file) | |
264 | adios (NULLCP, "only one file at a time!"); | |
265 | if (!(cp = *argp++) || *cp == '-') | |
266 | adios (NULLCP, "missing argument to %s", argp[-2]); | |
267 | file = path (cp, TFILE); | |
268 | continue; | |
269 | case FILTSW: | |
270 | if (!(cp = *argp++) || *cp == '-') | |
271 | adios (NULLCP, "missing argument to %s", argp[-2]); | |
272 | filter = getcpy (libpath (cp)); | |
273 | continue; | |
274 | case FORMSW: | |
275 | if (!(form = *argp++) || *form == '-') | |
276 | adios (NULLCP, "missing argument to %s", argp[-2]); | |
277 | continue; | |
278 | ||
279 | case FRMTSW: | |
280 | format++; | |
281 | continue; | |
282 | case NFRMTSW: | |
283 | format = 0; | |
284 | continue; | |
285 | ||
286 | case INPLSW: | |
287 | inplace++; | |
288 | continue; | |
289 | case NINPLSW: | |
290 | inplace = 0; | |
291 | continue; | |
292 | ||
293 | case QURYSW: | |
294 | querysw++; | |
295 | continue; | |
296 | case NQURYSW: | |
297 | querysw = 0; | |
298 | continue; | |
299 | ||
300 | case WIDTHSW: | |
301 | if (!(cp = *argp++) || *cp == '-') | |
302 | adios (NULLCP, "missing argument to %s", argp[-2]); | |
303 | if ((outputlinelen = atoi (cp)) < 10) | |
304 | adios (NULLCP, "impossible width %d", outputlinelen); | |
305 | continue; | |
306 | ||
307 | case DFOLDSW: | |
308 | if (dfolder) | |
309 | adios (NULLCP, "only one draft folder at a time!"); | |
310 | if (!(cp = *argp++) || *cp == '-') | |
311 | adios (NULLCP, "missing argument to %s", argp[-2]); | |
312 | dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp, | |
313 | *cp != '@' ? TFOLDER : TSUBCWF); | |
314 | continue; | |
315 | case DMSGSW: | |
316 | if (dmsg) | |
317 | adios (NULLCP, "only one draft message at a time!"); | |
318 | if (!(dmsg = *argp++) || *dmsg == '-') | |
319 | adios (NULLCP, "missing argument to %s", argp[-2]); | |
320 | continue; | |
321 | case NDFLDSW: | |
322 | dfolder = NULL; | |
323 | isdf = NOTOK; | |
324 | continue; | |
325 | } | |
326 | if (*cp == '+' || *cp == '@') { | |
327 | if (folder) | |
328 | adios (NULLCP, "only one folder at a time!"); | |
329 | else | |
330 | folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); | |
331 | } | |
332 | else | |
333 | if (msg) | |
334 | adios (NULLCP, "only one message at a time!"); | |
335 | else | |
336 | msg = cp; | |
337 | } | |
338 | ||
339 | /* \f */ | |
340 | ||
341 | cwd = getcpy (pwd ()); | |
342 | ||
343 | if (!m_find ("path")) | |
344 | free (path ("./", TFOLDER)); | |
345 | if (file && (msg || folder)) | |
346 | adios (NULLCP, "can't mix files and folders/msgs"); | |
347 | ||
348 | try_it_again: ; | |
349 | #ifndef MHE | |
350 | (void) strcpy (drft, m_draft (dfolder, dmsg, NOUSE, &isdf)); | |
351 | if (stat (drft, &st) != NOTOK) { | |
352 | #else /* MHE */ | |
353 | (void) strcpy (drft, buildsw ? m_maildir ("reply") | |
354 | : m_draft (dfolder, NULLCP, NOUSE, &isdf)); | |
355 | if (!buildsw && stat (drft, &st) != NOTOK) { | |
356 | #endif /* MHE */ | |
357 | printf ("Draft \"%s\" exists (%ld bytes).", drft, st.st_size); | |
358 | for (i = LISTDSW; i != YESW;) { | |
359 | if (!(argp = getans ("\nDisposition? ", isdf ? aqrnl : aqrl))) | |
360 | done (1); | |
361 | switch (i = smatch (*argp, isdf ? aqrnl : aqrl)) { | |
362 | case NOSW: | |
363 | done (0); | |
364 | case NEWSW: | |
365 | dmsg = NULL; | |
366 | goto try_it_again; | |
367 | case YESW: | |
368 | break; | |
369 | case LISTDSW: | |
370 | (void) showfile (++argp, drft); | |
371 | break; | |
372 | case REFILSW: | |
373 | if (refile (++argp, drft) == 0) | |
374 | i = YESW; | |
375 | break; | |
376 | default: | |
377 | advise (NULLCP, "say what?"); | |
378 | break; | |
379 | } | |
380 | } | |
381 | } | |
382 | ||
383 | /* \f */ | |
384 | ||
385 | if (file) { | |
386 | anot = 0; | |
387 | goto go_to_it; | |
388 | } | |
389 | ||
390 | if (!msg) | |
391 | msg = "cur"; | |
392 | if (!folder) | |
393 | folder = m_getfolder (); | |
394 | maildir = m_maildir (folder); | |
395 | ||
396 | if (chdir (maildir) == NOTOK) | |
397 | adios (maildir, "unable to change directory to"); | |
398 | if (!(mp = m_gmsg (folder))) | |
399 | adios (NULLCP, "unable to read folder %s", folder); | |
400 | if (mp -> hghmsg == 0) | |
401 | adios (NULLCP, "no messages in %s", folder); | |
402 | ||
403 | if (!m_convert (mp, msg)) | |
404 | done (1); | |
405 | m_setseq (mp); | |
406 | ||
407 | if (mp -> numsel > 1) | |
408 | adios (NULLCP, "only one message at a time!"); | |
409 | ||
410 | m_replace (pfolder, folder); | |
411 | if (mp -> lowsel != mp -> curmsg) | |
412 | m_setcur (mp, mp -> lowsel); | |
413 | m_sync (mp); | |
414 | m_update (); | |
415 | ||
416 | go_to_it: ; | |
417 | msg = file ? file : getcpy (m_name (mp -> lowsel)); | |
418 | ||
419 | if ((in = fopen (msg, "r")) == NULL) | |
420 | adios (msg, "unable to open"); | |
421 | ||
422 | replout (in, msg, drft); | |
423 | (void) fclose (in); | |
424 | ||
425 | if (nwhat) | |
426 | done (0); | |
427 | (void) what_now (ed, nedit, NOUSE, drft, msg, 0, mp, | |
428 | anot ? "Replied" : NULLCP, inplace, cwd); | |
429 | done (1); | |
430 | } | |
431 | ||
432 | /* \f */ | |
433 | ||
434 | docc (cp, ccflag) | |
435 | register char *cp; | |
436 | int ccflag; | |
437 | { | |
438 | switch (smatch (cp, ccswitches)) { | |
439 | case AMBIGSW: | |
440 | ambigsw (cp, ccswitches); | |
441 | done (1); | |
442 | case UNKWNSW: | |
443 | adios (NULLCP, "-%scc %s unknown", ccflag ? "" : "no", cp); | |
444 | ||
445 | case CTOSW: | |
446 | ccto = ccflag; | |
447 | break; | |
448 | ||
449 | case CCCSW: | |
450 | cccc = ccflag; | |
451 | break; | |
452 | ||
453 | case CMESW: | |
454 | ccme = ccflag; | |
455 | break; | |
456 | ||
457 | case CALSW: | |
458 | ccto = cccc = ccme = ccflag; | |
459 | break; | |
460 | } | |
461 | } |