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-3.1.1-40-g9ba835f


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-3.1.1-40-g9ba835f
Date: Thu, 19 Jan 2017 07:15:02 +0000 (UTC)

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=9ba835fbb5a937735f51925c2170bbc748820fcf

The branch, master has been updated
       via  9ba835fbb5a937735f51925c2170bbc748820fcf (commit)
       via  012c66ddbbf4c852f2f26e1c075e7ddb808559c1 (commit)
      from  447719f64f327cb136b835b318294c23ebe0f16c (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 9ba835fbb5a937735f51925c2170bbc748820fcf
Author: Sergey Poznyakoff <address@hidden>
Date:   Wed Jan 18 17:39:16 2017 +0200

    Provide functions for expanding string using mu_assoc_t table.
    
    The functions are used wherever variables can be expected, most
    notably in configuration statements, such as ldap, namespace (imap4d),
    etc.  Apart from expanding variables it also provides command
    expansion $(command args...)
    
    The commands currently available are:
    
      domainpart ARG       splits its argument on the first occurrence of @
                           and returns the part after it.
      localpart ARG        splits its argument on the first occurrence of @
                           and returns the part before it.
      shell CMD ARG...     runs shell command CMD and returns its output
    
    * include/mailutils/cstr.h (mu_str_expand, mu_str_vexpand): New protos.
    * libmailutils/string/expvar.c: New file.
    * libmailutils/string/Makefile.am: Add expvar.c
    
    * libmailutils/tests/exp.c: New file.
    * libmailutils/tests/Makefile.am: Add exp.c
    
    * imap4d/imap4d.c (namespace_cfg_init): Fix docstring.
    * imap4d/namespace.c (namespace_translate_name): Use mu_str_expand.
    
    * libmailutils/mailbox/mbx_default.c (mu_construct_user_mailbox_url):
    Use mu_str_vexpand.
    * libmu_auth/ldap.c (_mu_ldap_search): Likewise.
    * libmu_auth/radius.c (_expand_query): Likewise.
    * libmu_auth/sql.c (mu_sql_expand_query): Likewise.
    
    * mu/shell.c (mutool_prompt_env): Remove.
    (shell_prompt): Rewrite
    (input_line_interactive): Use mu_str_expand.
    (mutool_shell_prompt_assoc): New function.
    * mu/mu.h (mutool_shell_prompt_assoc): New proto.
    * mu/imap.c (imap_prompt_env): Use mutool_shell_prompt_assoc.
    * mu/pop.c (pop_prompt_env): Likewise.
    * mu/smtp.c (smtp_prompt_env): Likewise.

commit 012c66ddbbf4c852f2f26e1c075e7ddb808559c1
Author: Sergey Poznyakoff <address@hidden>
Date:   Wed Jan 18 17:38:23 2017 +0200

    Minor change
    
    * libmailutils/mime/mime.c: Fix formatting

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

Summary of changes:
 imap4d/imap4d.c                    |    1 +
 imap4d/namespace.c                 |   82 ++++-----
 include/mailutils/cstr.h           |    3 +
 libmailutils/mailbox/mbx_default.c |   32 ++--
 libmailutils/mime/mime.c           |  110 ++++++------
 libmailutils/string/Makefile.am    |    1 +
 libmailutils/string/expvar.c       |  341 ++++++++++++++++++++++++++++++++++++
 libmailutils/tests/Makefile.am     |    1 +
 libmailutils/tests/exp.c           |   51 ++++++
 libmu_auth/ldap.c                  |   40 ++---
 libmu_auth/radius.c                |   39 ++---
 libmu_auth/sql.c                   |   32 ++--
 mu/imap.c                          |   43 ++---
 mu/mu.h                            |    2 +-
 mu/pop.c                           |   34 +---
 mu/shell.c                         |   64 ++++---
 mu/smtp.c                          |   33 +---
 17 files changed, 611 insertions(+), 298 deletions(-)
 create mode 100644 libmailutils/string/expvar.c
 create mode 100644 libmailutils/tests/exp.c

diff --git a/imap4d/imap4d.c b/imap4d/imap4d.c
index eca84c9..ceded08 100644
--- a/imap4d/imap4d.c
+++ b/imap4d/imap4d.c
@@ -517,6 +517,7 @@ namespace_cfg_init (void)
   if (mu_create_canned_section ("prefix", &section))
     abort ();
   section->docstring = N_("Define a single prefix");
+  section->label = N_("string");
   mu_cfg_section_add_params (section, prefix_param);
   section->parser = prefix_section_parser;
   
diff --git a/imap4d/namespace.c b/imap4d/namespace.c
index cf5e550..242549a 100644
--- a/imap4d/namespace.c
+++ b/imap4d/namespace.c
@@ -153,28 +153,6 @@ namespace_init (void)
   mu_assoc_sort_r (prefixes, cmplen, NULL);
 }
       
-static int
-expand_vars (char **env, char const *input, char **output)
-{
-  struct mu_wordsplit ws;
-  size_t wordc;
-  char **wordv;
-  
-  ws.ws_env = (const char **) env;
-  if (mu_wordsplit (input, &ws,
-                   MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
-                   MU_WRDSF_ENV | MU_WRDSF_ENV_KV))
-    {
-      mu_error (_("cannot expand line `%s': %s"), input,
-               mu_wordsplit_strerror (&ws));
-      return 1;
-    }
-  mu_wordsplit_get_words (&ws, &wordc, &wordv);
-  *output = wordv[0];
-  mu_wordsplit_free (&ws);
-  return 0;
-}
-
 static char *
 prefix_translate_name (struct namespace_prefix const *pfx, char const *name,
                       size_t namelen, int url)
@@ -290,23 +268,12 @@ extract_username (char const *name, struct 
namespace_prefix const *pfx)
   return user;
 }
 
-enum
-  {
-    ENV_USER = 1,
-    ENV_HOME = 3,
-    ENV_NULL = 4
-  };
-
-#define ENV_INITIALIZER \
-  { [ENV_USER-1] = "user", [ENV_HOME-1] = "home", [ENV_NULL] = NULL }
-
 char *
 namespace_translate_name (char const *name, int url,
                          struct namespace_prefix const **return_pfx)
 {
   char *res = NULL;
   struct namespace_prefix const *pfx;
-  char *env[] = ENV_INITIALIZER;
   
   if (mu_c_strcasecmp (name, "INBOX") == 0 && auth_data->change_uid)
     {
@@ -318,44 +285,65 @@ namespace_translate_name (char const *name, int url,
 
   if (res)
     {
+      mu_assoc_t assoc;
+      int rc;
       char *dir;
       
+      rc = mu_assoc_create (&assoc, 0);
+      if (rc)
+       {
+         mu_diag_funcall (MU_DIAG_ERROR, "mu_assoc_create", NULL, rc);
+         free (res);
+         imap4d_bye (ERR_NO_MEM);
+       }
+      
       switch (pfx->ns)
        {
        case NS_PRIVATE:
-         env[ENV_USER] = auth_data->name;
-         env[ENV_HOME] = real_homedir;
+         mu_assoc_install (assoc, "user", auth_data->name);
+         mu_assoc_install (assoc, "home", real_homedir);
          break;
 
        case NS_OTHER:
          {
            struct mu_auth_data *adata;
-           env[ENV_USER] = extract_username (name, pfx);
-           adata = mu_get_auth_by_name (env[ENV_USER]);
+           char *user = extract_username (name, pfx);
+           mu_assoc_install (assoc, "user", user);
+           adata = mu_get_auth_by_name (user);
            if (adata)
              {
-               env[ENV_HOME] = mu_strdup (adata->dir);
+               mu_assoc_install (assoc, "home", mu_strdup (adata->dir));
                mu_auth_data_free (adata);
              }
+           mu_assoc_set_destroy_item (assoc, mu_list_free_item);
          }
          break;
 
        case NS_SHARED:
          break;
        }
-      
-      if (expand_vars (env, res, &dir))
-       imap4d_bye (ERR_NO_MEM);
+
+      rc = mu_str_expand (&dir, res, assoc);
       free (res);
-      res = dir;
-      trim_delim (res, '/');
-      
-      if (pfx->ns == NS_OTHER)
+      mu_assoc_destroy (&assoc);
+      if (rc)
        {
-         free (env[ENV_USER]);
-         free (env[ENV_HOME]);
+         if (rc == MU_ERR_FAILURE)
+           {
+             mu_error (_("cannot expand line `%s': %s"), res, dir);
+             free (dir);
+           }
+         else
+           {
+             mu_error (_("cannot expand line `%s': %s"), res,
+                       mu_strerror (rc));
+           }
+         imap4d_bye (ERR_NO_MEM);
        }
       
+      res = dir;
+      trim_delim (res, '/');
+      
       if (return_pfx)
        *return_pfx = pfx;
     }
diff --git a/include/mailutils/cstr.h b/include/mailutils/cstr.h
index 6ad3317..ec909d3 100644
--- a/include/mailutils/cstr.h
+++ b/include/mailutils/cstr.h
@@ -58,6 +58,9 @@ int mu_c_str_unescape (char const *str, char const *chr, char 
const *xtab,
 int mu_c_str_unescape_trans (char const *str, char const *trans,
                             char **ret_str);
 
+
+int mu_str_expand (char **output, char const *input, mu_assoc_t assoc);
+int mu_str_vexpand (char **output, char const *input, ...);
   
 #ifdef __cplusplus
 }
diff --git a/libmailutils/mailbox/mbx_default.c 
b/libmailutils/mailbox/mbx_default.c
index 6ece825..dad9535 100644
--- a/libmailutils/mailbox/mbx_default.c
+++ b/libmailutils/mailbox/mbx_default.c
@@ -38,7 +38,7 @@
 #include <mailutils/mu_auth.h>
 #include <mailutils/folder.h>
 #include <mailutils/auth.h>
-#include <mailutils/wordsplit.h>
+#include <mailutils/cstr.h>
 #include <mailutils/io.h>
 
 #include <mailutils/sys/mailbox.h>
@@ -158,32 +158,22 @@ mu_construct_user_mailbox_url (char **pout, const char 
*name)
 {
   int rc;
   const char *pat = mu_mailbox_url ();
-  const char *env[3];
-  struct mu_wordsplit ws;
-
-  env[0] = "user";
-  env[1] = (char*) name;
-  env[2] = NULL;
-  ws.ws_env = env;
-  rc = mu_wordsplit (pat, &ws,
-                    MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
-                    MU_WRDSF_ENV | MU_WRDSF_ENV_KV);
+  char *result;
     
+  rc = mu_str_vexpand (&result, pat, "user", name, NULL);
   if (rc)
     {
-      mu_error (_("cannot expand line `%s': %s"), pat,
-               mu_wordsplit_strerror (&ws));
+      if (rc == MU_ERR_FAILURE)
+       {
+         mu_error (_("cannot expand line `%s': %s"), pat, result);
+         free (result);
+       }
+      else
+       mu_error (_("cannot expand line `%s': %s"), pat, mu_strerror (rc));
       return rc;
     }
 
-  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;
+  *pout = result;
   return 0;
 }
 
diff --git a/libmailutils/mime/mime.c b/libmailutils/mime/mime.c
index 968ada8..2ba565d 100644
--- a/libmailutils/mime/mime.c
+++ b/libmailutils/mime/mime.c
@@ -70,9 +70,9 @@ _mime_append_part (mu_mime_t mime, mu_message_t msg,
                   size_t offset, size_t len, size_t lines)
 {
   struct _mime_part *mime_part, **part_arr;
-  int             ret;
-  size_t          size;
-  mu_header_t     hdr;
+  int ret;
+  size_t size;
+  mu_header_t hdr;
 
   if ((mime_part = calloc (1, sizeof (*mime_part))) == NULL)
     return ENOMEM;
@@ -147,8 +147,8 @@ _mime_append_part (mu_mime_t mime, mu_message_t msg,
 static void
 _mime_munge_content_header (char *field_body)
 {
-  char           *p, *e, *str = field_body;
-  int             quoted = 0;
+  char *p, *e, *str = field_body;
+  int quoted = 0;
 
   mu_str_stripws (field_body);
 
@@ -184,8 +184,8 @@ _mime_munge_content_header (char *field_body)
 static char    *
 _mime_get_param (char *field_body, const char *param, int *len)
 {
-  char           *str, *p, *v, *e;
-  int             quoted = 0, was_quoted;
+  char *str, *p, *v, *e;
+  int quoted = 0, was_quoted;
 
   if (len == NULL || (str = field_body) == NULL)
     return NULL;
@@ -242,11 +242,10 @@ _mime_append_header_line (mu_mime_t mime)
 {
   if (mime->header_length + mime->line_ndx > mime->header_buf_size)
     {
-      char           *nhb;
+      char *nhb;
 
-      if ((nhb =
-          realloc (mime->header_buf,
-                   mime->header_length + mime->line_ndx + 128)) == NULL)
+      if ((nhb = realloc (mime->header_buf,
+                         mime->header_length + mime->line_ndx + 128)) == NULL)
        return;
       mime->header_buf = nhb;
       mime->header_buf_size = mime->header_length + mime->line_ndx + 128;
@@ -259,20 +258,20 @@ _mime_append_header_line (mu_mime_t mime)
 static int
 _mime_parse_mpart_message (mu_mime_t mime)
 {
-  char           *cp, *cp2;
-  size_t         blength, mb_length, mb_offset, mb_lines;
-  int            ret;
-  size_t         nbytes;
+  char *cp, *cp2;
+  size_t blength, mb_length, mb_offset, mb_lines;
+  int ret;
+  size_t nbytes;
 
   if (!(mime->flags & MIME_PARSER_ACTIVE))
     {
-      char           *boundary;
-      int             len;
+      char *boundary;
+      int len;
 
       if ((ret = _mime_setup_buffers (mime)) != 0)
        return ret;
-      if ((boundary =
-          _mime_get_param (mime->content_type, "boundary", &len)) == NULL)
+      if ((boundary = _mime_get_param (mime->content_type, "boundary", &len))
+         == NULL)
        return EINVAL;
       if ((mime->boundary = calloc (1, len + 1)) == NULL)
        return ENOMEM;
@@ -289,9 +288,8 @@ _mime_parse_mpart_message (mu_mime_t mime)
   blength = strlen (mime->boundary);
 
   mu_stream_seek (mime->stream, mime->cur_offset, MU_SEEK_SET, NULL);
-  while ((ret =
-         mu_stream_read (mime->stream, mime->cur_buf, mime->buf_size,
-                         &nbytes)) == 0 && nbytes)
+  while ((ret = mu_stream_read (mime->stream, mime->cur_buf, mime->buf_size,
+                               &nbytes)) == 0 && nbytes)
     {
       cp = mime->cur_buf;
       while (nbytes)
@@ -308,9 +306,8 @@ _mime_parse_mpart_message (mu_mime_t mime)
                  break;
 
                case MIME_STATE_SCAN_BOUNDARY:
-                 cp2 =
-                   mime->cur_line[0] ==
-                   '\n' ? mime->cur_line + 1 : mime->cur_line;
+                 cp2 = mime->cur_line[0] == '\n'
+                       ? mime->cur_line + 1 : mime->cur_line;
                  if (mime->line_ndx >= blength)
                    {
                      if ((!strncmp (cp2, "--", 2)
@@ -423,7 +420,7 @@ _mime_parse_mpart_message (mu_mime_t mime)
 static int
 _mimepart_body_size (mu_body_t body, size_t *psize)
 {
-  mu_message_t       msg = mu_body_get_owner (body);
+  mu_message_t msg = mu_body_get_owner (body);
   struct _mime_part *mime_part = mu_message_get_owner (msg);
 
   if (mime_part == NULL)
@@ -436,7 +433,7 @@ _mimepart_body_size (mu_body_t body, size_t *psize)
 static int
 _mimepart_body_lines (mu_body_t body, size_t *plines)
 {
-  mu_message_t       msg = mu_body_get_owner (body);
+  mu_message_t msg = mu_body_get_owner (body);
   struct _mime_part *mime_part = mu_message_get_owner (msg);
 
   if (mime_part == NULL)
@@ -451,9 +448,9 @@ static int
 _mime_set_content_type (mu_mime_t mime)
 {
   const char  *content_type;
-  mu_header_t     hdr = NULL;
-  size_t          size;
-  int             ret;
+  mu_header_t hdr = NULL;
+  size_t size;
+  int ret;
 
   /* Delayed the creation of the header 'til they create the final message via
      mu_mime_get_message()  */
@@ -657,12 +654,13 @@ _mime_body_stream_seek (mu_stream_t stream, mu_off_t off, 
mu_off_t *presult)
   while (0)
 
 static int
-_mime_body_stream_read (mu_stream_t stream, char *buf, size_t buflen, size_t 
*nbytes)
+_mime_body_stream_read (mu_stream_t stream, char *buf, size_t buflen,
+                       size_t *nbytes)
 {
   struct _mime_body_stream *mstr = (struct _mime_body_stream *)stream;
   mu_mime_t mime = mstr->mime;
-  int                ret = 0;
-  size_t             total = 0;
+  int ret = 0;
+  size_t total = 0;
   
   if (mime->nmtp_parts == 0)
     {
@@ -674,7 +672,7 @@ _mime_body_stream_read (mu_stream_t stream, char *buf, 
size_t buflen, size_t *nb
     {
       do
        {
-         size_t             part_nbytes = 0;
+         size_t part_nbytes = 0;
 
          if (buflen == 0)
            break;
@@ -847,18 +845,18 @@ create_mime_body_stream (mu_stream_t *pstr, mu_mime_t 
mime)
 static int
 _mime_body_size (mu_body_t body, size_t *psize)
 {
-  mu_message_t       msg = mu_body_get_owner (body);
-  mu_mime_t          mime = mu_message_get_owner (msg);
+  mu_message_t msg = mu_body_get_owner (body);
+  mu_mime_t mime = mu_message_get_owner (msg);
   return _mime_part_size (mime, psize);
 }
 
 static int
 _mime_body_lines (mu_body_t body, size_t *plines)
 {
-  mu_message_t       msg = mu_body_get_owner (body);
-  mu_mime_t          mime = mu_message_get_owner (msg);
-  int             i, ret;
-  size_t          total = 0;
+  mu_message_t msg = mu_body_get_owner (body);
+  mu_mime_t mime = mu_message_get_owner (msg);
+  int i, ret;
+  size_t total = 0;
 
   if (mime->nmtp_parts == 0)
     {
@@ -884,10 +882,10 @@ _mime_body_lines (mu_body_t body, size_t *plines)
 int
 mu_mime_create (mu_mime_t *pmime, mu_message_t msg, int flags)
 {
-  mu_mime_t          mime = NULL;
-  int             ret = 0;
-  size_t          size;
-  mu_body_t          body;
+  mu_mime_t mime = NULL;
+  int ret = 0;
+  size_t size;
+  mu_body_t body;
 
   if (pmime == NULL)
     return EINVAL;
@@ -898,10 +896,9 @@ mu_mime_create (mu_mime_t *pmime, mu_message_t msg, int 
flags)
     {
       if ((ret = mu_message_get_header (msg, &mime->hdrs)) == 0)
        {
-         if ((ret =
-              mu_header_get_value (mime->hdrs,
-                                   MU_HEADER_CONTENT_TYPE,
-                                   NULL, 0, &size)) == 0 && size)
+         if ((ret = mu_header_get_value (mime->hdrs,
+                                         MU_HEADER_CONTENT_TYPE,
+                                         NULL, 0, &size)) == 0 && size)
            {
              if ((mime->content_type = malloc (size + 1)) == NULL)
                ret = ENOMEM;
@@ -1039,9 +1036,10 @@ mu_mime_get_part (mu_mime_t mime, size_t part, 
mu_message_t *msg)
              if (ret == 0)
                {
                  mu_stream_set_flags (stream,
-                                      MU_STREAM_READ | (flags &
-                                                        (MU_STREAM_SEEK
-                                                         | 
MU_STREAM_NONBLOCK)));
+                                      MU_STREAM_READ
+                                      | (flags &
+                                         (MU_STREAM_SEEK
+                                          | MU_STREAM_NONBLOCK)));
                  mu_body_set_stream (body, stream, mime_part->msg);
                  mu_message_set_body (mime_part->msg, body, mime_part);
                  mime_part->body_created = 1;
@@ -1079,8 +1077,8 @@ mu_mime_get_num_parts (mu_mime_t mime, size_t *nmtp_parts)
 int
 mu_mime_add_part (mu_mime_t mime, mu_message_t msg)
 {
-  int             ret;
-
+  int ret;
+  
   if (mime == NULL || msg == NULL || (mime->flags & MIME_NEW_MESSAGE) == 0)
     return EINVAL;
   if ((ret = _mime_append_part (mime, msg, 0, 0, 0)) == 0)
@@ -1091,9 +1089,9 @@ mu_mime_add_part (mu_mime_t mime, mu_message_t msg)
 int
 mu_mime_get_message (mu_mime_t mime, mu_message_t *msg)
 {
-  mu_stream_t        body_stream;
-  mu_body_t          body;
-  int                ret = 0;
+  mu_stream_t body_stream;
+  mu_body_t body;
+  int ret = 0;
 
   if (mime == NULL || msg == NULL)
     return EINVAL;
diff --git a/libmailutils/string/Makefile.am b/libmailutils/string/Makefile.am
index 035accf..76d8421 100644
--- a/libmailutils/string/Makefile.am
+++ b/libmailutils/string/Makefile.am
@@ -25,6 +25,7 @@ libstring_la_SOURCES = \
  cstrunescape.c\
  cstrlower.c\
  cstrupper.c\
+ expvar.c\
  hexstr.c\
  safefilename.c\
  stpcpy.c\
diff --git a/libmailutils/string/expvar.c b/libmailutils/string/expvar.c
new file mode 100644
index 0000000..a9361ef
--- /dev/null
+++ b/libmailutils/string/expvar.c
@@ -0,0 +1,341 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 1999-2003, 2005-2007, 2009-2012, 2014-2017 Free
+   Software Foundation, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General
+   Public License along with this library.  If not, see 
+   <http://www.gnu.org/licenses/>. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mailutils/errno.h>
+#include <mailutils/error.h>
+#include <mailutils/io.h>
+#include <mailutils/nls.h>
+#include <mailutils/assoc.h>
+#include <mailutils/cstr.h>
+#include <mailutils/cctype.h>
+#include <mailutils/wordsplit.h>
+
+static int
+exp_getvar (char **ret, const char *vptr, size_t vlen, void *data)
+{
+  int rc;
+  char *varname, *s = NULL;
+  mu_assoc_t assoc = data;
+  
+  if (mu_assoc_is_empty (assoc))
+    return MU_WRDSE_UNDEF;
+
+  varname = malloc (vlen + 1);
+  if (!varname)
+    return MU_WRDSE_NOSPACE;
+  memcpy (varname, vptr, vlen);
+  varname[vlen] = 0;
+
+  rc = mu_assoc_lookup (assoc, varname, &s);
+  free (varname);
+
+  switch (rc)
+    {
+    case 0:
+      rc = MU_WRDSE_OK;
+      break;
+      
+    case MU_ERR_NOENT:
+      rc = MU_WRDSE_UNDEF;
+      break;
+
+    case MU_ERR_BUFSPACE:
+    case ENOMEM:
+      rc = MU_WRDSE_NOSPACE;
+      break;
+
+    default:
+      s = (char*) mu_strerror (rc);
+      rc = MU_WRDSE_USERERR;
+    }
+
+  if (s)
+    {
+      s = strdup (s);
+      if (!s)
+       return MU_WRDSE_NOSPACE;
+      *ret = s;
+    }
+  
+  return rc;
+}
+
+static int
+exp_localpart (int argc, char **argv, char **result)
+{
+  size_t len = strcspn (argv[1], "@");
+  char *s;
+
+  s = malloc (len + 1);
+  if (!s)
+    return MU_WRDSE_NOSPACE;
+  memcpy (s, argv[1], len);
+  s[len] = 0;
+
+  *result = s;
+  return MU_WRDSE_OK;
+}
+
+static int
+exp_domainpart (int argc, char **argv, char **result)
+{
+  char *s = strchr (argv[1], '@');
+
+  if (s)
+    s++;
+  else
+    s = "";
+
+  s = strdup (s);
+  if (!s)
+    return MU_WRDSE_NOSPACE;
+  
+  *result = s;
+  
+  return MU_WRDSE_OK;
+}
+
+static int
+exp_shell (char **ret, char const *str, size_t len, void *closure)
+{
+  FILE *fp;
+  char *cmd;
+  int c, lastc;
+  char *buffer = NULL;
+  size_t bufsize = 0;
+  size_t buflen = 0;
+  
+  cmd = malloc (len + 1);
+  if (!cmd)
+    return MU_WRDSE_NOSPACE;
+  memcpy (cmd, str, len);
+  cmd[len] = 0;
+
+  fp = popen (cmd, "r");
+  if (!fp)
+    {
+      ret = NULL;
+      if (mu_asprintf (ret, "can't run %s: %s", cmd, mu_strerror (errno)))
+       return MU_WRDSE_NOSPACE;
+      else
+       return MU_WRDSE_USERERR;
+    }
+
+  while ((c = fgetc (fp)) != EOF)
+    {
+      lastc = c;
+      if (c == '\n')
+       c = ' ';
+      if (buflen == bufsize)
+       {
+         char *p;
+         
+         if (bufsize == 0)
+           bufsize = 80;
+         else
+           bufsize *= 2;
+         p = realloc (buffer, bufsize);
+         if (!p)
+           {
+             free (buffer);
+             free (cmd);
+             return MU_WRDSE_NOSPACE;
+           }
+         buffer = p;
+       }
+      buffer[buflen++] = c;
+    }
+
+  if (buffer)
+    {
+      if (lastc == '\n')
+       --buflen;
+      buffer[buflen] = 0;
+    }
+  
+  pclose (fp);
+  free (cmd);
+
+  *ret = buffer;
+  return MU_WRDSE_OK;  
+}
+
+struct exp_command
+{
+  char *name;
+  int minarg;
+  int maxarg;
+  int (*exp) (int argc, char **argv, char **ret);
+};
+
+static struct exp_command exp_command_tab[] = {
+  { "localpart", 2, 2, exp_localpart },
+  { "domainpart", 2, 2, exp_domainpart },
+  { NULL }
+};
+
+static struct exp_command *
+findcom (char const *name)
+{
+  struct exp_command *cp;
+
+  for (cp = exp_command_tab; cp->name; cp++)
+    if (strcmp (name, cp->name) == 0)
+      return cp;
+
+  return NULL;
+}
+
+static int
+checkargc (struct exp_command *cmd, int argc)
+{
+  if (cmd->minarg && argc < cmd->minarg)
+    return 1;
+  else if (cmd->maxarg && argc > cmd->maxarg)
+    return 1;
+  return 0;
+}
+
+#define SHELL_CMD "shell"
+
+static int
+exp_runcmd (char **ret, const char *str, size_t len, char **argv, void 
*closure)
+{
+  int argc;
+  struct exp_command *cmd;
+  char *result = NULL;
+  int rc;
+
+  if (strcmp (argv[0], SHELL_CMD) == 0)
+    {
+      len -= sizeof SHELL_CMD;
+      str += sizeof SHELL_CMD;
+      while (len > 0 && mu_isspace (*str))
+       {
+         len--;
+         str++;
+       }
+      
+      if (len == 0)
+       {
+         if (mu_asprintf (ret, _("%s: bad number of arguments"), argv[0]))
+           return MU_WRDSE_NOSPACE;
+         return MU_WRDSE_USERERR;
+       }
+      return exp_shell (ret, str, len, closure);
+    }
+  
+  cmd = findcom (argv[0]);
+  if (!cmd)
+    {
+      if (mu_asprintf (ret, _("%s: unknown function"), argv[0]))
+       return MU_WRDSE_NOSPACE;
+      return MU_WRDSE_USERERR;
+    }
+  
+  for (argc = 0; argv[argc]; argc++)
+    ;
+
+  if (checkargc (cmd, argc))
+    {
+      if (mu_asprintf (ret, _("%s: bad number of arguments"), argv[0]))
+       return MU_WRDSE_NOSPACE;
+      return MU_WRDSE_USERERR;
+    }
+
+  rc = cmd->exp (argc, argv, &result);
+  if (rc == MU_WRDSE_USERERR && result == NULL)
+    {
+      if (mu_asprintf (ret, _("%s: command expansion error"), argv[0]))
+       return MU_WRDSE_NOSPACE;
+      return MU_WRDSE_USERERR;
+    }
+
+  if (rc == MU_WRDSE_OK || rc == MU_WRDSE_USERERR)
+    *ret = result;
+  
+  return rc;
+}
+  
+int
+mu_str_expand (char **output, char const *input, mu_assoc_t assoc)
+{
+  struct mu_wordsplit ws;
+  size_t wordc;
+  char **wordv;
+  
+  ws.ws_getvar = exp_getvar;
+  ws.ws_command = exp_runcmd;
+  ws.ws_closure = assoc;
+  ws.ws_options = MU_WRDSO_ARGV;
+
+  if (mu_wordsplit (input, &ws,
+                   MU_WRDSF_NOSPLIT | MU_WRDSF_GETVAR | MU_WRDSF_CLOSURE
+                   | MU_WRDSF_OPTIONS))
+    {
+      char *p = strdup (mu_wordsplit_strerror (&ws));
+      if (p)
+       *output = p;
+      return MU_ERR_FAILURE;
+    }
+  mu_wordsplit_get_words (&ws, &wordc, &wordv);
+  *output = wordv[0];
+  mu_wordsplit_free (&ws);
+  return 0;
+}
+
+int
+mu_str_vexpand (char **output, char const *input, ...)
+{
+  int rc;
+  mu_assoc_t assoc;
+  char *p[2];
+  int i;
+  va_list ap;
+  
+  rc = mu_assoc_create (&assoc, 0);
+  if (rc)
+    return rc;
+
+  va_start (ap, input);
+  i = 0;
+  while ((p[i] = va_arg (ap, char *)) != NULL)
+    {
+      if (i == 1)
+       {
+         rc = mu_assoc_install (assoc, p[0], p[1]);
+         if (rc)
+           {
+             mu_assoc_destroy (&assoc);
+             return rc;
+           }
+       }
+      i = (i + 1) % 2;
+    }
+  va_end (ap);
+
+  rc = mu_str_expand (output, input, assoc);
+  mu_assoc_destroy (&assoc);
+  return rc;
+}
diff --git a/libmailutils/tests/Makefile.am b/libmailutils/tests/Makefile.am
index 86cca83..b31b5ac 100644
--- a/libmailutils/tests/Makefile.am
+++ b/libmailutils/tests/Makefile.am
@@ -46,6 +46,7 @@ noinst_PROGRAMS = \
  debugspec\
  decode2047\
  encode2047\
+ exp\
  fltst\
  fsaf\
  fsaftomod\
diff --git a/libmailutils/tests/exp.c b/libmailutils/tests/exp.c
new file mode 100644
index 0000000..35a52d0
--- /dev/null
+++ b/libmailutils/tests/exp.c
@@ -0,0 +1,51 @@
+#include <mailutils/mailutils.h>
+
+int
+main (int argc, char **argv)
+{
+  mu_assoc_t assc;
+  char *p;
+  int i;
+  
+  MU_ASSERT (mu_assoc_create (&assc, 0));
+
+  for (i = 1; i < argc; i++)
+    {
+      p = strchr (argv[i], '=');
+      if (p)
+       {
+         *p++ = 0;
+         MU_ASSERT (mu_assoc_install (assc, argv[i], p));
+       }
+      else if (strcmp (argv[i], "--") == 0)
+       {
+         i++;
+         break;
+       }
+      else
+       break;
+    }
+
+  for (; i < argc; i++)
+    {
+      int rc = mu_str_expand (&p, argv[i], assc);
+      switch (rc)
+       {
+       case 0:
+         printf ("%s\n", p);
+         free (p);
+         break;
+
+       case MU_ERR_FAILURE:
+         mu_error ("%s", p);
+         free (p);
+         break;
+         
+       default:
+         mu_error ("%s", mu_strerror (rc));
+       }
+    }
+
+  return 0;
+}
+
diff --git a/libmu_auth/ldap.c b/libmu_auth/ldap.c
index b9594f0..298b5ba 100644
--- a/libmu_auth/ldap.c
+++ b/libmu_auth/ldap.c
@@ -598,38 +598,34 @@ _mu_ldap_search (LDAP *ld, const char *filter_pat, const 
char *key,
   size_t nattrs;
   LDAPMessage *res, *msg;
   ber_int_t msgid;
-  const char *env[3];
-  struct mu_wordsplit ws;
-
+  char *filter_str;
+  
   rc = _construct_attr_array (&nattrs, &attrs);
   if (rc)
     return rc;
 
-  env[0] = "user";
-  env[1] = key;
-  env[2] = 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)
+  rc = mu_str_vexpand (&filter_str, filter_pat, "user", key, NULL);
+  if (rc)
     {
-      mu_error (_("expanding %s yields empty string"), filter_pat);
-      mu_wordsplit_free (&ws);
       mu_argcv_free (nattrs, attrs);
-      return MU_ERR_FAILURE;
+      if (rc == MU_ERR_FAILURE)
+       {
+         mu_error (_("cannot expand line `%s': %s"), filter_pat,
+                   filter_str);
+         free (filter_str);
+       }
+      else
+       {
+         mu_error (_("cannot expand line `%s': %s"), filter_pat,
+                   mu_strerror (rc));
+       }
+      return rc;
     }
   
   rc = ldap_search_ext (ld, ldap_param.base, LDAP_SCOPE_SUBTREE,
-                       ws.ws_wordv[0], attrs, 0,
+                       filter_str, attrs, 0,
                        NULL, NULL, NULL, -1, &msgid);
-  mu_wordsplit_free (&ws);
+  free (filter_str);
   mu_argcv_free (nattrs, attrs);
 
   if (rc != LDAP_SUCCESS)
diff --git a/libmu_auth/radius.c b/libmu_auth/radius.c
index 08a00c7..acd5634 100644
--- a/libmu_auth/radius.c
+++ b/libmu_auth/radius.c
@@ -35,6 +35,7 @@
 #include <mailutils/iterator.h>
 #include <mailutils/mailbox.h>
 #include <mailutils/radius.h>
+#include <mailutils/cstr.h>
 #include <mailutils/wordsplit.h>
 #include <mailutils/mu_auth.h>
 #include <mailutils/error.h>
@@ -275,35 +276,25 @@ module_init (void *ptr)
 static char *
 _expand_query (const char *query, const char *ustr, const char *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_error (_("cannot expand line `%s': %s"), query,
-               mu_wordsplit_strerror (&ws));
-      return NULL;
-    }
-  else if (ws.ws_wordc == 0)
+  int rc;
+
+  rc = mu_str_vexpand (&ret, query, 
+                      "user", ustr,
+                      "passwd", passwd,
+                      NULL);
+  if (rc)
     {
-      mu_error (_("expanding %s yields empty string"), query);
-      mu_wordsplit_free (&ws);
+      if (rc == MU_ERR_FAILURE)
+       {
+         mu_error (_("cannot expand line `%s': %s"), query, ret);
+         free (ret);
+       }
+      else
+       mu_error (_("cannot expand line `%s': %s"), query, mu_strerror (rc));
       return NULL;
     }
   
-  ret = grad_emalloc (strlen (ws.ws_wordv[0]) + 1);
-  strcpy (ret, ws.ws_wordv[0]);
-  mu_wordsplit_free (&ws);
   return ret;
 }
 
diff --git a/libmu_auth/sql.c b/libmu_auth/sql.c
index bff0842..d69c36c 100644
--- a/libmu_auth/sql.c
+++ b/libmu_auth/sql.c
@@ -187,37 +187,27 @@ sql_escape_string (const char *ustr)
 char *
 mu_sql_expand_query (const char *query, const char *ustr)
 {
+  int rc;
   char *res;
   char *esc_ustr;
-  struct mu_wordsplit ws;
-  const char *env[2 + 1];
 
   if (!query)
     return NULL;
 
   esc_ustr = sql_escape_string (ustr);
-  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)
+  rc = mu_str_vexpand (&res, query, "user", esc_ustr, NULL);
+  free (esc_ustr);
+  if (rc)
     {
-      mu_error (_("expanding %s yields empty string"), query);
-      mu_wordsplit_free (&ws);
+      if (rc == MU_ERR_FAILURE)
+       {
+         mu_error (_("cannot expand line `%s': %s"), query, res);
+         free (res);
+       }
+      else
+       mu_error (_("cannot expand line `%s': %s"), query, mu_strerror (rc));
       return NULL;
     }
-  res = strdup (ws.ws_wordv[0]);
-  mu_wordsplit_free (&ws);
-  free (esc_ustr);
   return res;
 }
 
diff --git a/mu/imap.c b/mu/imap.c
index b600842..34e4ef2 100644
--- a/mu/imap.c
+++ b/mu/imap.c
@@ -121,37 +121,20 @@ static char **connect_argv;
 static char *username;
 
 static void
-imap_prompt_env ()
+imap_prompt_env (void)
 {
+  mu_assoc_t assoc = mutool_shell_prompt_assoc ();
   enum mu_imap_session_state state = current_imap_state ();
-  if (!mutool_prompt_env)
-    mutool_prompt_env = mu_calloc (2*7 + 1, sizeof(mutool_prompt_env[0]));
-
-  mutool_prompt_env[0] = "user";
-  mutool_prompt_env[1] = (state >= MU_IMAP_SESSION_AUTH && username) ?
-                           username : "[nouser]";
-
-  mutool_prompt_env[2] = "host"; 
-  mutool_prompt_env[3] = connect_argv ? host : "[nohost]";
-
-  mutool_prompt_env[4] = "program-name";
-  mutool_prompt_env[5] = (char*) mu_program_name;
-
-  mutool_prompt_env[6] = "canonical-program-name";
-  mutool_prompt_env[7] = "mu";
-
-  mutool_prompt_env[8] = "package";
-  mutool_prompt_env[9] = PACKAGE;
-
-  mutool_prompt_env[10] = "version";
-  mutool_prompt_env[11] = PACKAGE_VERSION;
+  const char *p;
+  
+  if (state >= MU_IMAP_SESSION_AUTH && username) 
+    mu_assoc_install (assoc, "user", username);
 
-  mutool_prompt_env[12] = "status";
-  if (mu_imap_session_state_str (state,
-                                (const char **) &mutool_prompt_env[13]))
-    mutool_prompt_env[12] = NULL;
+  if (connect_argv)
+    mu_assoc_install (assoc, "host", host); 
 
-  mutool_prompt_env[14] = NULL;
+  if (mu_imap_session_state_str (state, &p) == 0)
+    mu_assoc_install (assoc, "status", (void*) p);
 }
 
 /* Callbacks */
@@ -724,7 +707,11 @@ com_login (int argc, char **argv)
   memset (pwd, 0, strlen (pwd));
   free (passbuf);
   if (status == 0)
-    imap_prompt_env ();
+    {
+      free (username);
+      username = mu_strdup (argv[1]);
+      imap_prompt_env ();
+    }
   else
     report_failure ("login", status);
   return 0;
diff --git a/mu/mu.h b/mu/mu.h
index 6f286f2..712cafe 100644
--- a/mu/mu.h
+++ b/mu/mu.h
@@ -43,8 +43,8 @@ struct mutool_command
 };
 
 extern char *mutool_shell_prompt;
-extern char **mutool_prompt_env;
 extern int mutool_shell_interactive;
+mu_assoc_t mutool_shell_prompt_assoc (void);
 int mutool_shell (const char *name, struct mutool_command *cmd);
 mu_stream_t mutool_open_pager (void);
 
diff --git a/mu/pop.c b/mu/pop.c
index 22af129..cf4d60f 100644
--- a/mu/pop.c
+++ b/mu/pop.c
@@ -56,35 +56,17 @@ pop_session_str (enum pop_session_status stat)
 }
 
 static void
-pop_prompt_env ()
+pop_prompt_env (void)
 {
-  if (!mutool_prompt_env)
-    mutool_prompt_env = mu_calloc (2*7 + 1, sizeof(mutool_prompt_env[0]));
+  mu_assoc_t assoc = mutool_shell_prompt_assoc ();
 
-  mutool_prompt_env[0] = "user";
-  mutool_prompt_env[1] = (pop_session_status == pop_session_logged_in) ?
-                           username : "[nouser]";
-
-  mutool_prompt_env[2] = "host"; 
-  mutool_prompt_env[3] = (pop_session_status != pop_session_disconnected) ?
-                           host : "[nohost]";
-
-  mutool_prompt_env[4] = "program-name";
-  mutool_prompt_env[5] = (char*) mu_program_name;
-
-  mutool_prompt_env[6] = "canonical-program-name";
-  mutool_prompt_env[7] = "mu";
-
-  mutool_prompt_env[8] = "package";
-  mutool_prompt_env[9] = PACKAGE;
-
-  mutool_prompt_env[10] = "version";
-  mutool_prompt_env[11] = PACKAGE_VERSION;
-
-  mutool_prompt_env[12] = "status";
-  mutool_prompt_env[13] = (char*) pop_session_str (pop_session_status);
+  if (pop_session_status == pop_session_logged_in)
+    mu_assoc_install (assoc, "user", username);
+  if (pop_session_status != pop_session_disconnected)
+    mu_assoc_install (assoc, "host", host); 
 
-  mutool_prompt_env[14] = NULL;
+  mu_assoc_install (assoc, "status",
+                   pop_session_str (pop_session_status));
 }
 
 
diff --git a/mu/shell.c b/mu/shell.c
index c1d8415..358306f 100644
--- a/mu/shell.c
+++ b/mu/shell.c
@@ -24,7 +24,7 @@
 #endif
 
 char *mutool_shell_prompt;
-char **mutool_prompt_env;
+static mu_assoc_t mutool_prompt_assoc;
 int mutool_shell_interactive;
 
 
@@ -63,7 +63,7 @@ static int shell_history (int, char **);
 #endif
 
 struct mutool_command default_comtab[] = {
-  { "prompt",     1, 2, CMD_COALESCE_EXTRA_ARGS, shell_prompt,
+  { "prompt",     1, 2, 0, shell_prompt,
     N_("STRING"),
     N_("set command prompt") },
   { "exit",       1, 1, 0, shell_exit,    NULL,        N_("exit program") },
@@ -244,16 +244,8 @@ shell_help (int argc, char **argv)
 static int
 shell_prompt (int argc, char **argv)
 {
-  mu_wordsplit_t ws;
-  
-  if (mu_wordsplit (argv[1], &ws, MU_WRDSF_NOSPLIT | MU_WRDSF_DEFFLAGS))
-    mu_error ("mu_wordsplit: %s", mu_wordsplit_strerror (&ws));
-  else
-    {
-      free (mutool_shell_prompt);
-      mutool_shell_prompt = mu_strdup (ws.ws_wordv[0]);
-    }
-  mu_wordsplit_free (&ws);
+  free (mutool_shell_prompt);
+  mutool_shell_prompt = mu_strdup (argv[1]);
   return 0;
 }
 
@@ -593,23 +585,22 @@ execute_line (char *line)
 static char *
 input_line_interactive ()
 {
-  char *line;
-  int wsflags = MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD;
-  struct mu_wordsplit ws;
+  char *line, *prompt;
+  int rc;
   
   report_signals ();
-  if (mutool_prompt_env)
+  rc = mu_str_expand (&prompt, mutool_shell_prompt, mutool_prompt_assoc);
+  if (rc)
     {
-      ws.ws_env = (const char **)mutool_prompt_env;
-      wsflags |= MU_WRDSF_ENV | MU_WRDSF_ENV_KV;
-    }
-  if (mu_wordsplit (mutool_shell_prompt, &ws, wsflags))
-    line = readline (mutool_shell_prompt);
-  else
-    {
-      line = readline (ws.ws_wordv[0]);
-      mu_wordsplit_free (&ws);
+      if (rc == MU_ERR_FAILURE)
+       mu_error (_("cannot expand prompt: %s"), prompt);
+      else
+       mu_error (_("cannot expand prompt: %s"), mu_strerror (rc));
+      exit (1);
     }
+
+  line = readline (prompt);
+  free (prompt);
   return line;
 }
 
@@ -634,6 +625,29 @@ shell_exit (int argc MU_ARG_UNUSED, char **argv 
MU_ARG_UNUSED)
   return 0;
 }
 
+mu_assoc_t
+mutool_shell_prompt_assoc (void)
+{
+  if (mutool_prompt_assoc)
+    mu_assoc_clear (mutool_prompt_assoc);
+  else
+    {
+      int rc = mu_assoc_create (&mutool_prompt_assoc, 0);
+      if (rc)
+       {
+         mu_diag_funcall (MU_DIAG_ERROR, "mu_assoc_create", NULL, rc);
+         exit (1);
+       }
+    }
+  mu_assoc_install (mutool_prompt_assoc, "program-name", mu_program_name);
+  mu_assoc_install (mutool_prompt_assoc, "canonical-program-name",
+                   "mailutils");
+  mu_assoc_install (mutool_prompt_assoc, "package", PACKAGE);
+  mu_assoc_install (mutool_prompt_assoc, "version", PACKAGE_VERSION);
+
+  return mutool_prompt_assoc;
+}
+
 int
 mutool_shell (const char *name, struct mutool_command *cmd)
 {
diff --git a/mu/smtp.c b/mu/smtp.c
index bb2e268..ab013f2 100644
--- a/mu/smtp.c
+++ b/mu/smtp.c
@@ -69,39 +69,18 @@ smtp_session_str (enum smtp_session_status stat)
 }
 
 static void
-smtp_prompt_env ()
+smtp_prompt_env (void)
 {
+  mu_assoc_t assoc = mutool_shell_prompt_assoc ();
   const char *value;
   
-  if (!mutool_prompt_env)
-    mutool_prompt_env = mu_calloc (2*7 + 1, sizeof(mutool_prompt_env[0]));
-
-  mutool_prompt_env[0] = "user";
-  mutool_prompt_env[1] = "[nouser]";
   if (smtp_session_status == smtp_session_logged_in &&
       mu_smtp_get_param (smtp, MU_SMTP_PARAM_USERNAME, &value) == 0)
-    mutool_prompt_env[1] = (char*) value;
-
-  mutool_prompt_env[2] = "host"; 
-  mutool_prompt_env[3] = (smtp_session_status != smtp_session_disconnected) ?
-                           host : "[nohost]";
-
-  mutool_prompt_env[4] = "program-name";
-  mutool_prompt_env[5] = (char*) mu_program_name;
-
-  mutool_prompt_env[6] = "canonical-program-name";
-  mutool_prompt_env[7] = "mu";
+    mu_assoc_install (assoc, "user", value);
 
-  mutool_prompt_env[8] = "package";
-  mutool_prompt_env[9] = PACKAGE;
-
-  mutool_prompt_env[10] = "version";
-  mutool_prompt_env[11] = PACKAGE_VERSION;
-
-  mutool_prompt_env[12] = "status";
-  mutool_prompt_env[13] = (char*) smtp_session_str (smtp_session_status);
-
-  mutool_prompt_env[14] = NULL;
+  if (smtp_session_status != smtp_session_disconnected)
+    mu_assoc_install (assoc, "host", host);
+  mu_assoc_install (assoc, "status", smtp_session_str (smtp_session_status));
 }
 
 static void


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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