X-Git-Url: http://git.marmaro.de/?a=blobdiff_plain;f=uip%2Fsendsbr.c;h=dfd974f481694c9b9d6763cd450038ab2caa884f;hb=356f49083391bd018b6c5dfed21e59247b4cc74a;hp=877538bfb70d2cafd83c2c2630b4334b4db19804;hpb=38615191e71744b066425e0c44412b62dbe49cc2;p=mmh diff --git a/uip/sendsbr.c b/uip/sendsbr.c index 877538b..dfd974f 100644 --- a/uip/sendsbr.c +++ b/uip/sendsbr.c @@ -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. @@ -18,16 +16,10 @@ #include #include -#ifdef TIME_WITH_SYS_TIME +#ifdef HAVE_SYS_TIME_H # include -# include -#else -# ifdef TM_IN_SYS_TIME -# include -# else -# include -# endif #endif +#include int debugsw = 0; /* global */ int forwsw = 1; @@ -43,8 +35,8 @@ char *distfile = NULL; 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 */ @@ -60,7 +52,7 @@ char *getusername (void); /* * static prototypes */ -static void armed_done (int); +static void armed_done (int) NORETURN; static void alert (char *, int); static int tmp_fd (void); static void anno (int, struct stat *); @@ -71,7 +63,7 @@ static int sendaux (char **, int, char *, struct stat *); static int attach(char *, char *, int); static void clean_up_temporary_files(void); static int get_line(void); -static void make_mime_composition_file_entry(char *, int); +static void make_mime_composition_file_entry(char *, int, char *); /* @@ -125,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; } @@ -191,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. @@ -213,19 +209,27 @@ attach(char *attachment_header_field_name, char *draft_file_name, field = (char *)mh_xmalloc(field_size = 256); /* - * Scan the draft file for a header field name that matches the -attach - * argument. The existence of one indicates that the draft has attachments. - * Bail out if there are no attachments because we're done. Read to the - * end of the headers even if we have no attachments. + * Scan the draft file for a header field name, with a non-empty + * body, that matches the -attach argument. The existence of one + * indicates that the draft has attachments. Bail out if there + * are no attachments because we're done. Read to the end of the + * headers even if we have no attachments. */ length = strlen(attachment_header_field_name); has_attachment = 0; - while (get_line() != EOF && *field != '\0' && *field != '-') - if (strncasecmp(field, attachment_header_field_name, length) == 0 && field[length] == ':') - has_attachment = 1; + while (get_line() != EOF && *field != '\0' && *field != '-') { + if (strncasecmp(field, attachment_header_field_name, length) == 0 && + field[length] == ':') { + for (p = field + length + 1; *p == ' ' || *p == '\t'; p++) + ; + if (strlen (p) > 0) { + has_attachment = 1; + } + } + } if (has_attachment == 0) return (DONE); @@ -253,8 +257,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"); @@ -267,14 +275,16 @@ attach(char *attachment_header_field_name, char *draft_file_name, } /* - * Start at the beginning of the draft file. Copy all non-attachment header fields - * to the temporary composition file. Then add the dashed line separator. + * Start at the beginning of the draft file. Copy all + * non-attachment header fields to the temporary composition + * file. Then add the dashed line separator. */ rewind(draft_file); while (get_line() != EOF && *field != '\0' && *field != '-') - if (strncasecmp(field, attachment_header_field_name, length) != 0 || field[length] != ':') + if (strncasecmp(field, attachment_header_field_name, length) != 0 || + field[length] != ':') (void)fprintf(composition_file, "%s\n", field); (void)fputs("--------\n", composition_file); @@ -292,32 +302,58 @@ attach(char *attachment_header_field_name, char *draft_file_name, /* * Add a mhbuild MIME composition file line for the body if there was one. + * Set the default content type to text/plain so that mhbuild takes care + * of any necessary encoding. */ if (has_body) - make_mime_composition_file_entry(body_file_name, attachformat); + make_mime_composition_file_entry(body_file_name, attachformat, + "text/plain"); /* - * Now, go back to the beginning of the draft file and look for header fields - * that specify attachments. Add a mhbuild MIME composition file for each. + * Now, go back to the beginning of the draft file and look for + * header fields 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 != '-') { - if (strncasecmp(field, attachment_header_field_name, length) == 0 && field[length] == ':') { + if (strncasecmp(field, attachment_header_field_name, length) == 0 && + field[length] == ':') { for (p = field + length + 1; *p == ' ' || *p == '\t'; p++) ; - make_mime_composition_file_entry(p, attachformat); + /* Skip empty attachment_header_field_name lines. */ + if (strlen (p) > 0) { + struct stat st; + if (stat (p, &st) == OK) { + if (S_ISREG (st.st_mode)) { + /* Don't set the default content type so take + make_mime_composition_file_entry() will try + to infer it from the file type. */ + make_mime_composition_file_entry(p, attachformat, 0); + } else { + adios (NULL, "unable to attach %s, not a plain file", + p); + } + } else { + adios (NULL, "unable to access file \"%s\"", p); + } + } } } (void)fclose(composition_file); /* - * We're ready to roll! Run mhbuild on the composition file. Note that mhbuild - * is in the context as buildmimeproc. + * We're ready to roll! Run mhbuild on the composition file. + * Note that mhbuild is in the context as buildmimeproc. */ (void)sprintf(buf, "%s %s", buildmimeproc, composition_file_name); @@ -377,18 +413,19 @@ get_line(void) } static void -make_mime_composition_file_entry(char *file_name, int attachformat) +make_mime_composition_file_entry(char *file_name, int attachformat, + char *default_content_type) { 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 */ char *p; /* miscellaneous string pointer */ struct stat st; /* file status buffer */ - content_type = (char *)0; + content_type = default_content_type; /* * Check the file name for a suffix. Scan the context for that suffix on a @@ -451,7 +488,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); } @@ -495,11 +532,14 @@ make_mime_composition_file_entry(char *file_name, int attachformat) least. */ (void) fprintf (composition_file, "#%s <>", content_type); } else { - /* Suppress Content-Id, insert simple Content-Disposition. */ + /* Suppress Content-Id, insert simple Content-Disposition + and Content-Description with filename. */ + p = strrchr(file_name, '/'); (void) fprintf (composition_file, - "#%s; name=\"%s\" <>{attachment}", + "#%s; name=\"%s\" <> [%s]{attachment}", content_type, - ((p = strrchr(file_name, '/')) == (char *)0) ? file_name : p + 1); + (p == (char *)0) ? file_name : p + 1, + (p == (char *)0) ? file_name : p + 1); } break; @@ -512,11 +552,13 @@ make_mime_composition_file_entry(char *file_name, int attachformat) (void) fprintf (composition_file, "#%s <>", content_type); } else { /* Suppress Content-Id, insert Content-Disposition with - modification date. */ + modification date and Content-Description wtih filename. */ + p = strrchr(file_name, '/'); (void) fprintf (composition_file, - "#%s; name=\"%s\" <>{attachment; modification-date=\"%s\"}", + "#%s; name=\"%s\" <>[%s]{attachment; modification-date=\"%s\"}", content_type, - ((p = strrchr(file_name, '/')) == (char *)0) ? file_name : p + 1, + (p == (char *)0) ? file_name : p + 1, + (p == (char *)0) ? file_name : p + 1, dtime (&st.st_mtime, 0)); } @@ -668,17 +710,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); /* @@ -919,16 +962,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; } @@ -968,14 +1012,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;