$book = '..'?>include "$book/mh.php"; includeHeader('ovofmime.html', 'moabmi.html'); ?>
The Section MIME Header Fields introduced six content types: text, image, audio, video, message, and multipart. A multipart message is different from the other five. A multipart message has more than one part. Each part can have its own content type.
Let's start by looking at an Example, a fairly simple multipart message. This shows the MIME message as it's sent to the recipient. Luckily, you don't have to enter all this stuff to send a multipart message! A lot of it is added automatically. But going through it will help you understand what MH is doing and how the message is structured. (If you want to look ahead to the next Example, you'll see how the decoded message might look.)
Example: Sample multipart message,
From: Laura Rios <firstname.lastname@example.org> To: email@example.com Subject: Sara is two! Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Snip snip snip"Prologue: any text here is ignored by MIME mail programs
--Snip snip snip Content-Type: text/enriched; charset="us-ascii" Hi, Steve. Sara had her second birthday yesterday. Can you believe it? She is so <bold>big</bold>! Now if we can just live through the "terrible twos" for a year, <italic>sigh</italic>. Here are a few words from her. I've also scanned in a picture of her party. Tell your boss thanks for letting us keep in touch by email. Laura --Snip snip snip Content-type: audio/basic Content-transfer-encoding: base64 Content-description: Sara says "I love you, Steve" (awww) /Xr++/hoX2lqeXt8d/7z8/D5+PLw7/b+9fD09319/vz5f3j//Pz9fHp7fvrs9Wz/eH59domitted...
/////////////////y8= --Snip snip snip Content-type: image/gif Content-transfer-encoding: base64 Content-description: Cutting the cake, sort of R0lGODdhQAHIAKMAAAAAAP+2bQAAACQAAAAASEgAAAAkSEgkJG0kJJEkAABIkZFIJCRttrZtomitted...
l7Vry4B9aM+yKjifMosAADs= --Snip snip snip--Epilogue: any text here is ignored by MIME mail programs
The sample message (above) has three parts. The parts are separated by a boundary, which is specified as a parameter in the main Content-type: header field. Each part boundary starts with two dashes ( -- ). The last boundary in a message also ends with two dashes. It's important to pick a boundary that won't appear anywhere in the parts. MH chooses unique (but ugly) boundaries automatically; in this example, I used "Snip snip snip."
You can put text (the preamble) before the first boundary and more text (epilogue) after the last boundary. MIME mail readers will ignore the preamble and the epilogue, but non-MIME programs show it. So the preamble is a good place to put explanation for people who don't have MIME readers.
Each part of the message has its own header fields, called body part header fields. A plain text ASCII part doesn't need a Content-type: field.
Usually, but not always, the first part of a multipart message is text that introduces or explains the rest of the message. You can also sprinkle text parts throughout the message -- to explain the following non-text parts, for instance. A part can also have a Content-description: header field that summarizes what's in that part.
The first part of this sample message has a text/enriched content-type. Enriched text gives you some of the features of a word processor -- like boldface and italic text -- in a plain-ASCII message. For instance, <bold> starts text that should be shown boldfaced; the same token with a slash, </bold>, ends the boldfacing. The recipient's mail program justifies the text to fit the display; they may not be formatted the way you type them.
Line and paragraph breaks are handled in a clever way. To break a line of text at a particular place, leave an empty line. To end a paragraph, leave two empty lines. The enriched text reader will "eat" single empty lines to give the formatted effect you want; people with non-MIME mail programs will see the extra blank lines but should still get the idea.
The next Example shows what would happen as Steve's MH setup displays that message. (What would happen on your MH system depends on your setup. See the Chapter Making MH Work Your Way.)
Example: Sample multipart message, decoded
% show (Message inbox:34) From: Laura Rios <firstname.lastname@example.org> To: email@example.com Subject: Sara is two! (END) Part 1 text/plain 356 Press <return> to show content...Hi, Steve. Sara had her second birthday yesterday. Can you believe it? She is so big! Now if we can just live through the "terrible twos" for a year, sigh.
Here are a few words from her. I've also scanned in a picture of her party. Tell your boss thanks for letting us keep in touch by email.
Part 2 audio/basic 7200 Sara says "I love you, Steve" (awww) Press <return> to show content... ...sound plays on Steve's workstation speaker... Part 3 image/gif 57600 Cutting the cake, sort of Press <return> to show content... ...Window with color picture pops up... %
Another important kind of multipart message is multipart/alternative. It presents the same information in two or more ways, and the recipient's MUA chooses the most faithful form it can process. So, unlike other multipart message subtypes (where all parts are displayed), only one part of a multipart/alternative message is shown.
For instance, a multipart/alternative message might contain the same words in plain text, enriched text, and PostScript formats. If the recipient's MUA can display PostScript (with its assorted fonts, figures, and so on), the MUA will show that part; otherwise it will display enriched or plain text. When you compose a multipart/alternative message, the simplest format (the one closest to plain text) must come first. This rule makes it easier for someone with a non-MIME MUA to find the plain text.
Here's an example:
From: Jerry Peek <firstname.lastname@example.org> To: email@example.com Subject: New edition of "MH & xmh" covers MIME and MH-E MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaa0" Content-ID: <firstname.lastname@example.org> ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <email@example.com> We've just released the new third edition of "MH & xmh: Email for Users & Programmers." Changes include: - MIME (Multimedia) mail - The popular MH-E GNU Emacs front-end to MH ...omitted... ------- =_aaaaaaaaaa0 Content-Type: text/enriched; charset="us-ascii" Content-ID: <firstname.lastname@example.org> We've just released the new third edition of <italic>MH & xmh: Email for Users & Programmers</italic>. Changes include: <indent> - MIME (Multimedia) mail - The popular MH-E GNU Emacs front-end to MH ...omitted... ------- =_aaaaaaaaaa0 Content-Type: application/postscript Content-ID: <email@example.com> Content-Transfer-Encoding: quoted-printable %!PS-Adobe-3.0 %%Creator: groff version 1.09 ...omitted... %%Trailer end %%EOF ------- =_aaaaaaaaaa0--MH automatically created the boundaries. It added the first Content-Type: and all Content-ID: and Content-Transfer-Encoding: fields. This is the file I gave to MH to create the MIME message:
From: Jerry Peek <firstname.lastname@example.org> To: email@example.com Subject: New edition of "MH & xmh" covers MIME, exmh, and MH-E -------- #begin alternative We've just released the new third edition of "MH & xmh: Email for ...omitted... #<text/enriched We've just released the new third edition of <italic>MH & xmh: Email ...omitted... #application/postscript /u/jerry/mh-book/3rd_edition.ps #end
To find out more about MIME message composition, read the introduction in Section Sending MIME Mail and the details in Section Composing and Sending MIME Messages.
Multipart MIME messages can have a hierarchical structure like trees or outlines or UNIX directories: each part can be made of more parts. When MH shows these messages, it will work through the parts from first to last. The command mhn -list (for MH) or mhlist (for nmh-1.0 and above) shows a message structure and assigns numbers to the parts. (mhn is the MH command that processes MIME. There's much more about mhn and the corresponding nmh commands later in this book.)
The first part of the example message below is an overview. Next are two comments from the company's President Parker -- about jobs and the budget. Here's the mhn listing of message number 91:
% mhn -list 91 msg part type/subtype size description 91 multipart/mixed 272K 1 text/plain 2168 Overview of this message 2 multipart/alternative 113K 2.1 audio/basic 110K Parker re: jobs (audio) 2.2 text/plain 937 Parker re: jobs (transcript) 3 multipart/alternative 159K 3.1 audio/basic 156K Parker re: budget (audio) 3.2 text/plain 1029 Parker re: budget (transcript)As explained above, part 1 is an overview (the description of the part comes from the Content-Description: field). Part 2 and Part 3 are each two separate multipart/alternative messages; each part has the same information, first as audio and then as text. The first subpart of each part (2.1 and 3.1) are audio versions; they'll be played if your MH setup can play sound. Otherwise, parts 2.2 and 3.2 will be displayed; they have plain-text versions of the audio parts. (Note that mhn -list and mhlist don't necessarily show the parts in the same order as the original message.)
You don't have to read all of a message; you can specify the parts you want to see with a part-showing command like mhn -part 3.2 (MH) or mhshow -part 3.2 (nmh-1.0+).
Making subparts is simple if you remember that each part should be able to stand on its own. A part that's divided into subparts needs its own boundary marker. You don't have to worry about the boundary markers, though; MH will choose the right ones. Here's a look at the multipart message number 91 from the example above:
From: Clipping Service <firstname.lastname@example.org> To: email@example.com Subject: Parker on jobs and budget, 23 August 1994 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaaA" Content-ID: <firstname.lastname@example.org> ------- =_aaaaaaaaaaA Content-Type: text/plain; charset="us-ascii" Content-Description: Overview of this message This message has two sections of plain text and audio. If your mail reader can play audio, you'll hear those parts; otherwise you'll see the plain-text transcripts. ...omitted... ------- =_aaaaaaaaaaA Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaaB" ------- =_aaaaaaaaaaB Content-Type: text/plain; charset="us-ascii" Content-Description: Parker re: jobs (transcript) ...omitted... ------- =_aaaaaaaaaaB Content-Type: audio/basic Content-Description: Parker re: jobs (audio) ...omitted... ------- =_aaaaaaaaaaB-- ------- =_aaaaaaaaaaA Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaaC" ------- =_aaaaaaaaaaC Content-Type: text/plain; charset="us-ascii" Content-Description: Parker re: budget (transcript) ...omitted... ------- =_aaaaaaaaaaC Content-Type: audio/basic Content-Description: Parker re: budget (audio) ...omitted... ------- =_aaaaaaaaaaC-- ------- =_aaaaaaaaaaA--If you compare the boundaries to the mhn -list output above, you'll see how the parts and subparts are structured. The main parts (1, 2, and 3) are separated by a boundary that ends with aaaA. Parts 2 and 3, which have their own subparts, use subpart boundaries that end with aaaB and aaaC, respectively. These automatically generated boundaries also contain the string =_, which is guaranteed not to appear in any possible quoted-printable or base64 encodings.
That message was almost 300K bytes long. Sending it to 200 people around the company could use a big chunk of network capacity. MIME and MH have two ways to help with the problem of long message parts:
Of course, this won't work everywhere. Not everyone is directly connected to a network, and network "firewalls" can keep recipients from retrieving files over their connections. The mhn-access-ftp: or nmh-access-ftp: profile entry is for getting network access by other methods.