+ switch (attachformat) {
+ case 0:
+ /* Insert name, file mode, and Content-Id. */
+ fprintf(composition_file,
+ "#%s; name=\"%s\"; x-unix-mode=0%.3ho",
+ content_type, ((p = strrchr(file_name, '/'))
+ == NULL) ? file_name : p + 1,
+ (unsigned short)(st.st_mode & 0777));
+
+ if (strlen(file_name) > MAXPATHLEN) {
+ clean_up_temporary_files();
+ adios(NULL, "attachment file name `%s' too long.",
+ file_name);
+ }
+
+ sprintf(cmd, "file '%s'", file_name);
+
+ if ((fp = popen(cmd, "r")) != (FILE *)0 &&
+ fgets(cmd, sizeof (cmd), fp) != NULL) {
+ *strchr(cmd, '\n') = '\0';
+
+ /*
+ ** The output of the "file" command is of the form
+ **
+ ** file: description
+ **
+ ** Strip off the "file:" and subsequent white space.
+ */
+
+ for (p = cmd; *p != '\0'; p++) {
+ if (*p == ':') {
+ for (p++; *p != '\0'; p++) {
+ if (*p != '\t')
+ break;
+ }
+ break;
+ }
+ }
+
+ if (*p != '\0')
+ /* Insert Content-Description. */
+ fprintf(composition_file, " [ %s ]", p);
+
+ pclose(fp);
+ }
+
+ break;
+ case 1:
+ if (stringdex(toabsdir(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.
+ */
+ fprintf(composition_file, "#%s <>", content_type);
+ } else {
+ /*
+ ** Suppress Content-Id, insert simple
+ ** Content-Disposition.
+ */
+ fprintf(composition_file,
+ "#%s; name=\"%s\" <>{attachment}",
+ content_type,
+ ((p = strrchr(file_name, '/')) == NULL) ?
+ file_name : p + 1);
+ }
+
+ break;
+ case 2:
+ if (stringdex(toabsdir(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.
+ */
+ fprintf(composition_file, "#%s <>", content_type);
+ } else {
+ /*
+ ** Suppress Content-Id, insert Content-Disposition
+ ** with modification date.
+ */
+ fprintf(composition_file,
+ "#%s; name=\"%s\" <>{attachment; modification-date=\"%s\"}",
+ content_type,
+ ((p = strrchr(file_name, '/')) == NULL) ?
+ file_name : p + 1, dtime(&st.st_mtime, 0));
+ }
+
+ break;
+ default:
+ adios(NULL, "unsupported attachformat %d", attachformat);
+ }
+
+ /*
+ ** Finish up with the file name.
+ */
+
+ fprintf(composition_file, " %s\n", file_name);
+
+ return;
+}
+
+/*
+** Annotate original message, and
+** call `postproc' to send message.
+*/
+
+static int
+sendaux(char **vec, int vecp, char *drft, struct stat *st)
+{
+ pid_t child_id;
+ int i, status, fd, fd2;
+ char backup[BUFSIZ], buf[BUFSIZ];
+
+ fd = pushsw ? tmp_fd() : NOTOK;
+ fd2 = NOTOK;
+
+ vec[vecp++] = drft;
+ if (annotext) {
+ if ((fd2 = tmp_fd()) != NOTOK) {
+ vec[vecp++] = "-idanno";
+ snprintf(buf, sizeof(buf), "%d", fd2);
+ vec[vecp++] = buf;
+ } else {
+ admonish(NULL, "unable to create file for annotation list");
+ }
+ }
+ if (distfile && distout(drft, distfile, backup) == NOTOK)
+ done(1);
+ vec[vecp] = NULL;
+
+ for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
+ sleep(5);
+
+ switch (child_id) {
+ case -1:
+ /* oops -- fork error */
+ adios("fork", "unable to");
+ break; /* NOT REACHED */
+
+ case 0:
+ /*
+ ** child process -- send it
+ **
+ ** If fd is ok, then we are pushing and fd points to temp
+ ** file, so capture anything on stdout and stderr there.
+ */
+ if (fd != NOTOK) {
+ dup2(fd, fileno(stdout));
+ dup2(fd, fileno(stderr));
+ close(fd);
+ }
+ execvp(postproc, vec);
+ fprintf(stderr, "unable to exec ");
+ perror(postproc);
+ _exit(-1);
+ break; /* NOT REACHED */
+
+ default:
+ /*
+ ** parent process -- wait for it
+ */
+ if ((status = pidwait(child_id, NOTOK)) == OK) {
+ if (annotext && fd2 != NOTOK)
+ anno(fd2, st);
+ } else {
+ /*
+ ** If postproc failed, and we have good fd (which
+ ** means we pushed), then mail error message
+ ** (and possibly the draft) back to the user.
+ */
+ if (fd != NOTOK) {
+ alert(drft, fd);
+ close(fd);
+ } else {
+ advise(NULL, "message not delivered to anyone");
+ }
+ if (annotext && fd2 != NOTOK)
+ close(fd2);
+ if (distfile) {
+ unlink(drft);
+ if (rename(backup, drft) == NOTOK)
+ advise(drft, "unable to rename %s to",
+ backup);
+ }
+ }
+ break;
+ }
+
+ return status;