aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--Makefile.am4
-rw-r--r--bootstrap.conf8
-rw-r--r--configure.ac16
-rw-r--r--gnulib.modules9
m---------grecs0
-rw-r--r--lib/Makefile.am17
-rw-r--r--lib/config.c115
-rw-r--r--lib/intprops.h79
-rw-r--r--lib/libpies.h45
-rw-r--r--lib/nls.c11
-rw-r--r--lib/parsetime.c6
-rw-r--r--lib/proctitle.c10
-rw-r--r--lib/userprivs.c291
-rw-r--r--src/Makefile.am34
-rw-r--r--src/depmap.c18
-rw-r--r--src/limits.c27
-rw-r--r--src/meta1gram.y387
-rw-r--r--src/meta1lex.h14
-rw-r--r--src/meta1lex.l83
-rw-r--r--src/pies.c1248
-rw-r--r--src/pies.h131
-rw-r--r--src/progman.c531
-rw-r--r--src/socket.c187
24 files changed, 1544 insertions, 1730 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..fea8f96
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "grecs"]
+ path = grecs
+ url = git://git.gnu.org.ua/grecs.git
diff --git a/Makefile.am b/Makefile.am
index f665de1..67e64f3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
-ACLOCAL_AMFLAGS = -I m4 -I am
+ACLOCAL_AMFLAGS = -I m4 -I am -I grecs/am
-SUBDIRS=gnu lib src doc po
+SUBDIRS=gnu grecs lib src doc po
# Define the following variables in order to use the ChangeLog rule below:
# prev_change_log [optional] Name of the previous ChangeLog file.
diff --git a/bootstrap.conf b/bootstrap.conf
index ff05127..02ae139 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -17,6 +17,12 @@
source_base=gnu
gnulib_name=libgnu
gnulib_mk=Makefile.am
+SKIP_PO=t
+
+if git config submodule.grecs.url >/dev/null; then : ; else
+ git submodule init || exit $?
+ git submodule update || exit $?
+fi
MODAVOID="xalloc-die openat-die"
@@ -25,7 +31,7 @@ if [ -n "$MODAVOID" ]; then
fi
# gnulib modules used by this package.
-gnulib_modules=`grep '^[^#]' gnulib.modules`
+gnulib_modules=`grep -h '^[^#]' gnulib.modules grecs/gnulib.modules | sort | uniq`
NLS_MARKERS="\
mu_error:1"
diff --git a/configure.ac b/configure.ac
index 192fc53..e454566 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,19 +1,18 @@
# This file is part of Pies. -*- autoconf -*-
# Copyright (C) 2009 Sergey Poznyakoff
#
-# This program is free software; you can redistribute it and/or modify
+# Pies is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# This program is distributed in the hope that it will be useful,
+# Pies is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-# Process this file with autoconf to produce a configure script.
+# 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])
@@ -57,11 +56,8 @@ AC_CHECK_FUNCS([alarm dup2 gethostbyname isascii memmove memset select setenv so
# Gnulib
gl_INIT
-# **********************
-# Mailutils
-# **********************
-# FIXME
-AM_GNU_MAILUTILS(2.0, [mailer cfg argp], [:])
+# Grecs
+GRECS_SETUP
# Test for setproctitle
MF_PROCTITLE
@@ -90,6 +86,8 @@ esac
AC_CONFIG_FILES([Makefile
gnu/Makefile
+ grecs/Makefile
+ grecs/src/Makefile
lib/Makefile
src/Makefile
doc/Makefile
diff --git a/gnulib.modules b/gnulib.modules
index ef40e06..e505b7e 100644
--- a/gnulib.modules
+++ b/gnulib.modules
@@ -1,10 +1,15 @@
# List of gnulib modules needed for Pies.
# A module name per line. Empty lines and comments are ignored.
+argp
+c-ctype
+c-strcase
gettext
gitlog-to-changelog
inttostr
inttypes
-xalloc
+obstack
+progname
sysexits
-c-ctype
+xalloc
+xvasprintf
diff --git a/grecs b/grecs
new file mode 160000
+Subproject 0addbd7aa72859139542010ee21bfc370f32e13
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f83e7e3..a3ffed2 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,31 +1,30 @@
-# This file is part of Mailfromd.
+# This file is part of Pies.
# Copyright (C) 2005, 2006, 2007, 2008 Sergey Poznyakoff
#
-# This program is free software; you can redistribute it and/or modify
+# Pies is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# This program is distributed in the hope that it will be useful,
+# Pies is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with Pies. If not, see <http://www.gnu.org/licenses/>. */
-noinst_LIBRARIES=libmf.a
+noinst_LIBRARIES=libpies.a
noinst_HEADERS = libpies.h
-libmf_a_SOURCES=\
- config.c\
+libpies_a_SOURCES=\
nls.c\
parsetime.c\
proctitle.c\
- userprivs.c
+ strtotok.c
-libmf_a_LIBADD=$(LIBOBJS)
+libpies_a_LIBADD=$(LIBOBJS)
INCLUDES = -I$(top_srcdir)/gnu -I../gnu
diff --git a/lib/config.c b/lib/config.c
deleted file mode 100644
index 8fcb926..0000000
--- a/lib/config.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* This file is part of Pies.
- Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <libpies.h>
-
-
-char **
-config_array_to_argv (mu_config_value_t *val, mu_debug_t debug)
-{
- int i, j;
- int argc;
- char **argv;
-
- argc = val->v.arg.c;
- argv = xcalloc (argc + 1, sizeof (argv[0]));
- for (i = j = 0; i < argc; i++)
- {
- if (mu_cfg_assert_value_type (&val->v.arg.v[i], MU_CFG_STRING,
- debug) == 0)
- argv[j++] = xstrdup (val->v.arg.v[i].v.string);
- }
- argv[j] = NULL;
- return argv;
-}
-
-char *
-config_array_to_string (mu_config_value_t *val, mu_debug_t debug)
-{
- size_t len = 0;
- int i;
- char *str, *p;
-
- for (i = 0; i < val->v.arg.c; i++)
- {
- if (mu_cfg_assert_value_type (&val->v.arg.v[i], MU_CFG_STRING, debug))
- return NULL;
- len += strlen (val->v.arg.v[i].v.string) + 1;
- }
-
- str = xmalloc (len);
- p = str;
- for (i = 0; i < val->v.arg.c; i++)
- {
- size_t n = strlen (val->v.arg.v[i].v.string);
- memcpy (p, val->v.arg.v[i].v.string, n);
- p += n;
- *p++ = ' ';
- }
- str[len-1] = 0;
- return str;
-}
-
-
-int
-config_cb_timeout (struct timeval *pt, mu_debug_t debug,
- mu_config_value_t *val)
-{
- int rc;
- const char *endp;
- time_t t;
- const char *str;
- char *alloc_str = NULL;
-
- switch (val->type)
- {
- case MU_CFG_STRING:
- str = val->v.string;
- break;
-
- case MU_CFG_ARRAY:
- str = alloc_str = config_array_to_string (val, debug);
- if (!str)
- return 1;
- break;
-
- case MU_CFG_LIST:
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("unexpected list"));
- return 1;
- }
-
- rc = parse_time_interval (str, &t, &endp);
- if (rc)
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("unrecognized time format (near `%s')"),
- endp);
- else
- {
- pt->tv_usec = 0;
- pt->tv_sec = t;
- }
- free (alloc_str);
- return 0;
-}
-
-
-
-
diff --git a/lib/intprops.h b/lib/intprops.h
deleted file mode 100644
index 7db55e9..0000000
--- a/lib/intprops.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* intprops.h -- properties of integer types
-
- Copyright (C) 2001, 2002, 2003, 2004, 2005,
- 2007 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by Paul Eggert. */
-
-#include <limits.h>
-
-/* The extra casts in the following macros work around compiler bugs,
- e.g., in Cray C 5.0.3.0. */
-
-/* True if the arithmetic type T is an integer type. bool counts as
- an integer. */
-#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
-
-/* True if negative values of the signed integer type T use two's
- complement, ones' complement, or signed magnitude representation,
- respectively. Much GNU code assumes two's complement, but some
- people like to be portable to all possible C hosts. */
-#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
-#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
-#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
-
-/* True if the arithmetic type T is signed. */
-#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-
-/* The maximum and minimum values for the integer type T. These
- macros have undefined behavior if T is signed and has padding bits.
- If this is a problem for you, please let us know how to fix it for
- your host. */
-#define TYPE_MINIMUM(t) \
- ((t) (! TYPE_SIGNED (t) \
- ? (t) 0 \
- : TYPE_SIGNED_MAGNITUDE (t) \
- ? ~ (t) 0 \
- : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
-#define TYPE_MAXIMUM(t) \
- ((t) (! TYPE_SIGNED (t) \
- ? (t) -1 \
- : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
-
-/* Return zero if T can be determined to be an unsigned type.
- Otherwise, return 1.
- When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a
- tighter bound. Otherwise, it overestimates the true bound by one byte
- when applied to unsigned types of size 2, 4, 16, ... bytes.
- The symbol signed_type_or_expr__ is private to this header file. */
-#if __GNUC__ >= 2
-# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t))
-#else
-# define signed_type_or_expr__(t) 1
-#endif
-
-/* Bound on length of the string representing an integer type or expression T.
- Subtract 1 for the sign bit if T is signed; log10 (2.0) < 146/485;
- add 1 for integer division truncation; add 1 more for a minus sign
- if needed. */
-#define INT_STRLEN_BOUND(t) \
- ((sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) * 146 / 485 \
- + signed_type_or_expr__ (t) + 1)
-
-/* Bound on buffer size needed to represent an integer type or expression T,
- including the terminating null. */
-#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
diff --git a/lib/libpies.h b/lib/libpies.h
index 4733c63..7822595 100644
--- a/lib/libpies.h
+++ b/lib/libpies.h
@@ -1,24 +1,22 @@
/* This file is part of Pies.
Copyright (C) 2009 Sergey Poznyakoff
- This program is free software; you can redistribute it and/or modify
+ Pies is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
- This program is distributed in the hope that it will be useful,
+ Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
#include <unistd.h>
#include <stdlib.h>
#include <gettext.h>
-#include <mailutils/types.h>
-#include <mailutils/cfg.h>
#define _(String) gettext(String)
@@ -41,30 +39,25 @@ void *xcalloc (size_t count, size_t size);
char *xstrdup (const char *str);
-struct mf_privs
-{
- char *user;
- int allgroups;
- mu_list_t groups;
-};
-
-int switch_to_privs (uid_t uid, gid_t gid, mu_list_t retain_groups);
-int get_user_groups (mu_list_t *pgrouplist, const char *user);
-
-void mf_priv_setup (struct mf_privs *);
-void mf_epriv_setup (struct mf_privs *);
-
-
-char **config_array_to_argv (mu_config_value_t *val, mu_debug_t debug);
-char *config_array_to_string (mu_config_value_t *val, mu_debug_t debug);
-
-int config_cb_timeout (struct timeval *pt, mu_debug_t debug,
- mu_config_value_t *val);
-
-
void mf_proctitle_init (int argc, char *argv[], char *env[]);
void mf_proctitle_format (const char *fmt, ...);
size_t longtostr (long i, char *buf, size_t size);
size_t ulongtostr (unsigned long i, char *buf, size_t size);
+
+
+struct tokendef
+{
+ char *name;
+ int tok;
+};
+
+int strtotok_len (struct tokendef *tab, const char *str, size_t len,
+ int *pres);
+int strtotok_len_ci (struct tokendef *tab, const char *str, size_t len,
+ int *pres);
+int strtotok (struct tokendef *tab, const char *str, int *pres);
+int strtotok_ci (struct tokendef *tab, const char *str, int *pres);
+int toktostr (struct tokendef *tab, int tok, const char **pres);
+
diff --git a/lib/nls.c b/lib/nls.c
index f2b067e..b42192f 100644
--- a/lib/nls.c
+++ b/lib/nls.c
@@ -1,18 +1,18 @@
-/* This file is part of Mailfromd.
- Copyright (C) 2007, 2008 Sergey Poznyakoff
+/* This file is part of Pies.
+ Copyright (C) 2009 Sergey Poznyakoff
- This program is free software; you can redistribute it and/or modify
+ Pies is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
- This program is distributed in the hope that it will be useful,
+ Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -25,7 +25,6 @@ void
mf_init_nls ()
{
#ifdef ENABLE_NLS
- mu_init_nls ();
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
bindtextdomain ("mailfromd", LOCALEDIR);
diff --git a/lib/parsetime.c b/lib/parsetime.c
index 99d8079..6b74501 100644
--- a/lib/parsetime.c
+++ b/lib/parsetime.c
@@ -1,18 +1,18 @@
/* This file is part of Pies.
Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff
- This program is free software; you can redistribute it and/or modify
+ Pies is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
- This program is distributed in the hope that it will be useful,
+ Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
diff --git a/lib/proctitle.c b/lib/proctitle.c
index f9ff967..430811c 100644
--- a/lib/proctitle.c
+++ b/lib/proctitle.c
@@ -1,18 +1,18 @@
-/* This file is part of Mailfromd.
- Copyright (C) 2007, 2008 Sergey Poznyakoff
+/* This file is part of Pies.
+ Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff
- This program is free software; you can redistribute it and/or modify
+ Pies is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
- This program is distributed in the hope that it will be useful,
+ Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
diff --git a/lib/userprivs.c b/lib/userprivs.c
deleted file mode 100644
index 8d13c38..0000000
--- a/lib/userprivs.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/* This file is part of Mailfromd.
- Copyright (C) 2007, 2008 Sergey Poznyakoff
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include <stdlib.h>
-#include <string.h>
-#include <pwd.h>
-#include <grp.h>
-#include <unistd.h>
-#include <mailutils/assoc.h>
-#include <mailutils/errno.h>
-#include <mailutils/error.h>
-#include <mailutils/errno.h>
-#include <mailutils/nls.h>
-#include <mailutils/list.h>
-#include <mailutils/iterator.h>
-/* FIXME: */
-#include <sysexits.h>
-#include "libpies.h"
-
-int
-get_user_groups (mu_list_t *pgrouplist, const char *user)
-{
- int rc;
- struct group *gr;
- mu_list_t list;
-
- if (!*pgrouplist)
- {
- rc = mu_list_create (pgrouplist);
- if (rc)
- {
- mu_error (_("%s: cannot create list: %s"),
- "get_user_groups", mu_strerror (rc));
- return rc;
- }
- }
- list = *pgrouplist;
- setgrent ();
- for (rc = 0; rc == 0 && (gr = getgrent ());)
- {
- char **p;
- for (p = gr->gr_mem; *p; p++)
- if (strcmp (*p, user) == 0)
- {
- /* FIXME: Avoid duplicating gids */
- rc = mu_list_append (list, (void *) gr->gr_gid);
- if (rc)
- mu_error (_("%s: cannot append to list: %s"),
- "get_user_groups", mu_strerror (rc));
- break;
- }
- }
- endgrent ();
- return rc;
-}
-
-/* Switch to the given UID/GID */
-int
-switch_to_privs (uid_t uid, gid_t gid, mu_list_t retain_groups)
-{
- int rc = 0;
- gid_t *emptygidset;
- size_t size = 1, j = 1;
- mu_iterator_t itr;
-
- if (uid == 0)
- {
- mu_error (_("Refusing to run as root"));
- return 1;
- }
-
- /* Create a list of supplementary groups */
- mu_list_count (retain_groups, &size);
- size++;
- emptygidset = xmalloc (size * sizeof emptygidset[0]);
- emptygidset[0] = gid ? gid : getegid ();
-
- if (mu_list_get_iterator (retain_groups, &itr) == 0)
- {
- for (mu_iterator_first (itr);
- !mu_iterator_is_done (itr); mu_iterator_next (itr))
- mu_iterator_current (itr, (void **) (emptygidset + j++));
- mu_iterator_destroy (&itr);
- }
-
- /* Reset group permissions */
- if (geteuid () == 0 && setgroups (j, emptygidset))
- {
- mu_error (_("setgroups(1, %lu) failed: %s"),
- (unsigned long) emptygidset[0], mu_strerror (errno));
- rc = 1;
- }
- free (emptygidset);
-
- /* Switch to the user's gid. On some OSes the effective gid must
- be reset first */
-
-#if defined(HAVE_SETEGID)
- if ((rc = setegid (gid)) < 0)
- mu_error (_("setegid(%lu) failed: %s"),
- (unsigned long) gid, mu_strerror (errno));
-#elif defined(HAVE_SETREGID)
- if ((rc = setregid (gid, gid)) < 0)
- mu_error (_("setregid(%lu,%lu) failed: %s"),
- (unsigned long) gid, (unsigned long) gid, mu_strerror (errno));
-#elif defined(HAVE_SETRESGID)
- if ((rc = setresgid (gid, gid, gid)) < 0)
- mu_error (_("setresgid(%lu,%lu,%lu) failed: %s"),
- (unsigned long) gid,
- (unsigned long) gid, (unsigned long) gid, mu_strerror (errno));
-#endif
-
- if (rc == 0 && gid != 0)
- {
- if ((rc = setgid (gid)) < 0 && getegid () != gid)
- mu_error (_("setgid(%lu) failed: %s"),
- (unsigned long) gid, mu_strerror (errno));
- if (rc == 0 && getegid () != gid)
- {
- mu_error (_("Cannot set effective gid to %lu"),
- (unsigned long) gid);
- rc = 1;
- }
- }
-
- /* Now reset uid */
- if (rc == 0 && uid != 0)
- {
- uid_t euid;
-
- if (setuid (uid)
- || geteuid () != uid
- || (getuid () != uid && (geteuid () == 0 || getuid () == 0)))
- {
-
-#if defined(HAVE_SETREUID)
- if (geteuid () != uid)
- {
- if (setreuid (uid, -1) < 0)
- {
- mu_error (_("setreuid(%lu,-1) failed: %s"),
- (unsigned long) uid, mu_strerror (errno));
- rc = 1;
- }
- if (setuid (uid) < 0)
- {
- mu_error (_("second setuid(%lu) failed: %s"),
- (unsigned long) uid, mu_strerror (errno));
- rc = 1;
- }
- }
- else
-#endif
- {
- mu_error (_("setuid(%lu) failed: %s"),
- (unsigned long) uid, mu_strerror (errno));
- rc = 1;
- }
- }
-
- euid = geteuid ();
- if (uid != 0 && setuid (0) == 0)
- {
- mu_error (_("seteuid(0) succeeded when it should not"));
- rc = 1;
- }
- else if (uid != euid && setuid (euid) == 0)
- {
- mu_error (_("Cannot drop non-root setuid privileges"));
- rc = 1;
- }
-
- }
-
- return rc;
-}
-
-
-static int
-translate_item (void *item, void *data)
-{
- mu_list_t dst = data;
- struct group *group = getgrnam (item);
- if (!group)
- {
- mu_error (_("Unknown group: %s"), (char *) item);
- return 1;
- }
- return mu_list_append (dst, (void *) group->gr_gid);
-}
-
-static int
-grouplist_translate (mu_list_t * pdst, mu_list_t src)
-{
- mu_list_t dst;
- int rc;
-
- if (!src)
- return 0;
- rc = mu_list_create (&dst);
- if (rc)
- {
- mu_error (_("%s: cannot create list: %s"),
- "grouplist_translate", mu_strerror (rc));
- return rc;
- }
- *pdst = dst;
- return mu_list_do (src, translate_item, dst);
-}
-
-void
-mf_priv_setup (struct mf_privs *privs)
-{
- struct passwd *pw;
- mu_list_t grp = NULL;
-
- if (!privs || !privs->user)
- return;
-
- pw = getpwnam (privs->user);
- if (!pw)
- {
- mu_error (_("No such user: %s"), privs->user);
- exit (EX_CONFIG);
- }
-
- grouplist_translate (&grp, privs->groups);
- if (privs->allgroups && get_user_groups (&grp, privs->user))
- exit (EX_CONFIG);
- if (switch_to_privs (pw->pw_uid, pw->pw_gid, grp))
- exit (EX_SOFTWARE);
- mu_list_destroy (&grp);
-}
-
-
-void
-mf_epriv_setup (struct mf_privs *privs)
-{
- uid_t uid;
- gid_t gid;
-
- if (privs)
- {
- struct passwd *pw;
- if (!privs->user)
- return;
-
- pw = getpwnam (privs->user);
- if (!pw)
- {
- mu_error (_("No such user: %s"), privs->user);
- exit (EX_CONFIG);
- }
- uid = pw->pw_uid;
- gid = pw->pw_gid;
- }
- else
- {
- uid = 0;
- gid = 0;
- }
-
- if (setegid (gid))
- {
- mu_error (_("Cannot switch to EGID %lu: %s"),
- (unsigned long) gid, mu_strerror (errno));
- exit (EX_USAGE);
- }
- if (seteuid (uid))
- {
- mu_error (_("Cannot switch to EUID %lu: %s"),
- (unsigned long) uid, mu_strerror (errno));
- exit (EX_USAGE);
- }
-}
diff --git a/src/Makefile.am b/src/Makefile.am
index 52648c8..c0c3b8a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,31 +1,38 @@
-# This file is part of mailfrom filter.
+# This file is part of Pies.
# Copyright (C) 2008, 2009 Sergey Poznyakoff
#
-# This program is free software; you can redistribute it and/or modify
+# Pies is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# This program is distributed in the hope that it will be useful,
+# Pies is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
+# along with Pies. If not, see <http://www.gnu.org/licenses/>. */
sbin_PROGRAMS = pies
pies_SOURCES = \
+ acl.c\
+ addrfmt.c\
depmap.c\
+ diag.c\
limits.c\
+ meta.c\
meta1gram.y\
meta1lex.l\
pies.c\
progman.c\
- socket.c
+ socket.c\
+ url.c\
+ userprivs.c
noinst_HEADERS = \
+ acl.h\
meta1gram.h\
meta1lex.h\
pies.h
@@ -38,20 +45,25 @@ DISTCLEANFILES = pies.rc
meta1lex.c: meta1gram.h
+incdir=$(pkgdatadir)/$(VERSION)/include
+inc_DATA = pp-setup
+
INCLUDES = \
- $(MAILUTILS_INCLUDES)\
- $(MU_COMMON_INCLUDES)\
-I$(top_srcdir)/lib\
- -I$(top_srcdir)/gnu
+ -I$(top_srcdir)/gnu\
+ -I$(top_srcdir)/grecs/src
LDADD = \
- ../lib/libmf.a\
+ ../lib/libpies.a\
+ ../grecs/src/libgrecs.a\
../gnu/libgnu.a\
- $(MAILUTILS_LIBS)\
$(MF_PROCTITLE_LIBS)
AM_CPPFLAGS=-DSYSCONFDIR=\"$(sysconfdir)\"\
- -DSTATEDIR=\"$(localstatedir)\"
+ -DSTATEDIR=\"$(localstatedir)\"\
+ -DDEFAULT_PREPROCESSOR="$(DEFAULT_PREPROCESSOR)"\
+ -DDEFAULT_VERSION_INCLUDE_DIR=\"$(incdir)\"\
+ -DDEFAULT_INCLUDE_DIR=\"$(pkgdatadir)/include\"
AM_YFLAGS=-dvt -pmeta1
AM_LFLAGS=-dvp -Pmeta1 -olex.yy.c
diff --git a/src/depmap.c b/src/depmap.c
index 76b492f..8a2772f 100644
--- a/src/depmap.c
+++ b/src/depmap.c
@@ -1,18 +1,18 @@
-/* This file is part of Mailfromd.
- Copyright (C) 2008 Sergey Poznyakoff
+/* This file is part of Pies.
+ Copyright (C) 2008, 2009 Sergey Poznyakoff
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 3 of the License, or (at your
- option) any later version.
+ Pies is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
- This program is distributed in the hope that it will be useful,
+ Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program. If not, see <http://www.gnu.org/licenses/>. */
+ You should have received a copy of the GNU General Public License
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
#include "pies.h"
diff --git a/src/limits.c b/src/limits.c
index 90d6459..3d430af 100644
--- a/src/limits.c
+++ b/src/limits.c
@@ -1,18 +1,18 @@
-/* This file is part of Mailfromd.
- Copyright (C) 2008 Sergey Poznyakoff
+/* This file is part of Pies.
+ Copyright (C) 2008, 2009 Sergey Poznyakoff
- This program is free software; you can redistribute it and/or modify
+ Pies is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
- This program is distributed in the hope that it will be useful,
+ Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
#include <pies.h>
@@ -50,15 +50,14 @@ do_set_limit (int rlimit, rlim_t limit)
{
struct rlimit rlim;
- MU_DEBUG2 (pies_debug, MU_DEBUG_TRACE1,
- "Setting limit %d to %lu\n", rlimit, (unsigned long) limit);
+ debug (1, ("setting limit %d to %lu", rlimit, (unsigned long) limit));
rlim.rlim_cur = limit;
rlim.rlim_max = limit;
if (setrlimit(rlimit, &rlim))
{
- mu_diag_output (MU_DIAG_NOTICE, _("error setting limit: %s"),
- mu_strerror (errno));
+ logmsg (LOG_NOTICE, _("error setting limit: %s"),
+ strerror (errno));
return 1;
}
return 0;
@@ -67,11 +66,11 @@ do_set_limit (int rlimit, rlim_t limit)
static int
set_prio (int prio)
{
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE2, "Setting priority to %d\n", prio);
+ debug (2, ("Setting priority to %d", prio));
if (setpriority (PRIO_PROCESS, 0, prio))
{
- mu_diag_output (MU_DIAG_NOTICE, _("error setting priority: %s"),
- mu_strerror (errno));
+ logmsg (LOG_NOTICE, _("error setting priority: %s"),
+ strerror (errno));
return 1;
}
return 0;
@@ -81,7 +80,7 @@ set_prio (int prio)
static int
check_logins (const char *name, int limit)
{
- mu_diag_output (MU_DIAG_NOTICE, _("L limit is not implemented"));
+ logmsg (LOG_NOTICE, _("L limit is not implemented"));
return 0;
}
@@ -93,7 +92,7 @@ set_limits (const char *name, struct limits_rec *lrec)
if (!lrec)
return 0;
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE2, "Setting limits for %s\n", name);
+ debug (2, ("setting limits for %s", name));
#if defined(RLIMIT_AS)
if (lrec->set & SET_LIMIT_AS)
diff --git a/src/meta1gram.y b/src/meta1gram.y
index 4966634..db92d61 100644
--- a/src/meta1gram.y
+++ b/src/meta1gram.y
@@ -1,6 +1,6 @@
%{
-/* MeTA1 configuration parser for Mailfromd.
- Copyright (C) 2008 Sergey Poznyakoff
+/* MeTA1 configuration parser for Pies.
+ Copyright (C) 2008, 2009 Sergey Poznyakoff
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,99 +22,98 @@
#include "pies.h"
#include "meta1lex.h"
-/* FIXME: Use mu_opool_alloc? */
-static mu_config_value_t *
-create_value (int type)
+#define META1_QUEUE_DIR() \
+ (meta1_queue_dir ? meta1_queue_dir : "/var/spool/meta1")
+
+enum meta1_stmt_type
+{
+ meta1_simple,
+ meta1_block
+};
+
+struct meta1_stmt
+{
+ struct meta1_stmt *next;
+ grecs_locus_t locus;
+ enum meta1_stmt_type type;
+ const char *ident;
+ union
+ {
+ grecs_value_t *value;
+ struct meta1_stmt *list;
+ } v;
+};
+
+struct meta1_stmt *
+meta1_stmt_create (enum meta1_stmt_type type, const char *ident)
{
- mu_config_value_t *val = mu_alloc (sizeof (*val));
- val->type = type;
- return val;
+ struct meta1_stmt *p = xmalloc (sizeof (*p));
+ p->next = NULL;
+ p->type = type;
+ p->ident = ident;
+ p->locus = meta1_locus;
+ return p;
}
-static mu_config_value_t *
-config_value_dup (mu_config_value_t *src)
+static struct meta1_stmt *
+_reverse (struct meta1_stmt *list, struct meta1_stmt **root)
{
- if (!src)
- return NULL;
- else
+ struct meta1_stmt *next;
+
+ if (list->next == NULL)
{
- mu_config_value_t *val = mu_alloc (sizeof (*val));
- *val = *src;
- return val;
+ *root = list;
+ return list;
}
+ next = _reverse (list->next, root);
+ next->next = list;
+ list->next = NULL;
+ return list;
}
-static mu_cfg_node_t *
-alloc_node (enum mu_cfg_node_type type, mu_cfg_locus_t *loc,
- const char *tag, mu_config_value_t *label,
- mu_cfg_node_t *node)
+static struct meta1_stmt *
+reverse (struct meta1_stmt *in)
{
- char *p;
- mu_cfg_node_t *np;
- size_t size = sizeof *np + strlen (tag) + 1;
- np = mu_alloc (size);
- np->type = type;
- np->locus = *loc;
- p = (char*) (np + 1);
- np->tag = p;
- strcpy (p, tag);
- np->label = label;
- np->node = node;
- np->next = NULL;
- return np;
+ struct meta1_stmt *root;
+ if (!in)
+ return in;
+ _reverse (in, &root);
+ return root;
}
-static mu_cfg_node_t *translate_component (mu_cfg_node_t *);
-
-mu_cfg_node_t *meta1_parse_head;
-
+static void meta1_translate (struct meta1_stmt *);
%}
%union {
- mu_cfg_node_t node;
- mu_cfg_node_t *pnode;
- mu_config_value_t *value;
- struct { mu_cfg_node_t *head, *tail; } nodelist;
char *string;
- unsigned long number;
- mu_list_t list;
+ gl_list_t list;
+ grecs_value_t *value;
+ struct meta1_stmt *stmt;
}
%token <string> META1_IDENT META1_STRING META1_NUMBER
-
-%type <nodelist> stmtlist
-%type <pnode> stmt simple block
-%type <list> slist list values
-%type <string> string ident
+%type <list> slist values list
%type <value> value
-
+%type <string> string ident
+%type <stmt> stmtlist stmt simple block
%%
input : stmtlist
{
- mu_cfg_node_t *node;
- meta1_parse_head = NULL;
- for (node = $1.head; node; node = node->next)
- {
- mu_cfg_node_t *new_node = translate_component (node);
- if (new_node)
- {
- new_node->next = meta1_parse_head;
- meta1_parse_head = new_node;
- }
- }
+ struct meta1_stmt *stmt;
+ for (stmt = $1; stmt; stmt = stmt->next)
+ meta1_translate (stmt);
}
;
stmtlist: stmt
{
- $$.head = $$.tail = $1;
+ $$ = $1;
}
| stmtlist stmt
{
- $$ = $1;
- $$.tail->next = $2;
- $$.tail = $2;
+ $2->next = $1;
+ $$ = $2;
}
;
@@ -124,18 +123,15 @@ stmt : simple
simple : ident '=' value opt_sc
{
- $$ = alloc_node (mu_cfg_node_param, &meta1_locus,
- $1, $3,
- NULL);
+ $$ = meta1_stmt_create (meta1_simple, $1);
+ $$->v.value = $3;
}
;
block : ident tag '{' stmtlist '}' opt_sc
{
- /* FIXME: tag is currently ignored */
- $$ = alloc_node (mu_cfg_node_tag, &meta1_locus,
- $1, NULL,
- $4.head);
+ $$ = meta1_stmt_create (meta1_block, $1);
+ $$->v.list = reverse ($4);
}
;
@@ -148,17 +144,20 @@ ident : META1_IDENT
value : string
{
- $$ = create_value (MU_CFG_STRING);
+ $$ = xmalloc (sizeof (*$$));
+ $$->type = GRECS_TYPE_STRING;
$$->v.string = $1;
}
| list
{
- $$ = create_value (MU_CFG_LIST);
+ $$ = xmalloc (sizeof (*$$));
+ $$->type = GRECS_TYPE_LIST;
$$->v.list = $1;
}
| META1_NUMBER
{
- $$ = create_value (MU_CFG_STRING);
+ $$ = xmalloc (sizeof (*$$));
+ $$->type = GRECS_TYPE_STRING;
$$->v.string = $1;
}
;
@@ -166,31 +165,29 @@ value : string
string : META1_IDENT
| slist
{
- mu_iterator_t itr;
- mu_list_get_iterator ($1, &itr);
+ const void *p;
+ gl_list_iterator_t itr = gl_list_iterator ($1);
meta1_line_begin ();
- for (mu_iterator_first (itr);
- !mu_iterator_is_done (itr); mu_iterator_next (itr))
- {
- char *p;
- mu_iterator_current (itr, (void**)&p);
+ while (gl_list_iterator_next (&itr, &p, NULL))
meta1_line_add (p, strlen (p));
- }
+ gl_list_iterator_free (&itr);
$$ = meta1_line_finish ();
- mu_iterator_destroy (&itr);
- mu_list_destroy (&$1);
}
;
slist : META1_STRING
{
- mu_list_create (&$$);
- mu_list_append ($$, $1);
+ $$ = gl_list_create_empty (&gl_linked_list_implementation,
+ NULL,
+ NULL,
+ NULL,
+ true);
+ gl_list_add_last ($$, $1);
}
| slist META1_STRING
{
- mu_list_append ($1, $2);
+ gl_list_add_last ($1, $2);
$$ = $1;
}
;
@@ -207,12 +204,16 @@ list : '{' values '}'
values : value
{
- mu_list_create (&$$);
- mu_list_append ($$, $1);
+ $$ = gl_list_create_empty (&gl_linked_list_implementation,
+ NULL,
+ NULL,
+ NULL,
+ true);
+ gl_list_add_last ($$, $1);
}
| values ',' value
{
- mu_list_append ($1, $3);
+ gl_list_add_last ($1, $3);
$$ = $1;
}
;
@@ -232,19 +233,27 @@ yyerror (char *s)
void
meta1_parser_set_debug ()
{
- mu_log_level_t lev = mu_global_debug_level ("meta1");
- if (lev & MU_DEBUG_LEVEL_MASK (MU_DEBUG_TRACE6))
- yydebug = 1;
+ char *p = getenv ("META1_DEBUG_YACC");
+ yydebug = p && (*p - '0') > 0;
}
+static struct meta1_stmt *
+find_stmt (struct meta1_stmt *stmt, const char *ident)
+{
+ for (; stmt; stmt = stmt->next)
+ if (strcmp (stmt->ident, ident) == 0)
+ break;
+ return stmt;
+}
+
+
struct node_trans
{
char *name;
char *new_name;
- mu_cfg_node_t *(*fun) (const char *, mu_cfg_node_t *);
+ int (*xlat) (struct meta1_stmt *stmt, struct component *comp);
};
-
static struct node_trans *
find_node_trans (struct node_trans *tab, const char *name)
{
@@ -254,54 +263,43 @@ find_node_trans (struct node_trans *tab, const char *name)
return NULL;
}
-static mu_cfg_node_t *
-find_node (mu_cfg_node_t *list, const char *name)
-{
- for (; list; list = list->next)
- {
- if (strcmp (list->tag, name) == 0)
- return list;
- }
- return NULL;
-}
-
-static mu_cfg_node_t *
-xlat_listen_socket (const char *name, mu_cfg_node_t *src)
+static int
+xlat_listen_socket (struct meta1_stmt *stmt, struct component *comp)
{
- mu_cfg_node_t *p;
- mu_config_value_t *val;
+ struct meta1_stmt *p;
+ grecs_value_t *val;
+ p = find_stmt (stmt->v.list, "type");
+ if (!p || !p->v.value || p->v.value->type != GRECS_TYPE_STRING)
+ return 1;
meta1_line_begin ();
- p = find_node (src->node, "type");
- if (!p || !p->label || p->label->type != MU_CFG_STRING)
- return NULL;
- meta1_line_add (p->label->v.string, strlen (p->label->v.string));
+ meta1_line_add (p->v.value->v.string, strlen (p->v.value->v.string));
meta1_line_add ("://", 3);
- if (strcmp (p->label->v.string, "inet") == 0)
+ if (strcmp (p->v.value->v.string, "inet") == 0)
{
const char *addr;
- p = find_node (src->node, "address");
+ p = find_stmt (stmt->v.list, "address");
if (p)
{
- if (p->label->type != MU_CFG_STRING)
- return NULL;
- addr = p->label->v.string;
+ if (p->v.value->type != GRECS_TYPE_STRING)
+ return 1;
+ addr = p->v.value->v.string;
}
else
addr = "0.0.0.0";
meta1_line_add (addr, strlen (addr));
meta1_line_add (":", 1);
- p = find_node (src->node, "port");
- if (p->label->type != MU_CFG_STRING)
- return NULL;
- meta1_line_add (p->label->v.string, strlen (p->label->v.string));
+ p = find_stmt (stmt->v.list, "port");
+ if (p->v.value->type != GRECS_TYPE_STRING)
+ return 1;
+ meta1_line_add (p->v.value->v.string, strlen (p->v.value->v.string));
}
- else if (strcmp (p->label->v.string, "unix") == 0)
+ else if (strcmp (p->v.value->v.string, "unix") == 0)
{
- p = find_node (src->node, "path");
- if (!p || p->label->type != MU_CFG_STRING)
- return NULL;
- meta1_line_add (p->label->v.string, strlen (p->label->v.string));
+ p = find_stmt (stmt->v.list, "path");
+ if (!p || p->v.value->type != GRECS_TYPE_STRING)
+ return 1;
+ meta1_line_add (p->v.value->v.string, strlen (p->v.value->v.string));
/* FIXME: Other substatements:
listen_socket {
type=unix;
@@ -312,11 +310,15 @@ xlat_listen_socket (const char *name, mu_cfg_node_t *src)
}
*/
}
- val = create_value (MU_CFG_STRING);
+ val = xmalloc (sizeof (*val));
+ val->type = GRECS_TYPE_STRING;
val->v.string = meta1_line_finish ();
- return alloc_node (mu_cfg_node_param, &src->locus, "socket", val, NULL);
+ stmt->type = meta1_simple;
+ stmt->v.value = val;
+ return 0;
}
+
static struct node_trans root_node_trans[] = {
{ "listen_socket", "socket", xlat_listen_socket },
{ "start_action", "mode" },
@@ -328,112 +330,45 @@ static struct node_trans root_node_trans[] = {
{ NULL }
};
-static mu_cfg_node_t *
-create_string_node (const char *tag, const char *str, mu_cfg_locus_t *locus)
+static void
+meta1_translate_stmt (struct meta1_stmt *stmt, struct component *comp)
{
- mu_config_value_t *val = create_value (MU_CFG_STRING);
+ struct grecs_keyword *kwp;
- val->v.string = meta1_string (str, strlen (str));
- return alloc_node (mu_cfg_node_param, locus, tag, val, NULL);
-}
+ struct node_trans *nt = find_node_trans (root_node_trans, stmt->ident);
+ if (!nt)
+ return;
-static mu_cfg_node_t *
-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);
- val->v.arg.c = 2;
- val->v.arg.v = mu_alloc (2 * sizeof (val->v.arg.v[0]));
+ kwp = find_component_keyword (nt->new_name);
+ if (!kwp)
+ abort ();
- val->v.arg.v[1].type = MU_CFG_STRING;
- val->v.arg.v[0].v.string = meta1_string ("file", 4);
+ if (nt->xlat && nt->xlat (stmt, comp))
+ return;
- val->v.arg.v[1].type = MU_CFG_STRING;
- meta1_line_begin ();
- meta1_line_add (dir, strlen (dir));
- meta1_line_add ("/", 1);
- meta1_line_add (name, strlen (name));
- meta1_line_add (".log", 4);
- val->v.arg.v[1].v.string = meta1_line_finish ();
-
- return alloc_node (mu_cfg_node_param, locus, tag, val, NULL);
-}
-
-static mu_cfg_node_t *
-translate_node (mu_cfg_node_t *src)
-{
- mu_cfg_node_t *dst = NULL;
- struct node_trans *nt = find_node_trans (root_node_trans, src->tag);
-
- if (nt)
- {
- if (nt->fun)
- dst = nt->fun (nt->new_name, src);
- else
- dst = alloc_node (mu_cfg_node_param, &src->locus,
- nt->new_name, config_value_dup (src->label),
- NULL);
- }
- return dst;
+ grecs_process_ident (kwp, stmt->v.value, comp, &stmt->locus);
}
-#define META1_QUEUE_DIR() \
- (meta1_queue_dir ? meta1_queue_dir : "/var/spool/meta1")
-
-static mu_cfg_node_t *
-translate_node_list (mu_cfg_node_t *src, const char *name)
+static void
+meta1_translate (struct meta1_stmt *stmt)
{
- mu_cfg_node_t *head = NULL, *tail = NULL;
- mu_cfg_locus_t *locus = &src->locus;
+ struct component *comp;
+ struct meta1_stmt *p;
- for (; src; src = src->next)
- {
- mu_cfg_node_t *dst = translate_node (src);
- if (dst)
- {
- if (tail)
- tail->next = dst;
- else
- head = dst;
- tail = dst;
- }
- }
- if (head)
- {
- /* Add common statements: */
- mu_cfg_node_t *node;
-
- node = create_string_node ("allgroups", "yes", locus);
- tail->next = node;
- tail = node;
-
- node = create_string_node ("chdir", META1_QUEUE_DIR (), locus);
- tail->next = node;
- tail = node;
+ if (stmt->type != meta1_block)
+ return;
- node = create_redir_node ("stderr", META1_QUEUE_DIR (), name, locus);
- tail->next = node;
- tail = node;
-
- node = create_string_node ("settle-timeout", "1", locus);
- tail->next = node;
- tail = node;
- }
- return head;
-}
-
-static mu_cfg_node_t *
-translate_component (mu_cfg_node_t *src)
+ comp = component_create (stmt->ident);
+ for (p = stmt->v.list; p; p = p->next)
{
- mu_cfg_node_t *dst = NULL;
- if (src->type == mu_cfg_node_tag)
- {
- mu_config_value_t *val = create_value (MU_CFG_STRING);
- val->v.string = meta1_string (src->tag, strlen (src->tag));
- dst = alloc_node (mu_cfg_node_tag, &src->locus,
- "component", val,
- translate_node_list (src->node, val->v.string));
+ meta1_translate_stmt (p, comp);
}
- return dst;
+ comp->privs.allgroups = 1;
+ comp->dir = META1_QUEUE_DIR ();
+ comp->settle_timeout = 1;
+ comp->redir[RETR_ERR].type = redir_file;
+ comp->redir[RETR_ERR].v.file = xasprintf ("%s/%s.log",
+ META1_QUEUE_DIR (),
+ comp->tag);
+ component_finish (comp, &stmt->locus);
}
-
diff --git a/src/meta1lex.h b/src/meta1lex.h
index 8db32f9..035204b 100644
--- a/src/meta1lex.h
+++ b/src/meta1lex.h
@@ -1,23 +1,21 @@
-/* This file is part of Mailfromd.
- Copyright (C) 2008 Sergey Poznyakoff
+/* This file is part of Pies.
+ Copyright (C) 2009, 2009 Sergey Poznyakoff
- This program is free software; you can redistribute it and/or modify
+ Pies is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
- This program is distributed in the hope that it will be useful,
+ Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
-extern mu_cfg_locus_t meta1_locus;
+extern grecs_locus_t meta1_locus;
extern size_t meta1_error_count;
-extern mu_cfg_node_t *meta1_parse_head;
-extern mu_cfg_tree_t *meta1_parse_tree;
extern char *meta1_queue_dir;
char *meta1_string (const char *str, size_t len);
diff --git a/src/meta1lex.l b/src/meta1lex.l
index 312a1fd..0f08d87 100644
--- a/src/meta1lex.l
+++ b/src/meta1lex.l
@@ -1,6 +1,6 @@
%{
-/* MeTA1 configuration lexer for Mailfromd.
- Copyright (C) 2008 Sergey Poznyakoff
+/* MeTA1 configuration lexer for Pies.
+ Copyright (C) 2008, 2009 Sergey Poznyakoff
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,9 +22,10 @@
#include "meta1gram.h"
#include "meta1lex.h"
-mu_cfg_locus_t meta1_locus;
+grecs_locus_t meta1_locus;
size_t meta1_error_count;
-mu_opool_t meta1_pool;
+struct obstack meta1_stk;
+int meta1_stk_init;
char *meta1_queue_dir;
#define yylval meta1lval
@@ -98,7 +99,22 @@ yywrap ()
void
meta1_line_add (const char *text, size_t len)
{
- mu_opool_append (meta1_pool, text, len);
+ obstack_grow (&meta1_stk, text, len);
+}
+
+static char quote_transtab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
+
+static int
+unescape_char (int c)
+{
+ char *p;
+
+ for (p = quote_transtab; *p; p += 2)
+ {
+ if (*p == c)
+ return p[1];
+ }
+ return c;
}
static void
@@ -110,17 +126,17 @@ unescape_to_line (int c)
t = '\v';
else
{
- t = mu_argcv_unquote_char (c);
+ t = unescape_char (c);
if (t == c && t != '\\' && t != '\"')
meta1_parse_error (_("unknown escape sequence '\\%c'"), c);
}
- mu_opool_append_char (meta1_pool, t);
+ obstack_1grow (&meta1_stk, t);
}
void
meta1_line_add_unescape_last (const char *text, size_t len)
{
- mu_opool_append (meta1_pool, text, len - 2);
+ obstack_grow (&meta1_stk, text, len - 2);
unescape_to_line (text[len - 1]);
}
@@ -129,24 +145,25 @@ meta1_line_add_unescape_hex (const char *text, size_t len)
{
for (; text[len-1] != 'x' && len > 0; len--)
;
- mu_opool_append (meta1_pool, text, len - 2);
- mu_opool_append_char (meta1_pool, (char) strtoul (text + len, NULL, 16));
+ obstack_grow (&meta1_stk, text, len - 2);
+ obstack_1grow (&meta1_stk, (char) strtoul (text + len, NULL, 16));
}
void
meta1_line_begin ()
{
- if (!meta1_pool)
- mu_opool_create (&meta1_pool, 1);
- else
- mu_opool_clear (meta1_pool);
+ if (!meta1_stk_init)
+ {
+ obstack_init (&meta1_stk);
+ meta1_stk_init = 1;
+ }
}
char *
meta1_line_finish ()
{
- mu_opool_append_char (meta1_pool, 0);
- return mu_opool_finish (meta1_pool, NULL);
+ obstack_1grow (&meta1_stk, 0);
+ return obstack_finish (&meta1_stk);
}
char *
@@ -161,34 +178,23 @@ void
meta1_parse_error (const char *fmt, ...)
{
va_list ap;
- mu_debug_t debug;
- mu_diag_get_debug (&debug);
- mu_debug_printf (debug, 0, "%s:%lu: ", meta1_locus.file,
+ logmsg_printf (LOG_ERR, "%s:%lu: ", meta1_locus.file,
(unsigned long) meta1_locus.line);
va_start (ap, fmt);
- mu_debug_vprintf (debug, 0, fmt, ap);
- mu_debug_printf (debug, 0, "\n");
+ logmsg_vprintf (LOG_ERR, fmt, ap);
va_end (ap);
+ logmsg_printf (LOG_ERR, "\n");
meta1_error_count++;
}
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_TRACE7));
+ char *p = getenv ("META1_DEBUG_LEX");
+ yy_flex_debug = p && (*p - '0') > 0;
}
-static int
-_cfg_default_printer (void *unused, mu_log_level_t level, const char *str)
-{
- fprintf (stderr, "%s", str);
- return 0;
-}
-
-mu_cfg_tree_t *meta1_parse_tree;
-
/* Parse MeTA1 configuration file `name'. Populate `meta1_parse_tree' with
the parse tree. */
int
@@ -200,7 +206,8 @@ meta1_config_parse (const char *name)
fp = fopen (name, "r");
if (!fp)
{
- mu_error (_("%s: cannot open file: %s"), name, mu_strerror (errno));
+ logmsg (LOG_ERR,
+ _("%s: cannot open file: %s"), name, strerror (errno));
return 1;
}
meta1_locus.file = meta1_string (name, strlen (name));
@@ -213,16 +220,6 @@ meta1_config_parse (const char *name)
fclose (fp);
if (meta1_error_count)
rc = 1;
- if (rc == 0)
- {
- meta1_parse_tree = mu_alloc (sizeof (*meta1_parse_tree));
- mu_debug_create (&meta1_parse_tree->debug, NULL);
- mu_debug_set_print (meta1_parse_tree->debug, _cfg_default_printer, NULL);
- mu_debug_set_level (meta1_parse_tree->debug,
- mu_global_debug_level ("meta1"));
- meta1_parse_tree->node = meta1_parse_head;
- meta1_parse_tree->pool = meta1_pool;
- }
return rc;
}
diff --git a/src/pies.c b/src/pies.c
index 10862c2..f36c21f 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -1,27 +1,29 @@
-/* This file is part of Mailfromd.
+/* This file is part of Pies.
Copyright (C) 2008, 2009 Sergey Poznyakoff
- This program is free software; you can redistribute it and/or modify
+ Pies is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
- This program is distributed in the hope that it will be useful,
+ Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
#include "pies.h"
#include "meta1lex.h"
+char *conffile = SYSCONFDIR "/pies.conf";
+int preprocess_only; /* Preprocess config, do nothing more */
+int lint_mode; /* Test configuration syntax and exit */
int log_to_stderr; /* Use stderr for logging */
-char *log_tag; /* override mu_log_tag */
-mu_log_level_t debug_level;
-mu_debug_t pies_debug;
-struct mf_privs pies_privs;
+int log_facility = LOG_USER;
+char *log_tag;
+struct pies_privs pies_privs;
int foreground;
int command;
char *pidfile = STATEDIR "/pies.pid";
@@ -29,7 +31,7 @@ char *ctlfile = STATEDIR "/pies.ctl";
char *statfile = STATEDIR "/pies.stat";
mode_t pies_umask = 0;
unsigned long shutdown_timeout = 5;
-mu_acl_t pies_acl;
+pies_acl_t pies_acl;
limits_record_t pies_limits;
int force_option;
@@ -38,21 +40,8 @@ int force_option;
void
log_setup (int want_stderr)
{
- mu_debug_t debug;
-
- mu_diag_get_debug (&debug);
-
- if (log_tag)
- mu_log_tag = log_tag;
-
if (!want_stderr)
- {
- openlog (MU_LOG_TAG (), LOG_PID, mu_log_facility);
- mu_debug_set_print (debug, mu_diag_syslog_printer, NULL);
- mu_debug_default_printer = mu_debug_syslog_printer;
- }
- else
- mu_debug_default_printer = mu_debug_stderr_printer;
+ openlog (log_tag, LOG_PID, log_facility);
}
static int
@@ -66,75 +55,88 @@ stderr_closed_p()
}
-static int
-_cb_action (mu_debug_t debug, void *data, mu_config_value_t *arg)
+int
+assert_grecs_value_type (grecs_locus_t * locus,
+ const grecs_value_t * value, int type)
{
- enum return_action *pact = data;
- static struct mu_kwd actab[] = {
- { "disable", action_disable },
- { "restart", action_restart },
- { NULL }
- };
- int res;
-
- if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug))
- return 1;
- if (mu_kwd_xlat_name (actab, arg->v.string, &res))
+ if (!value || value->type != type)
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("unknown action code: %s"), arg);
+ grecs_error (locus, 0, _("expected %s, but found %s"),
+ grecs_data_type_string (type),
+ grecs_data_type_string (value->type));
+ return 1;
+ }
return 0;
}
- *pact = res;
+
+int
+assert_scalar_stmt (grecs_locus_t * locus, enum grecs_callback_command cmd)
+{
+ if (cmd != grecs_callback_set_value)
+ {
+ grecs_error (locus, 0, _("Unexpected block statement"));
+ return 1;
+ }
return 0;
}
+
static int
-_cb_notify_addr (mu_debug_t debug, void *data, mu_config_value_t *arg)
+_cb_action (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr, grecs_value_t * value, void *cb_data)
{
- mu_address_t *paddr = data;
- mu_address_t addr;
- int rc;
+ enum return_action *pact = varptr;
+ static struct tokendef actab[] = {
+ {"disable", action_disable},
+ {"restart", action_restart},
+ {NULL}
+ };
+ int res;
- if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug))
+ if (assert_scalar_stmt (locus, cmd)
+ || assert_grecs_value_type (locus, value, GRECS_TYPE_STRING))
return 1;
- rc = mu_address_create (&addr, arg->v.string);
- if (rc)
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("%s: invalid e-mail address: %s"),
- arg->v.string, mu_strerror (rc));
- if (*paddr)
+ if (strtotok (actab, value->v.string, &res))
{
- mu_address_union (paddr, addr);
- mu_address_destroy (&addr);
+ grecs_error (locus, 0, _("unknown action code: %s"), value->v.string);
+ return 1;
}
- else
- *paddr = addr;
+ *pact = res;
return 0;
}
-struct mu_cfg_param return_code_cfg_param[] = {
- { "action", mu_cfg_callback, NULL,
- mu_offsetof (struct component, act_temp.act), _cb_action,
+struct grecs_keyword return_code_cfg_param[] = {
+ {"action",
+ /* TRANSLATORS: disable and restart are keywords, do not translate them. */
+ N_("arg: {disable | restart}"),
N_("Specifies action to take when a component finishes with this "
"return code."),
- /* TRANSLATORS: disable and restart are keywords, do not translate them. */
- N_("arg: {disable | restart}") },
- { "notify", mu_cfg_callback, NULL,
- mu_offsetof (struct component, act_temp.addr), _cb_notify_addr,
+ grecs_type_string, NULL, offsetof (struct component, act_temp.act),
+ _cb_action,
+ },
+ {"notify",
+ N_("arg: emails"),
N_("Notify this address when then component terminates."),
- N_("arg: email-list") },
- { "message", mu_cfg_string, NULL,
- mu_offsetof (struct component, act_temp.message), NULL,
- N_("Notification message text (with headers).") },
- { "exec", mu_cfg_string, NULL,
- mu_offsetof (struct component, act_temp.command), NULL,
- N_("Execute this command.") },
+ grecs_type_string, NULL, offsetof (struct component, act_temp.addr)
+ },
+ {"message",
+ NULL,
+ N_("Notification message text (with headers)."),
+ grecs_type_string, NULL, offsetof (struct component, act_temp.message),
+ NULL},
+ {"exec",
+ NULL,
+ N_("Execute this command."),
+ grecs_type_string, NULL,
+ offsetof (struct component, act_temp.command),
+ NULL,
+ },
{NULL}
};
#define S(s) { #s, s }
-static struct mu_kwd ex_kwtab[] = {
+static struct tokendef ex_tokendef[] = {
S (EX_OK),
S (EX_USAGE),
S (EX_DATAERR),
@@ -154,7 +156,7 @@ static struct mu_kwd ex_kwtab[] = {
{NULL}
};
-static struct mu_kwd sig_kwtab[] = {
+static struct tokendef sig_tokendef[] = {
S (SIGHUP),
S (SIGINT),
S (SIGQUIT),
@@ -212,12 +214,14 @@ static struct mu_kwd sig_kwtab[] = {
#endif
{NULL}
};
+
#undef S
static struct action *
create_action (struct component *comp,
- mu_debug_t debug, mu_config_value_t *val, int argc,
- const char *(*getarg) (mu_config_value_t *, int, mu_debug_t))
+ grecs_locus_t * locus,
+ grecs_value_t * val, int argc,
+ const char *(*getarg) (grecs_value_t *, int, grecs_locus_t *))
{
int i;
unsigned *retv;
@@ -226,14 +230,14 @@ create_action(struct component *comp,
struct action *act;
retv = xcalloc (argc, sizeof *retv);
- if (argc == 0 || (argc == 1 && strcmp (getarg(val, 0, debug), "*") == 0))
+ if (argc == 0 || (argc == 1 && strcmp (getarg (val, 0, locus), "*") == 0))
allflag = 1;
else
{
for (i = 0; i < argc; i++)
{
unsigned n;
- const char *arg = getarg(val, i, debug);
+ const char *arg = getarg (val, i, locus);
size_t len = strlen (arg);
if (isdigit (arg[0]))
@@ -242,8 +246,7 @@ create_action(struct component *comp,
n = strtoul (arg, &p, 0);
if (*p)
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("%s: not a number"), p);
+ grecs_error (locus, 0, _("%s: not a number"), p);
continue;
}
}
@@ -255,23 +258,20 @@ create_action(struct component *comp,
n = strtoul (arg + 4, &p, 0);
if (*p)
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("%s: not a number"), p);
+ grecs_error (locus, 0, _("%s: not a number"), p);
continue;
}
}
- else if (mu_kwd_xlat_name_ci (sig_kwtab, arg, &n))
+ else if (strtotok_ci (sig_tokendef, arg, &n))
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("%s: not a signal code"), arg);
+ grecs_error (locus, 0, _("%s: not a signal code"), arg);
continue;
}
n |= STATUS_SIG_BIT;
}
- else if (mu_kwd_xlat_name_ci (ex_kwtab, arg, &n))
+ else if (strtotok_ci (ex_tokendef, arg, &n))
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("%s: not a return code"), arg);
+ grecs_error (locus, 0, _("%s: not a return code"), arg);
continue;
}
@@ -301,7 +301,7 @@ create_action(struct component *comp,
}
const char *
-_get_string_arg (mu_config_value_t *val, int num, mu_debug_t debug)
+_get_string_arg (grecs_value_t * val, int num, grecs_locus_t * locus)
{
if (num != 0)
return NULL;
@@ -309,128 +309,130 @@ _get_string_arg (mu_config_value_t *val, int num, mu_debug_t debug)
}
const char *
-_get_array_arg (mu_config_value_t *val, int num, mu_debug_t debug)
+_get_array_arg (grecs_value_t * val, int num, grecs_locus_t * locus)
{
if (num < val->v.arg.c)
{
- if (mu_cfg_assert_value_type (&val->v.arg.v[num], MU_CFG_STRING,
- debug) == 0)
+ if (assert_grecs_value_type (locus, val, GRECS_TYPE_STRING) == 0)
return val->v.arg.v[num].v.string;
}
return NULL;
}
const char *
-_get_list_arg (mu_config_value_t *val, int num, mu_debug_t debug)
+_get_list_arg (grecs_value_t * val, int num, grecs_locus_t * locus)
{
- mu_config_value_t *elt;
- int rc = mu_list_get (val->v.list, num, (void**)&elt);
- if (rc)
+ grecs_value_t *elt = (grecs_value_t *) gl_list_get_at (val->v.list, num);
+ if (!elt)
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("cannot get list item: %s"),
- mu_strerror (rc));
+ grecs_error (locus, 0, _("cannot get list item"));
}
- else if (mu_cfg_assert_value_type (elt, MU_CFG_STRING, debug) == 0)
+ else if (assert_grecs_value_type (locus, elt, GRECS_TYPE_STRING) == 0)
return elt->v.string;
return NULL;
}
static int
-return_code_section_parser (enum mu_cfg_section_stage stage,
- const mu_cfg_node_t *node,
- const char *section_label, void **section_data,
- void *call_data,
- mu_cfg_tree_t *tree)
+return_code_section_parser (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr,
+ grecs_value_t * value, void *cb_data)
{
- struct component *comp = *section_data;
+ struct component *comp = varptr;
size_t count;
struct action *act;
- if (!node->label)
+ switch (cmd)
{
- mu_cfg_format_error (tree->debug, MU_DEBUG_ERROR, _("missing tag"));
+ case grecs_callback_section_begin:
+ if (!value)
+ {
+ grecs_error (locus, 0, _("missing tag"));
return 1;
}
- switch (stage)
- {
- case mu_cfg_section_start:
- switch (node->label->type)
+ switch (value->type)
{
- case MU_CFG_STRING:
- act = create_action (comp, tree->debug, node->label,
- 1,
- _get_string_arg);
+ case GRECS_TYPE_STRING:
+ act = create_action (comp, locus, value, 1, _get_string_arg);
break;
- case MU_CFG_ARRAY:
- act = create_action (comp, tree->debug, node->label,
- node->label->v.arg.c,
- _get_array_arg);
+ case GRECS_TYPE_ARRAY:
+ act = create_action (comp, locus, value,
+ value->v.arg.c, _get_array_arg);
break;
- case MU_CFG_LIST:
- mu_list_count (node->label->v.list, &count);
- act = create_action (comp, tree->debug, node->label,
- count,
- _get_list_arg);
+ case GRECS_TYPE_LIST:
+ count = gl_list_size (value->v.list);
+ act = create_action (comp, locus, value, count, _get_list_arg);
}
-
+ *(struct component **) cb_data = comp;
if (!act)
return 1;
memset (&comp->act_temp, 0, sizeof (comp->act_temp));
break;
- case mu_cfg_section_end:
+ case grecs_callback_section_end:
act = comp->act_tail;
act->act = comp->act_temp.act;
act->addr = comp->act_temp.addr;
act->message = comp->act_temp.message;
act->command = comp->act_temp.command;
break;
+
+ case grecs_callback_set_value:
+ grecs_error (locus, 0, _("invalid use of block statement"));
}
return 0;
}
-void
-return_code_cfg_init ()
+static char **
+config_array_to_argv (grecs_value_t *val, grecs_locus_t *locus)
{
- struct mu_cfg_section *section;
+ int i, j;
+ int argc;
+ char **argv;
- if (mu_create_canned_section ("return-code", &section))
- exit (EX_SOFTWARE);
- section->parser = return_code_section_parser;
- section->label = N_("<tag: exit-code-list>");
- mu_cfg_section_add_params (section, return_code_cfg_param);
+ argc = val->v.arg.c;
+ argv = xcalloc (argc + 1, sizeof (argv[0]));
+ for (i = j = 0; i < argc; i++)
+ {
+ if (assert_grecs_value_type (locus, &val->v.arg.v[i], GRECS_TYPE_STRING)
+ == 0)
+ argv[j++] = xstrdup (val->v.arg.v[i].v.string);
+ }
+ argv[j] = NULL;
+ return argv;
}
static int
-_cb_command (mu_debug_t debug, void *data, mu_config_value_t *val)
+_cb_command (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr, grecs_value_t * value, void *cb_data)
{
int argc;
- char **argv, ***pargv = data;
- int rc;
+ char **argv, ***pargv = varptr;
+ struct wordsplit ws;
- switch (val->type)
+ switch (value->type)
{
- case MU_CFG_STRING:
- rc = mu_argcv_get (val->v.string, "", NULL, &argc, &argv);
- if (rc)
+ case GRECS_TYPE_STRING:
+ if (wordsplit (value->v.string, &ws, WRDSF_DEFFLAGS))
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- "mu_argcv_get: %s", mu_strerror (rc));
+ grecs_error (locus, 0, "wordsplit: %s", strerror (errno));
return 1;
}
+ argc = ws.ws_wordc;
+ argv = ws.ws_wordv;
+ ws.ws_wordv = NULL;
break;
- case MU_CFG_ARRAY:
- argv = config_array_to_argv (val, debug);
+ case GRECS_TYPE_ARRAY:
+ argv = config_array_to_argv (value, locus);
break;
- case MU_CFG_LIST:
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("unexpected list"));
+ case GRECS_TYPE_LIST:
+ grecs_error (locus, 0, _("unexpected list"));
return 1;
}
*pargv = argv;
@@ -438,19 +440,21 @@ _cb_command (mu_debug_t debug, void *data, mu_config_value_t *val)
}
static int
-_cb_umask (mu_debug_t debug, void *data, mu_config_value_t *arg)
+_cb_umask (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr, grecs_value_t * value, void *cb_data)
{
- mode_t *pmode = data;
+ mode_t *pmode = varptr;
char *p;
unsigned long n;
- if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug))
+ if (assert_scalar_stmt (locus, cmd)
+ || assert_grecs_value_type (locus, value, GRECS_TYPE_STRING))
return 1;
- n = strtoul (arg->v.string, &p, 8);
+ n = strtoul (value->v.string, &p, 8);
if (*p)
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("invalid octal number"));
+ grecs_error (locus, 0, _("invalid octal number"));
return 1;
}
*pmode = n;
@@ -458,32 +462,34 @@ _cb_umask (mu_debug_t debug, void *data, mu_config_value_t *arg)
}
static int
-_cb_env (mu_debug_t debug, void *data, mu_config_value_t *val)
+_cb_env (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr, grecs_value_t * value, void *cb_data)
{
- int rc;
int argc;
char **argv;
- char ***penv = data;
+ char ***penv = varptr;
+ struct wordsplit ws;
- switch (val->type)
+ switch (value->type)
{
- case MU_CFG_STRING:
- rc = mu_argcv_get_np (val->v.string, strlen (val->v.string), "",
- NULL, 0, &argc, &argv, NULL);
- if (rc)
+ case GRECS_TYPE_STRING:
+ if (wordsplit (value->v.string, &ws, WRDSF_DEFFLAGS))
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- "mu_argcv_get: %s", mu_strerror (rc));
+ grecs_error (locus, 0, "wordsplit: %s", strerror (errno));
return 1;
}
+ argc = ws.ws_wordc;
+ argv = ws.ws_wordv;
+ ws.ws_wordv = NULL;
break;
- case MU_CFG_ARRAY:
- argv = config_array_to_argv (val, debug);
+ case GRECS_TYPE_ARRAY:
+ argv = config_array_to_argv (value, locus);
break;
- case MU_CFG_LIST:
- mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("unexpected list"));
+ case GRECS_TYPE_LIST:
+ grecs_error (locus, 0, _("unexpected list"));
return 1;
}
@@ -491,27 +497,87 @@ _cb_env (mu_debug_t debug, void *data, mu_config_value_t *val)
return 0;
}
+
+int
+string_to_syslog_priority (const char *key, int *pres)
+{
+ static struct tokendef tokdef_prio[] = {
+ {"EMERG", LOG_EMERG},
+ {"ALERT", LOG_ALERT},
+ {"CRIT", LOG_CRIT},
+ {"ERR", LOG_ERR},
+ {"WARNING", LOG_WARNING},
+ {"NOTICE", LOG_NOTICE},
+ {"INFO", LOG_INFO},
+ {"DEBUG", LOG_DEBUG},
+ {NULL}
+ };
+
+ return strtotok_ci (tokdef_prio, key, pres);
+}
+
+int
+string_to_syslog_facility (const char *key, int *pres)
+{
+ static struct tokendef tokdef_fac[] = {
+ {"auth", LOG_AUTH},
+ {"authpriv", LOG_AUTHPRIV},
+ {"cron", LOG_CRON},
+ {"daemon", LOG_DAEMON},
+ {"ftp", LOG_FTP},
+ {"kern", LOG_KERN},
+ {"lpr", LOG_LPR},
+ {"mail", LOG_MAIL},
+ {"news", LOG_NEWS},
+ {"syslog", LOG_SYSLOG},
+ {"user", LOG_USER},
+ {"uucp", LOG_UUCP},
+ {"local0", LOG_LOCAL0},
+ {"local1", LOG_LOCAL1},
+ {"local2", LOG_LOCAL2},
+ {"local3", LOG_LOCAL3},
+ {"local4", LOG_LOCAL4},
+ {"local5", LOG_LOCAL5},
+ {"local6", LOG_LOCAL6},
+ {"local7", LOG_LOCAL7},
+ {NULL}
+ };
+
+ return strtotok_ci (tokdef_fac, key, pres);
+}
+
static int
-_cb_facility (mu_debug_t debug, void *data, mu_config_value_t *val)
+cb_syslog_facility (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr, grecs_value_t * value, void *cb_data)
{
- if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug))
- return 1;
+ const char *str;
- if (mu_string_to_syslog_facility (val->v.string, data))
- {
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("unknown syslog facility `%s'"),
- val->v.string);
+ if (assert_grecs_value_type (locus, value, GRECS_TYPE_STRING))
return 1;
+ str = value->v.string;
+ if (c_isdigit (str[0]))
+ {
+ char *p;
+ int n = strtoul (str, &p, 10);
+ if (*p)
+ grecs_error (locus, 0,
+ _("expected facility number or symbolic name"));
+ else
+ *(int *) varptr = n;
}
+ else if (string_to_syslog_facility (str, varptr))
+ grecs_error (locus, 0, _("unknown syslog facility `%s'"), str);
return 0;
}
static int
-_cb_redir (mu_debug_t debug, void *data, mu_config_value_t *arg)
+_cb_redir (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr, grecs_value_t * value, void *cb_data)
{
- struct redirector *rp = data;
- static struct mu_kwd redirtab[] = {
+ struct redirector *rp = varptr;
+ static struct tokendef redirtab[] = {
{"null", redir_null},
{"syslog", redir_syslog},
{"file", redir_file},
@@ -519,43 +585,41 @@ _cb_redir (mu_debug_t debug, void *data, mu_config_value_t *arg)
};
int res;
- switch (arg->type)
+ switch (value->type)
{
- case MU_CFG_STRING:
- if (strcmp (arg->v.string, "null") == 0)
+ case GRECS_TYPE_STRING:
+ if (strcmp (value->v.string, "null") == 0)
{
rp->type = redir_null;
break;
}
rp->type = redir_syslog;
- if (mu_string_to_syslog_priority (arg->v.string, &rp->v.prio))
+ if (string_to_syslog_priority (value->v.string, &rp->v.prio))
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("unknown syslog priority `%s'"),
- arg);
+ grecs_error (locus, 0, _("unknown syslog priority `%s'"),
+ value->v.string);
return 0;
}
break;
- case MU_CFG_ARRAY:
- if (mu_cfg_assert_value_type (&arg->v.arg.v[0], MU_CFG_STRING, debug))
+ case GRECS_TYPE_ARRAY:
+ if (assert_grecs_value_type (locus, &value->v.arg.v[0],
+ GRECS_TYPE_STRING))
return 0;
- if (mu_kwd_xlat_name (redirtab, arg->v.arg.v[0].v.string, &res))
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("%s: unrecognised redirector type"),
- arg->v.arg.v[0].v.string);
+ if (strtotok (redirtab, value->v.arg.v[0].v.string, &res))
+ grecs_error (locus, 0, _("%s: unrecognised redirector type"),
+ value->v.arg.v[0].v.string);
else
{
if (res != redir_null)
{
- if (arg->v.arg.c != 2)
+ if (value->v.arg.c != 2)
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("wrong number of arguments"));
+ grecs_error (locus, 0, _("wrong number of arguments"));
return 0;
}
- if (mu_cfg_assert_value_type (&arg->v.arg.v[1], MU_CFG_STRING,
- debug))
+ if (assert_grecs_value_type (locus, &value->v.arg.v[1],
+ GRECS_TYPE_STRING))
return 0;
switch (res)
@@ -564,18 +628,18 @@ _cb_redir (mu_debug_t debug, void *data, mu_config_value_t *arg)
break;
case redir_syslog:
- if (mu_string_to_syslog_priority (arg->v.arg.v[1].v.string,
+ if (string_to_syslog_priority (value->v.arg.v[1].v.string,
&rp->v.prio))
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
+ grecs_error (locus, 0,
_("unknown syslog priority `%s'"),
- arg->v.arg.v[1].v.string);
+ value->v.arg.v[1].v.string);
return 0;
}
break;
case redir_file:
- rp->v.file = xstrdup (arg->v.arg.v[1].v.string);
+ rp->v.file = xstrdup (value->v.arg.v[1].v.string);
break;
}
}
@@ -584,44 +648,33 @@ _cb_redir (mu_debug_t debug, void *data, mu_config_value_t *arg)
break;
default:
- mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("unexpected list"));
+ grecs_error (locus, 0, _("unexpected list"));
}
return 0;
}
static int
-_cb_url (mu_debug_t debug, void *data, mu_config_value_t *arg)
+_cb_url (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr, grecs_value_t * value, void *cb_data)
{
- int rc;
- mu_url_t url;
+ struct pies_url *url;
- if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug))
+ if (assert_scalar_stmt (locus, cmd)
+ || assert_grecs_value_type (locus, value, GRECS_TYPE_STRING))
return 1;
- rc = mu_url_create (&url, arg->v.string);
- if (rc)
- {
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("%s: cannot create URL: %s"),
- arg->v.string,
- mu_strerror (rc));
- return 0;
- }
- rc = mu_url_parse (url);
- if (rc)
+ if (pies_url_create (&url, value->v.string))
{
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("%s: cannot parse URL: %s"),
- arg->v.string,
- mu_strerror (rc));
- mu_url_destroy (&url);
+ grecs_error (locus, 0, _("%s: cannot create URL: %s"),
+ value->v.string, strerror (errno));
return 0;
}
- *(mu_url_t*) data = url;
+ *(struct pies_url **) varptr = url;
return 0;
}
-static struct mu_kwd modetab[] = {
+static struct tokendef modetab[] = {
{"exec", pies_comp_exec},
{"wait", pies_comp_exec},
{"accept", pies_comp_accept},
@@ -633,128 +686,203 @@ static struct mu_kwd modetab[] = {
};
static int
-_cb_mode (mu_debug_t debug, void *data, mu_config_value_t *arg)
+_cb_mode (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr, grecs_value_t * value, void *cb_data)
{
int res;
- if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug))
+ if (assert_scalar_stmt (locus, cmd)
+ || assert_grecs_value_type (locus, value, GRECS_TYPE_STRING))
return 1;
- if (mu_kwd_xlat_name (modetab, arg->v.string, &res))
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("%s: unrecognised mode"),
- arg->v.string);
+ if (strtotok (modetab, value->v.string, &res))
+ grecs_error (locus, 0, _("%s: unrecognised mode"), value->v.string);
else
- *(enum pies_comp_mode *)data = res;
+ *(enum pies_comp_mode *) varptr = res;
return 0;
}
static int
-_cb_limits (mu_debug_t debug, void *data, mu_config_value_t *arg)
+_cb_limits (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr, grecs_value_t * value, void *cb_data)
{
- limits_record_t *plrec = data;
+ limits_record_t *plrec = varptr;
char *p;
- if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug))
+ if (assert_scalar_stmt (locus, cmd)
+ || assert_grecs_value_type (locus, value, GRECS_TYPE_STRING))
return 1;
- if (parse_limits (plrec, (char*) arg->v.string, &p))
- mu_cfg_format_error (debug, MU_DEBUG_ERROR,
- _("invalid limit string (near %s)"),
- p);
+ if (parse_limits (plrec, (char *) value->v.string, &p))
+ grecs_error (locus, 0, _("invalid limit string (near %s)"), p);
return 0;
}
-struct mu_cfg_param component_cfg_param[] = {
- { "mode", mu_cfg_callback, NULL,
- mu_offsetof (struct component, mode), _cb_mode,
- N_("Component execution mode."),
+struct grecs_keyword component_cfg_param[] = {
+ {"mode",
/* TRANSLATORS: The words between '{' and '}' are keywords, do not
translate them. */
- N_("mode: {exec | wait | accept | inetd | nostartaccept | pass-fd | pass}")
+ N_
+ ("mode: {exec | wait | accept | inetd | nostartaccept | pass-fd | pass}"),
+ N_("Component execution mode."),
+ grecs_type_string, NULL, offsetof (struct component, mode),
+ _cb_mode,
},
- { "program", mu_cfg_string, NULL,
- mu_offsetof (struct component, program), NULL,
- N_("Full name of the program.") },
- { "command", mu_cfg_callback, NULL,
- mu_offsetof (struct component, argv), _cb_command,
- N_("Command line.") },
- { "prerequisites", MU_CFG_LIST_OF(mu_cfg_string), NULL,
- mu_offsetof (struct component, prereq), NULL,
+ {"program",
+ NULL,
+ N_("Full name of the program."),
+ grecs_type_string, NULL,
+ offsetof (struct component, program),
+ NULL,
+ },
+ {"command",
+ NULL,
+ N_("Command line."),
+ grecs_type_string, NULL, offsetof (struct component, argv),
+ _cb_command,
+ },
+ {"prerequisites",
+ N_("list"),
N_("List of prerequisites."),
- N_("list") },
- { "dependents", MU_CFG_LIST_OF(mu_cfg_string), NULL,
- mu_offsetof (struct component, depend), NULL,
+ grecs_type_string | GRECS_LIST, NULL, offsetof (struct component, prereq),
+ NULL,
+ },
+ {"dependents",
+ N_("list"),
N_("List of components for which this one is a prerequisite."),
- N_("list") },
- { "disable", mu_cfg_bool, NULL,
- mu_offsetof (struct component, disabled), NULL,
- N_("Disable this entry.") },
- { "settle-timeout", mu_cfg_uint, NULL,
- mu_offsetof (struct component, settle_timeout), NULL,
- N_("Time to wait before starting this component.") },
- { "precious", mu_cfg_bool, NULL,
- mu_offsetof (struct component, precious), NULL,
- N_("Mark this entry as precious.") },
- { "socket", mu_cfg_callback, NULL,
- mu_offsetof (struct component, socket_url), _cb_url,
+ grecs_type_string | GRECS_LIST, NULL, offsetof (struct component, depend),
+ NULL,
+ },
+ {"disable",
+ NULL,
+ N_("Disable this entry."),
+ grecs_type_bool, NULL, offsetof (struct component, disabled),
+ NULL,
+ },
+ {"settle-timeout",
+ NULL,
+ N_("Time to wait before starting this component."),
+ grecs_type_uint, NULL,
+ offsetof (struct component, settle_timeout),
+ NULL,
+ },
+ {"precious",
+ NULL,
+ N_("Mark this entry as precious."),
+ grecs_type_bool, NULL,
+ offsetof (struct component, precious),
+ NULL,
+ },
+ {"socket",
+ N_("url: string"),
N_("Listen on the given url."),
- N_("url: string") },
- { "pass-fd-socket", mu_cfg_string, NULL,
- mu_offsetof (struct component, pass_fd_socket), NULL,
+ grecs_type_string, NULL,
+ offsetof (struct component, socket_url),
+ _cb_url,
+ },
+ {"pass-fd-socket",
+ N_("name"),
N_("Pass fd through this socket."),
- N_("name") },
- { "acl", mu_cfg_section, NULL, mu_offsetof (struct component, acl), NULL,
- N_("Per-component access control list") },
- { "remove-file", mu_cfg_string, NULL,
- mu_offsetof (struct component, rmfile), NULL,
+ grecs_type_string, NULL,
+ offsetof (struct component, pass_fd_socket),
+ NULL,
+ },
+ {"acl",
+ N_("name: string"),
+ N_("Define ACL."),
+ grecs_type_section, NULL, 0,
+ acl_section_parser, NULL, acl_keywords},
+ {"remove-file",
+ N_("file"),
N_("Remove file before starting the component."),
- N_("file") },
- { "facility", mu_cfg_callback, NULL,
- mu_offsetof (struct component, facility), _cb_facility,
+ grecs_type_string, NULL, offsetof (struct component, rmfile),
+ NULL,
+ },
+ {"facility",
+ N_("arg"),
N_("Override default syslog facility for this component."),
- N_("arg") },
- { "stdout", mu_cfg_callback, NULL,
- mu_offsetof (struct component, redir[RETR_OUT]), _cb_redir,
+ grecs_type_string, NULL, offsetof (struct component, facility),
+ cb_syslog_facility,
+ },
+ {"stdout",
+ /* TRANSLATORS: file and syslog are keywords. Do not translate them. */
+ N_("type: {file | syslog}> <channel: string"),
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")
+ grecs_type_string, NULL, offsetof (struct component, redir[RETR_OUT]),
+ _cb_redir,
},
- { "stderr", mu_cfg_callback, NULL,
- mu_offsetof (struct component, redir[RETR_ERR]), _cb_redir,
+ {"stderr",
+ /* TRANSLATORS: file and syslog are keywords. Do not translate them. */
+ N_("type: {file | syslog}> <channel: string"),
N_("Redirect program's standard error to the given file or "
"syslog priority."),
- /* TRANSLATORS: file and syslog are keywords. Do not translate them. */
- N_("type: {file | syslog}> <channel: string")
+ grecs_type_string, NULL, offsetof (struct component, redir[RETR_ERR]),
+ _cb_redir,
+ },
+ {"user",
+ NULL,
+ N_("Run with this user privileges."),
+ grecs_type_string, NULL, offsetof (struct component, privs.user),
+ NULL,
},
- { "user", mu_cfg_string, NULL,
- mu_offsetof (struct component, privs.user), NULL,
- N_("Run with this user privileges.") },
- { "group", MU_CFG_LIST_OF(mu_cfg_string), NULL,
- mu_offsetof (struct component, privs.groups), NULL,
- N_("Retain supplementary group.") },
- { "allgroups", mu_cfg_bool, NULL,
- mu_offsetof (struct component, privs.allgroups), NULL,
- N_("Retain all supplementary groups of which user is a member.") },
- { "umask", mu_cfg_callback, NULL,
- mu_offsetof (struct component, umask), _cb_umask,
+ {"group",
+ NULL,
+ N_("Retain supplementary group."),
+ grecs_type_string | GRECS_LIST, NULL, offsetof (struct component,
+ privs.groups),
+ NULL,
+ },
+ {"allgroups",
+ NULL,
+ N_("Retain all supplementary groups of which user is a member."),
+ grecs_type_bool, NULL, offsetof (struct component, privs.allgroups),
+ NULL,
+ },
+ {"umask",
+ N_("arg: number"),
N_("Force this umask."),
- N_("arg: number") },
- { "limits", mu_cfg_callback, NULL,
- mu_offsetof (struct component, limits), _cb_limits,
- N_("Set system limits") },
- { "env", mu_cfg_callback, NULL,
- mu_offsetof (struct component, env), _cb_env,
+ grecs_type_string, NULL, offsetof (struct component, umask),
+ _cb_umask,
+ },
+ {"limits",
+ NULL,
+ N_("Set system limits"),
+ grecs_type_string, NULL, offsetof (struct component, limits),
+ _cb_limits,
+ },
+ {"env",
+ N_("arg: list"),
N_("Set program environment. Argument is a list of assignments "
"separated by white space."),
- N_("arg: list") },
- { "chdir", mu_cfg_string, NULL,
- mu_offsetof (struct component, dir), NULL,
+ grecs_type_string, NULL, offsetof (struct component, env),
+ _cb_env,
+ },
+ {"chdir",
+ N_("dir"),
N_("Change to this directory before executing the component."),
- N_("dir") },
- { "return-code", mu_cfg_section },
+ grecs_type_string, NULL, offsetof (struct component, dir),
+ NULL,
+ },
+ {"return-code",
+ N_("<tag: exit-code-list>"),
+ NULL, /* FIXME: Docstring? */
+ grecs_type_section, NULL, 0,
+ return_code_section_parser, NULL, return_code_cfg_param},
{NULL}
};
+struct grecs_keyword *
+find_component_keyword (const char *ident)
+{
+ struct grecs_keyword *kwp;
+
+ for (kwp = component_cfg_param; kwp->ident; kwp++)
+ if (strcmp (kwp->ident, ident) == 0)
+ return kwp;
+ return NULL;
+}
+
static char *
make_full_name (const char *dir, const char *file)
{
@@ -771,7 +899,7 @@ make_full_name (const char *dir, const char *file)
}
static int
-component_verify (struct component *comp, mu_debug_t debug)
+component_verify (struct component *comp, grecs_locus_t * locus)
{
int header = 0;
int i;
@@ -780,11 +908,10 @@ component_verify (struct component *comp, mu_debug_t debug)
{ \
if (!header) \
{ \
- mu_cfg_format_error (debug, MU_DEBUG_ERROR, \
- _("in component %s:"), comp->tag); \
+ grecs_error (locus, 0, _("in component %s:"), comp->tag); \
header = 1; \
} \
- mu_cfg_format_error (debug, MU_DEBUG_ERROR, fmt, arg); \
+ grecs_error (locus, 0, fmt, arg); \
} \
while (0)
@@ -807,7 +934,7 @@ component_verify (struct component *comp, mu_debug_t debug)
if (comp->dir)
{
char *p = make_full_name (comp->dir, comp->pass_fd_socket);
- free (comp->pass_fd_socket);
+ //free (comp->pass_fd_socket);
comp->pass_fd_socket = p;
}
else
@@ -835,7 +962,8 @@ component_verify (struct component *comp, mu_debug_t debug)
for (i = RETR_OUT; i <= RETR_ERR; i++)
{
- if (comp->redir[i].type == redir_file && comp->redir[i].v.file[0] != '/')
+ if (comp->redir[i].type == redir_file
+ && comp->redir[i].v.file[0] != '/')
{
if (comp->dir)
{
@@ -854,36 +982,24 @@ component_verify (struct component *comp, mu_debug_t debug)
#undef COMPERR
}
-static int
-component_section_parser (enum mu_cfg_section_stage stage,
- const mu_cfg_node_t *node,
- const char *section_label, void **section_data,
- void *call_data,
- mu_cfg_tree_t *tree)
-{
- struct component *comp;
-
- switch (stage)
+struct component *
+component_create (const char *name)
{
- case mu_cfg_section_start:
- if (node->label
- && mu_cfg_assert_value_type (node->label, MU_CFG_STRING,
- tree->debug))
- return 1;
- comp = progman_lookup_component (node->label->v.string);
+ struct component *comp = progman_lookup_component (name);
if (!comp)
{
comp = xzalloc (sizeof (*comp));
- comp->facility = mu_log_facility;
+ comp->facility = log_facility;
comp->redir[RETR_OUT].type = comp->redir[RETR_ERR].type = redir_null;
- comp->tag = node->label ? xstrdup (node->label->v.string) : NULL;
+ comp->tag = xstrdup (name);
+ }
+ return comp;
}
- *section_data = comp;
- break;
- case mu_cfg_section_end:
- comp = *(struct component **) section_data;
- if (component_verify (comp, tree->debug) == 0)
+void
+component_finish (struct component *comp, grecs_locus_t *locus)
+{
+ if (component_verify (comp, locus) == 0)
{
/* FIXME: The prog list is traversed twice for each component
statement, this is suboptimal. */
@@ -891,120 +1007,197 @@ component_section_parser (enum mu_cfg_section_stage stage,
register_prog (comp);
}
}
- return 0;
-}
-void
-component_cfg_init ()
+static int
+component_section_parser (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr, grecs_value_t * value, void *cb_data)
+{
+ struct component *comp;
+ void **section_data = cb_data;
+
+ switch (cmd)
{
- struct mu_cfg_section *section;
+ case grecs_callback_section_begin:
+ if (assert_grecs_value_type (locus, value, GRECS_TYPE_STRING))
+ return 1;
+ comp = component_create (value->v.string);
+ *section_data = comp;
+ break;
- if (mu_create_canned_section ("component", &section))
- exit (EX_SOFTWARE);
- section->parser = component_section_parser;
- section->label = N_("<tag: string>");
- mu_cfg_section_add_params (section, component_cfg_param);
+ case grecs_callback_section_end:
+ comp = *(struct component **) section_data;
+ component_finish (comp, locus);
+ }
+ return 0;
}
+/* syslog */
+static struct grecs_keyword syslog_kw[] = {
+ {"facility",
+ N_("name"),
+ N_("Set syslog facility. Arg is one of the following: user, daemon, "
+ "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), "
+ "or a facility number."),
+ grecs_type_string, &log_facility, 0, cb_syslog_facility},
+ {"tag", N_("string"), N_("Tag syslog messages with this string"),
+ grecs_type_string, &log_tag},
+# if 0
+ {"print-priority", N_("arg"), N_("Prefix each message with its priority"),
+ grecs_type_bool, &syslog_include_prio},
+#endif
+ {NULL},
+};
+
struct component default_component;
static int
-_cb_debug (mu_debug_t debug, void *data, mu_config_value_t *arg)
+_cm_include_meta1 (enum grecs_callback_command cmd,
+ grecs_locus_t *locus,
+ void *varptr, grecs_value_t *value, void *cb_data)
{
- int rc;
-
- if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug))
+ if (assert_grecs_value_type (locus, value, GRECS_TYPE_STRING))
return 1;
- rc = mu_debug_level_from_string (arg->v.string, &debug_level, debug);
- if (rc)
- return 0;
- if (!pies_debug)
- mu_debug_create (&pies_debug, NULL);
- mu_debug_set_level (pies_debug, debug_level);
+ meta1_config_parse (value->v.string);
return 0;
}
-static int _cm_include_meta1 (mu_debug_t, void *, mu_config_value_t *);
-
-struct mu_cfg_param pies_cfg_param[] = {
- { "component", mu_cfg_section },
- { "debug", mu_cfg_callback, NULL, 0, _cb_debug,
- N_("Set debug verbosity level.") },
- { "pidfile", mu_cfg_string, &pidfile, 0, NULL,
- N_("Write PID to this file.") },
- { "control-file", mu_cfg_string, &ctlfile, 0, NULL,
- N_("Set location of the control file.") },
- { "stat-file", mu_cfg_string, &statfile, 0, NULL,
- N_("Set location of the statistics output file.") },
- { "user", mu_cfg_string, &pies_privs.user, 0, NULL,
- N_("Run with this user privileges.") },
- { "group", MU_CFG_LIST_OF(mu_cfg_string), &pies_privs.groups, 0, NULL,
- N_("Retain supplementary group.") },
- { "allgroups", mu_cfg_bool, &pies_privs.allgroups, 0, NULL,
- N_("Retain all supplementary groups of which user is a member.") },
- { "umask", mu_cfg_callback, &pies_umask, 0, _cb_umask,
+struct grecs_keyword pies_cfg_param[] = {
+ /* FIXME */
+ {"component",
+ N_("<tag: string>"),
+ NULL, /* FIXME: Docstring */
+ grecs_type_section, NULL, 0,
+ component_section_parser, NULL, component_cfg_param},
+ {"syslog",
+ NULL,
+ N_("Configure syslog logging"),
+ grecs_type_section, NULL, 0, NULL, NULL, syslog_kw},
+ {"debug",
+ NULL,
+ N_("Set debug verbosity level."),
+ grecs_type_uint, &debug_level, 0, NULL},
+ {"source-info",
+ NULL,
+ N_("Show source info with debugging messages."),
+ grecs_type_bool, &source_info_option, 0, NULL},
+ {"pidfile",
+ NULL,
+ N_("Write PID to this file."),
+ grecs_type_string, &pidfile, 0,
+ NULL,
+ },
+ {"control-file",
+ NULL,
+ N_("Set location of the control file."),
+ grecs_type_string, &ctlfile, 0,
+ NULL,
+ },
+ {"stat-file",
+ NULL,
+ N_("Set location of the statistics output file."),
+ grecs_type_string, &statfile, 0,
+ NULL,
+ },
+ {"user",
+ NULL,
+ N_("Run with this user privileges."),
+ grecs_type_string, &pies_privs.user, 0,
+ NULL,
+ },
+ {"group",
+ NULL,
+ N_("Retain supplementary group."),
+ grecs_type_string | GRECS_LIST, /*FIXME*/ &pies_privs.groups, 0,
+ NULL,
+ },
+ {"allgroups",
+ NULL,
+ N_("Retain all supplementary groups of which user is a member."),
+ grecs_type_bool, &pies_privs.allgroups, 0,
+ NULL,
+ },
+ {"umask",
+ N_("arg: number"),
N_("Force this umask."),
- N_("arg: number") },
- { "limits", mu_cfg_callback, &pies_limits, 0, _cb_limits,
- N_("Set global system limits.") },
- { "shutdown-timeout", mu_cfg_uint, &shutdown_timeout, 0, NULL,
+ grecs_type_string, &pies_umask, 0,
+ _cb_umask,
+ },
+ {"limits",
+ NULL,
+ N_("Set global system limits."),
+ grecs_type_string, &pies_limits, 0, _cb_limits,
+ },
+ {"shutdown-timeout",
+ "n",
N_("Wait <n> seconds for all components to shut down."),
- "n" },
- { "return-code", mu_cfg_section, &default_component },
- { "acl", mu_cfg_section, &pies_acl, 0, NULL,
- N_("Global access control list") },
- { "include-meta1", mu_cfg_callback, NULL, 0, _cm_include_meta1,
+ grecs_type_uint, &shutdown_timeout, 0,
+ NULL,
+ },
+ {"return-code",
+ N_("<tag: exit-code-list>"),
+ NULL, /* FIXME: Docstring? */
+ grecs_type_section, &default_component, 0,
+ return_code_section_parser, NULL, return_code_cfg_param},
+ {"acl",
+ N_("name: string"),
+ N_("Define ACL."),
+ grecs_type_section, NULL, 0,
+ acl_section_parser, NULL, acl_keywords},
+ {"include-meta1",
+ N_("file: string"),
N_("Include components from the specified MeTA1 configuration file."),
- N_("file: string") },
- { "meta1-queue-dir", mu_cfg_string, &meta1_queue_dir, 0, NULL,
- N_("Set name of MeTA1 queue directory (default /var/spool/meta1).") },
+ grecs_type_string, NULL, 0,
+ _cm_include_meta1,
+ },
+ {"meta1-queue-dir",
+ NULL,
+ N_("Set name of MeTA1 queue directory (default /var/spool/meta1)."),
+ grecs_type_string, &meta1_queue_dir, 0,
+ NULL,
+ },
{NULL}
};
-static int
-_cm_include_meta1 (mu_debug_t debug, void *data, mu_config_value_t *arg)
+void
+config_init ()
{
- int flags = 0;
+ grecs_set_keywords (pies_cfg_param);
+ grecs_include_path_setup (DEFAULT_VERSION_INCLUDE_DIR,
+ DEFAULT_INCLUDE_DIR, NULL);
+ grecs_preprocessor = DEFAULT_PREPROCESSOR;
+ grecs_log_to_stderr = log_to_stderr;
+}
- if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug))
- return 1;
- if (meta1_config_parse (arg->v.string) == 0)
+void
+config_help ()
{
- if (mu_cfg_parser_verbose)
- flags |= MU_PARSE_CONFIG_VERBOSE;
- if (mu_cfg_parser_verbose > 1)
- flags |= MU_PARSE_CONFIG_DUMP;
- mu_cfg_tree_reduce (meta1_parse_tree, mu_program_name, pies_cfg_param,
- flags, NULL);
- }
- return 0;
+ static char docstring[] =
+ N_("Configuration file structure for pies.\n"
+ "For more information, use `info pies configuration'.");
+ grecs_format_docstring (stdout, docstring, 0);
+ grecs_format_statement_array (stdout, pies_cfg_param, 1, 0);
}
-
const char *program_version = "pies (" PACKAGE_STRING ")";
const char *package_bugreport = "<" PACKAGE_BUGREPORT ">";
static char doc[] = N_("pies -- process invocation and execution supervisor");
static char args_doc[] = "";
-static const char *capa[] = {
- "common",
- "logging",
- "mailer",
- "debug",
- NULL
-};
-
-enum {
+enum
+{
OPT_FOREGROUND = 256,
OPT_LOG_TAG,
OPT_SYSLOG,
OPT_STDERR,
OPT_DUMP_PREREQ,
OPT_DUMP_DEPMAP,
- OPT_FORCE
+ OPT_FORCE,
+ OPT_CONFIG_HELP,
+ OPT_SOURCE_INFO
};
#define OPT_RESTART 'R'
@@ -1021,8 +1214,18 @@ static struct argp_option options[] = {
N_("set the identifier used in syslog messages to STRING"), GRP + 1},
{"debug", 'x', N_("LEVEL"), 0,
N_("set debug verbosity level"), GRP + 1},
+ {"source-info", OPT_SOURCE_INFO, NULL, 0,
+ N_("show source info with debugging messages"), GRP + 1},
{"force", OPT_FORCE, NULL, 0,
N_("force startup even if another instance may be running"), GRP + 1},
+ {"lint", 't', NULL, 0,
+ N_("parse configuration file and exit"), GRP + 1},
+ {NULL, 'E', NULL, 0,
+ N_("preprocess config and exit"), GRP + 1},
+ {"config-file", 'c', N_("FILE"), 0,
+ N_("use FILE instead of the default configuration"), GRP + 1},
+ {"config-help", OPT_CONFIG_HELP, NULL, 0,
+ N_("show configuration file summary"), GRP + 1},
#undef GRP
#define GRP 10
@@ -1049,10 +1252,24 @@ static struct argp_option options[] = {
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
- static struct mu_argp_node_list lst;
-
switch (key)
{
+ case 't':
+ lint_mode = 1;
+ break;
+
+ case 'E':
+ preprocess_only = 1;
+ break;
+
+ case 'c':
+ conffile = arg;
+ break;
+
+ case OPT_CONFIG_HELP:
+ config_help ();
+ exit (0);
+
case OPT_FOREGROUND:
foreground = 1;
break;
@@ -1076,7 +1293,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'x':
- mu_argp_node_list_new (&lst, "debug", arg);
+ debug_level = strtoul (arg, NULL, 0);
+ break;
+
+ case OPT_SOURCE_INFO:
+ source_info_option = 1;
break;
case OPT_FORCE:
@@ -1088,11 +1309,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case ARGP_KEY_INIT:
- mu_argp_node_list_init (&lst);
break;
case ARGP_KEY_FINI:
- mu_argp_node_list_finish (&lst, NULL, NULL);
break;
default:
@@ -1135,11 +1354,11 @@ sig_handler (int sig)
case SIGINT:
case SIGQUIT:
action = ACTION_STOP;
- mu_diag_output (MU_DIAG_NOTICE, "received signal %d", sig);
+ logmsg (LOG_NOTICE, "received signal %d", sig);
break;
case SIGHUP:
- mu_diag_output (MU_DIAG_NOTICE, "received signal %d", sig);
+ logmsg (LOG_NOTICE, "received signal %d", sig);
action = ACTION_RESTART;
break;
@@ -1181,10 +1400,9 @@ pidfile_read (int must_exist)
if (!fp)
{
if (must_exist && errno != ENOENT)
- mu_diag_output (MU_DIAG_ERR,
+ logmsg (LOG_ERR,
_("cannot open pid file `%s': %s"),
- pidfile,
- mu_strerror (errno));
+ pidfile, strerror (errno));
return -1;
}
@@ -1196,18 +1414,18 @@ pidfile_read (int must_exist)
break;
else
{
- mu_diag_output (MU_DIAG_ERR,
+ logmsg (LOG_ERR,
_("unexpected character %#03o in pidfile `%s'"),
c, pidfile);
return -1;
}
}
fclose (fp);
- if (kill (n, 0))
+ if (n && kill (n, 0))
{
- mu_diag_output (MU_DIAG_ERR,
+ logmsg (LOG_ERR,
_("cannot signal master process %lu: %s"),
- (unsigned long) n, mu_strerror (errno));
+ (unsigned long) n, strerror (errno));
if (errno == EPERM)
return n; /* be on the safe side */
return -1;
@@ -1231,7 +1449,7 @@ pies_check_status (pid_t *ppid)
int i;
int rc;
- if (pid == -1)
+ if (pid <= 0)
return pies_status_ctr;
*ppid = pid;
@@ -1255,19 +1473,19 @@ stop_components ()
size_t size = 0;
char *buf = NULL;
- mu_diag_output (MU_DIAG_INFO, _("stopping components"));
+ logmsg (LOG_INFO, _("stopping components"));
fp = fopen (ctlfile, "r");
if (!fp)
{
- mu_error (_("cannot open control file `%s': %s"),
- ctlfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot open control file `%s': %s"),
+ ctlfile, strerror (errno));
return;
}
if (unlink (ctlfile))
{
- mu_error (_("cannot unlink control file `%s': %s"),
- ctlfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot unlink control file `%s': %s"),
+ ctlfile, strerror (errno));
fclose (fp);
return;
}
@@ -1298,8 +1516,8 @@ request_restart_components (char **argv)
fp = fopen (ctlfile, "w");
if (!fp)
{
- mu_error (_("cannot open control file `%s': %s"),
- ctlfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot open control file `%s': %s"),
+ ctlfile, strerror (errno));
return 1;
}
for (; *argv; argv++)
@@ -1318,12 +1536,11 @@ pies_reload ()
if (pid == -1)
{
- mu_diag_output (MU_DIAG_CRIT, _("pies is not running"));
+ logmsg (LOG_CRIT, _("pies is not running"));
return 1;
}
- mu_diag_output (MU_DIAG_INFO, _("reloading pies at PID %lu"),
- (unsigned long) pid);
+ logmsg (LOG_INFO, _("reloading pies at PID %lu"), (unsigned long) pid);
return kill (pid, SIGHUP) ? EX_SOFTWARE : 0;
}
@@ -1334,42 +1551,41 @@ pies_status ()
FILE *fp;
if (unlink (statfile) && errno != ENOENT)
- mu_diag_output (MU_DIAG_ERR, _("cannot unlink statfile `%s': %s"),
- statfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot unlink statfile `%s': %s"),
+ statfile, strerror (errno));
switch (pies_check_status (&pid))
{
case pies_status_ctr:
- mu_diag_output (MU_DIAG_INFO, _("pies is not running"));
+ logmsg (LOG_INFO, _("pies is not running"));
break;
case pies_status_stale:
- mu_diag_output (MU_DIAG_INFO,
+ logmsg (LOG_INFO,
_("pies is not running, but a pidfile "
- "is found (pid %lu)"),
- (unsigned long) pid);
+ "is found (pid %lu)"), (unsigned long) pid);
return 1; /* FIXME: hm? */
case pies_status_noresp:
- mu_diag_output (MU_DIAG_INFO,
+ logmsg (LOG_INFO,
_("pies seems to run with pid %lu, but is not responding"),
(unsigned long) pid);
if (unlink (statfile))
- mu_diag_output (MU_DIAG_ERR, _("cannot unlink statfile `%s': %s"),
- statfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot unlink statfile `%s': %s"),
+ statfile, strerror (errno));
return 2;
case pies_status_running:
fp = fopen (statfile, "r");
if (!fp)
- mu_diag_output (MU_DIAG_ERR, _("cannot open statfile `%s': %s"),
- statfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot open statfile `%s': %s"),
+ statfile, strerror (errno));
else
{
char c;
if (unlink (statfile))
- mu_diag_output (MU_DIAG_ERR, _("cannot unlink statfile `%s': %s"),
- statfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot unlink statfile `%s': %s"),
+ statfile, strerror (errno));
while ((c = fgetc (fp)) != EOF)
fputc (c, stdout);
fclose (fp);
@@ -1385,54 +1601,113 @@ pies_stop ()
if (pid == -1)
{
- mu_diag_output (MU_DIAG_CRIT, _("pies is not running"));
+ logmsg (LOG_CRIT, _("pies is not running"));
return EX_USAGE;
}
- mu_diag_output (MU_DIAG_INFO,
- _("stopping pies at PID %lu"), (unsigned long) pid);
+ logmsg (LOG_INFO, _("stopping pies at PID %lu"), (unsigned long) pid);
return kill (pid, SIGTERM) ? EX_SOFTWARE : 0;
}
-static int
-pies_cfg_verifier ()
+/* Pidfile */
+/* Check whether pidfile NAME exists and if so, whether its PID is still
+ active. Exit if it is. */
+void
+check_pidfile (char *name)
+{
+ unsigned long pid;
+ FILE *fp = fopen (name, "r");
+ if (!fp)
+ {
+ if (errno == ENOENT)
+ return;
+ logmsg (LOG_ERR, _("cannot open pidfile `%s': %s"),
+ name, strerror (errno));
+ exit (EX_TEMPFAIL);
+ }
+ if (fscanf (fp, "%lu", &pid) != 1)
+ {
+ logmsg (LOG_ERR, ("cannot get pid from pidfile `%s'"), name);
+ }
+ else
+ {
+ if (kill (pid, 0) == 0)
{
- return progman_build_depmap ();
+ logmsg (LOG_ERR,
+ _
+ ("%s appears to run with pid %lu. If it does not, remove `%s' and retry."),
+ program_name, pid, name);
+ exit (EX_USAGE);
+ }
+ }
+ fclose (fp);
+ if (unlink (pidfile))
+ {
+ logmsg (LOG_ERR, _("cannot unlink pidfile `%s': %s"),
+ name, strerror (errno));
+ exit (EX_USAGE);
+ }
+}
+
+void
+create_pidfile (char *name)
+{
+ FILE *fp = fopen (name, "w");
+ if (!fp)
+ {
+ logmsg (LOG_ERR, _("cannot create pidfile `%s': %s"),
+ name, strerror (errno));
+ exit (EX_TEMPFAIL);
+ }
+ fprintf (fp, "%lu", (unsigned long) getpid ());
+ fclose (fp);
+}
+
+void
+remove_pidfile (char *name)
+{
+ if (unlink (name))
+ logmsg (LOG_ERR, _("cannot unlink pidfile `%s': %s"),
+ name, strerror (errno));
}
int
main (int argc, char **argv)
{
- int rc;
int index;
pid_t pid;
extern char **environ;
- extern char *program_invocation_short_name; /* FIXME */
+ set_program_name (argv[0]);
mf_init_nls ();
mf_proctitle_init (argc, argv, environ);
- if (!program_invocation_short_name)
- program_invocation_short_name = argv[0];
/* Set default logging */
log_setup (!stderr_closed_p ());
- mu_acl_cfg_init ();
- return_code_cfg_init ();
- component_cfg_init ();
- mu_app_cfg_verifier = pies_cfg_verifier;
- mu_argp_init (program_version, package_bugreport);
- mu_register_all_mailer_formats ();
- rc = mu_app_init (&argp, capa, pies_cfg_param, argc, argv, 0, &index, NULL);
- if (rc)
+ config_init ();
+ if (argp_parse (&argp, argc, argv, 0, &index, NULL))
+ exit (EX_USAGE);
+
+ if (preprocess_only)
+ exit (grecs_preproc_run (conffile, grecs_preprocessor) ? EX_CONFIG : 0);
+
+ if (grecs_parse (conffile))
exit (EX_CONFIG);
+ if (lint_mode)
+ {
+ progman_build_depmap ();
+ exit (0);
+ }
+
+ /* Re-setup logging: it might have been reset in the config file */
log_setup (log_to_stderr);
if (argc != index && command != 'R')
{
- mu_error ("extra command line arguments");
+ logmsg (LOG_ERR, "extra command line arguments");
exit (EX_CONFIG);
}
@@ -1440,7 +1715,7 @@ main (int argc, char **argv)
switch (command)
{
case OPT_RESTART:
- mf_priv_setup (&pies_privs);
+ pies_priv_setup (&pies_privs);
if (pies_umask)
umask (pies_umask);
exit (request_restart_components (argv + index));
@@ -1463,7 +1738,7 @@ main (int argc, char **argv)
exit (0);
default:
- mf_priv_setup (&pies_privs);
+ pies_priv_setup (&pies_privs);
if (pies_umask)
umask (pies_umask);
}
@@ -1476,35 +1751,34 @@ main (int argc, char **argv)
case pies_status_noresp:
if (!force_option)
{
- mu_error (_("another pies instance may be running (pid %lu), "
- "use --force to override"),
- (unsigned long) pid);
+ logmsg (LOG_ERR,
+ _("another pies instance may be running (pid %lu), "
+ "use --force to override"), (unsigned long) pid);
exit (EX_USAGE);
}
break;
case pies_status_running:
- mu_error (_("another pies instance already running (pid %lu)"),
+ logmsg (LOG_ERR, _("another pies instance already running (pid %lu)"),
(unsigned long) pid);
exit (EX_USAGE);
}
- mu_diag_output (MU_DIAG_INFO, _("%s starting"), program_version);
+ logmsg (LOG_INFO, _("%s starting"), program_version);
+
+ if (!foreground)
+ check_pidfile (pidfile);
if (!foreground && daemon (0, 0) == -1)
{
- mu_error (_("cannot become a daemon: %s"),
- mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot become a daemon: %s"), strerror (errno));
exit (EX_SOFTWARE);
}
- rc = mu_daemon_create_pidfile (pidfile);
- if (rc)
- mu_error (_("cannot create PID file `%s': %s"),
- pidfile, mu_strerror (rc));
+ create_pidfile (pidfile);
if (argv[0][0] != '/')
- mu_diag_output (MU_DIAG_NOTICE,
+ logmsg (LOG_NOTICE,
N_("not started as an absolute pathname; "
"SIGHUP will not work"));
@@ -1556,26 +1830,20 @@ main (int argc, char **argv)
for (i = getmaxfd (); i > 0; i--)
close (i);
- mu_daemon_remove_pidfile ();
+ remove_pidfile (pidfile);
signal_setup (SIG_DFL);
execv (argv[0], argv);
}
- mu_diag_output (MU_DIAG_INFO, _("%s terminated"), program_version);
+ logmsg (LOG_INFO, _("%s terminated"), program_version);
exit (EX_OK);
}
void
xalloc_die ()
{
- mu_error ("not enough memory");
+ logmsg (LOG_CRIT, _("not enough memory"));
abort ();
}
-
-/*
- Local Variables:
- c-file-style: "gnu"
- End:
-*/
/* EOF */
diff --git a/src/pies.h b/src/pies.h
index add175c..c57a104 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -1,23 +1,24 @@
-/* This file is part of Mailfromd.
+/* This file is part of Pies.
Copyright (C) 2008, 2009 Sergey Poznyakoff
- This program is free software; you can redistribute it and/or modify
+ Pies is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
- This program is distributed in the hope that it will be useful,
+ Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
+#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/time.h>
@@ -35,18 +36,27 @@
#include <pwd.h>
#include <grp.h>
#include <signal.h>
+#include <time.h>
#include <sysexits.h>
+#include <argp.h>
-#include <mailutils/mailutils.h>
-#include <mailutils/daemon.h>
-#include <mailutils/libargp.h>
-#include <mailutils/syslog.h>
+#include <grecs.h>
+#include <wordsplit.h>
+#include "progname.h"
#include "inttostr.h"
#include "c-ctype.h"
#include "xalloc.h"
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+#include "obstack.h"
+#include "xvasprintf.h"
+
+#include "acl.h"
#include "libpies.h"
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
+
#define TESTTIME 2*60
#define SLEEPTIME 5*60
#define MAXSPAWN 10
@@ -88,11 +98,20 @@ struct action
size_t nstat;
unsigned *status;
enum return_action act; /* Action to take when the component terminates */
- mu_address_t addr; /* Addresses to notify about it. */
+ char *addr; /* Addresses to notify about it. */
char *message; /* Notification mail. */
char *command; /* Execute this command */
};
+
+/* user privs */
+struct pies_privs
+{
+ char *user;
+ int allgroups;
+ gl_list_t groups;
+};
+
enum pies_comp_mode
{
/* Execute the component, no sockets are opened. This is the default
@@ -121,23 +140,23 @@ struct component
char **argv; /* Program command line */
char **env; /* Program environment */
char *dir; /* Working directory */
- mu_list_t prereq; /* Prerequisites */
- mu_list_t depend; /* Dependency targets */
+ gl_list_t prereq; /* Prerequisites */
+ gl_list_t depend; /* Dependency targets */
unsigned settle_timeout; /* Time needed for started prerequisites to
settle */
/* FIXME: disabled and precious can be encoded as bits in mode */
int disabled; /* The componenet is disabled */
int precious; /* The component is precious (cannot be disabled) */
char *rmfile; /* Try to remove this file before starting */
- struct mf_privs privs; /* UID/GIDS+groups to run under */
+ struct pies_privs privs; /* UID/GIDS+groups to run under */
mode_t umask; /* Umask to install before starting */
limits_record_t limits; /* System limits */
- mu_url_t socket_url; /* Socket to listen on
+ struct pies_url *socket_url; /* Socket to listen on
(if mode != pies_comp_exec) */
char *pass_fd_socket; /* Socket to pass fd on
(if mode == pies_comp_pass_fd) */
- mu_acl_t acl;
- /* Retranslators: */
+ pies_acl_t acl;
+ /* Redirectors: */
int facility; /* Syslog facility. */
struct redirector redir[2]; /* Repeaters for stdout and stderr */
/* Actions to execute on various exit codes: */
@@ -145,11 +164,12 @@ struct component
struct action act_temp; /* Auxiliary object used during configuration */
};
-extern char *syslog_tag;
+extern int log_to_stderr;
+extern char *log_tag;
+extern int log_facility;
extern unsigned long shutdown_timeout;
extern struct component default_component;
-extern mu_acl_t pies_acl;
-extern mu_debug_t pies_debug;
+pies_acl_t pies_acl;
extern limits_record_t pies_limits;
void register_prog (struct component *comp);
@@ -187,11 +207,36 @@ unsigned depmap_first (pies_depmap_t dmap, enum pies_depmap_direction dir,
unsigned coord, pies_depmap_pos_t *ppos);
unsigned depmap_next (pies_depmap_t dmap, pies_depmap_pos_t pos);
+int assert_grecs_value_type (grecs_locus_t *locus,
+ const grecs_value_t *value, int type);
+
+struct component *component_create (const char *name);
+void component_finish (struct component *comp, grecs_locus_t *locus);
+struct grecs_keyword *find_component_keyword (const char *ident);
+
+
+/* url.c */
+struct pies_url
+{
+ char *string;
+ char *proto;
+ char *host;
+ int port;
+ char *path;
+ char *user;
+ char *passwd;
+ int argc;
+ char **argv;
+};
+
+int pies_url_create (struct pies_url **purl, const char *str);
+void pies_url_destroy (struct pies_url **purl);
+const char * pies_url_get_arg (struct pies_url *url, const char *argname);
void pies_pause (void);
int register_listener (int fd);
int pass_fd (const char *socket, int fd);
-int create_socket (mu_url_t url, const char *user, mode_t umask);
+int create_socket (struct pies_url *url, const char *user, mode_t umask);
int parse_limits (limits_record_t *plrec, char *str, char **endp);
@@ -203,3 +248,51 @@ int meta1lex (void);
int meta1error (char *s);
int meta1parse (void);
+
+void logmsg (int prio, const char *fmt, ...);
+void logmsg_printf (int prio, const char *fmt, ...);
+void logmsg_vprintf (int prio, const char *fmt, va_list ap);
+
+extern unsigned debug_level;
+extern int source_info_option;
+void debug_msg (const char *fmt, ...);
+
+#define debug(lev, args) \
+ do \
+ if (debug_level >= lev) \
+ { \
+ if (source_info_option) \
+ logmsg_printf (LOG_DEBUG, "%s:%lu:%s: ", \
+ __FILE__, __LINE__, __FUNCTION__); \
+ debug_msg args; \
+ } \
+ while (0)
+
+
+/* meta.c */
+struct metadef
+{
+ char *kw;
+ char *value;
+ const char *(*expand) (struct metadef *, void *);
+ char *storage;
+ void *data;
+};
+
+char *meta_expand_string (const char *string, struct metadef *def, void *data);
+void meta_free (struct metadef *def);
+
+
+/* addrfmt.c */
+void sockaddr_to_str (const struct sockaddr *sa, int salen,
+ char *bufptr, size_t buflen,
+ size_t *plen);
+char *sockaddr_to_astr (const struct sockaddr *sa, int salen);
+
+
+/* userprivs.c */
+int switch_to_privs (uid_t uid, gid_t gid, gl_list_t retain_groups);
+
+void pies_priv_setup (struct pies_privs *);
+void pies_epriv_setup (struct pies_privs *);
+
diff --git a/src/progman.c b/src/progman.c
index 9383aae..cee6775 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -1,18 +1,18 @@
-/* This file is part of Mailfromd.
+/* This file is part of Pies.
Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 3 of the License, or (at your
- option) any later version.
+ Pies is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
- This program is distributed in the hope that it will be useful,
+ Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program. If not, see <http://www.gnu.org/licenses/>. */
+ You should have received a copy of the GNU General Public License
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
#include "pies.h"
@@ -172,13 +172,11 @@ static char *
redir_tag (struct prog *master, int type)
{
static char *redirstr[2] = { "stdout", "stderr" };
- char *str = NULL;
- if (type < MU_ARRAY_SIZE(redirstr))
- asprintf (&str, "%s/%s", master->tag, redirstr[type]);
+ char *str;
+ if (type < ARRAY_SIZE(redirstr))
+ str = xasprintf ("%s/%s", master->tag, redirstr[type]);
else
- asprintf (&str, "%s/%d", master->tag, type);
- if (!str)
- xalloc_die ();
+ str = xasprintf ("%s/%d", master->tag, type);
return str;
}
@@ -261,11 +259,10 @@ prog_rebuild_prerequisites (struct prog *prog)
if (comp->prereq)
{
- mu_list_count (comp->prereq, &depc);
+ depc = gl_list_size (comp->prereq);
if (depc == 1)
{
- char *item;
- mu_list_get (comp->prereq, 0, (void**)&item);
+ const char *item = gl_list_get_at (comp->prereq, 0);
if (strcmp (item, "all") == 0)
{
dep_all = 1;
@@ -274,7 +271,10 @@ prog_rebuild_prerequisites (struct prog *prog)
depc++;
}
else if (strcmp (item, "none") == 0)
- mu_list_destroy (&comp->prereq);
+ {
+ gl_list_free (comp->prereq);
+ comp->prereq = NULL;
+ }
}
}
@@ -294,16 +294,13 @@ prog_rebuild_prerequisites (struct prog *prog)
}
else
{
- mu_iterator_t itr = NULL;
- mu_list_get_iterator (comp->prereq, &itr);
- for (mu_iterator_first (itr), depc = 0;
- !mu_iterator_is_done (itr); mu_iterator_next (itr), depc++)
+ const void *p;
+ gl_list_iterator_t itr = gl_list_iterator (comp->prereq);
+ while (gl_list_iterator_next (&itr, &p, NULL))
{
- char *str;
- mu_iterator_current (itr, (void**)&str);
- prog->prereq[depc] = str;
+ prog->prereq[depc++] = (char*) p;
}
- mu_iterator_destroy (&itr);
+ gl_list_iterator_free (&itr);
}
}
prog->prereq[depc] = NULL;
@@ -341,9 +338,9 @@ redirect_to_file (struct prog *master, int stream)
0644 & ~master->v.p.comp->umask);
if (fd == -1)
{
- mu_error (_("cannot open output file %s: %s"),
+ logmsg (LOG_ERR, _("cannot open output file %s: %s"),
master->v.p.comp->redir[stream].v.file,
- mu_strerror (errno));
+ strerror (errno));
return -1;
}
/* Fix file ownership */
@@ -405,9 +402,9 @@ open_redirector (struct prog *master, int stream)
_exit (0);
case -1:
- mu_diag_output (MU_DIAG_CRIT,
+ logmsg (LOG_CRIT,
_("cannot run redirector `%s': fork failed: %s"),
- master->tag, mu_strerror (errno));
+ master->tag, strerror (errno));
return -1;
default:
@@ -592,7 +589,7 @@ prog_start (struct prog *prog)
if (prog->v.p.count > MAXSPAWN)
{
- mu_error (ngettext (
+ logmsg (LOG_NOTICE, ngettext (
"%s is respawning too fast, disabled for %d minute",
"%s is respawning too fast, disabled for %d minutes",
SLEEPTIME / 60),
@@ -609,12 +606,12 @@ prog_start (struct prog *prog)
break;
case pies_comp_pass_fd:
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, _("unlinking %s\n"),
- prog->v.p.comp->pass_fd_socket);
+ debug (1, (_("unlinking %s"), prog->v.p.comp->pass_fd_socket));
if (unlink (prog->v.p.comp->pass_fd_socket) && errno != ENOENT)
{
- mu_error (_("cannot unlink %s: %s"), prog->v.p.comp->pass_fd_socket,
- mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot unlink %s: %s"),
+ prog->v.p.comp->pass_fd_socket,
+ strerror (errno));
return;
}
/* fall through */
@@ -630,7 +627,7 @@ prog_start (struct prog *prog)
}
if (listen (prog->v.p.socket, 8))
{
- mu_error ("listen: %s", mu_strerror (errno));
+ logmsg (LOG_ERR, "listen: %s", strerror (errno));
close (prog->v.p.socket);
prog->v.p.socket = -1;
prog->v.p.status = status_disabled;
@@ -644,15 +641,14 @@ prog_start (struct prog *prog)
return;
}
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, _("starting %s\n"), prog->tag);
+ debug (1, (_("starting %s"), prog->tag));
if (prog->v.p.comp->rmfile)
{
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, _("unlinking %s\n"),
- prog->v.p.comp->rmfile);
+ debug (1, (_("unlinking %s"), prog->v.p.comp->rmfile));
if (unlink (prog->v.p.comp->rmfile) && errno != ENOENT)
- mu_error (_("%s: cannot remove file `%s': %s"),
- prog->tag, prog->v.p.comp->rmfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("%s: cannot remove file `%s': %s"),
+ prog->tag, prog->v.p.comp->rmfile, strerror (errno));
}
redir[RETR_OUT] = open_redirector (prog, RETR_OUT);
@@ -665,22 +661,22 @@ prog_start (struct prog *prog)
signal_setup (SIG_DFL);
if (prog->v.p.comp->dir)
{
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, _("chdir %s\n"),
- prog->v.p.comp->dir);
+ debug (1, (_("chdir %s"), prog->v.p.comp->dir));
if (chdir (prog->v.p.comp->dir))
- mu_error (_("%s: cannot change to directory %s: %s"),
- prog->tag, prog->v.p.comp->dir, mu_strerror (errno));
+ logmsg (LOG_ERR, _("%s: cannot change to directory %s: %s"),
+ prog->tag, prog->v.p.comp->dir, strerror (errno));
}
environ = env_setup (prog->v.p.comp->env);
- if (mu_debug_check_level (pies_debug, MU_DEBUG_TRACE4))
+ if (debug_level >= 4)
{
int i;
for (i = 0; environ[i]; i++)
- __MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE4, "%s ", environ[i]);
- mu_debug_printf (pies_debug, MU_DEBUG_TRACE4, "\n");
+ logmsg_printf (LOG_DEBUG, "%s ", environ[i]);
+ logmsg_printf (LOG_DEBUG, "\n");
}
- mf_priv_setup (&prog->v.p.comp->privs);
+
+ pies_priv_setup (&prog->v.p.comp->privs);
if (prog->v.p.comp->umask)
umask (prog->v.p.comp->umask);
@@ -688,16 +684,16 @@ prog_start (struct prog *prog)
prog->v.p.comp->limits ?
prog->v.p.comp->limits : pies_limits);
- if (mu_debug_check_level (pies_debug, MU_DEBUG_TRACE1))
+ if (debug_level >= 1)
{
- char *cmdline;
- if (mu_argcv_string (prog->v.p.argc, prog->v.p.comp->argv,
- &cmdline) == 0)
+ int i;
+ logmsg_printf (LOG_DEBUG, "executing");
+ for (i = 0; i < prog->v.p.argc; i++)
{
- __MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1,
- "executing %s\n", cmdline);
- free (cmdline);
+ /* FIXME: quote */
+ logmsg_printf (LOG_DEBUG, " %s", prog->v.p.comp->argv[i]);
}
+ logmsg_printf (LOG_DEBUG, "\n");
}
switch (prog->v.p.comp->mode)
@@ -746,15 +742,15 @@ prog_start (struct prog *prog)
execvp (prog->v.p.comp->program ?
prog->v.p.comp->program : prog->v.p.comp->argv[0],
prog->v.p.comp->argv);
- openlog (MU_LOG_TAG (), LOG_PID, mu_log_facility);
+ openlog (log_tag, LOG_PID, prog->v.p.comp->facility);
syslog (LOG_CRIT, _("cannot start `%s': %s"), prog->tag,
- mu_strerror (errno));
+ strerror (errno));
_exit (EX_SOFTWARE);
case -1:
- mu_diag_output (MU_DIAG_CRIT,
+ logmsg (LOG_CRIT,
_("cannot run `%s': fork failed: %s"),
- prog->tag, mu_strerror (errno));
+ prog->tag, strerror (errno));
break;
default:
@@ -771,48 +767,29 @@ prog_start (struct prog *prog)
}
}
-int
-pies_check_acl (mu_acl_t acl, struct sockaddr *s, int salen)
+static int
+check_acl (pies_acl_t acl, struct sockaddr *s, int salen)
{
- mu_acl_result_t res;
+ struct acl_input input;
int rc;
if (!acl)
return 0;
- rc = mu_acl_check_sockaddr (acl, s, salen, &res);
- if (rc)
- {
- char *p = mu_sockaddr_to_astr (s, salen);
- mu_error (_("access from %s blocked: cannot check ACLs: %s"),
- p, mu_strerror (rc));
- free (p);
- return 1;
- }
-
- switch (res)
- {
- case mu_acl_result_undefined:
- {
- char *p = mu_sockaddr_to_astr (s, salen);
- mu_diag_output (MU_DIAG_INFO,
- _("%s: undefined ACL result; access allowed"),
- p);
- free (p);
- }
- break;
-
- case mu_acl_result_accept:
- break;
+ input.addr = s;
+ input.addrlen = salen;
+ input.user = NULL;
+ input.groups = NULL;
- case mu_acl_result_deny:
+ rc = pies_acl_check (acl, &input, 1);
+ if (rc == 0)
{
- char *p = mu_sockaddr_to_astr (s, salen);
- mu_error (_("Access from %s blocked."), p);
+ char *p = sockaddr_to_astr (s, salen);
+ logmsg (LOG_ERR, _("access from %s blocked"), p);
free (p);
return 1;
}
- }
+
return 0;
}
@@ -831,27 +808,28 @@ progman_accept (int socket)
fd = accept (socket, (struct sockaddr*) &addr, &addrlen);
if (fd == -1)
{
- mu_error (_("accept failed: %s"), mu_strerror (errno));
+ logmsg (LOG_ERR, _("accept failed: %s"), strerror (errno));
return 1;
}
p = prog_lookup_by_socket (socket);
if (!p)
{
- mu_error (_("INTERNAL ERROR: no matching prog for fd %d"), socket);
+ logmsg (LOG_EMERG,
+ _("INTERNAL ERROR: no matching prog for fd %d"), socket);
close (fd);
return 1;
}
- if (mu_debug_check_level (pies_debug, MU_DEBUG_TRACE1))
+ if (debug_level >= 1)
{
- char *s = mu_sockaddr_to_astr ((struct sockaddr *)&addr, addrlen);
- __MU_DEBUG2 (pies_debug, MU_DEBUG_TRACE1, "%s wants %s\n", s, p->tag);
+ char *s = sockaddr_to_astr ((struct sockaddr *)&addr, addrlen);
+ logmsg (LOG_DEBUG, "%s wants %s", s, p->tag);
free (s);
}
- if (pies_check_acl (p->v.p.comp->acl, (struct sockaddr *)&addr, addrlen)
- || pies_check_acl (pies_acl, (struct sockaddr *)&addr, addrlen))
+ if (check_acl (p->v.p.comp->acl, (struct sockaddr *)&addr, addrlen)
+ || check_acl (pies_acl, (struct sockaddr *)&addr, addrlen))
{
close (fd);
return 1;
@@ -869,40 +847,40 @@ progman_accept (int socket)
void
component_fixup_depend (struct component *comp)
{
- mu_iterator_t itr;
+ const void *p;
+ gl_list_iterator_t itr;
if (comp->depend == NULL)
return;
- mu_list_get_iterator (comp->depend, &itr);
- for (mu_iterator_first (itr);
- !mu_iterator_is_done (itr); mu_iterator_next (itr))
+ itr = gl_list_iterator (comp->depend);
+ while (gl_list_iterator_next (&itr, &p, NULL))
{
- char *tag;
+ const char *tag = p;
struct component *tgt;
- mu_iterator_current (itr, (void**)&tag);
tgt = progman_lookup_component (tag);
if (!tgt)
{
- mu_error (_("component %s declares dependency target %s, "
+ logmsg (LOG_ERR,
+ _("component %s declares dependency target %s, "
"which is not declared"),
comp->tag, tag);
continue;
}
if (!tgt->prereq)
{
- int rc = mu_list_create (&tgt->prereq);
- if (rc)
- {
- mu_error (_("cannot create list: %s"), mu_strerror (rc));
- continue;
- }
+ tgt->prereq = gl_list_create_empty(&gl_linked_list_implementation,
+ NULL,
+ NULL,
+ NULL,
+ false);
}
/* FIXME: memory allocation */
- mu_list_append (tgt->prereq, xstrdup (comp->tag));
+ gl_list_add_last (tgt->prereq, xstrdup (comp->tag));
}
- mu_list_destroy (&comp->depend);
+ gl_list_free (comp->depend);
+ comp->depend = NULL;
}
void
@@ -930,15 +908,15 @@ print_dep (struct prog *prog)
pies_depmap_pos_t pos;
unsigned n;
- mu_diag_printf (MU_DIAG_NOTICE, "%s -> ", prog->tag);
+ logmsg_printf (LOG_NOTICE, "%s -> ", prog->tag);
for (n = depmap_first (depmap, depmap_col, prog->idx, &pos);
n != (unsigned)-1;
n = depmap_next (depmap, pos))
{
struct prog *dp = prog_lookup_by_idx (n);
- mu_diag_printf (MU_DIAG_NOTICE, "%s -> ", dp->tag);
+ logmsg_printf (LOG_NOTICE, "%s -> ", dp->tag);
}
- mu_diag_printf (MU_DIAG_NOTICE, "%s\n", prog->tag);
+ logmsg_printf (LOG_NOTICE, "%s\n", prog->tag);
}
void
@@ -1003,7 +981,7 @@ progman_build_depmap ()
if (!dep)
{
prog->v.p.status = status_disabled;
- mu_error (_("component %s depends on %s, "
+ logmsg (LOG_ERR, _("component %s depends on %s, "
"which is not declared"),
prog->tag, prog->prereq[i]);
rc++;
@@ -1018,7 +996,7 @@ progman_build_depmap ()
if (depmap_isset (dp, i, i))
{
prog = prog_lookup_by_idx (i);
- mu_error (_("component %s depends on itself"), prog->tag);
+ logmsg (LOG_ERR, _("component %s depends on itself"), prog->tag);
print_dep (prog);
prog->v.p.status = status_disabled;
rc++;
@@ -1065,7 +1043,7 @@ progman_recompute_alarm ()
time_t alarm_time = 0, x;
recompute_alarm = 0;
- MU_DEBUG (pies_debug, MU_DEBUG_TRACE2, "Recomputing alarm settings\n");
+ debug (2, ("Recomputing alarm settings"));
for (prog = proghead; prog; prog = prog->next)
if (IS_PROG (prog))
{
@@ -1087,8 +1065,7 @@ progman_recompute_alarm ()
break;
}
}
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE2, "alarm=%lu\n",
- (unsigned long)alarm_time);
+ debug (2, ("alarm=%lu", (unsigned long)alarm_time));
if (alarm_time)
alarm (alarm_time);
}
@@ -1101,7 +1078,7 @@ progman_start ()
struct prog *prog;
recompute_alarm = 0;
- MU_DEBUG (pies_debug, MU_DEBUG_TRACE1, "Starting components\n");
+ debug (1, ("Starting components"));
for (prog = proghead; prog; prog = prog->next)
if (IS_PROG (prog)
&& ((prog->v.p.status == status_enabled && prog->pid == 0)
@@ -1115,7 +1092,8 @@ check_stopping (struct prog *prog, time_t now)
if (now - prog->v.p.timestamp >= shutdown_timeout)
{
if (prog->pid == 0)
- mu_error (_("INTERNAL ERROR: attempting to kill unexisting process %s"),
+ logmsg (LOG_EMERG,
+ _("INTERNAL ERROR: attempting to kill unexisting process %s"),
prog->tag);
else
kill (prog->pid, SIGKILL);
@@ -1130,8 +1108,7 @@ progman_wake_sleeping ()
struct prog *prog;
time_t now = time (NULL);
- MU_DEBUG (pies_debug, MU_DEBUG_TRACE1,
- "Managing sleeping/stopping components\n");
+ debug (1, ("Managing sleeping/stopping components"));
for (prog = proghead; prog; prog = prog->next)
if (IS_PROG (prog))
@@ -1174,8 +1151,7 @@ prog_start_prerequisites (struct prog *prog)
if (!prog->prereq)
return 0; /* Ok to startup */
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, "Starting prerequisites of %s\n",
- prog->tag);
+ debug (1, ("Starting prerequisites of %s", prog->tag));
ret = 0;
for (i = 0; prog->prereq[i]; i++)
{
@@ -1244,9 +1220,7 @@ prog_stop_dependents (struct prog *prog)
continue;
if (!warned && dp->pid)
{
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1,
- "Stopping dependencies of %s\n",
- prog->tag);
+ debug (1, ("Stopping dependencies of %s", prog->tag));
warned = 1;
}
prog_stop (dp, SIGTERM);
@@ -1268,9 +1242,7 @@ prog_stop (struct prog *prog, int sig)
recompute_alarm = 1;
}
}
- MU_DEBUG2 (pies_debug, MU_DEBUG_TRACE1,
- "Stopping %s (%lu)\n",
- prog->tag, (unsigned long) prog->pid);
+ debug (1, ("Stopping %s (%lu)", prog->tag, (unsigned long) prog->pid));
kill (prog->pid, sig);
}
@@ -1279,8 +1251,7 @@ prog_stop_all (int sig)
{
struct prog *prog;
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1,
- "Stopping all components (signal %d)\n", sig);
+ debug (1, ("Stopping all components (signal %d)", sig));
for (prog = progtail; prog; prog = prog->prev)
if (IS_PROG (prog)
&& (prog->v.p.status == status_enabled
@@ -1310,11 +1281,10 @@ print_status (char *tag, pid_t pid, int status, int expect_term)
if (WIFEXITED (status))
{
if (WEXITSTATUS (status) == 0)
- MU_DEBUG2 (pies_debug, MU_DEBUG_TRACE1,
- _("%s (%lu) exited successfully\n"),
- tag, (unsigned long) pid);
+ debug (1, (_("%s (%lu) exited successfully"),
+ tag, (unsigned long) pid));
else
- mu_diag_output (MU_DIAG_ERR,
+ logmsg (LOG_ERR,
_("%s (%lu) failed with status %d"),
tag, (unsigned long) pid,
WEXITSTATUS (status));
@@ -1324,70 +1294,179 @@ print_status (char *tag, pid_t pid, int status, int expect_term)
int prio;
if (expect_term && WTERMSIG (status) == SIGTERM)
- prio = MU_DIAG_DEBUG;
+ prio = LOG_DEBUG;
else
- prio = MU_DIAG_ERR;
+ prio = LOG_ERR;
- mu_diag_output (prio,
+ logmsg (prio,
_("%s (%lu) terminated on signal %d"),
tag, (unsigned long) pid,
WTERMSIG (status));
}
else if (WIFSTOPPED (status))
- mu_diag_output (MU_DIAG_ERR,
+ logmsg (LOG_ERR,
_("%s (%lu) stopped on signal %d"),
tag, (unsigned long) pid,
WSTOPSIG (status));
#ifdef WCOREDUMP
else if (WCOREDUMP (status))
- mu_diag_output (MU_DIAG_ERR,
+ logmsg (LOG_ERR,
_("%s (%lu) dumped core"),
tag, (unsigned long) pid);
#endif
else
- mu_diag_output (MU_DIAG_ERR,
+ logmsg (LOG_ERR,
_("%s (%lu) terminated with unrecognized status"),
tag, (unsigned long) pid);
}
-static void
-send_msg (mu_address_t rcpt, mu_message_t msg)
+static int
+wait_for_child (pid_t pid)
{
- mu_mailer_t mailer;
- int rc;
- const char *s;
+ int rc = 127;
+ int wait_status;
+
+ while (waitpid (pid, &wait_status, 0) == -1)
+ if (errno != EINTR)
+ {
+ logmsg (LOG_ERR, _("waitpid failed: %s"), strerror (errno));
+ return EX_OSERR;
+ }
- mu_address_sget_email (rcpt, 1, &s);
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, "Sending email to %s\n", s);
+ if (WIFSIGNALED (wait_status))
+ {
+ int sig = WTERMSIG (wait_status);
+ logmsg (LOG_ERR, _("child died with signal %d"), sig);
+ }
+ else if (WIFEXITED (wait_status))
+ {
+ rc = WEXITSTATUS (wait_status);
+ if (rc != 0)
+ logmsg (LOG_ERR, _("child returned status %d"), rc);
+ }
+ return rc;
+}
- rc = mu_mailer_create (&mailer, NULL);
- if (rc)
+void
+send_msg (char *rcpts, const char *msg_text)
{
- const char *mailer_url;
- mu_mailer_get_url_default (&mailer_url);
+ int i;
+ pid_t pid;
+ struct wordsplit ws;
+ int p[2];
+ size_t size;
- mu_error (_("Cannot create mailer `%s': %s"),
- mailer_url, mu_strerror (rc));
+ ws.ws_offs = 3; /* sendmail -oi -t */
+ ws.ws_delim = ",";
+ if (wordsplit (rcpts, &ws,
+ WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM | WRDSF_DOOFFS))
+ {
+ logmsg (LOG_ERR,
+ _("cannot parse recipient address list (%s)"),
+ rcpts);
return;
}
- /* FIXME: mailer flags? */
- rc = mu_mailer_open (mailer, 0);
- if (rc)
+ 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++)
+ {
+ char *arg = ws.ws_wordv[3 + i];
+ size_t len;
+
+ while (*arg && c_isblank (*arg))
+ arg++;
+ len = strlen (arg);
+ if (len > 0)
+ {
+ while (len > 0 && c_isblank(arg[len - 1]))
+ len--;
+ }
+ if (len == 0)
+ continue; //FIXME
+ if (arg[0] == '<' && arg[len-1] == '>')
{
- const char *mailer_url;
- mu_mailer_get_url_default (&mailer_url);
+ arg++;
+ len -= 2;
+ }
+ if (len == 0)
+ continue; //FIXME
+ memmove (ws.ws_wordv[3 + i], arg, len);
+ ws.ws_wordv[3 + i][len] = 0;
+ }
- mu_mailer_destroy(&mailer);
- mu_error (_("opening mailer `%s' failed: %s"),
- mailer_url, mu_strerror (rc));
+ /* Fork a child: */
+ pid = fork ();
+ if (pid <= 0)
+ wordsplit_free (&ws);
+
+ if (pid < 0)
+ {
+ logmsg (LOG_ERR,
+ _("cannot send mail: fork failed: %s"), strerror (errno));
+ return;
+ }
+
+ if (pid == 0)
+ //FIXME: SIGCHLD Handler? */
+ return;
+
+ /* Child process */
+ /* ============= */
+ signal (SIGCHLD, SIG_DFL);
+ signal (SIGPIPE, SIG_DFL);
+
+ if (pipe (p))
+ {
+ logmsg (LOG_ERR, _("cannot send mail: pipe failed: %s"),
+ strerror (errno));
+ wordsplit_free (&ws);
+ exit (EX_OSERR);
+ }
+
+ pid = fork ();
+ if (pid <= 0)
+ wordsplit_free (&ws);
+
+ if (pid < 0)
+ {
+ logmsg (LOG_ERR,
+ _("cannot send mail: fork failed: %s"), strerror (errno));
return;
}
- rc = mu_mailer_send_message (mailer, msg, NULL, rcpt);
- mu_mailer_destroy (&mailer);
- if (rc)
- mu_error (_("cannot send message: %s"), mu_strerror (rc));
+ if (pid)
+ {
+ /* Grand-child */
+ /* =========== */
+ if (p[0] != 0 && p[1] != 0)
+ close (0);
+ close (p[1]);
+ dup2 (p[0], 0);
+ execv (ws.ws_wordv[0], ws.ws_wordv);
+ exit (127);
+ }
+
+ /* Child again */
+ close (p[0]);
+
+ size = strlen (msg_text);
+ while (size)
+ {
+ ssize_t rc = write (p[1], msg_text, size);
+ if (rc <= 0)
+ {
+ logmsg (LOG_ERR, _("cannot write to pipe: %s"),
+ rc == 0 ? "EOF" : strerror (errno));
+ break;
+ }
+ size -= rc;
+ msg_text += rc;
+ }
+ close (p[1]);
+
+ exit (wait_for_child (pid));
}
static const char default_termination_message[] =
@@ -1397,67 +1476,36 @@ static const char default_termination_message[] =
"\n";
static void
-vartab_define_project (mu_vartab_t vtab)
+notify (const char *tag, int status, struct action *act)
+{
+ struct metadef mdef[] =
{
- static struct {
- char *name;
- char *value;
- } ptab[] = {
{ "canonical-program-name", "pies" },
{ "package", PACKAGE },
{ "version", PACKAGE_VERSION },
- { "mu-version", MAILUTILS_VERSION },
+#define COMPONENT_IDX 3
+ { "component", NULL },
+#define RETCODE_IDX 4
+ { "retcode", NULL },
+#define PROGRAM_NAME_IDX 5
+ { "program-name", NULL },
{ NULL }
};
- int i;
-
- for (i = 0; ptab[i].name; i++)
- mu_vartab_define (vtab, ptab[i].name, ptab[i].value, 1);
-}
-
-static void
-notify (const char *tag, int status, struct action *act)
-{
- mu_vartab_t vtab;
char *msg_text = NULL;
- mu_message_t msg = NULL;
- mu_stream_t stream = NULL;
- int rc;
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
- mu_vartab_create (&vtab);
- mu_vartab_define (vtab, "component", tag, 1);
- mu_vartab_define (vtab, "retcode", umaxtostr (status, buf), 1);
- mu_vartab_define (vtab, "program-name", mu_program_name, 1);
- vartab_define_project (vtab);
- rc = mu_vartab_expand (vtab,
- act->message ?
+ mdef[COMPONENT_IDX].value = (char*) tag;
+ mdef[RETCODE_IDX].value = umaxtostr (status, buf);
+ mdef[PROGRAM_NAME_IDX].value = (char*) program_name;
+ msg_text = meta_expand_string (act->message ?
act->message : default_termination_message,
- &msg_text);
- mu_vartab_destroy (&vtab);
- if (rc)
- {
- mu_error (_("cannot expand message body: %s"), mu_strerror (rc));
- /* FIXME: Notify anyway? */
- return;
- }
+ mdef, NULL);
- rc = mu_message_create (&msg, NULL);
- if (rc)
- {
- mu_error (_("cannot create message: %s"), mu_strerror (rc));
+ send_msg (act->addr, msg_text);
free (msg_text);
}
- mu_message_get_stream (msg, &stream);
- mu_stream_write (stream, msg_text, strlen (msg_text), 0, NULL);
- free (msg_text);
-
- send_msg (act->addr, msg);
- mu_message_destroy (&msg, mu_message_get_owner (msg));
-}
-
static int
status_matches_p (struct action *act, unsigned status)
{
@@ -1487,7 +1535,7 @@ run_command (struct action *act, struct prog *prog, unsigned retcode,
if (pid == (pid_t) -1)
{
- mu_error ("fork: %s", mu_strerror (errno));
+ logmsg (LOG_ERR, "fork: %s", strerror (errno));
return;
}
@@ -1495,8 +1543,7 @@ run_command (struct action *act, struct prog *prog, unsigned retcode,
{
int i;
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1,
- _("executing %s\n"), act->command);
+ debug (1, (_("executing %s"), act->command));
/* Child */
setenv ("PIES_VERSION", PACKAGE_VERSION, 1);
setenv ("PIES_COMPONENT", prog->tag, 1);
@@ -1522,7 +1569,7 @@ run_command (struct action *act, struct prog *prog, unsigned retcode,
while (waitpid (pid, &status, 0) == -1)
if (errno != EINTR)
{
- mu_error ("waitpid: %s", mu_strerror (errno));
+ logmsg (LOG_ERR, "waitpid: %s", strerror (errno));
break;
}
signal (SIGPIPE, saved_handler);
@@ -1540,7 +1587,7 @@ progman_cleanup (int expect_term)
struct prog *prog = prog_lookup_by_pid (pid);
if (!prog)
{
- mu_diag_output (MU_DIAG_NOTICE,
+ logmsg (LOG_NOTICE,
_("subprocess %lu finished"),
(unsigned long) pid);
continue;
@@ -1592,7 +1639,7 @@ progman_cleanup (int expect_term)
break;
case action_disable:
- mu_diag_output (MU_DIAG_NOTICE,
+ logmsg (LOG_NOTICE,
_("disabling component %s: "
"exited with code %d"),
prog->tag, status);
@@ -1613,8 +1660,7 @@ progman_cleanup (int expect_term)
else
{
/* It was a redirector of an already finished inetd process. */
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1,
- _("removing inetd redirector %s\n"), prog->tag);
+ debug (1, (_("removing inetd redirector %s"), prog->tag));
destroy_prog (&prog);
}
}
@@ -1629,7 +1675,7 @@ progman_stop_component (const char *name)
{
struct prog *prog;
- mu_diag_output (MU_DIAG_INFO, _("stopping component `%s'"), name);
+ logmsg (LOG_INFO, _("stopping component `%s'"), name);
for (prog = proghead; prog; prog = prog->next)
if (IS_PROG (prog) && strcmp (prog->tag, name) == 0)
{
@@ -1646,7 +1692,7 @@ progman_stop_component (const char *name)
break;
default:
- mu_diag_output (MU_DIAG_INFO,
+ logmsg (LOG_INFO,
_("stopping component `%s': "
"component not started"),
name);
@@ -1659,27 +1705,27 @@ progman_dump_stats (const char *filename)
{
FILE *fp;
struct prog *prog;
- char *s;
- int rc;
char *tmpfile = NULL;
asprintf (&tmpfile, "%s.%lu", filename, (unsigned long) getpid ());
if (!tmpfile)
{
- mu_error ("%s", mu_strerror (ENOMEM));
+ logmsg (LOG_ERR, "%s", strerror (ENOMEM));
return;
}
- mu_diag_output (MU_DIAG_INFO, _("dumping statistics to `%s'"), tmpfile);
+ logmsg (LOG_INFO, _("dumping statistics to `%s'"), tmpfile);
fp = fopen (tmpfile, "w");
if (!fp)
{
- mu_error (_("cannot open file `%s' for writing: %s"),
- tmpfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot open file `%s' for writing: %s"),
+ tmpfile, strerror (errno));
return;
}
for (prog = proghead; prog; prog = prog->next)
{
+ int i;
+
switch (prog->type)
{
case TYPE_COMPONENT:
@@ -1704,15 +1750,10 @@ progman_dump_stats (const char *filename)
fprintf (fp, _("[listener]"));
else
fprintf (fp, _("[not running]"));
- if (rc = mu_argcv_string (prog->v.p.argc, prog->v.p.comp->argv, &s))
- {
- mu_error (_("cannot convert argument list: %s"),
- mu_strerror (rc));
- }
- else
+ for (i = 0; i < prog->v.p.argc; i++)
{
- fprintf (fp, " %s", s);
- free (s);
+ /* FIXME: quote as appropriate */
+ fprintf (fp, " %s", prog->v.p.comp->argv[i]);
}
fputc ('\n', fp);
break;
@@ -1726,16 +1767,10 @@ progman_dump_stats (const char *filename)
unlink (filename);
if (rename (tmpfile, filename))
{
- mu_error (_("cannot rename %s to %s: %s"), tmpfile, filename,
- mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot rename %s to %s: %s"), tmpfile, filename,
+ strerror (errno));
unlink (tmpfile);
}
free (tmpfile);
}
-
-/*
- Local Variables:
- c-file-style: "gnu"
- End:
-*/
/* EOF */
diff --git a/src/socket.c b/src/socket.c
index 03ee59c..8f32ae7 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -1,18 +1,18 @@
-/* This file is part of Mailfromd.
- Copyright (C) 2007, 2008 Sergey Poznyakoff
+/* This file is part of Pies.
+ Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 3 of the License, or (at your
- option) any later version.
+ Pies is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
- This program is distributed in the hope that it will be useful,
+ Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program. If not, see <http://www.gnu.org/licenses/>. */
+ You should have received a copy of the GNU General Public License
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
#include "pies.h"
@@ -38,18 +38,18 @@ switch_eids (uid_t *puid, gid_t *pgid, mode_t *pumask)
mode_t omask = umask (*pumask);
if (setegid (*pgid))
- mu_error (_("Cannot switch to EGID %lu: %s"),
- (unsigned long) *pgid, mu_strerror (errno));
+ logmsg (LOG_ERR, _("Cannot switch to EGID %lu: %s"),
+ (unsigned long) *pgid, strerror (errno));
if (seteuid (*puid))
- mu_error (_("Cannot switch to EUID %lu: %s"),
- (unsigned long) *puid, mu_strerror (errno));
+ logmsg (LOG_ERR, _("Cannot switch to EUID %lu: %s"),
+ (unsigned long) *puid, strerror (errno));
*puid = ouid;
*pgid = ogid;
*pumask = omask;
}
int
-create_socket (mu_url_t url, const char *user, mode_t umaskval)
+create_socket (struct pies_url *url, const char *user, mode_t umaskval)
{
int rc;
int fd;
@@ -60,61 +60,52 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval)
struct sockaddr_un s_un;
} addr;
socklen_t socklen;
- const char *scheme;
uid_t uid = 0;
gid_t gid = 0;
int switch_back;
- rc = mu_url_sget_scheme (url, &scheme);
- if (rc)
+ if (strcmp (url->proto, "unix") == 0
+ || strcmp (url->proto, "file") == 0
+ || strcmp (url->proto, "socket") == 0)
{
- mu_error ("mu_url_sget_scheme: %s", mu_strerror (rc));
- return -1;
- }
-
- if (strcmp (scheme, "unix") == 0
- || strcmp (scheme, "file") == 0 || strcmp (scheme, "socket") == 0)
- {
- const char *path = NULL;
struct stat st;
- size_t vpc;
- char **vpairs;
- char *group = NULL;
+ const char *group = NULL;
- mu_url_sget_user (url, &user);
- if (mu_url_sget_fvpairs (url, &vpc, &vpairs) == 0)
+ user = url->user;
+ if (url->argc)
{
size_t i;
- for (i = 0; i < vpc; i++)
+ for (i = 0; i < url->argc; i++)
{
- size_t len = strcspn (vpairs[i], "=");
- if (strncmp (vpairs[i], "user", len) == 0)
- user = vpairs[i] + len + 1;
- else if (strncmp (vpairs[i], "group", len) == 0)
- group = vpairs[i] + len + 1;
- else if (strncmp (vpairs[i], "umask", len) == 0)
+ const char *arg = url->argv[i];
+ size_t len = strcspn (arg, "=");
+ if (strncmp (arg, "user", len) == 0)
+ user = arg + len + 1;
+ else if (strncmp (arg, "group", len) == 0)
+ group = arg + len + 1;
+ else if (strncmp (arg, "umask", len) == 0)
{
char *p;
- unsigned long n = strtoul (vpairs[i] + len + 1, &p, 8);
+ unsigned long n = strtoul (arg + len + 1, &p, 8);
if (*p)
- mu_error (_("%s: invalid octal number (%s)"),
- mu_url_to_string (url), vpairs[i] + len + 1);
+ logmsg (LOG_ERR, _("%s: invalid octal number (%s)"),
+ url->string, arg + len + 1);
else if (n & ~0777)
- mu_error (_("%s: invalid umask (%s)"),
- mu_url_to_string (url), vpairs[i] + len + 1);
+ logmsg (LOG_ERR, _("%s: invalid umask (%s)"),
+ url->string, arg + len + 1);
else
umaskval = n & 0777;
}
- else if (strncmp (vpairs[i], "mode", len) == 0)
+ else if (strncmp (arg, "mode", len) == 0)
{
char *p;
- unsigned long n = strtoul (vpairs[i] + len + 1, &p, 8);
+ unsigned long n = strtoul (arg + len + 1, &p, 8);
if (*p)
- mu_error (_("%s: invalid octal number (%s)"),
- mu_url_to_string (url), vpairs[i] + len + 1);
+ logmsg (LOG_ERR, _("%s: invalid octal number (%s)"),
+ url->string, arg + len + 1);
else if (n & ~0777)
- mu_error (_("%s: invalid mode (%s)"),
- mu_url_to_string (url), vpairs[i] + len + 1);
+ logmsg (LOG_ERR, _("%s: invalid mode (%s)"),
+ url->string, arg + len + 1);
else
umaskval = 0777 & ~n;
}
@@ -126,7 +117,7 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval)
struct passwd *pw = getpwnam (user);
if (!pw)
{
- mu_error (_("No such user: %s"), user);
+ logmsg (LOG_ERR, _("no such user: %s"), user);
return -1;
}
uid = pw->pw_uid;
@@ -138,36 +129,27 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval)
struct group *grp = getgrnam (group);
if (!grp)
{
- mu_error (_("No such group: %s"), user);
+ logmsg (LOG_ERR, _("no such group: %s"), user);
return -1;
}
gid = grp->gr_gid;
}
- rc = mu_url_sget_path (url, &path);
- if (rc)
- {
- mu_error ("mu_url_sget_path: %s", mu_strerror (rc));
- return -1;
- }
-
- if (strlen (path) > sizeof addr.s_un.sun_path)
+ if (strlen (url->path) > sizeof addr.s_un.sun_path)
{
errno = EINVAL;
- mu_error (_("%s: UNIX socket name too long"),
- mu_url_to_string (url));
+ logmsg (LOG_ERR, _("%s: UNIX socket name too long"), url->path);
return -1;
}
addr.sa.sa_family = PF_UNIX;
socklen = sizeof (addr.s_un);
- strcpy (addr.s_un.sun_path, path);
- if (stat(path, &st))
+ strcpy (addr.s_un.sun_path, url->path);
+ if (stat (url->path, &st))
{
if (errno != ENOENT)
{
- mu_error (_("%s: cannot stat socket: %s"),
- mu_url_to_string (url),
- mu_strerror (errno));
+ logmsg (LOG_ERR, _("%s: cannot stat socket: %s"),
+ url->string, strerror (errno));
return -1;
}
}
@@ -176,44 +158,21 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval)
/* FIXME: Check permissions? */
if (!S_ISSOCK (st.st_mode))
{
- mu_error (_("%s: not a socket"), mu_url_to_string (url));
+ logmsg (LOG_ERR, _("%s: not a socket"), url->string);
return -1;
}
- if (/*rmsocket && */ unlink (path))
+ if (/*rmsocket && */ unlink (url->path))
{
- mu_error (_("%s: cannot unlink: %s"),
- path, mu_strerror (errno));
+ logmsg (LOG_ERR, _("%s: cannot unlink: %s"),
+ url->path, strerror (errno));
return -1;
}
}
}
- else if (strcmp (scheme, "inet") == 0)
- {
- long n;
- const char *host = NULL;
- short port = 0;
-
- rc = mu_url_get_port (url, &n);
- if (rc)
- {
- mu_error ("mu_url_get_port: %s", mu_strerror (rc));
- return -1;
- }
-
- if (n == 0 || (port = n) != n)
- {
- mu_error (_("%s: port out of range"), mu_url_to_string (url));
- return -1;
- }
-
- rc = mu_url_sget_host (url, &host);
- if (rc == MU_ERR_NOENT)
- host = NULL;
- else if (rc)
+ else if (strcmp (url->proto, "inet") == 0)
{
- mu_error ("mu_url_sget_host: %s", mu_strerror (rc));
- return -1;
- }
+ const char *host = url->host;
+ short port = url->port;
addr.sa.sa_family = PF_INET;
socklen = sizeof (addr.s_in);
@@ -225,8 +184,8 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval)
struct hostent *hp = gethostbyname (host);
if (!hp)
{
- mu_error (_("%s: Unknown host name %s"),
- mu_url_to_string (url), host);
+ logmsg (LOG_ERR, _("%s: Unknown host name %s"),
+ url->string, host);
return -1;
}
addr.sa.sa_family = hp->h_addrtype;
@@ -238,23 +197,23 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval)
break;
default:
- mu_error (_("%s: unsupported address family"),
- mu_url_to_string (url));
+ logmsg (LOG_ERR, _("%s: unsupported address family"),
+ url->string);
return -1;
}
}
}
else
{
- mu_error ("%s: unknown scheme", mu_url_to_string (url));
+ logmsg (LOG_ERR, "%s: unknown scheme", url->string);
return -1;
}
fd = socket (addr.sa.sa_family, SOCK_STREAM, 0);
if (fd == -1)
{
- mu_error (_("%s: Cannot create socket: %s"),
- mu_url_to_string (url), mu_strerror (errno));
+ logmsg (LOG_ERR, _("%s: cannot create socket: %s"),
+ url->string, strerror (errno));
return -1;
}
@@ -263,8 +222,8 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval)
&& setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &rc,
sizeof (rc)) == -1)
{
- mu_error (_("%s: set reuseaddr failed (%s)"),
- mu_url_to_string (url), mu_strerror (errno));
+ logmsg (LOG_ERR, _("%s: set reuseaddr failed (%s)"),
+ url->string, strerror (errno));
close (fd);
return -1;
}
@@ -281,8 +240,8 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval)
switch_eids (&uid, &gid, &umaskval);
if (rc < 0)
{
- mu_error (_("%s: Cannot bind: %s"),
- mu_url_to_string (url), mu_strerror (errno));
+ logmsg (LOG_ERR, _("%s: cannot bind: %s"),
+ url->string, strerror (errno));
close (fd);
return -1;
}
@@ -297,14 +256,14 @@ open_unix_socket (const char *socket_name)
if (strlen (socket_name) > sizeof addr.sun_path)
{
- mu_error (_("%s: UNIX socket name too long"), socket_name);
+ logmsg (LOG_ERR, _("%s: UNIX socket name too long"), socket_name);
return -1;
}
fd = socket (PF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
{
- mu_error ("socket: %s", mu_strerror (errno));
+ logmsg (LOG_ERR, "socket: %s", strerror (errno));
return -1;
}
addr.sun_family = AF_UNIX;
@@ -312,7 +271,7 @@ open_unix_socket (const char *socket_name)
if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)))
{
- mu_error (_("%s: connect failed: %s"), socket_name, mu_strerror (errno));
+ logmsg (LOG_ERR, _("%s: connect failed: %s"), socket_name, strerror (errno));
close (fd);
return -1;
}
@@ -349,7 +308,7 @@ pass_fd0 (int fd, int payload)
msg.msg_accrights = (caddr_t) &payload;
msg.msg_accrightslen = sizeof (int);
#else
- mu_error (_("no way to send fd"));
+ logmsg (LOG_ERR, _("no way to send fd"));
return 1;
#endif /* HAVE_MSGHDR_MSG_CONTROL */
@@ -379,7 +338,7 @@ pass_fd (const char *socket, int fd)
if (!S_ISSOCK (st.st_mode))
{
- mu_error (_("%s: not a socket"), socket);
+ logmsg (LOG_ERR, _("%s: not a socket"), socket);
break;
}
sockfd = open_unix_socket (socket);
@@ -394,7 +353,7 @@ pass_fd (const char *socket, int fd)
}
if (errno != ENOENT)
{
- mu_error (_("cannot stat %s: %s"), socket, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot stat %s: %s"), socket, strerror (errno));
break;
}
}
@@ -410,7 +369,7 @@ register_listener (int fd)
{
if (listen (fd, 8) == -1)
{
- mu_error (_("listen: %s"), mu_strerror (errno));
+ logmsg (LOG_ERR, _("listen: %s"), strerror (errno));
return 1;
}
FD_SET (fd, &listenset);
@@ -438,7 +397,7 @@ pies_pause ()
else if (rc < 0)
{
if (errno != EINTR)
- mu_error ("select: %s", mu_strerror (errno));
+ logmsg (LOG_ERR, "select: %s", strerror (errno));
break;
}
}

Return to:

Send suggestions and report system problems to the System administrator.