commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. release-2.2-170-gc66e1b8


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-170-gc66e1b8
Date: Sat, 30 Oct 2010 15:20:49 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=c66e1b8de8fd661a34f03734cbb0a559324c3075

The branch, master has been updated
       via  c66e1b8de8fd661a34f03734cbb0a559324c3075 (commit)
      from  63fec21357c175772a8ca153266919c12b6f8bd5 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c66e1b8de8fd661a34f03734cbb0a559324c3075
Author: Sergey Poznyakoff <address@hidden>
Date:   Sat Oct 30 17:42:59 2010 +0300

    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.

-----------------------------------------------------------------------

Summary of changes:
 imap4d/imap4d.c                    |   39 ++++++++----
 imap4d/imap4d.h                    |    1 -
 imap4d/preauth.c                   |  114 +++++++++++++++++++--------------
 libmailutils/mailbox/mbx_default.c |   31 ++++++++--
 libmailutils/server/acl.c          |  121 +++++++++++++++++++++++++-----------
 libmailutils/string/wordsplit.c    |   16 ++++-
 libmu_auth/ldap.c                  |   35 +++++++----
 libmu_auth/radius.c                |   54 ++++++++---------
 libmu_auth/sql.c                   |   35 +++++++---
 libproto/mailer/prog.c             |  118 +++++++++++++++++++++--------------
 po/POTFILES.in                     |    1 +
 11 files changed, 356 insertions(+), 209 deletions(-)

diff --git a/imap4d/imap4d.c b/imap4d/imap4d.c
index cbadb83..844b953 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 26e9fc3..598bc58 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 1584df4..014da68 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 468230a..c36e682 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 d7a1362..27d2352 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 563752c..a7ed939 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 435c99d..5de7834 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 8c8a648..b7a7f2b 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 744701f..e622470 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 6a3c615..0a7428c 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 2201ad1..c23e197 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


hooks/post-receive
-- 
GNU Mailutils



reply via email to

[Prev in Thread] Current Thread [Next in Thread]