]> diplodocus.org Git - nmh/blob - uip/attach.c
Document changes to mhbuild and send.
[nmh] / uip / attach.c
1 /*
2 * attach.c -- routines to help attach files via whatnow
3 *
4 * This code is Copyright (c) 2002, by the authors of nmh. See the
5 * COPYRIGHT file in the root directory of the nmh distribution for
6 * complete copyright information.
7 */
8
9 #include <h/mh.h>
10 #include <h/utils.h>
11 #include <h/tws.h>
12
13 #ifdef MIMETYPEPROC
14 static char *get_file_info(const char *, const char *);
15 #endif /* MIMETYPEPROC */
16
17 /*
18 * Try to use external command to determine mime type, and possibly
19 * encoding. Caller is responsible for free'ing returned memory.
20 */
21 char *
22 mime_type(const char *file_name) {
23 char *content_type = NULL; /* mime content type */
24
25 #ifdef MIMETYPEPROC
26 char *mimetype;
27
28 if ((mimetype = get_file_info(MIMETYPEPROC, file_name))) {
29 #ifdef MIMEENCODINGPROC
30 /* Try to append charset for text content. */
31 char *mimeencoding;
32
33 if (strncasecmp(mimetype, "text", 4) == 0) {
34 if ((mimeencoding = get_file_info(MIMEENCODINGPROC, file_name))) {
35 content_type = concat(mimetype, "; charset=", mimeencoding,
36 NULL);
37 } else {
38 content_type = strdup(mimetype);
39 }
40 } else {
41 content_type = strdup(mimetype);
42 }
43 #else /* MIMEENCODINGPROC */
44 content_type = strdup(mimetype);
45 #endif /* MIMEENCODINGPROC */
46 }
47 #else /* MIMETYPEPROC */
48 NMH_UNUSED(file_name);
49 #endif /* MIMETYPEPROC */
50
51 return content_type;
52 }
53
54
55 #ifdef MIMETYPEPROC
56 /*
57 * Get information using proc about a file.
58 */
59 static char *
60 get_file_info(const char *proc, const char *file_name) {
61 char *cmd, *cp;
62 char *quotec = "'";
63
64 if ((cp = strchr(file_name, '\''))) {
65 /* file_name contains a single quote. */
66 if (strchr(file_name, '"')) {
67 advise(NULL, "filenames containing both single and double quotes "
68 "are unsupported for attachment");
69 return NULL;
70 } else {
71 quotec = "\"";
72 }
73 }
74
75 cmd = concat(proc, " ", quotec, file_name, quotec, NULL);
76 if ((cmd = concat(proc, " ", quotec, file_name, quotec, NULL))) {
77 FILE *fp;
78
79 if ((fp = popen(cmd, "r")) != NULL) {
80 char buf[BUFSIZ >= 2048 ? BUFSIZ : 2048];
81
82 buf[0] = '\0';
83 if (fgets(buf, sizeof buf, fp)) {
84 char *eol;
85
86 /* Skip leading <filename>:<whitespace>, if present. */
87 if ((cp = strchr(buf, ':')) != NULL) {
88 ++cp;
89 while (*cp && isblank((unsigned char) *cp)) {
90 ++cp;
91 }
92 } else {
93 cp = buf;
94 }
95
96 /* Truncate at newline (LF or CR), if present. */
97 if ((eol = strpbrk(cp, "\n\r")) != NULL) {
98 *eol = '\0';
99 }
100 } else if (buf[0] == '\0') {
101 /* This can happen on Cygwin if the popen()
102 mysteriously fails. Return NULL so that the caller
103 will use another method to determine the info. */
104 free (cp);
105 cp = NULL;
106 }
107
108 (void) pclose(fp);
109 } else {
110 advise(NULL, "no output from %s", cmd);
111 }
112
113 free(cmd);
114 } else {
115 advise(NULL, "concat with \"%s\" failed, out of memory?", proc);
116 }
117
118 return cp ? strdup(cp) : NULL;
119 }
120 #endif /* MIMETYPEPROC */