head 2.14; access; symbols; locks; strict; comment @ * @; 2.14 date 93.08.25.17.28.05; author jromine; state Exp; branches; next 2.13; 2.13 date 93.08.20.15.54.44; author jromine; state Exp; branches; next 2.12; 2.12 date 92.12.15.00.20.22; author jromine; state Exp; branches; next 2.11; 2.11 date 92.12.03.17.42.42; author jromine; state Exp; branches; next 2.10; 2.10 date 92.11.24.18.10.13; author jromine; state Exp; branches; next 2.9; 2.9 date 92.10.26.16.48.46; author jromine; state Exp; branches; next 2.8; 2.8 date 92.10.16.22.34.49; author jromine; state Exp; branches; next 2.7; 2.7 date 92.10.16.22.30.15; author jromine; state Exp; branches; next 2.6; 2.6 date 92.10.16.21.37.40; author jromine; state Exp; branches; next 2.5; 2.5 date 92.01.31.22.27.17; author jromine; state Exp; branches; next 2.4; 2.4 date 92.01.31.16.35.02; author jromine; state Exp; branches; next 2.3; 2.3 date 90.04.05.14.57.18; author sources; state Exp; branches; next 2.2; 2.2 date 90.02.06.13.30.51; author sources; state Exp; branches; next 2.1; 2.1 date 90.02.05.14.26.30; author sources; state Exp; branches; next 2.0; 2.0 date 89.11.17.15.58.11; author sources; state Exp; branches; next 1.1; 1.1 date 89.11.17.15.44.55; author sources; state Exp; branches; next ; desc @@ 2.14 log @off_t fixes for BSD44 @ text @/* sendsbr.c - routines to help WhatNow/Send along */ #ifndef lint static char ident[] = "@@(#)$Id: sendsbr.c,v 2.13 1993/08/20 15:54:44 jromine Exp jromine $"; #endif /* lint */ #include "../h/mh.h" #include #include #include #include #include static alert(), anno(), annoaux(); static int tmp_fd(); static int sendaux(); #ifdef MIME static int sendaux2(); #endif /* */ int debugsw = 0; /* global */ int forwsw = 1; int inplace = 0; int mime = 0; int pushsw = 0; int splitsw = -1; int unique = 0; int verbsw = 0; char *altmsg = NULL; /* .. */ char *annotext = NULL; char *distfile = NULL; static int armed = 0; static jmp_buf env; char *getusr (); off_t lseek (); long time (); /* */ int sendsbr (vec, vecp, drft, st) char **vec, *drft; int vecp; struct stat *st; { int status; armed++; switch (setjmp (env)) { case OK: status = sendaux (vec, vecp, drft, st) ? NOTOK : OK; break; default: status = DONE; break; } armed = 0; if (distfile) (void) unlink (distfile); return status; } /* */ #ifdef MIME #include "../h/mhn.h" static int sendaux (vec, vecp, drft, st) register char **vec, *drft; int vecp; register struct stat *st; { int compnum, nparts, partno, state, status; long clock, pos, start; char *cp, *dp, buffer[BUFSIZ], msgid[BUFSIZ], name[NAMESZ], partnum[BUFSIZ]; struct stat sts; FILE *in; if (splitsw < 0 || distfile || stat (drft, &sts) == NOTOK || sts.st_size < CPERMSG) { one_shot: ; splitsw = -1; return sendaux2 (vec, vecp, drft, st); } if ((in = fopen (drft, "r")) == NULL) adios (drft, "unable to open for reading"); cp = dp = NULL; start = 0L; for (compnum = 1, state = FLD;;) { switch (state = m_getfld (state, name, buffer, sizeof buffer, in)) { case FLD: case FLDPLUS: case FLDEOF: compnum++; if (uleq (name, VRSN_FIELD) || uleq (name, "Encrypted") || uleq (name, "Message-ID")) { while (state == FLDPLUS) state = m_getfld (state, name, buffer, sizeof buffer, in); } else if (uprf (name, XXX_FIELD_PRF)) { dp = add (concat (name, ":", buffer, NULLCP), dp); while (state == FLDPLUS) { state = m_getfld (state, name, buffer, sizeof buffer, in); dp = add (buffer, dp); } } else { cp = add (concat (name, ":", buffer, NULLCP), cp); while (state == FLDPLUS) { state = m_getfld (state, name, buffer, sizeof buffer, in); cp = add (buffer, cp); } } if (state != FLDEOF) { start = ftell (in) + 1; continue; } /* else fall... */ case BODY: case BODYEOF: case FILEEOF: break; case LENERR: case FMTERR: adios (NULLCP, "message format error in component #%d", compnum); default: adios (NULLCP, "getfld () returned %d", state); } break; } if (cp == NULL) adios (NULLCP, "headers missing from draft"); nparts = 1, pos = start; while (fgets (buffer, sizeof buffer - 1, in)) { register long len; if ((pos += (len = strlen (buffer))) > CPERMSG) nparts++, pos = len; } if (nparts == 1) { free (cp); if (dp) free (dp); (void) fclose (in); goto one_shot; } if (!pushsw) { printf ("Sending as %d Partial Messages\n", nparts); (void) fflush (stdout); } status = OK; vec[vecp++] = "-partno"; vec[vecp++] = partnum; if (splitsw == 0) vec[vecp++] = "-queued"; (void) time (&clock); (void) sprintf (msgid, "<%d.%ld@@%s>", getpid (), clock, LocalName ()); (void) fseek (in, start, 0); for (partno = 1; partno <= nparts; partno++) { char tmpdrf[BUFSIZ]; FILE *out; (void) strcpy (tmpdrf, m_scratch (drft, invo_name)); if ((out = fopen (tmpdrf, "w")) == NULL) adios (tmpdrf, "unable to open for writing"); (void) chmod (tmpdrf, 0600); (void) fputs (cp, out); fprintf (out, "%s: %s\n", VRSN_FIELD, VRSN_VALUE); fprintf (out, "%s: message/partial; id=\"%s\"; number=%d; total=%d\n", TYPE_FIELD, msgid, partno, nparts); fprintf (out, "%s: part %d of %d\n\n", DESCR_FIELD, partno, nparts); if (partno == 1) { if (dp) (void) fputs (dp, out); fprintf (out, "Message-ID: %s\n", msgid); fprintf (out, "\n"); } pos = 0; for (;;) { register long len; if (!fgets (buffer, sizeof buffer - 1, in)) { if (partno == nparts) break; adios (NULLCP, "premature eof"); } if ((pos += (len = strlen (buffer))) > CPERMSG) { (void) fseek (in, -len, 1); break; } (void) fputs (buffer, out); } if (fflush (out)) adios (tmpdrf, "error writing to"); (void) fclose (out); if (!pushsw && verbsw) { printf ("\n"); (void) fflush (stdout); } if (splitsw > 0 && 1 < partno && partno < nparts) { if (!pushsw) { printf ("pausing %d seconds before sending part %d...\n", splitsw, partno); (void) fflush (stdout); } sleep ((unsigned) splitsw); } (void) sprintf (partnum, "%d", partno); status = sendaux2 (vec, vecp, tmpdrf, st); (void) unlink (tmpdrf); if (status != OK) break; annotext = NULL; } free (cp); if (dp) free (dp); (void) fclose (in); if (status == OK && rename (drft, strcpy (buffer, m_backup (drft))) == NOTOK) advise (buffer, "unable to rename %s to", drft); return status; } #endif /* */ #ifndef MIME static int sendaux (vec, vecp, drft, st) #else /* MIME */ static int sendaux2 (vec, vecp, drft, st) #endif /* MIME */ register char **vec, *drft; int vecp; register struct stat *st; { int child_id, i, status, fd, fd2; char backup[BUFSIZ], buf[BUFSIZ], file[BUFSIZ]; fd = pushsw ? tmp_fd () : NOTOK; fd2 = NOTOK; if (pushsw && unique) { if (rename (drft, strcpy (file, m_scratch (drft, invo_name))) == NOTOK) adios (file, "unable to rename %s to", drft); drft = file; } vec[vecp++] = drft; if (annotext) if ((fd2 = tmp_fd ()) != NOTOK) { vec[vecp++] = "-idanno"; (void) sprintf (buf, "%d", fd2); vec[vecp++] = buf; } else admonish (NULLCP, "unable to create file for annotation list"); if (distfile && distout (drft, distfile, backup) == NOTOK) done (1); vec[vecp] = NULL; for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++) sleep (5); switch (child_id) { case NOTOK: /* oops */ adios ("fork", "unable to"); case OK: /* send it */ if (fd != NOTOK) { (void) dup2 (fd, fileno (stdout)); (void) dup2 (fd, fileno (stderr)); (void) close (fd); } execvp (postproc, vec); fprintf (stderr, "unable to exec "); perror (postproc); _exit (-1); default: /* wait for it */ if ((status = pidwait (child_id, NOTOK)) == 0) { if (annotext && fd2 != NOTOK) anno (fd2, st); if (splitsw < 0 && rename (drft, strcpy (buf, m_backup (drft))) == NOTOK) advise (buf, "unable to rename %s to", drft); } else { if (fd != NOTOK) { alert (drft, fd); (void) close (fd); } else advise (NULLCP, "message not delivered to anyone"); if (annotext && fd2 != NOTOK) (void) close (fd2); if (distfile) { (void) unlink (drft); if (rename (backup, drft) == NOTOK) advise (drft, "unable to rename %s to", backup); } } break; } return status; } /* */ static alert (file, out) register char *file; int out; { int child_id, i, in; char buf[BUFSIZ]; for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++) sleep (5); switch (child_id) { case NOTOK: /* oops */ advise ("fork", "unable to"); case OK: /* send it */ (void) signal (SIGHUP, SIG_IGN); (void) signal (SIGINT, SIG_IGN); (void) signal (SIGQUIT, SIG_IGN); (void) signal (SIGTERM, SIG_IGN); if (forwsw) if ((in = open (file, 0)) == NOTOK) admonish (file, "unable to re-open"); else { (void) lseek (out, (off_t)0, 2); (void) strcpy (buf, "\nMessage not delivered to anyone.\n"); (void) write (out, buf, strlen (buf)); (void) strcpy (buf, "\n------- Unsent Draft\n\n"); (void) write (out, buf, strlen (buf)); cpydgst (in, out, file, "temporary file"); (void) close (in); (void) strcpy (buf, "\n------- End of Unsent Draft\n"); (void) write (out, buf, strlen (buf)); if (rename (file, strcpy (buf, m_backup (file))) == NOTOK) admonish (buf, "unable to rename %s to", file); } (void) lseek (out, (off_t)0, 0); (void) dup2 (out, fileno (stdin)); (void) close (out); (void) sprintf (buf, "send failed on %s", forwsw ? "enclosed draft" : file); execlp (mailproc, r1bindex (mailproc, '/'), getusr (), "-subject", buf, NULLCP); fprintf (stderr, "unable to exec "); perror (mailproc); _exit (-1); default: /* no waiting... */ break; } } /* */ static int tmp_fd () { int fd; char tmpfil[BUFSIZ]; (void) strcpy (tmpfil, m_tmpfil (invo_name)); if ((fd = creat (tmpfil, 0600)) == NOTOK) return NOTOK; (void) close (fd); if ((fd = open (tmpfil, 2)) == NOTOK) return NOTOK; if (debugsw) advise (NULLCP, "temporary file %s selected", tmpfil); else if (unlink (tmpfil) == NOTOK) advise (tmpfil, "unable to remove"); return fd; } /* */ static anno (fd, st) int fd; register struct stat *st; { int child_id; TYPESIG (*hstat) (), (*istat) (), (*qstat) (), (*tstat) (); static char *cwd = NULL; struct stat st2; if (altmsg && (stat (altmsg, &st2) == NOTOK || st -> st_mtime != st2.st_mtime || st -> st_dev != st2.st_dev || st -> st_ino != st2.st_ino)) { if (debugsw) admonish (NULLCP, "$mhaltmsg mismatch"); return; } child_id = debugsw ? NOTOK : fork (); switch (child_id) { case NOTOK: /* oops */ if (!debugsw) advise (NULLCP, "unable to fork, so doing annotations by hand..."); if (cwd == NULL) cwd = getcpy (pwd ()); case OK: hstat = signal (SIGHUP, SIG_IGN); istat = signal (SIGINT, SIG_IGN); qstat = signal (SIGQUIT, SIG_IGN); tstat = signal (SIGTERM, SIG_IGN); annoaux (fd); if (child_id == OK) _exit (0); (void) signal (SIGHUP, hstat); (void) signal (SIGINT, istat); (void) signal (SIGQUIT, qstat); (void) signal (SIGTERM, tstat); (void) chdir (cwd); break; default: /* no waiting... */ (void) close (fd); break; } } /* */ static annoaux (fd) int fd; { int fd2, fd3, msgnum; char *cp, *folder, *maildir, buffer[BUFSIZ], **ap; FILE *fp; struct msgs *mp; if ((folder = getenv ("mhfolder")) == NULL || *folder == 0) { if (debugsw) admonish (NULLCP, "$mhfolder not set"); return; } maildir = m_maildir (folder); if (chdir (maildir) == NOTOK) { if (debugsw) admonish (maildir, "unable to change directory to"); return; } if (!(mp = m_gmsg (folder))) { if (debugsw) admonish (NULLCP, "unable to read folder %s"); return; } if (mp -> hghmsg == 0) { if (debugsw) admonish (NULLCP, "no messages in %s", folder); goto oops; } if ((cp = getenv ("mhmessages")) == NULL || *cp == 0) { if (debugsw) admonish (NULLCP, "$mhmessages not set"); goto oops; } if (!debugsw /* MOBY HACK... */ && pushsw && (fd3 = open ("/dev/null", 2)) != NOTOK && (fd2 = dup (fileno (stderr))) != NOTOK) { (void) dup2 (fd3, fileno (stderr)); (void) close (fd3); } else fd2 = NOTOK; for (ap = brkstring (cp = getcpy (cp), " ", NULLCP); *ap; ap++) (void) m_convert (mp, *ap); free (cp); if (fd2 != NOTOK) (void) dup2 (fd2, fileno (stderr)); if (mp -> numsel == 0) { if (debugsw) admonish (NULLCP, "no messages to annotate"); goto oops; } (void) lseek (fd, (off_t)0, 0); if ((fp = fdopen (fd, "r")) == NULL) { if (debugsw) admonish (NULLCP, "unable to fdopen annotation list"); goto oops; } cp = NULL; while (fgets (buffer, sizeof buffer, fp) != NULL) cp = add (buffer, cp); (void) fclose (fp); if (debugsw) advise (NULLCP, "annotate%s with %s: \"%s\"", inplace ? " inplace" : "", annotext, cp); for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) if (mp -> msgstats[msgnum] & SELECTED) { if (debugsw) advise (NULLCP, "annotate message %d", msgnum); (void) annotate (m_name (msgnum), annotext, cp, inplace, 1); } free (cp); oops: ; m_fmsg (mp); } /* */ void done (status) int status; { if (armed) longjmp (env, status ? status : NOTOK); exit (status); } @ 2.13 log @fixes from mtr: -partno, -queued interface @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: sendsbr.c,v 2.12 1992/12/15 00:20:22 jromine Exp jromine $"; d41 2 a42 1 long lseek (), time (); d400 1 a400 1 (void) lseek (out, 0L, 2); d412 1 a412 1 (void) lseek (out, 0L, 0); d568 1 a568 1 (void) lseek (fd, 0L, 0); @ 2.12 log @endif sugar @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: sendsbr.c,v 2.11 1992/12/03 17:42:42 jromine Exp jromine $"; d102 1 a105 1 status = OK; a106 3 vec[vecp++] = "-partno"; vec[vecp++] = partnum; d119 3 a121 1 if (uleq (name, VRSN_FIELD) || uleq (name, "Message-ID")) { d164 2 d174 10 d188 6 @ 2.11 log @fixes for -split 0 (from mtr) @ text @d3 2 a4 2 static char ident[] = "@@(#)$Id: sendsbr.c,v 2.10 1992/11/24 18:10:13 jromine Exp jromine $"; #endif lint @ 2.10 log @add decl @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: sendsbr.c,v 2.9 1992/10/26 16:48:46 jromine Exp jromine $"; d200 2 a201 1 (void) fputs (dp, out); d253 2 a254 1 free (dp); @ 2.9 log @fix from MTR @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: sendsbr.c,v 2.8 1992/10/16 22:34:49 jromine Exp jromine $"; d15 5 d267 1 a267 1 int sendaux (vec, vecp, drft, st) @ 2.8 log @MIME changes @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: sendsbr.c,v 2.7 1992/10/16 22:30:15 jromine Exp jromine $"; d335 1 a335 1 if (fd2 != NOTOK) @ 2.7 log @#ifdef MIME fixups @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: sendsbr.c,v 2.6 1992/10/16 21:37:40 jromine Exp jromine $"; d117 1 a117 1 if (uleq (name, VRSN_FIELD)) { d123 7 a129 6 if (uprf (name, XXX_FIELD_PRF)) { dp = add (concat (name, ": ", buffer, NULLCP), dp); while (state == FLDPLUS) { state = m_getfld (state, name, buffer, sizeof buffer, in); dp = add (buffer, dp); d131 7 a137 7 } else { cp = add (concat (name, ": ", buffer, NULLCP), cp); while (state == FLDPLUS) { state = m_getfld (state, name, buffer, sizeof buffer, in); cp = add (buffer, cp); a138 1 } d191 2 a192 2 fprintf (out, "Content-Description: part %d of %d\n\n", partno, nparts); d196 1 @ 2.6 log @MIME changes @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: sendsbr.c,v 2.5 1992/01/31 22:27:17 jromine Exp jromine $"; d67 1 a69 1 d256 1 d260 3 d264 1 d320 1 a320 1 if (fd2 != NOTOK) @ 2.5 log @kerberos @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: sendsbr.c,v 2.4 1992/01/31 16:35:02 jromine Exp jromine $"; d20 1 @ 2.4 log @Multimedia MH @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id: sendsbr.c,v 2.3 90/04/05 14:57:18 sources Exp $"; d489 1 a489 1 if ((folder = getenv ("mhfolder")) == NULL || *folder == NULL) { d511 1 a511 1 if ((cp = getenv ("mhmessages")) == NULL || *cp == NULL) { @ 2.3 log @add ID @ text @d3 1 a3 1 static char ident[] = "@@(#)$Id:$"; d21 1 d23 1 d35 1 a35 1 long lseek (); d66 4 a69 1 int sendaux (vec, vecp, drft, st) d75 189 d314 1 a314 1 if (annotext && fd2 != NOTOK) d316 3 a318 1 if (rename (drft, strcpy (buf, m_backup (drft))) == NOTOK) @ 2.2 log @ANSI Compilance @ text @d2 3 @ 2.1 log @TYPESIG @ text @d10 2 @ 2.0 log @changes for SUN40 shared libraries and NNTP under bbc @ text @d225 1 a225 1 int (*hstat) (), (*istat) (), (*qstat) (), (*tstat) (); @ 1.1 log @Initial revision @ text @d353 1 a353 1 (void) annotate (m_name (msgnum), annotext, cp, inplace); @