]>
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
;
87 for (pm
= ci
->ci_first_pm
; pm
; pm
= pm
->pm_next
) {
88 if (! strcasecmp ("boundary", pm
->pm_name
)) {
89 boundary
= pm
->pm_value
;
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_first_pm
!= 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
)
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 (pm
= ci2
->ci_first_pm
; pm
; pm
= pm
->pm_next
)
252 if (!strcasecmp (pm
->pm_name
, "name")) {
253 fprintf (out
, "%s", pm
->pm_value
);
259 fprintf (out
, "%s/%s", ci2
->ci_type
, ci2
->ci_subtype
);
260 for (pm
= ci2
->ci_first_pm
; pm
; pm
= pm
->pm_next
)
261 fprintf (out
, "; %s=\"%s\"", pm
->pm_name
, pm
->pm_value
);
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
= '\0', buffer
[BUFSIZ
];
332 CE ce
= &ct
->c_cefile
;
336 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
339 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);
351 if (n
> CPERLIN
- 3) {
364 if (*cp
< '!' || *cp
> '~')
372 fprintf (out
, "=%02X", *cp
& 0xff);
379 if (cp
> buffer
&& (*--cp
== ' ' || *cp
== '\t'))
390 (*ct
->c_ceclosefnx
) (ct
);
396 * Output a content using base64
400 writeBase64ct (CT ct
, FILE *out
)
404 CE ce
= &ct
->c_cefile
;
407 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
410 result
= writeBase64aux (ce
->ce_fp
, out
, (ct
->c_type
== CT_TEXT
));
411 (*ct
->c_ceclosefnx
) (ct
);