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