]>
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
= "", *cp
;
86 if ((cp
= get_param(ci
->ci_first_pm
, "boundary", '-', 0)))
90 * Output all header fields for this content
92 output_headers (ct
, out
);
95 * If this is the internal content structure for a
96 * "message/external", then we are done with the
97 * headers (since it has no body).
100 if (boundary
&& *boundary
!= '\0')
106 * Now output the content bodies.
108 switch (ct
->c_type
) {
117 m
= (struct multipart
*) ct
->c_ctparams
;
119 if (m
->mp_content_before
) {
120 fprintf (out
, "%s", m
->mp_content_before
);
123 for (part
= m
->mp_parts
; part
; part
= part
->mp_next
) {
124 CT p
= part
->mp_part
;
126 fprintf (out
, "\n--%s\n", boundary
);
127 if (output_content (p
, out
) == NOTOK
) {
128 if (boundary
&& *boundary
!= '\0')
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_first_pm
!= 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");
203 if (boundary
&& *boundary
!= '\0')
211 * Output all the header fields for a content
215 output_headers (CT ct
, FILE *out
)
221 fprintf (out
, "%s:%s", hp
->name
, hp
->value
);
228 * Write the phantom body for access-type "mail-server".
232 writeExternalBody (CT ct
, FILE *out
)
235 struct exbody
*e
= (struct exbody
*) ct
->c_ctparams
;
238 for (cp
= e
->eb_body
; *cp
; cp
++) {
239 CT ct2
= e
->eb_content
;
240 CI ci2
= &ct2
->c_ctinfo
;
246 dp
= trimcpy (ct2
->c_id
);
254 dp
= get_param(ci2
->ci_first_pm
, "name", '_', 0);
262 fprintf (out
, "%s/%s", ci2
->ci_type
, ci2
->ci_subtype
);
263 dp
= output_params(strlen(ci2
->ci_type
) +
264 strlen(ci2
->ci_subtype
) + 1,
265 ci2
->ci_first_pm
, NULL
, 0);
302 * Output a content without any transfer encoding
306 write8Bit (CT ct
, FILE *out
)
310 char c
, *file
, buffer
[BUFSIZ
];
311 CE ce
= &ct
->c_cefile
;
314 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
318 while ((inbytes
= fread (buffer
, 1, sizeof buffer
, ce
->ce_fp
)) > 0) {
319 c
= buffer
[inbytes
- 1];
320 fwrite (buffer
, 1, inbytes
, out
);
325 (*ct
->c_ceclosefnx
) (ct
);
331 * Output a content using quoted-printable
335 writeQuoted (CT ct
, FILE *out
)
339 char c
= '\0', buffer
[BUFSIZ
];
340 CE ce
= &ct
->c_cefile
;
344 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
347 while (fgets (buffer
, sizeof(buffer
) - 1, ce
->ce_fp
)) {
349 cp
= buffer
+ strlen (buffer
) - 1;
350 if ((c
= *cp
) == '\n')
353 if (strncmp (cp
= buffer
, "From ", sizeof("From ") - 1) == 0) {
354 fprintf (out
, "=%02X", *cp
++ & 0xff);
359 if (n
> CPERLIN
- 3) {
372 if (*cp
< '!' || *cp
> '~')
380 fprintf (out
, "=%02X", *cp
& 0xff);
387 if (cp
> buffer
&& (*--cp
== ' ' || *cp
== '\t'))
398 (*ct
->c_ceclosefnx
) (ct
);
404 * Output a content using base64
408 writeBase64ct (CT ct
, FILE *out
)
412 CE ce
= &ct
->c_cefile
;
415 if ((fd
= (*ct
->c_ceopenfnx
) (ct
, &file
)) == NOTOK
)
418 result
= writeBase64aux (ce
->ce_fp
, out
, (ct
->c_type
== CT_TEXT
));
419 (*ct
->c_ceclosefnx
) (ct
);