]> git.phdru.name Git - mimedecode.git/blob - mimedecode.docbook
Add options --save-headers/body/message
[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; if the message to
397             decode has a part of this type the program will pass the part as is,
398             without any additional processing.
399          </para>
400       </listitem>
401    </varlistentry>
402
403    <varlistentry>
404       <term>-B mask</term>
405       <listitem>
406          <para>
407            Append mask to the list of binary content types that will be not
408            content-transfer-decoded (will be left as base64 or such).
409          </para>
410       </listitem>
411    </varlistentry>
412
413    <varlistentry>
414       <term>-e mask</term>
415       <listitem>
416          <para>
417             Append mask to the list of error content types; if the message to
418             decode has a part of this type the program fails with ValueError.
419          </para>
420       </listitem>
421    </varlistentry>
422
423    <varlistentry>
424       <term>-i mask</term>
425       <listitem>
426          <para>
427             Append mask to the list of content types to ignore; if the message to
428             decode has a part of this type the program will not pass it, instead
429             a line "Message body of type `%s' skipped." will be issued.
430          </para>
431       </listitem>
432    </varlistentry>
433
434    <varlistentry>
435       <term>-t mask</term>
436       <listitem>
437          <para>
438             Append mask to the list of content types to convert to text; if the
439             message to decode has a part of this type the program will consult
440             mailcap database, find first copiousoutput filter and convert the
441             part.
442          </para>
443       </listitem>
444    </varlistentry>
445
446    <varlistentry>
447       <term>--save-headers mask</term>
448    </varlistentry>
449
450    <varlistentry>
451       <term>--save-body mask</term>
452    </varlistentry>
453
454    <varlistentry>
455       <term>--save-message mask</term>
456       <listitem>
457          <para>
458             Append mask to a list of content types to save to a file;
459             --save-headers saves only decoded headers of the message (or
460             subpart); --save-body saves only decoded body; --save-message saves
461             the entire message (or subpart).
462          </para>
463       </listitem>
464    </varlistentry>
465
466    <varlistentry>
467       <term>-O dest_dir</term>
468       <listitem>
469          <para>
470            Set destination directory for the output files. Default is current
471            directory.
472           </para>
473       </listitem>
474    </varlistentry>
475
476    <varlistentry>
477       <term>-o output_file</term>
478       <listitem>
479          <para>
480             Save output to the file related to the destination directory from
481             option -O. Also useful in case of redirected stdin:
482             <programlisting language="sh">mimedecode.py -o output_file &lt; input_file
483 cat input_file | mimedecode.py -o output_file</programlisting>
484          </para>
485       </listitem>
486    </varlistentry>
487 </variablelist>
488
489 <para>
490    The 5 list options (-Bbeit) require more explanation. They allow a user to
491    control body decoding with great flexibility. Think about said mail archive;
492    for example, its maintainer wants to put there only texts, convert
493    Postscript/PDF to text, pass HTML and images as is, and ignore everything
494    else. Easy:
495 </para>
496
497 <para>
498 <code language="sh">
499    mimedecode.py -t application/postscript -t application/pdf -b text/html
500          -b 'image/*' -i '*/*'
501 </code>
502 </para>
503
504 <para>
505    When the program decodes a message (non-MIME or a non-multipart subpart of a
506    MIME message), it consults Content-Type header. The content type is searched
507    in all 4 lists, in order "text-binary-ignore-error". If found, appropriate
508    action performed. If not found, the program search the same lists for
509    "type/*" mask (the type of "text/html" is just "text"). If found,
510    appropriate action performed. If not found, the program search the same
511    lists for "*/*" mask. If found, appropriate action performed. If not found,
512    the program uses default action, which is to decode everything to text (if
513    mailcap specifies a filter).
514 </para>
515
516 <para>
517    Initially all 4 lists are empty, so without any additional parameters
518 the program always uses the default decoding.
519 </para>
520
521 <para>
522   The 3 save list options (--save-headers/body/message) are similar. They make
523   the program to save every non-multipart subpart (only headers, or body, or
524   the entire subpart) that corresponds to the given mask to a file. Before
525   saving the message (or the subpart) is decoded according to all other options
526   and placed to the output stream as usual. Filename for the file is created
527   using "filename" parameter from the Content-Disposition header, or "name"
528   parameter from the Content-Type header if one of those exist; a serial
529   counter is prepended to the filename to avoid collisions; if there are no
530   name/filename parameters, the filename is just the serial counter. The file
531   is saved in the directory set with -O (default is the current directory).
532 </para>
533 </refsect1>
534
535
536 <refsect1>
537 <title>ENVIRONMENT</title>
538 <variablelist>
539   <varlistentry><term>LANG</term></varlistentry>
540   <varlistentry><term>LC_ALL</term></varlistentry>
541   <varlistentry><term>LC_CTYPE</term></varlistentry>
542 </variablelist>
543 <para>
544   Define current locale settings. Used to determine current default charset (if
545   your Python is properly installed and configured).
546 </para>
547 </refsect1>
548
549
550 <refsect1>
551 <title>BUGS</title>
552 <para>
553    The program may produce incorrect MIME message. The purpose of the program
554    is to decode whatever it is possible to decode, not to produce absolutely
555    correct MIME output. The incorrect parts are obvious - decoded
556    From/To/Cc/Reply-To/Mail-Followup-To/Subject headers and filenames. Other
557    than that output is correct MIME message. The program does not try to guess
558    whether the headers are correct. For example, if a message header states
559    that charset is iso8859-5, but the body is actually in utf-8 the program
560    will recode the message with the wrong charset.
561 </para>
562 </refsect1>
563
564
565 <refsect1>
566 <title>AUTHOR</title>
567 <para>
568   <firstname>Oleg</firstname>
569   <surname>Broytman</surname>
570   <email>phd@phdru.name</email>
571 </para>
572 </refsect1>
573
574
575 <refsect1>
576 <title>COPYRIGHT</title>
577 <para>
578   Copyright (C) 2001-2014 PhiloSoft Design.
579 </para>
580 </refsect1>
581
582
583 <refsect1>
584 <title>LICENSE</title>
585 <para>
586    GNU GPL
587 </para>
588 </refsect1>
589
590
591 <refsect1>
592 <title>NO WARRANTIES</title>
593 <para>
594    This program is distributed in the hope that it will be useful, but WITHOUT
595    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
596    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
597    more details.
598 </para>
599 </refsect1>
600
601
602 <refsect1>
603 <title>SEE ALSO</title>
604 <para>
605   mimedecode.py home page:
606   <ulink url="http://phdru.name/Software/Python/#mimedecode">http://phdru.name/Software/Python/#mimedecode</ulink>
607 </para>
608 </refsect1>
609
610 </refentry>