aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-10-13 16:53:42 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-10-13 16:53:42 +0300
commitc60e857d7f35128b077eac4a30a5900925bb38e8 (patch)
treec9bae66b94b2cfbd7b8869abf1b1dbe34bcf51e9
parent8a4ba77068e5d7f6eab2cc1c1c10f31dcbccf7a6 (diff)
downloadpies-c60e857d7f35128b077eac4a30a5900925bb38e8.tar.gz
pies-c60e857d7f35128b077eac4a30a5900925bb38e8.tar.bz2
Bugfixes.
* README: Update. * configure.ac: Change bug-reporting address. * doc/pies.texi: Minor fixes. * src/pies.c: New configuration statements: mailer-program and mailer-command-line. (mailer_program, mailer_command_line) (mailer_argc, mailer_argv): New globals. * src/pies.h (mailer_program, mailer_command_line) (mailer_argc, mailer_argv): New globals. * src/progman.c (destroy_prog): Bugfix: update master program when destroying a retranslator. (send_msg): Several bugfixes. Use mailer_argc, mailer_argv instead of hardcoding sendmail command line. Remove invalid recipient addresses from the resulting command line.
-rw-r--r--README84
-rw-r--r--configure.ac2
-rw-r--r--doc/pies.texi30
-rw-r--r--src/pies.c46
-rw-r--r--src/pies.h6
-rw-r--r--src/progman.c113
6 files changed, 236 insertions, 45 deletions
diff --git a/README b/README
index e69de29..6b86aea 100644
--- a/README
+++ b/README
@@ -0,0 +1,84 @@
+Pies README
+Copyright (C) 2009 Sergey Poznyakoff
+See the end of file for copying conditions.
+
+* Introduction
+
+This file contains brief information about configuring, testing
+and running Pies. It is *not* intended as a replacement
+for the documentation, it is provided as a brief reference only.
+The complete documentation for Pies is available in
+doc/ subdirectory. To read it without installing the package
+run `info -f doc/pies.info'. After the package is installed
+the documentation can be accessed running `info Pies'. Invoking
+`info pies' (with lower-case `p') will show you a concise
+description of the command line syntax (similar to a man-page style).
+
+* Overview
+
+Pies (pronounced ``p-yes'') stands for the Program Invocation and
+Execution Supervisor. This utility starts and controls execution of
+external programs, called ``components''. Each component is a stand-alone
+program, designed to be 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 a
+component terminates, pies tries to restarts it. Its configuration allows
+to specify actions other than simple restart, depending on the exit code
+of the component.
+
+Pies supports a wide variety of component types. For example, it can
+bind the standard input and output of a component to a network socket,
+which makes pies a replacement for the inetd utility. Pies implements
+powerful access control lists, which are especially useful with such
+inetd-style components.
+
+Pies can also be used to manage MeTA1 (http://meta1.org) components.
+Moreover, it is able to use MeTA1 configuration file directly, so that
+migration from the native mcp utility to pies does not require any
+efforts.
+
+Pies gives you complete control over the execution environment of
+each component. This includes modifying shell environment, running
+components with the given user privileges, etc. The standard error
+and/or output of any component may be redirected either to a disk
+file or to syslog.
+
+* Building
+
+A usual three-state procedure:
+
+ ./configure
+ make
+ make install
+
+See INSTALL for a generic options to ./configure.
+
+* Configuring and Running
+
+Please, see the Pies documentation.
+
+* Bug reporting.
+
+Send bug reports to <bug-pies@gnu.org.ua>.
+
+
+* Copyright information:
+
+Copyright (C) 2009 Sergey Poznyakoff
+
+ Permission is granted to anyone to make or distribute verbatim copies
+ of this document as received, in any medium, provided that the
+ copyright notice and this permission notice are preserved,
+ thus giving the recipient permission to redistribute in turn.
+
+ Permission is granted to distribute modified versions
+ of this document, or of portions of it,
+ under the above conditions, provided also that they
+ carry prominent notices stating who last changed them.
+
+
+Local Variables:
+mode: outline
+paragraph-separate: "[ ]*$"
+version-control: never
+End:
diff --git a/configure.ac b/configure.ac
index e454566..6903b8e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@
# along with Pies. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ([2.63])
-AC_INIT([pies], [1.0], [bug-mailfromd@gnu.org.ua])
+AC_INIT([pies], [1.0], [bug-pies@gnu.org.ua])
AC_CONFIG_SRCDIR([src/pies.h])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
diff --git a/doc/pies.texi b/doc/pies.texi
index 22c0f83..3f9ec4b 100644
--- a/doc/pies.texi
+++ b/doc/pies.texi
@@ -153,7 +153,8 @@ described above. This mode of operation is similar to that of
@cindex smtps
The 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
+designed expressly as a support for MeTA1@footnote{See
+@uref{http://www.meta1.org}} 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
@@ -1210,9 +1211,16 @@ acl common @{
@node include-meta1
@section Using MeTA1 Configuration File
-@cindex /etc/meta1/meta1.conf
- @command{Pies} is able to take a list of components from MeTA1
-configuration file:
+@flindex /etc/meta1/meta1.conf
+ MeTA1 is a mail transfer agent of new generation, designed
+to replace Sendmail in the future (@uref{http://www.meta1.org}).
+It has a modular structure, each module being an independent
+program, which is responsible for a particular task. The components
+are configured in the MeTA1 configuration file
+@file{/etc/meta1/meta1.conf}.
+
+ @command{Pies} is able to take a list of components directly
+from MeTA1 configuration file:
@deffn {Config} include-meta1 @var{file}
Parse @var{file} as MeTA1 configuration file and incorporate
@@ -1224,12 +1232,14 @@ include-meta1 /etc/meta1/meta1.conf;
@end deffn
Thus, you can use @command{pies} instead of the default MeTA1 program
-manager @command{mcp}.
+manager @command{mcp}. This is particularly useful if you use
+@samp{Mailfromd} (@uref{http://mailfromd.software.gnu.org.ua}) to
+control the mail flow.
-To ensure compatibility with MeTA1, the components read from MeTA1
-configuration are started in the reverse order (i.e. from last to first),
-and stopped in the order of their appearance in @var{file}. Of course,
-this does not affect normal @command{pies} components.
+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 @var{file}.
+Of course, this does not affect normal @command{pies} components.
The following @command{pies} statements are silently applied to
all MeTA1 components:
@@ -1711,7 +1721,7 @@ Display program version and license information and exit.
@node Reporting Bugs
@chapter How to Report a Bug
- Send bug-reports and suggestions to @email{bug-mailfromd@@gnu.org.ua}.
+ Send bug-reports and suggestions to @email{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
diff --git a/src/pies.c b/src/pies.c
index 87ddad3..3fcc529 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -36,6 +36,11 @@ unsigned long shutdown_timeout = 5;
pies_acl_t pies_acl;
limits_record_t pies_limits;
int force_option;
+char *mailer_program = "/usr/sbin/sendmail";
+char *mailer_command_line = "/usr/sbin/sendmail -oi -t";
+int mailer_argc;
+char **mailer_argv;
+
/* Logging */
@@ -1164,6 +1169,18 @@ struct grecs_keyword pies_keywords[] = {
grecs_type_string, &meta1_queue_dir, 0,
NULL,
},
+ {"mailer-program",
+ NULL,
+ N_("Full path to the mailer binary."),
+ grecs_type_string, &mailer_program, 0,
+ NULL
+ },
+ {"mailer-command-line",
+ NULL,
+ N_("Mailer command line (without recipient addresses)."),
+ grecs_type_string, &mailer_command_line, 0,
+ NULL
+ },
{NULL}
};
@@ -1258,6 +1275,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
switch (key)
{
case 't':
+ log_to_stderr = 1;
lint_mode = 1;
break;
@@ -1274,6 +1292,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
exit (0);
case OPT_FOREGROUND:
+ log_to_stderr = 1;
foreground = 1;
break;
@@ -1671,6 +1690,28 @@ remove_pidfile (char *name)
name, strerror (errno));
}
+
+static void
+set_mailer_argcv ()
+{
+ int i;
+ struct wordsplit ws;
+
+ if (wordsplit (mailer_command_line, &ws, WRDSF_DEFFLAGS))
+ {
+ logmsg (LOG_CRIT, _("cannot parse mailer command line: %s"),
+ strerror (errno));
+ exit (EX_CONFIG);
+ }
+ mailer_argc = ws.ws_wordc;
+ mailer_argv = xcalloc (mailer_argc + 1, sizeof (mailer_argv[0]));
+ for (i = 0; i < mailer_argc; i++)
+ mailer_argv[i] = xstrdup (ws.ws_wordv[i]);
+ mailer_argv[i] = NULL;
+ wordsplit_free (&ws);
+}
+
+
const char version_etc_copyright[] =
/* Do *not* mark this string for translation. %s is a copyright
symbol suitable for this locale */
@@ -1716,7 +1757,8 @@ main (int argc, char **argv)
mf_proctitle_init (argc, argv, environ);
/* Set default logging */
- log_setup (!stderr_closed_p ());
+ log_to_stderr = !stderr_closed_p ();
+ log_setup (log_to_stderr);
config_init ();
argp_program_version_hook = version;
if (argp_parse (&argp, argc, argv, 0, &index, NULL))
@@ -1728,6 +1770,8 @@ main (int argc, char **argv)
if (grecs_parse (conffile))
exit (EX_CONFIG);
+ set_mailer_argcv ();
+
if (lint_mode)
{
progman_build_depmap ();
diff --git a/src/pies.h b/src/pies.h
index c57a104..751c2a2 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -169,8 +169,12 @@ extern char *log_tag;
extern int log_facility;
extern unsigned long shutdown_timeout;
extern struct component default_component;
-pies_acl_t pies_acl;
+extern pies_acl_t pies_acl;
extern limits_record_t pies_limits;
+extern char *mailer_program;
+extern char *mailer_command_line;
+extern int mailer_argc;
+extern char **mailer_argv;
void register_prog (struct component *comp);
size_t progman_running_count (void);
diff --git a/src/progman.c b/src/progman.c
index 3211d9a..b85a797 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -163,6 +163,23 @@ unlink_prog (struct prog *pp)
void
destroy_prog (struct prog **pp)
{
+ struct prog *p = *pp;
+ switch (p->type)
+ {
+ case TYPE_COMPONENT:
+ break;
+
+ case TYPE_RETR:
+ {
+ struct prog *master = p->v.r.master;
+ if (p == master->v.p.redir[0])
+ master->v.p.redir[0] = NULL;
+ else if (p == master->v.p.redir[1])
+ master->v.p.redir[1] = NULL;
+ else
+ logmsg (LOG_NOTICE, _("orphan redirector: %s"), p->tag);
+ }
+ }
unlink_prog (*pp);
free (*pp);
*pp = NULL;
@@ -1350,13 +1367,13 @@ wait_for_child (pid_t pid)
void
send_msg (char *rcpts, const char *msg_text)
{
- int i;
- pid_t pid;
+ int i, j, k;
+ pid_t child_pid, grand_child_pid;
struct wordsplit ws;
int p[2];
size_t size;
- ws.ws_offs = 3; /* sendmail -oi -t */
+ ws.ws_offs = mailer_argc;
ws.ws_delim = ",";
if (wordsplit (rcpts, &ws,
WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM | WRDSF_DOOFFS))
@@ -1367,12 +1384,21 @@ send_msg (char *rcpts, const char *msg_text)
return;
}
- ws.ws_wordv[0] = "/usr/sbin/sendmail"; /* FIXME: path */
- ws.ws_wordv[1] = "-oi";
- ws.ws_wordv[2] = "-t";
- for (i = 0; i < ws.ws_wordc; i++)
+ debug (1, (_("sending notification to %s"), rcpts));
+
+ /* Copy mailer arguments */
+ for (i = 0; i < mailer_argc; i++)
+ ws.ws_wordv[i] = mailer_argv[i];
+ /* j - number of the recipient;
+ i - index of the ws_wordv being converted;
+ k - index of the ws_wordv to store the converted value to.
+
+ Normally i == k, unless there are some invalid ws_wordv's,
+ in which case i > k.
+ */
+ for (j = 0, k = i; j < ws.ws_wordc; j++, i++)
{
- char *arg = ws.ws_wordv[3 + i];
+ char *arg = ws.ws_wordv[i];
size_t len;
while (*arg && c_isblank (*arg))
@@ -1384,32 +1410,34 @@ send_msg (char *rcpts, const char *msg_text)
len--;
}
if (len == 0)
- continue; //FIXME
+ continue;
if (arg[0] == '<' && arg[len-1] == '>')
{
arg++;
len -= 2;
}
if (len == 0)
- continue; //FIXME
- memmove (ws.ws_wordv[3 + i], arg, len);
- ws.ws_wordv[3 + i][len] = 0;
+ continue;
+ memmove (ws.ws_wordv[k], arg, len);
+ ws.ws_wordv[k][len] = 0;
+ k++;
}
+ ws.ws_wordv[k] = NULL;
/* Fork a child: */
- pid = fork ();
- if (pid <= 0)
+ child_pid = fork ();
+ if (child_pid != 0)
wordsplit_free (&ws);
- if (pid < 0)
+ if (child_pid < 0)
{
logmsg (LOG_ERR,
_("cannot send mail: fork failed: %s"), strerror (errno));
return;
}
- if (pid == 0)
- //FIXME: SIGCHLD Handler? */
+ if (child_pid)
+ /*FIXME: SIGCHLD Handler? */
return;
/* Child process */
@@ -1425,18 +1453,15 @@ send_msg (char *rcpts, const char *msg_text)
exit (EX_OSERR);
}
- pid = fork ();
- if (pid <= 0)
- wordsplit_free (&ws);
-
- if (pid < 0)
+ grand_child_pid = fork ();
+ if (grand_child_pid < 0)
{
logmsg (LOG_ERR,
_("cannot send mail: fork failed: %s"), strerror (errno));
return;
}
- if (pid)
+ if (grand_child_pid == 0)
{
/* Grand-child */
/* =========== */
@@ -1444,7 +1469,7 @@ send_msg (char *rcpts, const char *msg_text)
close (0);
close (p[1]);
dup2 (p[0], 0);
- execv (ws.ws_wordv[0], ws.ws_wordv);
+ execv (mailer_program, ws.ws_wordv);
exit (127);
}
@@ -1466,7 +1491,7 @@ send_msg (char *rcpts, const char *msg_text)
}
close (p[1]);
- exit (wait_for_child (pid));
+ exit (wait_for_child (grand_child_pid));
}
static const char default_termination_message[] =
@@ -1485,9 +1510,11 @@ notify (const char *tag, int status, struct action *act)
{ "version", PACKAGE_VERSION },
#define COMPONENT_IDX 3
{ "component", NULL },
-#define RETCODE_IDX 4
+#define TERMINATION_IDX 4
+ { "termination", NULL },
+#define RETCODE_IDX 5
{ "retcode", NULL },
-#define PROGRAM_NAME_IDX 5
+#define PROGRAM_NAME_IDX 6
{ "program-name", NULL },
{ NULL }
};
@@ -1496,7 +1523,21 @@ notify (const char *tag, int status, struct action *act)
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
mdef[COMPONENT_IDX].value = (char*) tag;
- mdef[RETCODE_IDX].value = umaxtostr (status, buf);
+ if (WIFEXITED (status))
+ {
+ mdef[TERMINATION_IDX].value = _("exited with code");
+ mdef[RETCODE_IDX].value = umaxtostr (WEXITSTATUS (status), buf);
+ }
+ else if (WIFSIGNALED (status))
+ {
+ mdef[TERMINATION_IDX].value = _("caught signal");
+ mdef[RETCODE_IDX].value = umaxtostr (WTERMSIG (status), buf);
+ }
+ else
+ {
+ mdef[TERMINATION_IDX].value = "UNKNOWN";
+ mdef[RETCODE_IDX].value = "UNKNOWN";
+ }
mdef[PROGRAM_NAME_IDX].value = (char*) program_name;
msg_text = meta_expand_string (act->message ?
act->message : default_termination_message,
@@ -1614,11 +1655,21 @@ progman_cleanup (int expect_term)
act = default_component.act_head;
if (WIFEXITED (status))
+ {
retcode = WEXITSTATUS (status);
+ debug (1, (_("%s: terminated with code %d"),
+ prog->tag, retcode));
+ }
else if (WIFSIGNALED (status))
+ {
retcode = STATUS_SIG_BIT | WTERMSIG (status);
+ debug (1, (_("%s: terminated on signal %d"),
+ prog->tag, retcode));
+ }
else
{
+ debug (1, (_("%s: unrecognized termination status"),
+ prog->tag));
/* Enforce default action: */
act = NULL;
}
@@ -1639,10 +1690,8 @@ progman_cleanup (int expect_term)
break;
case action_disable:
- logmsg (LOG_NOTICE,
- _("disabling component %s: "
- "exited with code %d"),
- prog->tag, status);
+ logmsg (LOG_NOTICE, _("disabling component %s"),
+ prog->tag);
prog->v.p.status = status_disabled;
}
if (act->addr)

Return to:

Send suggestions and report system problems to the System administrator.