source: trunk/third/nmh/uip/mhlistsbr.c @ 12455

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