1 | |
---|
2 | /* |
---|
3 | * forw.c -- forward a message, or group of messages. |
---|
4 | * |
---|
5 | * $Id: forw.c,v 1.1.1.1 1999-02-07 18:14:13 danw Exp $ |
---|
6 | */ |
---|
7 | |
---|
8 | #include <h/mh.h> |
---|
9 | #include <fcntl.h> |
---|
10 | #include <h/fmt_scan.h> |
---|
11 | #include <zotnet/tws/tws.h> |
---|
12 | |
---|
13 | |
---|
14 | #define IFORMAT "digest-issue-%s" |
---|
15 | #define VFORMAT "digest-volume-%s" |
---|
16 | |
---|
17 | static struct swit switches[] = { |
---|
18 | #define ANNOSW 0 |
---|
19 | { "annotate", 0 }, |
---|
20 | #define NANNOSW 1 |
---|
21 | { "noannotate", 0 }, |
---|
22 | #define DFOLDSW 2 |
---|
23 | { "draftfolder +folder", 0 }, |
---|
24 | #define DMSGSW 3 |
---|
25 | { "draftmessage msg", 0 }, |
---|
26 | #define NDFLDSW 4 |
---|
27 | { "nodraftfolder", 0 }, |
---|
28 | #define EDITRSW 5 |
---|
29 | { "editor editor", 0 }, |
---|
30 | #define NEDITSW 6 |
---|
31 | { "noedit", 0 }, |
---|
32 | #define FILTSW 7 |
---|
33 | { "filter filterfile", 0 }, |
---|
34 | #define FORMSW 8 |
---|
35 | { "form formfile", 0 }, |
---|
36 | #define FRMTSW 9 |
---|
37 | { "format", 5 }, |
---|
38 | #define NFRMTSW 10 |
---|
39 | { "noformat", 7 }, |
---|
40 | #define INPLSW 11 |
---|
41 | { "inplace", 0 }, |
---|
42 | #define NINPLSW 12 |
---|
43 | { "noinplace", 0 }, |
---|
44 | #define MIMESW 13 |
---|
45 | { "mime", 0 }, |
---|
46 | #define NMIMESW 14 |
---|
47 | { "nomime", 0 }, |
---|
48 | #define DGSTSW 15 |
---|
49 | { "digest list", 0 }, |
---|
50 | #define ISSUESW 16 |
---|
51 | { "issue number", 0 }, |
---|
52 | #define VOLUMSW 17 |
---|
53 | { "volume number", 0 }, |
---|
54 | #define WHATSW 18 |
---|
55 | { "whatnowproc program", 0 }, |
---|
56 | #define NWHATSW 19 |
---|
57 | { "nowhatnowproc", 0 }, |
---|
58 | #define BITSTUFFSW 20 |
---|
59 | { "dashstuffing", 0 }, /* interface to mhl */ |
---|
60 | #define NBITSTUFFSW 21 |
---|
61 | { "nodashstuffing", 0 }, |
---|
62 | #define VERSIONSW 22 |
---|
63 | { "version", 0 }, |
---|
64 | #define HELPSW 23 |
---|
65 | { "help", 4 }, |
---|
66 | #define FILESW 24 |
---|
67 | { "file file", -4 }, /* interface from msh */ |
---|
68 | |
---|
69 | #ifdef MHE |
---|
70 | #define BILDSW 25 |
---|
71 | { "build", -5 }, /* interface from mhe */ |
---|
72 | #endif /* MHE */ |
---|
73 | |
---|
74 | { NULL, 0 } |
---|
75 | }; |
---|
76 | |
---|
77 | static struct swit aqrnl[] = { |
---|
78 | #define NOSW 0 |
---|
79 | { "quit", 0 }, |
---|
80 | #define YESW 1 |
---|
81 | { "replace", 0 }, |
---|
82 | #define LISTDSW 2 |
---|
83 | { "list", 0 }, |
---|
84 | #define REFILSW 3 |
---|
85 | { "refile +folder", 0 }, |
---|
86 | #define NEWSW 4 |
---|
87 | { "new", 0 }, |
---|
88 | { NULL, 0 } |
---|
89 | }; |
---|
90 | |
---|
91 | static struct swit aqrl[] = { |
---|
92 | { "quit", 0 }, |
---|
93 | { "replace", 0 }, |
---|
94 | { "list", 0 }, |
---|
95 | { "refile +folder", 0 }, |
---|
96 | { NULL, 0 } |
---|
97 | }; |
---|
98 | |
---|
99 | static char drft[BUFSIZ]; |
---|
100 | |
---|
101 | static char delim3[] = |
---|
102 | "\n------------------------------------------------------------\n\n"; |
---|
103 | static char delim4[] = "\n------------------------------\n\n"; |
---|
104 | |
---|
105 | |
---|
106 | static struct msgs *mp = NULL; /* used a lot */ |
---|
107 | |
---|
108 | |
---|
109 | /* |
---|
110 | * static prototypes |
---|
111 | */ |
---|
112 | static void mhl_draft (int, char *, int, int, char *, char *, int); |
---|
113 | static void copy_draft (int, char *, char *, int, int, int); |
---|
114 | static void copy_mime_draft (int); |
---|
115 | static int build_form (char *, char *, int, int); |
---|
116 | |
---|
117 | |
---|
118 | int |
---|
119 | main (int argc, char **argv) |
---|
120 | { |
---|
121 | int msgp = 0, anot = 0, inplace = 1, mime = 0; |
---|
122 | int issue = 0, volume = 0, dashstuff = 0; |
---|
123 | int nedit = 0, nwhat = 0, i, in; |
---|
124 | int out, isdf = 0, msgnum; |
---|
125 | char *cp, *cwd, *maildir, *dfolder = NULL; |
---|
126 | char *dmsg = NULL, *digest = NULL, *ed = NULL; |
---|
127 | char *file = NULL, *filter = NULL, *folder = NULL; |
---|
128 | char *form = NULL, buf[BUFSIZ], value[10]; |
---|
129 | char **argp, **arguments, *msgs[MAXARGS]; |
---|
130 | struct stat st; |
---|
131 | |
---|
132 | #ifdef MHE |
---|
133 | int buildsw = 0; |
---|
134 | #endif /* MHE */ |
---|
135 | |
---|
136 | #ifdef LOCALE |
---|
137 | setlocale(LC_ALL, ""); |
---|
138 | #endif |
---|
139 | invo_name = r1bindex (argv[0], '/'); |
---|
140 | |
---|
141 | /* read user profile/context */ |
---|
142 | context_read(); |
---|
143 | |
---|
144 | arguments = getarguments (invo_name, argc, argv, 1); |
---|
145 | argp = arguments; |
---|
146 | |
---|
147 | while ((cp = *argp++)) { |
---|
148 | if (*cp == '-') { |
---|
149 | switch (smatch (++cp, switches)) { |
---|
150 | case AMBIGSW: |
---|
151 | ambigsw (cp, switches); |
---|
152 | done (1); |
---|
153 | case UNKWNSW: |
---|
154 | adios (NULL, "-%s unknown", cp); |
---|
155 | |
---|
156 | case HELPSW: |
---|
157 | snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]", |
---|
158 | invo_name); |
---|
159 | print_help (buf, switches, 1); |
---|
160 | done (1); |
---|
161 | case VERSIONSW: |
---|
162 | print_version(invo_name); |
---|
163 | done (1); |
---|
164 | |
---|
165 | case ANNOSW: |
---|
166 | anot++; |
---|
167 | continue; |
---|
168 | case NANNOSW: |
---|
169 | anot = 0; |
---|
170 | continue; |
---|
171 | |
---|
172 | case EDITRSW: |
---|
173 | if (!(ed = *argp++) || *ed == '-') |
---|
174 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
175 | nedit = 0; |
---|
176 | continue; |
---|
177 | case NEDITSW: |
---|
178 | nedit++; |
---|
179 | continue; |
---|
180 | |
---|
181 | case WHATSW: |
---|
182 | if (!(whatnowproc = *argp++) || *whatnowproc == '-') |
---|
183 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
184 | nwhat = 0; |
---|
185 | continue; |
---|
186 | #ifdef MHE |
---|
187 | case BILDSW: |
---|
188 | buildsw++; /* fall... */ |
---|
189 | #endif /* MHE */ |
---|
190 | case NWHATSW: |
---|
191 | nwhat++; |
---|
192 | continue; |
---|
193 | |
---|
194 | case FILESW: |
---|
195 | if (file) |
---|
196 | adios (NULL, "only one file at a time!"); |
---|
197 | if (!(cp = *argp++) || *cp == '-') |
---|
198 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
199 | file = path (cp, TFILE); |
---|
200 | continue; |
---|
201 | case FILTSW: |
---|
202 | if (!(cp = *argp++) || *cp == '-') |
---|
203 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
204 | filter = getcpy (etcpath (cp)); |
---|
205 | mime = 0; |
---|
206 | continue; |
---|
207 | case FORMSW: |
---|
208 | if (!(form = *argp++) || *form == '-') |
---|
209 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
210 | continue; |
---|
211 | |
---|
212 | case FRMTSW: |
---|
213 | filter = getcpy (etcpath (mhlforward)); |
---|
214 | continue; |
---|
215 | case NFRMTSW: |
---|
216 | filter = NULL; |
---|
217 | continue; |
---|
218 | |
---|
219 | case INPLSW: |
---|
220 | inplace++; |
---|
221 | continue; |
---|
222 | case NINPLSW: |
---|
223 | inplace = 0; |
---|
224 | continue; |
---|
225 | |
---|
226 | case MIMESW: |
---|
227 | mime++; |
---|
228 | filter = NULL; |
---|
229 | continue; |
---|
230 | case NMIMESW: |
---|
231 | mime = 0; |
---|
232 | continue; |
---|
233 | |
---|
234 | case DGSTSW: |
---|
235 | if (!(digest = *argp++) || *digest == '-') |
---|
236 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
237 | mime = 0; |
---|
238 | continue; |
---|
239 | case ISSUESW: |
---|
240 | if (!(cp = *argp++) || *cp == '-') |
---|
241 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
242 | if ((issue = atoi (cp)) < 1) |
---|
243 | adios (NULL, "bad argument %s %s", argp[-2], cp); |
---|
244 | continue; |
---|
245 | case VOLUMSW: |
---|
246 | if (!(cp = *argp++) || *cp == '-') |
---|
247 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
248 | if ((volume = atoi (cp)) < 1) |
---|
249 | adios (NULL, "bad argument %s %s", argp[-2], cp); |
---|
250 | continue; |
---|
251 | |
---|
252 | case DFOLDSW: |
---|
253 | if (dfolder) |
---|
254 | adios (NULL, "only one draft folder at a time!"); |
---|
255 | if (!(cp = *argp++) || *cp == '-') |
---|
256 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
257 | dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp, |
---|
258 | *cp != '@' ? TFOLDER : TSUBCWF); |
---|
259 | continue; |
---|
260 | case DMSGSW: |
---|
261 | if (dmsg) |
---|
262 | adios (NULL, "only one draft message at a time!"); |
---|
263 | if (!(dmsg = *argp++) || *dmsg == '-') |
---|
264 | adios (NULL, "missing argument to %s", argp[-2]); |
---|
265 | continue; |
---|
266 | case NDFLDSW: |
---|
267 | dfolder = NULL; |
---|
268 | isdf = NOTOK; |
---|
269 | continue; |
---|
270 | |
---|
271 | case BITSTUFFSW: |
---|
272 | dashstuff = 1; /* trinary logic */ |
---|
273 | continue; |
---|
274 | case NBITSTUFFSW: |
---|
275 | dashstuff = -1; /* trinary logic */ |
---|
276 | continue; |
---|
277 | } |
---|
278 | } |
---|
279 | if (*cp == '+' || *cp == '@') { |
---|
280 | if (folder) |
---|
281 | adios (NULL, "only one folder at a time!"); |
---|
282 | else |
---|
283 | folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); |
---|
284 | } else { |
---|
285 | msgs[msgp++] = cp; |
---|
286 | } |
---|
287 | } |
---|
288 | |
---|
289 | cwd = getcpy (pwd ()); |
---|
290 | |
---|
291 | if (!context_find ("path")) |
---|
292 | free (path ("./", TFOLDER)); |
---|
293 | if (file && (msgp || folder)) |
---|
294 | adios (NULL, "can't mix files and folders/msgs"); |
---|
295 | |
---|
296 | try_it_again: |
---|
297 | |
---|
298 | #ifdef MHE |
---|
299 | strncpy (drft, buildsw ? m_maildir ("draft") |
---|
300 | : m_draft (dfolder, NULL, NOUSE, &isdf), sizeof(drft)); |
---|
301 | |
---|
302 | /* Check if a draft already exists */ |
---|
303 | if (!buildsw && stat (drft, &st) != NOTOK) { |
---|
304 | #else |
---|
305 | strncpy (drft, m_draft (dfolder, dmsg, NOUSE, &isdf), sizeof(drft)); |
---|
306 | |
---|
307 | /* Check if a draft already exists */ |
---|
308 | if (stat (drft, &st) != NOTOK) { |
---|
309 | #endif /* MHE */ |
---|
310 | printf ("Draft \"%s\" exists (%ld bytes).", drft, (long) st.st_size); |
---|
311 | for (i = LISTDSW; i != YESW;) { |
---|
312 | if (!(argp = getans ("\nDisposition? ", isdf ? aqrnl : aqrl))) |
---|
313 | done (1); |
---|
314 | switch (i = smatch (*argp, isdf ? aqrnl : aqrl)) { |
---|
315 | case NOSW: |
---|
316 | done (0); |
---|
317 | case NEWSW: |
---|
318 | dmsg = NULL; |
---|
319 | goto try_it_again; |
---|
320 | case YESW: |
---|
321 | break; |
---|
322 | case LISTDSW: |
---|
323 | showfile (++argp, drft); |
---|
324 | break; |
---|
325 | case REFILSW: |
---|
326 | if (refile (++argp, drft) == 0) |
---|
327 | i = YESW; |
---|
328 | break; |
---|
329 | default: |
---|
330 | advise (NULL, "say what?"); |
---|
331 | break; |
---|
332 | } |
---|
333 | } |
---|
334 | } |
---|
335 | |
---|
336 | if (file) { |
---|
337 | /* |
---|
338 | * Forwarding a file. |
---|
339 | */ |
---|
340 | anot = 0; /* don't want to annotate a file */ |
---|
341 | } else { |
---|
342 | /* |
---|
343 | * Forwarding a message. |
---|
344 | */ |
---|
345 | if (!msgp) |
---|
346 | msgs[msgp++] = "cur"; |
---|
347 | if (!folder) |
---|
348 | folder = getfolder (1); |
---|
349 | maildir = m_maildir (folder); |
---|
350 | |
---|
351 | if (chdir (maildir) == NOTOK) |
---|
352 | adios (maildir, "unable to change directory to"); |
---|
353 | |
---|
354 | /* read folder and create message structure */ |
---|
355 | if (!(mp = folder_read (folder))) |
---|
356 | adios (NULL, "unable to read folder %s", folder); |
---|
357 | |
---|
358 | /* check for empty folder */ |
---|
359 | if (mp->nummsg == 0) |
---|
360 | adios (NULL, "no messages in %s", folder); |
---|
361 | |
---|
362 | /* parse all the message ranges/sequences and set SELECTED */ |
---|
363 | for (msgnum = 0; msgnum < msgp; msgnum++) |
---|
364 | if (!m_convert (mp, msgs[msgnum])) |
---|
365 | done (1); |
---|
366 | seq_setprev (mp); /* set the previous sequence */ |
---|
367 | } |
---|
368 | |
---|
369 | if (filter && access (filter, R_OK) == NOTOK) |
---|
370 | adios (filter, "unable to read"); |
---|
371 | |
---|
372 | /* |
---|
373 | * Open form (component) file. |
---|
374 | */ |
---|
375 | if (digest) { |
---|
376 | if (issue == 0) { |
---|
377 | snprintf (buf, sizeof(buf), IFORMAT, digest); |
---|
378 | if (volume == 0 |
---|
379 | && (cp = context_find (buf)) |
---|
380 | && ((issue = atoi (cp)) < 0)) |
---|
381 | issue = 0; |
---|
382 | issue++; |
---|
383 | } |
---|
384 | if (volume == 0) |
---|
385 | snprintf (buf, sizeof(buf), VFORMAT, digest); |
---|
386 | if ((cp = context_find (buf)) == NULL || (volume = atoi (cp)) <= 0) |
---|
387 | volume = 1; |
---|
388 | if (!form) |
---|
389 | form = digestcomps; |
---|
390 | in = build_form (form, digest, volume, issue); |
---|
391 | } else { |
---|
392 | if (form) { |
---|
393 | if ((in = open (etcpath (form), O_RDONLY)) == NOTOK) |
---|
394 | adios (form, "unable to open form file"); |
---|
395 | } else { |
---|
396 | if ((in = open (etcpath (forwcomps), O_RDONLY)) == NOTOK) |
---|
397 | adios (forwcomps, "unable to open default components file"); |
---|
398 | form = forwcomps; |
---|
399 | } |
---|
400 | } |
---|
401 | |
---|
402 | if ((out = creat (drft, m_gmprot ())) == NOTOK) |
---|
403 | adios (drft, "unable to create"); |
---|
404 | |
---|
405 | /* |
---|
406 | * copy the components into the draft |
---|
407 | */ |
---|
408 | cpydata (in, out, form, drft); |
---|
409 | close (in); |
---|
410 | |
---|
411 | if (file) { |
---|
412 | /* just copy the file into the draft */ |
---|
413 | if ((in = open (file, O_RDONLY)) == NOTOK) |
---|
414 | adios (file, "unable to open"); |
---|
415 | cpydata (in, out, file, drft); |
---|
416 | close (in); |
---|
417 | close (out); |
---|
418 | } else { |
---|
419 | /* |
---|
420 | * If filter file is defined, then format the |
---|
421 | * messages into the draft using mhlproc. |
---|
422 | */ |
---|
423 | if (filter) |
---|
424 | mhl_draft (out, digest, volume, issue, drft, filter, dashstuff); |
---|
425 | else if (mime) |
---|
426 | copy_mime_draft (out); |
---|
427 | else |
---|
428 | copy_draft (out, digest, drft, volume, issue, dashstuff); |
---|
429 | close (out); |
---|
430 | |
---|
431 | if (digest) { |
---|
432 | snprintf (buf, sizeof(buf), IFORMAT, digest); |
---|
433 | snprintf (value, sizeof(value), "%d", issue); |
---|
434 | context_replace (buf, getcpy (value)); |
---|
435 | snprintf (buf, sizeof(buf), VFORMAT, digest); |
---|
436 | snprintf (value, sizeof(value), "%d", volume); |
---|
437 | context_replace (buf, getcpy (value)); |
---|
438 | } |
---|
439 | |
---|
440 | context_replace (pfolder, folder); /* update current folder */ |
---|
441 | seq_setcur (mp, mp->lowsel); /* update current message */ |
---|
442 | seq_save (mp); /* synchronize sequences */ |
---|
443 | context_save (); /* save the context file */ |
---|
444 | } |
---|
445 | |
---|
446 | if (nwhat) |
---|
447 | done (0); |
---|
448 | what_now (ed, nedit, NOUSE, drft, NULL, 0, mp, |
---|
449 | anot ? "Forwarded" : NULL, inplace, cwd); |
---|
450 | done (1); |
---|
451 | } |
---|
452 | |
---|
453 | |
---|
454 | /* |
---|
455 | * Filter the messages you are forwarding, into the |
---|
456 | * draft calling the mhlproc, and reading its output |
---|
457 | * from a pipe. |
---|
458 | */ |
---|
459 | |
---|
460 | static void |
---|
461 | mhl_draft (int out, char *digest, int volume, int issue, |
---|
462 | char *file, char *filter, int dashstuff) |
---|
463 | { |
---|
464 | pid_t child_id; |
---|
465 | int i, msgnum, pd[2]; |
---|
466 | char *vec[MAXARGS]; |
---|
467 | char buf1[BUFSIZ]; |
---|
468 | char buf2[BUFSIZ]; |
---|
469 | |
---|
470 | if (pipe (pd) == NOTOK) |
---|
471 | adios ("pipe", "unable to create"); |
---|
472 | |
---|
473 | vec[0] = r1bindex (mhlproc, '/'); |
---|
474 | |
---|
475 | for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++) |
---|
476 | sleep (5); |
---|
477 | switch (child_id) { |
---|
478 | case NOTOK: |
---|
479 | adios ("fork", "unable to"); |
---|
480 | |
---|
481 | case OK: |
---|
482 | close (pd[0]); |
---|
483 | dup2 (pd[1], 1); |
---|
484 | close (pd[1]); |
---|
485 | |
---|
486 | i = 1; |
---|
487 | vec[i++] = "-forwall"; |
---|
488 | vec[i++] = "-form"; |
---|
489 | vec[i++] = filter; |
---|
490 | |
---|
491 | if (digest) { |
---|
492 | vec[i++] = "-digest"; |
---|
493 | vec[i++] = digest; |
---|
494 | vec[i++] = "-issue"; |
---|
495 | snprintf (buf1, sizeof(buf1), "%d", issue); |
---|
496 | vec[i++] = buf1; |
---|
497 | vec[i++] = "-volume"; |
---|
498 | snprintf (buf2, sizeof(buf2), "%d", volume); |
---|
499 | vec[i++] = buf2; |
---|
500 | } |
---|
501 | |
---|
502 | /* |
---|
503 | * Are we dashstuffing (quoting) the lines that begin |
---|
504 | * with `-'. We use the mhl default (don't add any flag) |
---|
505 | * unless the user has specified a specific flag. |
---|
506 | */ |
---|
507 | if (dashstuff > 0) |
---|
508 | vec[i++] = "-dashstuffing"; |
---|
509 | else if (dashstuff < 0) |
---|
510 | vec[i++] = "-nodashstuffing"; |
---|
511 | |
---|
512 | if (mp->numsel >= MAXARGS - i) |
---|
513 | adios (NULL, "more than %d messages for %s exec", |
---|
514 | vec[0], MAXARGS - i); |
---|
515 | |
---|
516 | /* |
---|
517 | * Now add the message names to filter. We can only |
---|
518 | * handle about 995 messages (because vec is fixed size), |
---|
519 | * but that should be plenty. |
---|
520 | */ |
---|
521 | for (msgnum = mp->lowsel; msgnum <= mp->hghsel && i < sizeof(vec) - 1; |
---|
522 | msgnum++) |
---|
523 | if (is_selected (mp, msgnum)) |
---|
524 | vec[i++] = getcpy (m_name (msgnum)); |
---|
525 | vec[i] = NULL; |
---|
526 | |
---|
527 | execvp (mhlproc, vec); |
---|
528 | fprintf (stderr, "unable to exec "); |
---|
529 | perror (mhlproc); |
---|
530 | _exit (-1); |
---|
531 | |
---|
532 | default: |
---|
533 | close (pd[1]); |
---|
534 | cpydata (pd[0], out, vec[0], file); |
---|
535 | close (pd[0]); |
---|
536 | pidXwait(child_id, mhlproc); |
---|
537 | break; |
---|
538 | } |
---|
539 | } |
---|
540 | |
---|
541 | |
---|
542 | /* |
---|
543 | * Copy the messages into the draft. The messages are |
---|
544 | * not filtered through the mhlproc. Do dashstuffing if |
---|
545 | * necessary. |
---|
546 | */ |
---|
547 | |
---|
548 | static void |
---|
549 | copy_draft (int out, char *digest, char *file, int volume, int issue, int dashstuff) |
---|
550 | { |
---|
551 | int fd,i, msgcnt, msgnum; |
---|
552 | int len, buflen; |
---|
553 | register char *bp, *msgnam; |
---|
554 | char buffer[BUFSIZ]; |
---|
555 | |
---|
556 | msgcnt = 1; |
---|
557 | for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) { |
---|
558 | if (is_selected (mp, msgnum)) { |
---|
559 | if (digest) { |
---|
560 | strncpy (buffer, msgnum == mp->lowsel ? delim3 : delim4, |
---|
561 | sizeof(buffer)); |
---|
562 | } else { |
---|
563 | /* Get buffer ready to go */ |
---|
564 | bp = buffer; |
---|
565 | buflen = sizeof(buffer); |
---|
566 | |
---|
567 | strncpy (bp, "\n-------", buflen); |
---|
568 | len = strlen (bp); |
---|
569 | bp += len; |
---|
570 | buflen -= len; |
---|
571 | |
---|
572 | if (msgnum == mp->lowsel) { |
---|
573 | snprintf (bp, buflen, " Forwarded Message%s", |
---|
574 | mp->numsel > 1 ? "s" : ""); |
---|
575 | } else { |
---|
576 | snprintf (bp, buflen, " Message %d", msgcnt); |
---|
577 | } |
---|
578 | len = strlen (bp); |
---|
579 | bp += len; |
---|
580 | buflen -= len; |
---|
581 | |
---|
582 | strncpy (bp, "\n\n", buflen); |
---|
583 | } |
---|
584 | write (out, buffer, strlen (buffer)); |
---|
585 | |
---|
586 | if ((fd = open (msgnam = m_name (msgnum), O_RDONLY)) == NOTOK) { |
---|
587 | admonish (msgnam, "unable to read message"); |
---|
588 | continue; |
---|
589 | } |
---|
590 | |
---|
591 | /* |
---|
592 | * Copy the message. Add RFC934 quoting (dashstuffing) |
---|
593 | * unless given the -nodashstuffing flag. |
---|
594 | */ |
---|
595 | if (dashstuff >= 0) |
---|
596 | cpydgst (fd, out, msgnam, file); |
---|
597 | else |
---|
598 | cpydata (fd, out, msgnam, file); |
---|
599 | |
---|
600 | close (fd); |
---|
601 | msgcnt++; |
---|
602 | } |
---|
603 | } |
---|
604 | |
---|
605 | if (digest) { |
---|
606 | strncpy (buffer, delim4, sizeof(buffer)); |
---|
607 | } else { |
---|
608 | snprintf (buffer, sizeof(buffer), "\n------- End of Forwarded Message%s\n\n", |
---|
609 | mp->numsel > 1 ? "s" : ""); |
---|
610 | } |
---|
611 | write (out, buffer, strlen (buffer)); |
---|
612 | |
---|
613 | if (digest) { |
---|
614 | snprintf (buffer, sizeof(buffer), "End of %s Digest [Volume %d Issue %d]\n", |
---|
615 | digest, volume, issue); |
---|
616 | i = strlen (buffer); |
---|
617 | for (bp = buffer + i; i > 1; i--) |
---|
618 | *bp++ = '*'; |
---|
619 | *bp++ = '\n'; |
---|
620 | *bp = 0; |
---|
621 | write (out, buffer, strlen (buffer)); |
---|
622 | } |
---|
623 | } |
---|
624 | |
---|
625 | |
---|
626 | /* |
---|
627 | * Create a mhn composition file for forwarding message. |
---|
628 | */ |
---|
629 | |
---|
630 | static void |
---|
631 | copy_mime_draft (int out) |
---|
632 | { |
---|
633 | int msgnum; |
---|
634 | char buffer[BUFSIZ]; |
---|
635 | |
---|
636 | snprintf (buffer, sizeof(buffer), "#forw [forwarded message%s] +%s", |
---|
637 | mp->numsel == 1 ? "" : "s", mp->foldpath); |
---|
638 | write (out, buffer, strlen (buffer)); |
---|
639 | for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) |
---|
640 | if (is_selected (mp, msgnum)) { |
---|
641 | snprintf (buffer, sizeof(buffer), " %s", m_name (msgnum)); |
---|
642 | write (out, buffer, strlen (buffer)); |
---|
643 | } |
---|
644 | write (out, "\n", 1); |
---|
645 | } |
---|
646 | |
---|
647 | |
---|
648 | static int |
---|
649 | build_form (char *form, char *digest, int volume, int issue) |
---|
650 | { |
---|
651 | int in; |
---|
652 | int fmtsize; |
---|
653 | register char *nfs; |
---|
654 | char *line, tmpfil[BUFSIZ]; |
---|
655 | register FILE *tmp; |
---|
656 | register struct comp *cptr; |
---|
657 | struct format *fmt; |
---|
658 | int dat[5]; |
---|
659 | |
---|
660 | /* Get new format string */ |
---|
661 | nfs = new_fs (form, NULL, NULL); |
---|
662 | fmtsize = strlen (nfs) + 256; |
---|
663 | |
---|
664 | /* Compile format string */ |
---|
665 | fmt_compile (nfs, &fmt); |
---|
666 | |
---|
667 | FINDCOMP (cptr, "digest"); |
---|
668 | if (cptr) |
---|
669 | cptr->c_text = digest; |
---|
670 | FINDCOMP (cptr, "date"); |
---|
671 | if (cptr) |
---|
672 | cptr->c_text = getcpy(dtimenow (0)); |
---|
673 | |
---|
674 | dat[0] = issue; |
---|
675 | dat[1] = volume; |
---|
676 | dat[2] = 0; |
---|
677 | dat[3] = fmtsize; |
---|
678 | dat[4] = 0; |
---|
679 | |
---|
680 | strncpy (tmpfil, m_tmpfil (invo_name), sizeof(tmpfil)); |
---|
681 | if ((tmp = fopen (tmpfil, "w+")) == NULL) |
---|
682 | adios (tmpfil, "unable to create"); |
---|
683 | unlink (tmpfil); |
---|
684 | if ((in = dup (fileno (tmp))) == NOTOK) |
---|
685 | adios ("dup", "unable to"); |
---|
686 | |
---|
687 | if ((line = malloc ((unsigned) fmtsize)) == NULL) |
---|
688 | adios (NULL, "unable to allocate format line storage"); |
---|
689 | fmt_scan (fmt, line, fmtsize, dat); |
---|
690 | fputs (line, tmp); |
---|
691 | free (line); |
---|
692 | if (fclose (tmp)) |
---|
693 | adios (tmpfil, "error writing"); |
---|
694 | |
---|
695 | lseek (in, (off_t) 0, SEEK_SET); |
---|
696 | return in; |
---|
697 | } |
---|