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