summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--imap4d/imap4d.c39
-rw-r--r--imap4d/imap4d.h1
-rw-r--r--imap4d/preauth.c114
-rw-r--r--libmailutils/mailbox/mbx_default.c31
-rw-r--r--libmailutils/server/acl.c121
-rw-r--r--libmailutils/string/wordsplit.c16
-rw-r--r--libmu_auth/ldap.c35
-rw-r--r--libmu_auth/radius.c54
-rw-r--r--libmu_auth/sql.c35
-rw-r--r--libproto/mailer/prog.c118
-rw-r--r--po/POTFILES.in1
11 files changed, 356 insertions, 209 deletions
diff --git a/imap4d/imap4d.c b/imap4d/imap4d.c
index cbadb83d7..844b95324 100644
--- a/imap4d/imap4d.c
+++ b/imap4d/imap4d.c
@@ -308,21 +308,34 @@ imap4d_session_setup0 ()
if (modify_homedir)
{
- int rc;
- mu_vartab_t vtab;
char *expr = mu_tilde_expansion (modify_homedir, "/", real_homedir);
-
- mu_vartab_create (&vtab);
- mu_vartab_define (vtab, "user", auth_data->name, 0);
- mu_vartab_define (vtab, "home", real_homedir, 0);
- rc = mu_vartab_expand (vtab, expr, &imap4d_homedir);
- mu_vartab_destroy (&vtab);
- free (expr);
- if (rc)
+ struct mu_wordsplit ws;
+ const char *env[3];
+
+ env[0] = "user";
+ env[1] = auth_data->name;
+ env[2] = "home";
+ env[3] = real_homedir;
+ env[4] = NULL;
+
+ ws.ws_env = env;
+ if (mu_wordsplit (expr, &ws,
+ MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
+ MU_WRDSF_ENV | MU_WRDSF_ENV_KV))
+ {
+ mu_error (_("cannot expand line `%s': %s"), expr,
+ mu_wordsplit_strerror (&ws));
+ return 1;
+ }
+ else if (ws.ws_wordc == 0)
+ {
+ mu_error (_("expanding %s yields empty string"), expr);
+ return 1;
+ }
+ imap4d_homedir = strdup (ws.ws_wordv[0]);
+ if (!imap4d_homedir)
{
- free (real_homedir);
- mu_diag_funcall (MU_DIAG_ERROR, "mu_vartab_expand",
- modify_homedir, rc);
+ mu_error ("%s", mu_strerror (errno));
return 1;
}
}
diff --git a/imap4d/imap4d.h b/imap4d/imap4d.h
index 26e9fc323..598bc584f 100644
--- a/imap4d/imap4d.h
+++ b/imap4d/imap4d.h
@@ -100,7 +100,6 @@
#include <mailutils/server.h>
#include <mailutils/wordsplit.h>
#include <mailutils/alloc.h>
-#include <mailutils/vartab.h>
#include <mailutils/cctype.h>
#include <mailutils/cstr.h>
#include <mailutils/io.h>
diff --git a/imap4d/preauth.c b/imap4d/preauth.c
index 1584df482..014da68b2 100644
--- a/imap4d/preauth.c
+++ b/imap4d/preauth.c
@@ -61,22 +61,6 @@ ident_extract_username (char *reply)
}
static int
-trimcrlf (char *buf)
-{
- int len = strlen (buf);
- if (len == 0)
- return 0;
- if (buf[len-1] == '\n')
- {
- len--;
- if (buf[len-1] == '\r')
- len--;
- buf[len] = 0;
- }
- return len;
-}
-
-static int
is_des_p (const char *name)
{
int len = strlen (name);
@@ -369,8 +353,7 @@ do_preauth_ident (struct sockaddr *clt_sa, struct sockaddr *srv_sa)
return NULL;
}
mu_diag_output (MU_DIAG_INFO, "Got %s", buf);
- trimcrlf (buf);
- name = ident_extract_username (buf);
+ name = ident_extract_username (mu_str_stripws (buf));
if (!name)
mu_diag_output (MU_DIAG_INFO,
_("malformed IDENT response: `%s', from %s:%d"),
@@ -405,48 +388,83 @@ do_preauth_ident (struct sockaddr *clt_sa, struct sockaddr *srv_sa)
}
+#define SEQ(s, n, l) \
+ (((l) == (sizeof(s) - 1)) && memcmp (s, n, l) == 0)
+
+struct preauth_closure
+{
+ struct sockaddr_in *s_clt, *s_srv;
+};
+
+static const char *
+preauth_getvar (const char *name, size_t nlen, void *data)
+{
+ struct preauth_closure *clos = data;
+
+ if (clos->s_clt && clos->s_clt->sin_family == AF_INET)
+ {
+ if (SEQ ("client_address", name, nlen))
+ return inet_ntoa (clos->s_clt->sin_addr);
+ if (SEQ ("client_prot", name, nlen))
+ return mu_umaxtostr (0, ntohs (clos->s_clt->sin_port));
+ }
+ if (clos->s_srv && clos->s_srv->sin_family == AF_INET)
+ {
+ if (SEQ ("server_address", name, nlen))
+ return inet_ntoa (clos->s_srv->sin_addr);
+ if (SEQ ("server_port", name, nlen))
+ return mu_umaxtostr (0, ntohs (clos->s_srv->sin_port));
+ }
+ return NULL;
+}
+
/* External (program) preauth */
static char *
do_preauth_program (struct sockaddr *pcs, struct sockaddr *sa)
{
int rc;
- mu_vartab_t vtab;
- char *cmd;
- FILE *fp;
+ mu_stream_t str;
char *buf = NULL;
- size_t size = 0;
-
- mu_vartab_create (&vtab);
- if (pcs && pcs->sa_family == AF_INET)
+ size_t size = 0, n;
+ struct mu_wordsplit ws;
+ struct preauth_closure clos;
+
+ clos.s_clt = (struct sockaddr_in *) pcs;
+ clos.s_srv = (struct sockaddr_in *) sa;
+
+ ws.ws_getvar = preauth_getvar;
+ ws.ws_closure = &clos;
+ if (mu_wordsplit (preauth_program, &ws,
+ MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
+ MU_WRDSF_GETVAR | MU_WRDSF_CLOSURE))
{
- struct sockaddr_in *s_in = (struct sockaddr_in *)pcs;
- mu_vartab_define (vtab, "client_address", inet_ntoa (s_in->sin_addr), 0);
- mu_vartab_define (vtab, "client_port",
- mu_umaxtostr (0, ntohs (s_in->sin_port)), 0);
+ mu_error (_("cannot expand line `%s': %s"), preauth_program,
+ mu_wordsplit_strerror (&ws));
+ return NULL;
}
- if (sa && sa->sa_family == AF_INET)
+ else if (ws.ws_wordc == 0)
{
- struct sockaddr_in *s_in = (struct sockaddr_in *) sa;
- mu_vartab_define (vtab, "server_address", inet_ntoa (s_in->sin_addr), 0);
- mu_vartab_define (vtab, "server_port",
- mu_umaxtostr (0, ntohs (s_in->sin_port)), 0);
+ mu_wordsplit_free (&ws);
+ mu_error (_("`%s' expands to an empty line"), preauth_program);
+ return NULL;
}
- rc = mu_vartab_expand (vtab, preauth_program, &cmd);
- mu_vartab_destroy (&vtab);
- if (rc)
- return NULL;
- fp = popen (cmd, "r");
- free (cmd);
- rc = getline (&buf, &size, fp);
- pclose (fp);
- if (rc > 0)
+ rc = mu_prog_stream_create (&str, ws.ws_wordv[0], MU_STREAM_READ);
+ mu_wordsplit_free (&ws);
+ if (rc)
{
- if (trimcrlf (buf) == 0)
- {
- free (buf);
- return NULL;
- }
+ mu_error (_("cannot open input pipe from %s"), preauth_program);
+ return NULL;
+ }
+ rc = mu_stream_getline (str, &buf, &size, &n);
+ mu_stream_destroy (&str);
+ if (rc)
+ {
+ mu_error (_("read from `%s' failed"), preauth_program);
+ }
+ else
+ {
+ mu_rtrim_cset (buf, "\r\n");
return buf;
}
return NULL;
diff --git a/libmailutils/mailbox/mbx_default.c b/libmailutils/mailbox/mbx_default.c
index 468230a69..c36e68285 100644
--- a/libmailutils/mailbox/mbx_default.c
+++ b/libmailutils/mailbox/mbx_default.c
@@ -29,15 +29,16 @@
#include <confpaths.h>
+#include <mailutils/nls.h>
#include <mailutils/mailbox.h>
#include <mailutils/util.h>
#include <mailutils/debug.h>
#include <mailutils/error.h>
#include <mailutils/errno.h>
#include <mailutils/mu_auth.h>
-#include <mailutils/vartab.h>
#include <mailutils/folder.h>
#include <mailutils/auth.h>
+#include <mailutils/wordsplit.h>
#include <mailutils/sys/mailbox.h>
@@ -137,12 +138,30 @@ mu_construct_user_mailbox_url (char **pout, const char *name)
{
int rc;
const char *pat = mu_mailbox_url ();
- mu_vartab_t vtab;
+ const char *env[3];
+ struct mu_wordsplit ws;
+
+ env[0] = "user";
+ env[1] = (char*) name;
+ env[3] = NULL;
+ ws.ws_env = env;
+ if (mu_wordsplit (pat, &ws,
+ MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
+ MU_WRDSF_ENV | MU_WRDSF_ENV_KV))
+ {
+ mu_error (_("cannot expand line `%s': %s"), pat,
+ mu_wordsplit_strerror (&ws));
+ return errno;
+ }
- mu_vartab_create (&vtab);
- mu_vartab_define (vtab, "user", name, 1);
- rc = mu_vartab_expand (vtab, pat, pout);
- mu_vartab_destroy (&vtab);
+ if (ws.ws_wordc == 0)
+ /* FIXME: a special return code maybe? */
+ *pout = strdup ("");
+ else
+ *pout = strdup (ws.ws_wordv[0]);
+ mu_wordsplit_free (&ws);
+ if (!*pout)
+ return ENOMEM;
return rc;
}
diff --git a/libmailutils/server/acl.c b/libmailutils/server/acl.c
index d7a13629a..27d2352a1 100644
--- a/libmailutils/server/acl.c
+++ b/libmailutils/server/acl.c
@@ -36,7 +36,6 @@
#include <mailutils/error.h>
#include <mailutils/errno.h>
#include <mailutils/kwd.h>
-#include <mailutils/vartab.h>
#include <mailutils/io.h>
struct _mu_acl_entry
@@ -500,18 +499,12 @@ struct run_closure
unsigned idx;
mu_debug_t debug;
struct sockaddr *sa;
+ char *numbuf;
+ char *portbuf;
int salen;
mu_acl_result_t *result;
};
-static int
-_expand_aclno (const char *name, void *data, char **p)
-{
- struct run_closure *rp = data;
- /*FIXME: memory leak*/
- return mu_asprintf (p, "%u", rp->idx);
-}
-
#if defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX)
# define getmaxfd() sysconf (_SC_OPEN_MAX)
#elif defined (HAVE_GETDTABLESIZE)
@@ -520,52 +513,103 @@ _expand_aclno (const char *name, void *data, char **p)
# define getmaxfd() 64
#endif
-static int
-expand_arg (const char *cmdline, struct run_closure *rp, char **s)
+#define SEQ(s, n, l) \
+ (((l) == (sizeof(s) - 1)) && memcmp (s, n, l) == 0)
+
+static const char *
+acl_getvar (const char *name, size_t nlen, void *data)
{
- int rc;
- mu_vartab_t vtab;
-
- MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "Expanding \"%s\" => ", cmdline);
+ struct run_closure *rp = data;
+
+ if (SEQ ("aclno", name, nlen))
+ {
+ if (!rp->numbuf && mu_asprintf (&rp->numbuf, "%u", rp->idx))
+ return NULL;
+ return rp->numbuf;
+ }
- mu_vartab_create (&vtab);
- mu_vartab_define_exp (vtab, "aclno", _expand_aclno, NULL, rp);
switch (rp->sa->sa_family)
{
case AF_INET:
{
struct sockaddr_in *s_in = (struct sockaddr_in *)rp->sa;
- struct in_addr addr = s_in->sin_addr;
- char *p;
+
+ if (SEQ ("address", name, nlen))
+ {
+ struct in_addr addr = s_in->sin_addr;
+ addr.s_addr = htonl (addr.s_addr);
+ return inet_ntoa (addr);
+ }
+
+ if (SEQ ("port", name, nlen))
+ {
+ if (!rp->portbuf &&
+ mu_asprintf (&rp->portbuf, "%hu", ntohs (s_in->sin_port)))
+ return NULL;
+ return rp->portbuf;
+ }
+ break;
- mu_vartab_define (vtab, "family", "AF_INET", 1);
- addr.s_addr = htonl (addr.s_addr);
- mu_vartab_define (vtab, "address", inet_ntoa (addr), 0);
- if (mu_asprintf (&p, "%hu", ntohs (s_in->sin_port)) == 0)
+ case AF_UNIX:
+ if (SEQ ("address", name, nlen))
{
- mu_vartab_define (vtab, "port", p, 0);
- free (p);
+ struct sockaddr_un *s_un = (struct sockaddr_un *)rp->sa;
+ if (rp->salen == sizeof (s_un->sun_family))
+ return NULL;
+ else
+ return s_un->sun_path;
}
}
break;
-
+ }
+ return NULL;
+}
+
+static int
+expand_arg (const char *cmdline, struct run_closure *rp, char **s)
+{
+ int rc;
+ struct mu_wordsplit ws;
+ const char *env[3];
+
+ MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "Expanding \"%s\" => ", cmdline);
+ env[0] = "family";
+ switch (rp->sa->sa_family)
+ {
+ case AF_INET:
+ env[1] = "AF_INET";
+ break;
+
case AF_UNIX:
- {
- struct sockaddr_un *s_un = (struct sockaddr_un *)rp->sa;
-
- mu_vartab_define (vtab, "family", "AF_UNIX", 1);
- mu_vartab_define (vtab, "address", s_un->sun_path, 1);
- }
+ env[1] = "AF_UNIX";
break;
}
-
- rc = mu_vartab_expand (vtab, cmdline, s);
- mu_vartab_destroy (&vtab);
+ env[2] = NULL;
+ ws.ws_env = env;
+ ws.ws_getvar = acl_getvar;
+ ws.ws_closure = rp;
+ rc = mu_wordsplit (cmdline, &ws,
+ MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
+ MU_WRDSF_ENV | MU_WRDSF_ENV_KV |
+ MU_WRDSF_GETVAR | MU_WRDSF_CLOSURE);
if (rc == 0)
- MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "\"%s\". ", *s);
+ {
+ *s = strdup (ws.ws_wordv[0]);
+ mu_wordsplit_free (&ws);
+ if (!*s)
+ {
+ MU_DEBUG (rp->debug, MU_DEBUG_TRACE0, "failed: not enough memory. ");
+ return ENOMEM;
+ }
+ MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "\"%s\". ", *s);
+ }
else
- MU_DEBUG (rp->debug, MU_DEBUG_TRACE0, "failed. ");
+ {
+ MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "failed: %s",
+ mu_wordsplit_strerror (&ws));
+ rc = errno;
+ }
return rc;
}
@@ -744,7 +788,10 @@ mu_acl_check_sockaddr (mu_acl_t acl, const struct sockaddr *sa, int salen,
r.debug = acl->debug;
r.result = pres;
*r.result = mu_acl_result_undefined;
+ r.numbuf = r.portbuf = NULL;
mu_list_do (acl->aclist, _run_entry, &r);
+ free (r.numbuf);
+ free (r.portbuf);
free (r.sa);
return 0;
}
diff --git a/libmailutils/string/wordsplit.c b/libmailutils/string/wordsplit.c
index 563752c7f..a7ed93986 100644
--- a/libmailutils/string/wordsplit.c
+++ b/libmailutils/string/wordsplit.c
@@ -143,7 +143,7 @@ mu_wordsplit_init (struct mu_wordsplit *wsp, const char *input, size_t len,
if (wsp->ws_flags & MU_WRDSF_REUSE)
{
if (!(wsp->ws_flags & MU_WRDSF_APPEND))
- wsp->ws_wordc = 0;
+ mu_wordsplit_free_words (wsp);
}
else
{
@@ -1427,7 +1427,7 @@ mu_wordsplit (const char *command, struct mu_wordsplit *ws, int flags)
}
void
-mu_wordsplit_free (struct mu_wordsplit *ws)
+mu_wordsplit_free_words (struct mu_wordsplit *ws)
{
size_t i;
@@ -1435,8 +1435,18 @@ mu_wordsplit_free (struct mu_wordsplit *ws)
{
char *p = ws->ws_wordv[ws->ws_offs + i];
if (p)
- free (p);
+ {
+ free (p);
+ ws->ws_wordv[ws->ws_offs + i] = NULL;
+ }
}
+ ws->ws_wordc = 0;
+}
+
+void
+mu_wordsplit_free (struct mu_wordsplit *ws)
+{
+ mu_wordsplit_free_words (ws);
free (ws->ws_wordv);
ws->ws_wordv = NULL;
}
diff --git a/libmu_auth/ldap.c b/libmu_auth/ldap.c
index 435c99df4..5de7834ab 100644
--- a/libmu_auth/ldap.c
+++ b/libmu_auth/ldap.c
@@ -46,7 +46,6 @@
#include "mailutils/md5.h"
#include "mailutils/sha1.h"
#include "mailutils/ldap.h"
-#include "mailutils/vartab.h"
#include <ldap.h>
#include <lber.h>
@@ -504,33 +503,43 @@ _mu_ldap_search (LDAP *ld, const char *filter_pat, const char *key,
struct mu_auth_data **return_data)
{
int rc;
- char *filter;
char **attrs;
size_t nattrs;
LDAPMessage *res, *msg;
ber_int_t msgid;
- mu_vartab_t vtab;
+ const char *env[3];
+ struct mu_wordsplit ws;
rc = _construct_attr_array (&nattrs, &attrs);
if (rc)
return rc;
- mu_vartab_create (&vtab);
- mu_vartab_define (vtab, "user", key, 1);
- mu_vartab_define (vtab, "u", key, 1);
- rc = mu_vartab_expand (vtab, filter_pat, &filter);
- mu_vartab_destroy (&vtab);
- if (rc)
+ env[0] = "user";
+ env[1] = key;
+ env[3] = NULL;
+
+ ws.ws_env = env;
+ if (mu_wordsplit (filter_pat, &ws,
+ MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
+ MU_WRDSF_ENV | MU_WRDSF_ENV_KV))
+ {
+ mu_error (_("cannot expand line `%s': %s"), filter_pat,
+ mu_wordsplit_strerror (&ws));
+ return MU_ERR_FAILURE;
+ }
+ else if (ws.ws_wordc == 0)
{
+ mu_error (_("expanding %s yields empty string"), filter_pat);
+ mu_wordsplit_free (&ws);
mu_argcv_free (nattrs, attrs);
- return ENOMEM;
+ return MU_ERR_FAILURE;
}
-
+
rc = ldap_search_ext (ld, ldap_param.base, LDAP_SCOPE_SUBTREE,
- filter, attrs, 0,
+ ws.ws_wordv[0], attrs, 0,
NULL, NULL, NULL, -1, &msgid);
+ mu_wordsplit_free (&ws);
mu_argcv_free (nattrs, attrs);
- free (filter);
if (rc != LDAP_SUCCESS)
{
diff --git a/libmu_auth/radius.c b/libmu_auth/radius.c
index 8c8a64816..b7a7f2bee 100644
--- a/libmu_auth/radius.c
+++ b/libmu_auth/radius.c
@@ -40,7 +40,6 @@
#include <mailutils/error.h>
#include <mailutils/errno.h>
#include <mailutils/nls.h>
-#include <mailutils/vartab.h>
#include <mailutils/io.h>
#include <mailutils/cctype.h>
@@ -245,41 +244,38 @@ mu_radius_module_init (enum mu_gocs_op op, void *data)
static char *
_expand_query (const char *query, const char *ustr, const char *passwd)
{
- int rc;
- mu_vartab_t vtab;
- char *str, *ret;
-
- if (!query)
- return NULL;
-
- mu_vartab_create (&vtab);
- if (ustr)
- {
- mu_vartab_define (vtab, "user", ustr, 1);
- mu_vartab_define (vtab, "u", ustr, 1);
- }
-
- if (passwd)
+ struct mu_wordsplit ws;
+ const char *env[2 * 2 + 1];
+ char *ret;
+
+ env[0] = "user";
+ env[1] = (char*) ustr;
+ env[2] = "passwd";
+ env[3] = (char*) passwd;
+ env[4] = NULL;
+
+ ws.ws_env = env;
+ if (mu_wordsplit (query, &ws,
+ MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
+ MU_WRDSF_ENV | MU_WRDSF_ENV_KV))
{
- mu_vartab_define (vtab, "passwd", passwd, 1);
- mu_vartab_define (vtab, "p", passwd, 1);
+ mu_error (_("cannot expand line `%s': %s"), query,
+ mu_wordsplit_strerror (&ws));
+ return NULL;
}
-
- rc = mu_vartab_expand (vtab, query, &str);
- if (rc == 0)
+ else if (ws.ws_wordc == 0)
{
- ret = grad_emalloc (strlen (str) + 1);
- strcpy (ret, str);
- free (str);
+ mu_error (_("expanding %s yields empty string"), query);
+ mu_wordsplit_free (&ws);
+ return NULL;
}
- else
- ret = NULL;
-
- mu_vartab_destroy (&vtab);
+
+ ret = grad_emalloc (strlen (ws.ws_wordv[0]) + 1);
+ strcpy (ret, ws.ws_wordv[0]);
+ mu_wordsplit_free (&ws);
return ret;
}
-
static grad_avp_t *
create_request (grad_avp_t *template, const char *ustr, const char *passwd)
diff --git a/libmu_auth/sql.c b/libmu_auth/sql.c
index 744701fcf..e622470d2 100644
--- a/libmu_auth/sql.c
+++ b/libmu_auth/sql.c
@@ -49,7 +49,6 @@
#include <mailutils/nls.h>
#include <mailutils/util.h>
#include <mailutils/sql.h>
-#include <mailutils/vartab.h>
#include <mailutils/cstr.h>
#include "sql.h"
@@ -91,20 +90,34 @@ mu_sql_expand_query (const char *query, const char *ustr)
int rc;
char *res;
char *esc_ustr;
- mu_vartab_t vtab;
-
+ struct mu_wordsplit ws;
+ const char *env[2 + 1];
+
if (!query)
return NULL;
esc_ustr = sql_escape_string (ustr);
- mu_vartab_create (&vtab);
- mu_vartab_define (vtab, "user", ustr, 1);
- mu_vartab_define (vtab, "u", ustr, 1);
- rc = mu_vartab_expand (vtab, query, &res);
- if (rc)
- res = NULL;
- mu_vartab_destroy (&vtab);
-
+ env[0] = "user";
+ env[1] = (char*) ustr;
+ env[2] = NULL;
+
+ ws.ws_env = env;
+ if (mu_wordsplit (query, &ws,
+ MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
+ MU_WRDSF_ENV | MU_WRDSF_ENV_KV))
+ {
+ mu_error (_("cannot expand line `%s': %s"), query,
+ mu_wordsplit_strerror (&ws));
+ return NULL;
+ }
+ else if (ws.ws_wordc == 0)
+ {
+ mu_error (_("expanding %s yields empty string"), query);
+ mu_wordsplit_free (&ws);
+ return NULL;
+ }
+ res = strdup (ws.ws_wordv[0]);
+ mu_wordsplit_free (&ws);
free (esc_ustr);
return res;
}
diff --git a/libproto/mailer/prog.c b/libproto/mailer/prog.c
index 6a3c6157c..0a7428c86 100644
--- a/libproto/mailer/prog.c
+++ b/libproto/mailer/prog.c
@@ -32,7 +32,7 @@
#include <mailutils/message.h>
#include <mailutils/observer.h>
#include <mailutils/progmailer.h>
-#include <mailutils/vartab.h>
+#include <mailutils/wordsplit.h>
#include <mailutils/sys/url.h>
#include <mailutils/sys/mailer.h>
@@ -140,26 +140,24 @@ prog_close (mu_mailer_t mailer)
return mu_progmailer_close (mailer->data);
}
-static int
-_expand_sender (const char *name, void *data, char **p)
-{
- mu_address_t addr = data;
- char *email;
- int status = mu_address_aget_email (addr, 1, &email);
-
- if (status != 0)
- return status;
- *p = email;
- return 0;
-}
-
-struct ex_rcpt
+struct prog_exp
{
mu_message_t msg;
- mu_address_t addr;
- char *string;
+ mu_address_t sender_addr;
+ char *sender_str;
+ mu_address_t rcpt_addr;
+ char *rcpt_str;
};
+static const char *
+_expand_sender (struct prog_exp *pe)
+{
+ if (!pe->sender_str &&
+ mu_address_aget_email (pe->sender_addr, 1, &pe->sender_str))
+ return NULL;
+ return pe->sender_str;
+}
+
static int
address_add (mu_address_t *paddr, const char *value)
{
@@ -206,28 +204,27 @@ message_read_rcpt (mu_message_t msg, mu_address_t *paddr)
return 0;
}
-static int
-_expand_rcpt (const char *name, void *data, char **p)
+static const char *
+_expand_rcpt (struct prog_exp *pe)
{
- struct ex_rcpt *exrcpt = data;
int status;
- if (!exrcpt->string)
+ if (!pe->rcpt_str)
{
size_t i, count = 0;
size_t len = 0;
char *str;
mu_address_t tmp_addr = NULL, addr;
- if (exrcpt->addr)
- addr = exrcpt->addr;
+ if (pe->rcpt_addr)
+ addr = pe->rcpt_addr;
else
{
- status = message_read_rcpt (exrcpt->msg, &tmp_addr);
+ status = message_read_rcpt (pe->msg, &tmp_addr);
if (status)
{
mu_address_destroy (&tmp_addr);
- return status;
+ return NULL;
}
addr = tmp_addr;
}
@@ -241,7 +238,7 @@ _expand_rcpt (const char *name, void *data, char **p)
if ((status = mu_address_sget_email (addr, i, &email)) != 0)
{
mu_address_destroy (&tmp_addr);
- return status;
+ return NULL;
}
len += strlen (email);
}
@@ -250,9 +247,9 @@ _expand_rcpt (const char *name, void *data, char **p)
if (!str)
{
mu_address_destroy (&tmp_addr);
- return ENOMEM;
+ return NULL;
}
- exrcpt->string = str;
+ pe->rcpt_str = str;
for (i = 1; i <= count; i++)
{
@@ -267,14 +264,22 @@ _expand_rcpt (const char *name, void *data, char **p)
*str = 0;
mu_address_destroy (&tmp_addr);
}
- *p = exrcpt->string;
- return 0;
+ return pe->rcpt_str;
}
-void
-_free_rcpt (void *data, char *value)
+#define SEQ(s, n, l) \
+ (((l) == (sizeof(s) - 1)) && memcmp (s, n, l) == 0)
+
+static const char *
+prog_getvar (const char *name, size_t nlen, void *data)
{
- free (value);
+ struct prog_exp *pe = data;
+
+ if (SEQ ("sender", name, nlen))
+ return _expand_sender (pe);
+ if (SEQ ("rcpt", name, nlen))
+ return _expand_rcpt (pe);
+ return NULL;
}
static int
@@ -283,41 +288,58 @@ url_to_argv (mu_url_t url, mu_message_t msg,
int *pargc, char ***pargv)
{
int rc;
- mu_vartab_t vtab;
- struct ex_rcpt ex_rcpt;
+ struct prog_exp pe;
char **query;
size_t i;
size_t argc;
char **argv;
+ struct mu_wordsplit ws;
+ int wsflags;
- ex_rcpt.msg = msg;
- ex_rcpt.addr = to;
- ex_rcpt.string = NULL;
- mu_vartab_create (&vtab);
- mu_vartab_define_exp (vtab, "sender", _expand_sender, NULL, from);
- mu_vartab_define_exp (vtab, "rcpt", _expand_rcpt, _free_rcpt, &ex_rcpt);
+ pe.msg = msg;
+ pe.rcpt_addr = to;
+ pe.sender_addr = from;
+ pe.sender_str = pe.rcpt_str = NULL;
+
+ ws.ws_getvar = prog_getvar;
+ ws.ws_closure = &pe;
+ wsflags = MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
+ MU_WRDSF_GETVAR | MU_WRDSF_CLOSURE;
rc = mu_url_sget_query (url, &argc, &query);
if (rc)
return rc;
- argv = calloc (argc + 1, sizeof (argv[0]));
+ argv = calloc (argc + 2, sizeof (argv[0]));
if (!argv)
return ENOMEM;
+ rc = mu_url_aget_path (url, &argv[0]);
+ if (rc)
+ {
+ free (argv);
+ return rc;
+ }
+
for (i = 0; i < argc; i++)
{
- if ((rc = mu_vartab_expand (vtab, query[i], &argv[i])))
+ if (mu_wordsplit (query[i], &ws, wsflags))
{
mu_argcv_free (i, argv);
- mu_vartab_destroy (&vtab);
- return rc;
+ mu_wordsplit_free (&ws);
+ return errno;
}
+ if (ws.ws_wordc == 0)
+ argv[i+1] = strdup ("");
+ else
+ argv[i+1] = strdup (ws.ws_wordv[0]);
+ wsflags |= MU_WRDSF_REUSE;
}
- argv[i] = NULL;
+ argv[i+1] = NULL;
+ mu_wordsplit_free (&ws);
+ free (pe.sender_str);
+ free (pe.rcpt_str);
- mu_vartab_destroy (&vtab);
-
*pargc = argc;
*pargv = argv;
return 0;
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2201ad13d..c23e197fc 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -140,6 +140,7 @@ libmailutils/server/ipsrv.c
libmailutils/server/msrv.c
libmailutils/mailbox/message.c
+libmailutils/mailbox/mbx_default.c
libmailutils/mailer/mailer.c
libmailutils/mailer/smtp.c
libmailutils/mailer/smtp_gsasl.c

Return to:

Send suggestions and report system problems to the System administrator.