diff options
-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,5 +1,5 @@ # 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 @@ -34,37 +34,19 @@ alpha: 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,11 +1,13 @@ -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. @@ -72,7 +74,7 @@ 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 diff --git a/bootstrap.conf b/bootstrap.conf index 364978b..492aa78 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -1,5 +1,5 @@ # 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 @@ -31,11 +31,12 @@ if [ -n "$MODAVOID" ]; then 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 diff --git a/configure.ac b/configure.ac index a8848dd..0c1d2b9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ # 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 @@ -15,7 +15,7 @@ # 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]) @@ -57,7 +57,8 @@ AC_CHECK_FUNCS([alarm dup2 gethostbyname memmove memset select setenv socket str 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 @@ -85,8 +86,6 @@ IMPRIMATUR_INIT 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 d62e1a3..1e01a93 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -1,12 +1,11 @@ # 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 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,5 +1,5 @@ /* 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 @@ -19,10 +19,6 @@ #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) diff --git a/src/.gitignore b/src/.gitignore index 18a7111..4ad4290 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,3 +1,4 @@ +cmdline.h inetd meta1gram.c meta1gram.h diff --git a/src/Makefile.am b/src/Makefile.am index 19c6483..455b2c2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ # 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 @@ -35,25 +35,34 @@ pies_SOURCES = \ 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) @@ -1,5 +1,5 @@ /* 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 @@ -25,7 +25,6 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> -#include <hash.h> struct pies_sockaddr { @@ -40,15 +39,15 @@ struct acl_entry 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; }; @@ -61,14 +60,18 @@ 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) { @@ -189,24 +192,24 @@ _parse_sockaddr (struct acl_entry *entry, const grecs_value_t *value) 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--; @@ -219,24 +222,19 @@ _parse_from (struct acl_entry *entry, size_t argc, const grecs_value_t *argv) 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; } @@ -250,11 +248,11 @@ _parse_from (struct acl_entry *entry, size_t argc, const grecs_value_t *argv) } 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++; @@ -265,19 +263,19 @@ _parse_sub_acl (struct acl_entry *entry, size_t argc, grecs_value_t *argv) 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--; @@ -287,9 +285,9 @@ _parse_sub_acl (struct acl_entry *entry, size_t argc, grecs_value_t *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++; @@ -299,17 +297,13 @@ _parse_group (struct acl_entry *entry, size_t argc, grecs_value_t * argv) _("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++; } @@ -317,11 +311,11 @@ _parse_group (struct acl_entry *entry, size_t argc, grecs_value_t * 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); @@ -356,7 +350,7 @@ parse_acl_line (grecs_locus_t *locus, int allow, pies_acl_t acl, grecs_error (locus, 0, _("unexpected list")); return 1; } - gl_list_add_last (acl->list, entry); + grecs_list_append (acl->list, entry); return 0; } @@ -373,7 +367,6 @@ _acl_common_section_parser (enum grecs_callback_command cmd, int flag) { pies_acl_t acl; - grecs_locus_t defn_loc; const char *tag = NULL; int has_value = 0; @@ -412,15 +405,8 @@ _acl_common_section_parser (enum grecs_callback_command cmd, 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; @@ -570,11 +556,10 @@ _acl_check (struct acl_entry *ent, struct acl_input *input) 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; } @@ -585,16 +570,15 @@ _acl_check (struct acl_entry *ent, struct acl_input *input) 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; @@ -604,7 +588,7 @@ 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"))); @@ -622,12 +606,11 @@ 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; } @@ -635,43 +618,78 @@ pies_acl_check (pies_acl_t acl, struct acl_input *input, int 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 @@ -681,5 +699,5 @@ pies_acl_lookup (const char *name) 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,5 +1,5 @@ /* 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 @@ -30,7 +30,7 @@ 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); 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,5 +1,5 @@ /* 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 @@ -125,15 +125,43 @@ logmsg_printf (int prio, const char *fmt, ...) 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 { diff --git a/src/inetd.c b/src/inetd.c index 012266a..1d7798d 100644 --- a/src/inetd.c +++ b/src/inetd.c @@ -1,5 +1,5 @@ /* 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 @@ -28,11 +28,11 @@ #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/" @@ -281,13 +281,9 @@ inetd_conf_file (const char *file) 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]); diff --git a/src/meta1gram.y b/src/meta1gram.y index 6256448..deaf382 100644 --- a/src/meta1gram.y +++ b/src/meta1gram.y @@ -1,6 +1,6 @@ %{ /* 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 @@ -20,8 +20,10 @@ 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") @@ -51,7 +53,7 @@ meta1_stmt_create (enum meta1_stmt_type type, const char *ident) p->next = NULL; p->type = type; p->ident = ident; - p->locus = meta1_locus; + p->locus = meta1lloc; return p; } @@ -84,9 +86,12 @@ reverse (struct meta1_stmt *in) 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; } @@ -168,29 +173,25 @@ 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; } ; @@ -207,16 +208,12 @@ list : '{' values '}' 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; } ; @@ -229,7 +226,7 @@ opt_sc : /* empty */ int yyerror (char *s) { - meta1_parse_error ("%s", s); + grecs_error (&yylloc, 0, "%s", s); return 0; } diff --git a/src/meta1lex.h b/src/meta1lex.h index 0f7c75d..213fb40 100644 --- a/src/meta1lex.h +++ b/src/meta1lex.h @@ -1,5 +1,5 @@ /* 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 @@ -14,7 +14,6 @@ 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; diff --git a/src/meta1lex.l b/src/meta1lex.l index 4eca9e2..7faaf41 100644 --- a/src/meta1lex.l +++ b/src/meta1lex.l @@ -1,7 +1,7 @@ /* 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 @@ -26,16 +26,27 @@ %{ #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 @@ -45,10 +56,10 @@ X [0-9a-fA-F] "/*" 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}+ | @@ -82,18 +93,18 @@ X [0-9a-fA-F] 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]); } %% @@ -135,7 +146,7 @@ unescape_to_line (int c) { 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); } @@ -182,20 +193,6 @@ meta1_string (const char *str, size_t len) } 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"); @@ -217,15 +214,17 @@ meta1_config_parse (const char *name) _("%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,5 +1,5 @@ /* 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 @@ -26,7 +26,18 @@ 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; @@ -145,14 +156,11 @@ stderr_closed_p () } -#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)); @@ -412,9 +420,9 @@ _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; } @@ -422,7 +430,7 @@ _get_array_arg (grecs_value_t *val, int num, grecs_locus_t *locus) 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")); @@ -445,7 +453,7 @@ return_code_section_parser (enum grecs_callback_command cmd, 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; @@ -463,7 +471,7 @@ return_code_section_parser (enum grecs_callback_command cmd, 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; @@ -497,9 +505,9 @@ config_array_to_argv (grecs_value_t *val, grecs_locus_t *locus, size_t *pargc) 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) @@ -702,12 +710,12 @@ _cb_redir (enum grecs_callback_command cmd, 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) @@ -717,7 +725,7 @@ _cb_redir (enum grecs_callback_command cmd, 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; @@ -727,18 +735,18 @@ _cb_redir (enum grecs_callback_command cmd, 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; } } @@ -910,12 +918,11 @@ _cb_flags (enum grecs_callback_command cmd, 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)) @@ -1560,7 +1567,6 @@ struct grecs_keyword pies_keywords[] = { 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; @@ -1579,219 +1585,14 @@ config_help () /* 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 @@ -2156,34 +1957,6 @@ set_mailer_argcv () } -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) { @@ -2248,10 +2021,8 @@ main (int argc, char **argv) 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, '/'); @@ -2289,10 +2060,14 @@ main (int argc, char **argv) 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); @@ -2317,7 +2092,7 @@ main (int argc, char **argv) /* 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); @@ -2326,26 +2101,26 @@ main (int argc, char **argv) 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); @@ -1,5 +1,5 @@ /* 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 @@ -42,7 +42,7 @@ #include <signal.h> #include <time.h> #include <sysexits.h> -#include <argp.h> +#include <ctype.h> #include <grecs.h> #include <wordsplit.h> @@ -117,7 +117,7 @@ struct pies_privs { char *user; int allgroups; - gl_list_t groups; + struct grecs_list *groups; }; enum pies_comp_mode @@ -166,8 +166,8 @@ struct component 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 */ @@ -375,7 +375,7 @@ 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 *); diff --git a/src/progman.c b/src/progman.c index 4420a21..d24ea1a 100644 --- a/src/progman.c +++ b/src/progman.c @@ -1,5 +1,5 @@ /* 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 @@ -15,7 +15,6 @@ along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ #include "pies.h" -#include <hash.h> enum prog_type { @@ -89,7 +88,7 @@ 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) @@ -357,10 +356,10 @@ prog_rebuild_prerequisites (struct prog *prog) 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; @@ -370,7 +369,7 @@ prog_rebuild_prerequisites (struct prog *prog) } else if (strcmp (item, "none") == 0) { - gl_list_free (comp->prereq); + grecs_list_free (comp->prereq); comp->prereq = NULL; } } @@ -392,13 +391,10 @@ prog_rebuild_prerequisites (struct prog *prog) } 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; @@ -521,10 +517,10 @@ open_redirector (struct prog *master, int stream) } -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; @@ -542,15 +538,15 @@ conn_class_hasher (void const *data, size_t n_buckets) } /* 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 @@ -559,11 +555,20 @@ 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])); @@ -586,17 +591,20 @@ conn_class_lookup (const char *tag, } 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; } @@ -1411,16 +1419,14 @@ 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); @@ -1434,16 +1440,12 @@ component_fixup_depend (struct component *comp) } 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; } diff --git a/src/userprivs.c b/src/userprivs.c index b224a00..3270905 100644 --- a/src/userprivs.c +++ b/src/userprivs.c @@ -1,5 +1,5 @@ /* 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 @@ -38,30 +38,23 @@ 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 (); @@ -71,9 +64,7 @@ get_user_groups (gl_list_t init_list, const char *user) 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; } } @@ -83,33 +74,33 @@ get_user_groups (gl_list_t init_list, const char *user) /* 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 */ @@ -209,7 +200,7 @@ 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; @@ -227,7 +218,7 @@ pies_priv_setup (struct pies_privs *privs) grplist ? grplist : privs->groups)) exit (EX_SOFTWARE); if (grplist) - gl_list_free (grplist); + grecs_list_free (grplist); } |