diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-01-08 12:22:45 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-01-08 12:22:45 +0000 |
commit | 91ed4ebaa40027ef58cec1783117e81b97f00eec (patch) | |
tree | 134259bca34b5c7db89b6190d6e78a3ed14a7a2c | |
parent | d7d60da1082fd5213f24aa447df11767295a83bf (diff) | |
download | mailfromd-91ed4ebaa40027ef58cec1783117e81b97f00eec.tar.gz mailfromd-91ed4ebaa40027ef58cec1783117e81b97f00eec.tar.bz2 |
* configure.ac (AC_INIT): Rename to gmach (working name).
(MF_VERSION_PATCH): Raise to 91
Require at least MU-1.2.90
(AC_CONFIG_FILES): Add gnu/Makefile and smap/Makefile.
* NEWS: Update.
* bootstrap: Place gnulib files in gnu/
* lib: New directory.
* lib/libmf.h: New file.
* src/daemon.c, src/syslog_async.c, src/syslog_async.h,
src/version.c: Moved to lib
* src/mailfromd.h: Incude sysexits.h unconditionally.
Include libmf.h
* src/bi_sa.m4: Rewrite using mu_socket_stream_t.
* src/main.c: Remove pre-mu-1.2.90 dependencies.
* Makefile.am (SUBDIRS): Add gnu and smap.
* src/Makefile.am, gacopyz/Makefile.am: Update.
* src/mtasim.c (main): Remove (now superfluous) invocation of
mu_error_set_print.
* smap/smap.c: Rewrite using MU-1.2.90
* po/POTFILES.in: Update.
git-svn-id: file:///svnroot/mailfromd/branches/gmach@1542 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | NEWS | 12 | ||||
-rwxr-xr-x | bootstrap | 4 | ||||
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | gacopyz/Makefile.am | 4 | ||||
-rw-r--r-- | lib/daemon.c (renamed from src/daemon.c) | 0 | ||||
-rw-r--r-- | lib/libmf.h | 22 | ||||
-rw-r--r-- | lib/syslog_async.c (renamed from src/syslog_async.c) | 0 | ||||
-rw-r--r-- | lib/syslog_async.h (renamed from src/syslog_async.h) | 0 | ||||
-rw-r--r-- | lib/version.c (renamed from src/version.c) | 6 | ||||
-rw-r--r-- | po/POTFILES.in | 17 | ||||
-rw-r--r-- | smap/smap.c | 868 | ||||
-rw-r--r-- | src/Makefile.am | 32 | ||||
-rw-r--r-- | src/bi_sa.m4 | 104 | ||||
-rw-r--r-- | src/mailfromd.h | 50 | ||||
-rw-r--r-- | src/main.c | 54 | ||||
-rw-r--r-- | src/mtasim.c | 12 | ||||
-rw-r--r-- | tests/version.at | 2 |
18 files changed, 371 insertions, 828 deletions
diff --git a/Makefile.am b/Makefile.am index 04d12ad6..005ecda5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. AUTOMAKE_OPTIONS = gnits 1.8.5 std-options -SUBDIRS = lib gacopyz src mflib elisp po etc doc tests +SUBDIRS = gnu lib gacopyz src mflib smap elisp po etc doc tests ACLOCAL_AMFLAGS = -I m4 distuninstallcheck_listfiles = find . -type f -not -name 'mailfromd.rc' -print @@ -1,11 +1,17 @@ -Mailfromd NEWS -- history of user-visible changes. 2007-12-12 -Copyright (C) 2005, 2006, 2007 Sergey Poznyakoff +Mailfromd NEWS -- history of user-visible changes. 2008-01-08 +Copyright (C) 2005, 2006, 2007, 2008 Sergey Poznyakoff See the end of file for copying conditions. Please send mailfromd bug reports to <bug-mailfromd@gnu.org.ua> -Version 4.2.90 (SVN) +Version 4.2.91 (SVN) + +* Requires Mailutils 1.2.90 or better. + +* Includes smap. + +Smap is a general-purpose remote map for MeTA1. * write built-in @@ -4,6 +4,7 @@ ############################ GNULIB_DATE=2007-05-12 +GNU_SOURCE_BASE=gnu MODLIST="argp\ fprintftime\ @@ -281,7 +282,8 @@ if [ -n "$MODAVOID" ]; then gnulib_tool_options="`echo $MODAVOID | sed 's/\([^ ][^ ]*\)/--avoid &/g'`" fi -gnulib-tool --import $gnulib_tool_options $MODLIST +test -d $GNU_SOURCE_BASE || mkdir $GNU_SOURCE_BASE +gnulib-tool --import --source-base=$GNU_SOURCE_BASE $gnulib_tool_options $MODLIST echo "$0: Reconfiguring ..." diff --git a/configure.ac b/configure.ac index c2684558..6714d217 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ # This file is part of mailfromd. -# Copyright (C) 2005, 2006, 2007 Sergey Poznyakoff +# Copyright (C) 2005, 2006, 2007, 2008 Sergey Poznyakoff # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,8 +17,8 @@ AC_PREREQ(2.59) m4_define([MF_VERSION_MAJOR], 4) m4_define([MF_VERSION_MINOR], 2) -m4_define([MF_VERSION_PATCH], 90) -AC_INIT([mailfromd], +m4_define([MF_VERSION_PATCH], 91) +AC_INIT([gmach], MF_VERSION_MAJOR.MF_VERSION_MINOR[]m4_ifdef([MF_VERSION_PATCH],.MF_VERSION_PATCH), [bug-mailfromd@gnu.org.ua]) AC_CONFIG_SRCDIR([src/main.c]) @@ -85,7 +85,7 @@ extern char *strtok_r (char *s, const char *delim, char **save_ptr); ]) # Check for GNU Mailutils -AM_GNU_MAILUTILS(1.0, [all sieve cfg argp], [:]) +AM_GNU_MAILUTILS(1.2.90, [all sieve cfg argp], [:]) save_LIBS=$LIBS LIBS="$LIBS $MAILUTILS_LIBS" @@ -584,10 +584,12 @@ syslog_async=$syslog_async ]) AC_CONFIG_FILES([Makefile + gnu/Makefile lib/Makefile gacopyz/Makefile src/Makefile mflib/Makefile + smap/Makefile elisp/Makefile po/Makefile.in etc/Makefile diff --git a/gacopyz/Makefile.am b/gacopyz/Makefile.am index 3ddc0ea2..4dbef83a 100644 --- a/gacopyz/Makefile.am +++ b/gacopyz/Makefile.am @@ -1,5 +1,5 @@ # This file is part of mailfrom filter. -# Copyright (C) 2006, 2007 Sergey Poznyakoff +# Copyright (C) 2006, 2007, 2008 Sergey Poznyakoff # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -31,7 +31,7 @@ libgacopyz_a_SOURCES = \ EXTRA_DIST=trans.tab trans.awk BUILT_SOURCES=trans.h -INCLUDES=-I$(top_srcdir)/lib +INCLUDES=-I$(top_srcdir)/gnu -I../gnu trans.h: ${top_srcdir}/gacopyz/trans.tab ${top_srcdir}/gacopyz/trans.awk $(AWK) -f ${top_srcdir}/gacopyz/trans.awk \ diff --git a/src/daemon.c b/lib/daemon.c index 25e51a62..25e51a62 100644 --- a/src/daemon.c +++ b/lib/daemon.c diff --git a/lib/libmf.h b/lib/libmf.h new file mode 100644 index 00000000..21baa0cf --- /dev/null +++ b/lib/libmf.h @@ -0,0 +1,22 @@ +/* This file is part of mailfromd. + Copyright (C) 2005, 2006, 2008 Sergey Poznyakoff + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <gettext.h> + +#define _(String) gettext(String) +#define N_(String) String + +void mailfromd_version(const char *progname, FILE *stream); diff --git a/src/syslog_async.c b/lib/syslog_async.c index 006cf16e..006cf16e 100644 --- a/src/syslog_async.c +++ b/lib/syslog_async.c diff --git a/src/syslog_async.h b/lib/syslog_async.h index 9c0836c5..9c0836c5 100644 --- a/src/syslog_async.h +++ b/lib/syslog_async.h diff --git a/src/version.c b/lib/version.c index 7fa7c7f1..1f822062 100644 --- a/src/version.c +++ b/lib/version.c @@ -18,7 +18,9 @@ # include <config.h> #endif -#include "mailfromd.h" +#include <stdio.h> +#include <gettext.h> +#define _(String) gettext(String) const char version_etc_copyright[] = /* Do *not* mark this string for translation. %s is a copyright @@ -27,7 +29,7 @@ const char version_etc_copyright[] = "Copyright %s 2005, 2006, 2007 Sergey Poznyakoff"; void -mailfromd_version(const char *progname, FILE *stream, struct argp_state *state) +mailfromd_version(const char *progname, FILE *stream) { fprintf (stream, "%s (%s) %s\n", progname, PACKAGE, PACKAGE_VERSION); /* TRANSLATORS: Translate "(C)" to the copyright symbol diff --git a/po/POTFILES.in b/po/POTFILES.in index 70dc6d99..669c146a 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -16,11 +16,11 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # Library files -lib/argp-parse.c -lib/argp-help.c -lib/getopt.c -lib/obstack.c -lib/strftime.c +gnu/argp-parse.c +gnu/argp-help.c +gnu/getopt.c +gnu/obstack.c +gnu/strftime.c # Gacopyz files gacopyz/context.c @@ -31,6 +31,12 @@ gacopyz/proc.c gacopyz/server.c gacopyz/smfi.c +# libmf.a +lib/version.c + +# Smap +smap/smap.c + # Source files src/debug.cin src/optab.opc @@ -66,5 +72,4 @@ src/rate.c src/spf.c src/stack.c src/symtab.c -src/version.c diff --git a/smap/smap.c b/smap/smap.c index f22cf27b..04027795 100644 --- a/smap/smap.c +++ b/smap/smap.c @@ -1,5 +1,5 @@ /* This file is part of smap. - Copyright (C) 2006, 2007 Sergey Poznyakoff + Copyright (C) 2006, 2007, 2008 Sergey Poznyakoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,593 +32,61 @@ #include <ctype.h> #include <sysexits.h> /* FIXME */ #include <mailutils/mailutils.h> -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free -#include <obstack.h> +#include <mailutils/libargp.h> +#include <mailutils/libcfg.h> + +#include "libmf.h" /* FIXME */ #include <inttypes.h> const char *mu_umaxtostr (unsigned slot, uintmax_t val); -#define DEFAULT_URL "tcp://127.0.0.1:" -int reuse_smap_address = 1; -char *smap_url_string; +int smap_reload; +unsigned int smap_timeout; +int smap_transcript; char *run_as_user; char *syslog_tag; -char *negative_reply = "Nie znam takiego"; -char *positive_reply = "Swoj chlop"; - -struct daemon_param daemon_param = { - MODE_DAEMON, /* Start in daemon mode */ - 20, /* Default maximum number of children */ - 0, /* No standard port */ - 600, /* Idle timeout */ - 0, /* No transcript by default */ - NULL /* No PID file by default */ -}; - -typedef union -{ - struct sockaddr sa; - struct sockaddr_in s_in; - struct sockaddr_un s_un; -} all_addr_t; - -enum macro_id { - MACRO_KEY, - MACRO_AUTH_NAME, - MACRO_AUTH_PASSWD, - MACRO_AUTH_UID, - MACRO_AUTH_GID, - MACRO_AUTH_GECOS, - MACRO_AUTH_DIR, - MACRO_AUTH_SHELL, - MACRO_AUTH_MAILBOX, - MACRO_AUTH_QUOTA -}; - -struct macro_tab -{ - char *name; - size_t len; - enum macro_id id; -}; +char *negative_reply; +char *positive_reply; -static struct macro_tab macro_tab[] = { -#define S(s,m) { s, sizeof (s) - 1, m } - { "key", 3, MACRO_KEY }, - S(MU_AUTH_NAME, MACRO_AUTH_NAME), - S(MU_AUTH_PASSWD, MACRO_AUTH_PASSWD), - S(MU_AUTH_UID, MACRO_AUTH_UID), - S(MU_AUTH_GID, MACRO_AUTH_GID), - S(MU_AUTH_GECOS, MACRO_AUTH_GECOS), - S(MU_AUTH_DIR, MACRO_AUTH_DIR), - S(MU_AUTH_SHELL, MACRO_AUTH_SHELL), - S(MU_AUTH_MAILBOX, MACRO_AUTH_MAILBOX), - S(MU_AUTH_QUOTA, MACRO_AUTH_QUOTA), - { NULL } -#undef S -#undef concat -}; - -static struct obstack expand_stk; -static const char * -expand_macro (const char *str, const char *key, struct mu_auth_data *auth, - int delim, const char **endp) -{ - const char *p; - size_t len; - struct macro_tab *macro; - const char *ret = NULL; - - for (p = str; *p != delim && isascii (*p) && isalpha (*p); p++) - ; - len = p - str; - for (macro = macro_tab; macro->name; macro++) - { - if (len == macro->len && memcmp (macro->name, str, len) == 0) - { - switch (macro->id) - { - case MACRO_KEY: - ret = key; - break; - - case MACRO_AUTH_NAME: - ret = auth ? auth->name : ""; - break; - - case MACRO_AUTH_PASSWD: - ret = auth ? auth->passwd : ""; - break; - - case MACRO_AUTH_UID: - ret = auth ? mu_umaxtostr (1, auth->uid) : "-1"; - break; - - case MACRO_AUTH_GID: - ret = auth ? mu_umaxtostr (1, auth->gid) : "-1"; - break; - - case MACRO_AUTH_GECOS: - ret = auth ? auth->gecos : ""; - break; - - case MACRO_AUTH_DIR: - ret = auth ? auth->dir : ""; - break; - - case MACRO_AUTH_SHELL: - ret = auth ? auth->shell : ""; - break; - - case MACRO_AUTH_MAILBOX: - ret = auth ? auth->mailbox : ""; - break; - - case MACRO_AUTH_QUOTA: - ret = auth ? mu_umaxtostr (1, auth->quota) : "NONE"; - break; - } - break; - } - } - if (ret) - *endp = *p ? p + 1 : p; - return ret; -} - -static const char * +char * expand_reply_text (const char *arg, const char *key, struct mu_auth_data *auth) { - const char *p; - const char *str; - - obstack_init (&expand_stk); - for (p = arg; *p; ) - { - if (*p == '$') - { - if (p[1] == '$') - { - obstack_1grow (&expand_stk, '$'); - p += 2; - } - else if (p[1] == '{') - { - str = expand_macro (p + 2, key, auth, '}', &p); - if (str) - obstack_grow (&expand_stk, str, strlen (str)); - else - { - obstack_grow (&expand_stk, p, 2); - p += 2; - } - } - else - { - str = expand_macro (p + 1, key, auth, 0, &p); - if (str) - obstack_grow (&expand_stk, str, strlen (str)); - else - { - obstack_grow (&expand_stk, p, 1); - p++; - } - } - } - else - { - obstack_1grow (&expand_stk, *p); - p++; - } - } - obstack_1grow (&expand_stk, 0); - return obstack_finish (&expand_stk); -} - -static int -smap_open_internal (int *pfd, mu_url_t url, const char *urlstr) -{ - int fd; int rc; - int t = 1; - char buffer[64]; - all_addr_t addr; - int addrsize; - mode_t saved_umask; + mu_vartab_t vtab; + char *reply = NULL; - rc = mu_url_get_scheme (url, buffer, sizeof buffer, NULL); + mu_vartab_create (&vtab); + mu_vartab_define (vtab, "key", key, 0); + mu_vartab_define (vtab, MU_AUTH_NAME, auth ? auth->name : "", 0); + mu_vartab_define (vtab, MU_AUTH_PASSWD, auth ? auth->passwd : "", 0); + mu_vartab_define (vtab, MU_AUTH_UID, + auth ? mu_umaxtostr (1, auth->uid) : "-1", 0); + mu_vartab_define (vtab, MU_AUTH_GID, + auth ? mu_umaxtostr (1, auth->gid) : "-1", 0); + mu_vartab_define (vtab, MU_AUTH_GECOS, + auth ? auth->gecos : "", 0); + mu_vartab_define (vtab, MU_AUTH_DIR, auth ? auth->dir : "", 0); + mu_vartab_define (vtab, MU_AUTH_SHELL, auth ? auth->shell : "", 0); + mu_vartab_define (vtab, MU_AUTH_MAILBOX, auth ? auth->mailbox : "", 0); + mu_vartab_define (vtab, MU_AUTH_QUOTA, + auth ? mu_umaxtostr (1, auth->quota) : "NONE", 0); + rc = mu_vartab_expand (vtab, arg, &reply); if (rc) - { - mu_error (_("%s: cannot get scheme from URL: %s"), - urlstr, mu_strerror(rc)); - return EX_CONFIG; - } - - memset (&addr, 0, sizeof addr); - if (strcmp (buffer, "file") == 0 || strcmp (buffer, "socket") == 0) - { - size_t size; - - rc = mu_url_get_path (url, NULL, 0, &size); - if (rc) - { - mu_error (_("%s: cannot get path: %s"), urlstr, mu_strerror(rc)); - return EX_CONFIG; - } - - if (size > sizeof addr.s_un.sun_path - 1) - { - mu_error (_("%s: file name too long"), urlstr); - return EX_TEMPFAIL; - } - mu_url_get_path (url, addr.s_un.sun_path, sizeof addr.s_un.sun_path, - NULL); - - fd = socket (PF_UNIX, SOCK_STREAM, 0); - if (fd < 0) - { - mu_error ("socket: %s", mu_strerror (errno)); - return EX_TEMPFAIL; - } - - addr.s_un.sun_family = AF_UNIX; - addrsize = sizeof addr.s_un; - - if (reuse_smap_address) - { - struct stat st; - if (stat (addr.s_un.sun_path, &st)) - { - if (errno != ENOENT) - { - mu_error (_("file %s exists but cannot be stat'd"), - addr.s_un.sun_path); - return EX_TEMPFAIL; - } - } - else if (!S_ISSOCK (st.st_mode)) - { - mu_error (_("file %s is not a socket"), - addr.s_un.sun_path); - return EX_TEMPFAIL; - } - else - unlink (addr.s_un.sun_path); - } - - } - else if (strcmp (buffer, "tcp") == 0) - { - size_t size; - long n; - struct hostent *hp; - char *path = NULL; - short port = 0; - - rc = mu_url_get_port (url, &n); - if (rc) - { - mu_error (_("%s: cannot get port: %s"), urlstr, mu_strerror(rc)); - return EX_CONFIG; - } - - if (n == 0 || (port = n) != n) - { - mu_error (_("Port out of range: %ld"), n); - return EX_CONFIG; - } - - rc = mu_url_get_host (url, NULL, 0, &size); - if (rc) - { - mu_error (_("%s: cannot get host: %s"), urlstr, mu_strerror(rc)); - return EX_CONFIG; - } - path = malloc (size + 1); - if (!path) - { - mu_error (_("Not enough memory")); - return EX_TEMPFAIL; - } - mu_url_get_host (url, path, size + 1, NULL); - - fd = socket (PF_INET, SOCK_STREAM, 0); - if (fd < 0) - { - mu_error ("socket: %s", mu_strerror (errno)); - return EX_TEMPFAIL; - } - - addr.s_in.sin_family = AF_INET; - if (hp = gethostbyname (path)) - { - char **ap; - int count = 0; - - addr.s_in.sin_addr.s_addr = *(unsigned long*) hp->h_addr_list[0]; - - for (ap = hp->h_addr_list; *ap; ap++) - count++; - if (count > 1) - mu_error (_("warning: %s has several IP addresses, using %s"), - path, inet_ntoa (addr.s_in.sin_addr)); - } - else if (inet_aton (path, &addr.s_in.sin_addr) == 0) - { - mu_error ("invalid IP address: %s", path); - return EX_TEMPFAIL; - } - addr.s_in.sin_port = htons (port); - addrsize = sizeof addr.s_in; - - if (reuse_smap_address) - setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(t)); - } - else - { - mu_error (_("%s: invalid scheme"), urlstr); - return EX_CONFIG; - } - - saved_umask = umask (0117); - if (bind (fd, &addr.sa, addrsize) == -1) - { - mu_error ("bind: %s", strerror (errno)); - close (fd); - return EXIT_FAILURE; - } - umask (saved_umask); - *pfd = fd; - return 0; -} - -int -smap_open (int *pfd, char *urlstr) -{ - mu_url_t url = NULL; - int rc; - - rc = mu_url_create (&url, urlstr); - if (rc) - { - mu_error (_("%s: cannot create URL: %s"), - urlstr, mu_strerror (rc)); - return EX_CONFIG; - } - rc = mu_url_parse (url); - if (rc) - { - mu_error (_("%s: error parsing URL: %s"), - urlstr, mu_strerror(rc)); - return EX_CONFIG; - } - - rc = smap_open_internal (pfd, url, urlstr); - mu_url_destroy (&url); - return rc; -} - -size_t children; -static int need_cleanup = 0; - -void -process_cleanup () -{ - pid_t pid; - int status; - - if (need_cleanup) - { - need_cleanup = 0; - while ( (pid = waitpid (-1, &status, WNOHANG)) > 0) - --children; - } -} - -RETSIGTYPE -smap_sigchld (int signo) -{ - need_cleanup = 1; -#ifndef HAVE_SIGACTION - signal (signo, smap_sigchld); -#endif -} - -void -log_connection (all_addr_t *addr, socklen_t addrlen) -{ - switch (addr->sa.sa_family) - { - case PF_UNIX: - syslog (LOG_INFO, _("connect from socket")); - break; - - case PF_INET: - syslog (LOG_INFO, _("connect from %s"), inet_ntoa (addr->s_in.sin_addr)); - } -} - -int -smap_daemon (char *urlstr) -{ - int rc; - int listenfd, connfd; - all_addr_t addr; - socklen_t addrlen; - pid_t pid; - - if (daemon_param.mode == MODE_DAEMON) - { - if (daemon (0, 0) < 0) - { - mu_error (_("Failed to become a daemon")); - return EX_UNAVAILABLE; - } - } - - rc = smap_open (&listenfd, urlstr); - if (rc) - return rc; - - if (listen (listenfd, 128) == -1) - { - mu_error ("listen: %s", strerror (errno)); - close (listenfd); - return EX_UNAVAILABLE; - } - -#ifdef HAVE_SIGACTION - { - struct sigaction act; - act.sa_handler = lmtp_sigchld; - sigemptyset (&act.sa_mask); - act.sa_flags = 0; - sigaction (SIGCHLD, &act, NULL); - } -#else - signal (SIGCHLD, smap_sigchld); -#endif - - for (;;) - { - process_cleanup (); - if (children > daemon_param.maxchildren) - { - mu_error (_("too many children (%lu)"), - (unsigned long) children); - pause (); - continue; - } - addrlen = sizeof addr; - connfd = accept (listenfd, (struct sockaddr *)&addr, &addrlen); - if (connfd == -1) - { - if (errno == EINTR) - continue; - mu_error ("accept: %s", strerror (errno)); - continue; - /*exit (EXIT_FAILURE);*/ - } - - log_connection (&addr, addrlen); - - pid = fork (); - if (pid == -1) - syslog (LOG_ERR, "fork: %s", strerror (errno)); - else if (pid == 0) /* Child. */ - { - int status; - - close (listenfd); - status = smap_loop (fdopen (connfd, "r"), fdopen (connfd, "w")); - exit (status); - } - else - { - ++children; - } - close (connfd); - } -} - - -const char *program_version = "smap (" PACKAGE_STRING ")"; -static char doc[] = "Simple remote map for MeTA1"; -static char args_doc[] = ""; - -#define OPTION_GECOS 256 -#define OPTION_POSITIVE_REPLY 257 -#define OPTION_NEGATIVE_REPLY 258 -#define OPTION_NEGATIVE_OK 259 - -static struct argp_option options[] = -{ - { "url", 'u', "URL", 0, - N_("Set URL to listen on"), 0 }, - { "user", 'U', "NAME", 0, - N_("Run as user NAME"), 0 }, - { "gecos", OPTION_GECOS, NULL, 0, - N_("Return gecos"), 0 }, - { "log-tag", 'L', N_("STRING"), 0, - N_("Set syslog tag"), 0 }, - { "positive-reply", OPTION_POSITIVE_REPLY, N_("STRING"), 0, - N_("Set positive reply text"), 0 }, - { "negative-reply", OPTION_NEGATIVE_REPLY, N_("STRING"), 0, - N_("Set negative reply text"), 0 }, - { NULL } -}; - -static error_t parse_opt (int key, char *arg, struct argp_state *state); - -static struct argp argp = { - options, - parse_opt, - args_doc, - doc, - NULL, - NULL, NULL -}; - -static const char *argp_capa[] = { - "daemon", - "auth", - "common", - "license", - "logging", - NULL -}; - -static error_t -parse_opt (int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case ARGP_KEY_INIT: - state->child_inputs[0] = state->input; - break; - - case OPTION_NEGATIVE_REPLY: - negative_reply = arg; - break; - - case OPTION_POSITIVE_REPLY: - positive_reply = arg; - break; - - case 'L': - syslog_tag = arg; - break; - - case 'U': - run_as_user = arg; - break; - - case 'u': - smap_url_string = arg; - break; - - case OPTION_GECOS: - positive_reply = "${gecos}"; - break; - - default: - return ARGP_ERR_UNKNOWN; - - case ARGP_KEY_ERROR: - exit (EX_USAGE); - } - return 0; + mu_error (_("cannot expand string `%s': %s"), arg, mu_strerror (rc)); + mu_vartab_destroy (&vtab); + return NULL; } - + + int read_delim (FILE *fp, int delim, char *buf, size_t bufsize) { int c; int len = 0; - + + alarm (smap_timeout); bufsize--; while (len < bufsize && ((c = fgetc (fp))) != delim) { @@ -626,18 +94,19 @@ read_delim (FILE *fp, int delim, char *buf, size_t bufsize) { if (len) { - if (daemon_param.transcript && len) - syslog (LOG_INFO, "recv: %.*s:", len, buf); - mu_error ("unexpected end of file in input"); + if (smap_transcript && len) + mu_diag_output (MU_DIAG_INFO, "recv: %.*s:", len, buf); + mu_error (_("unexpected end of file in input")); exit (1); } return 0; } buf[len++] = c; } + alarm (0); buf[len] = 0; - if (daemon_param.transcript) - syslog (LOG_INFO, "recv: %s:", buf); + if (smap_transcript) + mu_diag_output (MU_DIAG_INFO, "recv: %s:", buf); return len; } @@ -649,16 +118,16 @@ smap_reply (FILE *fp, const char *code, const char *result) len += 1 + strlen (result); if (result) { - if (daemon_param.transcript) - syslog (LOG_INFO, "send: %lu:%s %s,", - (unsigned long) len, code, result); + if (smap_transcript) + mu_diag_output (MU_DIAG_INFO, "send: %lu:%s %s,", + (unsigned long) len, code, result); fprintf (fp, "%lu:%s %s,", (unsigned long) len, code, result); } else { - if (daemon_param.transcript) - syslog (LOG_INFO, "send: %lu:%s,", - (unsigned long) len, code); + if (smap_transcript) + mu_diag_output (MU_DIAG_INFO, "send: %lu:%s,", + (unsigned long) len, code); fprintf (fp, "%s:%s,", (unsigned long) len, code); } } @@ -677,33 +146,37 @@ smap_loop (FILE *in, FILE *out) /* Read input: */ while (read_delim (in, ':', buf, sizeof buf)) { + char *reply_txt = NULL; + int rc; + len = strtoul (buf, &p, 10); if (*p != 0) { - mu_error ("protocol error: expected packet length, but found %s", buf); + mu_error (_("protocol error: expected packet length, but found %s"), + buf); exit (1); } if (len > sizeof buf - 1) { - mu_error ("protocol error: packet length too big"); + mu_error (_("protocol error: packet length too big")); exit (1); } if (fread (buf, 1, len, in) != len) { - mu_error ("protocol error: short read"); + mu_error (_("protocol error: short read")); exit (1); } buf[len] = 0; - if (daemon_param.transcript) - syslog (LOG_INFO, "recv: %s,", buf); + if (smap_transcript) + mu_diag_output (MU_DIAG_INFO, "recv: %s,", buf); if (getc (in) != ',') { - mu_error ("protocol error: missing terminating comma"); + mu_error (_("protocol error: missing terminating comma")); exit (1); } buf[len] = 0; @@ -711,7 +184,7 @@ smap_loop (FILE *in, FILE *out) key = strchr (buf, ' '); if (!key) { - mu_error ("protocol error: missing map name"); + mu_error (_("protocol error: missing map name")); exit (1); } key++; @@ -725,14 +198,16 @@ smap_loop (FILE *in, FILE *out) /* Reply: */ if (!auth) { - smap_reply (out, "NOTFOUND", - expand_reply_text (negative_reply, key, NULL)); + reply_txt = expand_reply_text (negative_reply, key, NULL); + smap_reply (out, "NOTFOUND", reply_txt); } else { - smap_reply (out, "OK", expand_reply_text (positive_reply, key, auth)); + reply_txt = expand_reply_text (positive_reply, key, auth); + smap_reply (out, "OK", reply_txt); mu_auth_data_free (auth); } + free (reply_txt); } /* Cleanup and exit */ fclose (in); @@ -741,6 +216,17 @@ s |