diff options
-rw-r--r-- | imap4d/imap4d.c | 39 | ||||
-rw-r--r-- | imap4d/imap4d.h | 1 | ||||
-rw-r--r-- | imap4d/preauth.c | 114 | ||||
-rw-r--r-- | libmailutils/mailbox/mbx_default.c | 31 | ||||
-rw-r--r-- | libmailutils/server/acl.c | 121 | ||||
-rw-r--r-- | libmailutils/string/wordsplit.c | 16 | ||||
-rw-r--r-- | libmu_auth/ldap.c | 35 | ||||
-rw-r--r-- | libmu_auth/radius.c | 54 | ||||
-rw-r--r-- | libmu_auth/sql.c | 35 | ||||
-rw-r--r-- | libproto/mailer/prog.c | 118 | ||||
-rw-r--r-- | po/POTFILES.in | 1 |
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 |