]>
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 (! 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 (!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
)
302 char c
, *file
, buffer
[BUFSIZ
];
303 CE ce
= &ct
->c_cefile
;
306 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
310 while ((inbytes
= fread (buffer
, 1, sizeof buffer
, ce
->ce_fp
)) > 0) {
311 c
= buffer
[inbytes
- 1];
312 fwrite (buffer
, 1, inbytes
, out
);
317 (*ct
->c_ceclosefnx
) (ct
);
323 * Output a content using quoted-printable
327 writeQuoted (CT ct
, FILE *out
)
331 char c
, buffer
[BUFSIZ
];
332 CE ce
= &ct
->c_cefile
;
335 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
338 while (fgets (buffer
, sizeof(buffer
) - 1, ce
->ce_fp
)) {
341 cp
= buffer
+ strlen (buffer
) - 1;
342 if ((c
= *cp
) == '\n')
345 if (strncmp (cp
= buffer
, "From ", sizeof("From ") - 1) == 0) {
346 fprintf (out
, "=%02X", *cp
++ & 0xff);
352 if (n
> CPERLIN
- 3) {
365 if (*cp
< '!' || *cp
> '~')
373 fprintf (out
, "=%02X", *cp
& 0xff);
380 if (cp
> buffer
&& (*--cp
== ' ' || *cp
== '\t'))
389 (*ct
->c_ceclosefnx
) (ct
);
395 * Output a content using base64
399 writeBase64ct (CT ct
, FILE *out
)
403 CE ce
= &ct
->c_cefile
;
406 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
409 result
= writeBase64aux (ce
->ce_fp
, out
);
410 (*ct
->c_ceclosefnx
) (ct
);