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