     [file version.texi not included]
     [file rendition.texi not included]
     [file macros.texi not included]

Published by the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

Copyright © 2005, 2006, 2007, 2008, 2009 Sergey Poznyakoff

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover texts being ``GNU Pies Manual'', and with the Back-Cover Texts as in (a) below.  A copy of the license is included in the section entitled ``GNU Free Documentation License''.

(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify this GNU Manual, like GNU software.  Copies published by the Free Software Foundation raise funds for GNU development.''

GNU Pies Manual
***************

This edition of the GNU Pies Manual, last updated UPDATED, documents pies Version VERSION.

Introduction
************

The name pies (pronounced p-yes) stands for Program Invocation and Execution Supervisor.  This utility starts and controls execution of external programs, called components.  Each component is a stand-alone program, which is executed in the foreground.  Upon startup, pies reads the list of components from its configuration file, starts them, and remains in the background, controlling their execution.  When any of the components terminates, pies restarts it.  Its configuration allows to specify actions other than simple restart, depending on the exit code of the component.

A component A may depend on another components, say B and C, i.e. require them to be running at the moment of its startup.  Components B and C are called prerequisites for A, while A is called a dependency or dependent component of B, C.

Before restarting any component, pies verifies if it is a prerequisite for any other components.  If so, it first terminates its dependencies, then restarts the component, and then starts its dependencies again, in the order of their appearance in the configuration file.

The standard output and standard error streams of a component can be redirected to a file or to an arbitrary syslog channel.

This way of operation applies to the init-style components, called so because of the similarity with the init process manager.  Pies is also able to handle components that receive input on their stdin and send reply to stdout.  Such components are called inetd-style components.

Inetd-style components are not executed right after pies startup.  Instead, pies opens a socket for each of them and listens for connections on these sockets.  When a connection arrives, it decides what component the socket corresponds to, and invokes this component to handle that connection.  In this case, the connection is bound to component's stdin and stdout streams.  The stderr stream can be redirected to a file or to syslog, as described above.  This mode of operation is similar to that of the inetd utility.

Third type of components supported by pies are meta1-style components.  As its name suggests, this type is designed expressly as a support for MeTA1 (See http://www.meta1.org) components, namely smtps.  This type can be regarded as a mixture of the above two.  For each meta1-style component pies opens a socket after start-up, and then executes the component.  Once the component is running, pies passes it the file descriptor of that socket, through another preconfigured UNIX-style socket.  Further handling of the socket is the responsibility of the component itself.

The last flavor of pies components are accept-style components, which are handled basically as inetd-style ones, except that after binding to the socket pies immediately starts the component, without waiting for an actual connection.

Any number of components of all three styles can be handled simultaneously.

Components are started in the order of their appearance in the configuration file and terminated in the reverse order.  The same ordering applies when starting or stopping a component dependencies,

As an exception, this order is reversed for the components read from files included by include-meta1 statement (see include-meta1).

Pies Configuration File
***********************

Pies reads its settings and component definitions from the configuration file pies.conf, located in the system configuration directory (in most cases /etc or /usr/local/etc, depending on how the package was compiled). An alternative location may be specified using --config-file (-c command line option).

If any errors are encountered in the configuration file, the program reports them on the standard error and exits with status 78.

To test the configuration file without actually starting the server, the --lint (-t) command line option is provided.  It causes pies to check its configuration file and exit with status 0 if no errors were detected, and with status 78 otherwise.

Before parsing, configuration file is preprocessed using m4 (see Preprocessor).  To see the preprocessed configuration without actually parsing it, use -E command line option.

The rest of this section describes the configuration file syntax in detail.  You can receive a concise summary of all configuration directives any time by running pies --config-help.

Configuration File Syntax
=========================

The configuration file consists of statements and comments.

There are three classes of lexical tokens: keywords, values, and separators. Blanks, tabs, newlines and comments, collectively called white space are ignored except as they serve to separate tokens.  Some white space is required to separate otherwise adjacent keywords and values.

Comments
--------

Comments may appear anywhere where white space may appear in the configuration file.  There are two kinds of comments: single-line and multi-line comments.  Single-line comments start with # or // and continue to the end of the line:

     # This is a comment
     // This too is a comment

Multi-line or C-style comments start with the two characters /* (slash, star) and continue until the first occurrence of */ (star, slash).

Multi-line comments cannot be nested.

Statements
----------

A simple statement consists of a keyword and value separated by any amount of whitespace.  The simple statement is terminated with a semicolon (;), unless it contains a here-document (see below), in which case the semicolon is optional.

Examples of simple statements are:

     pidfile /var/run/pies.pid;
     source-info yes;
     debug 10;

A keyword begins with a letter and may contain letters, decimal digits, underscores (_) and dashes (-). Examples of keywords are: group, control-file.

A value can be one of the following:

number
     A number is a sequence of decimal digits.

boolean
     A boolean value is one of the following: yes, true, t or 1, meaning true, and no, false, nil, 0 meaning false.

unquoted string
     An unquoted string may contain letters, digits, and any of the following characters: _, -, ., /, :.

quoted string
     A quoted string is any sequence of characters enclosed in double-quotes (").  A backslash appearing within a quoted string introduces an escape sequence, which is replaced with a single character according to the following rules:

     Table: Backslash escapes

     Sequence   Replaced with
     \a   Audible bell character (ASCII 7)
     \b   Backspace character (ASCII 8)
     \f   Form-feed character (ASCII 12)
     \n   Newline character (ASCII 10)
     \r   Carriage return character (ASCII 13)
     \t   Horizontal tabulation character (ASCII 9)
     \v   Vertical tabulation character (ASCII 11)
     \\   A single backslash (\)
     \"   A double-quote.

     In addition, any occurrence of \ immediately followed by a newline character (ASCII 10) is removed from the string.  This allows to split long strings over several physical lines, e.g.:

          "a long string may be\
           split over several lines"

     If the character following a backslash is not one of those specified above, the backslash is ignored and a warning is issued.

     Two or more adjacent quoted strings are concatenated, which gives another way to split long strings over several lines to improve readability.  The following fragment produces the same result as in the example above:

          "a long string may be"
          " split over several lines"

Here-document
     Here-document is a special construct that allows to introduce strings of text containing embedded newlines.

     The <<WORD construct instructs the parser to read all the following lines up to the line containing only WORD, with possible trailing blanks.  Any lines thus read are concatenated together into a single string.  For example:

          <<EOT
          A multiline
          string
          EOT

     Body of a here-document is interpreted the same way as double-quoted string, unless WORD is preceded by a backslash (e.g. <<\EOT) or enclosed in double-quotes, in which case the text is read as is, without interpretation of escape sequences.

     If WORD is prefixed with - (a dash), then all leading tab characters are stripped from input lines and the line containing WORD.  Furthermore, if - is followed by a single space, all leading whitespace is stripped from them.  This allows to indent here-documents in a natural fashion.  For example:

          <<- TEXT
              All leading whitespace will be
              ignored when reading these lines.
          TEXT

     It is important that the terminating delimiter be the only token on its line.  The only exception to this rule is allowed if a here-document appears as the last element of a statement.  In this case a semicolon can be placed on the same line with its terminating delimiter, as in:

          help-text <<-EOT
                  A sample help text.
          EOT;

list
     A list is a comma-separated list of values.  Lists are delimited by parentheses.  The following example shows a statement whose value is a list of strings:

          dependents (pmult, auth);

     In any case where a list is appropriate, a single value is allowed without being a member of a list: it is equivalent to a list with a single member.  This means that, e.g. dependents auth; is equivalent to dependents (auth);.

A block statement introduces a logical group of another statements.  It consists of a keyword, followed by an optional value, and a sequence of statements enclosed in curly braces, as shown in the example below:

     component multiplexor {
             command "pmult";
     }

The closing curly brace may be followed by a semicolon, although this is not required.

Using Preprocessor to Improve the Configuration.
------------------------------------------------

Before parsing, the configuration file is preprocessed using external preprocessor m4.  For a complete user manual, refer to GNU M4 (GNU M4 macro processor). In this subsection we assume the reader is sufficiently acquainted with m4 macro processor.

The external preprocessor is invoked with -s flag, instructing it to include line synchronization information in its output.  This information is then used by the parser to display meaningful diagnostic.  An initial set of macro definitions is supplied by the pp-setup file, located in $PREFIX/share/pies/VERSION/include directory (where VERSION means the version of the package).

The default pp-setup file renames all m4 built-in macro names so they all start with the prefix m4_.  This is similar to GNU m4 --prefix-builtin options, but has an advantage that it works with non-GNU m4 implementations as well.

Additional preprocessor symbols may be defined and the existing symbols may be undefined using the following command line options:

--define=SYM[=VALUE]
-D SYMBOL[=VALUE]
     Define symbol SYM as having VALUE, or emtpy, if the VALUE is not given.

--undefine=SYM
-U SYM
     Undefine symbol SYM.

Component Statement
===================

 -- Config: component
     The component statement defines a new component:

     component TAG {
       ...
     }

The component is identified by its tag, which is given as argument to the component keyword.

The following are the basic statements which are allowed within the component block:

 -- Config: component: mode MODE
     Declare the type (style) of the component.  Accepted values for MODE are:

     exec
     wait
          Define an init-style component (see init-style).  This is the default.

     inetd
     nostartaccept
          Define an inetd-style component (see inetd-style).

     pass
     pass-fd
          Define a meta1-style component (see meta1-style).

     accept
          Define a accept-style component (see accept-style).

 -- Config: component: program NAME
     Full file name of the component binary.  This binary will be executed (via /bin/sh -c) each time pies decides it needs to start the component.

     To supply command line arguments, use command statement.

 -- Config: component: command STRING
     Command line for the program.  The argument should be just as arguments normally are, starting with the name of the program.  The latter may be different from the one specified to program statement.  Its value will be available to the program as argv[0].

 -- Config: component: disable BOOL
     If BOOL is true, this component is disabled, i.e. pies will ignore it.

 -- Config: component: precious BOOL
     If BOOL is true, this component is marked as precious. Precious components are never disabled by pies, even if they respawn too fast.

 -- Config: component: acl { ... }
     Set access control list for this component.  See ACL, for a detailed description of access control lists.

The following subsections describe the rest of component substatements.

Component Prerequisites
-----------------------

Prerequisites (see component prerequisite) for a component are declared using the following statement:

 -- Config: component: prerequisites TAG-LIST
     The argument is either a list of component tags, defined before this component, or one of the following words:

     all
          Declare all components defined so far as prerequisites for this one.

     none
          No prerequisites.  This is the default.

If you wish, you can define dependents, instead of prerequisites:

 -- Config: component: dependents TAG-LIST
     Declare dependents for this component.  VAR-LIST is a list of component tags.

Component Privileges
--------------------

The following statements control the privileges the component is executed with.

 -- Config: component: user USER-NAME
     Start component with the UID and GID of this user.

 -- Config: component: group GROUP-LIST
     Retain supplementary groups, specified in GROUP-LIST.

 -- Config: component: allgroups BOOL
     Retain all supplementary groups of which the user (as given with user statement) is a member.  This is the default for components specified in meta1.conf file (see include-meta1).

Resources
---------

 -- Config: component: limits STRING
     Impose limits on system resources, as defined by STRING.  The argument consists of commands, optionally separated by any amount of whitespace.  A command is a single command letter followed by a number, that specifies the limit.  The command letters are case-insensitive and coincide with those used by the shell ulimit utility:

     Table: Limit Command Letters

     Command    The limit it sets
     A          max address space (KB)
     C          max core file size (KB)
     D          max data size (KB)
     F          maximum file size (KB)
     M          max locked-in-memory address space (KB)
     N          max number of open files
     R          max resident set size (KB)
     S          max stack size (KB)
     T          max CPU time (MIN)
     U          max number of processes
     P          process priority -20..20 (negative = high priority)

     For example:

          limits T10 R20 U16 P20

     Additionally, the command letter L is recognized.  It is reserved for future use (number of logins limit) and is ignored in version VERSION.

 -- Config: component: umask NUMBER
     Set the umask.  The NUMBER must be an octal value not greater than 777.  The default umask is inherited at startup.

 -- Config: component: env ARGS
     Set program environment.

     Arguments are a whitespace-delimited list of specifiers.  The following specifiers are understood:

     - (a dash)
          Clear the environment.  This is understood only when used as a first word in ARGS.

     -NAME
          Unset the environment variable NAME.

     -NAME=VAL
          Unset the environment variable NAME only if its value is VAL.

     NAME
          Retain the environment variable NAME.

     NAME=VALUE
          Define environment variable NAME to have given VALUE.

     NAME+=VALUE
          Retain variable NAME and append VALUE to its existing value.  If no such variable is present in the environment, it is created and VALUE is assigned to it.  However, if VALUE begins with a punctuation character, this character is removed from it before the assignment.  This is convenient for using this construct with environment variables like PATH, e.g.:

               PATH+=:/sbin

          In this example, if PATH exists, :/sbin will be appended to it.  Otherwise, it will be created and /sbin will be assigned to it.

     NAME=+VALUE
          Retain variable NAME and prepend VALUE to its existing value.  If no such variable is present in the environment, it is created and VALUE is assigned to it.  However, if VALUE ends with a punctuation character, this character is removed from it before assignment.

Actions Before Startup
----------------------

Several statements are available that specify actions to perform immediately before starting the component:

 -- Config: component: chdir DIR
     Change to the directory DIR.

 -- Config: component: remove-file FILE-NAME
     Remove FILE-NAME.  This is useful, for example, to remove stale UNIX sockets or pid-files, which may otherwise prevent the component from starting normally.

     As of version VERSION only one remove-file may be given.

 -- Config: component: pass-fd-timeout NUMBER
     Wait NUMBER of seconds for the pass-fd socket to become available (see Meta1-Style Components).  Default is 5 seconds.

Exit Actions
------------

The default behavior of pies if an init-style component terminates is to restart it.  Unless the component terminates with 0 exit code, a corresponding error message is issued to the log file.  This behavior can be modified using return-code statement:

 -- Config: component: return-code

          return-code CODES {
            ...
          }

The CODES argument is a list of exit codes or signal names. Exit codes can be specified either as decimal numbers or as symbolic code names from the table below:

Table: Standard Exit Codes

Name         Numeric value
EX_OK            0
EX_USAGE         64
EX_DATAERR       65
EX_NOINPUT       66
EX_NOUSER        67
EX_NOHOST        68
EX_UNAVAILABLE   69
EX_SOFTWARE      70
EX_OSERR         71
EX_OSFILE        72
EX_CANTCREAT     73
EX_IOERR         74
EX_TEMPFAIL      75
EX_PROTOCOL      76
EX_NOPERM        77
EX_CONFIG        78

Signal numbers can be given either as SIG+N, where N is the signal number, or as signal names from the following list: SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGIOT, SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGSTKFLT, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGPOLL, SIGIO, SIGPWR, SIGSYS.

If the component exits with an exit code listed in CODES or is terminated on a signal listed in CODES, pies executes actions specified in that return-code block.  The actions are executed in the order of their appearance below:

 -- Config: return-code: exec COMMAND
     Execute the supplied external command.  Prior to execution, all file descriptors are closed.  The COMMAND inherits the environment from the main pies process with the following additional variables:

     PIES_VERSION
          The pies version number (VERSION).

     PIES_COMPONENT
          Tag of the terminated component (see tag).

     PIES_PID
          PID of the terminated component.

     PIES_SIGNAL
          If the component terminated on signal, the number of that signal.

     PIES_STATUS
          Program exit code.

 -- Config: return-code: action disable | restart
     If restart is given, restart the component.  This is the default.  Otherwise, mark the component as disabled.  Component dependents are stopped and marked as disabled as well.  Once disabled, the components are never restarted, unless their restart is requested by the administrator.

 -- Config: return-code: notify EMAIL-STRING
     Send an email notification to addresses in EMAIL-STRING. See Notification, for a detailed discussion of this feature.

 -- Config: return-code: message STRING
     Supply notification message text to use by notify statement. See Notification, for a detailed discussion of this feature.

Any number of return-code statements are allowed, provided that their CODES do not intersect.

The return-code statements can also be used outside of component block.  In this case, they supply global actions, i.e. actions applicable to all components.  Any return-code statements appearing within a component block override the global ones.

Output Redirectors
------------------

Output redirectors allow to redirect the standard error and/or standard output of a component to a file or syslog facility.

 -- Config: component: stderr TYPE CHANNEL
 -- Config: component: stdout TYPE CHANNEL
     Redirect standard error (if stderr) or standard output (if stdout) to the given channel.

     The type of redirection is specified by TYPE argument:

     file
          Redirect to a file.  In this case CHANNEL gives the full name of the file.  For example:

               stderr file /var/log/component/name.err;

     syslog
          Redirect to a syslog channel.  The syslog priority is given by the CHANNEL argument.  Its allowed values are: emerg, alert, crit, err, warning, notice, info, debug.  The facility is inherited from the syslog statement (see syslog), or from the facility statement (see below), if given.

          Example:

               stderr syslog err;

 -- Config: component: facility SYSLOG-FACILITY
     Specify the syslog facility to use in syslog redirectors.  Allowed SYSLOG-FACILITY values are: user, daemon, auth, authpriv, mail, cron, local0 through local7 (all names case-insensitive), or a facility number.

Inetd-Style Components
----------------------

Inetd-style components are declared using mode inetd statement.  You must also declare a socket to listen on.

 -- Config: component: socket URL
     Define a socket to listen on.  Allowed values for URL are:

     file name
          Specifies a UNIX socket file name.  You may use a relative file name, provided that chdir statement is used for this component (see chdir).

     local://FILE[;ARGS]
     file://FILE[;ARGS]
     unix://FILE[;ARGS]
          Listen on the UNIX socket file FILE, which is either an absolute or relative file name, as described above.  Optional arguments ARGS control ownership and file mode of FILE.  They are a list of assignments, separated by semicolons.  The following values are allowed:

          user
               User name of the socket owner.

          group
               Owner group of the socket, if it differs from the user group.

          mode
               Socket file mode (octal number between 0 and 777).

          umask
               Umask to use when creating the socket (octal number between 0 and 777).

          For example:

               socket "unix:/var/run/socket;user=nobody;group=mail;mode=770";

     inet://IP:PORT
          Listen on IPv4 address IP (may be given as a symbolic host name), on port PORT.

     Notice, that pies version VERSION handles only TCP sockets and only IPv4 addresses.  Support for IPv6 will be added in future versions.  Support for UDP sockets will be added if there is a demand.

Meta1-Style Components
----------------------

Meta1-style components are declared using mode pass statement.  For such components, you must declare both a socket to listen on (see inetd-socket and a UNIX socket name to pass the file descriptor to the component.  The latter is defined using pass-fd-socket statement:

 -- Config: component: pass-fd-socket FILE-NAME
     The argument is an absolute or relative file name of the socket file. In the latter case, the chdir DIR statement must be used for this component (see chdir), and the socket will be looked under DIR.

     This socket file is supposed to be created by the component binary upon its startup.

Component Syntax Summary
------------------------

This subsection summarizes the component summary.  For each statement, a reference to its detailed description is supplied.

     component TAG {
       # Component execution mode.
       # See mode.
       mode exec | wait | accept | inetd | nostartaccept | pass-fd | pass;

       # Full name of the program.
       # See program.
       program NAME;
       # Command line.
       # See command.
       command STRING;

       # Disable this entry.
       # See disable.
       disable BOOL;
       # Mark this entry as precious.
       # See precious.
       precious BOOL;

       # List of prerequisites.
       # See Prerequisites.
       prerequisites (COMPNAMES);
       # List of components for which this one is a prerequisite.
       # See dependents.
       dependents (COMPNAMES);

       # Listen on the given url.
       # See Inetd-Style Components.
       socket URL;

       # Pass fd through this socket.
       # See Meta1-Style Components.
       pass-fd-socket SOKET-NAME;

       # ACL for this component.
       # See ACL Statement (GNU Mailutils Manual).
       acl { ... }

       # Override default syslog facility for this component.
       facility FACILITY;
       # Redirect program's standard output to the given
       # file or syslog priority.
       # See Output Redirectors.
       stdout file | syslog CHANNEL;
       # Redirect program's standard error to the given
       # file or syslog priority.
       # See Output Redirectors.
       stderr file | syslog CHANNEL;

       # Run with this user privileges.
       # See Component Privileges.
       user USER-NAME;
       # Retain supplementary group.
       # See group.
       group GROUP-NAME;
       # Retain all supplementary groups of which user is a member.
       # See allgroups.
       allgroups BOOL;

       # Set system limits.
       # See Resources.
       limits STRING;

       # Force this umask.
       # See umask.
       umask NUMBER;

       # Set program environment.
       # See env.
       env ASSIGNMENTS;

       # Change to this directory before executing the component.
       # See chdir.
       chdir DIR;
       # Remove FILE-NAME before starting the component.
       # See remove-file.
       remove-file FILE-NAME;
       # Wait NUMBER of seconds for pass-fd socket to become available.
       # See pass-fd-timeout.
       pass-fd-timeout NUMBER;

       # Actions:
       # See Exit Actions.
       return-code EXIT-CODE-LIST {
         # Action to take when a component finishes with this return code.
         action disable | restart;
         # Notify these addresses when then component terminates.
         notify EMAIL-STRING;
         # Notification message text (with headers).
         message STRING;
       }
     }

Notification
============

Pies provides a notification mechanism, which can be used to send email messages when components terminate.  The exact contents of such notifications and the list of their recipients may depend on the exit code which the component returned.  Notification is configured by supplying notify and message statements in a return-code block.

 -- Config: return-code: notify EMAIL-STRING
     Send email notification to addresses from EMAIL-STRING.  The latter is a comma-separated list of email addresses, e.g.:

          notify "root@localhost,postmaster@localhost";

     Each address may be optionally enclosed in angular brackets (< and >).

 -- Config: return-code: message STRING
     Supply the email message text to be sent.  STRING must be a valid RFC 822 message, i.e. it must begin with message headers, followed by an empty line and the actual message body.

     The message may contain variable data in the form of variable references.  A variable is an entity that holds some data describing the event that occurred.  Meta-variables are referenced using the following construct:

          ${NAME}

     where NAME is the name of the variable.  Before actually sending the message, each occurrence of this construct is removed from the text and replaced by the actual value of the referenced variable. For example, the variables component and retcode expand to the name of the exited component and its exit code, correspondingly. Supposing that component is ftpd and retcode is 76, the following fragment:

          Subject: ${component} exited with code ${retcode}

     will become:

          Subject: ftpd exited with code 76

     The table below lists all available variables and their expansions:

     Table: Notification Variables

     Variable   Expansion
     canonical-program-name   pies
     program-name   Program name of the pies binary.
     package        Package name (Pies).
     version        Package version (VERSION).
     component      Name of the terminated component.
     termination    Termination cause (see below).
     retcode        Component exit code (or signal number, if exited
     on signal), in decimal.

     The termination variable is set so as to facilitate its use with the retcode variable.  Namely, its value is exited with, if the component exited and terminated on signal, if it terminated on a signal.  Thus, using

          ${termination} ${retcode}

     results in a correct English sentence.  This message, however, cannot be properly internationalized.  This will be fixed in the future versions.

     If message statement is not given, the following default message is used instead:

          From: <>
          X-Agent: ${canonical-program-name} (${package} ${version})
          Subject: Component ${component} ${termination} ${retcode}.

Notification messages are sent using an external program, called mailer.  By default it is /usr/sbin/sendmail.  You can change it using the following configuration statement:

 -- Config: mailer-program PROG
     Use PROG as a mailer program.  The mailer must meet the following requirements:

      1. It must read the message from its standard input.

      2. It must treat the non-optional arguments in its command line as recipient addresses.

     For example, the following statement instructs pies to use exim as a mailer:

          mailer-program /usr/sbin/exim;

By default, the mailer program is invoked as follows:

     /usr/sbin/sendmail -oi -t RCPTS

where RCPTS is a whitespace-separated list of addresses supplied in the notify statement.

The mailer command may be altered using mailer-command-line statement:

 -- Config: mailer-command-line STRING
     Set mailer command line.  Notice, that STRING must include the command name as well.  The mailer-program statement supplies the full name of the binary which will be executed, while the first word from the mailer-command-line argument gives the string it receives as argv[0].

     The example below shows how to use this statement to alter the envelope sender address:

          mailer-command-line "sendmail -f root@domain.com -oi -t";

Access Control Lists
====================

Access control lists, or ACLs for short, are lists of permissions that control access to inetd, access and meta1-style components.

An ACL is defined using acl block statement:

 -- Config: acl

          acl {
            DEFINITIONS
          }

This statement is allowed both in global context and within a component block.  If both are present, the global-level ACL is consulted first, and if it allows access, the component ACL is consulted.  As a result, access is granted only if both lists allow it.

A named ACL is an access control list which is assigned its own name.  Named ACLs are defined using the defacl statement:

 -- Config: defacl NAME

          defacl NAME {
            DEFINITIONS
          }

     The NAME parameter specifies a unique name for that ACL.  Named ACLs are applied only if referenced from another ACL (either global or a per-component one, or any named ACL, referenced from these).  See ACL references, below.

In both forms, the part between the curly braces (denoted by DEFINITIONS), is a list of access control statements. There are two types of such statements:

 -- Config: acl: allow [USER-GROUP] SUB-ACL HOST-LIST
 -- Config: acl: allow any
     Allow access to the component.

 -- Config: acl: deny [USER-GROUP] SUB-ACL HOST-LIST
 -- Config: acl: deny any
     Deny access to the component.

All parts of an access statement are optional, but at least one of them must be present.  The USER-GROUP part is reserved for future use and is described in more detail in User-Group ACLs.

The SUB-ACL part, if present, allows to branch to another ACL.  The syntax of this part is:

     acl NAME

where NAME is the name of an ACL defined previously in defacl statement.

The HOST-LIST group allows to match client addresses. It consists of the from keyword followed by a list of address specifiers.  Allowed address specifiers are:

ADDR
     Matches if the client IP equals ADDR. The latter may be given either as an IP address or as a host name, in which case it will be resolved and the first of its IP addresses will be used.

ADDR/NETLEN
     Matches if first NETLEN bits from the client IP address equal to ADDR.  The network mask length, NETLEN must be an integer number in the range from 0 to 32.  The address part, ADDR, is as described above.

ADDR/NETMASK
     The specifier matches if the result of logical AND between the client IP address and NETMASK equals to ADDR.  The network mask must be specified in ``dotted quad'' form, e.g. 255.255.255.224.

FILENAME
     Matches if connection was received from a UNIX socket FILENAME, which must be given as an absolute file name.

The special form allow any means to allow access unconditionally.  Similarly, deny any, denies access unconditionally.  Normally, one of these forms appears as the last statement in an ACL definition.

To summarize, the syntax of an access statement is:

     allow|deny [acl NAME] [from ADDR-LIST]

where square brackets denote optional parts.

When an ACL is checked, its entries are tried in turn until one of them matches, or the end of the list is reached.  If a matched entry is found, its command verb, allow or deny, defines the result of the ACL check.  If the end of the list is reached, the result is allow, unless explicitly specified otherwise (using the ``any'' form.)

For example, the following ACL allows access for anybody coming from networks 192.168.10.0/24 and 192.168.100.0/24, or any connection that matches the named ACL my-nets (which should have been defined before this definition).  Access is denied for anybody else:

     acl {
         allow from (192.168.10.0/24, 192.168.100.0/24);
         allow acl "my-nets";
         deny all;
     }

Using MeTA1 Configuration File
==============================

MeTA1 is a mail transfer agent of new generation, designed to replace Sendmail in the future (http://www.meta1.org). It has a modular structure, each module being an independent responsible for a particular task.  The components are configured in the MeTA1 configuration file /etc/meta1/meta1.conf.

Pies is able to take a list of components directly from MeTA1 configuration file:

 -- Config: include-meta1 FILE
     Parse FILE as MeTA1 configuration file and incorporate components defined there into the current component list.

     For example:

     include-meta1 /etc/meta1/meta1.conf;

Thus, you can use pies instead of the default MeTA1 program manager mcp.  This is particularly useful if you use Mailfromd (http://mailfromd.software.gnu.org.ua) to control the mail flow.

To ensure compatibility with MeTA1, the components read from its configuration file are started in the reverse order (i.e. from last to first), and stopped in the order of their appearance in FILE. Of course, this does not affect normal pies components.

The following pies statements are silently applied to all MeTA1 components:

     allgroups yes;
     stderr file COMPNAME.log
     chdir QUEUE-DIR

Here, COMPNAME stands for the name of the component, and QUEUE-DIR stands for the name of MeTA1 queue directory.  The latter is /var/spool/meta1 by default.  It can be changed using the following statement:

 -- Config: meta1-queue-dir DIR
     Set name of MeTA1 queue directory.

To override any default settings for a MeTA1 component, add a command section with the desired settings after including meta1.conf.  For example, here is how to redirect the standard error of the smtps component to local1.debug syslog channel:

     include-meta1 /etc/meta1/meta1.conf

     component smtps {
       facility local1;
       stderr syslog debug;
     }

Global Configuration
====================

The statements described in this section affect pies behavior as a whole.

 -- Config: syslog { ... }
     This block statement configures logging via syslog.  It has two substatements:

 -- Config: syslog: tag STRING
     Prefix syslog messages with this string.  By default, the program name is used.

 -- Config: syslog: facility STRING
     Set syslog facility to use.  Allowed values are: user, daemon, auth, authpriv, mail, cron, local0 through local7 (case-insensitive), or a facility number.

 -- Config: umask NUMBER
     Set the default umask.  The NUMBER must be an octal value not greater than 777.  The default umask is inherited at startup.

 -- Config: limits ARG
     Set global system limits for all pies components.  See limits, for a detailed description of ARG.

 -- Config: return-code { ... }
     Configure global exit actions.  See Exit Actions, for a detailed description of this statement.

 -- Config: shutdown-timeout NUMBER;
     Wait NUMBER of seconds for all components to shut down. Default is 5 seconds.

Less Useful Statements
----------------------

Some configuration file statements are provided for completeness and are rarely, if at all used.  If used improperly, they may severely impair the functionality of pies or even render it useless.  Do not use them, unless you have a good knowledge of pies internals and understand their impact.

The following three statements define file names of various files needed by pies.  Use them only if the defaults does not suit your needs:

 -- Config: pidfile FILE
     Write PID of the master pies process to FILE.  By default the master PID is stored in LOCALSTATEDIR/pies.pid, where LOCALSTATEDIR is the local state directory, defined at compile time (usually, it is /usr/local/var or /usr/var).

 -- Config: control-file FILE
     Set file name of the pies control file.  Default is LOCALSTATEDIR/pies.ctl

 -- Config: stat-file FILE
     Set file name of the statistics output file.  Default is LOCALSTATEDIR/pies.stat.

Normally, pies must be run with root privileges.  If, however, you found such an implementation for it, that requires another privileges, you may change them using the following three statements:

 -- Config: user USER-NAME
     Start pies with the UID and GID of this user.

 -- Config: group GROUP-LIST
     Retain the supplementary groups, specified in GROUP-LIST.

 -- Config: allgroups BOOL
     Retain all supplementary groups of which user, given with user statement, is a member.

Pies Debugging
**************

The amount of debugging information produced by pies is configured by the following statements:

 -- Config: debug LEVEL
     Set debugging level.  The LEVEL must be a non-negative decimal integer.  In version VERSION the following debugging levels are used:

     1
          Log all basic actions: starting and stopping of components, received incoming TCP connections, sending mails.  Notify about setting limits.  Log pre-startup actions (see Actions Before Startup).

     2
          Log setting particular limits.  Log the recomputed alarms.

     4
          Dump execution environments

     6
          Debug the parser of MeTA1 configuration grammar.

     7
          Debug the lexical analyzer of MeTA1 configuration file.

 -- Config: source-info BOOL
     This statement decides whether debugging messages should contain source information.  To enable source information, use:

          source-info yes;

     This feature is designed for pies developers.

Configuration Example
*********************

In this section we provide several examples of working pies configuration files.

Simplest Case: Using Pies to Run Pmult
======================================

The example below runs pmult (see Pmilter multiplexer program (Mailfromd Manual)) utility with the privileges of meta1 user.  Both standard error and standard output are redirected to the syslog facility mail, priorities err and info, correspondingly.

     component pmult {
       command "/usr/local/sbin/pmult";
       user meta1s;
       facility mail;
       stderr syslog err;
       stdout syslog info;
     }

Using Pies to Run Pmult and MeTA1
=================================

The example below is a working configuration file for running pmult and all components of MeTA1, configured in /etc/meta1/meta1.conf.  The global return-code statement is used to configure pies behavior for some exit codes.

     # Sample pies configuration for running pmult and MeTA1

     # Special handling for exit codes that mean the program was
     # incorrectly used or misconfigured.
     return-code (EX_USAGE, EX_CONFIG) {
       action disable;
       notify "root";
       message <<- EOT
         From: Pies <>
         X-Agent: ${canonical-program-name} (${package} ${version})
         Subject: Component ${component} disabled.

         Component "${component}" has terminated with code ${retcode},
         which means it encountered some configuration problem.
         I will not restart it automatically. Please fix its configuration
         and restart it manually at your earliest convenience.

         To restart, run ``${program-name} -R ${component}''
         ---
         Wuff-wuff,
         Pies
       EOT;
     }

     component pmult {
       command "/usr/local/sbin/pmult";
       user meta1s;
       stderr syslog err;
       stdout syslog info;
     }

     include-meta1 "/etc/meta1/meta1.conf";

Running Pies Instead of Inetd
=============================

This configuration file allows to run pies instead of initd.  It starts two services: ftp and pop3d, and restricts access to them to two local subnets:

     acl {
        allow from 10.10.10.0/24;
        allow from 192.168.10.0/27;
        deny from any;
     }

     debug 3;

     component ftp {
        mode inetd;
        socket "inet://0.0.0.0:21";
        umask 027;
        program /usr/sbin/ftpd
        command "ftpd -l -C";
     }

     component pop3d {
        mode inetd;
        socket "inet://0.0.0.0:110";
        program "/usr/sbin/pop3d";
        command "pop3d --inetd";
     }

Command Line Usage
******************

When run without arguments, pies parses and loads the configuration file, detaches itself from the controlling terminal (becomes a daemon), and starts all components.  Before actually starting up, it ensures that no another instance of it is already running, by looking for a PID file and verifying that the PID listed there is alive and responding.  If another instance is running, pies refuses to start up.

After startup, you can verify the status of the running process using --status command line option:

     $ pies --status
     redirector smtps/stderr 4697
     redirector pmult/stderr 4677
     redirector pmult/stdout 4676
     component pmult 4678 /usr/local/sbin/pmult
     component smar 4680 smar -f /etc/meta1/meta1.conf -d 100
     component qmgr 4691 qmgr -f /etc/meta1/meta1.conf
     component smtpc 4696 smtpc -f /etc/meta1/meta1.conf
     component smtps 4698 smtps -d100 -f /etc/meta1/meta1.conf

In its output, lines beginning with component refer to running components.  For running components, the following information is displayed:

 1. Component tag (see Component Statement).

 2. PID of the running instance of the component.

 3. Command line of the component, as set by the command statement (see command).

If the component is not running, the reason is indicated in the PID column, between the square brackets, e.g.:

     component pmult [disabled; scheduled for Mon 01 Dec 2008 20:27:02]
       /usr/local/sbin/pmult

(the example above is split in two lines for readability).

You can restart any component by using the --restart-component (-R) option, e.g.:

     $ pies -R pmult smtps

To stop all running components and shut down pies, use the --stop (-S) command line option:

     $ pies --stop

Two options are provided for verifying inter-component dependencies.  The --dump-depmap option prints on the standard output the dependency map.  This map is a square matrix with rows representing dependents and columns representing prerequisites. An X sign is placed on each crossing which corresponds to the actual dependency.  For example:

     $ pies --dump-depmap
     Dependency map:
         0  1  2  3  4
      0
      1
      2     X
      3        X
      4     X  X

     Legend:
      0: pmult
      1: smar
      2: qmgr
      3: smtpc
      4: smtps

This example corresponds to the configuration file shown in Hairy Pies.  To illustrate how to read it, consider the 4th row of the table.  According to the legend, number 4 means smtps component.  There are two X marks: in columns 1 and 2.  This means that smtps depends on smar and qmgr.

You can also list prerequisites explicitly:

     $ pies --dump-prereq
     qmgr: smar
     smtpc: qmgr
     smtps: smar qmgr

Pies Invocation
***************

This section summarizes pies command line options.

     config-file

--config-file=FILE

-c FILE
     Read configuration from FILE, instead of the default /etc/pies.conf.

     See Pies Configuration File.

     config-help

--config-help
     Show configuration file summary.  See Pies Configuration File.

     define

--define=SYM[=VALUE]
-D SYMBOL[=VALUE]
     Define symbol SYM as having VALUE, or emtpy, if the VALUE is not given.  See Preprocessor.

     debug

--debug=LEVEL
-x LEVEL
     Set debug verbosity level.  See Pies Debugging, for a description of LEVEL.

     dump-depmap

--dump-depmap
     Dump dependency map.  See dump-depmap.

     dump-prereq

--dump-prereq
     Dump prerequisite charts.  See dump-prereq.

-E
     Preprocess configuration file and exit.  See Preprocessor.

     force

--force
     Force startup even if another instance may be running.

     foreground

--foreground
     Remain in foreground.

--help
     Display a short usage summary and exit.

     lint

--lint
-t

     source-info

--source-info
     Show source info with debugging messages.  See source-info.

     status

--status
-s
     Display info about the running instance.  See pies-status.

     stderr

--stderr
     Log to standard error.

     stop

--stop
-S
     Stop the running instance.

     syslog

--syslog
     Log to syslog.  This is the default.

     reload hup

-r
--reload
--hup
     Reload the running instance of pies.

     restart-component

-R
--restart-component
     Restart components named in the command line.  See pies-restart.

--version
     Display program version and license information and exit.

--undefine=SYM
-U SYM
     Undefine symbol SYM.  See Preprocessor.

--usage
     Display a short summary of available options and exit.

How to Report a Bug
*******************

Send bug-reports and suggestions to bug-pies@gnu.org.ua.

If you think you've found a bug, please be sure to include maximum information needed to reliably reproduce it, or at least to analyze it.  The information needed is:

  * Version of the package you are using.

  * Compilation options used when configuring the package.

  * Run-time configuration (pies.conf file and the command line options used).

  * Detailed description of the bug.

  * Conditions under which the bug appears.

User-Group ACLs
***************

     [file usr-acl.texi not included]

GNU Free Documentation License
******************************

     [file fdl.texi not included]

Concept Index
*************

This is a general index of all issues discussed in this manual