diff options
-rw-r--r-- | doc/pies.texi | 839 | ||||
-rw-r--r-- | pies/meta1gram.y | 6 | ||||
-rw-r--r-- | pies/meta1lex.l | 2 | ||||
-rw-r--r-- | pies/pies.c | 54 | ||||
-rw-r--r-- | pies/pies.h | 14 | ||||
-rw-r--r-- | pies/progman.c | 96 |
6 files changed, 925 insertions, 86 deletions
diff --git a/doc/pies.texi b/doc/pies.texi index 136f8a9..4197bbf 100644 --- a/doc/pies.texi +++ b/doc/pies.texi @@ -2,4 +2,843 @@ @c Copyright (C) 2008 Sergey Poznyakoff @c See file mailfromd.texi for copying conditions. @c ******************************************************************* +@cindex component, pies + The name @command{pies} (pronounced @samp{p-yes}) stands for +@samp{Program Invocation and Execution Supervisor}. This utility +starts and controls execution of external programs, called +@dfn{components}. Each component is a stand-alone program, which is +executed in foreground. Upon startup, @command{pies} reads the list +of components from its configuration file, starts them, and remains in +background, controlling their execution. When any of the components +terminates, @command{pies} restarts it. Its configuration allows to +specify actions other than simple restart, depending on the exit code +of the component. + +@cindex prerequisite, pies +@cindex dependency, pies +@cindex dependents, pies +@anchor{component prerequisite} + A component @samp{A} may depend on another components, say +@samp{B} and @samp{C}, i.e. require them to be running at the moment of its +startup. Components @samp{B} and @samp{C} are called +@dfn{prerequisites} for @samp{A}, while @samp{A} is called a +@dfn{dependency} or @dfn{dependent} component of @samp{B}, @samp{C}. + + Before restarting any component, @command{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 appearence in the +configuration file. + + The standard output and standard error streams of a component can be +redirected to a file or to an arbitrary @command{syslog} channel. + +@anchor{init-style} +@cindex init-style components + These way of operation applies to so-called @dfn{init-style} +components, called so because of the similarity with the +@command{init} process manager. @command{Pies} is also able to handle +components that receive input on their @samp{stdin} and send reply to +@samp{stdout}. Such components are called @dfn{inetd-style} +components. + +@anchor{inetd-style} +@cindex inetd-style components + Inetd-style components are not executed right after @command{pies} +startup. Instead, @command{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 service that connection. In this case, the connection is +bound to component's @samp{stdin} and @samp{stdout} streams. The +@samp{stderr} stream can be redirected to a file or to syslog, as +described above. This mode of operation is sililar to that of +@command{inetd} utility. + +@anchor{meta1-style} +@cindex meta1-style components +@cindex smtps + Third type of components, supported by @command{pies} are +@dfn{meta1-style} components. As the name suggests this type is +designed expressly as a support for MeTA1 components, namely +@command{smtps}. This type can be regarded as a mixture of the above +two. For each meta1-style component @command{pies} opens a socket +after start-up, and then executes the component. Once the component +is running, @command{pies} passes it the file descriptor of the +socket, using a preconfigured @acronym{UNIX}-style socket. Further +handling of the socket is the responsibility of the component itself. + +@anchor{accept-style} +@cindex accept-style components + The last flavor of @command{pies} components are @dfn{accept-style} +components, which are handled basically as @samp{inetd-style} ones, +except that after binding to the socket @command{pies} immedately +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 appearence in the +configuration file and terminated in reverse order. When starting or +stopping component dependencies, the same order is preserved. + + This order is reversed for files included by @code{include-meta1} +statement (@pxref{include-meta1}). + +@menu +* Pies Configuration File:: +* Component Statement:: +* include-meta1:: +* Global Configuration:: +* Pies Debugging:: +* Configuration Example:: +* Pies Invocation:: +@end menu + +@node Pies Configuration File +@section Pies Configuration File + @command{Pies} reads its configuration from the main Mailutils +configuration file. @xref{configuration, Mailutils Configuration +File,, mailutils, GNU Mailutils Manual}, for a description of GNU +Mailutils configuration system. It is recommended to use +@code{include @var{directory}} statement (@pxref{Include, Include +Statement,, mailutils, GNU Mailutils Manual}), and to place +@command{pies} configuration in file @file{@var{directory}/pies}. +@xref{MeTA1}, for an example. + +The following standard Mailutils configuration statements are understood: + +@multitable @columnfractions 0.3 0.6 +@headitem Statement @tab Reference +@item debug @tab @xref{Debug Statement, Mailutils Debug Statement,, +mailutils, GNU Mailutils Manual}. +@item logging @tab @xref{Logging Statement, Mailutils Logging,, +mailutils, GNU Mailutils Manual}. +@item include @tab @xref{Include, Include Statements,, +mailutils, GNU Mailutils Manual}. +@item mailer @tab @xref{Mailer, Mailer Configuration,, +mailutils, GNU Mailutils Manual}. +@item acl @tab @xref{ACL Statement, ACL Statement,, +mailutils, GNU Mailutils Manual}. +@end multitable + +@node Component Statement +@section Component Statement +@kwindex component + The @code{component} statement defines a new component: + +@smallexample +component @var{tag} @{ + @dots{} +@} +@end smallexample + +The component is identified by its @dfn{tag}, which is given as +argument to the @code{component} keyword. + +@deffn {Pies Conf} mode @var{mode} + Declare the type (style) of the component. Accepted values for +@var{mode} are: + +@table @asis +@item exec +@itemx wait + Create an @samp{init-style} component (@pxref{init-style}). + +@item inetd +@itemx nostartaccept + Create an @samp{inetd-style} component (@pxref{inetd-style}). + +@item pass +@itemx pass-fd + Create a @samp{meta1-style} component (@pxref{meta1-style}). + +@item accept + Create a @samp{accept-style} component (@pxref{accept-style}). +@end table +@end deffn + +@deffn {Pies Conf} program @var{name} +Full file name of the component binary. This binary will be executed +(via @command{/bin/sh -c}) each time @command{pies} decides it needs +to start the component. + +To supply command line arguments, use @code{command} statement. +@end deffn + +@deffn {Pies Conf} command @var{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 @code{program} +statement. Its value will be available to the program as +@code{argv[0]}. +@end deffn + +@deffn {Pies Conf} disable @var{bool} +If @var{bool} is @samp{true}, this component is disabled, +i.e. @command{pies} will ignore it. +@end deffn + +@deffn {Pies Conf} precious @var{bool} +@cindex precious components, pies +If @var{bool} is @samp{true}, this component is marked as precious. +Precious components are never disabled by @command{pies}, even if they +respawn too fast. +@end deffn + + +@menu +* Prerequisites:: +* Component Privileges:: +* Resources:: +* Actions Before Startup:: +* Exit Actions:: +* Output Redirectors:: +* Inetd-Style Components:: +* Meta1-Style Components:: +* Component Syntax Summary:: +@end menu + +@node Prerequisites +@subsection Component Prerequisites +@cindex declaring prerequisites +@cindex prerequisites, declaring +Prerequisites (@pxref{component prerequisite}) for a component are +declared using the following statement: + +@deffn {Pies Conf} prerequisites @var{tag-list} +The argument is either a list of component tags, @emph{defined before +this component}, or one of the following words: + +@table @asis +@item all +Declare all components defined so far as prerequisites for this one. + +@item none +No prerequisites. This is the default. +@end table +@end deffn + + If you wish, you can define dependents, instead of prerequisites: + +@deffn {Pies Conf} dependents @var{tag-list} +Declare dependents for this component. @var{var-list} is a list of +component tags. +@end deffn + +@node Component Privileges +@subsection Component Privileges +@cindex privileges, pies + Following statements control the privileges with which the component +is executed. + +@deffn {Pies Conf} user @var{user-name} +Start component with the UID and GID of this user. +@end deffn + +@deffn {Pies Conf} group @var{group-list} +Retain supplementary groups, specified in @var{group-list}. +@end deffn + +@deffn {Pies Conf} allgroups @var{bool} +Retain all supplementary groups of which user, given with +@command{user} statement, is a member. This is the default for +components specified in @file{meta1.conf} file (@pxref{include-meta1}). +@end deffn + +@node Resources +@subsection Resources + +@deffn {Pies Conf} limits @var{string} +Impose limits on system resources, as defined by @var{string}. The +argument consists of @dfn{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 @code{ulimit} +utility: + +@multitable @columnfractions 0.3 0.6 +@headitem Command @tab The limit it sets +@item A @tab max address space (KB) +@item C @tab max core file size (KB) +@item D @tab max data size (KB) +@item F @tab maximum file size (KB) +@item M @tab max locked-in-memory address space (KB) +@item N @tab max number of open files +@item R @tab max resident set size (KB) +@item S @tab max stack size (KB) +@item T @tab max CPU time (MIN) +@item U @tab max number of processes +@item P @tab process priority -20..20 (negative = high priority) +@end multitable + +For example: + +@smallexample +limits T10 R20 U16 P20 +@end smallexample + +Additionally, the command letter @samp{L} is recognized. It is +reserved for future use (@samp{number of logins} limit) and is ignored +in version @value{VERSION}. +@end deffn + +@deffn {Pies Conf} umask @var{number} +Set the umask. The @var{number} must be an octal value not greater +than @samp{777}. The default umask is inherited at startup. +@end deffn + +@deffn {Pies Conf} env @var{args} +Set program environment. + +Arguments are a whitespace-delimited list of specifiers. The +following specifiers are understood: + +@table @asis +@item - (a dash) +Clear the environment. This is understood only when used as a first +word in @var{args}. + +@item -@var{name} +Unset the environment variable @var{name}. + +@item -@var{name}=@var{val} +Unset the environment variable @var{name} only if its value is @var{val}. + +@item @var{name} +Retain the environment variable @var{name}. + +@item @var{name}=@var{value} +Define environment variable @var{name} to have given @var{value}. + +@item @var{name}+=@var{value} +Retain variable @var{name} and append @var{value} to its existing +value. If no such variable is present in the environment, it is +created and @var{value} is assigned to it. However, if @var{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 @env{PATH}, e.g.: + +@smallexample +PATH+=:/sbin +@end smallexample + +In this example, if @env{PATH} exists, @samp{:/sbin} will be appended +to it. Otherwise, it will be created and @samp{/sbin} will be +assigned to it. + +@item @var{name}=+@var{value} +Retain variable @var{name} and prepend @var{value} to its existing +value. If no such variable is present in the environment, it is +created and @var{value} is assigned to it. However, if @var{value} +ends with a punctuation character, this character is removed from it +before assignment. +@end table +@end deffn + +@node Actions Before Startup +@subsection Actions Before Startup + + Several statements are available that specify actions to perform +immediately before starting the component: + +@deffn {Pies Conf} chdir @var{dir} +Change to the directory @var{dir}. +@end deffn + +@deffn {Pies Conf} remove-file @var{file-name} +Remove @var{file-name}. This is useful, for example, to remove stale +@acronym{UNIX} sockets or pid-files, which may otherwise prevent the +component from starting normally. + +As of version @value{VERSION} only one @command{remove-file} may be given. +@end deffn + +@deffn {Pies Conf} settle-timeout @var{number} +Wait @var{number} seconds. This is kind of kludge. Currently it is +used for components imported from @file{meta1.conf} file +(@pxref{include-meta1}), where @code{settle-timeout 1} is implied. +This may change in future versions. +@end deffn + +@node Exit Actions +@subsection Exit Actions +@kwindex return-code + The default behavior of @command{pies} if an @samp{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 +@code{return-code} statement: + +@smallexample +return-code @var{codes} @{ + @dots{} +@} +@end smallexample + + Its argument is a list of exit codes. Exit codes can be specified +as decimal numbers, or as symbolic code names from the table below: + +@multitable @columnfractions 0.5 0.3 +@headitem Name @tab Numeric value +@item EX_OK @tab 0 +@item EX_USAGE @tab 64 +@item EX_DATAERR @tab 65 +@item EX_NOINPUT @tab 66 +@item EX_NOUSER @tab 67 +@item EX_NOHOST @tab 68 +@item EX_UNAVAILABLE @tab 69 +@item EX_SOFTWARE @tab 70 +@item EX_OSERR @tab 71 +@item EX_OSFILE @tab 72 +@item EX_CANTCREAT @tab 73 +@item EX_IOERR @tab 74 +@item EX_TEMPFAIL @tab 75 +@item EX_PROTOCOL @tab 76 +@item EX_NOPERM @tab 77 +@item EX_CONFIG @tab 78 +@end multitable + + If the component exits with an exit code listed in @var{codes}, +@command{pies} executes actions specified by its substatements. These +are: + +@deffn {Pies Conf} action @samp{disable | restart} +If @samp{restart} is given, restart the component. This is the +default. Otherwise, mark the component and as disabled. Component +dependents are stopped and marked as disabled as well. Disabled +components are never started, unless requested by the administrator. +@end deffn + +@deffn {Pies Conf} notify @var{email-string} +Send an email notification to addresses in @var{email-string}. The +latter is a comma-separated list of email addresses, e.g.: + +@smallexample +notify "root@@localhost,postmaster@@localhost"; +@end smallexample + +The @code{mailer} statement (@pxref{Mailer, Mailer Configuration,, +mailutils, GNU Mailutils Manual}) configures the mailer used to send +the message. The message itself is configured by the @code{message} +statement. +@end deffn + +@deffn {Pies Conf} message @var{string} +Supply notification message text to use by @code{notify} statement. +@var{String} must be a valid RFC 822 message text, i.e. it must begin +with message headers, followed by an empty line and actual message +body. + +The following macro-variables are expanded within @var{string}: + +@multitable @columnfractions 0.5 0.5 +@headitem Variable @tab Expansion +@item canonical-program-name @tab @samp{pies} +@item program-name @tab Program name of the @command{pies} binary. +@item package @tab Package name (@samp{Mailfromd}). +@item version @tab Package version (@value{VERSION}). +@item mu-version @tab Version of GNU Mailutils. +@item component @tab Name of the terminated component. +@item retcode @tab Component exit code, in decimal. +@end multitable + +If @code{message} statement is not given, the following default +message is used instead: + +@smallexample +From: <> +X-Agent: $@{canonical-program-name@} ($@{package@} $@{version@}) +Subject: Component $@{component@} terminated with code $@{retcode@}. + +@end smallexample +@end deffn + + Any number of @code{return-code} statements are allowed, provided +that their @var{codes} do not intersect. + + Such statements can also be used outside of @code{component} block. +In this case, they supply global actions, i.e. actions applicable to +all components. The @code{return-code} statements appearing within a +@code{component} block override the global ones. + +@node Output Redirectors +@subsection Output Redirectors +@cindex repeater + Output redirectors allow to redirect standard error and/or standard +output of a component to a file or @command{syslog} facility. + +@deffn {Pies Conf} stderr @var{type} @var{channel} +@deffnx {Pies Conf} stdout @var{type} @var{channel} +Redirect standard error (if @code{stderr}) or standard output (if +@code{stdout}) to the given channel. + +The type of redirection is specified by @var{type} argument: + +@table @asis +@item file +Redirect to file. In this case @var{channel} gives the full name of +the file. For example: + +@smallexample +stderr file /var/log/component/name.err; +@end smallexample + +@item syslog +Redirect to the syslog channel. The syslog priority is given by the +@var{channel} argument. Its allowed values are: @samp{emerg}, +@samp{alert}, @samp{crit}, @samp{err}, @samp{warning}, @samp{notice}, +@samp{info}, @samp{debug}. The facility is inherited from the +@code{logging} statement (@pxref{Logging Statement, Mailutils Logging,, +mailutils, GNU Mailutils Manual}), or from @code{facility} statement +(see below), if given. + +Example: + +@smallexample +stderr syslog err; +@end smallexample +@end table +@end deffn + +@deffn {Pies Conf} facility @var{syslog-facility} +Specify the syslog facility to use in syslog redirectors. Allowed +values for @var{syslog-facility} are: @samp{user}, @samp{daemon}, +@samp{auth}, @samp{authpriv}, @samp{mail}, @samp{cron}, @samp{local0} +through @samp{local7} (all names case-insensitive), or a facility number. +@end deffn + +@node Inetd-Style Components +@subsection Inetd-Style Components +@cindex inetd-style components + Inetd-style components are declared using @code{mode inetd} +statement. You must also declare a socket to listen for requests for +such components: + +@anchor{inetd-socket} +@deffn {Pies Conf} socket @var{url} +Define a socket to listen on. Allowed values for @var{url} are: + +@table @asis +@item file name +Specifies a @acronym{UNIX} socket file name. You may use a relative +file name, provided that @code{chdir} statement is used for this +component (@pxref{Actions Before Startup, chdir}). + +@item local://@var{file}[;@var{args}] +@itemx file://@var{file}[;@var{args}] +@itemx unix://@var{file}[;@var{args}] +Listen on a @acronym{UNIX} socket file @var{file}, which may be either +absolute or relative file name, as described above. Optional +arguments @var{args} control ownership and file mode of @var{file}. They +are a list of assignments, separated by semicolons. The following +values are allowed: + +@table @asis +@item user +User name of the socket owner. + +@item group +Owner group of the socket, if it differs from the @code{user} group. + +@item mode +Socket file mode (octal number between @samp{0} and @samp{777}). + +@item umask +Umask to use when creating the socket (octal number between @samp{0} +and @samp{777}). +@end table + +For example: + +@smallexample +socket unix:/var/run/socket;user=nobody;group=mail;mode=770 +@end smallexample + +@item inet://@var{ip}:@var{port} +Listen on IPv4 address @var{ip} (may be given as a symbolic host name), +on port @var{port}. +@end table + +Notice, that @command{pies} version @value{VERSION} handles only +@acronym{TCP} sockets and only IPv4 addresses. Support for IPv6 will +be added in future versions. Support for @acronym{UDP} sockets will +be added if there is a demand. +@end deffn + +@node Meta1-Style Components +@subsection Meta1-Style Components +@cindex meta1-style components + Meta1-style components are declared using @code{mode pass} +statement. For such components, you must declare both a socket to +listen on (@pxref{inetd-socket} and a @acronym{UNIX} socket name to +pass the file descriptor to the component. The latter is defined +using @code{pass-fd-socket} statement: + +@deffn {Pies Conf} pass-fd-socket @var{file-name} +The argument is an absolute or relative file name of the socket file. +In the latter case, the @code{chdir @var{dir}} statement must be used +for this component (@pxref{Actions Before Startup, chdir}), and the +socket will be looked under @var{dir}. + +This socket file is supposed to be created by the component binary +upon its startup. +@end deffn + +@node Component Syntax Summary +@subsection Component Syntax Summary + This subsection summarizes the @code{component} summary. For each +statement, a reference to its detailed description is supplied. + +@smallexample +component @var{tag} @{ + # @r{Component execution mode.} + # @xref{Component Statement, mode}. + mode @samp{exec | wait | accept | inetd | nostartaccept | pass-fd | pass}; + + # @r{Full name of the program.} + # @xref{Component Statement, program}. + program @var{name}; + # @r{Command line.} + # @xref{Component Statement, command}. + command @var{string}; + + # @r{Disable this entry.} + # @xref{Component Statement, disable}. + disable @var{bool}; + # @r{Mark this entry as precious.} + # @xref{Component Statement, precious}. + precious @var{bool}; + + # @r{List of prerequisites.} + # @xref{Prerequisites}. + prerequisites (@var{compnames}); + # @r{List of components for which this one is a prerequisite.} + # @xref{Prerequisites, dependents}. + dependents (@var{compnames}); + + # @r{Listen on the given url.} + # @xref{Inetd-Style Components}. + socket @var{url}; + + # @r{Pass fd through this socket.} + # @xref{Meta1-Style Components}. + pass-fd-socket @var{soket-name}; + + # @r{ACL for this component.} + # @xref{ACL Statement, ACL Statement,, mailutils, GNU Mailutils Manual}. + acl @{ @dots{} @} + + # @r{Override default syslog facility for this component.} + facility @var{facility}; + # @r{Redirect program's standard output to the given} + # @r{file or syslog priority.} + # @xref{Output Redirectors}. + stdout @samp{file | syslog} @var{channel}; + # @r{Redirect program's standard error to the given} + # @r{file or syslog priority.} + # @xref{Output Redirectors}. + stderr @samp{file | syslog} @var{channel}; + + # @r{Run with this user privileges.} + # @xref{Component Privileges}. + user @var{user-name}; + # @r{Retain supplementary group.} + # @xref{Component Privileges, group}. + group @var{group-name}; + # @r{Retain all supplementary groups of which user is a member.} + # @xref{Component Privileges, allgroups}. + allgroups @var{bool}; + + # @r{Set system limits.} + # @xref{Resources}. + limits @var{string}; + + # @r{Force this umask.} + # @xref{Resources, umask}. + umask @var{number}; + + # @r{Set program environment.} + # @xref{Resources, env}. + env @var{assignments}; + + # @r{Change to this directory before executing the component.} + # @xref{Actions Before Startup, chdir}. + chdir @var{dir}; + # @r{Remove @var{file-name} before starting the component.} + # @xref{Actions Before Startup, remove-file}. + remove-file @var{file-name}; + # @r{Time to wait before starting this component.} + # @xref{Actions Before Startup, settle-timeout}. + settle-timeout @var{number}; + + # @r{Actions:} + # @xref{Exit Actions}. + return-code @var{exit-code-list} @{ + # @r{Action to take when a component finishes with this return code.} + action @samp{disable | restart}; + # @r{Notify these addresses when then component terminates.} + notify @var{email-string}; + # @r{Notification message text (with headers).} + message @var{string}; + @} +@} +@end smallexample + +@node include-meta1 +@section Using MeTA1 Configuration File +@cindex /etc/meta1/meta1.conf + @command{Pies} is able to take list of components from MeTA1 +configuration file: + +@deffn {Pies Conf} include-meta1 @var{file} +Parse @var{file} as MeTA1 configuration file and incorporate +components defined there into the current component list. + +For example: + +include-meta1 /etc/meta1/meta1.conf; +@end deffn + +Thus, you can use @command{pies} instead of the default MeTA1 program +manager @command{mcp}. + +To ensure compatibility with MeTA1, the components read from MeTA1 +configuration are started in reverse order (i.e. from last to first), +and stoppend in order of their appearence in @var{file}. Of course, +this does not affect normal @command{pies} components. + +The following @command{pies} statements are silently applied to +all MeTA1 components: + +@smallexample +allgroups yes; +stderr file @var{compname}.log +chdir @var{queue-dir} +@end smallexample + +Here, @var{compname} stands for the name of the component, and +@var{queue-dir} stands for the name of MeTA1 queue directory. The +latter is @file{/var/spool/meta1} by default. It can be changed using +the following statement + +@deffn {Pies Conf} meta1-queue-dir @var{dir} +Set name of MeTA1 queue directory. +@end deffn + +To override any default settings for a MeTA1 component, add a +@code{command} section with the desired settings after including +@file{meta1.conf}. For example, here is how to redirect program +diagnostics to @samp{local1.debug} syslog channel: + +@smallexample +include-meta1 /etc/meta1/meta1.conf + +component smtps @{ + facility local1; + stderr syslog debug; +@} +@end smallexample + +@node Global Configuration +@section Global Configuration +@WRITEME{} + +@ignore +# Write PID to this file. +pidfile <arg: string>; +# Set location of the control file. +control-file <arg: string>; +# Set location of the statistics output file. +stat-file <arg: string>; +# Run with this user privileges. +user <arg: string>; +# Retain supplementary group. +group <arg: list of string>; +# Retain all supplementary groups of which user is a member. +allgroups <arg: boolean>; +# Force this umask. +umask <arg: number>; +# Set global system limits +limits <arg: string>; +# Wait <n> seconds for all components to shut down. +shutdown-timeout <n: number>; +return-code <tag: exit-code-list> { +@end ignore + +@node Pies Debugging +@section Pies Debugging + The amount of debugging information produced by @command{pies} is configured +using two configuration statements. First of all, the standard +@code{debug} block statement controls debugging of the underlying GNU +Mailutils libraries (@pxref{Debug Statement, Mailutils Configuration +File,, mailutils, GNU Mailutils Manual}). Secondly, the @code{debug} +statement controls debugging output of the @command{pies} utility +itself. + +@deffn {Pies Conf} debug @var{spec} +Set debugging level for the @command{pies} code. @xref{Debug +Statement, Mailutils Configuration File,, mailutils, GNU Mailutils +Manual}, for a description of @var{spec} syntax. The following +debugging levels are used: + +@table @asis +@item trace1 +Log all basic actions: starting and stopping of components, received incoming +@acronym{TCP} connections, sending mails. Notify about setting +limits. Log pre-startup actions (@pxref{Actions Before Startup}). + +@item trace2 +Log setting particular limits. Log recomputing alarms. + +@item trace4 +Dump execution environments + +@item trace6 +Debug the parser of MeTA1 configuration grammar. + +@item trace7 +Debug the lexical analyzer of MeTA1 configuration file. +@end table +@end deffn + +@node Configuration Example +@section Configuration Example +@UNREVISED{} + +@smallexample +# 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@} --start $@{component@}' + --- + Wuff-wuff, + Pies +@} + +component pmult @{ + command "/usr/local/sbin/pmult"; + user meta1s; + stderr syslog info; + stdout syslog info; +@} + +include-meta1 "/etc/meta1/meta1.conf"; +@end smallexample + +@node Pies Invocation +@section Pies Invocation @WRITEME{} diff --git a/pies/meta1gram.y b/pies/meta1gram.y index 7ab93a7..4966634 100644 --- a/pies/meta1gram.y +++ b/pies/meta1gram.y @@ -233,7 +233,7 @@ void meta1_parser_set_debug () { mu_log_level_t lev = mu_global_debug_level ("meta1"); - if (lev & MU_DEBUG_LEVEL_MASK (MU_DEBUG_TRACE7)) + if (lev & MU_DEBUG_LEVEL_MASK (MU_DEBUG_TRACE6)) yydebug = 1; } @@ -338,7 +338,7 @@ create_string_node (const char *tag, const char *str, mu_cfg_locus_t *locus) } static mu_cfg_node_t * -create_retr_node (const char *tag, const char *dir, +create_redir_node (const char *tag, const char *dir, const char *name, mu_cfg_locus_t *locus) { mu_config_value_t *val = create_value (MU_CFG_ARRAY); @@ -411,7 +411,7 @@ translate_node_list (mu_cfg_node_t *src, const char *name) tail->next = node; tail = node; - node = create_retr_node ("stderr", META1_QUEUE_DIR (), name, locus); + node = create_redir_node ("stderr", META1_QUEUE_DIR (), name, locus); tail->next = node; tail = node; diff --git a/pies/meta1lex.l b/pies/meta1lex.l index 4d8b9d0..312a1fd 100644 --- a/pies/meta1lex.l +++ b/pies/meta1lex.l @@ -177,7 +177,7 @@ void meta1_lexer_set_debug () { mu_log_level_t lev = mu_global_debug_level ("meta1"); - yy_flex_debug = (lev & MU_DEBUG_LEVEL_MASK (MU_DEBUG_TRACE2)); + yy_flex_debug = (lev & MU_DEBUG_LEVEL_MASK (MU_DEBUG_TRACE7)); } static int diff --git a/pies/pies.c b/pies/pies.c index 836ea9c..6daf6b0 100644 --- a/pies/pies.c +++ b/pies/pies.c @@ -418,13 +418,13 @@ _cb_facility (mu_debug_t debug, void *data, mu_config_value_t *val) } static int -_cb_retr (mu_debug_t debug, void *data, mu_config_value_t *arg) +_cb_redir (mu_debug_t debug, void *data, mu_config_value_t *arg) { - struct retranslator *rp = data; - static struct mu_kwd retrtab[] = { - { "null", retr_null }, - { "syslog", retr_syslog }, - { "file", retr_file }, + struct redirector *rp = data; + static struct mu_kwd redirtab[] = { + { "null", redir_null }, + { "syslog", redir_syslog }, + { "file", redir_file }, { NULL } }; int res; @@ -434,10 +434,10 @@ _cb_retr (mu_debug_t debug, void *data, mu_config_value_t *arg) case MU_CFG_STRING: if (strcmp (arg->v.string, "null") == 0) { - rp->type = retr_null; + rp->type = redir_null; break; } - rp->type = retr_syslog; + rp->type = redir_syslog; if (mu_string_to_syslog_priority (arg->v.string, &rp->v.prio)) { mu_cfg_format_error (debug, MU_DEBUG_ERROR, @@ -450,13 +450,13 @@ _cb_retr (mu_debug_t debug, void *data, mu_config_value_t *arg) case MU_CFG_ARRAY: if (mu_cfg_assert_value_type (&arg->v.arg.v[0], MU_CFG_STRING, debug)) return 0; - if (mu_kwd_xlat_name (retrtab, arg->v.arg.v[0].v.string, &res)) + if (mu_kwd_xlat_name (redirtab, arg->v.arg.v[0].v.string, &res)) mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("%s: unrecognised retranslator type"), + _("%s: unrecognised redirector type"), arg->v.arg.v[0].v.string); else { - if (res != retr_null) + if (res != redir_null) { if (arg->v.arg.c != 2) { @@ -470,10 +470,10 @@ _cb_retr (mu_debug_t debug, void *data, mu_config_value_t *arg) switch (res) { - case retr_null: + case redir_null: break; - case retr_syslog: + case redir_syslog: if (mu_string_to_syslog_priority (arg->v.arg.v[1].v.string, &rp->v.prio)) { @@ -484,7 +484,7 @@ _cb_retr (mu_debug_t debug, void *data, mu_config_value_t *arg) } break; - case retr_file: + case redir_file: rp->v.file = xstrdup (arg->v.arg.v[1].v.string); break; } @@ -616,21 +616,21 @@ struct mu_cfg_param component_cfg_param[] = { N_("Per-component access control list") }, { "remove-file", mu_cfg_string, NULL, mu_offsetof (struct component, rmfile), NULL, - N_("Remove file before starting the component.") + N_("Remove file before starting the component."), N_("file") }, { "facility", mu_cfg_callback, NULL, mu_offsetof (struct component, facility), _cb_facility, - N_("Override default facility for this component."), + N_("Override default syslog facility for this component."), N_("arg") }, { "stdout", mu_cfg_callback, NULL, - mu_offsetof (struct component, retr[RETR_OUT]), _cb_retr, + mu_offsetof (struct component, redir[RETR_OUT]), _cb_redir, N_("Redirect program's standard output to the given file or " "syslog priority."), /* TRANSLATORS: file and syslog are keywords. Do not translate them. */ N_("type: {file | syslog}> <channel: string") }, { "stderr", mu_cfg_callback, NULL, - mu_offsetof (struct component, retr[RETR_ERR]), _cb_retr, + mu_offsetof (struct component, redir[RETR_ERR]), _cb_redir, N_("Redirect program's standard error to the given file or " "syslog priority."), /* TRANSLATORS: file and syslog are keywords. Do not translate them. */ @@ -737,26 +737,26 @@ component_verify (struct component *comp, mu_debug_t debug) } if (comp->mode != pies_comp_exec - && comp->retr[RETR_OUT].type != retr_null) + && comp->redir[RETR_OUT].type != redir_null) { - COMPERR ("%s", _("stdout retranslation invalid in this mode")); - comp->retr[RETR_OUT].type = retr_null; + COMPERR ("%s", _("stdout translation invalid in this mode")); + comp->redir[RETR_OUT].type = redir_null; } for (i = RETR_OUT; i <= RETR_ERR; i++) { - if (comp->retr[i].type == retr_file && comp->retr[i].v.file[0] != '/') + if (comp->redir[i].type == redir_file && comp->redir[i].v.file[0] != '/') { if (comp->dir) { - char *p = make_full_name (comp->dir, comp->retr[i].v.file); - free (comp->retr[i].v.file); - comp->retr[i].v.file = p; + char *p = make_full_name (comp->dir, comp->redir[i].v.file); + free (comp->redir[i].v.file); + comp->redir[i].v.file = p; } else COMPERR (_("%s: must be an absolute " "file name or chdir must be specified"), - comp->retr[i].v.file); + comp->redir[i].v.file); } } @@ -785,7 +785,7 @@ component_section_parser (enum mu_cfg_section_stage stage, { comp = xzalloc (sizeof (*comp)); comp->facility = mu_log_facility; - comp->retr[RETR_OUT].type = comp->ret |