1MHBUILD(1) General Commands Manual MHBUILD(1)
2
3
4
6 mhbuild - translate MIME composition drafts for nmh messages
7
9 mhbuild [-help] [-version] file [-auto | -noauto] [-list | -nolist]
10 [-realsize | -norealsize] [-headers | -noheaders] [-directives |
11 -nodirectives] [-rfc934mode | -norfc934mode] [-contentid | -nocon‐
12 tentid] [-verbose | -noverbose] [-disposition | -nodisposition]
13 [-headerencoding encoding-algorithm | -autoheaderencoding] [-max‐
14 unencoded line-length] [-dist]
15
17 The mhbuild command will translate a MIME composition draft into a
18 valid MIME message.
19
20 mhbuild creates multi-media messages as specified in RFCs 2045 through
21 2049. This includes the encoding of message headers as specified by
22 RFC 2047, and, additionally, the encoding of MIME parameters as speci‐
23 fied in RFC 2231.
24
25 If you specify the name of the composition file as “-”, then mhbuild
26 will accept the composition draft on the standard input. If the trans‐
27 lation of this input is successful, mhbuild will output the new MIME
28 message to the standard output. This argument must be the last argu‐
29 ment on the command line.
30
31 Otherwise, if the file argument to mhbuild is the name of a valid com‐
32 position file, and the translation is successful, mhbuild will replace
33 the original file with the new MIME message. It will rename the origi‐
34 nal file to start with the “,” character and end with the string
35 “.orig”, e.g., if you are editing the file “draft”, it will be renamed
36 to “,draft.orig”. This allows you to easily recover the mhbuild input
37 file.
38
39 Listing the Contents
40 The -list switch tells mhbuild to list the table of contents associated
41 with the MIME message that is created.
42
43 The -headers switch indicates that a one-line banner should be dis‐
44 played above the listing. The -realsize switch tells mhbuild to evalu‐
45 ate the “native” (decoded) format of each content prior to listing.
46 This provides an accurate count at the expense of a small delay. If
47 the -verbose switch is present, then the listing will show any “extra”
48 information that is present in the message, such as comments in the
49 “Content-Type” header.
50
51 If the -disposition switch is present, then the listing will show any
52 relevant information from the “Content-Disposition” header.
53
54 Simplified Attachment Interface
55 For users who wish to simply attach files to text content, mhbuild will
56 scan the composition file for “Attach” headers. An “Attach” header
57 contains a filename that will be appended to the message using normal
58 MIME encapsulation rules. One filename is allowed per “Attach” header,
59 but multiple “Attach” headers are allowed per composition file.
60
61 These files will be appended after any other MIME content, including
62 any content specified by mhbuild directives (see below). See send(1)
63 for more details.
64
65 By default, the Content-Disposition will be “attachment”. mhbuild
66 looks for user profile and mhn.defaults entries of the form
67
68 mhbuild-disposition-type/subtype
69 or
70 mhbuild-disposition-type
71
72 to supply the disposition value. The only supported values are “at‐
73 tachment” and “inline”.
74
75 Convert Interface
76 The convert interface is a powerful mechanism that supports replying to
77 MIME messages. These placeholders are used in the following descrip‐
78 tion:
79
80 TYPE content type/subtype
81 CONVERTER external program, and any fixed arguments, to con‐
82 vert content, such as from a request to a reply
83 ARGSTRING arguments to pass from repl to CONVERTER
84 FILE full path of message being replied to
85 The convert support is based on pseudoheaders of the form
86
87 Nmh-mhbuild-file-TYPE: FILE
88 Nmh-mhbuild-args-TYPE: ARGSTRING
89
90 in the draft. For each such pseudoheader, mhbuild looks in the profile
91 and mhn.defaults for the corresponding TYPE entry to find the converter
92 that supports it:
93
94 mhbuild-convert-TYPE: CONVERTER
95
96 It's a fatal error if no such entry is found for TYPE. An empty entry,
97 e.g.,
98
99 mhbuild-convert-text/html:
100
101 excludes parts of that TYPE from the draft.
102
103 The mhn.defaults file contains default mhbuild-convert-text/html and
104 mhbuild-convert-text/plain entries. Profile entries can be used to
105 override corresponding mhn.defaults entries, as usual.
106
107 For each TYPE part in FILE, mhbuild runs CONVERTER ARGSTRING on the
108 content of the part. Each part in FILE that has no corresponding TYPE
109 entry in the profile or mhn.defaults is excluded from the draft; the
110 user can include them using mhbuild directives.
111
112 repl inserts Nmh-mhbuild-text/html: and Nmh-mhbuild-text/plain: pseudo‐
113 headers in every draft. The user can prevent insertion of content
114 parts of either of those types by putting corresponding empty entries
115 in their profile.
116
117 Only the highest precedence alternative with a supported TYPE of a mul‐
118 tipart/alternative part is used.
119
120 mhn.defaults.sh selects the text/html-to-text/plain converter at in‐
121 stall time.
122
123 Some content types require the addition of parameters to the Content-
124 Type header, such as “method=REPLY” for text/calendar. mhbuild looks
125 for a Content-Type header, followed by a blank line, at the beginning
126 of the converter output. If one is found, it is used for the corre‐
127 sponding part in the reply draft.
128
129 The convert interface doesn't support different ARGSTRINGs or different
130 converters for different parts of the same TYPE. That would require
131 associating parts by part number with the ARGSTRINGs or converters.
132 Instead, that can be done (currently, without using the convert sup‐
133 port), with mhbuild directives as described below, e.g.,
134
135 #text/html; charset=utf-8 *8bit | mhstore -noverbose -part 42.7
136 -outfile - | w3m -dump -cols 64 -T text/html -O utf-8
137
138 The only way to mix convert pseudoheaders and mhbuild directives is to
139 insert the directives before mhbuild is run, which is typically done by
140 entering mime at the “What now?” prompt, or with an -editor mhbuild
141 switch.
142
143 If there are any Nmh-mhbuild- pseudoheaders in the composition file,
144 mhbuild divides the translation into two stages. The first stage in‐
145 cludes all translations except encoding of text content. The second
146 stage encodes text content as needed. This allows the user to edit the
147 text prior to encoding. The second stage, along with the first stage
148 if it had not yet been performed, is selected with the -auto switch.
149
150 These (optional) setup steps can make the convert support easier to
151 use:
152
153 1) Add this line to your profile:
154
155 mhbuild-next: $EDITOR
156
157 assuming that your EDITOR environment variable is set; if not, re‐
158 place EDITOR with the name of your editor. Without that profile
159 entry, a response of “e[dit]” at the What now? prompt will require
160 specification of your editor if an -editor mhbuild switch is used.
161
162 2) If using repl, source the Bourne-shell compatible functions in
163 /usr/share/doc/nmh/contrib/replaliases.
164
165 Translating the Composition File
166 mhbuild is essentially a filter to aid in the composition of MIME mes‐
167 sages. mhbuild will convert an mhbuild “composition file” into a valid
168 MIME message. An mhbuild “composition file” is just a file containing
169 plain text that is interspersed with various mhbuild directives. When
170 this file is processed by mhbuild, the various directives will be ex‐
171 panded to the appropriate content, and will be encoded according to the
172 MIME standards. The resulting MIME message can then be sent by elec‐
173 tronic mail.
174
175 The formal syntax for a mhbuild composition file is defined at the end
176 of this document, but the ideas behind this format are not complex.
177 Basically, the body contains one or more contents. A content consists
178 of either a directive, indicated with a “#” as the first character of a
179 line; or, plaintext (one or more lines of text). The continuation
180 character, “\“, may be used to enter a single directive on more than
181 one line, e.g.,
182
183 #image/png \
184 /home/foobar/junk/picture.png
185
186 There are five kinds of directives: “type” directives, which name the
187 type and subtype of the content; “external-type” directives, which also
188 name the type and subtype of the content; the “message” directive
189 (#forw), which is used to forward one or more messages; the “begin” di‐
190 rective (#begin), which is used to create a multipart content; and the
191 “on/off/pop” directives (#on, #off, #pop) which control whether any
192 other directives are honored at all.
193
194 The -directives switch allows control over whether mhbuild will honor
195 any of the “#”-directives. This can also be affected with the #on or
196 #off directives, and #pop, which restores the state of processing to
197 that preceding the most recent #on or #off. (The #on, #off, and #pop
198 directives are always honored, of course.) This allows inclusion of
199 plain text which looks like mhbuild directives, without causing errors:
200
201 #off
202 #include <stdio.h>
203 puts("hello, world!");
204 #pop
205
206 Currently the stack depth for the #on/off/pop directives is 32.
207
208 The “type” directive is used to directly specify the type and subtype
209 of a content. You may only specify discrete types in this manner
210 (can't specify the types multipart or message with this directive).
211 You may optionally specify the name of a file containing the contents
212 in “native” (decoded) format. If this filename starts with the “|”
213 character, then it represents a command to execute whose output is cap‐
214 tured accordingly. For example,
215
216 #audio/basic |raw2audio -F < /usr/lib/sound/giggle.au
217
218 If a filename is not given, mhbuild will look for information in the
219 user's profile to determine how the different contents should be com‐
220 posed. This is accomplished by consulting a composition string, and
221 executing it under /bin/sh, with the standard output set to the con‐
222 tent. If the -verbose switch is given, mhbuild will echo any commands
223 that are used to create contents in this way.
224
225 The composition string may contain the following escapes:
226
227 %a Insert parameters from directive
228 %f Insert filename containing content
229 %F %f, and stdout is not re-directed
230 %s Insert content subtype
231 %% Insert character %
232
233 First, mhbuild will look for an entry of the form:
234
235 mhbuild-compose-type/subtype
236
237 to determine the command to use to compose the content. If this isn't
238 found, mhbuild will look for an entry of the form:
239
240 mhbuild-compose-type
241
242 to determine the composition command. If this isn't found, mhbuild
243 will complain.
244
245 An example entry might be:
246
247 mhbuild-compose-audio/basic: record | raw2audio -F
248
249 Because commands like these will vary, depending on the display envi‐
250 ronment used for login, composition strings for different contents
251 should probably be put in the file specified by the MHBUILD environment
252 variable, instead of directly in your user profile.
253
254 The “external-type” directives are used to provide a MIME reference to
255 a content, rather than enclosing the contents itself (for instance, by
256 specifying an ftp site). Hence, instead of providing a filename as
257 with the type directives, external-parameters are supplied. These look
258 like regular parameters, so they must be separated accordingly. For
259 example,
260
261 #@application/octet-stream; \
262 type=tar; \
263 conversions=compress \
264 [this is the nmh distribution] \
265 {attachment; filename="nmh.tar.gz"} \
266 name="nmh.tar.gz"; \
267 directory="/pub/nmh"; \
268 site="ftp.math.gatech.edu"; \
269 access-type=anon-ftp; \
270 mode="image"
271
272 You must give a description string to separate the content parameters
273 from the external-parameters (although this string may be empty). This
274 description string is specified by enclosing it within “[]”. A dispo‐
275 sition string, to appear in a “Content-Disposition” header, may appear
276 in the optional “{}”.
277
278 These parameters are of the form:
279
280 access-type= usually “anon-ftp”, “mail-server”, or “url”
281 name= filename
282 permission= read-only or read-write
283 site= hostname
284 directory= directoryname (optional)
285 mode= usually “ascii” or “image” (optional)
286 size= number of octets
287 server= mailbox
288 subject= subject to send
289 body= command to send for retrieval
290 url= URL of content
291
292 A minimum “external-type” directive for the url access-type would be as
293 follows:
294
295 #@application/octet-stream [] access-type=url; \
296 url="http://download.savannah.gnu.org/releases/nmh/nmh-1.5.tar.gz"
297
298 Any long URLs will be wrapped according to RFC 2231 rules.
299
300 The “message” directive (#forw) is used to specify a message or group
301 of messages to include. You may optionally specify the name of the
302 folder and which messages are to be forwarded. If a folder is not
303 given, it defaults to the current folder. Similarly, if a message is
304 not given, it defaults to the current message. Hence, the message di‐
305 rective is similar to the forw command, except that the former uses the
306 MIME rules for encapsulation rather than those specified in RFC 934.
307 For example,
308
309 #forw +inbox 42 43 99
310
311 If you include a single message, it will be included directly as a con‐
312 tent of type “message/rfc822”. If you include more than one message,
313 then mhbuild will add a content of type “multipart/digest” and include
314 each message as a subpart of this content.
315
316 If you are using this directive to include more than one message, you
317 may use the -rfc934mode switch. This switch will indicate that mhbuild
318 should attempt to utilize the MIME encapsulation rules in such a way
319 that the “multipart/digest” that is created is (mostly) compatible with
320 the encapsulation specified in RFC 934. If given, then RFC 934 compli‐
321 ant user-agents should be able to burst the message on recep‐
322 tion -- providing that the messages being encapsulated do not contain
323 encapsulated messages themselves. The drawback of this approach is
324 that the encapsulations are generated by placing an extra newline at
325 the end of the body of each message.
326
327 The “begin” directive is used to create a multipart content. When us‐
328 ing the “begin” directive, you must specify at least one content be‐
329 tween the begin and end pairs.
330
331 #begin
332 This will be a multipart with only one part.
333 #end
334
335 If you use multiple directives in a composition draft, mhbuild will au‐
336 tomatically encapsulate them inside a multipart content. Therefore the
337 “begin” directive is only necessary if you wish to use nested multi‐
338 parts, or create a multipart message containing only one part.
339
340 For all of these directives, the user may include a brief description
341 of the content between the “[” character and the “]” character. This
342 description will be copied into the “Content-Description” header when
343 the directive is processed.
344
345 #forw [important mail from Bob] +bob 1 2 3 4 5
346
347 Similarly, a disposition string may optionally be provided between “{”
348 and “}” characters; it will be copied into the “Content-Disposition”
349 header when the directive is processed. If a disposition string is
350 provided that does not contain a filename parameter, and a filename is
351 provided in the directive, it will be added to the “Content-Disposi‐
352 tion” header. For example, the following directive:
353
354 #text/plain; charset=iso-8859-1 <>{attachment} /tmp/summary.txt
355
356 creates these message part headers:
357
358 Content-Type: text/plain; charset="iso-8859-1"
359 Content-Disposition: attachment; filename="summary.txt"
360
361 By default, mhbuild will generate a unique “Content-ID:” for each di‐
362 rective, corresponding to each message part; however, the user may
363 override this by defining the ID using the “<” and “>” characters. The
364 -nocontentid switch suppresses creation of all “Content-ID:” headers,
365 even in the top level of the message.
366
367 Normally mhbuild will choose an appropriate Content-Transfer-Encoding
368 based on the content and the MIME Content-Type. However, you can over‐
369 ride that in an mhbuild directive by specifying “*” and the encoding.
370 Acceptable encoding values are “8bit”, “qp” (for quoted-printable), and
371 “b64” (for base64 encoding). It should be noted that undesired results
372 may occur if 8bit or quoted-printable is selected for binary content,
373 due to the translation between Unix line endings and the line endings
374 use by the mail transport system.
375
376 In addition to the various directives, plaintext can be present.
377 Plaintext is gathered, until a directive is found or the draft is ex‐
378 hausted, and this is made to form a text content. If the plaintext
379 must contain a “#” at the beginning of a line, simply double it, e.g.,
380
381 ##when sent, this line will start with only one #
382
383 If you want to end the plaintext prior to a directive, e.g., to have
384 two plaintext contents adjacent, simply insert a line containing a sin‐
385 gle “#” character, e.g.,
386
387 this is the first content
388 #
389 and this is the second
390
391 Finally, if the plaintext starts with a line of the form:
392
393 Content-Description: text
394
395 then this will be used to describe the plaintext content. You MUST
396 follow this line with a blank line before starting your text.
397
398 By default, plaintext is captured as a text/plain content. You can
399 override this by starting the plaintext with “#<” followed by a con‐
400 tent-type specification. For example, e.g.,
401
402 #<text/enriched
403 this content will be tagged as text/enriched
404 #
405 and this content will be tagged as text/plain
406 #
407 #<application/x-patch [this is a patch]
408 and this content will be tagged as application/x-patch
409
410 Note that if you use the “#<” plaintext-form, then the content-descrip‐
411 tion must be on the same line which identifies the content type of the
412 plaintext.
413
414 When composing a text content, you may indicate the relevant character
415 set by adding the “charset” parameter to the directive.
416
417 #<text/plain; charset=iso-8859-5
418
419 If a text content contains any 8-bit characters (characters with the
420 high bit set) and the character set is not specified as above, then mh‐
421 build will assume the character set is of the type given by the stan‐
422 dard locale(1) environment variables. If these environment variables
423 are not set, then the character set will be labeled as “x-unknown”.
424
425 If a text content contains only 7-bit characters and the character set
426 is not specified as above, then the character set will be labeled as
427 “us-ascii”.
428
429 By default text content with the high bit set is encoded with an 8-bit
430 Content-Transfer-Encoding. If the text has lines longer than the value
431 of -maxunencoded (which defaults to 78) then the text is encoded using
432 the quoted-printable encoding.
433
434 The -headerencoding switch will indicate which algorithm to use when
435 encoding any message headers that contain 8-bit characters. The valid
436 arguments are base64 for base-64 encoding, quoted for quoted-printable
437 encoding, and utf-8 which requires that all 8-bit header field bodies
438 be encoded as UTF-8 (RFC 6530) and that the message be sent to a SMTP
439 server that supports SMTPUTF8 (RFC 6531). The -autoheaderencoding
440 switch instructs mhbuild to automatically pick the encoding, either
441 base64 or quoted-printable, that results in a shorter encoded string.
442
443 Putting this all together, here is an example of a more complex message
444 draft, which will expand into a multipart/mixed message containing five
445 parts:
446
447 To: nobody@nowhere.org
448 cc:
449 Subject: Look and listen to me!
450 --------
451 The first part will be text/plain
452 #<text/enriched
453 The second part will be text/enriched
454 #
455 This third part will be text/plain
456 #audio/basic [silly giggle] \
457 |raw2audio -F < /usr/lib/sounds/giggle.au
458 #image/gif [photo of foobar] \
459 /home/foobar/lib/picture.gif
460
461 Transfer Encodings
462 After mhbuild constructs the new MIME message by parsing directives,
463 including files, etc., it scans the contents of the message to deter‐
464 mine which transfer encoding to use. It will check for 8-bit data,
465 long lines, spaces at the end of lines, and clashes with multipart
466 boundaries. It will then choose a transfer encoding appropriate for
467 each content type.
468
469 Invoking mhbuild
470 Typically, mhbuild is invoked by the whatnow program. This command
471 will expect the body of the draft to be formatted as an mhbuild compo‐
472 sition file. Once you have composed this input file using a command
473 such as comp, forw, or repl, you invoke mhbuild at the “What now”
474 prompt with
475
476 What now? mime
477
478 prior to sending the draft. This will cause whatnow to execute mhbuild
479 to translate the composition file into MIME format.
480
481 Normally it is an error to invoke mhbuild on a file that is already in
482 MIME format. The -auto switch will cause mhbuild to exit without error
483 if the input file already has valid MIME headers. The use of -auto
484 also enables the -nodirectives switch.
485
486 Finally, you should consider adding this line to your profile:
487
488 lproc: show
489
490 This way, if you decide to list after invoking mime, the command
491
492 What now? list
493
494 will work as you expect.
495
496 The -dist switch is intended to be used by dist. It will cause mhbuild
497 to not generate any MIME headers in the composition file (such as
498 “MIME-Version” or “Content-Type”), but it will still encode message
499 headers according to RFC 2047.
500
501 User Environment
502 Because the environment in which mhbuild operates may vary for a user,
503 mhbuild will look for the environment variable MHBUILD. If present,
504 this specifies the name of an additional user profile which should be
505 read. Hence, when a user logs in on a particular machine, this envi‐
506 ronment variable should be set to refer to a file containing defini‐
507 tions useful on that machine.
508
509 Finally, mhbuild will attempt to consult
510
511 /etc/nmh/mhn.defaults
512
513 if it exists.
514
515 See "Profile Lookup" in mh-profile(5) for the profile search order, and
516 for how duplicate entries are treated.
517
518 Syntax of Composition Files
519 The following is the formal syntax of a mhbuild “composition file”.
520
521 body ::= 1*(content | EOL)
522
523 content ::= directive | plaintext
524
525 directive ::= "#" type "/" subtype
526 0*(";" attribute "=" value)
527 [ "(" comment ")" ]
528 [ "<" id ">" ]
529 [ "[" description "]" ]
530 [ "{" disposition "}" ]
531 [ "*8bit" | "*qp" | "*b64" ]
532 [ filename ]
533 EOL
534
535 | "#@" type "/" subtype
536 0*(";" attribute "=" value)
537 [ "(" comment ")" ]
538 [ "<" id ">" ]
539 [ "[" description "]" ]
540 [ "{" disposition "}" ]
541 [ "*8bit" | "*qp" | "*b64" ]
542 external-parameters
543 EOL
544
545 | "#forw"
546 [ "<" id ">" ]
547 [ "[" description "]" ]
548 [ "{" disposition "}" ]
549 [ "+"folder ] [ 0*msg ]
550 EOL
551
552 | "#begin"
553 [ "<" id ">" ]
554 [ "[" description "]" ]
555 [ "{" disposition "}" ]
556 [ "alternative"
557 | "parallel"
558 | something-else ]
559 EOL
560 1*body
561 "#end" EOL
562
563 plaintext ::= [ "Content-Description:"
564 description EOL EOL ]
565 1*line
566 [ "#" EOL ]
567
568 | "#<" type "/" subtype
569 0*(";" attribute "=" value)
570 [ "(" comment ")" ]
571 [ "[" description "]" ]
572 [ "{" disposition "}" ]
573 [ "*8bit" | "*qp" | "*b64" ]
574 EOL
575 1*line
576 [ "#" EOL ]
577
578 line ::= "##" text EOL
579 -- interpreted as "#"text EOL
580 | text EOL
581
583 mhbuild looks for additional user profile files and mhn.defaults in
584 multiple locations: absolute pathnames are accessed directly, tilde ex‐
585 pansion is done on usernames, and files are searched for in the user's
586 Mail directory as specified in their profile. If not found there, the
587 directory “/etc/nmh” is checked.
588
589 $HOME/.mh_profile The user's profile.
590 $MHBUILD Additional profile entries.
591 /etc/nmh/mhn.defaults
592 System default MIME profile entries.
593
595 Path: To determine the user's nmh directory.
596 Current-Folder: To find the default current folder.
597 mhbuild-compose-type*:
598 Template for composing contents.
599
601 mhlist(1), mhshow(1), mhstore(1)
602
603 Multipurpose Internet Mail Extensions (MIME) Part One: Format of Inter‐
604 net Message Bodies (RFC 2045)
605
606 Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types (RFC
607 2046)
608
609 Multipurpose Internet Mail Extensions (MIME) Part Three: Message Header
610 Extensions for Non-ASCII Text (RFC 2047)
611
612 Internet Message Format (RFC 5322)
613
614 MIME Parameter Value and Encoded Word Extensions: Character Sets, Lan‐
615 guages, and Continuations (RFC 2231)
616
617 Proposed Standard for Message Encapsulation (RFC 934)
618
619 Definition of the URL MIME External-Body Access-Type (RFC 2017)
620
621 Overview and Framework for Internationalized Email (RFC 6530)
622
623 SMTP Extension for Internationalized Email (RFC 6531)
624
626 -noauto
627 -autoheaderencoding
628 -contentid
629 -headers
630 -maxunencoded 78
631 -nodisposition
632 -norfc934mode
633 -noverbose
634 -realsize
635
637 -autoheaderencoding
638 -contentid
639 -headers
640 -maxunencoded 78
641 -nodisposition
642 -norfc934mode
643 -noverbose
644 -realsize
645 -nodirectives
646
647
648
649nmh-1.8 2023-02-07 MHBUILD(1)