aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-01-08 12:22:45 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-01-08 12:22:45 +0000
commit91ed4ebaa40027ef58cec1783117e81b97f00eec (patch)
tree134259bca34b5c7db89b6190d6e78a3ed14a7a2c
parentd7d60da1082fd5213f24aa447df11767295a83bf (diff)
downloadmailfromd-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.am2
-rw-r--r--NEWS12
-rwxr-xr-xbootstrap4
-rw-r--r--configure.ac10
-rw-r--r--gacopyz/Makefile.am4
-rw-r--r--lib/daemon.c (renamed from src/daemon.c)0
-rw-r--r--lib/libmf.h22
-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.in17
-rw-r--r--smap/smap.c868
-rw-r--r--src/Makefile.am32
-rw-r--r--src/bi_sa.m4104
-rw-r--r--src/mailfromd.h50
-rw-r--r--src/main.c54
-rw-r--r--src/mtasim.c12
-rw-r--r--tests/version.at2
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
diff --git a/NEWS b/NEWS
index 9e0d81f1..e0117a8b 100644
--- a/NEWS
+++ b/NEWS
@@ -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
diff --git a/bootstrap b/bootstrap
index c5d0106e..5da0d574 100755
--- a/bootstrap
+++ b/bootstrap
@@ -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