static void
make_mime_composition_file_entry(char *file_name)
{
- int binary; /* binary character found flag */
- int c; /* current character */
- 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 */
-
- content_type = NULL;
-
-
- /*
- ** Check the file name for a suffix. Scan the context for that
- ** suffix on a mhshow-suffix- entry. We use these entries to
- ** be compatible with mhshow, and there's no reason to make the
- ** user specify each suffix twice. Context entries of the form
- ** "mhshow-suffix-contenttype" in the name have the suffix in
- ** the field, including the dot.
- */
-
- if ((p = strrchr(file_name, '.')) != NULL) {
- for (np = m_defs; np; np = np->n_next) {
- if (strncasecmp(np->n_name, "mhshow-suffix-", 14) == 0
- && mh_strcasecmp(p, np->n_field) == 0)
- {
- content_type = np->n_name + 14;
- break;
- }
+ FILE *fp;
+ struct node *np;
+ char *cp;
+ char content_type[BUFSIZ];
+ char cmdbuf[BUFSIZ];
+ char *cmd = mimetypequeryproc;
+
+ for (np = m_defs; np; np = np->n_next) {
+ if (strcasecmp(np->n_name, mimetypequery)==0) {
+ cmd = np->n_field;
+ break;
}
}
+ snprintf(cmdbuf, sizeof cmdbuf, "%s %s", cmd, file_name);
- /*
- ** No content type was found, either because there was no matching
- ** entry in the context or because the file name has no suffix.
- ** Open the file and check for non-ASCII characters. Choose the
- ** content type based on this check.
- */
-
- if (content_type == NULL) {
- if ((fp = fopen(file_name, "r")) == (FILE *)0) {
- clean_up_temporary_files();
- adios(NULL, "unable to access file \"%s\"",
- file_name);
- }
-
- binary = 0;
-
- while ((c = getc(fp)) != EOF) {
- if (c > 127 || c < 0) {
- binary = 1;
- break;
- }
- }
-
- fclose(fp);
-
- content_type = binary ?
- "application/octet-stream" : "text/plain";
+ if (!(fp = popen(cmdbuf, "r"))) {
+ clean_up_temporary_files();
+ adios(NULL, "unable to determine content type with `%s'",
+ cmdbuf);
}
+ if (fgets(content_type, sizeof content_type, fp) &&
+ (cp = strrchr(content_type, '\n'))) {
+ *cp = '\0';
+ } else {
+ strcpy(content_type, "application/octet-stream");
+ admonish(NULL, "problems with `%s', using fall back type `%s'",
+ cmdbuf, content_type);
+ }
+ pclose(fp);
- /*
- ** Make sure that the attachment file exists and is readable.
- ** Append a mhbuild directive to the draft file. This starts with
- ** the content type. Append a file name attribute and a private
- ** x-unix-mode attribute. Also append a description obtained
- ** (if possible) by running the "file" command on the file.
- */
-
+ /* TODO: don't use access(2) because it checks for ruid, not euid */
if (access(file_name, R_OK) != 0) {
clean_up_temporary_files();
- adios(NULL, "unable to access file \"%s\"", file_name);
+ adios(NULL, "unable to access file `%s'", file_name);
}
+ fprintf(composition_file, "#%s; name=\"%s\" <>{attachment}",
+ content_type,
+ (!(cp = strrchr(file_name, '/'))) ? file_name : cp + 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);
- }
-
- /* Finish up with the file name. */
fprintf(composition_file, " %s\n", file_name);
return;