Removed (allmost all) JLR-specific code.
[mmh] / uip / repl.c
1 /*
2 ** repl.c -- reply to a message
3 **
4 ** This code is Copyright (c) 2002, by the authors of nmh.  See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
7 */
8
9 #include <h/mh.h>
10 #include <h/utils.h>
11
12
13 static struct swit switches[] = {
14 #define GROUPSW  0
15         { "group", 0 },
16 #define NGROUPSW  1
17         { "nogroup", 0 },
18 #define ANNOSW  2
19         { "annotate", 0 },
20 #define NANNOSW  3
21         { "noannotate", 0 },
22 #define CCSW  4
23         { "cc all|to|cc|me", 0 },
24 #define NCCSW  5
25         { "nocc type", 0 },
26 #define EDITRSW  6
27         { "editor editor", 0 },
28 #define NEDITSW  7
29         { "noedit", 0 },
30 #define FCCSW  8
31         { "fcc folder", 0 },
32 #define FILTSW  9
33         { "filter filterfile", 0 },
34 #define FORMSW  10
35         { "form formfile", 0 },
36 #define FRMTSW  11
37         { "format", 5 },
38 #define NFRMTSW  12
39         { "noformat", 7 },
40 #define INPLSW  13
41         { "inplace", 0 },
42 #define NINPLSW  14
43         { "noinplace", 0 },
44 #define MIMESW  15
45         { "mime", 0 },
46 #define NMIMESW  16
47         { "nomime", 0 },
48 #define QURYSW  17
49         { "query", 0 },
50 #define NQURYSW  18
51         { "noquery", 0 },
52 #define WHATSW  19
53         { "whatnowproc program", 0 },
54 #define NWHATSW  20
55         { "nowhatnowproc", 0 },
56 #define WIDTHSW  21
57         { "width columns", 0 },
58 #define VERSIONSW  22
59         { "version", 0 },
60 #define HELPSW  23
61         { "help", 0 },
62 #define FILESW  24
63         { "file file", 4 },  /* interface from msh */
64
65 #ifdef MHE
66 #define BILDSW  25
67         { "build", 5 },  /* interface from mhe */
68 #endif
69
70         { NULL, 0 }
71 };
72
73 static struct swit ccswitches[] = {
74 #define CTOSW  0
75         { "to", 0 },
76 #define CCCSW  1
77         { "cc", 0 },
78 #define CMESW  2
79         { "me", 0 },
80 #define CALSW  3
81         { "all", 0 },
82         { NULL, 0 }
83 };
84
85 short ccto = -1;  /* global for replsbr */
86 short cccc = -1;
87 short ccme = -1;
88 short querysw = 0;
89
90 short outputlinelen = OUTPUTLINELEN;
91 short groupreply = 0;  /* Is this a group reply? */
92
93 int mime = 0;  /* include original as MIME part */
94 char *form   = NULL;  /* form (components) file */
95 char *filter = NULL;  /* message filter file */
96 char *fcc = NULL;  /* folders to add to Fcc: header */
97
98
99 /*
100 ** prototypes
101 */
102 void docc(char *, int);
103
104
105 int
106 main(int argc, char **argv)
107 {
108         int anot = 0, inplace = 1;
109         int nedit = 0, nwhat = 0;
110         char *cp, *cwd, *dp, *maildir, *file = NULL;
111         char *folder = NULL, *msg = NULL;
112         char *ed = NULL, drft[BUFSIZ], buf[BUFSIZ];
113         char **argp, **arguments;
114         struct msgs *mp = NULL;
115         FILE *in;
116
117 #ifdef MHE
118         int buildsw = 0;
119 #endif /* MHE */
120
121 #ifdef LOCALE
122         setlocale(LC_ALL, "");
123 #endif
124         invo_name = mhbasename(argv[0]);
125
126         /* read user profile/context */
127         context_read();
128
129         arguments = getarguments(invo_name, argc, argv, 1);
130         argp = arguments;
131
132         while ((cp = *argp++)) {
133                 if (*cp == '-') {
134                         switch (smatch(++cp, switches)) {
135                         case AMBIGSW:
136                                 ambigsw(cp, switches);
137                                 done(1);
138                         case UNKWNSW:
139                                 adios(NULL, "-%s unknown", cp);
140
141                         case HELPSW:
142                                 snprintf(buf, sizeof(buf), "%s: [+folder] [msg] [switches]", invo_name);
143                                 print_help(buf, switches, 1);
144                                 done(0);
145                         case VERSIONSW:
146                                 print_version(invo_name);
147                                 done(1);
148
149                         case GROUPSW:
150                                 groupreply++;
151                                 continue;
152                         case NGROUPSW:
153                                 groupreply = 0;
154                                 continue;
155
156                         case ANNOSW:
157                                 anot++;
158                                 continue;
159                         case NANNOSW:
160                                 anot = 0;
161                                 continue;
162
163                         case CCSW:
164                                 if (!(cp = *argp++) || *cp == '-')
165                                         adios(NULL, "missing argument to %s",
166                                                         argp[-2]);
167                                 docc(cp, 1);
168                                 continue;
169                         case NCCSW:
170                                 if (!(cp = *argp++) || *cp == '-')
171                                         adios(NULL, "missing argument to %s",
172                                                         argp[-2]);
173                                 docc(cp, 0);
174                                 continue;
175
176                         case EDITRSW:
177                                 if (!(ed = *argp++) || *ed == '-')
178                                         adios(NULL, "missing argument to %s",
179                                                         argp[-2]);
180                                 nedit = 0;
181                                 continue;
182                         case NEDITSW:
183                                 nedit++;
184                                 continue;
185
186                         case WHATSW:
187                                 if (!(whatnowproc = *argp++) ||
188                                                 *whatnowproc == '-')
189                                         adios(NULL, "missing argument to %s",
190                                                         argp[-2]);
191                                 nwhat = 0;
192                                 continue;
193 #ifdef MHE
194                         case BILDSW:
195                                 buildsw++;  /* fall... */
196 #endif /* MHE */
197                         case NWHATSW:
198                                 nwhat++;
199                                 continue;
200
201                         case FCCSW:
202                                 if (!(cp = *argp++) || *cp == '-')
203                                         adios(NULL, "missing argument to %s",
204                                                         argp[-2]);
205                                 dp = NULL;
206                                 if (*cp == '@')
207                                         cp = dp = getcpy(expandfol(cp));
208                                 if (fcc)
209                                         fcc = add(", ", fcc);
210                                 fcc = add(cp, fcc);
211                                 if (dp)
212                                         free(dp);
213                                 continue;
214
215                         case FILESW:
216                                 if (file)
217                                         adios(NULL, "only one file at a time!");
218                                 if (!(cp = *argp++) || *cp == '-')
219                                         adios(NULL, "missing argument to %s",
220                                                         argp[-2]);
221                                 file = getcpy(expanddir(cp));
222                                 continue;
223                         case FILTSW:
224                                 if (!(cp = *argp++) || *cp == '-')
225                                         adios(NULL, "missing argument to %s",
226                                                         argp[-2]);
227                                 filter = getcpy(etcpath(cp));
228                                 mime = 0;
229                                 continue;
230                         case FORMSW:
231                                 if (!(form = *argp++) || *form == '-')
232                                         adios(NULL, "missing argument to %s",
233                                                         argp[-2]);
234                                 continue;
235
236                         case FRMTSW:
237                                 filter = getcpy(etcpath(mhlreply));
238                                 mime = 0;
239                                 continue;
240                         case NFRMTSW:
241                                 filter = NULL;
242                                 continue;
243
244                         case INPLSW:
245                                 inplace++;
246                                 continue;
247                         case NINPLSW:
248                                 inplace = 0;
249                                 continue;
250
251                         case MIMESW:
252                                 mime++;
253                                 filter = NULL;
254                                 continue;
255                         case NMIMESW:
256                                 mime = 0;
257                                 continue;
258
259                         case QURYSW:
260                                 querysw++;
261                                 continue;
262                         case NQURYSW:
263                                 querysw = 0;
264                                 continue;
265
266                         case WIDTHSW:
267                                 if (!(cp = *argp++) || *cp == '-')
268                                         adios(NULL, "missing argument to %s",
269                                                         argp[-2]);
270                                 if ((outputlinelen = atoi(cp)) < 10)
271                                         adios(NULL, "impossible width %d",
272                                                         outputlinelen);
273                                 continue;
274                         }
275                 }
276                 if (*cp == '+' || *cp == '@') {
277                         if (folder)
278                                 adios(NULL, "only one folder at a time!");
279                         else
280                                 folder = getcpy(expandfol(cp));
281                 } else {
282                         if (msg)
283                                 adios(NULL, "only one message at a time!");
284                         else
285                                 msg = cp;
286                 }
287         }
288
289         if (ccto == -1)
290                 ccto = groupreply;
291         if (cccc == -1)
292                 cccc = groupreply;
293         if (ccme == -1)
294                 ccme = groupreply;
295
296         cwd = getcpy(pwd());
297
298         if (file && (msg || folder))
299                 adios(NULL, "can't mix files and folders/msgs");
300
301 #ifdef MHE
302         strncpy(drft, buildsw ? toabsdir("reply")
303                 : m_draft(seq_beyond), sizeof(drft));
304 #else
305         strncpy(drft, m_draft(seq_beyond), sizeof(drft));
306 #endif /* MHE */
307
308         if (file) {
309                 /*
310                 ** We are replying to a file.
311                 */
312                 anot = 0;  /* we don't want to annotate a file */
313         } else {
314                 /*
315                 ** We are replying to a message.
316                 */
317                 if (!msg)
318                         msg = seq_cur;
319                 if (!folder)
320                         folder = getcurfol();
321                 maildir = toabsdir(folder);
322
323                 if (chdir(maildir) == NOTOK)
324                         adios(maildir, "unable to change directory to");
325
326                 /* read folder and create message structure */
327                 if (!(mp = folder_read(folder)))
328                         adios(NULL, "unable to read folder %s", folder);
329
330                 /* check for empty folder */
331                 if (mp->nummsg == 0)
332                         adios(NULL, "no messages in %s", folder);
333
334                 /* parse the message range/sequence/name and set SELECTED */
335                 if (!m_convert(mp, msg))
336                         done(1);
337                 seq_setprev(mp);  /* set the previous-sequence */
338
339                 if (mp->numsel > 1)
340                         adios(NULL, "only one message at a time!");
341
342                 context_replace(curfolder, folder); /* update current folder */
343                 seq_setcur(mp, mp->lowsel);  /* update current message  */
344                 seq_save(mp);  /* synchronize sequences   */
345                 context_save();  /* save the context file   */
346         }
347
348         msg = file ? file : getcpy(m_name(mp->lowsel));
349
350         if ((in = fopen(msg, "r")) == NULL)
351                 adios(msg, "unable to open");
352
353         /* find form (components) file */
354         if (!form) {
355                 if (groupreply)
356                         form = etcpath(replgroupcomps);
357                 else
358                         form = etcpath(replcomps);
359         }
360
361         replout(in, msg, drft, mp, outputlinelen, mime, form, filter, fcc);
362         fclose(in);
363
364         if (nwhat)
365                 done(0);
366         what_now(ed, nedit, NOUSE, drft, msg, 0, mp, anot ? "Replied" : NULL,
367                         inplace, cwd);
368         done(1);
369         return 1;
370 }
371
372 void
373 docc(char *cp, int ccflag)
374 {
375         switch (smatch(cp, ccswitches)) {
376         case AMBIGSW:
377                 ambigsw(cp, ccswitches);
378                 done(1);
379         case UNKWNSW:
380                 adios(NULL, "-%scc %s unknown", ccflag ? "" : "no", cp);
381
382         case CTOSW:
383                 ccto = ccflag;
384                 break;
385
386         case CCCSW:
387                 cccc = ccflag;
388                 break;
389
390         case CMESW:
391                 ccme = ccflag;
392                 break;
393
394         case CALSW:
395                 ccto = cccc = ccme = ccflag;
396                 break;
397         }
398 }