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