]>
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
) {
164 /* Special case: if this is a non-MIME message with no
165 body, don't emit the newline that would appear between
166 the headers and body. In that case, the call to
167 write8Bit() shouldn't be needed, but is harmless. */
168 if (ct
->c_ctinfo
.ci_attrs
[0] != NULL
||
169 ct
->c_begin
!= ct
->c_end
) {
172 result
= write8Bit (ct
, out
);
177 result
= write8Bit (ct
, out
);
182 result
= writeQuoted (ct
, out
);
187 result
= writeBase64ct (ct
, out
);
191 advise (NULL
, "can't handle binary transfer encoding in content");
196 advise (NULL
, "unknown transfer encoding in content");
208 * Output all the header fields for a content
212 output_headers (CT ct
, FILE *out
)
218 fprintf (out
, "%s:%s", hp
->name
, hp
->value
);
225 * Write the phantom body for access-type "mail-server".
229 writeExternalBody (CT ct
, FILE *out
)
231 char **ap
, **ep
, *cp
;
232 struct exbody
*e
= (struct exbody
*) ct
->c_ctparams
;
235 for (cp
= e
->eb_body
; *cp
; cp
++) {
236 CT ct2
= e
->eb_content
;
237 CI ci2
= &ct2
->c_ctinfo
;
243 char *dp
= trimcpy (ct2
->c_id
);
251 for (ap
= ci2
->ci_attrs
, ep
= ci2
->ci_values
; *ap
; ap
++, ep
++)
252 if (!mh_strcasecmp (*ap
, "name")) {
253 fprintf (out
, "%s", *ep
);
259 fprintf (out
, "%s/%s", ci2
->ci_type
, ci2
->ci_subtype
);
260 for (ap
= ci2
->ci_attrs
, ep
= ci2
->ci_values
; *ap
; ap
++, ep
++)
261 fprintf (out
, "; %s=\"%s\"", *ap
, *ep
);
294 * Output a content without any transfer encoding
298 write8Bit (CT ct
, FILE *out
)
301 char c
, *file
, buffer
[BUFSIZ
];
302 CE ce
= ct
->c_cefile
;
305 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
309 while (fgets (buffer
, sizeof(buffer
) - 1, ce
->ce_fp
)) {
310 c
= buffer
[strlen (buffer
) - 1];
316 (*ct
->c_ceclosefnx
) (ct
);
322 * Output a content using quoted-printable
326 writeQuoted (CT ct
, FILE *out
)
330 char c
, buffer
[BUFSIZ
];
331 CE ce
= ct
->c_cefile
;
334 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
337 while (fgets (buffer
, sizeof(buffer
) - 1, ce
->ce_fp
)) {
340 cp
= buffer
+ strlen (buffer
) - 1;
341 if ((c
= *cp
) == '\n')
344 if (strncmp (cp
= buffer
, "From ", sizeof("From ") - 1) == 0) {
345 fprintf (out
, "=%02X", *cp
++ & 0xff);
351 if (n
> CPERLIN
- 3) {
364 if (*cp
< '!' || *cp
> '~')
372 fprintf (out
, "=%02X", *cp
& 0xff);
379 if (cp
> buffer
&& (*--cp
== ' ' || *cp
== '\t'))
388 (*ct
->c_ceclosefnx
) (ct
);
394 * Output a content using base64
398 writeBase64ct (CT ct
, FILE *out
)
402 CE ce
= ct
->c_cefile
;
405 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
408 result
= writeBase64aux (ce
->ce_fp
, out
);
409 (*ct
->c_ceclosefnx
) (ct
);