Mailfromd Manual (split by section):   Section:   Chapter:FastBack: Library   Up: Library   FastForward: Using MFL Mode   Contents: Table of ContentsIndex: Concept Index

5.23 I/O functions

MFL provides a set of functions for writing to disk files, pipes or sockets and reading from them. The idea behind them is the same as in most other programming languages: first you open the resource with a call to open which returns a descriptor i.e. an integer number uniquely identifying the resource. Then you can write or read from it using this descriptor. Finally, when the resource is no longer needed, you can close it with a call to close.

The number of available resource descriptors is limited. The default limit is 1024. You can tailor it to your needs using the max-streams runtime configuration statement. See max-streams, for a detailed description.

Built-in Function: number open (string name)

The name argument specifies the name of a resource to open and the access rights you need to have on it. The function returns a descriptor of the opened stream, which can subsequently be used as an argument to other I/O operations.

First symbols of name determine the type of the resource to be opened and the access mode:

>

The rest of name is a name of a file. Open the file for read-write access. If the file exists, truncate it to zero length, otherwise create the file.

>>

The rest of name is a name of a file. Open the file for appending (writing at end of file). The file is created if it does not exist.

|

Treat the rest of name as the command name and its arguments. Run this command and open its standard input for writing. The standard error is closed before launching the program. This can be altered by using the following versions of this construct:

|2>null: command

Standard error is redirected to /dev/null.

|2>file:name command

Execute command with its standard error redirected to the file name. If the file exists, it will be truncated.

|2>>file:name command

Standard error of the command is appended to the file name. If file does not exist, it will be created.

The ‘|2>null:’ construct described above is a shortcut for

|2>>file:/dev/null command
|2>syslog:facility[.priority] command

Standard error is redirected to the given syslog facility and, optionally, priority. If the latter is omitted, ‘LOG_ERR’ is assumed.

Valid values for facility are: ‘user’, ‘daemon’, ‘auth’, ‘authpriv’, ‘mail’, and ‘local0’ through ‘local7’. Valid values for priority are: ‘emerg’, ‘alert’, ‘crit’, ‘err’, ‘warning’, ‘notice’, ‘info’, ‘debug’. Both facility and priority may be given in upper, lower or mixed cases.

Notice, that no whitespace characters are allowed between ‘|’ and ‘2>’.

|<

Treat the rest of name as the command name and its arguments. Run this command with its stdin closed and stdout open for reading.

The standard error is treated as described above (see ‘|’).

|&

Treat the rest of name as the command name and its arguments. Run this command and set up for two-way communication with it, i.e writes to the descriptor returned by open will send data to the program’s standard input, reads from the descriptor will get data from the program’s standard output.

The standard error is treated as described above (see ‘|’). For example, the following redirects it to syslog ‘mail.debug’:

|&2>syslog:mail.debug command
@

Treat the rest of name as the URL of a socket to connect to. Valid URL forms are described in milter port specification.

If none of these prefixes is used, name is treated as a name of an existing file and open will attempt to open this file for reading.

The open function will signal exception e_failure if it is unable to open the resource or get the required access to it.

Built-in Function: number spawn (string cmd [, number in, number out, number err])

Runs the supplied command cmd. The syntax of the cmd is the same as for the name argument to open (see above), which begins with ‘|’, excepting that the ‘|’ sign is optional. That is:

spawn("/bin/cat")

has exactly the same effect as

open("|/bin/cat")

Optional arguments specify file stream descriptors to be used for the program standard input, output and error streams, correspondingly. If supplied, these should be the values returned by a previous call to open or tempfile. The value ‘-1’ means no redirection.

The example below starts the awk program with a simple expression as its argument and redirects the content of the file /etc/passwd to its standard input. The returned stream descriptor is bound to the command’s standard output (see the description of ‘|<’ prefix above). The standard error is closed:

number fd spawn("<awk -F: '{print $1}'", open("/etc/passwd"))
Built-in Function: void close (number rd)

The argument rd is a resource descriptor returned by a previous call to open. The function close closes the resource and deallocates any memory associated with it.

close will signal e_range exception if rd lies outside of allowed range of resource descriptors. See max-streams.

Notice that you are not required to close resources opened by open. Any unclosed resource will be closed automatically upon the termination of the filtering program.

Built-in Function: void shutdown (number rd, number how)

This function causes all or part of a full-duplex connection to be closed. The rd must be either a socket descriptor (returned by open(@...)) or a two-way pipe socket descriptor (returned by open(|&...)), otherwise the call to shutdown is completely equivalent to close.

The how argument identifies which part of the connection to shut down:

SHUT_RD

Read connection. All further receptions will be disallowed.

SHUT_WR

Write connection. All further transmissions will be disallowed.

SHUT_RDWR

Shut down both read and write parts.

Built-in Function: number tempfile ([string tmpdir])

Creates a nameless temporary file and returns its descriptor. Optional tmpdir supplies the directory where to create the file, instead of the default /tmp.

Built-in Function: void rewind (number rd)

Rewinds the stream identified by rd to its beginning.

Built-in Function: number copy (number dst, number src)

Copies all data from the stream src to dst. Returns number of bytes copied.

The following functions provide basic read/write capabilities.

Built-in Function: void write (number rd, string str [, number size])

Writes the string str to the resource descriptor rd. If the size argument is given, writes this number of bytes.

The function will signal e_range exception if rd lies outside of allowed range of resource descriptors, and e_io exception if an I/O error occurs.

Built-in Function: void write_body (number rd, pointer bp , number size)

Write the body segment of length size from pointer bp to the stream rd. This function can be used only in prog body (see body handler). Its second and third arguments correspond exactly to the parameters of the body handler, so the following construct writes the message body to the resource fd, which should have been open prior to invoking the body handler:

prog body
do
  write_body(fd, $1, $2)
done
Built-in Function: string read (number rd, number n)

Read and return n bytes from the resource descriptor rd.

The function may signal the following exceptions:

e_range

rd lies outside of allowed range of resource descriptors.

e_eof

End of file encountered.

e_io

An I/O error occurred.

Built-in Function: string getdelim (number rd, string delim)

Read and return the next string terminated by delim from the resource descriptor rd.

The terminating delim string will be removed from the return value.

The function may signal the following exceptions:

e_range

rd lies outside of allowed range of resource descriptors.

e_eof

End of file encountered.

e_io

An I/O error occurred.

Built-in Function: string getline (number rd)

Read and return the next line from the resource descriptor rd. A line is any sequence of characters terminated with the default line delimiter. The default delimiter is a property of rd, i.e. different descriptors can have different line delimiters. The default value is ‘\n’ (ASCII 10), and can be changed using the fd_set_delimiter function (see below).

The function may signal the following exceptions:

e_range

rd lies outside of allowed range of resource descriptors.

e_eof

End of file encountered.

e_io

An I/O error occurred.

Built-in Function: void fd_set_delimiter (number fd, string delim)

Set new line delimiter for the descriptor fd, which must be in opened state.

Default delimiter is a newline character (ASCII 10). The following example shows how to change it to CRLF sequence:

fd_set_delimiter(fd, "\r\n")
Built-in Function: string fd_delimiter (number fd)

Returns the line delimiter string for fd.

The following example shows how mailfromd I/O functions can be used to automatically add IP addresses to an RBL zone:

set nsupdate_cmd
  "/usr/bin/nsupdate -k /etc/bind/Kmail.+157+14657.private"
  
func block_address(string addr)
do
  number fd
  string domain

  set fd open "|%nsupdate_cmd"

  set domain revip(addr) . ".rbl.myzone.come"
  write(fd, "prereq nxrrset %domain A\n"
             "update add %domain 86400 A %addr\n\n"
done

The function revip is defined in revip.

Mailfromd Manual (split by section):   Section:   Chapter:FastBack: Library   Up: Library   FastForward: Using MFL Mode   Contents: Table of ContentsIndex: Concept Index