Reformated comments and long lines
[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 = r1bindex (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", argp[-2]);
166                                         docc (cp, 1);
167                                         continue;
168                                 case NCCSW:
169                                         if (!(cp = *argp++) || *cp == '-')
170                                                 adios (NULL, "missing argument to %s", argp[-2]);
171                                         docc (cp, 0);
172                                         continue;
173
174                                 case EDITRSW:
175                                         if (!(ed = *argp++) || *ed == '-')
176                                                 adios (NULL, "missing argument to %s", argp[-2]);
177                                         nedit = 0;
178                                         continue;
179                                 case NEDITSW:
180                                         nedit++;
181                                         continue;
182
183                                 case WHATSW:
184                                         if (!(whatnowproc = *argp++) ||
185                                                         *whatnowproc == '-')
186                                                 adios (NULL, "missing argument to %s", argp[-2]);
187                                         nwhat = 0;
188                                         continue;
189 #ifdef MHE
190                                 case BILDSW:
191                                         buildsw++;  /* fall... */
192 #endif /* MHE */
193                                 case NWHATSW:
194                                         nwhat++;
195                                         continue;
196
197                                 case FCCSW:
198                                         if (!(cp = *argp++) || *cp == '-')
199                                                 adios (NULL, "missing argument to %s", argp[-2]);
200                                         dp = NULL;
201                                         if (*cp == '@')
202                                                 cp = dp = path (cp + 1,
203                                                                 TSUBCWF);
204                                         if (fcc)
205                                                 fcc = add (", ", fcc);
206                                         fcc = add (cp, fcc);
207                                         if (dp)
208                                                 free (dp);
209                                         continue;
210
211                                 case FILESW:
212                                         if (file)
213                                                 adios (NULL, "only one file at a time!");
214                                         if (!(cp = *argp++) || *cp == '-')
215                                                 adios (NULL, "missing argument to %s", argp[-2]);
216                                         file = path (cp, TFILE);
217                                         continue;
218                                 case FILTSW:
219                                         if (!(cp = *argp++) || *cp == '-')
220                                                 adios (NULL, "missing argument to %s", argp[-2]);
221                                         filter = getcpy (etcpath (cp));
222                                         mime = 0;
223                                         continue;
224                                 case FORMSW:
225                                         if (!(form = *argp++) || *form == '-')
226                                                 adios (NULL, "missing argument to %s", argp[-2]);
227                                         continue;
228
229                                 case FRMTSW:
230                                         filter = getcpy (etcpath (mhlreply));
231                                         mime = 0;
232                                         continue;
233                                 case NFRMTSW:
234                                         filter = NULL;
235                                         continue;
236
237                                 case INPLSW:
238                                         inplace++;
239                                         continue;
240                                 case NINPLSW:
241                                         inplace = 0;
242                                         continue;
243
244                                 case MIMESW:
245                                         mime++;
246                                         filter = NULL;
247                                         continue;
248                                 case NMIMESW:
249                                         mime = 0;
250                                         continue;
251
252                                 case QURYSW:
253                                         querysw++;
254                                         continue;
255                                 case NQURYSW:
256                                         querysw = 0;
257                                         continue;
258
259                                 case WIDTHSW:
260                                         if (!(cp = *argp++) || *cp == '-')
261                                                 adios (NULL, "missing argument to %s", argp[-2]);
262                                         if ((outputlinelen = atoi (cp)) < 10)
263                                                 adios (NULL, "impossible width %d", outputlinelen);
264                                         continue;
265                         }
266                 }
267                 if (*cp == '+' || *cp == '@') {
268                         if (folder)
269                                 adios (NULL, "only one folder at a time!");
270                         else
271                                 folder = pluspath (cp);
272                 } else {
273                         if (msg)
274                                 adios (NULL, "only one message at a time!");
275                         else
276                                 msg = cp;
277                 }
278         }
279
280         if (ccto == -1)
281                 ccto = groupreply;
282         if (cccc == -1)
283                 cccc = groupreply;
284         if (ccme == -1)
285                 ccme = groupreply;
286
287         cwd = getcpy (pwd ());
288
289         if (!context_find ("path"))
290                 free (path ("./", TFOLDER));
291         if (file && (msg || folder))
292                 adios (NULL, "can't mix files and folders/msgs");
293
294 #ifdef MHE
295         strncpy (drft, buildsw ? m_maildir ("reply")
296                 : m_draft("new"), sizeof(drft));
297 #else
298         strncpy (drft, m_draft("new"), sizeof(drft));
299 #endif /* MHE */
300
301         if (file) {
302                 /*
303                 ** We are replying to a file.
304                 */
305                 anot = 0;  /* we don't want to annotate a file */
306         } else {
307                 /*
308                 ** We are replying to a message.
309                 */
310                 if (!msg)
311                         msg = "cur";
312                 if (!folder)
313                         folder = getfolder (1);
314                 maildir = m_maildir (folder);
315
316                 if (chdir (maildir) == NOTOK)
317                         adios (maildir, "unable to change directory to");
318
319                 /* read folder and create message structure */
320                 if (!(mp = folder_read (folder)))
321                         adios (NULL, "unable to read folder %s", folder);
322
323                 /* check for empty folder */
324                 if (mp->nummsg == 0)
325                         adios (NULL, "no messages in %s", folder);
326
327                 /* parse the message range/sequence/name and set SELECTED */
328                 if (!m_convert (mp, msg))
329                         done (1);
330                 seq_setprev (mp);  /* set the previous-sequence */
331
332                 if (mp->numsel > 1)
333                         adios (NULL, "only one message at a time!");
334
335                 context_replace (pfolder, folder);  /* update current folder */
336                 seq_setcur (mp, mp->lowsel);  /* update current message  */
337                 seq_save (mp);  /* synchronize sequences   */
338                 context_save ();  /* save the context file   */
339         }
340
341         msg = file ? file : getcpy (m_name (mp->lowsel));
342
343         if ((in = fopen (msg, "r")) == NULL)
344                 adios (msg, "unable to open");
345
346         /* find form (components) file */
347         if (!form) {
348                 if (groupreply)
349                         form = etcpath (replgroupcomps);
350                 else
351                         form = etcpath (replcomps);
352         }
353
354         replout (in, msg, drft, mp, outputlinelen, mime, form, filter, fcc);
355         fclose (in);
356
357         if (nwhat)
358                 done (0);
359         what_now (ed, nedit, NOUSE, drft, msg, 0, mp,
360                         anot ? "Replied" : NULL, inplace, cwd);
361         done (1);
362         return 1;
363 }
364
365 void
366 docc (char *cp, int ccflag)
367 {
368         switch (smatch (cp, ccswitches)) {
369                 case AMBIGSW:
370                         ambigsw (cp, ccswitches);
371                         done (1);
372                 case UNKWNSW:
373                         adios (NULL, "-%scc %s unknown",
374                                         ccflag ? "" : "no", cp);
375
376                 case CTOSW:
377                         ccto = ccflag;
378                         break;
379
380                 case CCCSW:
381                         cccc = ccflag;
382                         break;
383
384                 case CMESW:
385                         ccme = ccflag;
386                         break;
387
388                 case CALSW:
389                         ccto = cccc = ccme = ccflag;
390                         break;
391         }
392 }