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