1 /* sendsbr.c - routines to help WhatNow/Send along */
3 static char ident[] = "@(#)$Id: sendsbr.c,v 2.14 1993/08/25 17:28:05 jromine Exp $";
10 #include <sys/types.h>
13 static alert(), anno(), annoaux();
17 static int sendaux2();
22 int debugsw = 0; /* global */
31 char *altmsg = NULL; /* .. */
32 char *annotext = NULL;
33 char *distfile = NULL;
46 int sendsbr (vec, vecp, drft, st)
55 switch (setjmp (env)) {
57 status = sendaux (vec, vecp, drft, st) ? NOTOK : OK;
66 (void) unlink (distfile);
76 static int sendaux (vec, vecp, drft, st)
80 register struct stat *st;
101 || stat (drft, &sts) == NOTOK
102 || sts.st_size < CPERMSG) {
105 return sendaux2 (vec, vecp, drft, st);
108 if ((in = fopen (drft, "r")) == NULL)
109 adios (drft, "unable to open for reading");
113 for (compnum = 1, state = FLD;;) {
114 switch (state = m_getfld (state, name, buffer, sizeof buffer, in)) {
120 if (uleq (name, VRSN_FIELD)
121 || uleq (name, "Encrypted")
122 || uleq (name, "Message-ID")) {
123 while (state == FLDPLUS)
124 state = m_getfld (state, name, buffer, sizeof buffer,
128 if (uprf (name, XXX_FIELD_PRF)) {
129 dp = add (concat (name, ":", buffer, NULLCP), dp);
130 while (state == FLDPLUS) {
131 state = m_getfld (state, name, buffer,
133 dp = add (buffer, dp);
137 cp = add (concat (name, ":", buffer, NULLCP), cp);
138 while (state == FLDPLUS) {
139 state = m_getfld (state, name, buffer,
141 cp = add (buffer, cp);
144 if (state != FLDEOF) {
145 start = ftell (in) + 1;
156 adios (NULLCP, "message format error in component #%d",
160 adios (NULLCP, "getfld () returned %d", state);
166 adios (NULLCP, "headers missing from draft");
168 nparts = 1, pos = start;
169 while (fgets (buffer, sizeof buffer - 1, in)) {
172 if ((pos += (len = strlen (buffer))) > CPERMSG)
186 printf ("Sending as %d Partial Messages\n", nparts);
187 (void) fflush (stdout);
191 vec[vecp++] = "-partno";
192 vec[vecp++] = partnum;
194 vec[vecp++] = "-queued";
196 (void) time (&clock);
197 (void) sprintf (msgid, "<%d.%ld@%s>", getpid (), clock, LocalName ());
199 (void) fseek (in, start, 0);
200 for (partno = 1; partno <= nparts; partno++) {
204 (void) strcpy (tmpdrf, m_scratch (drft, invo_name));
205 if ((out = fopen (tmpdrf, "w")) == NULL)
206 adios (tmpdrf, "unable to open for writing");
207 (void) chmod (tmpdrf, 0600);
209 (void) fputs (cp, out);
210 fprintf (out, "%s: %s\n", VRSN_FIELD, VRSN_VALUE);
212 "%s: message/partial; id=\"%s\"; number=%d; total=%d\n",
213 TYPE_FIELD, msgid, partno, nparts);
214 fprintf (out, "%s: part %d of %d\n\n", DESCR_FIELD, partno,
219 (void) fputs (dp, out);
220 fprintf (out, "Message-ID: %s\n", msgid);
228 if (!fgets (buffer, sizeof buffer - 1, in)) {
229 if (partno == nparts)
231 adios (NULLCP, "premature eof");
234 if ((pos += (len = strlen (buffer))) > CPERMSG) {
235 (void) fseek (in, -len, 1);
239 (void) fputs (buffer, out);
243 adios (tmpdrf, "error writing to");
247 if (!pushsw && verbsw) {
249 (void) fflush (stdout);
251 if (splitsw > 0 && 1 < partno && partno < nparts) {
253 printf ("pausing %d seconds before sending part %d...\n",
255 (void) fflush (stdout);
258 sleep ((unsigned) splitsw);
261 (void) sprintf (partnum, "%d", partno);
262 status = sendaux2 (vec, vecp, tmpdrf, st);
263 (void) unlink (tmpdrf);
277 rename (drft, strcpy (buffer, m_backup (drft))) == NOTOK)
278 advise (buffer, "unable to rename %s to", drft);
287 static int sendaux (vec, vecp, drft, st)
289 static int sendaux2 (vec, vecp, drft, st)
294 register struct stat *st;
305 fd = pushsw ? tmp_fd () : NOTOK;
308 if (pushsw && unique) {
309 if (rename (drft, strcpy (file, m_scratch (drft, invo_name)))
311 adios (file, "unable to rename %s to", drft);
316 if ((fd2 = tmp_fd ()) != NOTOK) {
317 vec[vecp++] = "-idanno";
318 (void) sprintf (buf, "%d", fd2);
322 admonish (NULLCP, "unable to create file for annotation list");
323 if (distfile && distout (drft, distfile, backup) == NOTOK)
327 for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++)
330 case NOTOK: /* oops */
331 adios ("fork", "unable to");
333 case OK: /* send it */
335 (void) dup2 (fd, fileno (stdout));
336 (void) dup2 (fd, fileno (stderr));
339 execvp (postproc, vec);
340 fprintf (stderr, "unable to exec ");
344 default: /* wait for it */
345 if ((status = pidwait (child_id, NOTOK)) == 0) {
346 if (annotext && fd2 != NOTOK)
349 && rename (drft, strcpy (buf, m_backup (drft)))
351 advise (buf, "unable to rename %s to", drft);
359 advise (NULLCP, "message not delivered to anyone");
360 if (annotext && fd2 != NOTOK)
363 (void) unlink (drft);
364 if (rename (backup, drft) == NOTOK)
365 advise (drft, "unable to rename %s to", backup);
376 static alert (file, out)
385 for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
388 case NOTOK: /* oops */
389 advise ("fork", "unable to");
391 case OK: /* send it */
392 (void) signal (SIGHUP, SIG_IGN);
393 (void) signal (SIGINT, SIG_IGN);
394 (void) signal (SIGQUIT, SIG_IGN);
395 (void) signal (SIGTERM, SIG_IGN);
397 if ((in = open (file, 0)) == NOTOK)
398 admonish (file, "unable to re-open");
400 (void) lseek (out, (off_t)0, 2);
401 (void) strcpy (buf, "\nMessage not delivered to anyone.\n");
402 (void) write (out, buf, strlen (buf));
403 (void) strcpy (buf, "\n------- Unsent Draft\n\n");
404 (void) write (out, buf, strlen (buf));
405 cpydgst (in, out, file, "temporary file");
407 (void) strcpy (buf, "\n------- End of Unsent Draft\n");
408 (void) write (out, buf, strlen (buf));
409 if (rename (file, strcpy (buf, m_backup (file))) == NOTOK)
410 admonish (buf, "unable to rename %s to", file);
412 (void) lseek (out, (off_t)0, 0);
413 (void) dup2 (out, fileno (stdin));
415 (void) sprintf (buf, "send failed on %s",
416 forwsw ? "enclosed draft" : file);
418 execlp (mailproc, r1bindex (mailproc, '/'), getusr (),
419 "-subject", buf, NULLCP);
420 fprintf (stderr, "unable to exec ");
424 default: /* no waiting... */
431 static int tmp_fd () {
435 (void) strcpy (tmpfil, m_tmpfil (invo_name));
436 if ((fd = creat (tmpfil, 0600)) == NOTOK)
440 if ((fd = open (tmpfil, 2)) == NOTOK)
443 advise (NULLCP, "temporary file %s selected", tmpfil);
445 if (unlink (tmpfil) == NOTOK)
446 advise (tmpfil, "unable to remove");
455 register struct stat *st;
458 TYPESIG (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
459 static char *cwd = NULL;
463 (stat (altmsg, &st2) == NOTOK
464 || st -> st_mtime != st2.st_mtime
465 || st -> st_dev != st2.st_dev
466 || st -> st_ino != st2.st_ino)) {
468 admonish (NULLCP, "$mhaltmsg mismatch");
472 child_id = debugsw ? NOTOK : fork ();
474 case NOTOK: /* oops */
477 "unable to fork, so doing annotations by hand...");
479 cwd = getcpy (pwd ());
482 hstat = signal (SIGHUP, SIG_IGN);
483 istat = signal (SIGINT, SIG_IGN);
484 qstat = signal (SIGQUIT, SIG_IGN);
485 tstat = signal (SIGTERM, SIG_IGN);
491 (void) signal (SIGHUP, hstat);
492 (void) signal (SIGINT, istat);
493 (void) signal (SIGQUIT, qstat);
494 (void) signal (SIGTERM, tstat);
499 default: /* no waiting... */
521 if ((folder = getenv ("mhfolder")) == NULL || *folder == 0) {
523 admonish (NULLCP, "$mhfolder not set");
526 maildir = m_maildir (folder);
527 if (chdir (maildir) == NOTOK) {
529 admonish (maildir, "unable to change directory to");
532 if (!(mp = m_gmsg (folder))) {
534 admonish (NULLCP, "unable to read folder %s");
537 if (mp -> hghmsg == 0) {
539 admonish (NULLCP, "no messages in %s", folder);
543 if ((cp = getenv ("mhmessages")) == NULL || *cp == 0) {
545 admonish (NULLCP, "$mhmessages not set");
548 if (!debugsw /* MOBY HACK... */
550 && (fd3 = open ("/dev/null", 2)) != NOTOK
551 && (fd2 = dup (fileno (stderr))) != NOTOK) {
552 (void) dup2 (fd3, fileno (stderr));
557 for (ap = brkstring (cp = getcpy (cp), " ", NULLCP); *ap; ap++)
558 (void) m_convert (mp, *ap);
561 (void) dup2 (fd2, fileno (stderr));
562 if (mp -> numsel == 0) {
564 admonish (NULLCP, "no messages to annotate");
568 (void) lseek (fd, (off_t)0, 0);
569 if ((fp = fdopen (fd, "r")) == NULL) {
571 admonish (NULLCP, "unable to fdopen annotation list");
575 while (fgets (buffer, sizeof buffer, fp) != NULL)
576 cp = add (buffer, cp);
580 advise (NULLCP, "annotate%s with %s: \"%s\"",
581 inplace ? " inplace" : "", annotext, cp);
582 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
583 if (mp -> msgstats[msgnum] & SELECTED) {
585 advise (NULLCP, "annotate message %d", msgnum);
586 (void) annotate (m_name (msgnum), annotext, cp, inplace, 1);
601 longjmp (env, status ? status : NOTOK);