Next: , Previous: , Up: Library   [Contents][Index]

5.19 Message Functions

The functions described below retrieve information from RFC822 messages. The message to operate upon is identified by its descriptor, an integer number returned by the previous call to mailbox_get_message (see mailbox_get_message) or current_message (see current_message) function. The maximum number of message descriptors is limited by 1024. You can change this limit using the max-open-messages runtime configuration statement (see max-open-messages).

Built-in Function: number message_size (number nmsg)

Return the size of the message nmsg, in bytes. Notice, that if nmsg refers to current message (see current_message), the returned value is less than the size seen by the MTA, because mailfromd recodes CR-LF sequences to LF, i.e. removes carriage returns (ASCII 13) occurring before line feeds (ASCII 10. To obtain actual message length as seen by the MTA, add the number of lines in the message:

  set actual_length message_size(nmsg) + message_lines(nmsg)
Built-in Function: boolean message_body_is_empty (number nmsg)

Returns true if the body of message nmsg has zero size or contains only whitespace characters. If the ‘Content-Transfer-Encoding’ header is present, it is used to decode body before processing.

Built-in Function: void message_close (number nmsg)

Close the message identified by descriptor nmsg.

Built-in Function: number message_lines (number nmsg)

Return total number of lines in message nmsg. The following relation holds true:

message_lines(x) = message_body_lines(x)
                         + message_header_lines(x) + 1
Built-in Function: string message_read_line (number nmsg)

Read and return next line from the message nmsg. If there are no more lines to read, raise the eof exception.

Use message_rewind to rewind the message stream and read its contents again.

Built-in Function: void message_rewind (number nmsg)

Rewind the stream associated with message referred to by descriptor nmsg.

Built-in Function: number message_from_stream (number fd; string filter_chain)

Converts contents of the stream identified by fd to a mail message. Returns identifier of the created message.

Optional filter_chain supplies the name of a Mailutils filter chain, through which the data will be passed before converting. See http://mailutils.org/wiki/Filter_chain, for a description of filter chains.

Built-in Function: void message_to_stream (number fd, number nmsg; string filter_chain)

Copies message nsmg to stream descriptor fd. The descriptor must be obtained by a previous call to open.

Optional filter_chain supplies the name of a Mailutils filter chain, through which the data will be passed before writing them to fd. See http://mailutils.org/wiki/Filter_chain, for a description of filter chains.


Next: , Up: Message functions   [Contents][Index]

5.19.1 Header functions

Built-in Function: number message_header_size (number nmsg)

Return the size, in bytes of the headers of message nmsg. See the note to the message_size, above.

Built-in Function: number message_header_lines (number nmsg)

Return number of lines occupied by headers in message nmsg.

Built-in Function: number message_header_count (number nmsg, [string name])

Return number of headers in message nmsg.

If name is supplied, count only headers with that name.

Built-in Function: string message_find_header (number nmsg, string name [, number idx])

Return value of header name from the message nmsg. If the message contains several headers with the same name, optional parameter idx may be used to select one of them. Headers are numbered from ‘1’.

If no matching header is not found, the not_found exception is raised. If another error occurs, the failure exception is raised.

The returned string is a verbatim copy of the message contents (except for eventual CR-LF -> LF translation, see above). You might need to apply the unfold function to it (see unfold).

Built-in Function: string message_nth_header_name (number nmsg, number n)

Returns the name of the nth header in message nmsg. If there is no such header, e_range exception is raised.

Built-in Function: string message_nth_header_value (number msg, number n)

Returns the value of the nth header in message nmsg. If there is no such header, e_range exception is raised.

Built-in Function: boolean message_has_header (number nmsg, string name [, number idx])

Return true if message nmsg contains header with the given name. If there are several headers with the same name, optional parameter idx may be used to select one of them.


Next: , Previous: , Up: Message functions   [Contents][Index]

5.19.2 Message body functions

Built-in Function: number message_body_size (number nmsg)

Return the size, in bytes, of the body of message nmsg. See the note to the message_size, above.

Built-in Function: number message_body_lines (number nmsg)

Return number of lines in the body of message referred to by descriptor nmsg.

Built-in Function: void message_body_rewind (number nmsg)

Rewind the stream associated with the body of message referred to by descriptor nmsg.

A call to message_body_read_line (see below) after calling this function will return the first line from the message body.

Built-in Function: string message_read_body_line (number nmsg)

Read and return next line from the body of the message nmsg. If there are no more lines to read, raise the eof exception.

Use message_body_rewind (see above) to rewind the body stream and read its contents again.

Built-in Function: void message_body_to_stream (number fd, number nmsg; string filter_pipe)

Copies the body of the message nsmg to stream descriptor fd. The descriptor must be obtained by a previous call to open.

Optional filter_pipe supplies a sequence of Mailutils filters, through which the data will be passed before writing them to fd. See Filtering functions, for a discussion of filter pipe syntax.

In addition to filters described in See Filters, two special filters are provided for use with this function: mimedecode and charset. The mimedecode filter instructs the function to decode the message body by reverting the encoding specified by its Content-Transfer-Encoding header. It is normally used as the very first filter in chain. The charset filter recodes the message body from it original character set to the character set specified as its argument.

See mimedecode, for a detailed discussion of this feature.


Next: , Previous: , Up: Message functions   [Contents][Index]

5.19.3 MIME functions

Built-in Function: boolean message_is_multipart (number nmsg)

Return true if message nmsg is a multipart (MIME) message.

Built-in Function: number message_count_parts (number nmsg)

Return number of parts in message nmsg, if it is a multipart (MIME) message. If it is not, return ‘1’.

Use message_is_multipart to check whether the message is a multipart one.

Built-in Function: number message_get_part (number nmsg, number n)

Extract nth part from the multipart message nmsg. Numeration of parts begins from ‘1’. Return message descriptor referring to the extracted part. Message parts are regarded as messages, so any message functions can be applied to them.

Built-in Function: string message_content_type (number nmsg)

Returns content type for the message nmsg. The returned string is composed of content type and subtype, delimited by slash.

If nmsg is not a multipart message, the function returns ‘text/plain’.

Several functions are provided for decoding multi-part messages. Such decoding is governed by Content-Transfer-Encoding and Content-Type headers of the message. The Content-Transfer-Encoding header defines the method used to encode the message. The value of Content-Type header is used to determine the character set the body is written in.

Basic MIME decoding facilities are provided by the built-in function message_body_to_stream, described in the previous subsection. To instruct it to decode the content, pass it the filter_chain argument beginning with the word mimedecode. The usual sequence is:

set fd open("> outfile")
message_body_to_stream(fd, msg, "mimedecode")

To ensure that the produced stream is represented in a specific character set, use the charset special filter. Its argument is the name of the character set to recode the text to:

set fd open("> outfile")
message_body_to_stream(fd, msg, "mimedecode|charset(utf-8)")

The charset filter takes also an optional second argument – a fallback method, specifying what to do when an octet sequence is encountered that cannot be represented in the requested character set. Possible values for this argument are:

none

Stop further conversion and signal the e_ilseq exception.

copy-pass

Copy the offending character to the output verbatim.

copy-octal

Represent the offending character as a C octal sequence (‘\nnn’, where n is an octal digit). This is the default.

To decode a particular part of the message, first extract it using the message_get_part function. Recall that message parts are messages as well, and as such can be passed to message_body_to_stream. For example, the following code fragment extracts all top-level parts of a multi-part message to files named ‘part.N’:

if message_is_multipart(msg)
  set n message_count_parts(msg)
  loop for set i 1, while i <= n, set i i + 1
  do
    set fd open("> part.%i")
    message_body_to_stream(fd, message_get_part(msg, i), "mimedecode")
    close(fd)
  done
fi

The mime.mfl module provides additional functions for decoding multi-part messages:

Library Function: number message_body_decode (number nmsg; string charset, string fallback)

Decodes the body of the message (or message part) nmsg, optionally converting it to the given charset. The fallback argument specifies what to do if a byte sequence cannot be converted to the specified character set. See iconv fallback, for a detailed discussion.

The function returns a descriptor of the I/O stream that contains the decoded material. See I/O functions for a discussion of functions available for reading from it.

Library Function: number message_part_decode(number nmsg, number part; string charset, string fallback)

Decodes the body of the given part of a MIME message nmsg. The argument part is a 1-based index of the part in the message. Optional arguments charset and fallback have the same meaning as in message_body_decode (see above).

Returns a descriptor of the I/O stream that contains the decoded material.

This function is equivalent to:

message_body_decode(message_get_part(nmsg, part, charset,
                    fallback))

Previous: , Up: Message functions   [Contents][Index]

5.19.4 Message digest functions

Message digests are specially formatted messages that contain certain number of mail messages, encapsulated using the method described in RFC 934. Such digests are often used in mailing lists to reduce the frequency of sending mails. Messages of this format are also produced by the forward function in most MUA’s.

The usual way to handle a message digest in MFL is to convert it first to a MIME message, and then to use functions for accessing its parts (see MIME functions).

Built-in Function: number message_burst (number nmsg ; number flags)

Converts the message identified by the descriptor nmsg to a multi-part message. Returns a descriptor of the created message.

Optional argument flags controls the behavior of the bursting agent. It is a bitwise OR of error action and bursting flags.

Error action defines what to do if a part of the digest is not in RFC822 message format. If it is ‘BURST_ERR_FAIL’ (the default), the function will raise the ‘e_format’ exception. If onerr is ‘BURST_ERR_IGNORE’, the improperly formatted part will be ignored. Finally, the value ‘BURST_ERR_BODY’ instructs message_burst to create a replacement part with empty headers and the text of the offending part as its body.

Bursting flags control various aspects of the agent behavior. Currently only one flag is defined, ‘BURST_DECODE’, which instructs the agent to decode any MIME parts (according to the ‘Content-Transfer-Encoding’ header) it encounters while bursting the message.

Parts of a message digest are separated by so-called encapsulation boundaries, which are in essence lines beginning with at least one dash followed by a non-whitespace character. A dash followed by a whitespace serves as a byte-stuffing character, a sort of escape for lines which begin with a dash themselves. Unfortunately, there are mail agents which do not follow byte-stuffing rules and pass lines beginning with dashes unmodified into resulting digests. To help handle such cases a global variable is provided which controls how much dashes should the line begin with for it to be recognized as an encapsulation boundary.

Built-in variable: number burst_eb_min_length

Minimal number of consecutive dashes an encapsulation boundary must begin with.

The default is 2.

The following example shows a function which saves all parts of a digest message to separate disk files. The argument orig is a message descriptor. The resulting files are named by concatenating the string supplied by the stem argument and the ordinal number (1-based) of the message part.

func burst_digest(number orig, string stem)
do
  number msg message_burst(orig)
  number nparts message_count_parts(msg)

  loop for number i 1,
       while i <= nparts,
       set i i + 1
  do
    number part message_get_part(msg, i)
    number out open(sprintf('>%s%02d', stem, i))
    message_to_stream(out, part)
  done
  message_close(msg)
done

Previous: , Up: Message functions   [Contents][Index]