Added -messageid switch to send(1) and post(8). This allows selection
[mmh] / uip / sendsbr.c
index cc15a0f..3865258 100644 (file)
@@ -2,8 +2,6 @@
 /*
  * sendsbr.c -- routines to help WhatNow/Send along
  *
- * $Id$
- *
  * This code is Copyright (c) 2002, by the authors of nmh.  See the
  * COPYRIGHT file in the root directory of the nmh distribution for
  * complete copyright information.
 #include <h/tws.h>
 #include <h/utils.h>
 
-#ifdef TIME_WITH_SYS_TIME
+#ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
-# include <time.h>
-#else
-# ifdef TM_IN_SYS_TIME
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
 #endif
+#include <time.h>
 
 int debugsw = 0;               /* global */
 int forwsw  = 1;
@@ -41,11 +33,10 @@ char *altmsg   = NULL;              /*  .. */
 char *annotext = NULL;
 char *distfile = NULL;
 
-static int armed = 0;
 static jmp_buf env;
 
-static char    body_file_name[MAXPATHLEN + 1];         /* name of temporary file for body content */
-static char    composition_file_name[MAXPATHLEN + 1];  /* name of mhbuild composition temporary file */
+static char    body_file_name[PATH_MAX + 1];           /* name of temporary file for body content */
+static char    composition_file_name[PATH_MAX + 1];    /* name of mhbuild composition temporary file */
 static int     field_size;                             /* size of header field buffer */
 static char    *field;                                 /* header field buffer */
 static FILE    *draft_file;                            /* draft file pointer */
@@ -56,12 +47,12 @@ static      FILE    *composition_file;                      /* composition file pointer */
  * external prototypes
  */
 int sendsbr (char **, int, char *, struct stat *, int, char *, int);
-int done (int);
 char *getusername (void);
 
 /*
  * static prototypes
  */
+static void armed_done (int) NORETURN;
 static void alert (char *, int);
 static int tmp_fd (void);
 static void anno (int, struct stat *);
@@ -118,7 +109,7 @@ sendsbr (char **vec, int vecp, char *drft, struct stat *st, int rename_drft, cha
        }
     }
 
-    armed++;
+    done=armed_done;
     switch (setjmp (env)) {
     case OK: 
        /*
@@ -126,8 +117,11 @@ sendsbr (char **vec, int vecp, char *drft, struct stat *st, int rename_drft, cha
         * rename the draft file.  I'm not quite sure why.
         */
        if (pushsw && unique) {
-           if (rename (drft, strncpy (file, m_scratch (drft, invo_name), sizeof(file)))
-                   == NOTOK)
+            char *cp = m_mktemp2(drft, invo_name, NULL, NULL);
+            if (cp == NULL) {
+                adios ("sendsbr", "unable to create temporary file");
+            }
+           if (rename (drft, strncpy(file, cp, sizeof(file))) == NOTOK)
                adios (file, "unable to rename %s to", drft);
            drft = file;
        }
@@ -154,7 +148,7 @@ sendsbr (char **vec, int vecp, char *drft, struct stat *st, int rename_drft, cha
        break;
     }
 
-    armed = 0;
+    done=exit;
     if (distfile)
        unlink (distfile);
 
@@ -192,12 +186,13 @@ static    int
 attach(char *attachment_header_field_name, char *draft_file_name,
        int attachformat)
 {
-    char               buf[MAXPATHLEN + 6];    /* miscellaneous buffer */
+    char               buf[PATH_MAX + 6];      /* miscellaneous buffer */
     int                        c;                      /* current character for body copy */
     int                        has_attachment;         /* draft has at least one attachment */
     int                        has_body;               /* draft has a message body */
     int                        length;                 /* length of attachment header field name */
     char               *p;                     /* miscellaneous string pointer */
+    FILE               *fp;                    /* pointer for mhn.defaults */
 
     /*
      * Open up the draft file.
@@ -254,8 +249,12 @@ attach(char *attachment_header_field_name, char *draft_file_name,
      * Make names for the temporary files.
      */
 
-    (void)strncpy(body_file_name, m_scratch("", m_maildir(invo_name)), sizeof (body_file_name));
-    (void)strncpy(composition_file_name, m_scratch("", m_maildir(invo_name)), sizeof (composition_file_name));
+    (void)strncpy(body_file_name,
+                  m_mktemp(m_maildir(invo_name), NULL, NULL),
+                  sizeof (body_file_name));
+    (void)strncpy(composition_file_name,
+                  m_mktemp(m_maildir(invo_name), NULL, NULL),
+                  sizeof (composition_file_name));
 
     if (has_body)
        body_file = fopen(body_file_name, "w");
@@ -303,6 +302,11 @@ attach(char *attachment_header_field_name, char *draft_file_name,
      * that specify attachments.  Add a mhbuild MIME composition file for each.
      */
 
+    if ((fp = fopen (p = etcpath ("mhn.defaults"), "r"))) {
+       readconfig ((struct node **) NULL, fp, p, 0);
+       fclose(fp);
+    }
+
     rewind(draft_file);
 
     while (get_line() != EOF && *field != '\0' && *field != '-') {
@@ -382,7 +386,7 @@ make_mime_composition_file_entry(char *file_name, int attachformat)
 {
     int                        binary;                 /* binary character found flag */
     int                        c;                      /* current character */
-    char               cmd[MAXPATHLEN + 6];    /* file command buffer */
+    char               cmd[PATH_MAX + 6];      /* file command buffer */
     char               *content_type;          /* mime content type */
     FILE               *fp;                    /* content and pipe file pointer */
     struct     node    *np;                    /* context scan node pointer */
@@ -401,7 +405,7 @@ make_mime_composition_file_entry(char *file_name, int attachformat)
 
     if ((p = strrchr(file_name, '.')) != (char *)0) {
        for (np = m_defs; np; np = np->n_next) {
-           if (strncasecmp(np->n_name, "mhshow-suffix-", 14) == 0 && strcasecmp(p, np->n_field) == 0) {
+           if (strncasecmp(np->n_name, "mhshow-suffix-", 14) == 0 && mh_strcasecmp(p, np->n_field) == 0) {
                content_type = np->n_name + 14;
                break;
            }
@@ -452,7 +456,7 @@ make_mime_composition_file_entry(char *file_name, int attachformat)
         (void)fprintf(composition_file, "#%s; name=\"%s\"; x-unix-mode=0%.3ho",
             content_type, ((p = strrchr(file_name, '/')) == (char *)0) ? file_name : p + 1, (unsigned short)(st.st_mode & 0777));
 
-        if (strlen(file_name) > MAXPATHLEN) {
+        if (strlen(file_name) > PATH_MAX) {
             clean_up_temporary_files();
             adios((char *)0, "attachment file name `%s' too long.", file_name);
         }
@@ -489,17 +493,42 @@ make_mime_composition_file_entry(char *file_name, int attachformat)
 
         break;
     case 1:
-        /* Suppress Content-Id, insert simple Content-Disposition. */
-        (void) fprintf (composition_file, "#%s <>{attachment}", content_type);
+        if (stringdex (m_maildir(invo_name), file_name) == 0) {
+            /* Content had been placed by send into a temp file.
+               Don't generate Content-Disposition header, because
+               it confuses Microsoft Outlook, Build 10.0.6626, at
+               least. */
+            (void) fprintf (composition_file, "#%s <>", content_type);
+        } else {
+            /* Suppress Content-Id, insert simple Content-Disposition
+               and Content-Description with filename. */
+            p = strrchr(file_name, '/');
+            (void) fprintf (composition_file,
+                            "#%s; name=\"%s\" <> [%s]{attachment}",
+                            content_type,
+                            (p == (char *)0) ? file_name : p + 1,
+                            (p == (char *)0) ? file_name : p + 1);
+        }
 
         break;
     case 2:
-        /* Suppress Content-Id, insert Content-Disposition with
-           modification date. */
-        (void) fprintf (composition_file,
-                        "#%s <>{attachment; modification-date=\"%s\"}",
-                        content_type,
-                        dtime (&st.st_mtime, 0));
+        if (stringdex (m_maildir(invo_name), file_name) == 0) {
+            /* Content had been placed by send into a temp file.
+               Don't generate Content-Disposition header, because
+               it confuses Microsoft Outlook, Build 10.0.6626, at
+               least. */
+            (void) fprintf (composition_file, "#%s <>", content_type);
+        } else {
+            /* Suppress Content-Id, insert Content-Disposition with
+               modification date and Content-Description wtih filename. */
+            p = strrchr(file_name, '/');
+            (void) fprintf (composition_file,
+                            "#%s; name=\"%s\" <>[%s]{attachment; modification-date=\"%s\"}",
+                            content_type,
+                            (p == (char *)0) ? file_name : p + 1,
+                            (p == (char *)0) ? file_name : p + 1,
+                            dtime (&st.st_mtime, 0));
+        }
 
         break;
     default:
@@ -551,13 +580,13 @@ splitmsg (char **vec, int vecp, char *drft, struct stat *st, int delay)
                /*
                 * This header field is discarded.
                 */
-               if (!strcasecmp (name, "Message-ID")) {
+               if (!mh_strcasecmp (name, "Message-ID")) {
                    while (state == FLDPLUS)
                        state = m_getfld (state, name, buffer, sizeof(buffer), in);
                } else if (uprf (name, XXX_FIELD_PRF)
-                       || !strcasecmp (name, VRSN_FIELD)
-                       || !strcasecmp (name, "Subject")
-                       || !strcasecmp (name, "Encrypted")) {
+                       || !mh_strcasecmp (name, VRSN_FIELD)
+                       || !mh_strcasecmp (name, "Subject")
+                       || !mh_strcasecmp (name, "Encrypted")) {
                    /*
                     * These header fields are copied to the enclosed
                     * header of the first message in the collection
@@ -566,7 +595,7 @@ splitmsg (char **vec, int vecp, char *drft, struct stat *st, int delay)
                     * version of it, can be copied to the header
                     * of each messsage/partial in the collection.
                     */
-                   if (!strcasecmp (name, "Subject")) {
+                   if (!mh_strcasecmp (name, "Subject")) {
                        size_t sublen;
 
                        strncpy (subject, buffer, BUFSIZ);
@@ -649,17 +678,18 @@ splitmsg (char **vec, int vecp, char *drft, struct stat *st, int delay)
        vec[vecp++] = "-queued";
 
     time (&clock);
-    snprintf (msgid, sizeof(msgid), "<%d.%ld@%s>",
-               (int) getpid(), (long) clock, LocalName());
+    snprintf (msgid, sizeof(msgid), "%s", message_id (clock, 0));
 
     fseek (in, start, SEEK_SET);
     for (partno = 1; partno <= nparts; partno++) {
        char tmpdrf[BUFSIZ];
        FILE *out;
 
-       strncpy (tmpdrf, m_scratch (drft, invo_name), sizeof(tmpdrf));
-       if ((out = fopen (tmpdrf, "w")) == NULL)
-           adios (tmpdrf, "unable to open for writing");
+       char *cp = m_mktemp2(drft, invo_name, NULL, &out);
+        if (cp == NULL) {
+           adios (drft, "unable to create temporary file for");
+        }
+       strncpy(tmpdrf, cp, sizeof(tmpdrf));
        chmod (tmpdrf, 0600);
 
        /*
@@ -900,16 +930,17 @@ static int
 tmp_fd (void)
 {
     int fd;
-    char tmpfil[BUFSIZ];
+    char *tfile = NULL;
+
+    tfile = m_mktemp2(NULL, invo_name, &fd, NULL);
+    if (tfile == NULL) return NOTOK;
+    fchmod(fd, 0600);
 
-    strncpy (tmpfil, m_tmpfil (invo_name), sizeof(tmpfil));
-    if ((fd = open (tmpfil, O_RDWR | O_CREAT | O_TRUNC, 0600)) == NOTOK)
-       return NOTOK;
     if (debugsw)
-       advise (NULL, "temporary file %s selected", tmpfil);
+       advise (NULL, "temporary file %s selected", tfile);
     else
-       if (unlink (tmpfil) == NOTOK)
-           advise (tmpfil, "unable to remove");
+       if (unlink (tfile) == NOTOK)
+           advise (tfile, "unable to remove");
 
     return fd;
 }
@@ -949,14 +980,14 @@ anno (int fd, struct stat *st)
            sigaddset (&set, SIGINT);
            sigaddset (&set, SIGQUIT);
            sigaddset (&set, SIGTERM);
-           SIGPROCMASK (SIG_BLOCK, &set, &oset);
+           sigprocmask (SIG_BLOCK, &set, &oset);
 
            annoaux (fd);
            if (child_id == OK)
                _exit (0);
 
            /* reset the signal mask */
-           SIGPROCMASK (SIG_SETMASK, &oset, &set);
+           sigprocmask (SIG_SETMASK, &oset, &set);
 
            chdir (cwd);
            break;
@@ -990,7 +1021,7 @@ annoaux (int fd)
     }
     if (!(mp = folder_read (folder))) {
        if (debugsw)
-           admonish (NULL, "unable to read folder %s");
+           admonish (NULL, "unable to read folder %s", folder);
        return;
     }
 
@@ -1055,12 +1086,10 @@ oops:
 }
 
 
-int
-done (int status)
+static void
+armed_done (int status)
 {
-    if (armed)
-       longjmp (env, status ? status : NOTOK);
+    longjmp (env, status ? status : NOTOK);
 
     exit (status);
-    return 1;  /* dead code to satisfy the compiler */
 }