]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/sendsbr.c
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
);