]> git.phdru.name Git - mimedecode.git/blob - mimedecode.docbook
Documentation update
[mimedecode.git] / mimedecode.docbook
1 <?xml version="1.0" standalone="no"?>
2 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
3   "file:///usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd">
4
5 <refentry id="mimedecode.py">
6
7 <refentryinfo>
8   <title>mimedecode.py</title>
9   <productname>mimedecode.docbook</productname>
10   <author>
11     <firstname>Oleg</firstname>
12     <surname>Broytman</surname>
13     <email>phd@phdru.name</email>
14     <personblurb/>
15   </author>
16   <copyright>
17     <year>2001-2014</year>
18     <holder>PhiloSoft Design.</holder>
19   </copyright>
20 </refentryinfo>
21
22 <refmeta>
23    <refentrytitle>mimedecode.py</refentrytitle>
24    <manvolnum>1</manvolnum>
25 </refmeta>
26
27 <refnamediv>
28    <refname>mimedecode.py</refname>
29    <refpurpose>decode MIME message</refpurpose>
30 </refnamediv>
31
32 <refsynopsisdiv>
33    <cmdsynopsis>
34       <command>mimedecode.py</command>
35       <arg choice="opt">
36          <option>-h|--help</option>
37       </arg>
38       <arg choice="opt">
39          <option>-V|--version</option>
40       </arg>
41       <arg choice="opt">
42          <option>-cCDP</option>
43       </arg>
44       <arg choice="opt">
45          <option>-f charset</option>
46       </arg>
47       <arg choice="opt">
48          <option>-H|--host=hostname</option>
49       </arg>
50       <arg choice="opt">
51          <option>-d header1[,header2,header3...]</option>
52       </arg>
53       <arg choice="opt">
54          <option>-d *[,-header1,-header2,-header3...]</option>
55       </arg>
56       <arg choice="opt">
57         <option>-p header1[,header2,header3,...]:param1[,param2,param3,...]</option>
58       </arg>
59       <arg choice="opt">
60         <option>-p *[,-header1,-header2,-header3,...]:param1[,param2,param3,...]</option>
61       </arg>
62       <arg choice="opt">
63         <option>-p header1[,header2,header3,...]:*[,-param1,-param2,-param3,...]</option>
64       </arg>
65       <arg choice="opt">
66         <option>-p *[,-header1,-header2,-header3,...]:*[,-param1,-param2,-param3,...]</option>
67       </arg>
68       <arg choice="opt">
69          <option>-r header1[,header2,header3...]</option>
70       </arg>
71       <arg choice="opt">
72          <option>-r *[,-header1,-header2,-header3...]</option>
73       </arg>
74       <arg choice="opt">
75         <option>-R header1[,header2,header3,...]:param1[,param2,param3,...]</option>
76       </arg>
77       <arg choice="opt">
78         <option>-R *[,-header1,-header2,-header3,...]:param1[,param2,param3,...]</option>
79       </arg>
80       <arg choice="opt">
81         <option>-R header1[,header2,header3,...]:*[,-param1,-param2,-param3,...]</option>
82       </arg>
83       <arg choice="opt">
84         <option>-R *[,-header1,-header2,-header3,...]:*[,-param1,-param2,-param3,...]</option>
85       </arg>
86       <arg choice="opt">
87          <option>--set-header header:value</option>
88       </arg>
89       <arg choice="opt">
90          <option>--set-param header:param=value</option>
91       </arg>
92       <arg choice="opt">
93          <option>-Bbeit mask</option>
94       </arg>
95       <arg choice="opt">
96          <option>--save-headers|body|message mask</option>
97       </arg>
98       <arg choice="opt">
99          <option>-O dest_dir</option>
100       </arg>
101       <arg choice="opt">
102          <option>-o output_file</option>
103       </arg>
104       <arg choice="opt">input_file
105         <arg choice="opt">output_file</arg>
106       </arg>
107    </cmdsynopsis>
108 </refsynopsisdiv>
109
110
111 <refsect1>
112 <title>DESCRIPTION</title>
113 <para>
114    Mail users, especially in non-English countries, often find that mail
115    messages arrived in different formats, with different content types, in
116    different encodings and charsets. Usually it is good because it allows to
117    use an appropriate format/encoding/whatever. Sometimes, though, some
118    unification is desirable. For example, one may want to put mail messages
119    into an archive, make HTML indices, run search indexer, etc. In such
120    situations converting messages to text in one character set and skipping
121    some binary attachments is much desirable.
122 </para>
123
124 <para>
125    Here is the solution - mimedecode.py!
126 </para>
127
128 <para>
129    This is a program to decode MIME messages. The program expects one input
130    file (either on command line or on stdin) which is treated as an RFC822
131    message, and decodes to stdout or an output file. If the file is not an
132    RFC822 message it is just copied to the output one-to-one. If the file is a
133    simple RFC822 message it is decoded as one part. If it is a MIME message
134    with multiple parts ("attachments") all parts are decoded. Decoding can be
135    controlled by command-line options.
136 </para>
137
138 <para>
139    First, for every part the program removes headers and parameters listed with
140    -r and -R options. Then, Subject and Content-Disposition headers (and all
141    headers listed with -d and -p options) are examined. If any of those exists,
142    they are decoded according to RFC2047. Content-Disposition header is not
143    decoded - only its "filename" parameter. Encoded header parameters violate
144    the RFC, but widely deployed anyway by ignorant coders who never even heard
145    about RFCs. Correct parameter encoding specified by RFC2231. This program
146    decodes RFC2231-encoded parameters, too.
147 </para>
148
149 <para>
150    Then the body of the message (or the current part) is decoded. Decoding
151    starts with looking at header Content-Transfer-Encoding. If the header
152    specifies non-8bit encoding (usually base64 or quoted-printable), the body
153    converted to 8bit. Then, if its content type is multipart (multipart/related
154    or multipart/mixed, e.g) every part is recursively decoded. If it is not
155    multipart, mailcap database is consulted to find a way to convert the body
156    to plain text. (I have no idea how mailcap can be configured on OSes other
157    than POSIX, please don't ask me; real OS users can consult my example at
158    <ulink url="http://phdru.name/Software/dotfiles/mailcap.html">http://phdru.name/Software/dotfiles/mailcap.html</ulink>).
159    The decoding process uses the first copiousoutput filter it can find. If
160    there are no filters the body just passed as is.
161 </para>
162
163 <para>
164    Then Content-Type header is consulted for charset. If it is not equal to the
165    current locale charset and recoding is allowed the body text is recoded.
166    Finally message headers and the body are flushed to stdout.
167 </para>
168 </refsect1>
169
170 <refsect1>
171   <para>
172     Please be warned that in the following options asterisk is a shell
173     metacharacter and should be escaped or quoted. Either write -d \*,-h1,-h2
174     or -d '*,-h1,-h2' or such.
175   </para>
176 </refsect1>
177
178 <refsect1>
179 <title>OPTIONS</title>
180 <variablelist>
181    <varlistentry>
182       <term>-h</term>
183       <term>-help</term>
184       <listitem>
185          <para>
186             Print brief usage help and exit.
187          </para>
188       </listitem>
189    </varlistentry>
190
191    <varlistentry>
192       <term>-V</term>
193       <term>--version</term>
194       <listitem>
195          <para>
196             Print version and exit.
197          </para>
198       </listitem>
199    </varlistentry>
200
201    <varlistentry>
202       <term>-c</term>
203       <listitem>
204          <para>
205             Recode different character sets in message bodies to the current
206             default charset; this is the default.
207          </para>
208       </listitem>
209    </varlistentry>
210
211    <varlistentry>
212       <term>-C</term>
213       <listitem>
214          <para>
215             Do not recode character sets in message bodies.
216          </para>
217       </listitem>
218    </varlistentry>
219
220    <varlistentry>
221       <term>-f charset</term>
222       <listitem>
223          <para>
224             Force this charset to be the current default charset instead of
225             the current locale.
226          </para>
227       </listitem>
228    </varlistentry>
229
230    <varlistentry>
231       <term>-H hostname</term>
232       <term>--host=hostname</term>
233       <listitem>
234          <para>
235            Use this hostname in X-MIME-Autoconverted headers instead of the
236            current hostname.
237          </para>
238       </listitem>
239    </varlistentry>
240
241    <varlistentry>
242       <term>-d header1[,header2,header3...]</term>
243       <listitem>
244          <para>
245             Add the header(s) to a list of headers to decode; initially the
246             list contains headers "From", "To", "Cc", "Reply-To",
247             "Mail-Followup-To" and "Subject".
248          </para>
249       </listitem>
250    </varlistentry>
251
252    <varlistentry>
253       <term>-d *[,-header1,-header2,-header3...]</term>
254       <listitem>
255          <para>
256            This variant completely changes headers decoding. First, the list of
257            headers to decode is cleared. Then all the headers are decoded
258            except the given list of exceptions (headers listed with '-'). In
259            this mode it would be meaningless to give more than one -d options
260            but the program doesn't enforce it.
261          </para>
262       </listitem>
263    </varlistentry>
264
265    <varlistentry>
266       <term>-D</term>
267       <listitem>
268          <para>
269             Clear the list of headers to decode (make it empty).
270          </para>
271       </listitem>
272    </varlistentry>
273
274    <varlistentry>
275       <term>-p header1[,header2,header3,...]:param1[,param2,param3,...]</term>
276       <listitem>
277          <para>
278             Add the parameters(s) to a list of headers parameters to decode;
279             the parameters will be decoded only for the given header(s).
280             Initially the list contains header "Content-Type", parameter "name";
281             and header "Content-Disposition", parameter "filename".
282          </para>
283       </listitem>
284    </varlistentry>
285
286    <varlistentry>
287       <term>-p *[,-header1,-header2,-header3,...]:param1[,param2,param3,...]</term>
288       <listitem>
289          <para>
290             Add the parameters(s) to a list of headers parameters to decode;
291             the parameters will be decoded for all headers except the given
292             ones.
293          </para>
294       </listitem>
295    </varlistentry>
296
297    <varlistentry>
298       <term>-p header1[,header2,header3,...]:*[,-param1,-param2,-param3,...]</term>
299       <listitem>
300          <para>
301            Decode all parameters except listed for the given list of headers.
302          </para>
303       </listitem>
304    </varlistentry>
305
306    <varlistentry>
307       <term>-p *[,-header1,-header2,-header3,...]:*[,-param1,-param2,-param3,...]</term>
308       <listitem>
309          <para>
310            Decode all parameters except listed for all headers (except listed).
311          </para>
312       </listitem>
313    </varlistentry>
314
315    <varlistentry>
316       <term>-P</term>
317       <listitem>
318          <para>
319             Clear the list of headers parameters to decode (make it empty).
320          </para>
321       </listitem>
322    </varlistentry>
323
324    <varlistentry>
325       <term>-r header1[,header2,header3...]</term>
326       <listitem>
327          <para>
328             Add the header(s) to a list of headers to remove completely;
329             initially the list is empty.
330          </para>
331       </listitem>
332    </varlistentry>
333
334    <varlistentry>
335       <term>-r *[,-header1,-header2,-header3...]</term>
336       <listitem>
337          <para>
338            Remove all headers except listed.
339          </para>
340       </listitem>
341    </varlistentry>
342
343    <varlistentry>
344       <term>-R header1[,header2,header3,...]:param1[,param2,param3,...]</term>
345       <listitem>
346          <para>
347             Add the parameters(s) to a list of headers parameters to remove;
348             the parameters will be decoded only for the given header(s).
349             Initially the list is empty.
350          </para>
351       </listitem>
352    </varlistentry>
353
354    <varlistentry>
355       <term>-R *[,-header1,-header2,-header3,...]:param1[,param2,param3,...]</term>
356    </varlistentry>
357
358    <varlistentry>
359       <term>-R header1[,header2,header3,...]:*[,-param1,-param2,-param3,...]</term>
360    </varlistentry>
361
362    <varlistentry>
363       <term>-R *[,-header1,-header2,-header3,...]:*[,-param1,-param2,-param3,...]</term>
364       <listitem>
365          <para>
366            Remove listed parameters (or all parameters except listed) frome
367            these headers (or from all headers except listed).
368          </para>
369       </listitem>
370    </varlistentry>
371
372    <varlistentry>
373       <term>--set-header header:value</term>
374       <listitem>
375          <para>
376            The program sets or changes value for the header to the given value
377            (only at the top-level message).
378          </para>
379       </listitem>
380    </varlistentry>
381
382    <varlistentry>
383       <term>--set-param header:param=value</term>
384       <listitem>
385          <para>
386            The program sets or changes value for the header's parameter to the
387            given value (only at the top-level message). The header must exist.
388          </para>
389       </listitem>
390    </varlistentry>
391
392    <varlistentry>
393       <term>-B mask</term>
394       <listitem>
395          <para>
396            Append mask to the list of binary content types that will be not
397            content-transfer-decoded (will be left as base64 or such).
398          </para>
399       </listitem>
400    </varlistentry>
401
402    <varlistentry>
403       <term>-b mask</term>
404       <listitem>
405          <para>
406             Append mask to the list of binary content types; if the message to
407             decode has a part of this type the program will
408             content-transfer-decode (base64 or whatever to 8bit binary) it but
409             pass the part as is, without any further processing.
410          </para>
411       </listitem>
412    </varlistentry>
413
414    <varlistentry>
415       <term>-e mask</term>
416       <listitem>
417          <para>
418             Append mask to the list of error content types; if the message to
419             decode has a part of this type the program fails with ValueError.
420          </para>
421       </listitem>
422    </varlistentry>
423
424    <varlistentry>
425       <term>-i mask</term>
426       <listitem>
427          <para>
428             Append mask to the list of content types to ignore; if the message to
429             decode has a part of this type the program will not pass it, instead
430             a line "Message body of type `%s' skipped." will be issued.
431          </para>
432       </listitem>
433    </varlistentry>
434
435    <varlistentry>
436       <term>-t mask</term>
437       <listitem>
438          <para>
439             Append mask to the list of content types to convert to text; if the
440             message to decode has a part of this type the program will consult
441             mailcap database, find first copiousoutput filter and convert the
442             part.
443          </para>
444       </listitem>
445    </varlistentry>
446
447    <varlistentry>
448       <term>--save-headers mask</term>
449    </varlistentry>
450
451    <varlistentry>
452       <term>--save-body mask</term>
453    </varlistentry>
454
455    <varlistentry>
456       <term>--save-message mask</term>
457       <listitem>
458          <para>
459             Append mask to a list of content types to save to a file;
460             --save-headers saves only decoded headers of the message (or
461             subpart); --save-body saves only decoded body; --save-message saves
462             the entire message or subpart (headers + body).
463          </para>
464       </listitem>
465    </varlistentry>
466
467    <varlistentry>
468       <term>-O dest_dir</term>
469       <listitem>
470          <para>
471            Set destination directory for the output files; the directory must
472            exist. Default is current directory.
473           </para>
474       </listitem>
475    </varlistentry>
476
477    <varlistentry>
478       <term>-o output_file</term>
479       <listitem>
480          <para>
481             Save output to the file related to the destination directory from
482             option -O. Also useful in case of redirected stdin:
483             <programlisting language="sh">mimedecode.py -o output_file &lt; input_file
484 cat input_file | mimedecode.py -o output_file</programlisting>
485          </para>
486       </listitem>
487    </varlistentry>
488 </variablelist>
489
490 <para>
491    The 5 list options (-Bbeit) require more explanation. They allow a user to
492    control body decoding with great flexibility. Think about said mail archive;
493    for example, its maintainer wants to put there only texts, convert
494    PDF/Postscript to text, pass HTML and images as is (decoding base64 to html
495    but left images in base64), and ignore everything else. Easy:
496 </para>
497
498 <para>
499 <code language="sh">
500    mimedecode.py -t application/pdf -t application/postscript -b text/html
501          -B 'image/*' -i '*/*'
502 </code>
503 </para>
504
505 <para>
506    When the program decodes a message (non-MIME or a non-multipart subpart of a
507    MIME message), it consults Content-Type header. The content type is searched
508    in all 5 lists, in order "text-binary-ignore-error". If found, appropriate
509    action performed. If not found, the program search the same lists for
510    "type/*" mask (the type of "text/html" is just "text"). If found,
511    appropriate action performed. If not found, the program search the same
512    lists for "*/*" mask. If found, appropriate action performed. If not found,
513    the program uses default action, which is to decode everything to text (if
514    mailcap specifies a filter).
515 </para>
516
517 <para>
518    Initially all 5 lists are empty, so without any additional parameters
519 the program always uses the default decoding.
520 </para>
521
522 <para>
523   The 3 save list options (--save-headers/body/message) are similar. They make
524   the program to save every non-multipart subpart (only headers, or body, or
525   the entire subpart) that corresponds to the given mask to a file. Before
526   saving the message (or the subpart) is decoded according to all other options
527   and placed to the output stream as usual. Filename for the file is created
528   using "filename" parameter from the Content-Disposition header, or "name"
529   parameter from the Content-Type header if one of those exist; a serial
530   counter is prepended to the filename to avoid collisions; if there are no
531   name/filename parameters, the filename is just the serial counter. The file
532   is saved in the directory set with -O (default is the current directory).
533 </para>
534 </refsect1>
535
536
537 <refsect1>
538 <title>ENVIRONMENT</title>
539 <variablelist>
540   <varlistentry><term>LANG</term></varlistentry>
541   <varlistentry><term>LC_ALL</term></varlistentry>
542   <varlistentry><term>LC_CTYPE</term></varlistentry>
543 </variablelist>
544 <para>
545   Define current locale settings. Used to determine current default charset (if
546   your Python is properly installed and configured).
547 </para>
548 </refsect1>
549
550
551 <refsect1>
552 <title>BUGS</title>
553 <para>
554    The program may produce incorrect MIME message. The purpose of the program
555    is to decode whatever it is possible to decode, not to produce absolutely
556    correct MIME output. The incorrect parts are obvious - decoded
557    From/To/Cc/Reply-To/Mail-Followup-To/Subject headers and filenames. Other
558    than that output is correct MIME message. The program does not try to guess
559    whether the headers are correct. For example, if a message header states
560    that charset is iso8859-5, but the body is actually in utf-8 the program
561    will recode the message with the wrong charset.
562 </para>
563 </refsect1>
564
565
566 <refsect1>
567 <title>AUTHOR</title>
568 <para>
569   <firstname>Oleg</firstname>
570   <surname>Broytman</surname>
571   <email>phd@phdru.name</email>
572 </para>
573 </refsect1>
574
575
576 <refsect1>
577 <title>COPYRIGHT</title>
578 <para>
579   Copyright (C) 2001-2014 PhiloSoft Design.
580 </para>
581 </refsect1>
582
583
584 <refsect1>
585 <title>LICENSE</title>
586 <para>
587    GNU GPL
588 </para>
589 </refsect1>
590
591
592 <refsect1>
593 <title>NO WARRANTIES</title>
594 <para>
595    This program is distributed in the hope that it will be useful, but WITHOUT
596    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
597    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
598    more details.
599 </para>
600 </refsect1>
601
602
603 <refsect1>
604 <title>SEE ALSO</title>
605 <para>
606   mimedecode.py home page:
607   <ulink url="http://phdru.name/Software/Python/#mimedecode">http://phdru.name/Software/Python/#mimedecode</ulink>
608 </para>
609 </refsect1>
610
611 </refentry>