1 /* forw.c - forward messages */
3 static char ident[] = "@(#)$Id: forw.c,v 1.15 1995/12/06 21:07:03 jromine Exp $";
7 #include "../h/formatsbr.h"
8 #include "../zotnet/tws.h"
10 #include <sys/types.h>
17 #define MIMEminc(a) (a)
22 #define IFORMAT "digest-issue-%s"
23 #define VFORMAT "digest-volume-%s"
25 static mhl_draft(), copy_draft(), build_form();
28 static struct swit switches[] = {
35 "draftfolder +folder", 0,
37 "draftmessage msg", 0,
47 "filter filterfile", 0,
64 "nomime", MIMEminc(-6),
74 "whatnowproc program", 0,
82 "file file", -4, /* interface from msh */
85 "dashmunging", -4, /* interface to mhl */
91 "build", -5, /* interface from mhe */
99 static struct swit aqrnl[] = {
115 static struct swit aqrl[] = {
126 static char drft[BUFSIZ];
128 static char delim3[] =
129 "\n------------------------------------------------------------\n\n";
130 static char delim4[] = "\n------------------------------\n\n";
133 static struct msgs *mp = NULL; /* used a lot */
184 setlocale(LC_ALL, "");
186 invo_name = r1bindex (argv[0], '/');
187 if ((cp = m_find (invo_name)) != NULL) {
188 ap = brkstring (cp = getcpy (cp), " ", "\n");
189 ap = copyip (ap, arguments);
193 (void) copyip (argv + 1, ap);
198 while (cp = *argp++) {
200 switch (smatch (++cp, switches)) {
202 ambigsw (cp, switches);
205 adios (NULLCP, "-%s unknown", cp);
207 (void) sprintf (buf, "%s [+folder] [msgs] [switches]",
209 help (buf, switches);
220 if (!(ed = *argp++) || *ed == '-')
221 adios (NULLCP, "missing argument to %s", argp[-2]);
229 if (!(whatnowproc = *argp++) || *whatnowproc == '-')
230 adios (NULLCP, "missing argument to %s", argp[-2]);
235 buildsw++; /* fall... */
243 adios (NULLCP, "only one file at a time!");
244 if (!(cp = *argp++) || *cp == '-')
245 adios (NULLCP, "missing argument to %s", argp[-2]);
246 file = path (cp, TFILE);
249 if (!(cp = *argp++) || *cp == '-')
250 adios (NULLCP, "missing argument to %s", argp[-2]);
251 filter = getcpy (libpath (cp));
255 if (!(form = *argp++) || *form == '-')
256 adios (NULLCP, "missing argument to %s", argp[-2]);
260 filter = getcpy (libpath (mhlforward));
284 if (!(digest = *argp++) || *digest == '-')
285 adios (NULLCP, "missing argument to %s", argp[-2]);
289 if (!(cp = *argp++) || *cp == '-')
290 adios (NULLCP, "missing argument to %s", argp[-2]);
291 if ((issue = atoi (cp)) < 1)
292 adios (NULLCP, "bad argument %s %s", argp[-2], cp);
295 if (!(cp = *argp++) || *cp == '-')
296 adios (NULLCP, "missing argument to %s", argp[-2]);
297 if ((volume = atoi (cp)) < 1)
298 adios (NULLCP, "bad argument %s %s", argp[-2], cp);
303 adios (NULLCP, "only one draft folder at a time!");
304 if (!(cp = *argp++) || *cp == '-')
305 adios (NULLCP, "missing argument to %s", argp[-2]);
306 dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp,
307 *cp != '@' ? TFOLDER : TSUBCWF);
311 adios (NULLCP, "only one draft message at a time!");
312 if (!(dmsg = *argp++) || *dmsg == '-')
313 adios (NULLCP, "missing argument to %s", argp[-2]);
327 if (*cp == '+' || *cp == '@') {
329 adios (NULLCP, "only one folder at a time!");
331 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
339 cwd = getcpy (pwd ());
341 if (!m_find ("path"))
342 free (path ("./", TFOLDER));
343 if (file && (msgp || folder))
344 adios (NULLCP, "can't mix files and folders/msgs");
348 (void) strcpy (drft, m_draft (dfolder, dmsg, NOUSE, &isdf));
349 if (stat (drft, &st) != NOTOK) {
351 (void) strcpy (drft, buildsw ? m_maildir ("draft")
352 : m_draft (dfolder, NULLCP, NOUSE, &isdf));
353 if (!buildsw && stat (drft, &st) != NOTOK) {
355 printf ("Draft \"%s\" exists (%ld bytes).", drft, (long) st.st_size);
356 for (i = LISTDSW; i != YESW;) {
357 if (!(argp = getans ("\nDisposition? ", isdf ? aqrnl : aqrl)))
359 switch (i = smatch (*argp, isdf ? aqrnl : aqrl)) {
368 (void) showfile (++argp, drft);
371 if (refile (++argp, drft) == 0)
375 advise (NULLCP, "say what?");
389 msgs[msgp++] = "cur";
391 folder = m_getfolder ();
392 maildir = m_maildir (folder);
394 if (chdir (maildir) == NOTOK)
395 adios (maildir, "unable to change directory to");
396 if (!(mp = m_gmsg (folder)))
397 adios (NULLCP, "unable to read folder %s", folder);
398 if (mp -> hghmsg == 0)
399 adios (NULLCP, "no messages in %s", folder);
401 for (msgnum = 0; msgnum < msgp; msgnum++)
402 if (!m_convert (mp, msgs[msgnum]))
409 if (filter && access (filter, 04) == NOTOK)
410 adios (filter, "unable to read");
414 (void) sprintf (buf, IFORMAT, digest);
416 && (cp = m_find (buf))
417 && ((issue = atoi (cp)) < 0))
422 (void) sprintf (buf, VFORMAT, digest);
423 if ((cp = m_find (buf)) == NULL || (volume = atoi (cp)) <= 0)
427 in = build_form (form, digest, volume, issue);
431 if ((in = open (libpath (form), 0)) == NOTOK)
432 adios (form, "unable to open form file");
435 if ((in = open (libpath (forwcomps), 0)) == NOTOK)
436 adios (forwcomps, "unable to open default components file");
440 if ((out = creat (drft, m_gmprot ())) == NOTOK)
441 adios (drft, "unable to create");
443 cpydata (in, out, form, drft);
449 if ((in = open (file, 0)) == NOTOK)
450 adios (file, "unable to open");
451 cpydata (in, out, file, drft);
458 mhl_draft (out, digest, volume, issue, drft, filter, dashflg);
460 copy_draft (out, digest, drft, volume, issue, mime);
464 (void) sprintf (buf, IFORMAT, digest);
465 (void) sprintf (value, "%d", issue);
466 m_replace (buf, getcpy (value));
467 (void) sprintf (buf, VFORMAT, digest);
468 (void) sprintf (value, "%d", volume);
469 m_replace (buf, getcpy (value));
472 m_replace (pfolder, folder);
473 if (mp -> lowsel != mp -> curmsg)
474 m_setcur (mp, mp -> lowsel);
481 (void) what_now (ed, nedit, NOUSE, drft, NULLCP, 0, mp,
482 anot ? "Forwarded" : NULLCP, inplace, cwd);
488 static mhl_draft (out, digest, volume, issue, file, filter, dashflg)
493 register char *digest,
505 if (pipe (pd) == NOTOK)
506 adios ("pipe", "unable to create");
508 vec[0] = r1bindex (mhlproc, '/');
510 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
514 adios ("fork", "unable to");
517 (void) close (pd[0]);
518 (void) dup2 (pd[1], 1);
519 (void) close (pd[1]);
522 vec[i++] = "-forwall";
526 vec[i++] = "-digest";
529 sprintf(buf1, "%d", issue); vec[i++] = buf1;
530 vec[i++] = "-volume";
531 sprintf(buf2, "%d", volume); vec[i++] = buf2;
533 vec[i++] = dashflg ? "-dashmunging" : "-nodashmunging";
534 if (mp -> numsel >= MAXARGS - i)
535 adios (NULLCP, "more than %d messages for %s exec",
536 vec[0], MAXARGS - i);
537 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
538 if (mp -> msgstats[msgnum] & SELECTED)
539 vec[i++] = getcpy (m_name (msgnum));
542 execvp (mhlproc, vec);
543 fprintf (stderr, "unable to exec ");
548 (void) close (pd[1]);
549 cpydata (pd[0], out, vec[0], file);
550 (void) close (pd[0]);
551 (void) pidXwait (child_id, mhlproc);
558 static copy_draft (out, digest, file, volume, issue, mime)
563 register char *digest,
575 (void) sprintf (buffer, "#forw [forwarded message%s] +%s",
576 mp -> numsel == 1 ? "" : "s", mp -> foldpath);
577 (void) write (out, buffer, strlen (buffer));
578 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
579 if (mp -> msgstats[msgnum] & SELECTED) {
580 (void) sprintf (buffer, " %s", m_name (msgnum));
581 (void) write (out, buffer, strlen (buffer));
583 (void) write (out, "\n", 1);
590 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
591 if (mp -> msgstats[msgnum] & SELECTED) {
593 (void) strcpy (buffer,
594 msgnum == mp -> lowsel ? delim3 : delim4);
596 (void) strcpy (bp = buffer, "\n-------"), bp += strlen (bp);
597 if (msgnum == mp -> lowsel)
598 (void) sprintf (bp, " Forwarded Message%s",
599 mp -> numsel > 1 ? "s" : "");
601 (void) sprintf (bp, " Message %d", msgcnt);
603 (void) strcpy (bp, "\n\n");
605 (void) write (out, buffer, strlen (buffer));
607 if ((fd = open (msgnam = m_name (msgnum), 0)) == NOTOK) {
608 admonish (msgnam, "unable to read message");
611 cpydgst (fd, out, msgnam, file);
618 (void) strcpy (buffer, delim4);
620 (void) sprintf (buffer, "\n------- End of Forwarded Message%s\n\n",
621 mp -> numsel > 1 ? "s" : "");
622 (void) write (out, buffer, strlen (buffer));
625 (void) sprintf (buffer, "End of %s Digest [Volume %d Issue %d]\n", digest, volume, issue);
627 for (bp = buffer + i; i > 1; i--)
631 (void) write (out, buffer, strlen (buffer));
637 static int build_form (form, digest, volume, issue)
649 register struct comp *cptr;
653 nfs = new_fs (form, NULLCP, NULLCP);
654 fmtsize = strlen (nfs) + 256;
655 (void) fmt_compile (nfs, &fmt);
657 FINDCOMP (cptr, "digest");
659 cptr->c_text = digest;
660 FINDCOMP (cptr, "date");
662 cptr->c_text = getcpy(dtimenow ());
670 (void) strcpy (tmpfil, m_tmpfil (invo_name));
671 if ((tmp = fopen (tmpfil, "w+")) == NULL)
672 adios (tmpfil, "unable to create");
673 (void) unlink (tmpfil);
674 if ((in = dup (fileno (tmp))) == NOTOK)
675 adios ("dup", "unable to");
677 if ((line = malloc ((unsigned) fmtsize)) == NULLCP)
678 adios (NULLCP, "unable to allocate format line storage");
679 (void) fmtscan (fmt, line, fmtsize, dat);
680 (void) fputs (line, tmp);
683 adios (tmpfil, "error writing");
685 (void) lseek (in, (off_t)0, 0);