]> diplodocus.org Git - nmh/blob - uip/comp.c
* I had alphabetized the --configure options in the --help output
[nmh] / uip / comp.c
1
2 /*
3 * comp.c -- compose a message
4 *
5 * $Id$
6 */
7
8 #include <h/mh.h>
9 #include <fcntl.h>
10
11 static struct swit switches[] = {
12 #define DFOLDSW 0
13 { "draftfolder +folder", 0 },
14 #define DMSGSW 1
15 { "draftmessage msg", 0 },
16 #define NDFLDSW 2
17 { "nodraftfolder", 0 },
18 #define EDITRSW 3
19 { "editor editor", 0 },
20 #define NEDITSW 4
21 { "noedit", 0 },
22 #define FILESW 5
23 { "file file", 0 },
24 #define FORMSW 6
25 { "form formfile", 0 },
26 #define USESW 7
27 { "use", 0 },
28 #define NUSESW 8
29 { "nouse", 0 },
30 #define WHATSW 9
31 { "whatnowproc program", 0 },
32 #define NWHATSW 10
33 { "nowhatnowproc", 0 },
34 #define VERSIONSW 11
35 { "version", 0 },
36 #define HELPSW 12
37 { "help", 0 },
38 { NULL, 0 }
39 };
40
41 static struct swit aqrunl[] = {
42 #define NOSW 0
43 { "quit", 0 },
44 #define YESW 1
45 { "replace", 0 },
46 #define USELSW 2
47 { "use", 0 },
48 #define LISTDSW 3
49 { "list", 0 },
50 #define REFILSW 4
51 { "refile +folder", 0 },
52 #define NEWSW 5
53 { "new", 0 },
54 { NULL, 0 }
55 };
56
57 static struct swit aqrul[] = {
58 { "quit", 0 },
59 { "replace", 0 },
60 { "use", 0 },
61 { "list", 0 },
62 { "refile", 0 },
63 { NULL, 0 }
64 };
65
66
67 int
68 main (int argc, char **argv)
69 {
70 int use = NOUSE, nedit = 0, nwhat = 0;
71 int i, in, isdf = 0, out;
72 char *cp, *cwd, *maildir, *dfolder = NULL;
73 char *ed = NULL, *file = NULL, *form = NULL;
74 char *folder = NULL, *msg = NULL, buf[BUFSIZ];
75 char drft[BUFSIZ], **argp, **arguments;
76 struct msgs *mp = NULL;
77 struct stat st;
78
79 #ifdef LOCALE
80 setlocale(LC_ALL, "");
81 #endif
82 invo_name = r1bindex (argv[0], '/');
83
84 /* read user profile/context */
85 context_read();
86
87 arguments = getarguments (invo_name, argc, argv, 1);
88 argp = arguments;
89
90 while ((cp = *argp++)) {
91 if (*cp == '-') {
92 switch (smatch (++cp, switches)) {
93 case AMBIGSW:
94 ambigsw (cp, switches);
95 done (1);
96 case UNKWNSW:
97 adios (NULL, "-%s unknown", cp);
98
99 case HELPSW:
100 snprintf (buf, sizeof(buf), "%s [+folder] [msg] [switches]",
101 invo_name);
102 print_help (buf, switches, 1);
103 done (1);
104 case VERSIONSW:
105 print_version(invo_name);
106 done (1);
107
108 case EDITRSW:
109 if (!(ed = *argp++) || *ed == '-')
110 adios (NULL, "missing argument to %s", argp[-2]);
111 nedit = 0;
112 continue;
113 case NEDITSW:
114 nedit++;
115 continue;
116
117 case WHATSW:
118 if (!(whatnowproc = *argp++) || *whatnowproc == '-')
119 adios (NULL, "missing argument to %s", argp[-2]);
120 nwhat = 0;
121 continue;
122 case NWHATSW:
123 nwhat++;
124 continue;
125
126 case FORMSW:
127 if (!(form = *argp++) || *form == '-')
128 adios (NULL, "missing argument to %s", argp[-2]);
129 continue;
130
131 case USESW:
132 use++;
133 continue;
134 case NUSESW:
135 use = NOUSE;
136 continue;
137
138 case FILESW: /* compatibility */
139 if (file)
140 adios (NULL, "only one file at a time!");
141 if (!(file = *argp++) || *file == '-')
142 adios (NULL, "missing argument to %s", argp[-2]);
143 isdf = NOTOK;
144 continue;
145
146 case DFOLDSW:
147 if (dfolder)
148 adios (NULL, "only one draft folder at a time!");
149 if (!(cp = *argp++) || *cp == '-')
150 adios (NULL, "missing argument to %s", argp[-2]);
151 dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
152 *cp != '@' ? TFOLDER : TSUBCWF);
153 continue;
154 case DMSGSW:
155 if (file)
156 adios (NULL, "only one draft message at a time!");
157 if (!(file = *argp++) || *file == '-')
158 adios (NULL, "missing argument to %s", argp[-2]);
159 continue;
160 case NDFLDSW:
161 dfolder = NULL;
162 isdf = NOTOK;
163 continue;
164 }
165 }
166 if (*cp == '+' || *cp == '@') {
167 if (folder)
168 adios (NULL, "only one folder at a time!");
169 else
170 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
171 } else {
172 if (msg)
173 adios (NULL, "only one message at a time!");
174 else
175 msg = cp;
176 }
177 }
178
179 cwd = getcpy (pwd ());
180
181 if (!context_find ("path"))
182 free (path ("./", TFOLDER));
183
184 /*
185 * Check if we are using a draft folder
186 * and have specified a message in it.
187 */
188 if ((dfolder || context_find ("Draft-Folder")) && !folder && msg && !file) {
189 file = msg;
190 msg = NULL;
191 }
192 if (form && (folder || msg))
193 adios (NULL, "can't mix forms and folders/msgs");
194
195 if (folder || msg) {
196 /*
197 * Use a message as the "form" for the new message.
198 */
199 if (!msg)
200 msg = "cur";
201 if (!folder)
202 folder = getfolder (1);
203 maildir = m_maildir (folder);
204
205 if (chdir (maildir) == NOTOK)
206 adios (maildir, "unable to change directory to");
207
208 /* read folder and create message structure */
209 if (!(mp = folder_read (folder)))
210 adios (NULL, "unable to read folder %s", folder);
211
212 /* check for empty folder */
213 if (mp->nummsg == 0)
214 adios (NULL, "no messages in %s", folder);
215
216 /* parse the message range/sequence/name and set SELECTED */
217 if (!m_convert (mp, msg))
218 done (1);
219 seq_setprev (mp); /* set the previous-sequence */
220
221 if (mp->numsel > 1)
222 adios (NULL, "only one message at a time!");
223
224 if ((in = open (form = getcpy (m_name (mp->lowsel)), O_RDONLY)) == NOTOK)
225 adios (form, "unable to open message");
226 } else {
227 /*
228 * Open a component or forms file
229 */
230 if (form) {
231 if ((in = open (etcpath (form), O_RDONLY)) == NOTOK)
232 adios (form, "unable to open form file");
233 } else {
234 if ((in = open (etcpath (components), O_RDONLY)) == NOTOK)
235 adios (components, "unable to open default components file");
236 form = components;
237 }
238 }
239
240 try_it_again:
241 strncpy (drft, m_draft (dfolder, file, use, &isdf), sizeof(drft));
242
243 /*
244 * Check if we have an existing draft
245 */
246 if ((out = open (drft, O_RDONLY)) != NOTOK) {
247 i = fdcompare (in, out);
248 close (out);
249
250 /*
251 * If we have given -use flag, or if the
252 * draft is just the same as the components
253 * file, then no need to ask any questions.
254 */
255 if (use || i)
256 goto edit_it;
257
258 if (stat (drft, &st) == NOTOK)
259 adios (drft, "unable to stat");
260 printf ("Draft \"%s\" exists (%ld bytes).", drft, (long) st.st_size);
261 for (i = LISTDSW; i != YESW;) {
262 if (!(argp = getans ("\nDisposition? ", isdf ? aqrunl : aqrul)))
263 done (1);
264 switch (i = smatch (*argp, isdf ? aqrunl : aqrul)) {
265 case NOSW:
266 done (0);
267 case NEWSW:
268 file = NULL;
269 use = NOUSE;
270 goto try_it_again;
271 case YESW:
272 break;
273 case USELSW:
274 use++;
275 goto edit_it;
276 case LISTDSW:
277 showfile (++argp, drft);
278 break;
279 case REFILSW:
280 if (refile (++argp, drft) == 0)
281 i = YESW;
282 break;
283 default:
284 advise (NULL, "say what?");
285 break;
286 }
287 }
288 } else {
289 if (use)
290 adios (drft, "unable to open");
291 }
292
293 if ((out = creat (drft, m_gmprot ())) == NOTOK)
294 adios (drft, "unable to create");
295 cpydata (in, out, form, drft);
296 close (in);
297 close (out);
298
299 edit_it:
300 context_save (); /* save the context file */
301
302 if (nwhat)
303 done (0);
304 what_now (ed, nedit, use, drft, NULL, 0, NULLMP, NULL, 0, cwd);
305 return done (1);
306 }