Initialize vecp in send anno()
[mmh] / uip / send.c
index e1e7518..ed6b08d 100644 (file)
@@ -15,6 +15,8 @@
 #include <h/mime.h>
 #include <h/tws.h>
 #include <h/utils.h>
+#include <sysexits.h>
+#include <sys/wait.h>
 
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
@@ -22,7 +24,7 @@
 #include <time.h>
 
 int debugsw = 0;  /* global */
-char *altmsg   = NULL;
+char *altmsg = NULL;
 char *annotext = NULL;
 char *distfile = NULL;
 
@@ -50,6 +52,7 @@ static int signandenc(char *);
 static void clean_up_temporary_files(void);
 static int get_line(void);
 static void make_mime_composition_file_entry(char *);
+static char* strexit(int status);
 
 
 static struct swit switches[] = {
@@ -234,8 +237,7 @@ main(int argc, char **argv)
 static int
 sendsbr(char **vec, int vecp, char *drft, struct stat *st)
 {
-       int status;
-       char buffer[BUFSIZ];
+       int status, dupfd;
        char *original_draft;
 
        /*
@@ -292,12 +294,16 @@ sendsbr(char **vec, int vecp, char *drft, struct stat *st)
                status = sendaux(vec, vecp, drft, st) ? NOTOK : OK;
                if (status == OK) {
                        /* move original draft to +trash folder */
-                       snprintf(buffer, sizeof buffer,
-                                       "</dev/null refile -file %s +trash",
-                                       original_draft);
-                       if (system(buffer) != 0) {
+                       /* temporary close stdin, for refile not to ask */
+                       dupfd = dup(0);
+                       close(0);
+                       if (execprogl("refile", "refile", "-file",
+                                       original_draft, "+trash",
+                                       (char *)NULL) != 0) {
                                advise(NULL, "unable to trash the draft");
                        }
+                       dup2(dupfd, 0);
+                       close(dupfd);
                }
                break;
 
@@ -442,8 +448,8 @@ attach(char *draft_file_name)
        fclose(composition_file);
 
        /* We're ready to roll! */
-       sprintf(buf, "mhbuild %s", composition_file_name);
-       if (system(buf) != 0) {
+       if (execprogl("mhbuild", "mhbuild", composition_file_name,
+                       (char *)NULL) != 0) {
                /* some problem */
                clean_up_temporary_files();
                return (NOTOK);
@@ -463,6 +469,7 @@ signandenc(char *draft_file_name)
        char buf[BUFSIZ];
        int dosign = 0;
        int doenc = 0;
+       int ret;
 
        if (!(draft_file = fopen(draft_file_name, "r"))) {
                adios(NULL, "can't open draft file `%s'.", draft_file_name);
@@ -489,9 +496,14 @@ signandenc(char *draft_file_name)
        strcpy(composition_file_name, draft_file_name);
 
        /* We're ready to roll! */
-       sprintf(buf, "mhsign -m%s '%s'", doenc ? " -e" : "",
-                       draft_file_name);
-       if (system(buf) != 0) {
+       if (doenc) {
+               ret = execprogl("mhsign", "mhsign", "-m", "-e",
+                               draft_file_name, (char *)NULL);
+       } else {
+               ret = execprogl("mhsign", "mhsign", "-m",
+                               draft_file_name, (char *)NULL);
+       }
+       if (ret != 0) {
                /* some problem */
                return (NOTOK);
        }
@@ -636,13 +648,14 @@ sendaux(char **vec, int vecp, char *drft, struct stat *st)
 
        default:
                /* parent process -- wait for it */
-               if ((status = pidwait(child_id, NOTOK)) == OK) {
+               status = pidwait(child_id, NOTOK);
+               if (WIFEXITED(status) && WEXITSTATUS(status) == EX_OK) {
                        if (annotext) {
                                anno(st);
                        }
                } else {
                        /* spost failed */
-                       advise(NULL, "message not delivered to anyone");
+                       advise(NULL, "%s", strexit(status));
                        if (distfile) {
                                unlink(drft);
                                if (rename(backup, drft) == NOTOK) {
@@ -651,9 +664,9 @@ sendaux(char **vec, int vecp, char *drft, struct stat *st)
                                }
                        }
                }
-               break;
        }
 
+
        return status;
 }
 
@@ -664,6 +677,9 @@ anno(struct stat *st)
        struct stat st2;
        char *msgs, *folder;
        char buf[BUFSIZ];
+       char *vec[MAXARGS];
+       int vecp = 0;
+       char *cp, *dp;
 
        if (altmsg && (stat(altmsg, &st2) == NOTOK ||
                        st->st_mtime != st2.st_mtime ||
@@ -691,14 +707,50 @@ anno(struct stat *st)
                advise(NULL, "annotate as `%s': %s %s", annotext,
                                folder, msgs);
        }
-       snprintf(buf, sizeof buf, "anno -comp '%s' '+%s' %s",
-                       annotext, folder, msgs);
-       if (system(buf) != 0) {
+       vec[vecp++] = "anno";
+       vec[vecp++] = "-comp";
+       vec[vecp++] = annotext;
+       snprintf(buf, sizeof buf, "+%s", folder);
+       vec[vecp++] = buf;
+
+       while (isspace(*msgs)) {
+               msgs++;
+       }
+       for (cp=dp=msgs; *cp; cp++) {
+               if (isspace(*cp)) {
+                       while (isspace(*cp)) {
+                               *cp++ = '\0';
+                       }
+                       vec[vecp++] = dp;
+                       dp = cp;
+               }
+       }
+       vec[vecp++] = dp;
+       vec[vecp] = NULL;
+       if (execprog(*vec, vec) != 0) {
                advise(NULL, "unable to annotate");
        }
 }
 
 
+char*
+strexit(int status)
+{
+       if (WIFSIGNALED(status)) {
+               return "spost or sendmail killed by signal";
+       }
+       if (!WIFEXITED(status)) {
+               return "message not delivered to anyone";
+       }
+       switch (WEXITSTATUS(status)) {
+       case EX_TEMPFAIL:
+               return "Temporary error, maybe the MTA has queued the message";
+       default:
+               return "message not delivered to anyone";
+       }
+}
+
+
 static void
 armed_done(int status)
 {