NAME Mail::Message -- manipulate mail messages (parse, analyze and compose) SYNOPSIS To parse the stdin and print it, use Mail::Message; my $m = Mail::Message->parse({ fh => *STDIN{IO} }); $m1->print; to parse file $filename, use Mail::Message; my $m = Mail::Message->parse({ file => $filename }); to make a message of the body part, my $msg = new Mail::Message { boundary => $mime_boundary, data_type => $data_type_defined_in_header_content_type, data => \$message_body, }; Please specify SCALAR REFERENCE as "data". To make a message of the header, my $msg = new Mail::Message { boundary => $mime_boundary, data_type => 'text/rfc822-headers', data => $header, }; Please specify "Mail::Header" or "FML::Header" object as "data". TODO: It is useful to C the message but inconvenient to build a message from scratch. DESCRIPTION OVERVIEW "A mail message" has the data to send and some delivery information in the header. "Mail::Message" objects construct a chain of header and data. "Mail::Message" object holds them and other control information such as the reference to the next "Mail::Message" object, et. al. "Mail::Message" provides useful functions to analyze a mail message. such as to analyze MIME information, to check and get information on message (part) size et. al. It can handle MIME multipart. "Mail::Message" also can compose a multipart message in primitive way. It is useful for you to use "Mail::Message::Compose" class to handle MIME multipart in more clever way. It is an adapter for "MIME::Lite" class. INTERNAL REPRESENTATION One mail consists of a message or messages. They are all plain text or a set of plain text, images, html and so on. "Mail::Message" is a chain which represents a set of several kinds of messages. Elements of one object chain are bi-directional among them. For example, a MIME/multipart message is a chain of message objects such as undef -> mesg1 -> mesg2 -> mesg3 -> undef <- <- <- <- To describe such a chain, a message object consists of bi-directional object chains. Described below, "MIME delimiter" is also treated as a virtual message for convenience. $message = { version => 1.0, next => \$next_message, prev => \$prev_message, base_data_type => "text/plain", mime_version => 1.0, header => $header, data_type => "text/plain", data => \$message_body, # optional. if unknonw, speculate it from header info. charset => "iso-2022-jp", encoding => "7bit", data_info => \$information, } key value ----------------------------------------------------- version Mail::Message object version next pointer to the next message prev pointer to the previous message base_data_type type of the whole message mime_version MIME version header MIME header of the part data_type type of each message (part) data reference to the data (that is, memory area) data_info reference to miscellaneous information. Only rfc822/message type uses "data_info" field. "header" holds MIME content header of the corresponding message. The default value for each key follows: key value ----------------------------------------------------- version 1.0 next undef prev undef base_data_type text/plain mime_version 1.0 header undef data_type text/plain data '' data_info '' HOW TO PARSE plain/text If the message is just a plain/text, which is usual, internal representation follows: i base_data_type data_type ---------------------------------------------------------- 0: text/plain text/plain where the "i" is the "i"-th element of a chain. multipart/... Consider the following multipart message. Content-Type: multipart/mixed; boundary="boundary" ... preamble ... --boundary Content-Type: text/plain; charset="iso-2022-jp" --boundary Content-Type: image/gif; --boundary-- ... trailor ... "Mail::Message" parser interpetes it as follows: base_data_type data_type ---------------------------------------------------------- 0: multipart/mixed multipart.preamble 1: multipart/mixed multipart.delimiter 2: multipart/mixed text/plain 3: multipart/mixed multipart.delimiter 4: multipart/mixed image/gif 5: multipart/mixed multipart.close-delimiter 6: multipart/mixed multipart.trailer "multipart.something" is a faked type to treat both real content, MIME delimiters and others in the same Mail::Message framework. METHODS to create a message object new($args) constructor which makes "one" message object. In almost cases, new() is used to make a message object, which is a part of one mail message. We use this framework to make a header object by specifying data_type => text/rfc822-headers, data => Mail::Header or FML::Header object, in $args (HASH REFERENCE). Pay attention the type of "data". "WARNING:" It is useful to treate the message header and body in separate way when we compose the message by sequential attachments. If you build a message by scratch, you must compose a header object. When you "parse()" to a mail, you will get the whole set of a chain and a body message. dup_header() duplicate a message chain. Precisely speaking, it duplicates only the header object but not duplicate body part. So, the next object of the duplicated header, "dup_header0" in the following figure, is the first body part "part1" of the origianl chain. header0 ----> part1 -> part2 -> ... A | dup_header0 --- METHODS TO PARSE parse($args) read data from file descriptor $fd and parse it to the mail header and the body. parse({ fd => $fd, }); You can specify file not file descriptor. parse({ file => $file, }); prepend($data) prepend the message to the object chain. append($data) append the message to the object chain. whole_message_header() return Mail::Header object corresponding to the header part for the object $self. whole_message_body() alias of "whole_message_body_head()". whole_message_body_head() return the first or the head Mail::Message object in a chain for the body part of the message $self. whole_message_as_str($args) To extract the first 2048 bytes in the whole message (body), specify the following parameters in $args. $args = { start => 0, end => 2048, type => 'exact', }; By default, parameters $args = { start => 0, end => 2048, indent => ' ', }; It returns the text until the first null line over the first 2048 bytes. whole_message_header_data_type() return the "type" string. It is the whole message type which is speculated from header "Content-Type:". METHODS to manipulate a chain find($args) return the first "Mail::Message" object with the specified attrribute. You can specify "data_type" in $args HASH REFERENCE. For example, $m = $msg->find( { data_type => 'text/plain' } ); $m is the first "text/plain" object in a chain of $msg object. This method is used for the exact match. $m = $msg->find( { data_type_regexp => 'text' } ); $m is the first "text/*" object in a chain of $msg object. __head_message() no argument. It return the head object of a chain of "Mail::Message" objects. Usually it is the header part. __last_message() no argument. It return the last object of a chain of "Mail::Message" objects. Usually it is the last message in the body part. _next_message_is( $obj ) The next part of $self object is $obj. _prev_message_is( $obj ) The previous part of $self object is $obj. METHODS to print print( $fd ) print out a chain of messages to the file descriptor $fd. If $fd is not specified, STDOUT is used. set_print_mode(mode) set print mode to "mode". The available is "raw" or "smtp". reset_print_mode() reset print() mode. It sets the mode to be "raw". METHODS to manipulate a multipart message build_mime_multipart_chain($args) build a mime message by scratch. This may be obsolete since we use "MIME::Lite" to build a mime message now. parse_and_build_mime_multipart_chain($args) parse the multipart mail. Actually it calculates the begin and end offset for each part of content, not split() and so on. "new()" calls this routine if the message looks MIME multipart. build_mime_header($args) make a fundamental mime header fields and return it. CREATE MESSAGE SUMMARY outline($params) one_line_summary($params) return one line summary. summary($params) return short summary. METHODS (UTILITY FUNCTIONS) size() return the message size of this object. is_empty() return this message has empty content or not. is_multipart() return this message has empty content or not. charset() return charset. encoding_mechanism() return encoding type for specified Mail::Message not whole mail. The return value is one of base64, quoted-printable or undef. offset_pair() return offset information in the data. return value is ARRAY ($offset_begin, $offset_end) on the Mail::Message object. header_size() get whole header size for this object ($self) body_size() get whole body size for this object ($self) envelope_sender() return reverse_path for this object ($self) data_type() return the data type of the given message object ($self) not the whole mail message. num_paragraphs() same as paragraph_total(). paragraph_total() return the number of paragraphs in the message ($self). nth_paragraph($n) return the string of $n-th paragraph. For example, nth_paragraph(1) returns the 1st paragraph. The syntax is usual not C language flabour. message_fields() return header string in the message content. It is mie header for whole mail or each message of MIME/multipart. message_text($size) get body string in the message content, which is the whole mail (plain text) or body part of a block of multipart. If $size is specified, return the first $size bytes in the body. find_first_plaintext_message($args) return the Messages object for the first "plain/text" message in a chain. For example, $m = $msg->find_first_plaintext_message(); $body = $m->message_text(); where $body is the mail body (string). message_chain_as_array_ref() return the chain of message objects as ARRAY_REF of OBJ's like this: [ Mail::Message, Mail::Message, ... ] set_log_function() internal use. set CODE REFERENCE to the log function unset_log_function() unset CODE REFERENCE used as log functions. data_type_list() show the list of data_types in the chain order. This is defined for debug and removed in the future. UTILITY for Accept-Language: accept_language_list() return list of languages to accept as ARRAY_REF such as [ 'ja', 'en', '*' ] but [ '*' ] if Accept-Language: unavailable. METHODS to make a whole mail message Please use "Mail::Message::Compose" class. This is an adapter for "MIME::Lite", so your request is forwarded to "MIME::Lite" class :-) use Mail::Message::Compose; $msg = Mail::Message::Compose->new( From => 'fukachan@fml.org', To => 'rudo@nuinui.net', Cc => 'kenken@nuinui.net', Subject => 'help', Type => 'text/plain', Path => 'help', ); $msg->attr('content-type.charset' => 'us-ascii'); # show message; print $msg->as_string; APPENDIX (RFC2046 Appendix A) Appendix A -- Collected Grammar This appendix contains the complete BNF grammar for all the syntax specified by this document. By itself, however, this grammar is incomplete. It refers by name to several syntax rules that are defined by RFC 822. Rather than reproduce those definitions here, and risk unintentional differences between the two, this document simply refers the reader to RFC 822 for the remaining definitions. Wherever a term is undefined, it refers to the RFC 822 definition. boundary := 0*69 bcharsnospace bchars := bcharsnospace / " " bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" / "+" / "_" / "," / "-" / "." / "/" / ":" / "=" / "?" body-part := <"message" as defined in RFC 822, with all header fields optional, not starting with the specified dash-boundary, and with the delimiter not occurring anywhere in the body part. Note that the semantics of a part differ from the semantics of a message, as described in the text.> close-delimiter := delimiter "--" dash-boundary := "--" boundary ; boundary taken from the value of ; boundary parameter of the ; Content-Type field. delimiter := CRLF dash-boundary discard-text := *(*text CRLF) ; May be ignored or discarded. encapsulation := delimiter transport-padding CRLF body-part epilogue := discard-text multipart-body := [preamble CRLF] dash-boundary transport-padding CRLF body-part *encapsulation close-delimiter transport-padding [CRLF epilogue] preamble := discard-text transport-padding := *LWSP-char ; Composers MUST NOT generate ; non-zero length transport ; padding, but receivers MUST ; be able to handle padding ; added by message transports. CODING STYLE See "http://www.fml.org/software/FNF/" on fml coding style guide. AUTHOR Ken'ichi Fukamachi COPYRIGHT Copyright (C) 2001,2002,2003,2004,2005,2006 Ken'ichi Fukamachi All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. HISTORY Mail::Message first appeared in fml8 mailing list driver package. See "http://www.fml.org/" for more details.