]> diplodocus.org Git - nmh/blob - man/mhfixmsg.man
Fixed mhshow part markers when displaying multiple messages.
[nmh] / man / mhfixmsg.man
1 .TH MHFIXMSG %manext1% 2018-01-14 "%nmhversion%"
2 .
3 .\" %nmhwarning%
4 .
5 .SH NAME
6 mhfixmsg \- nmh's MIME-email rewriter with various transformations
7 .SH SYNOPSIS
8 .HP 5
9 .na
10 .B mhfixmsg
11 .RB [ \-help ]
12 .RB [ \-version ]
13 .RI [ +folder ]
14 .RI [ msgs " | "
15 .IR "absolute pathname" " | "
16 .B \-file
17 .IR file ]
18 .RB [ \-decodetext
19 8bit|7bit|binary |
20 .BR \-nodecodetext ]
21 .RB [ \-decodetypes
22 .IR "type/[subtype][,...]" ]
23 .RB [ \-decodeheaderfieldbodies
24 utf-8 |
25 .BR \-nodecodeheaderfieldbodies ]
26 .RB [ \-crlflinebreaks " | " \-nocrlflinebreaks ]
27 .RB [ \-textcharset
28 .I charset
29 .RB "| " \-notextcharset ]
30 .RB [ \-reformat " | " \-noreformat ]
31 .RB [ \-replacetextplain " | " \-noreplacetextplain ]
32 .RB [ \-fixboundary " | " \-nofixboundary ]
33 .RB [ \-fixcte " | " \-nofixcte ]
34 .RB [ \-fixtype
35 .IR mimetype ]
36 .RB [ \-outfile
37 .IR outfile ]
38 .RB [ \-rmmproc
39 .IR program ]
40 .RB [ \-normmproc ]
41 .RB [ \-changecur " | " \-nochangecur ]
42 .RB [ \-verbose " | " \-noverbose ]
43 .ad
44 .SH DESCRIPTION
45 .B mhfixmsg
46 rewrites MIME messages, applying specific transformations such as
47 decoding of MIME-encoded message parts and repairing invalid MIME
48 headers.
49 .PP
50 MIME messages are specified in RFC 2045 to RFC 2049
51 (see
52 .IR mhbuild (1)).
53 The
54 .B mhlist
55 command is invaluable for viewing the content structure of MIME
56 messages.
57 .B mhfixmsg
58 passes non-MIME messages through without any transformations. If no
59 transformations apply to a MIME message, the original message or file
60 is not modified or removed. Thus,
61 .B mhfixmsg
62 can safely be run multiple times on a message.
63 .PP
64 The
65 .B \-decodetext
66 switch enables a transformation to decode each base64 and quoted-printable
67 text message part to the selected 8-bit, 7-bit, or
68 binary encoding.
69 If 7-bit is selected for a base64 part but it will only fit
70 8-bit, as defined by RFC 2045, then it will be decoded to 8-bit
71 quoted-printable.
72 Similarly, with 8-bit, if the decoded text would be binary,
73 then the part is not decoded (and a message will be displayed if
74 .B \-verbose
75 is enabled). Note that
76 .B \-decodetext
77 binary can produce messages that are not compliant with RFC 5322, \(sc2.1.1.
78 .PP
79 When the
80 .B \-decodetext
81 switch is enabled, each carriage return character that precedes a
82 linefeed character is removed from text parts encoded in ASCII,
83 ISO-8859-x, UTF-8, or Windows-12xx.
84 .PP
85 The
86 .B \-decodetypes
87 switch specifies the message parts, by type and optionally subtype,
88 to which
89 .B \-decodetext
90 applies. Its argument is a comma-separated list of type/subtype
91 elements. If an element does not contain a subtype, then
92 .B \-decodetext
93 applies to all subtypes of the type. The default is
94 .B \-decodetypes
95 .IR text ;
96 it can be overridden, e.g., with
97 .B \-decodetypes
98 .I text/plain
99 to restrict
100 .B \-decodetext
101 to just text/plain parts.
102 .PP
103 The
104 .B \-decodeheaderfieldbodies
105 switch enables decoding of UTF-8 header field bodies, when supplied
106 with its mandatory
107 .I utf-8
108 argument. The
109 .B \-nodecodeheaderfieldbodies
110 inhibits this transformation. The transformation can produce a message
111 that does not conform with RFC 2047, \(sc1, paragraph 6, because the decoded
112 header field body could contain unencoded non-ASCII characters. It is
113 therefore not enabled by default.
114 .PP
115 By default, carriage return characters are preserved or inserted at
116 the end of each line of text content. The
117 .B \-crlflinebreaks
118 switch selects this behavior and is enabled by default. The
119 .B \-nocrlflinebreaks
120 switch causes carriage return characters to be stripped from, and not
121 inserted in, text content when it is decoded and encoded. Note that
122 its use can cause the generation of MIME messages that do not conform
123 with RFC 2046, \(sc4.1.1, paragraph 1.
124 .PP
125 The
126 .B \-textcharset
127 switch specifies that all text/plain parts of the message(s)
128 should be converted to
129 .IR charset .
130 Charset conversions require that
131 .B nmh
132 be built with
133 .IR iconv (3);
134 see
135 .IR mhparam (1)
136 for how determine whether your
137 .B nmh
138 installation includes that.
139 To convert text parts other than text/plain, an external program can
140 be used, via the
141 .B \-reformat
142 switch.
143 .PP
144 The
145 .B \-reformat
146 switch enables a transformation for text parts in the message. For
147 each text part that is not text/plain and that does not have a
148 corresponding text/plain in a multipart/alternative part,
149 .B mhfixmsg
150 looks for a mhfixmsg-format-text/subtype profile entry that matches
151 the subtype of the part. If one is found and can be used to
152 successfully convert the part to text/plain,
153 .B mhfixmsg
154 inserts that text/plain part at the beginning of the containing
155 multipart/alternative part, if present. If not, it creates a
156 multipart/alternative part.
157 .PP
158 With the
159 .B \-reformat
160 switch, multipart/related parts are handled differently than
161 multipart/alternative. If the multipart/related has only a single
162 part that is not text/plain and can be converted to text/plain, a
163 text/plain part is added and the type of the part is changed to
164 multipart/alternative. If the multipart/related has more than one
165 part but does not have a text/plain part,
166 .B mhfixmsg
167 tries to add one.
168 .PP
169 The
170 .B \-replacetextplain
171 switch broadens the applicability of
172 .BR \-reformat ,
173 by always replacing a corresponding text/plain part, if one exists.
174 If
175 .B \-verbose
176 is enabled, the replacement will be shown as two steps: a removal of
177 the text/plain part, followed by the usual insertion of a new part.
178 .PP
179 .B \-reformat
180 requires a profile entry for each text part subtype to be reformatted.
181 The mhfixmsg-format-text/subtype profile entries are based on external
182 conversion programs, and are used in the same way that
183 .B mhshow
184 uses its mhshow-show-text/subtype entries. When
185 .B nmh
186 is installed, it searches for a conversion program for text/html
187 content, and if one is found, inserts a mhfixmsg-format-text/html
188 entry in %nmhetcdir%/mhn.defaults. An entry of the same name in the
189 user's profile takes precedence. The user can add entries for
190 other text subtypes to their profile.
191 .PP
192 The
193 .B \-fixboundary
194 switch enables a transformation to repair the boundary portion of the
195 Content-Type header field of the message to match the boundaries of
196 the outermost multipart part of the message, if it does not. That
197 condition is indicated by a \*(lqbogus multipart content in
198 message\*(rq error message from
199 .B mhlist
200 and other
201 .B nmh
202 programs that parse MIME messages.
203 .PP
204 The
205 .B \-fixcte
206 switch enables a transformation to change the
207 Content-Transfer-Encoding from an invalid value to 8-bit in message
208 parts with a Content-Type of multipart and message, as required by
209 RFC 2045, \(sc6.4. That condition is indicated by a \*(lqmust be
210 encoded in 7bit, 8bit, or binary\*(rq error message from
211 .B mhlist
212 and other
213 .B nmh
214 programs that parse MIME messages.
215 .PP
216 The
217 .B \-fixtype
218 switch ensures that each part of the message has the correct MIME type
219 shown in its Content-Type header. It may be repeated. It is
220 typically used to replace \*(lqapplication/octet-stream\*(rq with a
221 more descriptive MIME type. It may not be used for multipart and
222 message types.
223 .PP
224 .B mhfixmsg
225 applies two transformations unconditionally.
226 The first removes an extraneous trailing semicolon from the parameter
227 lists of MIME header field values.
228 The second replaces RFC 2047 encoding with RFC 2231 encoding of name
229 and filename parameters in Content-Type and Content-Disposition header
230 field values, respectively.
231 .PP
232 The
233 .B \-verbose
234 switch directs
235 .B mhfixmsg
236 to output informational message for each transformation applied.
237 .PP
238 The return status of
239 .B mhfixmsg
240 is 0 if all of the requested transformations are performed, or
241 non-zero otherwise.
242 .RB ( mhfixmsg
243 will not decode to binary content with the default
244 .B \-decodetext
245 setting, but a request to do so is not considered a failure, and is noted
246 with
247 .BR \-verbose .)
248 If a problem is detected with any one of multiple messages such that
249 the return status is non-zero, then none of the messages will be
250 modified.
251 .PP
252 The
253 .B \-file
254 .I file
255 switch directs
256 .B mhfixmsg
257 to use the specified file as the source message, rather than a message
258 from a folder. Only one file argument may be provided. The
259 .B \-file
260 switch is implied if
261 .I file
262 is an absolute pathname. If the file is \*(lq-\*(rq, then
263 .B mhfixmsg
264 accepts the source message on the standard input stream. If the
265 .B \-outfile
266 switch is not enabled when using the standard input stream,
267 .B mhfixmsg
268 will not produce a transformed output message.
269 .PP
270 .BR mhfixmsg ,
271 by default, transforms the message in place. If the
272 .B \-outfile
273 switch is enabled, then
274 .B mhfixmsg
275 does not modify the input message or file, but instead places its
276 output in the specified file. An outfile name of \*(lq-\*(rq
277 specifies the standard output stream.
278 .PP
279 Combined with the
280 .B \-verbose
281 switch, the
282 .B \-outfile
283 switch can be used to show what transformations
284 .B mhfixmsg
285 would apply without actually applying them, e.g.,
286 .PP
287 .RS 5
288 mhfixmsg -outfile /dev/null -verbose
289 .RE
290 .PP
291 As always, this usage obeys any
292 .B mhfixmsg
293 switches in the user's profile.
294 .PP
295 .B \-outfile
296 can be combined with
297 .B rcvstore
298 to add a single transformed message to a different folder, e.g.,
299 .PP
300 .RS 5
301 mhfixmsg -outfile - | \\
302 .RS 0
303 %nmhlibexecdir%/rcvstore +folder
304 .RE
305 .RE
306 .SS Summary of Applicability
307 The transformations apply to the parts of a message depending on
308 content type and/or encoding as follows:
309 .PP
310 .RS 5
311 .nf
312 .ta \w'\-decodeheaderfieldbodies 'u
313 \-decodetext base64 and quoted-printable encoded text parts
314 \-decodetypes limits parts to which -decodetext applies
315 \-decodeheaderfieldbodies all message parts
316 \-crlflinebreaks text parts
317 \-textcharset text/plain parts
318 \-reformat text parts that are not text/plain
319 \-fixboundary outermost multipart part
320 \-fixcte multipart or message part
321 \-fixtype all except multipart and message parts
322 .fi
323 .RE
324 .SS "Backup of Original Message/File"
325 If it applies any transformations to a message or file, and the
326 .B \-outfile
327 switch is not used,
328 .B mhfixmsg
329 backs up the original the same way as
330 .BR rmm .
331 That is, it uses the
332 .I rmmproc
333 profile component, if present. If not present,
334 .B mhfixmsg
335 moves the original message to a backup file.
336 The
337 .B \-rmmproc
338 switch may be used to override this profile component. The
339 .B \-normmproc
340 switch disables the use of any
341 .I rmmproc
342 profile component and negates all prior
343 .B \-rmmproc
344 switches.
345 .SS "Integration with inc"
346 .B mhfixmsg
347 can be used as an add-hook, as described in %docdir%/README-HOOKS.
348 Note that add-hooks are called from all
349 .B nmh
350 programs that add a message to a folder, not just
351 .BR inc .
352 Alternatively, a simple shell alias or function can be used to call
353 .B mhfixmsg
354 immediately after a successful invocation of
355 .BR inc .
356 One approach could be based on:
357 .PP
358 .RS 5
359 msgs=\`inc -format '%(msg)'\` && [ -n "$msgs" ] && scan $msgs && \
360 mhfixmsg -nochangecur $msgs
361 .RE
362 .PP
363 Another approach would rely on adding a sequence to Unseen-Sequence,
364 which
365 .B inc
366 sets with the newly incorporated messages. Those could then be
367 supplied to
368 .BR mhfixmsg .
369 An example is shown below.
370 .SS "Integration with procmail"
371 By way of example, here is an excerpt from a procmailrc file
372 that filters messages through
373 .B mhfixmsg
374 before storing them in the user's
375 .I nmh-workers
376 folder. It also stores the incoming message in the
377 .I Backups
378 folder in a filename generated by
379 .BR mkstemp ,
380 which is a non-POSIX utility to generate a temporary file.
381 Alternatively,
382 .B mhfixmsg
383 could be called on the message after it is stored.
384 .PP
385 .RS 5
386 .nf
387 .ta \w'\-fixboundary 'u
388 PATH = %bindir%:$PATH
389 LANG = en_US.utf8
390 MAILDIR = \`mhparam path\`
391 #### The Backups directory is relative to MAILDIR.
392 MKSTEMP = 'mkstemp -directory Backups -prefix mhfixmsg'
393 MHFIXMSG = 'mhfixmsg -noverbose -file - -outfile -'
394 STORE = %nmhlibexecdir%/rcvstore
395
396 :0 w: nmh-workers/procmail.$LOCKEXT
397 * ^TOnmh-workers@nongnu.org
398 | tee \`$MKSTEMP\` | $MHFIXMSG | $STORE +nmh-workers
399 .fi
400 .RE
401 .SH "EXAMPLES"
402 .SS Basic usage
403 To run
404 .B mhfixmsg
405 on the current message in the current folder, with default transformations to
406 fix MIME boundaries and Content-Transfer-Encoding, to decode text and
407 application/ics content parts to 8 bit, and to add a corresponding text/plain
408 part where lacking:
409 .PP
410 .RS
411 .nf
412 mhfixmsg -verbose
413 .fi
414 .RE
415 .SS Specified folder and messages
416 To run
417 .B mhfixmsg
418 on specified messages, without its informational output:
419 .PP
420 .RS
421 .nf
422 mhfixmsg +inbox last:4
423 .fi
424 .RE
425 .SS View without modification
426 By default,
427 .B mhfixmsg
428 transforms the message in place.
429 To view the MIME structure that would result from running
430 .B mhfixmsg
431 on the current message, without modifying the message:
432 .PP
433 .RS
434 .nf
435 mhfixmsg -outfile - | mhlist -file -
436 .fi
437 .RE
438 .SS Search message without modification
439 To search the current message, which possibly contains base64
440 or quoted printable encoded text parts, without modifying it,
441 use the
442 .B \-outfile
443 switch:
444 .PP
445 .RS
446 .nf
447 mhfixmsg -outfile - | grep \fIpattern\fR
448 .fi
449 .RE
450 .PP
451 .B \-outfile
452 can be abbreviated in usual MH fashion, e.g., to -o. The search will be
453 on the entire message, not just text parts.
454 .SS Translate text/plain parts to UTF-8
455 To translate all text/plain parts in the current message to UTF-8, in addition
456 to all of the default transformations:
457 .PP
458 .RS
459 .nf
460 mhfixmsg -textcharset utf-8
461 .fi
462 .RE
463 .SS Fix all messages in a folder
464 To run
465 .B mhfixmsg
466 on all of the messages in a folder:
467 .PP
468 .RS
469 .nf
470 mhfixmsg +folder all
471 .fi
472 .RE
473 .PP
474 Alternatively,
475 .B mhfixmsg
476 can be run on each message separately, e.g., using a Bourne shell loop:
477 .PP
478 .RS
479 .nf
480 for msg in \`pick +folder\`; do mhfixmsg +folder $msg; done
481 .fi
482 .RE
483 .PP
484 The two appearances of the
485 .B +folder
486 switch in that command protect against concurrent context changes by other
487 .B nmh
488 command invocations.
489 .SS Run on newly incorporated messages
490 To run
491 .B mhfixmsg
492 on messages as they are incorporated:
493 .PP
494 .RS
495 .nf
496 inc && mhfixmsg -nochangecur unseen
497 .fi
498 .RE
499 .PP
500 This assumes that the Unseen-Sequence profile entry is set to
501 .BR unseen ,
502 as shown in
503 .IR mh-profile (5).
504 .SH FILES
505 .B mhfixmsg
506 looks for mhn.defaults in multiple locations: absolute pathnames are
507 accessed directly, tilde expansion is done on usernames, and files are
508 searched for in the user's
509 .I Mail
510 directory as specified in their profile. If not found there, the directory
511 .RI \*(lq %nmhetcdir% \*(rq
512 is checked.
513 .PP
514 .fc ^ ~
515 .nf
516 .ta \w'%nmhetcdir%/mhn.defaults 'u
517 ^$HOME/.mh_profile~^The user profile
518 ^%nmhetcdir%/mhn.defaults~^Default mhfixmsg conversion entries
519 .fi
520 .SH "PROFILE COMPONENTS"
521 .fc ^ ~
522 .nf
523 .ta 2.4i
524 .ta \w'ExtraBigProfileName 'u
525 ^Path:~^To determine the user's nmh directory
526 ^Current\-Folder:~^To find the default current folder
527 ^rmmproc:~^Program to delete original messages or files
528 .fi
529 .SH "SEE ALSO"
530 .IR iconv (3),
531 .IR inc (1),
532 .IR mh-mkstemp (1),
533 .IR mh-profile (5),
534 .IR mhbuild (1),
535 .IR mhlist (1),
536 .IR mhparam (1),
537 .IR mhshow (1),
538 .IR procmail (1),
539 .IR procmailrc (5),
540 .IR rcvstore (1),
541 .IR rmm (1)
542 .SH DEFAULTS
543 .nf
544 .RB ` +folder "' defaults to the current folder"
545 .RB ` msgs "' defaults to cur"
546 .RB ` "\-decodetext 8bit"'
547 .RB ` "\-decodetypes text,application/ics"'
548 .RB ` \-nodecodeheaderfieldbodies '
549 .RB ` \-crlflinebreaks '
550 .RB ` \-notextcharset '
551 .RB ` \-reformat '
552 .RB ` \-noreplacetextplain '
553 .RB ` \-fixboundary '
554 .RB ` \-fixcte '
555 .RB ` \-changecur '
556 .RB ` \-noverbose '
557 .fi
558 .SH CONTEXT
559 If a folder is given, it will become the current folder. The last
560 message selected from a folder will become the current message, unless
561 the
562 .B \-nochangecur
563 switch is enabled. If the
564 .B \-file
565 switch or an absolute pathname is used, the context will not be
566 modified.