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