]>
diplodocus.org Git - nmh/blob - uip/mhoutsbr.c
246d99b49d16d4b8c28af362d0929dfb3330a710
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>
19 #include <h/mhparse.h>
25 int output_message (CT
, char *);
26 int output_message_fp (CT
, FILE *, char *);
31 static int output_content (CT
, FILE *);
32 static void output_headers (CT
, FILE *);
33 static int writeExternalBody (CT
, FILE *);
34 static int write8Bit (CT
, FILE *);
35 static int writeQuoted (CT
, FILE *);
36 static int writeBase64ct (CT
, FILE *);
40 * Main routine to output a MIME message contained
41 * in a Content structure, to a file. Any necessary
42 * transfer encoding is added.
46 output_message_fp (CT ct
, FILE *fp
, char *file
)
48 if (output_content (ct
, fp
) == NOTOK
)
52 advise ((file
?file
:"<FILE*>"), "error writing to");
59 output_message (CT ct
, char *file
)
64 if (! strcmp (file
, "-")) {
66 } else if ((fp
= fopen (file
, "w")) == NULL
) {
67 advise (file
, "unable to open for writing");
70 status
= output_message_fp(ct
, fp
, file
);
71 if (strcmp (file
, "-")) fclose(fp
);
77 * Output a Content structure to a file.
81 output_content (CT ct
, FILE *out
)
84 CI ci
= &ct
->c_ctinfo
;
85 char *boundary
= ci
->ci_values
[0], **ap
, **vp
;
87 for (ap
= ci
->ci_attrs
, vp
= ci
->ci_values
; *ap
; ++ap
, ++vp
) {
88 if (! strcasecmp ("boundary", *ap
)) {
95 * Output all header fields for this content
97 output_headers (ct
, out
);
100 * If this is the internal content structure for a
101 * "message/external", then we are done with the
102 * headers (since it has no body).
108 * Now output the content bodies.
110 switch (ct
->c_type
) {
119 m
= (struct multipart
*) ct
->c_ctparams
;
121 if (m
->mp_content_before
) {
122 fprintf (out
, "%s", m
->mp_content_before
);
125 for (part
= m
->mp_parts
; part
; part
= part
->mp_next
) {
126 CT p
= part
->mp_part
;
128 fprintf (out
, "\n--%s\n", boundary
);
129 if (output_content (p
, out
) == NOTOK
)
132 fprintf (out
, "\n--%s--\n", boundary
);
134 if (m
->mp_content_after
) {
135 fprintf (out
, "%s", m
->mp_content_after
);
142 if (ct
->c_subtype
== MESSAGE_EXTERNAL
) {
145 e
= (struct exbody
*) ct
->c_ctparams
;
146 if (output_content (e
->eb_content
, out
) == NOTOK
)
149 /* output phantom body for access-type "mail-server" */
151 writeExternalBody (ct
, out
);
153 result
= write8Bit (ct
, out
);
158 * Handle discrete types (text/application/audio/image/video)
161 switch (ct
->c_encoding
) {
163 /* Special case: if this is a non-MIME message with no
164 body, don't emit the newline that would appear between
165 the headers and body. In that case, the call to
166 write8Bit() shouldn't be needed, but is harmless. */
167 if (ct
->c_ctinfo
.ci_attrs
[0] != NULL
||
168 ct
->c_begin
!= ct
->c_end
) {
171 result
= write8Bit (ct
, out
);
176 result
= write8Bit (ct
, out
);
181 result
= writeQuoted (ct
, out
);
186 result
= writeBase64ct (ct
, out
);
190 advise (NULL
, "can't handle binary transfer encoding in content");
195 advise (NULL
, "unknown transfer encoding in content");
207 * Output all the header fields for a content
211 output_headers (CT ct
, FILE *out
)
217 fprintf (out
, "%s:%s", hp
->name
, hp
->value
);
224 * Write the phantom body for access-type "mail-server".
228 writeExternalBody (CT ct
, FILE *out
)
230 char **ap
, **ep
, *cp
;
231 struct exbody
*e
= (struct exbody
*) ct
->c_ctparams
;
234 for (cp
= e
->eb_body
; *cp
; cp
++) {
235 CT ct2
= e
->eb_content
;
236 CI ci2
= &ct2
->c_ctinfo
;
242 char *dp
= trimcpy (ct2
->c_id
);
250 for (ap
= ci2
->ci_attrs
, ep
= ci2
->ci_values
; *ap
; ap
++, ep
++)
251 if (!strcasecmp (*ap
, "name")) {
252 fprintf (out
, "%s", *ep
);
258 fprintf (out
, "%s/%s", ci2
->ci_type
, ci2
->ci_subtype
);
259 for (ap
= ci2
->ci_attrs
, ep
= ci2
->ci_values
; *ap
; ap
++, ep
++)
260 fprintf (out
, "; %s=\"%s\"", *ap
, *ep
);
293 * Output a content without any transfer encoding
297 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 ((inbytes
= fread (buffer
, 1, sizeof buffer
, ce
->ce_fp
)) > 0) {
310 c
= buffer
[inbytes
- 1];
311 fwrite (buffer
, 1, inbytes
, out
);
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
);