diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-10-22 23:03:24 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-10-23 00:42:30 +0300 |
commit | 21ffba77b92f79a59c62728ede4ad7a4ecb5a0ee (patch) | |
tree | c3204285a3ba57d590d815c682f1113b6f48d834 | |
parent | eb8797c9a28f3f4e238bad89b56d331492df7828 (diff) | |
download | pies-21ffba77b92f79a59c62728ede4ad7a4ecb5a0ee.tar.gz pies-21ffba77b92f79a59c62728ede4ad7a4ecb5a0ee.tar.bz2 |
Switch to the latest Grecs.
* Makefile.am (ChangeLog): Use git2chg.awk to build it.
* NEWS: Update.
* bootstrap.conf (gnulib_modules): Grecs does not depend on gnulib any more.
* configure.ac: Version 1.2.90.
Define GRECS_HOST_PROJECT_INCLUDES, remove grecs Makefiles from
AC_CONFIG_FILES: it is now done by GRECS_SETUP itself.
* gnulib.modules (gitlog-to-changelog,argp): Remove.
(configmake): New module.
* grecs: Update to a52ab6c6.
* lib/libpies.h: Remove redefinitions of _() and N_().
* src/Makefile.am: Update for the recent grecs.
* src/acl.c: Rewrite using Grecs support for lists and symtabs.
* src/acl.h: Likewise.
* src/diag.c: Likewise.
* src/inetd.c: Likewise.
* src/meta1gram.y: Likewise.
* src/meta1lex.h: Likewise.
* src/meta1lex.l: Likewise.
* src/pies.c: Likewise.
* src/pies.h: Likewise.
* src/progman.c: Likewise.
* src/userprivs.c: Likewise.
-rw-r--r-- | Makefile.am | 42 | ||||
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | bootstrap.conf | 9 | ||||
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | gnulib.modules | 3 | ||||
m--------- | grecs | 0 | ||||
-rw-r--r-- | lib/libpies.h | 6 | ||||
-rw-r--r-- | src/.gitignore | 1 | ||||
-rw-r--r-- | src/Makefile.am | 17 | ||||
-rw-r--r-- | src/acl.c | 206 | ||||
-rw-r--r-- | src/acl.h | 4 | ||||
-rw-r--r-- | src/cmdline.opt | 193 | ||||
-rw-r--r-- | src/diag.c | 40 | ||||
-rw-r--r-- | src/inetd.c | 18 | ||||
-rw-r--r-- | src/meta1gram.y | 47 | ||||
-rw-r--r-- | src/meta1lex.h | 3 | ||||
-rw-r--r-- | src/meta1lex.l | 55 | ||||
-rw-r--r-- | src/pies.c | 329 | ||||
-rw-r--r-- | src/pies.h | 12 | ||||
-rw-r--r-- | src/progman.c | 86 | ||||
-rw-r--r-- | src/userprivs.c | 49 |
21 files changed, 562 insertions, 575 deletions
diff --git a/Makefile.am b/Makefile.am index b3c49a2..de4bf81 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,8 +1,8 @@ # This file is part of GNU Pies. -# Copyright (C) 2008, 2009, 2010 Sergey Poznyakoff +# Copyright (C) 2008, 2009, 2010, 2011 Sergey Poznyakoff # # GNU 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. # @@ -31,40 +31,22 @@ dist-hook: alpha: $(MAKE) dist distdir=$(PACKAGE)-$(VERSION)-`date +"%Y%m%d"` alphacheck: $(MAKE) distcheck distdir=$(PACKAGE)-$(VERSION)-`date +"%Y%m%d"` -# Define the following variables in order to use the ChangeLog rule below: -# prev_change_log [optional] Name of the previous ChangeLog file. -# gen_start_date [optional] Start ChangeLog from this date. -# changelog_dir [mandatory] Directory where to create ChangeLog +# Name of the previous ChangeLog file. prev_change_log = ChangeLog.mfd +# Start Git ChangeLog from this date. gen_start_date = 2009-09-04 -changelog_dir = . .PHONY: ChangeLog -ChangeLog: - @if test -d .git; then \ - cmd=$(top_srcdir)/build-aux/gitlog-to-changelog; \ - if test -n "$(gen_start_date)"; then \ - cmd="$$cmd --since=\"$(gen_start_date)\""; \ - fi; \ - $$cmd --format='%s%n%n%b%n' | \ - sed '/<unknown>$$/d' | fmt -s > $(changelog_dir)/cl-t; \ - if test -n "$(prev_change_log)" && test -f "$(prev_change_log)"; \ - then \ - echo "" >> $(changelog_dir)/cl-t; \ - cat "$(prev_change_log)" | \ - sed '/^Local Variables:/,/^End:/d' >> $(changelog_dir)/cl-t; \ - fi; \ - echo "Local Variables:" >> $(changelog_dir)/cl-t; \ - echo "mode: change-log" >> $(changelog_dir)/cl-t; \ - echo "version-control: never" >> $(changelog_dir)/cl-t; \ - echo "buffer-read-only: t" >> $(changelog_dir)/cl-t; \ - echo "End:" >> $(changelog_dir)/cl-t; \ - echo "" >> $(changelog_dir)/cl-t; \ - sed -n '1,/^[^#]/s/^#//p' $(top_srcdir)/Makefile.am \ - >> $(changelog_dir)/cl-t; \ - rm -f $(changelog_dir)/ChangeLog; \ - mv $(changelog_dir)/cl-t $(changelog_dir)/ChangeLog; \ +ChangeLog: + $(AM_V_GEN)if test -d .git; then \ + git log --pretty='format:%ct %an <%ae>%n%n%s%n%n%b%n' | \ + awk -f $(top_srcdir)/@GRECS_SUBDIR@/build-aux/git2chg.awk \ + -vsince=\"$(gen_start_date)\" -vappend=\"$(prev_change_log)\" \ + > ChangeLog.tmp; \ + cmp ChangeLog ChangeLog.tmp > /dev/null 2>&1 || \ + mv ChangeLog.tmp ChangeLog; \ + rm -f ChangeLog.tmp; \ fi @@ -1,14 +1,16 @@ -GNU Pies NEWS -- history of user-visible changes. 2009-12-11 -Copyright (C) 2009, 2010 Sergey Poznyakoff +GNU Pies NEWS -- history of user-visible changes. 2011-10-23 +Copyright (C) 2009, 2010, 2011 Sergey Poznyakoff See the end of file for copying conditions. Please send Pies bug reports to <bug-pies@gnu.org> or <bug-pies@gnu.org.ua> +Version 1.2.90 (Git) + Version 1.2, 2009-12-11 * First release as a GNU package. * Full inetd support @@ -69,13 +71,13 @@ First stand-alone release. Previous versions were released as part of Mailfromd (http://mailfromd.software.gnu.org.ua). ========================================================================= Copyright information: -Copyright (C) 2009 Sergey Poznyakoff +Copyright (C) 2009, 2010, 2011 Sergey Poznyakoff Permission is granted to anyone to make or distribute verbatim copies of this document as received, in any medium, provided that the copyright notice and this permission notice are preserved, thus giving the recipient permission to redistribute in turn. diff --git a/bootstrap.conf b/bootstrap.conf index 364978b..492aa78 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -1,8 +1,8 @@ # Bootstrap configuration for GNU Pies. -*- shell-script -*- -# Copyright (C) 2008, 2009, 2010 Sergey Poznyakoff +# Copyright (C) 2008, 2009, 2010, 2011 Sergey Poznyakoff # # GNU 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. # @@ -28,17 +28,18 @@ MODAVOID="xalloc-die openat-die" if [ -n "$MODAVOID" ]; then gnulib_tool_option_extras="`echo $MODAVOID | sed 's/\([^ ][^ ]*\)/--avoid &/g'`" fi # gnulib modules used by this package. -gnulib_modules=`grep -h '^[^#]' gnulib.modules grecs/gnulib.modules | sort | uniq` +gnulib_modules=`grep -h '^[^#]' gnulib.modules | sort | uniq` NLS_MARKERS="\ - mu_error:1" - + mu_error:1\ + grecs_error:3\ + grecs_warning:3" # Additional xgettext options to use. Use "\\\newline" to break lines. if [ -n "$NLS_MARKERS" ]; then XGETTEXT_OPTIONS="$XGETTEXT_OPTIONS "`echo $NLS_MARKERS | tr ' ' '\n' | sed 's/.*/ --flag=&:pass-c-format\\\\\\\\\\\\/'`" " fi diff --git a/configure.ac b/configure.ac index a8848dd..0c1d2b9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # This file is part of GNU Pies. -*- autoconf -*- -# Copyright (C) 2009, 2010 Sergey Poznyakoff +# Copyright (C) 2009, 2010, 2011 Sergey Poznyakoff # # GNU 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. # @@ -12,13 +12,13 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. AC_PREREQ([2.63]) -AC_INIT([GNU Pies], [1.2], [bug-pies@gnu.org.ua]) +AC_INIT([GNU Pies], [1.2.90], [bug-pies@gnu.org.ua]) AC_CONFIG_SRCDIR([src/pies.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([1.11 gnits tar-ustar dist-bzip2 std-options silent-rules]) # Enable silent rules by default: @@ -54,13 +54,14 @@ AC_FUNC_FORK AC_CHECK_FUNCS([alarm dup2 gethostbyname memmove memset select setenv socket strchr strcspn strtol strtoul sysconf getdtablesize vsyslog]) # Gnulib gl_INIT # Grecs -GRECS_SETUP +GRECS_SETUP([grecs],[tests git2chg getopt]) +GRECS_HOST_PROJECT_INCLUDES='-I$(top_srcdir)/gnu -I$(top_builddir)/gnu' # Test for setproctitle MF_PROCTITLE # Gettext. AM_ICONV @@ -82,13 +83,11 @@ AH_BOTTOM([ ]) IMPRIMATUR_INIT AC_CONFIG_FILES([Makefile gnu/Makefile - grecs/Makefile - grecs/src/Makefile lib/Makefile src/Makefile doc/Makefile po/Makefile.in]) AC_OUTPUT diff --git a/gnulib.modules b/gnulib.modules index d62e1a3..1e01a93 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -1,15 +1,14 @@ # List of gnulib modules needed for Pies. # A module name per line. Empty lines and comments are ignored. -argp c-ctype c-strcase +configmake fprintftime gettext -gitlog-to-changelog inttostr inttypes obstack progname quotearg sysexits diff --git a/grecs b/grecs -Subproject edcc575bcdc9e50bdb79f422ad0f11dc79f3eaa +Subproject a52ab6c6c38e1dca047ada4d60249fb323942f0 diff --git a/lib/libpies.h b/lib/libpies.h index 04910d5..d071846 100644 --- a/lib/libpies.h +++ b/lib/libpies.h @@ -1,8 +1,8 @@ /* This file is part of GNU Pies. - Copyright (C) 2009, 2010 Sergey Poznyakoff + Copyright (C) 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -16,16 +16,12 @@ #include <unistd.h> #include <stdlib.h> #include <gettext.h> -#define _(String) gettext(String) -#define N_(String) String - - #if defined HAVE_SYSCONF && defined _SC_OPEN_MAX # define getmaxfd() sysconf(_SC_OPEN_MAX) #elif defined (HAVE_GETDTABLESIZE) # define getmaxfd() getdtablesize() #else # define getmaxfd() 256 diff --git a/src/.gitignore b/src/.gitignore index 18a7111..4ad4290 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,6 +1,7 @@ +cmdline.h inetd meta1gram.c meta1gram.h meta1gram.output meta1lex.c pies diff --git a/src/Makefile.am b/src/Makefile.am index 19c6483..455b2c2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,8 +1,8 @@ # This file is part of GNU Pies. -# Copyright (C) 2008, 2009, 2010 Sergey Poznyakoff +# Copyright (C) 2008, 2009, 2010, 2011 Sergey Poznyakoff # # GNU 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. # @@ -32,31 +32,40 @@ pies_SOURCES = \ socket.c\ url.c\ userprivs.c noinst_HEADERS = \ acl.h\ + cmdline.h\ meta1gram.h\ meta1lex.h\ pies.h meta1lex.c: meta1gram.h +BUILT_SOURCES=cmdline.h + incdir=$(pkgdatadir)/$(VERSION)/include inc_DATA = pp-setup -EXTRA_DIST = pp-setup inetd.in +EXTRA_DIST = cmdline.opt pp-setup inetd.in + +SUFFIXES=.opt .c .h +.opt.h: + $(AM_V_GEN)m4 -s $(top_srcdir)/@GRECS_SUBDIR@/build-aux/getopt.m4 $< > $@ + +cmdline.h: cmdline.opt INCLUDES = \ -I$(top_srcdir)/lib\ -I$(top_srcdir)/gnu\ -I$(top_builddir)/gnu\ - -I$(top_srcdir)/grecs/src + @GRECS_INCLUDES@ LDADD = \ ../lib/libpies.a\ - ../grecs/src/libgrecs.a\ + @GRECS_LDADD@\ ../gnu/libgnu.a\ $(MF_PROCTITLE_LIBS) pkgstatedir=$(localstatedir)/pies AM_CPPFLAGS=\ @@ -1,8 +1,8 @@ /* This file is part of GNU Pies - Copyright (C) 2009, 2010 Sergey Poznyakoff + Copyright (C) 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -22,13 +22,12 @@ #include <sys/socket.h> #include <sys/time.h> #include <sys/un.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> -#include <hash.h> struct pies_sockaddr { unsigned netmask; int salen; struct sockaddr sa; @@ -37,41 +36,45 @@ struct pies_sockaddr struct acl_entry { grecs_locus_t locus; int allow; int authenticated; pies_acl_t acl; - gl_list_t groups; - gl_list_t sockaddrs; + struct grecs_list *groups; + struct grecs_list *sockaddrs; }; struct pies_acl { char *name; grecs_locus_t locus; - gl_list_t list; + struct grecs_list *list; }; /* ACL creation */ pies_acl_t pies_acl_create (const char *name, grecs_locus_t *locus) { pies_acl_t acl = xmalloc (sizeof (acl[0])); acl->name = name ? xstrdup (name) : NULL; acl->locus = *locus; - acl->list = gl_list_create_empty(&gl_linked_list_implementation, - NULL, - NULL, - NULL, - false); + acl->list = grecs_list_create (); return acl; } +void +pies_acl_free (pies_acl_t acl) +{ + free (acl->name); + grecs_list_free (acl->list); + free (acl); +} + static struct pies_sockaddr * create_acl_sockaddr (int family, int len) { struct pies_sockaddr *p = xzalloc (sizeof (*p)); p->salen = len; p->sa.sa_family = family; @@ -186,60 +189,55 @@ _parse_sockaddr (struct acl_entry *entry, const grecs_value_t *value) return 1; } } else sptr->netmask = 0xfffffffful; } - gl_list_add_last (entry->sockaddrs, sptr); + grecs_list_append (entry->sockaddrs, sptr); return 0; } static int -_parse_from (struct acl_entry *entry, size_t argc, const grecs_value_t *argv) +_parse_from (struct acl_entry *entry, size_t argc, grecs_value_t **argv) { if (argc == 0) return 0; - else if (argv->type == GRECS_TYPE_LIST) + else if (argv[0]->type == GRECS_TYPE_LIST) { grecs_error (&entry->locus, 0, _("expected `from', but found list")); return 1; } - else if (strcmp (argv->v.string, "from")) + else if (strcmp (argv[0]->v.string, "from")) { grecs_error (&entry->locus, 0, _("expected `from', but found `%s'"), - argv->v.string); + argv[0]->v.string); return 1; } argc--; argv++; if (argc == 0) { grecs_error (&entry->locus, 0, _("unexpected end of statement after `from'")); return 1; } - entry->sockaddrs = gl_list_create_empty(&gl_linked_list_implementation, - NULL, - NULL, - NULL, - false); - if (argv->type == GRECS_TYPE_STRING) + entry->sockaddrs = grecs_list_create (); + if (argv[0]->type == GRECS_TYPE_STRING) { - if (_parse_sockaddr (entry, argv)) + if (_parse_sockaddr (entry, argv[0])) return 1; } else { - gl_list_iterator_t itr = gl_list_iterator (argv->v.list); - const void *p; int rc = 0; - while (gl_list_iterator_next (&itr, &p, NULL)) - rc += _parse_sockaddr (entry, (const grecs_value_t*) p); - gl_list_iterator_free (&itr); + struct grecs_list_entry *ep; + + for (ep = argv[0]->v.list->head; ep; ep = ep->next) + rc += _parse_sockaddr (entry, (const grecs_value_t*) ep->data); if (rc) return rc; } if (argc - 1) { @@ -247,84 +245,80 @@ _parse_from (struct acl_entry *entry, size_t argc, const grecs_value_t *argv) return 1; } return 0; } static int -_parse_sub_acl (struct acl_entry *entry, size_t argc, grecs_value_t *argv) +_parse_sub_acl (struct acl_entry *entry, size_t argc, grecs_value_t **argv) { if (argc == 0) return 0; - if (strcmp (argv->v.string, "acl") == 0) + if (strcmp (argv[0]->v.string, "acl") == 0) { argc--; argv++; if (argc == 0) { grecs_error (&entry->locus, 0, _("expected ACL name, but found end of statement")); return 1; } - if (argv->type != GRECS_TYPE_STRING) + if (argv[0]->type != GRECS_TYPE_STRING) { grecs_error (&entry->locus, 0, _("expected string, but found list")); return 1; } - entry->acl = pies_acl_lookup (argv->v.string); + entry->acl = pies_acl_lookup (argv[0]->v.string); if (!entry->acl) { grecs_error (&entry->locus, 0, _("ACL not defined: `%s'"), - argv->v.string); + argv[0]->v.string); return 1; } argc--; argv++; } return _parse_from (entry, argc, argv); } static int -_parse_group (struct acl_entry *entry, size_t argc, grecs_value_t * argv) +_parse_group (struct acl_entry *entry, size_t argc, grecs_value_t **argv) { - if (strcmp (argv->v.string, "group") == 0) + if (strcmp (argv[0]->v.string, "group") == 0) { argc--; argv++; if (argc == 0) { grecs_error (&entry->locus, 0, _("expected group list, but found end of statement")); return 1; } - if (argv->type == GRECS_TYPE_STRING) + if (argv[0]->type == GRECS_TYPE_STRING) { - entry->groups = gl_list_create_empty(&gl_linked_list_implementation, - NULL, - NULL, - NULL, - false); - gl_list_add_last (entry->groups, (void *) argv->v.string); + entry->groups = grecs_list_create (); + grecs_list_append (entry->groups, xstrdup (argv[0]->v.string)); } else - entry->groups = argv->v.list; + entry->groups = argv[0]->v.list; argc--; argv++; } return _parse_sub_acl (entry, argc, argv); } static int -_parse_acl (struct acl_entry *entry, size_t argc, grecs_value_t *argv) +_parse_acl (struct acl_entry *entry, size_t argc, grecs_value_t **argv) { - if (assert_grecs_value_type (&entry->locus, argv, GRECS_TYPE_STRING)) + if (assert_grecs_value_type (&entry->locus, argv[0], GRECS_TYPE_STRING)) return 1; - else if (_parse_token (entry, argv) == 0) + else if (_parse_token (entry, argv[0]) == 0) return _parse_sub_acl (entry, argc - 1, argv + 1); else return _parse_group (entry, argc, argv); } int @@ -353,13 +347,13 @@ parse_acl_line (grecs_locus_t *locus, int allow, pies_acl_t acl, break; case GRECS_TYPE_LIST: grecs_error (locus, 0, _("unexpected list")); return 1; } - gl_list_add_last (acl->list, entry); + grecs_list_append (acl->list, entry); return 0; } #define ACL_TAG_NONE 0 #define ACL_TAG_IGNORE 1 #define ACL_TAG_OPTIONAL 2 @@ -370,13 +364,12 @@ _acl_common_section_parser (enum grecs_callback_command cmd, grecs_locus_t *locus, grecs_value_t *value, pies_acl_t *pacl, int flag) { pies_acl_t acl; - grecs_locus_t defn_loc; const char *tag = NULL; int has_value = 0; switch (cmd) { case grecs_callback_section_begin: @@ -409,21 +402,14 @@ _acl_common_section_parser (enum grecs_callback_command cmd, else if (flag == ACL_TAG_REQUIRED) { grecs_error (locus, 0, _("missing ACL name")); return 1; } acl = pies_acl_create (tag, locus); - if (tag && pies_acl_install (acl, &defn_loc)) - { - grecs_error (locus, 0, - _("redefinition of ACL %s"), - value->v.string); - grecs_error (&defn_loc, 0, - _("location of the previous definition")); - return 1; - } + if (tag && (acl = pies_acl_install (acl)) == NULL) + return 1; if (pacl) *pacl = acl; break; case grecs_callback_section_end: case grecs_callback_set_value: @@ -567,47 +553,45 @@ _acl_check (struct acl_entry *ent, struct acl_input *input) if (!result) return result; } if (ent->groups) { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (ent->groups); - while (result && gl_list_iterator_next (&itr, &p, NULL)) - result = match_group (input->groups, p); - gl_list_iterator_free (&itr); + struct grecs_list_entry *ep; + + for (ep = ent->groups->head; result && ep; ep = ep->next) + result = match_group (input->groups, ep->data); if (!result) return result; } result = pies_acl_check (ent->acl, input, 1); if (!result) return result; if (ent->sockaddrs) { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (ent->sockaddrs); + struct grecs_list_entry *ep; + result = 0; - while (gl_list_iterator_next (&itr, &p, NULL)) + for (ep = ent->sockaddrs->head; ep; ep = ep->next) { - result = _check_sockaddr ((struct pies_sockaddr *)p, input); + result = _check_sockaddr ((struct pies_sockaddr *)ep->data, input); if (result) break; } - gl_list_iterator_free (&itr); } return result; } static int _acl_check_cb (struct acl_entry *ent, struct acl_input *input, int *pres) { int result = _acl_check (ent, input); - debug (1, ("%s:%d: %s", ent->locus.file, ent->locus.line, + debug (1, ("%s:%d: %s", ent->locus.beg.file, ent->locus.beg.line, /* TRANSLATORS: `MATCHES' is the verb `match' in 2nd person. E.g., in French: CONCORD AVEC */ result ? _("MATCHES") : _("does not match"))); if (result) { @@ -619,67 +603,101 @@ _acl_check_cb (struct acl_entry *ent, struct acl_input *input, int *pres) int pies_acl_check (pies_acl_t acl, struct acl_input *input, int result) { if (acl) { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (acl->list); - while (gl_list_iterator_next (&itr, &p, NULL) - && !_acl_check_cb ((struct acl_entry *)p, input, &result)) - ; - gl_list_iterator_free (&itr); + struct grecs_list_entry *ep; + + for (ep = acl->list->head; ep; ep = ep->next) + if (_acl_check_cb ((struct acl_entry *)ep->data, input, &result)) + break; } return result; } /* Hash table */ -static Hash_table *acl_table; +static struct grecs_symtab *acl_table; /* Calculate the hash of a string. */ -static size_t -acl_hasher (void const *data, size_t n_buckets) +static unsigned +acl_hasher (void *data, unsigned long n_buckets) { const struct pies_acl *p = data; - return hash_string (p->name, n_buckets); + return grecs_hash_string (p->name, n_buckets); } /* Compare two strings for equality. */ -static bool +static int acl_compare (void const *data1, void const *data2) { const struct pies_acl *p1 = data1; const struct pies_acl *p2 = data2; - return strcasecmp (p1->name, p2->name) == 0; + return strcasecmp (p1->name, p2->name); } -int -pies_acl_install (pies_acl_t acl, grecs_locus_t * locus) +static int +acl_copy (void *a, void *b) +{ + const struct pies_acl *pb = b; + + memcpy (a, b, sizeof (struct pies_acl)); + memset (b, 0, sizeof (struct pies_acl)); + return 0; +} + +static void +acl_free_entry (void *p) +{ + pies_acl_free (p); +} + +pies_acl_t +pies_acl_install (pies_acl_t acl) { pies_acl_t ret; - if (!((acl_table - || (acl_table = hash_initialize (0, 0, - acl_hasher, - acl_compare, 0))) - && (ret = hash_insert (acl_table, acl)))) - xalloc_die (); - - if (ret != acl) + int install = 1; + + if (!acl_table) { - if (locus) - *locus = ret->locus; - return 1; + acl_table = grecs_symtab_create(sizeof (struct pies_acl), + acl_hasher, + acl_compare, + acl_copy, + NULL, + acl_free_entry); + if (!acl_table) + xalloc_die (); } - return 0; + + ret = grecs_symtab_lookup_or_install (acl_table, acl, &install); + + if (!ret) + { + logmsg (LOG_ERR, _("cannot install acl: %s"), strerror (errno)); + exit (1); + } + + if (!install) + { + grecs_error (&acl->locus, 0, + _("redefinition of ACL %s"), + ret->name); + grecs_error (&ret->locus, 0, + _("location of the previous definition")); + ret = NULL; + } + pies_acl_free (acl); + return ret; } pies_acl_t pies_acl_lookup (const char *name) { struct pies_acl samp; if (!acl_table) return NULL; samp.name = (char *) name; - return hash_lookup (acl_table, &samp); + return grecs_symtab_lookup_or_install (acl_table, &samp, NULL); } @@ -1,8 +1,8 @@ /* This file is part of GNU Pies - Copyright (C) 2009, 2010 Sergey Poznyakoff + Copyright (C) 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -27,13 +27,13 @@ struct acl_input pies_acl_t pies_acl_create (const char *name, grecs_locus_t *locus); int pies_acl_check (pies_acl_t acl, struct acl_input *input, int result); int parse_acl_line (grecs_locus_t *locus, int allow, pies_acl_t acl, grecs_value_t *value); pies_acl_t pies_acl_lookup (const char *name); -int pies_acl_install (pies_acl_t acl, grecs_locus_t * locus); +pies_acl_t pies_acl_install (pies_acl_t acl); int assert_grecs_value_type (grecs_locus_t *locus, const grecs_value_t *value, int type); extern struct grecs_keyword acl_keywords[]; extern int acl_section_parser (enum grecs_callback_command cmd, diff --git a/src/cmdline.opt b/src/cmdline.opt new file mode 100644 index 0000000..31fcf20 --- /dev/null +++ b/src/cmdline.opt @@ -0,0 +1,193 @@ +/* This file is part of GNU Pies. -*- c -*- + Copyright (C) 2008, 2009, 2010, 2011 Sergey Poznyakoff + + GNU 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. + + GNU 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 GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ + +OPTIONS_BEGIN("pies", + [<process invocation and execution supervisor>], + [<>], + [<gnu>], + [<copyright_year=2011>], + [<copyright_holder=Sergey Poznyakoff>]) + +GROUP(Operation Mode) + +OPTION(config-file,c,FILE, + [<use FILE instead of the default configuration>]) +BEGIN + add_config (current_syntax, optarg); +END + +OPTION(config-help,,, + [<show configuration file summary>]) +BEGIN + config_help (); + exit (0); +END + +OPTION(,E,, + [<preprocess config and exit>]) +BEGIN + preprocess_only = 1; +END + +OPTION(force,,, + [<force startup even if another instance may be running>]) +BEGIN + force_option = 1; +END + +OPTION(foreground,,, + [<remain in foreground>]) +BEGIN + log_to_stderr_only = 1; + foreground = 1; +END + +OPTION(inetd,i,, + [<run in inetd mode>]) +BEGIN + if (!instance) + instance = "inetd"; + current_syntax = CONF_INETD; + inetd_mode = 1; +END + +OPTION(instance,,NAME, + [<set instance name>]) +BEGIN + instance = optarg; +END + +OPTION(rate,,NUMBER, + [<set default maximum rate for inetd-style components>]) +BEGIN + char *p; + default_max_rate = strtoul (optarg, &p, 10); + if (*p) + { + logmsg (LOG_ERR, _("not a number: %s"), optarg); + exit (EX_USAGE); + } +END + +OPTION(stderr,,, + [<log to stderr>]) +BEGIN + log_to_stderr_only = 1; +END + +OPTION(syntax,,[<{pies|inetd|meta1}>], + [<expect configuration files in the given syntax>]) +BEGIN + if (str_to_config_syntax (optarg, ¤t_syntax)) + { + logmsg (LOG_ERR, _("unknown syntax type: %s"), optarg); + exit (EX_USAGE); + } +END + +OPTION(syslog,,, + [<log to syslog>]) +BEGIN + log_to_stderr_only = 0; +END + +OPTION(lint,t,, + [<parse configuration file and exit>]) +BEGIN + log_to_stderr_only = 1; + lint_mode = 1; +END + +GROUP(Preprocessor) + +OPTION(define,D,[<NAME[=VALUE]>], + [<define a preprocessor symbol NAME as having VALUE or empty>]) +BEGIN + add_pp_option ("-D", optarg); +END + +OPTION(undefine,U,NAME, + [<undefine a preprocessor symbol NAME>]) +BEGIN + add_pp_option ("-U", optarg); +END + +GROUP(Component Management) + +OPTION(reload,r,, + [<reload the running instance of pies>]) +ALIAS(hup) +BEGIN + log_to_stderr_only = 1; + command = COM_RELOAD; +END + +OPTION(restart-component,R,, + [<restart components named in the command line>]) +BEGIN + log_to_stderr_only = 1; + command = COM_RESTART; +END + +OPTION(status,s,, + [<display info about the running instance>]) +BEGIN + log_to_stderr_only = 1; + command = COM_STATUS; +END + +OPTION(stop,S,, + [<stop the running instance>]) +BEGIN + log_to_stderr_only = 1; + command = COM_STOP; +END + +GROUP(Debugging and Additional Diagnostics) + +OPTION(dump-depmap,,, + [<dump dependency map>]) +BEGIN + log_to_stderr_only = 1; + command = COM_DUMP_DEPMAP; +END + +OPTION(dump-prereq,,, + [<dump prerequisite charts>]) +BEGIN + log_to_stderr_only = 1; + command = COM_DUMP_PREREQ; +END + +OPTION(source-info,,, + [<show source info with debugging messages>]) +BEGIN + source_info_option = 1; +END + +OPTION(debug,x,LEVEL, + [<set debug verbosity level>]) +BEGIN + debug_level = strtoul (optarg, NULL, 0); +END + +OPTIONS_END + +void +parse_options(int argc, char *argv[], int *index) +{ + GETOPT(argc, argv, *index) +} @@ -1,8 +1,8 @@ /* This file is part of GNU Pies. - Copyright (C) 2009, 2010 Sergey Poznyakoff + Copyright (C) 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -122,21 +122,49 @@ logmsg_printf (int prio, const char *fmt, ...) va_end (ap); } void grecs_print_diag (grecs_locus_t *locus, int err, int errcode, const char *msg) { + char *locstr = NULL; + if (locus) { + size_t size = 0; + + if (locus->beg.col == 0) + grecs_asprintf (&locstr, &size, "%s:%u", + locus->beg.file, + locus->beg.line); + else if (strcmp (locus->beg.file, locus->end.file)) + grecs_asprintf (&locstr, &size, "%s:%u.%u-%s:%u.%u", + locus->beg.file, + locus->beg.line, locus->beg.col, + locus->end.file, + locus->end.line, locus->end.col); + else if (locus->beg.line != locus->end.line) + grecs_asprintf (&locstr, &size, "%s:%u.%u-%u.%u", + locus->beg.file, + locus->beg.line, locus->beg.col, + locus->end.line, locus->end.col); + else + grecs_asprintf (&locstr, &size, "%s:%u.%u-%u", + locus->beg.file, + locus->beg.line, locus->beg.col, + locus->end.col); + } + + if (locstr) + { if (errcode) - logmsg (err ? LOG_ERR : LOG_WARNING, "%s:%lu: %s: %s", - locus->file, (unsigned long)locus->line, msg, - strerror (errcode)); + logmsg (err ? LOG_ERR : LOG_WARNING, "%s: %s: %s", + locstr, msg, strerror (errcode)); else - logmsg (err ? LOG_ERR : LOG_WARNING, "%s:%lu: %s", - locus->file, (unsigned long)locus->line, msg); + logmsg (err ? LOG_ERR : LOG_WARNING, "%s: %s", + locstr, msg); + free (locstr); } else { if (errcode) logmsg (err ? LOG_ERR : LOG_WARNING, "%s: %s", msg, strerror (errcode)); diff --git a/src/inetd.c b/src/inetd.c index 012266a..1d7798d 100644 --- a/src/inetd.c +++ b/src/inetd.c @@ -1,8 +1,8 @@ /* This file is part of GNU Pies. - Copyright (C) 2009, 2010 Sergey Poznyakoff + Copyright (C) 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -25,17 +25,17 @@ #define IFLD_USER 4 /* user */ #define IFLD_SERVER_PATH 5 /* server program path */ #define IFLD_SERVER_ARGS 6 /* server program arguments */ #define IFLD_MIN_COUNT 6 /* Minimum number of fields in entry */ -/* FIXME: Duplicated in grex-lex.l */ +/* FIXME: Copied from grecs/src/tree.c */ static void -listel_dispose(const void *el) +listel_dispose(void *el) { - free((void*)el); + free(el); } #define TCPMUX_PREFIX_STR "tcpmux/" #define TCPMUX_PREFIX_LEN (sizeof(TCPMUX_PREFIX_STR)-1) static int @@ -278,19 +278,15 @@ inetd_conf_file (const char *file) if (ISCF_TCPMUX (comp->flags)) comp->tcpmux = mktag (address, "tcpmux"); comp->service = xstrdup (service); comp->privs.user = xstrdup (user); /* FIXME: memory leak */ if (group) { - comp->privs.groups = - gl_list_create_empty (&gl_linked_list_implementation, - NULL, - NULL, - listel_dispose, - true); - gl_list_add_last (comp->privs.groups, xstrdup (group)); + comp->privs.groups = grecs_list_create (); + comp->privs.groups->free_entry = listel_dispose; + grecs_list_append (comp->privs.groups, xstrdup (group)); } comp->program = xstrdup (ws.ws_wordv[IFLD_SERVER_PATH]); if (ws.ws_wordc > IFLD_MIN_COUNT) { diff --git a/src/meta1gram.y b/src/meta1gram.y index 6256448..deaf382 100644 --- a/src/meta1gram.y +++ b/src/meta1gram.y @@ -1,9 +1,9 @@ %{ /* MeTA1 configuration parser for GNU Pies. - Copyright (C) 2008, 2009, 2010 Sergey Poznyakoff + Copyright (C) 2008, 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -17,14 +17,16 @@ /* This file implements a grammar for parsing MeTA1 main configuration file, and a set of functions for converting its statements into Pies configuration statements. */ #include "pies.h" +#include "grecs-locus.h" #include "meta1lex.h" - +#include "meta1gram.h" + #define META1_QUEUE_DIR() \ (meta1_queue_dir ? meta1_queue_dir : "/var/spool/meta1") enum meta1_stmt_type { meta1_simple, @@ -48,13 +50,13 @@ struct meta1_stmt * meta1_stmt_create (enum meta1_stmt_type type, const char *ident) { struct meta1_stmt *p = xmalloc (sizeof (*p)); p->next = NULL; p->type = type; p->ident = ident; - p->locus = meta1_locus; + p->locus = meta1lloc; return p; } static struct meta1_stmt * _reverse (struct meta1_stmt *list, struct meta1_stmt **root) { @@ -81,15 +83,18 @@ reverse (struct meta1_stmt *in) return root; } static void meta1_translate (struct meta1_stmt *); %} +%error-verbose +%locations + %union { char *string; - gl_list_t list; + struct grecs_list *list; grecs_value_t *value; struct meta1_stmt *stmt; } %token <string> META1_IDENT META1_STRING META1_NUMBER %type <list> slist values list @@ -165,35 +170,31 @@ value : string } ; string : META1_IDENT | slist { - const void *p; - gl_list_iterator_t itr = gl_list_iterator ($1); - + struct grecs_list_entry *ep; meta1_line_begin (); - while (gl_list_iterator_next (&itr, &p, NULL)) - meta1_line_add (p, strlen (p)); - gl_list_iterator_free (&itr); + for (ep = $1->head; ep; ep = ep->next) + { + const char *p = ep->data; + meta1_line_add (p, strlen (p)); + } $$ = meta1_line_finish (); } ; slist : META1_STRING { - $$ = gl_list_create_empty (&gl_linked_list_implementation, - NULL, - NULL, - NULL, - true); - gl_list_add_last ($$, $1); + $$ = grecs_list_create (); + grecs_list_append ($$, $1); } | slist META1_STRING { - gl_list_add_last ($1, $2); + grecs_list_append ($1, $2); $$ = $1; } ; list : '{' values '}' { @@ -204,35 +205,31 @@ list : '{' values '}' $$ = $2; } ; values : value { - $$ = gl_list_create_empty (&gl_linked_list_implementation, - NULL, - NULL, - NULL, - true); - gl_list_add_last ($$, $1); + $$ = grecs_list_create (); + grecs_list_append ($$, $1); } | values ',' value { - gl_list_add_last ($1, $3); + grecs_list_append ($1, $3); $$ = $1; } ; opt_sc : /* empty */ | ';' ; %% int yyerror (char *s) { - meta1_parse_error ("%s", s); + grecs_error (&yylloc, 0, "%s", s); return 0; } void meta1_parser_set_debug () { diff --git a/src/meta1lex.h b/src/meta1lex.h index 0f7c75d..213fb40 100644 --- a/src/meta1lex.h +++ b/src/meta1lex.h @@ -1,8 +1,8 @@ /* This file is part of GNU Pies. - Copyright (C) 2009, 2010, 2009 Sergey Poznyakoff + Copyright (C) 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -11,13 +11,12 @@ 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 GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ -extern grecs_locus_t meta1_locus; extern size_t meta1_error_count; extern char *meta1_queue_dir; char *meta1_string (const char *str, size_t len); void meta1_line_add (const char *text, size_t len); void meta1_line_add_unescape_last (const char *text, size_t len); diff --git a/src/meta1lex.l b/src/meta1lex.l index 4eca9e2..7faaf41 100644 --- a/src/meta1lex.l +++ b/src/meta1lex.l @@ -1,10 +1,10 @@ /* MeTA1 configuration lexer for GNU Pies. -*- c -*- */ %top { /* MeTA1 configuration lexer for GNU Pies. - Copyright (C) 2008, 2009, 2010 Sergey Poznyakoff + Copyright (C) 2008, 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -23,35 +23,46 @@ # include <config.h> #endif } %{ #include "pies.h" +#include "grecs-locus.h" #include "meta1gram.h" #include "meta1lex.h" -grecs_locus_t meta1_locus; -size_t meta1_error_count; +static struct grecs_locus_point meta1_locus_point; struct obstack meta1_stk; int meta1_stk_init; char *meta1_queue_dir; - #define yylval meta1lval + +#define YY_USER_ACTION do \ + { \ + if (YYSTATE == 0) \ + { \ + meta1lloc.beg = meta1_locus_point; \ + meta1lloc.beg.col++; \ + } \ + meta1_locus_point.col += yyleng; \ + meta1lloc.end = meta1_locus_point; \ + } \ + while (0); %} %x COMMENT STR X [0-9a-fA-F] %% /* C-style comments */ "/*" BEGIN (COMMENT); <COMMENT>[^*\n]* /* eat anything that's not a '*' */ <COMMENT>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ -<COMMENT>\n ++meta1_locus.line; +<COMMENT>\n grecs_locus_point_advance_line(meta1_locus_point); <COMMENT>"*"+"/" BEGIN (INITIAL); /* End-of-line comments */ -#.*\n { meta1_locus.line++; } +#.*\n grecs_locus_point_advance_line(meta1_locus_point); #.* /* end-of-file comment */; /* Number */ 0[xX]{X}+ | 0[0-7]+ | [1-9][0-9]+ { meta1_line_begin (); meta1_line_add (yytext, yyleng); @@ -79,24 +90,24 @@ X [0-9a-fA-F] <STR>[^\\"\n]*\" { BEGIN (INITIAL); if (yyleng > 1) meta1_line_add (yytext, yyleng - 1); yylval.string = meta1_line_finish (); return META1_STRING; } <STR>[^\\"\n]*\n { BEGIN (INITIAL); - meta1_parse_error (_("newline in a string")); + grecs_error (&meta1lloc, 0, _("newline in a string")); meta1_line_add (yytext, yyleng - 1); yylval.string = meta1_line_finish (); return META1_STRING; } /* Other tokens */ [ \t\f][ \t\f]* ; -\n { meta1_locus.line++; } +\n grecs_locus_point_advance_line(meta1_locus_point); [,;{}=] return yytext[0]; . { if (isascii (yytext[0]) && isprint (yytext[0])) - meta1_parse_error (_("stray character %c"), yytext[0]); + grecs_error (&meta1lloc, 0, _("stray character %c"), yytext[0]); else - meta1_parse_error (_("stray character \\%03o"), + grecs_error (&meta1lloc, 0, _("stray character \\%03o"), (unsigned char) yytext[0]); } %% int yywrap () { @@ -132,13 +143,13 @@ unescape_to_line (int c) if (c == 'v') t = '\v'; else { t = unescape_char (c); if (t == c && t != '\\' && t != '\"') - meta1_parse_error (_("unknown escape sequence '\\%c'"), c); + grecs_error (&meta1lloc, 0, _("unknown escape sequence '\\%c'"), c); } obstack_1grow (&meta1_stk, t); } void meta1_line_add_unescape_last (const char *text, size_t len) @@ -179,26 +190,12 @@ meta1_string (const char *str, size_t len) meta1_line_begin (); meta1_line_add (str, len); return meta1_line_finish (); } void -meta1_parse_error (const char *fmt, ...) -{ - va_list ap; - - logmsg_printf (LOG_ERR, "%s:%lu: ", meta1_locus.file, - (unsigned long) meta1_locus.line); - va_start (ap, fmt); - logmsg_vprintf (LOG_ERR, fmt, ap); - va_end (ap); - logmsg_printf (LOG_ERR, "\n"); - meta1_error_count++; -} - -void meta1_lexer_set_debug () { char *p = getenv ("META1_DEBUG_LEX"); yy_flex_debug = p && (*p - '0') > 0; } @@ -214,21 +211,23 @@ meta1_config_parse (const char *name) if (!fp) { logmsg (LOG_ERR, _("%s: cannot open file: %s"), name, strerror (errno)); return 1; } - meta1_locus.file = meta1_string (name, strlen (name)); - meta1_locus.line = 1; + meta1_locus_point.file = meta1_string (name, strlen (name)); + meta1_locus_point.line = 1; + meta1_locus_point.col = 0; meta1_lexer_set_debug (); meta1_parser_set_debug (); yyrestart (fp); + grecs_error_count = 0; rc = meta1parse (); fclose (fp); - if (meta1_error_count) + if (grecs_error_count) rc = 1; return rc; } @@ -1,8 +1,8 @@ /* This file is part of GNU Pies. - Copyright (C) 2008, 2009, 2010 Sergey Poznyakoff + Copyright (C) 2008, 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -23,13 +23,24 @@ int preprocess_only; /* Preprocess config, do nothing more */ int lint_mode; /* Test configuration syntax and exit */ int log_to_stderr_only; /* Use only stderr for logging */ int log_facility = LOG_USER; char *log_tag; struct pies_privs pies_privs; int foreground; -int command; + +enum pies_command { + COM_START, + COM_RESTART, + COM_RELOAD, + COM_STATUS, + COM_STOP, + COM_DUMP_PREREQ, + COM_DUMP_DEPMAP +}; + +enum pies_command command; char *statedir = DEFAULT_STATE_DIR; char *instance; char *pidfile; char *ctlfile; char *statfile; char *qotdfile; @@ -142,20 +153,17 @@ stderr_closed_p () return 1; close (fd); return fd <= 2; } -#define GRECS_VALUE_IS_EMPTY(val) \ - (!(val) || ((val)->type == GRECS_TYPE_STRING && !(val)->v.string)) - int assert_grecs_value_type (grecs_locus_t *locus, const grecs_value_t *value, int type) { - if (GRECS_VALUE_IS_EMPTY (value)) + if (GRECS_VALUE_EMPTY_P (value)) { grecs_error (locus, 0, _("expected %s"), grecs_data_type_string (type)); return 1; } if (value->type != type) @@ -409,23 +417,23 @@ _get_string_arg (grecs_value_t *val, int num, grecs_locus_t *locus) const char * _get_array_arg (grecs_value_t *val, int num, grecs_locus_t *locus) { if (num < val->v.arg.c) { - if (assert_grecs_value_type (locus, &val->v.arg.v[num], + if (assert_grecs_value_type (locus, val->v.arg.v[num], GRECS_TYPE_STRING) == 0) - return val->v.arg.v[num].v.string; + return val->v.arg.v[num]->v.string; } return NULL; } const char * _get_list_arg (grecs_value_t *val, int num, grecs_locus_t *locus) { - grecs_value_t *elt = (grecs_value_t *) gl_list_get_at (val->v.list, num); + grecs_value_t *elt = (grecs_value_t *) grecs_list_index (val->v.list, num); if (!elt) { grecs_error (locus, 0, _("cannot get list item")); } else if (assert_grecs_value_type (locus, elt, GRECS_TYPE_STRING) == 0) return elt->v.string; @@ -442,13 +450,13 @@ return_code_section_parser (enum grecs_callback_command cmd, size_t count; struct action *act; switch (cmd) { case grecs_callback_section_begin: - if (GRECS_VALUE_IS_EMPTY (value)) + if (GRECS_VALUE_EMPTY_P (value)) { grecs_error (locus, 0, _("missing tag")); return 1; } switch (value->type) @@ -460,13 +468,13 @@ return_code_section_parser (enum grecs_callback_command cmd, case GRECS_TYPE_ARRAY: act = create_action (comp, locus, value, value->v.arg.c, _get_array_arg); break; case GRECS_TYPE_LIST: - count = gl_list_size (value->v.list); + count = grecs_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)); @@ -494,15 +502,15 @@ config_array_to_argv (grecs_value_t *val, grecs_locus_t *locus, size_t *pargc) char **argv; 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) + 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++] = xstrdup (val->v.arg.v[i]->v.string); } argv[j] = NULL; if (pargc) *pargc = argc; return argv; } @@ -699,49 +707,49 @@ _cb_redir (enum grecs_callback_command cmd, value->v.string); return 0; } break; case GRECS_TYPE_ARRAY: - if (assert_grecs_value_type (locus, &value->v.arg.v[0], + if (assert_grecs_value_type (locus, value->v.arg.v[0], GRECS_TYPE_STRING)) return 0; - if (strtotok (redirtab, value->v.arg.v[0].v.string, &res)) + 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); + value->v.arg.v[0]->v.string); else { if (res != redir_null) { if (value->v.arg.c != 2) { grecs_error (locus, 0, _("wrong number of arguments")); return 0; } - if (assert_grecs_value_type (locus, &value->v.arg.v[1], + if (assert_grecs_value_type (locus, value->v.arg.v[1], GRECS_TYPE_STRING)) return 0; switch (res) { case redir_null: break; case redir_syslog: - if (string_to_syslog_priority (value->v.arg.v[1].v.string, + if (string_to_syslog_priority (value->v.arg.v[1]->v.string, &rp->v.prio)) { grecs_error (locus, 0, _("unknown syslog priority `%s'"), - value->v.arg.v[1].v.string); + value->v.arg.v[1]->v.string); return 0; } break; case redir_file: - rp->v.file = xstrdup (value->v.arg.v[1].v.string); + rp->v.file = xstrdup (value->v.arg.v[1]->v.string); break; } } rp->type = res; } break; @@ -907,18 +915,17 @@ _cb_flags (enum grecs_callback_command cmd, return 1; } break; case GRECS_TYPE_LIST: { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (value->v.list); - - while (gl_list_iterator_next (&itr, &p, NULL)) + struct grecs_list_entry *ep; + + for (ep = value->v.list->head; ep; ep = ep->next) { - const grecs_value_t *vp = p; + const grecs_value_t *vp = ep->data; if (assert_grecs_value_type (locus, vp, GRECS_TYPE_STRING)) return 1; if (str_to_cf (vp->v.string, flags)) { grecs_error (locus, 0, _("%s: unrecognised flag"), vp->v.string); @@ -1557,13 +1564,12 @@ struct grecs_keyword pies_keywords[] = { {NULL} }; void config_init () { - grecs_set_keywords (pies_keywords); grecs_include_path_setup (DEFAULT_VERSION_INCLUDE_DIR, DEFAULT_INCLUDE_DIR, NULL); grecs_log_to_stderr = log_to_stderr_only; if (DEFAULT_PREPROCESSOR) { obstack_init (&pp_stk); @@ -1576,225 +1582,20 @@ void config_help () { static char docstring[] = /* TRANSLATORS: do not translate words between ` and ' */ 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_keywords, 1, 0); + grecs_print_docstring (docstring, 0, stdout); + grecs_print_statement_array (pies_keywords, 1, 0, stdout); } - -const char *program_version = "pies (" PACKAGE_STRING ")"; -const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">"; -static char doc[] = N_("pies -- process invocation and execution supervisor"); -static char args_doc[] = ""; - -enum -{ - OPT_FOREGROUND = 256, - OPT_SYNTAX, - OPT_SYSLOG, - OPT_STDERR, - OPT_DUMP_PREREQ, - OPT_DUMP_DEPMAP, - OPT_FORCE, - OPT_CONFIG_HELP, - OPT_SOURCE_INFO, - OPT_RATE, - OPT_INSTANCE -}; - -#define OPT_RESTART 'R' -#define OPT_RELOAD 'r' -#define OPT_STATUS 's' -#define OPT_STOP 'S' - -static struct argp_option options[] = { -#define GRP 0 - {NULL, 0, NULL, 0, N_("Operation Mode"), GRP}, - {"foreground", OPT_FOREGROUND, 0, 0, N_("remain in foreground"), GRP + 1}, - {"stderr", OPT_STDERR, NULL, 0, N_("log to stderr"),}, - {"syslog", OPT_SYSLOG, NULL, 0, N_("log to syslog"),}, - {"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}, - {"inetd", 'i', NULL, 0, - N_("run in inetd mode"), 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}, - {"syntax", OPT_SYNTAX, "{pies|inetd|meta1}", 0, - N_("expect configuration files in the given syntax"), GRP+1 }, - {"rate", OPT_RATE, N_("NUMBER"), 0, - N_("set default maximum rate for inetd-style components"), - GRP + 1}, - {"instance", OPT_INSTANCE, N_("NAME"), 0, - N_("set instance name"), - GRP + 1}, -#undef GRP - -#define GRP 5 - {NULL, 0, NULL, 0, N_("Preprocessor"), GRP}, - {"define", 'D', N_("NAME[=VALUE]"), 0, - N_("define a preprocessor symbol NAME as having VALUE, or empty"), GRP+1 }, - {"undefine", 'U', N_("NAME"), 0, - N_("undefine a preprocessor symbol NAME"), GRP+1 }, -#undef GRP - -#define GRP 10 - {NULL, 0, NULL, 0, N_("Component Management"), GRP}, - {"restart-component", OPT_RESTART, NULL, 0, - N_("restart components named in the command line"), GRP + 1}, - {"reload", OPT_RELOAD, NULL, 0, - N_("reload the running instance of pies "), GRP + 1}, - {"hup", 0, NULL, OPTION_ALIAS}, - {"status", OPT_STATUS, NULL, 0, - N_("display info about the running instance "), GRP + 1}, - {"stop", OPT_STOP, NULL, 0, - N_("stop the running instance "), GRP + 1}, -#undef GRP - -#define GRP 20 - {NULL, 0, NULL, 0, N_("Debugging and Additional Diagnostics"), GRP}, - {"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}, - {"dump-prereq", OPT_DUMP_PREREQ, NULL, 0, - N_("dump prerequisite charts"), GRP + 1}, - {"dump-depmap", OPT_DUMP_DEPMAP, NULL, 0, - N_("dump dependency map"), GRP + 1}, -#undef GRP - {NULL} -}; - static enum config_syntax current_syntax = CONF_PIES; -static error_t -parse_opt (int key, char *arg, struct argp_state *state) -{ - char *p; - - switch (key) - { - case 'c': - add_config (current_syntax, arg); - break; - - case 'D': - add_pp_option ("-D", arg); - break; - - case 'U': - add_pp_option ("-U", arg); - break; - - case 'E': - preprocess_only = 1; - break; - - case 'i': - if (!instance) - instance = "inetd"; - current_syntax = CONF_INETD; - inetd_mode = 1; - break; - - case 't': - log_to_stderr_only = 1; - lint_mode = 1; - break; - - case OPT_CONFIG_HELP: - config_help (); - exit (0); - - case OPT_FOREGROUND: - log_to_stderr_only = 1; - foreground = 1; - break; - - case OPT_INSTANCE: - instance = arg; - break; - - case OPT_SYNTAX: - if (str_to_config_syntax (arg, ¤t_syntax)) - { - logmsg (LOG_ERR, _("unknown syntax type: %s"), arg); - exit (EX_USAGE); - } - break; - - case OPT_RELOAD: - case OPT_STATUS: - case OPT_STOP: - case OPT_RESTART: - case OPT_DUMP_PREREQ: - case OPT_DUMP_DEPMAP: - log_to_stderr_only = 1; - command = key; - break; - - case OPT_SYSLOG: - log_to_stderr_only = 0; - break; - - case OPT_STDERR: - log_to_stderr_only = 1; - break; - - case 'x': - debug_level = strtoul (arg, NULL, 0); - break; - - case OPT_RATE: - default_max_rate = strtoul (arg, &p, 10); - if (*p) - { - logmsg (LOG_ERR, _("not a number: %s"), arg); - exit (EX_USAGE); - } - break; - - case OPT_SOURCE_INFO: - source_info_option = 1; - break; - - case OPT_FORCE: - force_option = 1; - break; - - case ARGP_KEY_INIT: - break; - - case ARGP_KEY_FINI: - break; - - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static struct argp argp = { - options, - parse_opt, - args_doc, - doc, - NULL, - NULL, - NULL -}; +#include "cmdline.h" - #define ACTION_CONT 0 #define ACTION_STOP 1 #define ACTION_RESTART 2 #define ACTION_COMPRELOAD 3 #define ACTION_DUMPSTATS 4 @@ -2153,40 +1954,12 @@ set_mailer_argcv () mailer_argv[i] = xstrdup (ws.ws_wordv[i]); mailer_argv[i] = NULL; wordsplit_free (&ws); } -const char version_etc_copyright[] = - /* Do *not* mark this string for translation. %s is a copyright - symbol suitable for this locale */ - "Copyright %s 2009 Sergey Poznyakoff"; - - -static void -version (FILE *stream, struct argp_state *state) -{ - fprintf (stream, "%s (%s) %s\n", PACKAGE, PACKAGE_NAME, PACKAGE_VERSION); - /* TRANSLATORS: Translate "(C)" to the copyright symbol - (C-in-a-circle), if this symbol is available in the user's - locale. Otherwise, do not translate "(C)"; leave it as-is. */ - fprintf (stream, version_etc_copyright, _("(C)")); - - fputs (_("\ -\n\ -License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\ -This is free software: you are free to change and redistribute it.\n\ -There is NO WARRANTY, to the extent permitted by law.\n\ -\n\ -"), - stream); - - /* TRANSLATORS: %s denotes an author name. */ - fprintf (stream, _("Written by %s.\n"), "Sergey Poznyakoff"); -} - static char * mkfilename (const char *dir, const char *name, const char *suf) { size_t dirlen = strlen (dir); char *s; @@ -2245,16 +2018,14 @@ main (int argc, char **argv) set_quoting_style (NULL, shell_quoting_style); /* Set default logging */ diag_setup (DIAG_TO_SYSLOG | (stderr_closed_p () ? 0 : DIAG_TO_STDERR)); config_init (); - argp_program_version_hook = version; - if (argp_parse (&argp, argc, argv, 0, &index, NULL)) - exit (EX_USAGE); - + parse_options (argc, argv, &index); + if (!instance) { instance = strrchr (program_name, '/'); if (!instance) instance = (char*) program_name; else @@ -2286,16 +2057,20 @@ main (int argc, char **argv) else for (file = conf_head; file; file = file->next) { switch (file->syntax) { case CONF_PIES: - if (grecs_parse (file->name)) - exit (EX_CONFIG); - break; - + { + struct grecs_node *tree = grecs_parse (file->name); + if (!tree || grecs_tree_process (tree, pies_keywords)) + exit (EX_CONFIG); + grecs_tree_free (tree); + break; + } + case CONF_INETD: if (inetd_parse_conf (file->name)) exit (EX_CONFIG); break; case CONF_META1: @@ -2314,41 +2089,41 @@ main (int argc, char **argv) exit (0); } /* Re-setup logging: it might have been reset in the config file */ diag_setup (log_to_stderr_only ? DIAG_TO_STDERR : 0); - if (argc != index && command != 'R') + if (argc != index && command != COM_RESTART) { logmsg (LOG_ERR, "extra command line arguments"); exit (EX_CONFIG); } progman_build_depmap (); switch (command) { - case OPT_RESTART: + case COM_RESTART: pies_priv_setup (&pies_privs); if (pies_umask) umask (pies_umask); exit (request_restart_components (argv + index)); - case OPT_RELOAD: + case COM_RELOAD: exit (pies_reload ()); - case OPT_STATUS: + case COM_STATUS: exit (pies_status ()); - case OPT_STOP: + case COM_STOP: exit (pies_stop ()); - case OPT_DUMP_PREREQ: + case COM_DUMP_PREREQ: progman_dump_prereq (); exit (0); - case OPT_DUMP_DEPMAP: + case COM_DUMP_DEPMAP: progman_dump_depmap (); exit (0); default: pies_priv_setup (&pies_privs); if (pies_umask) @@ -1,8 +1,8 @@ /* This file is part of GNU Pies. - Copyright (C) 2008, 2009, 2010 Sergey Poznyakoff + Copyright (C) 2008, 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -39,13 +39,13 @@ #include <string.h> #include <pwd.h> #include <grp.h> #include <signal.h> #include <time.h> #include <sysexits.h> -#include <argp.h> +#include <ctype.h> #include <grecs.h> #include <wordsplit.h> #include "progname.h" #include "inttostr.h" @@ -114,13 +114,13 @@ struct action /* user privs */ struct pies_privs { char *user; int allgroups; - gl_list_t groups; + struct grecs_list *groups; }; enum pies_comp_mode { /* Execute the component, no sockets are opened. This is the default Pies mode. */ @@ -163,14 +163,14 @@ struct component char *tag; /* Entry tag (for diagnostics purposes) */ char *program; /* Program name */ size_t argc; /* Number of command line arguments */ char **argv; /* Program command line */ char **env; /* Program environment */ char *dir; /* Working directory */ - gl_list_t prereq; /* Prerequisites */ - gl_list_t depend; /* Dependency targets */ + struct grecs_list *prereq; /* Prerequisites */ + struct grecs_list *depend; /* Dependency targets */ int flags; /* CF_ bitmask */ size_t max_instances; /* Maximum number of simultaneously running instances */ char *rmfile; /* Try to remove this file before starting */ struct pies_privs privs; /* UID/GIDS+groups to run under */ mode_t umask; /* Umask to install before starting */ @@ -372,13 +372,13 @@ 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); +int switch_to_privs (uid_t uid, gid_t gid, struct grecs_list *retain_groups); void pies_priv_setup (struct pies_privs *); void pies_epriv_setup (struct pies_privs *); /* inetd.c */ int inetd_parse_conf (const char *file); diff --git a/src/progman.c b/src/progman.c index 4420a21..d24ea1a 100644 --- a/src/progman.c +++ b/src/progman.c @@ -1,8 +1,8 @@ /* This file is part of GNU Pies. - Copyright (C) 2007, 2008, 2009, 2010 Sergey Poznyakoff + Copyright (C) 2007, 2008, 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -12,13 +12,12 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ #include "pies.h" -#include <hash.h> enum prog_type { TYPE_COMPONENT, TYPE_REDIRECTOR, TYPE_COMMAND @@ -86,13 +85,13 @@ struct prog #define IS_COMPONENT(p) ((p)->type == TYPE_COMPONENT) static size_t numcomp; static struct prog *proghead, *progtail; static pies_depmap_t depmap; static int recompute_alarm; -static Hash_table *conn_tab; +static struct grecs_symtab *conn_tab; void progman_iterate_comp (int (*fun) (struct component *, void *), void *data) { struct prog *prog; @@ -354,26 +353,26 @@ prog_rebuild_prerequisites (struct prog *prog) struct prog *p; int dep_all = 0; size_t depc = 0; if (comp->prereq) { - depc = gl_list_size (comp->prereq); + depc = grecs_list_size (comp->prereq); if (depc == 1) { - const char *item = gl_list_get_at (comp->prereq, 0); + const char *item = grecs_list_index (comp->prereq, 0); if (strcmp (item, "all") == 0) { dep_all = 1; for (p = proghead; p; p = p->next) if (p->type == TYPE_COMPONENT) depc++; } else if (strcmp (item, "none") == 0) { - gl_list_free (comp->prereq); + grecs_list_free (comp->prereq); comp->prereq = NULL; } } } if (depc == 0) @@ -389,19 +388,16 @@ prog_rebuild_prerequisites (struct prog *prog) for (p = proghead; p; p = p->next) if (p->type == TYPE_COMPONENT) prog->prereq[depc++] = p->tag; } else { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (comp->prereq); - while (gl_list_iterator_next (&itr, &p, NULL)) - { - prog->prereq[depc++] = (char*) p; - } - gl_list_iterator_free (&itr); + struct grecs_list_entry *ep; + + for (ep = comp->prereq->head; ep; ep = ep->next) + prog->prereq[depc++] = (char*) ep->data; } } prog->prereq[depc] = NULL; } size_t @@ -518,16 +514,16 @@ open_redirector (struct prog *master, int stream) close (p[0]); return p[1]; } } -static size_t -conn_class_hasher (void const *data, size_t n_buckets) +static unsigned +conn_class_hasher (void *data, unsigned long n_buckets) { - struct conn_class const *pcclass = data; + struct conn_class *pcclass = data; unsigned char const *tag = (unsigned char const *)pcclass->tag; size_t value = 0; unsigned char ch; size_t len; while ((ch = *tag++)) @@ -539,34 +535,43 @@ conn_class_hasher (void const *data, size_t n_buckets) tag++, len--) value = (value * 31 + *tag) % n_buckets; return value; } /* Compare two strings for equality. */ -static bool +static int conn_class_compare (void const *data1, void const *data2) { struct conn_class const *p1 = data1; struct conn_class const *p2 = data2; - return p1->sa_len == p2->sa_len && - memcmp (&p1->sa_storage, &p2->sa_storage, p1->sa_len) == 0 && - strcmp (p1->tag, p2->tag) == 0; + return !(p1->sa_len == p2->sa_len && + memcmp (&p1->sa_storage, &p2->sa_storage, p1->sa_len) == 0 && + strcmp (p1->tag, p2->tag) == 0); } static void conn_class_free (void *data) { free (data); } +static int +conn_class_copy(void *a, void *b) +{ + memcpy(a, b, sizeof(struct conn_class)); + memset(a, 0, sizeof(struct conn_class)); + return 0; +} + static struct conn_class * conn_class_lookup (const char *tag, union pies_sockaddr_storage const *sa_storage_ptr, size_t sa_len) { + int install = 1; struct conn_class *probe, *ret; probe = xmalloc (sizeof (probe[0])); probe->tag = tag; probe->sa_storage = *sa_storage_ptr; probe->sa_len = sa_len; @@ -583,23 +588,26 @@ conn_class_lookup (const char *tag, logmsg (LOG_ERR, _("unexpected socket family: %d"), probe->sa_storage.s.sa_family); break; } probe->count = 0; + if (!conn_tab) + { + conn_tab = grecs_symtab_create(sizeof (struct conn_class), + conn_class_hasher, + conn_class_compare, + conn_class_copy, + NULL, + conn_class_free); + if (!conn_tab) + xalloc_die (); + } - if (!((conn_tab - || (conn_tab = hash_initialize (0, 0, - conn_class_hasher, - conn_class_compare, - conn_class_free))) - && (ret = hash_insert (conn_tab, probe)))) - xalloc_die (); - - if (probe != ret) - free (probe); + ret = grecs_symtab_lookup_or_install (conn_tab, probe, &install); + free (probe); return ret; } static void conn_class_report (struct conn_class *pcclass) { @@ -1408,22 +1416,20 @@ progman_accept (int socket) } void component_fixup_depend (struct component *comp) { - const void *p; - gl_list_iterator_t itr; + struct grecs_list_entry *ep; if (comp->depend == NULL) return; - itr = gl_list_iterator (comp->depend); - while (gl_list_iterator_next (&itr, &p, NULL)) + for (ep = comp->depend->head; ep; ep = ep->next) { - const char *tag = p; + const char *tag = ep->data; struct component *tgt; tgt = progman_lookup_component (tag); if (!tgt) { logmsg (LOG_ERR, @@ -1431,22 +1437,18 @@ component_fixup_depend (struct component *comp) "which is not declared"), comp->tag, tag); continue; } if (!tgt->prereq) { - tgt->prereq = gl_list_create_empty(&gl_linked_list_implementation, - NULL, - NULL, - NULL, - false); + tgt->prereq = grecs_list_create(); } /* FIXME: memory allocation */ - gl_list_add_last (tgt->prereq, xstrdup (comp->tag)); + grecs_list_append (tgt->prereq, xstrdup (comp->tag)); } - gl_list_free (comp->depend); + grecs_list_free (comp->depend); comp->depend = NULL; } void fixup_prerequisites () { diff --git a/src/userprivs.c b/src/userprivs.c index b224a00..3270905 100644 --- a/src/userprivs.c +++ b/src/userprivs.c @@ -1,8 +1,8 @@ /* This file is part of GNU Pies. - Copyright (C) 2007, 2008, 2009, 2010 Sergey Poznyakoff + Copyright (C) 2007, 2008, 2009, 2010, 2011 Sergey Poznyakoff GNU 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. @@ -35,84 +35,75 @@ str_eq (const void *elt1, const void *elt2) void str_dispose (const void *elt) { free ((void*)elt); } -gl_list_t -get_user_groups (gl_list_t init_list, const char *user) +struct grecs_list * +get_user_groups (struct grecs_list *init_list, const char *user) { int rc; struct group *gr; - gl_list_t list; + struct grecs_list *list; - list = gl_list_create_empty(&gl_linked_list_implementation, - str_eq, - NULL, - str_dispose, - false); + list = grecs_list_create(); if (init_list) { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (init_list); - while (gl_list_iterator_next (&itr, &p, NULL)) + struct grecs_list_entry *ep; + + for (ep = init_list->head; ep; ep = ep->next) { - char *s = xstrdup (p); - if (!gl_list_add_last (list, s)) - free (s); + grecs_list_append (list, xstrdup ((char*)ep->data)); } - gl_list_iterator_free (&itr); } setgrent (); for (rc = 0; rc == 0 && (gr = getgrent ());) { char **p; for (p = gr->gr_mem; *p; p++) if (strcmp (*p, user) == 0) { - char *s = xstrdup (gr->gr_name); - if (!gl_list_add_last (list, s)) - free (s); + grecs_list_append (list, xstrdup (gr->gr_name)); break; } } endgrent (); return list; } /* Switch to the given UID/GID */ int -switch_to_privs (uid_t uid, gid_t gid, gl_list_t retain_groups) +switch_to_privs (uid_t uid, gid_t gid, struct grecs_list *retain_groups) { int rc = 0; gid_t *emptygidset; size_t size = 1, j = 1; /* Create a list of supplementary groups */ - size = 1 + (retain_groups ? gl_list_size (retain_groups) : 0); + size = 1 + (retain_groups ? grecs_list_size (retain_groups) : 0); emptygidset = xcalloc (size, sizeof emptygidset[0]); emptygidset[0] = gid ? gid : getegid (); if (retain_groups) { - const void *p; - gl_list_iterator_t itr = gl_list_iterator (retain_groups); - while (gl_list_iterator_next (&itr, &p, NULL)) + struct grecs_list_entry *ep; + + for (ep = retain_groups->head; ep; ep = ep->next) { - struct group *group = getgrnam ((const char*)p); + const char *grname = ep->data; + struct group *group = getgrnam (grname); if (!group) { - logmsg (LOG_ERR, _("unknown group: %s"), (const char*)p); + logmsg (LOG_ERR, _("unknown group: %s"), grname); free (emptygidset); return 1; } emptygidset[j++] = group->gr_gid; } - gl_list_iterator_free (&itr); } /* Reset group permissions */ if (geteuid () == 0 && setgroups (j, emptygidset)) { logmsg (LOG_ERR, _("setgroups(1, %lu) failed: %s"), @@ -206,13 +197,13 @@ switch_to_privs (uid_t uid, gid_t gid, gl_list_t retain_groups) void pies_priv_setup (struct pies_privs *privs) { struct passwd *pw; - gl_list_t grplist = 0; + struct grecs_list *grplist = 0; if (!privs || !privs->user) return; pw = getpwnam (privs->user); if (!pw) @@ -224,13 +215,13 @@ pies_priv_setup (struct pies_privs *privs) if (privs->allgroups) grplist = get_user_groups (privs->groups, privs->user); if (switch_to_privs (pw->pw_uid, pw->pw_gid, grplist ? grplist : privs->groups)) exit (EX_SOFTWARE); if (grplist) - gl_list_free (grplist); + grecs_list_free (grplist); } void pies_epriv_setup (struct pies_privs *privs) { |