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