source: MondoRescue/branches/3.3/mindi-busybox/mailutils/makemime.c@ 3723

Last change on this file since 3723 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 8.2 KB
RevLine 
[3621]1/* vi: set sw=4 ts=4: */
2/*
3 * makemime: create MIME-encoded message
4 *
5 * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
6 *
7 * Licensed under GPLv2, see file LICENSE in this source tree.
8 */
9
10//kbuild:lib-$(CONFIG_MAKEMIME) += makemime.o mail.o
11
12#include "libbb.h"
13#include "mail.h"
14
15#if 0
16# define dbg_error_msg(...) bb_error_msg(__VA_ARGS__)
17#else
18# define dbg_error_msg(...) ((void)0)
19#endif
20
21/*
22 makemime -c type [-o file] [-e encoding] [-C charset] [-N name] \
23 [-a "Header: Contents"] file
24 -m [ type ] [-o file] [-e encoding] [-a "Header: Contents"] file
25 -j [-o file] file1 file2
26 @file
27
28 file: filename - read or write from filename
29 - - read or write from stdin or stdout
30 &n - read or write from file descriptor n
31 \( opts \) - read from child process, that generates [ opts ]
32
33Options:
34 -c type - create a new MIME section from "file" with this
35 Content-Type: (default is application/octet-stream).
36 -C charset - MIME charset of a new text/plain section.
37 -N name - MIME content name of the new mime section.
38 -m [ type ] - create a multipart mime section from "file" of this
39 Content-Type: (default is multipart/mixed).
40 -e encoding - use the given encoding (7bit, 8bit, quoted-printable,
41 or base64), instead of guessing. Omit "-e" and use
42 -c auto to set Content-Type: to text/plain or
43 application/octet-stream based on picked encoding.
44 -j file1 file2 - join mime section file2 to multipart section file1.
45 -o file - write the result to file, instead of stdout (not
46 allowed in child processes).
47 -a header - prepend an additional header to the output.
48
49 @file - read all of the above options from file, one option or
50 value on each line.
51 {which version of makemime is this? What do we support?}
52*/
53/* man makemime:
54
55 * -c TYPE: create a (non-multipart) MIME section with Content-Type: TYPE
56 * makemime -c TYPE [-e ENCODING] [-o OUTFILE] [-C CHARSET] [-N NAME] [-a HEADER...] FILE
57 * The -C option sets the MIME charset attribute for text/plain content.
58 * The -N option sets the name attribute for Content-Type:
59 * Encoding must be one of the following: 7bit, 8bit, quoted-printable, or base64.
60
61 * -m multipart/TYPE: create a multipart MIME collection with Content-Type: multipart/TYPE
62 * makemime -m multipart/TYPE [-e ENCODING] [-o OUTFILE] [-a HEADER...] FILE
63 * Type must be either "multipart/mixed", "multipart/alternative", or some other MIME multipart content type.
64 * Additionally, encoding can only be "7bit" or "8bit", and will default to "8bit" if not specified.
65 * Finally, filename must be a MIME-formatted section, NOT a regular file.
66 * The -m option creates an initial multipart MIME collection, that contains only one MIME section, taken from filename.
67 * The collection is written to standard output, or the pipe or to outputfile.
68
69 * -j FILE1: add a section to a multipart MIME collection
70 * makemime -j FILE1 [-o OUTFILE] FILE2
71 * FILE1 must be a MIME collection that was previously created by the -m option.
72 * FILE2 must be a MIME section that was previously created by the -c option.
73 * The -j options adds the MIME section in FILE2 to the MIME collection in FILE1.
74 */
75
76
77/* In busybox 1.15.0.svn, makemime generates output like this
78 * (empty lines are shown exactly!):
79{headers added with -a HDR}
80Mime-Version: 1.0
81Content-Type: multipart/mixed; boundary="24269534-2145583448-1655890676"
82
83--24269534-2145583448-1655890676
84Content-Type: {set by -c, e.g. text/plain}; charset={set by -C, e.g. us-ascii}
85Content-Disposition: inline; filename="A"
86Content-Transfer-Encoding: base64
87
88...file A contents...
89--24269534-2145583448-1655890676
90Content-Type: {set by -c, e.g. text/plain}; charset={set by -C, e.g. us-ascii}
91Content-Disposition: inline; filename="B"
92Content-Transfer-Encoding: base64
93
94...file B contents...
95--24269534-2145583448-1655890676--
96
97 *
98 * For reference: here is an example email to LKML which has
99 * 1st unnamed part (so it serves as an email body)
100 * and one attached file:
101...other headers...
102Content-Type: multipart/mixed; boundary="=-tOfTf3byOS0vZgxEWcX+"
103...other headers...
104Mime-Version: 1.0
105...other headers...
106
107
108--=-tOfTf3byOS0vZgxEWcX+
109Content-Type: text/plain
110Content-Transfer-Encoding: 7bit
111
112...email text...
113...email text...
114
115
116--=-tOfTf3byOS0vZgxEWcX+
117Content-Disposition: attachment; filename="xyz"
118Content-Type: text/plain; name="xyz"; charset="UTF-8"
119Content-Transfer-Encoding: 7bit
120
121...file contents...
122...file contents...
123
124--=-tOfTf3byOS0vZgxEWcX+--
125
126...random junk added by mailing list robots and such...
127*/
128
129//usage:#define makemime_trivial_usage
130//usage: "[OPTIONS] [FILE]..."
131//usage:#define makemime_full_usage "\n\n"
132//usage: "Create multipart MIME-encoded message from FILEs\n"
133/* //usage: "Transfer encoding is base64, disposition is inline (not attachment)\n" */
134//usage: "\n -o FILE Output. Default: stdout"
135//usage: "\n -a HDR Add header(s). Examples:"
136//usage: "\n \"From: user@host.org\", \"Date: `date -R`\""
137//usage: "\n -c CT Content type. Default: application/octet-stream"
138//usage: "\n -C CS Charset. Default: " CONFIG_FEATURE_MIME_CHARSET
139/* //usage: "\n -e ENC Transfer encoding. Ignored. base64 is assumed" */
140//usage: "\n"
141//usage: "\nOther options are silently ignored"
142
143/*
144 * -c [Content-Type] should create just one MIME section
145 * with "Content-Type:", "Content-Transfer-Encoding:", and HDRs from "-a HDR".
146 * NB: without "Content-Disposition:" auto-added, unlike we do now
147 * NB2: -c has *optional* param which nevertheless _can_ be specified after a space :(
148 *
149 * -m [multipart/mixed] should create multipart MIME section
150 * with "Content-Type:", "Content-Transfer-Encoding:", and HDRs from "-a HDR",
151 * and add FILE to it _verbatim_:
152 * HEADERS
153 *
154 * --=_1_1321709112_1605
155 * FILE_CONTENTS
156 * --=_1_1321709112_1605
157 * without any encoding of FILE_CONTENTS. (Basically, it expects that FILE
158 * is the result of "makemime -c").
159 *
160 * -j MULTIPART_FILE1 SINGLE_FILE2 should output MULTIPART_FILE1 + SINGLE_FILE2
161 *
162 * Our current behavior is a mutant "-m + -c + -j" one: we create multipart MIME
163 * and we put "-c" encoded FILEs into many multipart sections.
164 */
165
166int makemime_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
167int makemime_main(int argc UNUSED_PARAM, char **argv)
168{
169 llist_t *opt_headers = NULL, *l;
170 const char *opt_output;
171 const char *content_type = "application/octet-stream";
172#define boundary opt_output
173 enum {
174 OPT_c = 1 << 0, // create (non-multipart) section
175 OPT_e = 1 << 1, // Content-Transfer-Encoding. Ignored. Assumed base64
176 OPT_o = 1 << 2, // output to
177 OPT_C = 1 << 3, // charset
178 OPT_N = 1 << 4, // COMPAT
179 OPT_a = 1 << 5, // additional headers
180 //OPT_m = 1 << 6, // create mutipart section
181 //OPT_j = 1 << 7, // join section to multipart section
182 };
183
184 INIT_G();
185
186 // parse options
187 opt_complementary = "a::";
188 opts = getopt32(argv,
189 "c:e:o:C:N:a:", // "m:j:",
190 &content_type, NULL, &opt_output, &G.opt_charset, NULL, &opt_headers //, NULL, NULL
191 );
192 //argc -= optind;
193 argv += optind;
194
195 // respect -o output
196 if (opts & OPT_o)
197 freopen(opt_output, "w", stdout);
198
199 // no files given on command line? -> use stdin
200 if (!*argv)
201 *--argv = (char *)"-";
202
203 // put additional headers
204 for (l = opt_headers; l; l = l->link)
205 puts(l->data);
206
207 // make a random string -- it will delimit message parts
208 srand(monotonic_us());
209 boundary = xasprintf("%u-%u-%u",
210 (unsigned)rand(), (unsigned)rand(), (unsigned)rand());
211
212 // put multipart header
213 printf(
214 "Mime-Version: 1.0\n"
215 "Content-Type: multipart/mixed; boundary=\"%s\"\n"
216 , boundary
217 );
218
219 // put attachments
220 while (*argv) {
221 printf(
222 "\n--%s\n"
223 "Content-Type: %s; charset=%s\n"
224 "Content-Disposition: inline; filename=\"%s\"\n"
225 "Content-Transfer-Encoding: base64\n"
226 , boundary
227 , content_type
228 , G.opt_charset
229 , bb_get_last_path_component_strip(*argv)
230 );
231 encode_base64(*argv++, (const char *)stdin, "");
232 }
233
234 // put multipart footer
235 printf("\n--%s--\n" "\n", boundary);
236
237 return EXIT_SUCCESS;
238#undef boundary
239}
Note: See TracBrowser for help on using the repository browser.