]> diplodocus.org Git - nmh/blob - uip/mhmisc.c
Fix bug #42718; ali(1) still refers to removed options -normalize and
[nmh] / uip / mhmisc.c
1
2 /*
3 * mhparse.c -- misc routines to process MIME messages
4 *
5 * This code is Copyright (c) 2002, by the authors of nmh. See the
6 * COPYRIGHT file in the root directory of the nmh distribution for
7 * complete copyright information.
8 */
9
10 #include <h/mh.h>
11 #include <h/mime.h>
12 #include <h/mhparse.h>
13 #include <h/utils.h>
14
15 extern int debugsw;
16
17 /*
18 * limit actions to specified parts or content types
19 */
20 int npart = 0;
21 int ntype = 0;
22 char *parts[NPARTS + 1];
23 char *types[NTYPES + 1];
24
25 int userrs = 0;
26
27 static char *errs = NULL;
28
29
30 /*
31 * prototypes
32 */
33 int part_ok (CT, int);
34 int type_ok (CT, int);
35 void content_error (char *, CT, char *, ...);
36 void flush_errors (void);
37
38
39 int
40 part_ok (CT ct, int sP)
41 {
42 char **ap;
43 int len;
44
45 if (npart == 0 || (ct->c_type == CT_MULTIPART && (sP || ct->c_subtype)))
46 return 1;
47
48 for (ap = parts; *ap; ap++) {
49 len = strlen(*ap);
50 if (!strncmp (*ap, ct->c_partno, len) &&
51 (!ct->c_partno[len] || ct->c_partno[len] == '.' ))
52 return 1;
53 }
54
55 return 0;
56 }
57
58
59 int
60 type_ok (CT ct, int sP)
61 {
62 char **ap;
63 char buffer[BUFSIZ];
64 CI ci = &ct->c_ctinfo;
65
66 if (ntype == 0 || (ct->c_type == CT_MULTIPART && (sP || ct->c_subtype)))
67 return 1;
68
69 snprintf (buffer, sizeof(buffer), "%s/%s", ci->ci_type, ci->ci_subtype);
70 for (ap = types; *ap; ap++)
71 if (!strcasecmp (*ap, ci->ci_type) || !strcasecmp (*ap, buffer))
72 return 1;
73
74 return 0;
75 }
76
77
78 /*
79 * Returns true if this content is marked as "inline".
80 *
81 * Technically we should check parent content to see if they have
82 * disposition to use as a default, but we don't right now. Maybe
83 * later ....
84 */
85
86 int
87 is_inline(CT ct)
88 {
89 /*
90 * If there isn't any disposition at all, it's "inline". Obviously
91 * if it's "inline", then it's inline. RFC 2183 says if it's an unknown
92 * disposition, treat it as 'attachment'.
93 */
94
95 if (! ct->c_dispo_type || strcasecmp(ct->c_dispo_type, "inline") == 0)
96 return 1;
97 else
98 return 0;
99 }
100
101 int
102 make_intermediates (char *file)
103 {
104 char *cp;
105
106 for (cp = file + 1; (cp = strchr(cp, '/')); cp++) {
107 struct stat st;
108
109 *cp = '\0';
110 if (stat (file, &st) == NOTOK) {
111 int answer;
112 char *ep;
113 if (errno != ENOENT) {
114 advise (file, "error on directory");
115 losing_directory:
116 *cp = '/';
117 return NOTOK;
118 }
119
120 ep = concat ("Create directory \"", file, "\"? ", NULL);
121 answer = getanswer (ep);
122 free (ep);
123
124 if (!answer)
125 goto losing_directory;
126 if (!makedir (file)) {
127 advise (NULL, "unable to create directory %s", file);
128 goto losing_directory;
129 }
130 }
131
132 *cp = '/';
133 }
134
135 return OK;
136 }
137
138
139 /*
140 * Construct error message for content
141 */
142
143 void
144 content_error (char *what, CT ct, char *fmt, ...)
145 {
146 va_list arglist;
147 int i, len, buflen;
148 char *bp, buffer[BUFSIZ];
149 CI ci;
150
151 bp = buffer;
152 buflen = sizeof(buffer);
153
154 if (userrs && invo_name && *invo_name) {
155 snprintf (bp, buflen, "%s: ", invo_name);
156 len = strlen (bp);
157 bp += len;
158 buflen -= len;
159 }
160
161 va_start (arglist, fmt);
162
163 vsnprintf (bp, buflen, fmt, arglist);
164 len = strlen (bp);
165 bp += len;
166 buflen -= len;
167
168 ci = &ct->c_ctinfo;
169
170 if (what) {
171 char *s;
172
173 if (*what) {
174 snprintf (bp, buflen, " %s: ", what);
175 len = strlen (bp);
176 bp += len;
177 buflen -= len;
178 }
179
180 if ((s = strerror (errno)))
181 snprintf (bp, buflen, "%s", s);
182 else
183 snprintf (bp, buflen, "Error %d", errno);
184
185 len = strlen (bp);
186 bp += len;
187 buflen -= len;
188 }
189
190 i = strlen (invo_name) + 2;
191
192 /* Now add content type and subtype */
193 snprintf (bp, buflen, "\n%*.*s(content %s/%s", i, i, "",
194 ci->ci_type, ci->ci_subtype);
195 len = strlen (bp);
196 bp += len;
197 buflen -= len;
198
199 /* Now add the message/part number */
200 if (ct->c_file) {
201 snprintf (bp, buflen, " in message %s", ct->c_file);
202 len = strlen (bp);
203 bp += len;
204 buflen -= len;
205
206 if (ct->c_partno) {
207 snprintf (bp, buflen, ", part %s", ct->c_partno);
208 len = strlen (bp);
209 bp += len;
210 buflen -= len;
211 }
212 }
213
214 snprintf (bp, buflen, ")");
215 len = strlen (bp);
216 bp += len;
217 buflen -= len;
218
219 if (userrs) {
220 *bp++ = '\n';
221 *bp = '\0';
222 buflen--;
223
224 errs = add (buffer, errs);
225 } else {
226 advise (NULL, "%s", buffer);
227 }
228 }
229
230
231 void
232 flush_errors (void)
233 {
234 if (errs) {
235 fflush (stdout);
236 fprintf (stderr, "%s", errs);
237 free (errs);
238 errs = NULL;
239 }
240 }