]> diplodocus.org Git - nmh/blob - man/mhfixmsg.man
Don't consider failure to build a text/plain part to be an error.
[nmh] / man / mhfixmsg.man
1 .TH MHFIXMSG %manext1% "February 20, 2016" "%nmhversion%"
2 .\"
3 .\" %nmhwarning%
4 .\"
5 .SH NAME
6 mhfixmsg \- rewrite MIME messages with various transformations
7 .SH SYNOPSIS
8 .HP 5
9 .na
10 .B mhfixmsg
11 .RI [ +folder ]
12 .RI [ msgs " | "
13 .IR "absolute pathname" " | "
14 .RB \-file
15 .IR file ]
16 .RB [ \-decodetext
17 8bit/7bit |
18 .BR \-nodecodetext ]
19 .RB [ \-decodetypes
20 .IR "type/[subtype][,...]" ]
21 .RB [ \-textcharset
22 .I charset
23 .RB "| " \-notextcharset ]
24 .RB [ \-reformat " | " \-noreformat ]
25 .RB [ \-replacetextplain " | " \-noreplacetextplain ]
26 .RB [ \-fixboundary " | " \-nofixboundary ]
27 .RB [ \-fixcte " | " \-nofixcte ]
28 .RB [ \-fixtype
29 .IR mimetype ]
30 .RB [ \-outfile
31 .IR outfile ]
32 .RB [ \-rmmproc
33 .IR program ]
34 .RB [ \-normmproc ]
35 .RB [ \-changecur " | " \-nochangecur ]
36 .RB [ \-verbose " | " \-noverbose ]
37 .RB [ \-version ]
38 .RB [ \-help ]
39 .ad
40 .SH DESCRIPTION
41 .B mhfixmsg
42 rewrites MIME messages, applying specific transformations such as
43 decoding of MIME-encoded message parts and repairing invalid MIME
44 headers.
45 .PP
46 MIME messages are specified in RFC 2045 to RFC 2049
47 (see
48 .IR mhbuild (1)).
49 The
50 .B mhlist
51 command is invaluable for viewing the content structure of MIME
52 messages.
53 .B mhfixmsg
54 passes non-MIME messages through without any transformations. If no
55 transformations apply to a MIME message, the original message or file
56 is not modified or removed.
57 .PP
58 The
59 .B \-decodetext
60 switch enables a transformation to decode each base64 and
61 quoted-printable text message part to the selected 8bit or 7bit
62 encoding. If 7bit is selected for a base64 part but it will only fit
63 8bit, as defined by RFC 2045, then it will be decoded to 8bit
64 quoted-printable. Otherwise, if the decoded text would not fit the
65 selected encoding, the part is not decoded (and a message will be
66 displayed if
67 .B \-verbose
68 is enabled).
69 .PP
70 When the
71 .B \-decodetext
72 switch is enabled, each carriage return character that precedes a
73 linefeed character is removed from text parts encoded in ASCII,
74 ISO-8859-x, UTF-8, or Windows-12xx.
75 .PP
76 The
77 .B \-decodetypes
78 switch specifies the message parts, by type and optionally subtype,
79 to which
80 .B \-decodetext
81 applies. Its argument is a comma-separated list of type/subtype
82 elements. If an element does not contain a subtype, then
83 .B \-decodetext
84 applies to all subtypes of the type. The default is
85 .B \-decodetypes
86 .IR text ;
87 it can be overridden, e.g., with
88 .B \-decodetypes
89 .I text/plain
90 to restrict
91 .B \-decodetext
92 to just text/plain parts.
93 .PP
94 The
95 .B \-textcharset
96 switch specifies that all text/plain parts of the message(s)
97 should be converted to
98 .IR charset .
99 Charset conversions require that
100 .B nmh
101 be built with
102 .IR iconv (3);
103 see the
104 .BR mhparam (1)
105 man page for how determine whether your
106 .B nmh
107 installation includes that.
108 To convert text parts other than text/plain, an external program can
109 be used, via the
110 .B \-reformat
111 switch.
112 .PP
113 The
114 .B \-reformat
115 switch enables a transformation for text parts in the message. For
116 each text part that is not text/plain and that does not have a
117 corresponding text/plain in a multipart/alternative part,
118 .B mhfixmsg
119 looks for a mhfixmsg-format-text/subtype profile entry that matches
120 the subtype of the part. If one is found and can be used to
121 successfully convert the part to text/plain,
122 .B mhfixmsg
123 inserts that text/plain part at the beginning of the containing
124 multipart/alternative part, if present. If not, it creates a
125 multipart/alternative part.
126 .PP
127 With the
128 .B \-reformat
129 switch, multipart/related parts are handled differently than
130 multipart/alternative. If the multipart/related has only a single
131 part that is not text/plain and can be converted to text/plain, a
132 text/plain part is added and the type of the part is changed to
133 multipart/alternative. If the multipart/related has more than one
134 part but does not have a text/plain part,
135 .B mhfixmsg
136 tries to add one.
137 .PP
138 The
139 .B \-replacetextplain
140 switch broadens the applicability of
141 .B \-reformat
142 by always replacing a corresponding text/plain part, if one exists.
143 If
144 .B \-verbose
145 if enabled, the replacement will be shown as two steps: a removal of
146 the text/plain part followed by the usual insertion of a new part.
147 .PP
148 .B \-reformat
149 requires a profile entry for each text part subtype to be reformatted.
150 The mhfixmsg-format-text/subtype profile entries are based on external
151 conversion programs, and are used the same way that
152 .B mhshow
153 uses its mhshow-show-text/subtype entries. When
154 .B nmh
155 is installed, it searches for a conversion program for text/html
156 content, and if one is found, inserts a mhfixmsg-format-text/html
157 entry in %nmhetcdir%/mhn.defaults. An entry of the same name in the
158 user's profile takes precedence. The user can add entries for
159 other text subtypes to their profile.
160 .PP
161 The
162 .B \-fixboundary
163 switch enables a transformation to repair the boundary portion of the
164 Content-Type header field of the message to match the boundaries of
165 the outermost multipart part of the message, if it does not. That
166 condition is indicated by a \*(lqbogus multipart content in
167 message\*(rq error message from
168 .B mhlist
169 and other
170 .B nmh
171 programs that parse MIME messages.
172 .PP
173 The
174 .B \-fixcte
175 switch enables a transformation to change the
176 Content-Transfer-Encoding from an invalid value to 8bit in message
177 parts with a Content-Type of multipart, as required by RFC 2045,
178 Section 6.4. That condition is indicated by a \*(lqmust be encoded in
179 7bit, 8bit, or binary\*(rq error message from
180 .B mhlist
181 and other
182 .B nmh
183 programs that parse MIME messages.
184 .PP
185 The
186 .B \-fixtype
187 switch ensures that each part of the message has the correct MIME type
188 shown in its Content-Type header. It may be repeated. It is
189 typically used to replace \*(lqapplication/octet-stream\*(rq with a
190 more descriptive MIME type. It may not be used for multipart and
191 message types.
192 .PP
193 .B mhfixmsg
194 applies one transformation unconditionally: it removes an extraneous
195 trailing semicolon from the parameter lists of MIME header fields.
196 .PP
197 The
198 .B \-verbose
199 switch directs
200 .B mhfixmsg
201 to output informational message for each transformation applied.
202 .PP
203 The return status of
204 .B mhfixmsg
205 is 0 if all of the requested transformations are performed, or
206 non-zero otherwise.
207 .RB ( mhfixmsg
208 will not decode to binary content, but a request to do so is
209 not considered a failure, and is noted with
210 .BR \-verbose .)
211 If a problem is detected with any one of multiple messages such that
212 the return status is non-zero, then none of the messages will be
213 modified.
214 .PP
215 The
216 .B \-file
217 .I file
218 switch directs
219 .B mhfixmsg
220 to use the specified
221 file as the source message, rather than a message from a folder.
222 Only one file argument may be provided. The
223 .B \-file
224 switch is implied if
225 .I file
226 is an absolute pathname.
227 If the file is \*(lq-\*(rq, then
228 .B mhfixmsg
229 accepts the source message on the standard input stream. If
230 the
231 .B \-outfile
232 switch is not enabled when using the standard input stream,
233 .B mhfixmsg
234 will not produce a transformed output message.
235 .PP
236 .BR mhfixmsg ,
237 by default, transforms the message in place. If the
238 .B \-outfile
239 switch is enabled, then
240 .B mhfixmsg
241 does not modify the input message or file, but instead places its
242 output in the specified file. An outfile name of \*(lq-\*(rq
243 specifies the standard output stream.
244 .PP
245 Combined with the
246 .B \-verbose
247 switch, the
248 .B \-outfile
249 switch can be used to show what transformations
250 .B mhfixmsg
251 would apply without actually applying them, e.g.,
252 .PP
253 .RS 5
254 mhfixmsg -outfile /dev/null -verbose
255 .RE
256 .PP
257 As always, this usage obeys any
258 .B mhfixmsg
259 switches in the user's profile.
260 .PP
261 .B \-outfile
262 can be combined with
263 .B rcvstore
264 to add a single transformed message to a different folder, e.g.,
265 .PP
266 .RS 5
267 mhfixmsg -outfile - | \\
268 .RS 0
269 %nmhlibexecdir%/rcvstore +folder
270 .RE
271 .RE
272 .SS Summary of Applicability
273 The transformations apply to the parts of a message depending on
274 content type and/or encoding as follows:
275 .PP
276 .RS 5
277 .nf
278 .ta \w'\-fixboundary 'u
279 \-decodetext base64 and quoted-printable encoded text parts
280 \-decodetypes limits parts to which -decodetext applies
281 \-textcharset text/plain parts
282 \-reformat text parts that are not text/plain
283 \-fixboundary outermost multipart part
284 \-fixcte multipart part
285 \-fixtype all except multipart and message parts
286 .fi
287 .RE
288 .PP
289 .SS "Backup of Original Message/File"
290 If it applies any transformations to a message or file,
291 and the
292 .B \-outfile
293 switch is not used,
294 .B mhfixmsg
295 backs up the original the same way as
296 .BR rmm .
297 That is, it uses the
298 .I rmmproc
299 profile component, if present. If not present,
300 .B mhfixmsg
301 moves the original message to a backup file.
302 The
303 .B \-rmmproc
304 switch may be used to override this profile component. The
305 .B \-normmproc
306 switch disables the use of any
307 .I rmmproc
308 profile component and negates all prior
309 .B \-rmmproc
310 switches.
311 .PP
312 .SS "Integration with inc"
313 .B mhfixmsg
314 can be used as an add-hook, as described in %docdir%/README-HOOKS.
315 Note that add-hooks are called from all
316 .B nmh
317 programs that add a message to a folder, not just
318 .BR inc .
319 Alternatively, a simple shell alias or function can be used to
320 call
321 .B mhfixmsg
322 immediately after a successful invocation of
323 .BR inc .
324 One approach could be based on:
325 .PP
326 .RS 5
327 msgs=`inc -format '%(msg)'` && [ -n "$msgs" ] && scan $msgs && \
328 mhfixmsg -nochangecur $msgs
329 .RE
330 .PP
331 Another approach would rely on adding a sequence to Unseen-Sequence,
332 which
333 .B inc
334 sets with the newly incorporated messages. Those could then be
335 supplied to
336 .BR mhfixmsg .
337 .SS "Integration with procmail"
338 By way of example, here is an excerpt from a procmailrc file
339 that filters messages through
340 .B mhfixmsg
341 before storing them in the user's
342 .I nmh-workers
343 folder. It also stores the incoming message in the
344 .I Backups
345 folder in a filename generated by
346 .BR mkstemp ,
347 which is a non-POSIX utility to generate a temporary file.
348 Alternatively,
349 .B mhfixmsg
350 could be called on the message after it is stored.
351 .PP
352 .RS 5
353 .nf
354 .ta \w'\-fixboundary 'u
355 PATH = %bindir%:$PATH
356 MAILDIR = `mhparam path`
357 #### The Backups directory is relative to MAILDIR.
358 MKSTEMP = 'mkstemp -directory Backups -prefix mhfixmsg'
359 MHFIXMSG = 'mhfixmsg -noverbose -file - -outfile -'
360 STORE = %nmhlibexecdir%/rcvstore
361
362 :0 w: nmh-workers/procmail.$LOCKEXT
363 * ^TOnmh-workers@nongnu.org
364 | tee `$MKSTEMP` | $MHFIXMSG | $STORE +nmh-workers
365 .fi
366 .RE
367 .PP
368 .SH FILES
369 .B mhfixmsg
370 looks for mhn.defaults in multiple locations: absolute pathnames are
371 accessed directly, tilde expansion is done on usernames, and files are
372 searched for in the user's
373 .I Mail
374 directory as specified in their profile. If not found there, the directory
375 .RI \*(lq %nmhetcdir% \*(rq
376 is checked.
377 .PP
378 .fc ^ ~
379 .nf
380 .ta \w'%nmhetcdir%/mhn.defaults 'u
381 ^$HOME/\&.mh\(ruprofile~^The user profile
382 ^%nmhetcdir%/mhn.defaults~^Default mhfixmsg conversion entries
383 .fi
384 .SH "PROFILE COMPONENTS"
385 .fc ^ ~
386 .nf
387 .ta 2.4i
388 .ta \w'ExtraBigProfileName 'u
389 ^Path:~^To determine the user's nmh directory
390 ^Current\-Folder:~^To find the default current folder
391 ^rmmproc:~^Program to delete original messages or files
392 .fi
393 .SH "SEE ALSO"
394 .IR inc (1),
395 .IR iconv (3),
396 .IR mh-profile (5),
397 .IR mhbuild (1),
398 .IR mhlist (1),
399 .IR mhparam (1),
400 .IR mhshow (1),
401 .IR mh-mkstemp (1),
402 .IR procmail (1),
403 .IR procmailrc (5),
404 .IR rcvstore (1),
405 .IR rmm (1)
406 .SH DEFAULTS
407 .nf
408 .RB ` +folder "' defaults to the current folder"
409 .RB ` msgs "' defaults to cur"
410 .RB ` "\-decodetext 8bit"'
411 .RB ` "\-decodetypes text"'
412 .RB ` \-notextcharset '
413 .RB ` \-reformat '
414 .RB ` \-noreplacetextplain '
415 .RB ` \-fixboundary '
416 .RB ` \-fixcte '
417 .RB ` \-changecur '
418 .RB ` \-noverbose '
419 .fi
420 .SH CONTEXT
421 If a folder is given, it will become the current folder. The last
422 message selected from a folder will become the current message, unless
423 the
424 .B \-nochangecur
425 switch is enabled. If the
426 .B \-file
427 switch or an absolute pathname is used, the context will not be
428 modified.