]>
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>
18 #include <h/mhparse.h>
24 int output_message (CT
, char *);
25 int output_message_fp (CT
, FILE *, char *);
30 static int output_content (CT
, FILE *);
31 static void output_headers (CT
, FILE *);
32 static int writeExternalBody (CT
, FILE *);
33 static int write8Bit (CT
, FILE *);
34 static int writeQuoted (CT
, FILE *);
35 static int writeBase64ct (CT
, FILE *);
39 * Main routine to output a MIME message contained
40 * in a Content structure, to a file. Any necessary
41 * transfer encoding is added.
45 output_message_fp (CT ct
, FILE *fp
, char *file
)
47 if (output_content (ct
, fp
) == NOTOK
)
51 advise ((file
?file
:"<FILE*>"), "error writing to");
58 output_message (CT ct
, char *file
)
63 if (! strcmp (file
, "-")) {
65 } else if ((fp
= fopen (file
, "w")) == NULL
) {
66 advise (file
, "unable to open for writing");
69 status
= output_message_fp(ct
, fp
, file
);
70 if (strcmp (file
, "-")) fclose(fp
);
76 * Output a Content structure to a file.
80 output_content (CT ct
, FILE *out
)
83 CI ci
= &ct
->c_ctinfo
;
84 char *boundary
= ci
->ci_values
[0], **ap
, **vp
;
86 for (ap
= ci
->ci_attrs
, vp
= ci
->ci_values
; *ap
; ++ap
, ++vp
) {
87 if (! strcasecmp ("boundary", *ap
)) {
94 * Output all header fields for this content
96 output_headers (ct
, out
);
99 * If this is the internal content structure for a
100 * "message/external", then we are done with the
101 * headers (since it has no body).
107 * Now output the content bodies.
109 switch (ct
->c_type
) {
118 m
= (struct multipart
*) ct
->c_ctparams
;
120 if (m
->mp_content_before
) {
121 fprintf (out
, "%s", m
->mp_content_before
);
124 for (part
= m
->mp_parts
; part
; part
= part
->mp_next
) {
125 CT p
= part
->mp_part
;
127 fprintf (out
, "\n--%s\n", boundary
);
128 if (output_content (p
, out
) == NOTOK
)
131 fprintf (out
, "\n--%s--\n", boundary
);
133 if (m
->mp_content_after
) {
134 fprintf (out
, "%s", m
->mp_content_after
);
141 if (ct
->c_subtype
== MESSAGE_EXTERNAL
) {
144 e
= (struct exbody
*) ct
->c_ctparams
;
145 if (output_content (e
->eb_content
, out
) == NOTOK
)
148 /* output phantom body for access-type "mail-server" */
150 writeExternalBody (ct
, out
);
152 result
= write8Bit (ct
, out
);
157 * Handle discrete types (text/application/audio/image/video)
160 switch (ct
->c_encoding
) {
162 /* Special case: if this is a non-MIME message with no
163 body, don't emit the newline that would appear between
164 the headers and body. In that case, the call to
165 write8Bit() shouldn't be needed, but is harmless. */
166 if (ct
->c_ctinfo
.ci_attrs
[0] != NULL
||
167 ct
->c_begin
!= ct
->c_end
) {
170 result
= write8Bit (ct
, out
);
175 result
= write8Bit (ct
, out
);
180 result
= writeQuoted (ct
, out
);
185 result
= writeBase64ct (ct
, out
);
189 advise (NULL
, "can't handle binary transfer encoding in content");
194 advise (NULL
, "unknown transfer encoding in content");
206 * Output all the header fields for a content
210 output_headers (CT ct
, FILE *out
)
216 fprintf (out
, "%s:%s", hp
->name
, hp
->value
);
223 * Write the phantom body for access-type "mail-server".
227 writeExternalBody (CT ct
, FILE *out
)
229 char **ap
, **ep
, *cp
;
230 struct exbody
*e
= (struct exbody
*) ct
->c_ctparams
;
233 for (cp
= e
->eb_body
; *cp
; cp
++) {
234 CT ct2
= e
->eb_content
;
235 CI ci2
= &ct2
->c_ctinfo
;
241 char *dp
= trimcpy (ct2
->c_id
);
249 for (ap
= ci2
->ci_attrs
, ep
= ci2
->ci_values
; *ap
; ap
++, ep
++)
250 if (!strcasecmp (*ap
, "name")) {
251 fprintf (out
, "%s", *ep
);
257 fprintf (out
, "%s/%s", ci2
->ci_type
, ci2
->ci_subtype
);
258 for (ap
= ci2
->ci_attrs
, ep
= ci2
->ci_values
; *ap
; ap
++, ep
++)
259 fprintf (out
, "; %s=\"%s\"", *ap
, *ep
);
292 * Output a content without any transfer encoding
296 write8Bit (CT ct
, FILE *out
)
300 char c
, *file
, buffer
[BUFSIZ
];
301 CE ce
= &ct
->c_cefile
;
304 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
308 while ((inbytes
= fread (buffer
, 1, sizeof buffer
, ce
->ce_fp
)) > 0) {
309 c
= buffer
[inbytes
- 1];
310 fwrite (buffer
, 1, inbytes
, out
);
315 (*ct
->c_ceclosefnx
) (ct
);
321 * Output a content using quoted-printable
325 writeQuoted (CT ct
, FILE *out
)
329 char c
, buffer
[BUFSIZ
];
330 CE ce
= &ct
->c_cefile
;
333 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
336 while (fgets (buffer
, sizeof(buffer
) - 1, ce
->ce_fp
)) {
339 cp
= buffer
+ strlen (buffer
) - 1;
340 if ((c
= *cp
) == '\n')
343 if (strncmp (cp
= buffer
, "From ", sizeof("From ") - 1) == 0) {
344 fprintf (out
, "=%02X", *cp
++ & 0xff);
350 if (n
> CPERLIN
- 3) {
363 if (*cp
< '!' || *cp
> '~')
371 fprintf (out
, "=%02X", *cp
& 0xff);
378 if (cp
> buffer
&& (*--cp
== ' ' || *cp
== '\t'))
387 (*ct
->c_ceclosefnx
) (ct
);
393 * Output a content using base64
397 writeBase64ct (CT ct
, FILE *out
)
401 CE ce
= &ct
->c_cefile
;
404 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
407 result
= writeBase64aux (ce
->ce_fp
, out
);
408 (*ct
->c_ceclosefnx
) (ct
);