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