]>
diplodocus.org Git - nmh/blob - uip/mhoutsbr.c
3 * mhoutsbr.c -- routines to output MIME messages
4 * -- given a Content structure
6 * This code is Copyright (c) 2002, by the authors of nmh. See the
7 * COPYRIGHT file in the root directory of the nmh distribution for
8 * complete copyright information.
13 #include <h/signals.h>
20 #include <h/mhparse.h>
26 int output_message (CT
, char *);
27 int output_message_fp (CT
, FILE *, char *);
32 static int output_content (CT
, FILE *);
33 static void output_headers (CT
, FILE *);
34 static int writeExternalBody (CT
, FILE *);
35 static int write8Bit (CT
, FILE *);
36 static int writeQuoted (CT
, FILE *);
37 static int writeBase64ct (CT
, FILE *);
41 * Main routine to output a MIME message contained
42 * in a Content structure, to a file. Any necessary
43 * transfer encoding is added.
47 output_message_fp (CT ct
, FILE *fp
, char *file
)
49 if (output_content (ct
, fp
) == NOTOK
)
53 advise ((file
?file
:"<FILE*>"), "error writing to");
60 output_message (CT ct
, char *file
)
65 if (! strcmp (file
, "-")) {
67 } else if ((fp
= fopen (file
, "w")) == NULL
) {
68 advise (file
, "unable to open for writing");
71 status
= output_message_fp(ct
, fp
, file
);
72 if (strcmp (file
, "-")) fclose(fp
);
78 * Output a Content structure to a file.
82 output_content (CT ct
, FILE *out
)
85 CI ci
= &ct
->c_ctinfo
;
86 char *boundary
= ci
->ci_values
[0], **ap
, **vp
;
88 for (ap
= ci
->ci_attrs
, vp
= ci
->ci_values
; *ap
; ++ap
, ++vp
) {
89 if (! mh_strcasecmp ("boundary", *ap
)) {
96 * Output all header fields for this content
98 output_headers (ct
, out
);
101 * If this is the internal content structure for a
102 * "message/external", then we are done with the
103 * headers (since it has no body).
109 * Now output the content bodies.
111 switch (ct
->c_type
) {
120 m
= (struct multipart
*) ct
->c_ctparams
;
122 if (m
->mp_content_before
) {
123 fprintf (out
, "%s", m
->mp_content_before
);
126 for (part
= m
->mp_parts
; part
; part
= part
->mp_next
) {
127 CT p
= part
->mp_part
;
129 fprintf (out
, "\n--%s\n", boundary
);
130 if (output_content (p
, out
) == NOTOK
)
133 fprintf (out
, "\n--%s--\n", boundary
);
135 if (m
->mp_content_after
) {
136 fprintf (out
, "%s", m
->mp_content_after
);
143 if (ct
->c_subtype
== MESSAGE_EXTERNAL
) {
146 e
= (struct exbody
*) ct
->c_ctparams
;
147 if (output_content (e
->eb_content
, out
) == NOTOK
)
150 /* output phantom body for access-type "mail-server" */
152 writeExternalBody (ct
, out
);
154 result
= write8Bit (ct
, out
);
159 * Handle discrete types (text/application/audio/image/video)
162 switch (ct
->c_encoding
) {
165 result
= write8Bit (ct
, out
);
170 result
= write8Bit (ct
, out
);
175 result
= writeQuoted (ct
, out
);
180 result
= writeBase64ct (ct
, out
);
184 advise (NULL
, "can't handle binary transfer encoding in content");
189 advise (NULL
, "unknown transfer encoding in content");
201 * Output all the header fields for a content
205 output_headers (CT ct
, FILE *out
)
211 fprintf (out
, "%s:%s", hp
->name
, hp
->value
);
218 * Write the phantom body for access-type "mail-server".
222 writeExternalBody (CT ct
, FILE *out
)
224 char **ap
, **ep
, *cp
;
225 struct exbody
*e
= (struct exbody
*) ct
->c_ctparams
;
228 for (cp
= e
->eb_body
; *cp
; cp
++) {
229 CT ct2
= e
->eb_content
;
230 CI ci2
= &ct2
->c_ctinfo
;
236 char *dp
= trimcpy (ct2
->c_id
);
244 for (ap
= ci2
->ci_attrs
, ep
= ci2
->ci_values
; *ap
; ap
++, ep
++)
245 if (!mh_strcasecmp (*ap
, "name")) {
246 fprintf (out
, "%s", *ep
);
252 fprintf (out
, "%s/%s", ci2
->ci_type
, ci2
->ci_subtype
);
253 for (ap
= ci2
->ci_attrs
, ep
= ci2
->ci_values
; *ap
; ap
++, ep
++)
254 fprintf (out
, "; %s=\"%s\"", *ap
, *ep
);
287 * Output a content without any transfer encoding
291 write8Bit (CT ct
, FILE *out
)
294 char c
, *file
, buffer
[BUFSIZ
];
295 CE ce
= ct
->c_cefile
;
298 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
302 while (fgets (buffer
, sizeof(buffer
) - 1, ce
->ce_fp
)) {
303 c
= buffer
[strlen (buffer
) - 1];
309 (*ct
->c_ceclosefnx
) (ct
);
315 * Output a content using quoted-printable
319 writeQuoted (CT ct
, FILE *out
)
323 char c
, buffer
[BUFSIZ
];
324 CE ce
= ct
->c_cefile
;
327 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
330 while (fgets (buffer
, sizeof(buffer
) - 1, ce
->ce_fp
)) {
333 cp
= buffer
+ strlen (buffer
) - 1;
334 if ((c
= *cp
) == '\n')
337 if (strncmp (cp
= buffer
, "From ", sizeof("From ") - 1) == 0) {
338 fprintf (out
, "=%02X", *cp
++ & 0xff);
344 if (n
> CPERLIN
- 3) {
357 if (*cp
< '!' || *cp
> '~')
365 fprintf (out
, "=%02X", *cp
& 0xff);
372 if (cp
> buffer
&& (*--cp
== ' ' || *cp
== '\t'))
381 (*ct
->c_ceclosefnx
) (ct
);
387 * Output a content using base64
391 writeBase64ct (CT ct
, FILE *out
)
395 CE ce
= ct
->c_cefile
;
398 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
401 result
= writeBase64aux (ce
->ce_fp
, out
);
402 (*ct
->c_ceclosefnx
) (ct
);