Next: Filtering functions, Previous: Character Type, Up: Library [Contents][Index]
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.
By default, all I/O operations are unbuffered. This can be changed by setting the following global variables:
Sets the default buffering type. Allowed values are (symbolic names are defined in status.mfl module):
0
BUFFER_NONE
No buffering. This is the default.
1
BUFFER_FULL
Full buffering. Size of the buffer is set by the
io_buffer_size
global variable (see below).
2
BUFFER_LINE
Line buffering. When reading, it is pretty much the same as
BUFFER_FULL
. When writing, the data are accumulated in buffer
and actually sent to the underlying transport stream when the newline
character is seen.
The initial size of the buffer is set by the io_buffer_size
variable. It will grow as needed during the I/O.
Set the buffer size if io_buffering
is set to
BUFFER_FULL
or BUFFER_LINE
. By default, this variable
is set to the size of the system page.
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.
Buffering mode for the opened stream is defined by the
io_buffering
and io_buffer_size
global variables. It
can be changed using the setbuf
function (see setbuf).
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:
Standard error is redirected to /dev/null.
Execute command with its standard error redirected to the file name. If the file exists, it will be truncated.
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
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.
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.
Buffering mode for the opened stream is defined by the
io_buffering
and io_buffer_size
global variables. It
can be changed using the setbuf
function (see setbuf).
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"))
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.
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:
Read connection. All further receptions will be disallowed.
Write connection. All further transmissions will be disallowed.
Shut down both read and write parts.
Creates a nameless temporary file and returns its descriptor. Optional tmpdir supplies the directory where to create the file, instead of the default /tmp.
Rewinds the stream identified by rd to its beginning.
Copies all data from the stream src to dst. Returns number of bytes copied.
The following functions provide basic read/write capabilities.
Writes the string str to the resource descriptor rd. If the size argument is given, writes this number of bytes.
This function always attempts to write the requested amount of
data. It will signal e_range
exception if rd lies
outside of allowed range of resource descriptors, e_io
exception if an I/O error occurs, and e_eof
exception
if it wrote 0 bytes (e.g. because the underlying device is full).
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
Read and return at most n bytes from the resource descriptor rd.
If there are less than n bytes in the stream, the remaining
bytes will be returned. Use length()
to obtain the actual size
of the returned data. If there are no bytes left, the e_eof
exception will be signalled.
The function may signal the following exceptions:
rd lies outside of allowed range of resource descriptors.
End of file encountered.
An I/O error occurred.
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.
When using this function, it is highly recommended to enable full
buffering for fd, either by setting io_buffering
before
open
(see io_buffering) or by calling setbuf
after it (see setbuf). See getline, for an example.
This function may signal the following exceptions:
rd lies outside of allowed range of resource descriptors.
End of file encountered.
An I/O error occurred.
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).
When using this function, it is highly recommended to enable full
buffering for fd, either by setting io_buffering
before
open
(see io_buffering) or by calling setbuf
after it (see setbuf), e.g.:
set fd open(input) setbuf(fd, BUFFER_FULL) set line getline(fd) ...
This function may signal the following exceptions:
rd lies outside of allowed range of resource descriptors.
End of file encountered.
An I/O error occurred.
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")
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 reverse_ipstr(addr) . ".rbl.myzone.come" write(fd, "prereq nxrrset %domain A\n" "update add %domain 86400 A %addr\n\n" done
The function reverse_ipstr
is defined in Internet address manipulation functions.
Changes the buffering mode of fd according to the remaining two
arguments. The type specifies buffering type
(see io_buffering), and size supplies the buffer size for
buffering types BUFFER_FULL
and BUFFER_LINE
. If
size is omitted, it defaults to io_buffer_size
(see io_buffer_size). Omitted type defaults to
io_buffering
(see io_buffering).
Returns the type of buffering currently in effect for the descriptor fd. See io_buffering, for a list of possible return values.
If this function returns BUFFER_FULL
or BUFFER_LINE
, you
can use getbufsize
to get the associated buffer size.
Returns the buffer size for the descriptor fd.
Next: Filtering functions, Previous: Character Type, Up: Library [Contents][Index]