Commit c66e1b8d c66e1b8de8fd661a34f03734cbb0a559324c3075 by Sergey Poznyakoff

Remove all uses of vartab, replacing them with wordsplit.

* libmailutils/string/wordsplit.c (mu_wordsplit_init): Call
mu_wordsplit_free_words to reclaim the memory.
(mu_wordsplit_free_words): New function.
(mu_wordsplit_free): Use mu_wordsplit_free_words.

* imap4d/imap4d.c (imap4d_session_setup0): Use wordsplit instead of
vartab.
* imap4d/imap4d.h: Don't include vartab.h.
* imap4d/preauth.c (do_preauth_ident): Use mu_str_stripws instead of
the static trimcrlf, which is removed.
(do_preauth_program): Use wordsplit instead of
vartab and mu_prog_stream_create instead of popen.
* libmailutils/mailbox/mbx_default.c: Include nls.h
Don't include vartab.h
(mu_construct_user_mailbox_url): Use wordsplit instead of
vartab.
* libmailutils/server/acl.c (expand_arg): Use wordsplit instead of
vartab.
* libmu_auth/ldap.c (_mu_ldap_search):L Likewise.
* libmu_auth/radius.c (_expand_query): Likewise.
* libmu_auth/sql.c (mu_sql_expand_query): Likewise.
* libproto/mailer/prog.c (_expand_sender, _expand_rcpt): Rewrite.
(url_to_argv): : Use wordsplit instead of
vartab.

* po/POTFILES.in: Add more files.
1 parent 63fec213
......@@ -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))
{
free (real_homedir);
mu_diag_funcall (MU_DIAG_ERROR, "mu_vartab_expand",
modify_homedir, rc);
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)
{
mu_error ("%s", mu_strerror (errno));
return 1;
}
}
......
......@@ -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>
......
......@@ -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);
}
rc = mu_vartab_expand (vtab, preauth_program, &cmd);
mu_vartab_destroy (&vtab);
if (rc)
mu_wordsplit_free (&ws);
mu_error (_("`%s' expands to an empty line"), preauth_program);
return NULL;
}
fp = popen (cmd, "r");
free (cmd);
rc = getline (&buf, &size, fp);
pclose (fp);
if (rc > 0)
{
if (trimcrlf (buf) == 0)
rc = mu_prog_stream_create (&str, ws.ws_wordv[0], MU_STREAM_READ);
mu_wordsplit_free (&ws);
if (rc)
{
free (buf);
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;
......
......@@ -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;
}
......
......@@ -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;
struct run_closure *rp = data;
MU_DEBUG1 (rp->debug, MU_DEBUG_TRACE0, "Expanding \"%s\" => ", cmdline);
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;
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)
if (SEQ ("address", name, nlen))
{
mu_vartab_define (vtab, "port", p, 0);
free (p);
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;
case AF_UNIX:
if (SEQ ("address", name, nlen))
{
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);
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;
rc = mu_vartab_expand (vtab, cmdline, s);
mu_vartab_destroy (&vtab);
case AF_UNIX:
env[1] = "AF_UNIX";
break;
}
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)
{
*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;
}
......
......@@ -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);
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;
}
......
......@@ -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)
{
......
......@@ -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,42 +244,39 @@ 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)
{
......
......@@ -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;
}
......
......@@ -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,40 +288,57 @@ 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;
pe.msg = msg;
pe.rcpt_addr = to;
pe.sender_addr = from;
pe.sender_str = pe.rcpt_str = NULL;
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);
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;
mu_vartab_destroy (&vtab);
argv[i+1] = NULL;
mu_wordsplit_free (&ws);
free (pe.sender_str);
free (pe.rcpt_str);
*pargc = argc;
*pargv = argv;
......
......@@ -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
......