NAME *MIME::Mini* - Minimal code to parse/create mbox files and mail messages SYNOPSIS use MIME::Mini ':all'; or: use MIME::Mini qw( formail mail2str mail2multipart mail2singlepart mail2mbox insert_header append_header replace_header delete_header insert_part append_part replace_part delete_part header headers header_names param mimetype encoding filename body message parts newparam newmail ); # Parse mbox file, doing something with each mail message formail(sub { <> }, sub { my $mail = shift; ...; }) # Create an email with text/plain, image/png, and message/rfc822 attachments my $mail = newmail ( To => 'you@there.com', From => 'me@here.com', Subject => 'test', parts => [ newmail(body => "hi\n"), newmail(body => $png, type => 'image/png', filename => 'hi.png'), newmail(message => newmail(qw(To to@you From from@me body hi"))) ] ); print mail2str($mail); DESCRIPTION *MIME::Mini* is a collection of functions that parse and produce mailbox files and individual mail messages. It started out as *minimail*, a non-module cut-and-paste version, intended to be compact enough to cut and paste directly into perl scripts that don't want to require non-standard perl modules. *MIME::Mini* is for people that prefer a CPAN module. It is intended to be yet another alternative to *MIME-tools*. *MIME-tools* does things that this code doesn't (such as uuencode and binhex decoding). And *MIME::Mini* does things that *MIME-tools* doesn't such as reading and writing mailbox files correctly (repairing incorrectly formatted ones along the way), and transparently unravelling "winmail.dat" attachments (aka *MS-TNEF*). *MIME::Mini* is much smaller (about 3% of the size of *MIME-tools* and the other modules it requires, and about 20% of the size of *MIME-Lite* (which doesn't parse)), and so takes much less time during program start up. FUNCTIONS formail(sub { <> }, sub { $mail = shift }) Parses a mailbox or a mail message. Calls the first function argument to retrieve input lines and calls the second function argument with every mail message found. Terminates when the first argument returns undef or when the second function returns false. Quoted "From_" lines are unquoted. mail2str($mail) Returns a string version of a mail message. If the mail message includes a mailbox header, lines in the body starting with "From_" are quoted and the string result will definitely be terminated with a blank line. This means that mailbox files with blank lines missing between mail messages and with unquoted "From_" lines will be automatically repaired with the code below (Incidentally, malformed nested multipart body parts are also repaired). formail(sub { <> }, sub { print mail2str(shift) }); mail2multipart($mail) Converts a singlepart mail message into a multipart mail message with a single body part (i.e. the body of the original mail message). Returns the mail message. Does nothing to mail messages that are already multipart mail messages. mail2singlepart($mail) Converts a multipart mail message with a single body part into a singlepart mail message whose body is the original body part. Returns the mail message. Does nothing to mail messages that are already singlepart mail messages or multipart mail messages with multiple parts. Acts recursively. mail2mbox($mail) Converts a mail message into an mailbox item. Does nothing to mail messages that are already mailbox items. This affects the result of *mail2str()*. insert_header($mail, $header[, $language[, $charset]]) Inserts a new mail header before any existing mail headers. If the header contains non-ascii characters, it will be encoded in accordance with RFC2047. If the *$language* and *$charset* parameters are not supplied, they default to "en" and "iso-8859-1" (if possible, "utf-8" otherwise), respectively. append_header($mail, $header[, $language[, $charset]]) Appends a new mail header after any existing mail headers. replace_header($mail, $header[, $language[, $charset]]) Replaces all instances of a mail header with a new mail header. delete_header($mail, $header, $recurse) Deletes all headers that match the *$header* pattern. If the *$recurse* parameter is provided and non-zero, matching headers in internal body parts will also be deleted. insert_part($mail, $part, $index) Inserts the given body part at the given index. The *$part* parameter must have been produced by *formail()* or *newmail()*. The *$mail* parameter must already be a multipart mail message. append_part($mail, $part) Appends the given body part. replace_part($mail, $part, $index) Replaces the body part at the given index with the given body part. delete_part($mail, $index) Deletes the body part at the given index. header($mail, $header) Returns a list of values of headers with the given name. RFC2822 comments are removed. If any of the values contain RFC2047 encoded words (i.e. "=?charset?[qb]?...?="), they are decoded, and the bytes in the given charset (e.g., "us-ascii", "iso-8859-*", "utf-8") are then decoded into "characters" (i.e., unicode codepoints). They are also unfolded. If this is not what you want, use $mail->{header} or $mail->{headers} directly. headers($mail) Returns a list of all complete headers with decoding and unfolding performed as with *header()*. header_names($mail) Returns a list of the names of headers present in the given mail message. param($mail, $header, $param) Returns the value of the given parameter of the given MIME header of the given mail message. *header()* is used for RFC2047 decoding. If the parameter has been split or encoded in accordance with RFC2231 (i.e. "param1*0="a" param1*1="b" param2*="charset'lang'%63""), it is decoded (if "us-ascii" or "iso-8859-*" or "utf-8") and reassembled. mimetype($mail, $parent) Returns the declared or default mimetype of the given mail message or body part. Returns "octet/application" when the encoding is invalid. encoding($mail) Returns the declared or implied encoding of the given mail message or body part. filename($part) Returns the RFC2183 filename of the given body part. Uses *param()* to perform any decoding that might be necessary. Also removes any directory component of the filename and replaces any unfriendly characters with dash characters. body($mail) Returns the decoded body of the given mail message or body part. Must not be called on a multipart mail message or a mail message whose mimetype is "message/rfc822". message($mail) Returns the message inside the given mail message whose mimetype is "message/rfc822". Must not be called on a multipart message or a mail message whose mimetype is not "message/rfc822". parts($mail[, $parts]) When no *$parts* parameter is given, returns a reference to an array of body parts in the given multipart message. When the *$parts* parameter is given, it is a reference to an array of body parts, and it will replace the existing body parts. Must not be called on a singlepart mail message. newparam($name, $value[, $language[, $charset]]]) Creates a MIME header parameter, possibly split and encoded in accordance with RFC2231. Returns a string that looks like "; name=value" which can be used as part of the *$header* argument in functions like *append_header()* and as part of any header value in the function *newmail()*. If the value contains non-ascii characters, and the *$language* and *$charset* parameters are not supplied, they default to "en" and "utf-8" or "iso-8859-1", respectively. newmail(...) Creates a new mail message based on the given arguments (which take the form of a hash). It is not necessary to supply all information. Anything that needs to be added will be added automatically. The important parameters are: [A-Z]* - Arbitrary mail headers: e.g. From To Subject type - Content-Type: e.g. image/png charset - Content-Type's charset parameter: e.g. iso-8859-1 encoding - Content-Transfer-Encoding: e.g. base64 filename - Content-Disposition's filename parameter body - body of the message (don't use with parts or message) parts - array-ref of parts (don't use with body or message) message - body of message/rfc822 message (don't use with body or parts) mbox - Mbox From_ header Supplying *body* implies "text/plain". Supplying *parts* implies "multipart/mixed". Supplying *message* implies "message/rfc822". Default *disposition* is "inline" for "text/*" and "message/rfc822", or "attachment" for all other types. The default *charset* is "us-ascii" when *body* contains only ASCII bytes. Otherwise, it is "utf-8" when *body* is a valid UTF-8 byte sequence. Otherwise, it is your local (non-utf8) charset, or "iso-8859-1". Default *encoding* is determined from the type and nature of the mail message and its data. You shouldn't have to supply *encoding* unless you want to create messages with "8bit" encoding. If the mail message really is a mail message, and not just a body part, "Date", "MIME-Version" and "Message-ID" headers are automatically included if they have not been supplied by the caller. Less important parameters are: disposition - Content-Disposition: i.e. inline or attachment created - Content-Disposition's creation-date parameter modified - Content-Disposition's modification-date parameter read - Content-Disposition's read-date parameter size - Content-Disposition's size parameter description - Content-Description language - Content-Language duration - Content-Duration location - Content-Location base - Content-Base features - Content-Features alternative - Content-Alternative id - Content-ID md5 - Content-MD5 Note: If you supply "filename" but not "body" (or "message" or "parts"), and the filename refers to a readable file, then the following parameters will be determined automatically: "body", "modified", "read", "size". The rest of the less important parameters are just shortcuts for standard MIME headers. There is no support beyond that for any of them. STRUCTURE A mail message (or body part) is a hash containing some of the following entries: mbox - mailbox From_ header warn - parser errors in the form: X-Warning: ... headers - arrayref of mail headers in order of appearance header - hashref by name of arrayrefs of mail headers body - text of singlepart mail message mime_type - mimetype of the mail message or body part mime_parts - arrayref of mail messages (body parts) mime_message - message of a message/rfc822 mail message mime_boundary - boundary for a multipart mail message mime_preamble - any text before the first multipart boundary mime_epilogue - any text after the last multipart boundary mime_prev_boundary - saved boundary of message after mail2singlepart mime_prev_preamble - saved preamble of message after mail2singlepart mime_prev_epilogue - saved epilogue of message after mail2singlepart Note that *body*, *mime_parts* and *mime_message* are mutually exclusive and that *mime_type* only exists when *mime_parts* or *mime_message* exist. EXAMPLES Parsing example: Repair mailbox files formail(sub { <> }, sub { print mail2str(shift) }); Building example: A mail message with attachments print mail2str(newmail( To => 'you@there.com', From => 'me@here.com', Subject => 'test', parts => [ newmail(body => "hi\n"), newmail(body => $png, type => 'image/png', filename => 'hi.png'), newmail(message => newmail(qw(To to@you From from@me body hi"))) ])); CAVEAT The *header()* and *headers()* functions automatically decode RFC2047 encoded headers. This is an attempt to satisfy the following requirement in RFC2047: The program must be able to display the unencoded text if the character set is "US-ASCII". For the ISO-8859-* character sets, the mail reading program must at least be able to display the characters which are also in the ASCII set. Rather than discarding "iso-8859-*" characters that are not also "us-ascii", *header()* and *headers()* decode them to "characters" (unicode codeponts) in perl's internal string format. This is arguably more useful, but knowledge of the original character set is lost. Hopefully, that isn't important. But actually "displaying" these characters will require the client application to encode the headers appropriately for the local system. The original, encoded headers can be accessed directly via "$mail->{headers}" which is a reference to an array of raw encoded headers. SEE ALSO RFC2822, RFC2045, RFC2046, RFC2047, RFC2231, RFC2183 (also RFC3282, RFC3066, RFC2424, RFC2557, RFC2110, RFC3297, RFC2912, RFC2533, RFC1864, RFC2387, RFC2912, RFC2533, RFC2387, RFC2076). The mailbox format used is the mboxrd format described in "http://www.qmail.org/man/man5/mbox.html". AUTHOR 20230508 raf COPYRIGHT AND LICENSE Copyright (C) 2005-2007, 2023 raf This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.