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