X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/db744b85cee9eccd9840823d06fa8ea1ff124993..c576ad2674c37a1c63f004c71049998f38854c64:/sbr/mime_type.c diff --git a/sbr/mime_type.c b/sbr/mime_type.c index e4f3e5b8..0bfc3377 100644 --- a/sbr/mime_type.c +++ b/sbr/mime_type.c @@ -1,5 +1,4 @@ -/* - * mime_type.c -- routine to determine the MIME Content-Type of a file +/* mime_type.c -- routine to determine the MIME Content-Type of a file * * This code is Copyright (c) 2014, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for @@ -9,6 +8,7 @@ #include #include #include +#include "mime_type.h" #ifdef MIMETYPEPROC static char *get_file_info(const char *, const char *); @@ -33,17 +33,13 @@ mime_type(const char *file_name) { /* Try to append charset for text content. */ char *mimeencoding; - if (strncasecmp(mimetype, "text", 4) == 0) { - if ((mimeencoding = get_file_info(MIMEENCODINGPROC, file_name))) { - content_type = concat(mimetype, "; charset=", mimeencoding, - NULL); - free (mimetype); - } else { - content_type = mimetype; - } - } else { + if (!strncasecmp(mimetype, "text", 4) && + (mimeencoding = get_file_info(MIMEENCODINGPROC, file_name))) { + content_type = concat(mimetype, "; charset=", mimeencoding, NULL); + free(mimeencoding); + free(mimetype); + } else content_type = mimetype; - } #else /* MIMEENCODINGPROC */ content_type = mimetype; #endif /* MIMEENCODINGPROC */ @@ -69,7 +65,7 @@ mime_type(const char *file_name) { if ((p = strrchr(file_name, '.')) != NULL) { for (np = m_defs; np; np = np->n_next) { if (strncasecmp(np->n_name, "mhshow-suffix-", 14) == 0 && - strcasecmp(p, np->n_field ? np->n_field : "") == 0) { + strcasecmp(p, FENDNULL(np->n_field)) == 0) { content_type = strdup(np->n_name + 14); break; } @@ -87,7 +83,7 @@ mime_type(const char *file_name) { int binary = 0, c; if (!(fp = fopen(file_name, "r"))) { - advise (NULL, "unable to access file \"%s\"", file_name); + inform("unable to access file \"%s\"", file_name); return NULL; } @@ -112,64 +108,58 @@ mime_type(const char *file_name) { #ifdef MIMETYPEPROC /* * Get information using proc about a file. - */ + * Non-null return value must be free(3)'d. */ static char * -get_file_info(const char *proc, const char *file_name) { - char *cmd, *cp; - char *quotec = "'"; - - if ((cp = strchr(file_name, '\''))) { - /* file_name contains a single quote. */ +get_file_info(const char *proc, const char *file_name) +{ + char *quotec; + char *cmd; + FILE *fp; + bool ok; + char buf[max(BUFSIZ, 2048)]; + char *info; + char *needle; + + if (strchr(file_name, '\'')) { if (strchr(file_name, '"')) { - advise(NULL, "filenames containing both single and double quotes " - "are unsupported for attachment"); + inform("filenames containing both single and double quotes " + "are unsupported for attachment"); return NULL; } quotec = "\""; - } + } else + quotec = "'"; - if ((cmd = concat(proc, " ", quotec, file_name, quotec, NULL))) { - FILE *fp; - - if ((fp = popen(cmd, "r")) != NULL) { - char buf[BUFSIZ >= 2048 ? BUFSIZ : 2048]; - - buf[0] = '\0'; - if (fgets(buf, sizeof buf, fp)) { - char *eol; - - /* Skip leading :, if present. */ - if ((cp = strchr(buf, ':')) != NULL) { - ++cp; - while (*cp && isblank((unsigned char) *cp)) { - ++cp; - } - } else { - cp = buf; - } - - /* Truncate at newline (LF or CR), if present. */ - if ((eol = strpbrk(cp, "\n\r")) != NULL) { - *eol = '\0'; - } - } else if (buf[0] == '\0') { - /* This can happen on Cygwin if the popen() - mysteriously fails. Return NULL so that the caller - will use another method to determine the info. */ - free (cp); - cp = NULL; - } - - (void) pclose(fp); - } else { - advise(NULL, "no output from %s", cmd); - } + cmd = concat(proc, " ", quotec, file_name, quotec, NULL); + if (!cmd) { + inform("concat with \"%s\" failed, out of memory?", proc); + return NULL; + } + if ((fp = popen(cmd, "r")) == NULL) { + inform("no output from %s", cmd); free(cmd); - } else { - advise(NULL, "concat with \"%s\" failed, out of memory?", proc); + return NULL; } - return cp ? strdup(cp) : NULL; + ok = fgets(buf, sizeof buf, fp); + free(cmd); + (void)pclose(fp); + if (!ok) + return NULL; + + /* s#^.*:[ \t]*##. */ + info = buf; + if ((needle = strchr(info, ':'))) { + info = needle + 1; + while (isblank((unsigned char)*info)) + info++; + } + + /* s#[\n\r].*##. */ + if ((needle = strpbrk(info, "\n\r"))) + *needle = '\0'; + + return strdup(info); } #endif /* MIMETYPEPROC */