]> diplodocus.org Git - nmh/blob - uip/mhlistsbr.c
oauth.c: Alter permissions from 0755 to 0644.
[nmh] / uip / mhlistsbr.c
1 /* mhlistsbr.c -- routines to list information about the
2 * -- contents of 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 "sbr/r1bindex.h"
11 #include "sbr/trimcpy.h"
12 #include <fcntl.h>
13 #include "h/mts.h"
14 #include "h/tws.h"
15 #include "h/mime.h"
16 #include "h/mhparse.h"
17 #include "h/utils.h"
18 #include "mhmisc.h"
19
20 /*
21 * static prototypes
22 */
23 static void list_single_message (CT, int, int, int, int);
24 static int list_debug (CT);
25 static int list_multi (CT, int, int, int, int, int);
26 static int list_partial (CT, int, int, int, int, int);
27 static int list_external (CT, int, int, int, int, int);
28 static int list_encoding (CT);
29
30
31 /*
32 * various formats for -list option
33 */
34 #define LSTFMT1 "%4s %-5s %-24s %5s %s\n"
35 #define LSTFMT2a "%4d "
36 #define LSTFMT2b "%-5s %-24.24s "
37 #define LSTFMT2bv "%-5s %-24s "
38 #define LSTFMT2c1 "%5lu"
39 #define LSTFMT2c2 "%4lu%c"
40 #define LSTFMT2c3 "huge "
41 #define LSTFMT2c4 " "
42 #define LSTFMT2d1 " %.36s"
43 #define LSTFMT2d1v " %s"
44 #define LSTFMT2d2 "\t %-65s\n"
45
46
47 /*
48 * Top level entry point to list group of messages
49 */
50
51 void
52 list_all_messages (CT *cts, int headers, int realsize, int verbose, int debug,
53 int dispo)
54 {
55 CT ct, *ctp;
56
57 if (headers)
58 printf (LSTFMT1, "msg", "part", "type/subtype", "size", "description");
59
60 for (ctp = cts; *ctp; ctp++) {
61 ct = *ctp;
62 list_single_message (ct, realsize, verbose, debug, dispo);
63 }
64
65 flush_errors ();
66 }
67
68
69 /*
70 * Entry point to list a single message
71 */
72
73 static void
74 list_single_message (CT ct, int realsize, int verbose, int debug, int dispo)
75 {
76 if (type_ok (ct, 1)) {
77 umask (ct->c_umask);
78 list_switch (ct, 1, realsize, verbose, debug, dispo);
79 if (ct->c_fp) {
80 fclose (ct->c_fp);
81 ct->c_fp = NULL;
82 }
83 if (ct->c_ceclosefnx)
84 (*ct->c_ceclosefnx) (ct);
85 }
86 }
87
88
89 /*
90 * Primary switching routine to list information about a content
91 */
92
93 int
94 list_switch (CT ct, int toplevel, int realsize, int verbose, int debug,
95 int dispo)
96 {
97 switch (ct->c_type) {
98 case CT_MULTIPART:
99 return list_multi (ct, toplevel, realsize, verbose, debug, dispo);
100
101 case CT_MESSAGE:
102 switch (ct->c_subtype) {
103 case MESSAGE_PARTIAL:
104 return list_partial (ct, toplevel, realsize, verbose,
105 debug, dispo);
106
107 case MESSAGE_EXTERNAL:
108 return list_external (ct, toplevel, realsize, verbose,
109 debug, dispo);
110
111 case MESSAGE_RFC822:
112 default:
113 return list_content (ct, toplevel, realsize, verbose,
114 debug, dispo);
115 }
116
117 case CT_TEXT:
118 case CT_AUDIO:
119 case CT_IMAGE:
120 case CT_VIDEO:
121 case CT_APPLICATION:
122 default:
123 return list_content (ct, toplevel, realsize, verbose, debug, dispo);
124 }
125
126 return 0; /* NOT REACHED */
127 }
128
129
130 /*
131 * Method for listing information about a simple/generic content
132 */
133
134 int
135 list_content (CT ct, int toplevel, int realsize, int verbose, int debug,
136 int dispo)
137 {
138 unsigned long size;
139 char *cp, buffer[BUFSIZ];
140 CI ci = &ct->c_ctinfo;
141 PM pm;
142
143 if (toplevel > 0)
144 printf (LSTFMT2a, atoi (r1bindex (FENDNULL(ct->c_file), '/')));
145 else
146 printf(toplevel < 0 ? "part " : " ");
147
148 snprintf (buffer, sizeof(buffer), "%s/%s", FENDNULL(ci->ci_type),
149 FENDNULL(ci->ci_subtype));
150 if (verbose)
151 printf (LSTFMT2bv, FENDNULL(ct->c_partno), buffer);
152 else
153 printf (LSTFMT2b, FENDNULL(ct->c_partno), buffer);
154
155 if (ct->c_cesizefnx && realsize)
156 size = (*ct->c_cesizefnx) (ct);
157 else
158 size = ct->c_end - ct->c_begin;
159
160 /* find correct scale for size (Kilo/Mega/Giga/Tera) */
161 for (cp = " KMGT"; size > 9999; size /= 1000)
162 if (!*++cp)
163 break;
164
165 /* print size of this body part */
166 switch (*cp) {
167 case ' ':
168 if (size > 0 || ct->c_encoding != CE_EXTERNAL)
169 printf (LSTFMT2c1, size);
170 else
171 printf (LSTFMT2c4);
172 break;
173
174 default:
175 printf (LSTFMT2c2, size, *cp);
176 break;
177
178 case '\0':
179 printf (LSTFMT2c3);
180 }
181
182 /* print Content-Description */
183 if (ct->c_descr) {
184 char *dp;
185
186 dp = cpytrim (ct->c_descr);
187 if (verbose)
188 printf (LSTFMT2d1v, dp);
189 else
190 printf (LSTFMT2d1, dp);
191 free (dp);
192 }
193
194 putchar('\n');
195
196 if (verbose) {
197 CI ci = &ct->c_ctinfo;
198
199 for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
200 printf ("\t %s=\"%s\"\n", pm->pm_name,
201 get_param_value(pm, '?'));
202 }
203
204 /*
205 * If verbose, print any RFC-822 comments in the
206 * Content-Type line.
207 */
208 if (ci->ci_comment) {
209 char *dp;
210
211 dp = cpytrim (ci->ci_comment);
212 snprintf (buffer, sizeof(buffer), "(%s)", dp);
213 free (dp);
214 printf (LSTFMT2d2, buffer);
215 }
216 }
217
218 if (dispo && ct->c_dispo_type) {
219 printf ("\t disposition \"%s\"\n", ct->c_dispo_type);
220
221 if (verbose) {
222 for (pm = ct->c_dispo_first; pm; pm = pm->pm_next) {
223 printf ("\t %s=\"%s\"\n", pm->pm_name,
224 get_param_value(pm, '?'));
225 }
226 }
227 }
228
229 if (debug)
230 list_debug (ct);
231
232 return OK;
233 }
234
235
236 /*
237 * Print debugging information about a content
238 */
239
240 static int
241 list_debug (CT ct)
242 {
243 CI ci = &ct->c_ctinfo;
244 PM pm;
245
246 fflush (stdout);
247 fprintf (stderr, " partno \"%s\"\n", FENDNULL(ct->c_partno));
248
249 /* print MIME-Version line */
250 if (ct->c_vrsn)
251 fprintf (stderr, " %s:%s\n", VRSN_FIELD, ct->c_vrsn);
252
253 /* print Content-Type line */
254 if (ct->c_ctline)
255 fprintf (stderr, " %s:%s\n", TYPE_FIELD, ct->c_ctline);
256
257 /* print parsed elements of content type */
258 fprintf (stderr, " type \"%s\"\n", FENDNULL(ci->ci_type));
259 fprintf (stderr, " subtype \"%s\"\n", FENDNULL(ci->ci_subtype));
260 fprintf (stderr, " comment \"%s\"\n", FENDNULL(ci->ci_comment));
261 fprintf (stderr, " magic \"%s\"\n", FENDNULL(ci->ci_magic));
262
263 /* print parsed parameters attached to content type */
264 fprintf (stderr, " parameters\n");
265 for (pm = ci->ci_first_pm; pm; pm = pm->pm_next)
266 fprintf (stderr, " %s=\"%s\"\n", pm->pm_name,
267 get_param_value(pm, '?'));
268
269 /* print internal flags for type/subtype */
270 fprintf(stderr, " type %#x subtype %#x params %p\n",
271 ct->c_type, ct->c_subtype, (void *)ct->c_ctparams);
272
273 fprintf (stderr, " showproc \"%s\"\n", FENDNULL(ct->c_showproc));
274 fprintf (stderr, " termproc \"%s\"\n", FENDNULL(ct->c_termproc));
275 fprintf (stderr, " storeproc \"%s\"\n", FENDNULL(ct->c_storeproc));
276
277 /* print transfer encoding information */
278 if (ct->c_celine)
279 fprintf (stderr, " %s:%s", ENCODING_FIELD, ct->c_celine);
280
281 /* print internal flags for transfer encoding */
282 fprintf(stderr, " transfer encoding %#x params %p\n",
283 ct->c_encoding, (void *)&ct->c_cefile);
284
285 /* print Content-ID */
286 if (ct->c_id)
287 fprintf (stderr, " %s:%s", ID_FIELD, ct->c_id);
288
289 /* print Content-Description */
290 if (ct->c_descr)
291 fprintf (stderr, " %s:%s", DESCR_FIELD, ct->c_descr);
292
293 /* print Content-Disposition */
294 if (ct->c_dispo)
295 fprintf (stderr, " %s:%s", DISPO_FIELD, ct->c_dispo);
296
297 fprintf(stderr, " disposition \"%s\"\n", FENDNULL(ct->c_dispo_type));
298 fprintf(stderr, " disposition parameters\n");
299 for (pm = ct->c_dispo_first; pm; pm = pm->pm_next)
300 fprintf (stderr, " %s=\"%s\"\n", pm->pm_name,
301 get_param_value(pm, '?'));
302
303 fprintf(stderr, " read fp %p file \"%s\" begin %ld end %ld\n",
304 (void *)ct->c_fp, FENDNULL(ct->c_file), ct->c_begin, ct->c_end);
305
306 /* print more information about transfer encoding */
307 list_encoding (ct);
308
309 return OK;
310 }
311
312
313 /*
314 * list content information for type "multipart"
315 */
316
317 static int
318 list_multi (CT ct, int toplevel, int realsize, int verbose, int debug,
319 int dispo)
320 {
321 struct multipart *m = (struct multipart *) ct->c_ctparams;
322 struct part *part;
323
324 /* list the content for toplevel of this multipart */
325 list_content (ct, toplevel, realsize, verbose, debug, dispo);
326
327 /* now list for all the subparts */
328 for (part = m->mp_parts; part; part = part->mp_next) {
329 CT p = part->mp_part;
330
331 if (part_ok (p) && type_ok (p, 1))
332 list_switch (p, 0, realsize, verbose, debug, dispo);
333 }
334
335 return OK;
336 }
337
338
339 /*
340 * list content information for type "message/partial"
341 */
342
343 static int
344 list_partial (CT ct, int toplevel, int realsize, int verbose, int debug,
345 int dispo)
346 {
347 struct partial *p = (struct partial *) ct->c_ctparams;
348
349 list_content (ct, toplevel, realsize, verbose, debug, dispo);
350 if (verbose) {
351 printf ("\t [message %s, part %d", p->pm_partid, p->pm_partno);
352 if (p->pm_maxno)
353 printf (" of %d", p->pm_maxno);
354 puts("]");
355 }
356
357 return OK;
358 }
359
360
361 /*
362 * list content information for type "message/external"
363 */
364
365 static int
366 list_external (CT ct, int toplevel, int realsize, int verbose, int debug,
367 int dispo)
368 {
369 struct exbody *e = (struct exbody *) ct->c_ctparams;
370
371 /*
372 * First list the information for the
373 * message/external content itself.
374 */
375 list_content (ct, toplevel, realsize, verbose, debug, dispo);
376
377 if (verbose) {
378 if (!e->eb_access)
379 puts("\t [missing access-type]"); /* Must be defined. */
380 if (e->eb_flags == NOTOK)
381 puts("\t [service unavailable]");
382 }
383
384 /*
385 * Now list the information for the external content
386 * to which this content points.
387 */
388 list_content (e->eb_content, 0, realsize, verbose, debug, dispo);
389
390 return OK;
391 }
392
393
394 /*
395 * list information about the Content-Transfer-Encoding
396 * used by a content.
397 */
398
399 static int
400 list_encoding (CT ct)
401 {
402 CE ce = &ct->c_cefile;
403
404 fprintf(stderr, " decoded fp %p file \"%s\"\n",
405 (void *)ce->ce_fp, FENDNULL(ce->ce_file));
406
407 return OK;
408 }