Commit 622bc770 622bc770d5f8d7500fa409993c8fef8de5736962 by Sergey Poznyakoff

Revise associative array API

* configure.ac (VI_REVISION): Increase.
* include/mailutils/assoc.h (mu_assoc_create): Change prototype.
(mu_assoc_ref,mu_assoc_ref_install)
(mu_assoc_remove_ref): Remove.
(mu_assoc_get): New proto.
(mu_assoc_lookup,mu_assoc_lookup_ref): New proto.
(mu_assoc_install_ref): New proto.
(mu_assoc_set_free): Remove.
(mu_assoc_set_destroy_item): Set proto.
* include/mailutils/types.hin (mu_deallocator_t): New typedef.
* include/mailutils/list.h (mu_list_destroy_item_t): Change definition.
* libmailutils/base/assoc.c: Rewrite.  Link all entries in
a doubly-linked list to preserve natural ordering during iterations.
* libmailutils/base/mutil.c (mutil_parse_field_map): Update calls
to assoc API.
* libmailutils/cfg/driver.c (alloc_section_tab)
(mu_create_canned_section,mu_create_canned_param)
(mu_get_canned_container,parse_mapping)
(mu_cfg_field_map): Likewise.
* libmailutils/mime/mimehdr.c (_mu_mime_param_free): Free the pointer
itself.
(flush_param,mu_mime_param_assoc_create)
(mu_mime_param_assoc_add)
(_mime_header_parse)
(mu_mimehdr_aget_decoded_param): Update calls to assoc API.
(mu_mime_param_free): New function.
* libmailutils/property/assocprop.c: Likewise.
* libmu_sieve/environment.c: Likewise.
* libmu_sieve/variables.c: Likewise.
* libproto/imap/id.c: Likewise.
* mail/alias.c: Likewise.
* mail/testsuite/mail/alias.exp: Update ordering of expected output.
* mu/imap.c (com_id): Update.

* include/mailutils/mime.h (mu_rfc2047_decode_param): Change prototype.
* libmailutils/base/rfc2047.c (mu_rfc2047_decode_param): Allocate
returned value, instead of filling an already allocated structure.
* libproto/imap/fetch.c: Reflect changes.
1 parent 8c834b60
......@@ -32,7 +32,7 @@ AB_INIT
dnl Library versioning
AC_SUBST(VI_CURRENT, 5)
AC_SUBST(VI_REVISION, 1)
AC_SUBST(VI_REVISION, 2)
AC_SUBST(VI_AGE, 0)
dnl Library paths
......
......@@ -28,18 +28,19 @@ extern "C" {
#define MU_ASSOC_COPY_KEY 0x01
#define MU_ASSOC_ICASE 0x02
typedef void (*mu_assoc_free_fn) (void *data);
int mu_assoc_create (mu_assoc_t *passoc, size_t elsize, int flags);
int mu_assoc_create (mu_assoc_t *passoc, int flags);
void mu_assoc_destroy (mu_assoc_t *passoc);
void mu_assoc_clear (mu_assoc_t assoc);
void *mu_assoc_ref (mu_assoc_t assoc, const char *name);
int mu_assoc_lookup (mu_assoc_t assoc, const char *name, void *dataptr);
void *mu_assoc_get (mu_assoc_t assoc, const char *name);
int mu_assoc_install (mu_assoc_t assoc, const char *name, void *value);
int mu_assoc_ref_install (mu_assoc_t assoc, const char *name, void **pval);
int mu_assoc_lookup_ref (mu_assoc_t assoc, const char *name, void *dataptr);
int mu_assoc_install_ref (mu_assoc_t assoc, const char *name, void *pval);
int mu_assoc_get_iterator (mu_assoc_t assoc, mu_iterator_t *piterator);
int mu_assoc_remove_ref (mu_assoc_t assoc, void *data);
int mu_assoc_remove (mu_assoc_t assoc, const char *name);
int mu_assoc_set_free (mu_assoc_t assoc, mu_assoc_free_fn fn);
int mu_assoc_set_destroy_item (mu_assoc_t assoc, mu_deallocator_t fn);
int mu_assoc_count (mu_assoc_t assoc, size_t *pcount);
#ifdef __cplusplus
......
......@@ -59,7 +59,7 @@ int mu_list_get_comparator (mu_list_t _list, mu_list_comparator_t *_pcmp);
/* The destroy function is responsible for deallocating a list element.
By default, it is not set. */
typedef void (*mu_list_destroy_item_t) (void *);
typedef mu_deallocator_t mu_list_destroy_item_t;
/* An often used destroy function. It simply calls free(3) over the
_item. */
......
......@@ -57,7 +57,8 @@ int mu_rfc2047_decode (const char *tocode, const char *fromstr,
int mu_rfc2047_encode (const char *charset, const char *encoding,
const char *text, char **result);
int mu_rfc2047_decode_param (const char *tocode, const char *input,
struct mu_mime_param *param);
struct mu_mime_param **param);
void mu_mime_param_free (struct mu_mime_param *p);
int mu_base64_encode (const unsigned char *input, size_t input_len,
unsigned char **output, size_t * output_len);
......
......@@ -129,6 +129,10 @@ typedef struct _mu_dbm_file *mu_dbm_file_t;
typedef struct _mu_imapio *mu_imapio_t;
typedef struct _mu_msgset *mu_msgset_t;
/* Pointer to a function responsible for freeing the memory resources
allocated for its argument. */
typedef void (*mu_deallocator_t) (void *);
typedef void (*mu_onexit_t) (void*);
typedef unsigned int mu_debug_handle_t;
typedef unsigned int mu_debug_level_t;
......
......@@ -29,6 +29,7 @@
#include <mailutils/errno.h>
#include <mailutils/nls.h>
#include <mailutils/assoc.h>
#include <mailutils/list.h>
#include <mailutils/stream.h>
#include <mailutils/sql.h>
......@@ -56,12 +57,6 @@ mu_mh_delim (const char *str)
return str[0] == '\n';
}
static void
assoc_str_free (void *data)
{
free (data);
}
int
mutil_parse_field_map (const char *map, mu_assoc_t *passoc_tab, int *perr)
{
......@@ -91,10 +86,10 @@ mutil_parse_field_map (const char *map, mu_assoc_t *passoc_tab, int *perr)
}
if (!assoc_tab)
{
rc = mu_assoc_create (&assoc_tab, sizeof(char*), 0);
rc = mu_assoc_create (&assoc_tab, 0);
if (rc)
break;
mu_assoc_set_free (assoc_tab, assoc_str_free);
mu_assoc_set_destroy_item (assoc_tab, mu_list_free_item);
*passoc_tab = assoc_tab;
}
*p++ = 0;
......@@ -104,7 +99,7 @@ mutil_parse_field_map (const char *map, mu_assoc_t *passoc_tab, int *perr)
rc = errno;
break;
}
rc = mu_assoc_install (assoc_tab, tok, &pptr);
rc = mu_assoc_install (assoc_tab, tok, pptr);
if (rc)
{
free (p);
......
......@@ -234,18 +234,23 @@ _rfc2047_decode_param (const char *tocode, const char *input,
int
mu_rfc2047_decode_param (const char *tocode, const char *input,
struct mu_mime_param *param)
struct mu_mime_param **param_ptr)
{
int rc;
struct mu_mime_param tmp;
struct mu_mime_param *p;
if (!input)
return EINVAL;
if (!param)
if (!param_ptr)
return MU_ERR_OUT_PTR_NULL;
rc = _rfc2047_decode_param (tocode, input, &tmp);
p = malloc (sizeof (*p));
if (!p)
return errno;
rc = _rfc2047_decode_param (tocode, input, p);
if (rc == 0)
*param = tmp;
*param_ptr = p;
else
mu_mime_param_free (p);
return rc;
}
......
......@@ -46,8 +46,7 @@ static void
alloc_section_tab ()
{
if (!section_tab)
mu_assoc_create (&section_tab, sizeof (struct mu_cfg_cont **),
MU_ASSOC_COPY_KEY);
mu_assoc_create (&section_tab, MU_ASSOC_COPY_KEY);
}
int
......@@ -56,7 +55,7 @@ mu_create_canned_section (char *name, struct mu_cfg_section **psection)
int rc;
struct mu_cfg_cont **pcont;
alloc_section_tab ();
rc = mu_assoc_ref_install (section_tab, name, (void **)&pcont);
rc = mu_assoc_install_ref (section_tab, name, &pcont);
if (rc == 0)
{
mu_config_create_container (pcont, mu_cfg_cont_section);
......@@ -74,7 +73,7 @@ mu_create_canned_param (char *name, struct mu_cfg_param **pparam)
int rc;
struct mu_cfg_cont **pcont;
alloc_section_tab ();
rc = mu_assoc_ref_install (section_tab, name, (void **)&pcont);
rc = mu_assoc_install_ref (section_tab, name, &pcont);
if (rc == 0)
{
mu_config_create_container (pcont, mu_cfg_cont_param);
......@@ -89,8 +88,7 @@ mu_create_canned_param (char *name, struct mu_cfg_param **pparam)
struct mu_cfg_cont *
mu_get_canned_container (const char *name)
{
struct mu_cfg_cont **pcont = mu_assoc_ref (section_tab, name);
return pcont ? *pcont : NULL;
return mu_assoc_get (section_tab, name);
}
......@@ -615,19 +613,13 @@ parse_mapping (void *item, void *data)
val = mu_strdup (str + len + 1);
if (!val)
return ENOMEM;
clos->err = mu_assoc_install (clos->assoc, key, &val);
clos->err = mu_assoc_install (clos->assoc, key, val);
free (key);
if (clos->err)
return 1;
return 0;
}
static void
assoc_str_free (void *data)
{
free (data);
}
int
mu_cfg_field_map (struct mu_config_value const *val, mu_assoc_t *passoc,
char **err_term)
......@@ -636,10 +628,10 @@ mu_cfg_field_map (struct mu_config_value const *val, mu_assoc_t *passoc,
struct mapping_closure clos;
mu_list_t list = NULL;
rc = mu_assoc_create (&clos.assoc, sizeof(char*), 0);
rc = mu_assoc_create (&clos.assoc, 0);
if (rc)
return rc;
mu_assoc_set_free (clos.assoc, assoc_str_free);
mu_assoc_set_destroy_item (clos.assoc, mu_list_free_item);
clos.err_term = NULL;
switch (val->type)
......
......@@ -45,12 +45,13 @@
info */
/* Free members of struct mu_mime_param, but do not free it itself. */
static void
_mu_mime_param_free (struct mu_mime_param *p)
void
mu_mime_param_free (struct mu_mime_param *p)
{
free (p->lang);
free (p->cset);
free (p->value);
free (p);
}
/* Treat ITEM as a pointer to struct mu_mime_param and reclaim all
......@@ -60,7 +61,7 @@ _mu_mime_param_free (struct mu_mime_param *p)
static void
_mu_mime_param_free_item (void *item)
{
_mu_mime_param_free (item);
mu_mime_param_free (item);
}
/* Recode a string between two charsets.
......@@ -153,31 +154,38 @@ flush_param (struct param_continuation *cont, mu_assoc_t assoc, int subset,
const char *outcharset)
{
int rc;
struct mu_mime_param param, *param_slot = NULL;
struct mu_mime_param *param, **param_slot;
mu_off_t size;
if (subset)
{
param_slot = mu_assoc_ref (assoc, cont->param_name);
if (!param_slot)
rc = mu_assoc_lookup_ref (assoc, cont->param_name, &param_slot);
if (rc)
return 0;
}
param = calloc (1, sizeof *param);
if (!param)
return errno;
if (cont->param_lang)
{
param.lang = strdup (cont->param_lang);
if (!param.lang)
param->lang = strdup (cont->param_lang);
if (!param->lang)
{
mu_mime_param_free (param);
return ENOMEM;
}
}
else
param.lang = NULL;
param->lang = NULL;
if (outcharset || cont->param_cset)
{
param.cset = strdup (outcharset ? outcharset : cont->param_cset);
if (!param.cset)
param->cset = strdup (outcharset ? outcharset : cont->param_cset);
if (!param->cset)
{
free (param.lang);
mu_mime_param_free (param);
return ENOMEM;
}
}
......@@ -185,23 +193,25 @@ flush_param (struct param_continuation *cont, mu_assoc_t assoc, int subset,
rc = mu_stream_size (cont->param_value, &size);
if (rc == 0)
{
param.value = malloc (size + 1);
if (!param.value)
param->value = malloc (size + 1);
if (!param->value)
{
mu_mime_param_free (param);
rc = ENOMEM;
}
}
if (rc == 0)
{
rc = mu_stream_seek (cont->param_value, 0, MU_SEEK_SET, NULL);
if (rc == 0)
rc = mu_stream_read (cont->param_value, param.value, size, NULL);
param.value[size] = 0;
rc = mu_stream_read (cont->param_value, param->value, size, NULL);
param->value[size] = 0;
}
if (rc)
{
free (param.lang);
free (param.cset);
mu_mime_param_free (param);
return rc;
}
......@@ -209,26 +219,25 @@ flush_param (struct param_continuation *cont, mu_assoc_t assoc, int subset,
mu_c_strcasecmp (cont->param_cset, outcharset))
{
char *tmp;
rc = _recode_string (param.value, cont->param_cset, outcharset, &tmp);
free (param.value);
rc = _recode_string (param->value, cont->param_cset, outcharset, &tmp);
free (param->value);
if (rc)
{
free (param.lang);
free (param.cset);
mu_mime_param_free (param);
return rc;
}
param.value = tmp;
param->value = tmp;
}
if (param_slot)
if (subset)
{
*param_slot = param;
}
else
{
rc = mu_assoc_install (assoc, cont->param_name, &param);
rc = mu_assoc_install (assoc, cont->param_name, param);
if (rc)
_mu_mime_param_free (&param);
mu_mime_param_free (param);
}
return rc;
......@@ -239,10 +248,9 @@ int
mu_mime_param_assoc_create (mu_assoc_t *paramtab)
{
mu_assoc_t assoc;
int rc = mu_assoc_create (&assoc, sizeof (struct mu_mime_param),
MU_ASSOC_ICASE);
int rc = mu_assoc_create (&assoc, MU_ASSOC_ICASE);
if (rc == 0)
mu_assoc_set_free (assoc, _mu_mime_param_free_item);
mu_assoc_set_destroy_item (assoc, _mu_mime_param_free_item);
*paramtab = assoc;
return rc;
}
......@@ -251,20 +259,7 @@ mu_mime_param_assoc_create (mu_assoc_t *paramtab)
int
mu_mime_param_assoc_add (mu_assoc_t assoc, const char *name)
{
struct mu_mime_param param;
memset (&param, 0, sizeof param);
return mu_assoc_install (assoc, name, &param);
}
/* See FIXME near the end of _mime_header_parse, below. */
static int
_remove_entry (void *item, void *data)
{
struct mu_mime_param *p = item;
mu_assoc_t assoc = data;
mu_assoc_remove_ref (assoc, p);
return 0;
return mu_assoc_install (assoc, name, NULL);
}
/* A working horse of this module. Parses input string, which should
......@@ -331,7 +326,7 @@ _mime_header_parse (const char *text, char **pvalue,
char *p;
char *decoded;
int flags = 0;
struct mu_mime_param param;
struct mu_mime_param *param;
key = ws.ws_wordv[i];
if (key[0] == ';')
......@@ -484,19 +479,20 @@ _mime_header_parse (const char *text, char **pvalue,
}
else
{
struct mu_mime_param *param;
rc = mu_rfc2047_decode_param (outcharset, val, &param);
if (rc)
return rc;
cset = csetp = param.cset;
lang = langp = param.lang;
decoded = param.value;
cset = csetp = param->cset;
lang = langp = param->lang;
decoded = param->value;
free (param);
}
val = decoded;
if (flags & MU_MIMEHDR_MULTILINE)
{
rc = mu_stream_write (cont.param_value, val, strlen (val),
NULL);
rc = mu_stream_write (cont.param_value, val, strlen (val), NULL);
free (decoded);
free (csetp);
free (langp);
......@@ -505,18 +501,22 @@ _mime_header_parse (const char *text, char **pvalue,
continue;
}
memset (&param, 0, sizeof (param));
param = calloc (1, sizeof (*param));
if (!param)
rc = ENOMEM;
else
{
if (lang)
{
param.lang = strdup (lang);
if (!param.lang)
param->lang = strdup (lang);
if (!param->lang)
rc = ENOMEM;
else
{
param.cset = strdup (cset);
if (!param.cset)
param->cset = strdup (cset);
if (!param->cset)
{
free (param.lang);
free (param->lang);
rc = ENOMEM;
}
}
......@@ -524,6 +524,7 @@ _mime_header_parse (const char *text, char **pvalue,
free (csetp);
free (langp);
}
if (rc)
{
......@@ -531,27 +532,29 @@ _mime_header_parse (const char *text, char **pvalue,
break;
}
param.value = strdup (val);
param->value = strdup (val);
free (decoded);
if (!param.value)
if (!param->value)
{
_mu_mime_param_free (&param);
mu_mime_param_free (param);
rc = ENOMEM;
break;
}
if (subset)
{
struct mu_mime_param *p = mu_assoc_ref (assoc, key);
if (p)
struct mu_mime_param **p;
if (mu_assoc_lookup_ref (assoc, key, &p) == 0)
*p = param;
else
mu_mime_param_free (param);
}
else
{
rc = mu_assoc_install (assoc, key, &param);
rc = mu_assoc_install (assoc, key, param);
if (rc)
{
_mu_mime_param_free (&param);
mu_mime_param_free (param);
break;
}
}
......@@ -574,12 +577,7 @@ _mime_header_parse (const char *text, char **pvalue,
if (subset)
{
/* Eliminate empty elements.
FIXME: What I wanted to do initially is commented out, because
unfortunately iterator_ctl is not defined for assoc tables...
*/
#if 0
/* Eliminate empty elements. */
mu_iterator_t itr;
rc = mu_assoc_get_iterator (assoc, &itr);
......@@ -592,38 +590,11 @@ _mime_header_parse (const char *text, char **pvalue,
struct mu_mime_param *p;
mu_iterator_current_kv (itr, (const void **)&name, (void**)&p);
if (!p->value)
if (!p)
mu_iterator_ctl (itr, mu_itrctl_delete, NULL);
}
mu_iterator_destroy (&itr);
}
#else
/* ... Instead, the following kludgy approach is taken: */
mu_iterator_t itr;
mu_list_t elist;
rc = mu_list_create (&elist);
if (rc)
return rc;
rc = mu_assoc_get_iterator (assoc, &itr);
if (rc == 0)
{
for (mu_iterator_first (itr); rc == 0 && !mu_iterator_is_done (itr);
mu_iterator_next (itr))
{
const char *name;
struct mu_mime_param *p;
mu_iterator_current_kv (itr, (const void **)&name, (void**)&p);
if (!p->value)
rc = mu_list_append (elist, p);
}
mu_iterator_destroy (&itr);
}
if (rc == 0)
mu_list_foreach (elist, _remove_entry, assoc);
mu_list_destroy (&elist);
#endif
}
return rc;
......@@ -782,7 +753,7 @@ mu_mimehdr_aget_decoded_param (const char *str, const char *name,
rc = mu_mime_header_parse_subset (str, charset, NULL, assoc);
if (rc == 0)
{
struct mu_mime_param *param = mu_assoc_ref (assoc, name);
struct mu_mime_param *param = mu_assoc_get (assoc, name);
if (!param)
rc = MU_ERR_NOENT;
else
......@@ -852,7 +823,7 @@ _get_attachment_name (mu_message_t msg, const char *charset,
{
struct mu_mime_param *param;
if (mu_c_strcasecmp (disp, "attachment") == 0 &&
(param = mu_assoc_ref (assoc, "filename")))
(param = mu_assoc_get (assoc, "filename")))
{
*pbuf = param->value;
if (psz)
......@@ -893,7 +864,7 @@ _get_attachment_name (mu_message_t msg, const char *charset,
if (ret == 0)
{
struct mu_mime_param *param;
if ((param = mu_assoc_ref (assoc, "name")))
if ((param = mu_assoc_get (assoc, "name")))
{
*pbuf = param->value;
if (psz)
......
......@@ -25,13 +25,9 @@
#include <mailutils/assoc.h>
#include <mailutils/stream.h>
#include <mailutils/iterator.h>
#include <mailutils/list.h>
#include <stdlib.h>
struct property_item
{
char *value;
};
static void
_assoc_prop_done (struct _mu_property *prop)
{
......@@ -46,13 +42,13 @@ _assoc_prop_getval (struct _mu_property *prop,
const char *key, const char **pval)
{
mu_assoc_t assoc = prop->_prop_data;
struct property_item *item;
char *item;
item = mu_assoc_ref (assoc, key);
item = mu_assoc_get (assoc, key);
if (item == NULL)
return MU_ERR_NOENT;
if (pval)
*pval = item->value;
*pval = item;
return 0;
}
......@@ -62,14 +58,14 @@ _assoc_prop_setval (struct _mu_property *prop, const char *key,
const char *val, int overwrite)
{
mu_assoc_t assoc = prop->_prop_data;
struct property_item *item;
char **item;
int rc;
rc = mu_assoc_ref_install (assoc, key, (void **)&item);
rc = mu_assoc_install_ref (assoc, key, &item);
if (rc == 0)
{
item->value = strdup (val);
if (!item->value)
*item = strdup (val);
if (!*item)
{
mu_assoc_remove (assoc, key);
return ENOMEM;
......@@ -80,8 +76,8 @@ _assoc_prop_setval (struct _mu_property *prop, const char *key,
char *newval = strdup (val);
if (!newval)
return ENOMEM;
free (item->value);
item->value = newval;
free (*item);
*item = newval;
}
else
return rc;
......@@ -105,13 +101,6 @@ _assoc_prop_clear (struct _mu_property *prop)
}
static void *
_assoc_prop_dataptr (void *in)
{
struct property_item *item = in;
return item->value;
}
static int
_assoc_prop_getitr (struct _mu_property *prop, mu_iterator_t *pitr)
{
......@@ -121,20 +110,11 @@ _assoc_prop_getitr (struct _mu_property *prop, mu_iterator_t *pitr)
rc = mu_assoc_get_iterator ((mu_assoc_t)prop->_prop_data, &itr);
if (rc)
return rc;
mu_iterator_set_dataptr (itr, _assoc_prop_dataptr);
*pitr = itr;
return 0;
}
static void
prop_free_value (void *data)
{
struct property_item *item = data;
free (item->value);
}
static int
_assoc_prop_fill (struct _mu_property *prop)
{
......@@ -201,10 +181,10 @@ mu_assoc_property_init (struct _mu_property *prop)
mu_assoc_t assoc;
int rc;
rc = mu_assoc_create (&assoc, sizeof (struct property_item), 0);
rc = mu_assoc_create (&assoc, 0);
if (rc)
return rc;
mu_assoc_set_free (assoc, prop_free_value);
mu_assoc_set_destroy_item (assoc, mu_list_free_item);
prop->_prop_data = assoc;
prop->_prop_done = _assoc_prop_done;
......
......@@ -179,10 +179,10 @@ mu_sieve_get_environ (mu_sieve_machine_t mach, char const *name, char **retval)
if (!mach->exenv)
return MU_ERR_NOENT;
p = mu_assoc_ref (mach->exenv, name);
p = mu_assoc_get (mach->exenv, name);
if (p)
{
*retval = strdup (*(char**)p);
*retval = strdup (p);
if (!*retval)
return errno;
}
......@@ -204,11 +204,11 @@ mu_sieve_set_environ (mu_sieve_machine_t mach, char const *name,
if (!mach->exenv)
{
int rc = mu_assoc_create (&mach->exenv, sizeof (char *), 0);
int rc = mu_assoc_create (&mach->exenv, 0);
if (rc)
return rc;
}
rc = mu_assoc_ref_install (mach->exenv, name, (void **) &pptr);
rc = mu_assoc_install_ref (mach->exenv, name, &pptr);
if (rc == 0 || rc == MU_ERR_EXISTS)
{
char *copy = strdup (value);
......
......@@ -166,7 +166,7 @@ sieve_action_set (mu_sieve_machine_t mach)
size_t i;
char *name;
char *value;
struct sieve_variable *vptr;
struct sieve_variable *var, **vptr;
int rc;
mu_sieve_get_arg (mach, 0, SVT_STRING, &name);
......@@ -181,21 +181,29 @@ sieve_action_set (mu_sieve_machine_t mach)
value = str;
}
rc = mu_assoc_ref_install (mach->vartab, name, (void **)&vptr);
rc = mu_assoc_install_ref (mach->vartab, name, &vptr);
switch (rc)
{
case 0:
var = malloc (sizeof (*var));
if (!var)
{
mu_sieve_error (mach, "%s", mu_strerror (errno));
mu_sieve_abort (mach);
}
*vptr = var;
break;
case MU_ERR_EXISTS:
mu_sieve_free (mach, vptr->value);
var = *vptr;
mu_sieve_free (mach, var->value);
break;
default:
mu_sieve_error (mach, "mu_assoc_ref_install: %s", mu_strerror (rc));
mu_sieve_abort (mach);
}
vptr->value = value;
var->value = value;
return 0;
}
......@@ -354,7 +362,7 @@ mu_i_sv_expand_variables (char const *input, size_t len,
memcpy (name, input, len);
name[len] = 0;
var = mu_assoc_ref (mach->vartab, name);
var = mu_assoc_get (mach->vartab, name);
free (name);
......@@ -383,11 +391,10 @@ mu_sieve_require_variables (mu_sieve_machine_t mach)
if (mach->vartab)
return 0;
rc = mu_assoc_create (&mach->vartab, sizeof (struct sieve_variable),
MU_ASSOC_ICASE);
rc = mu_assoc_create (&mach->vartab, MU_ASSOC_ICASE);
if (rc)
mu_sieve_error (mach, "mu_assoc_create: %s", mu_strerror (rc));
mu_assoc_set_destroy_item (mach->vartab, mu_list_free_item);
if (rc == 0)
{
mu_sieve_register_action (mach, "set", sieve_action_set,
......@@ -418,11 +425,14 @@ mu_i_sv_copy_variables (mu_sieve_machine_t child, mu_sieve_machine_t parent)
{
const char *name;
struct sieve_variable const *val;
struct sieve_variable newval;
struct sieve_variable *newval;
mu_iterator_current_kv (itr, (const void **)&name, (void**)&val);
newval.value = mu_sieve_strdup (child, val->value);
mu_assoc_install (child->vartab, name, &newval);
newval = malloc (sizeof (*newval));
if (!newval)
mu_sieve_abort (child);
newval->value = mu_sieve_strdup (child, val->value);
mu_assoc_install (child->vartab, name, newval);
}
mu_iterator_destroy (&itr);
......
......@@ -362,7 +362,7 @@ static int
_map_body_param (void **itmv, size_t itmc, void *call_data)
{
mu_assoc_t assoc = call_data;
struct mu_mime_param param;
struct mu_mime_param *param;
struct imap_list_element *key, *val;
int rc;
......@@ -377,12 +377,18 @@ _map_body_param (void **itmv, size_t itmc, void *call_data)
rc = mu_rfc2047_decode_param ("UTF-8", val->v.string, &param);
if (rc)
{
param.lang = param.cset = NULL;
param.value = strdup (val->v.string);
if (!param.value)
param = malloc (sizeof (*param));
if (!param)
return ENOMEM;
param->lang = param->cset = NULL;
param->value = strdup (val->v.string);
if (!param->value)
{
free (param);
return ENOMEM;
}
}
return mu_assoc_install (assoc, key->v.string, &param);
return mu_assoc_install (assoc, key->v.string, param);
}
static int
......
......@@ -27,22 +27,19 @@
#include <mailutils/imap.h>
#include <mailutils/sys/imap.h>
void
_id_free (void *data)
{
char *s = *(char**)data;
free (s);
}
static int
_id_mapper (void **itmv, size_t itmc, void *call_data)
{
int rc;
char *copy;
mu_assoc_t assoc = call_data;
struct imap_list_element *key = itmv[0], *val = itmv[1];
if (key->type != imap_eltype_string || val->type != imap_eltype_string)
return MU_ERR_FAILURE;
rc = mu_assoc_install (assoc, key->v.string, &val->v.string);
copy = strdup (val->v.string);
if (!copy)
return errno;
rc = mu_assoc_install (assoc, key->v.string, copy);
if (rc == 0)
val->v.string = NULL;
return rc;
......@@ -52,10 +49,10 @@ static mu_assoc_t
create_id_assoc (void)
{
mu_assoc_t assoc;
int rc = mu_assoc_create (&assoc, sizeof (char**), MU_ASSOC_ICASE);
int rc = mu_assoc_create (&assoc, MU_ASSOC_ICASE);
if (rc)
return NULL;
mu_assoc_set_free (assoc, _id_free);
mu_assoc_set_destroy_item (assoc, mu_list_free_item);
return assoc;
}
......
......@@ -17,34 +17,27 @@
#include "mail.h"
typedef struct _alias *alias_t;
struct _alias
{
mu_list_t list;
};
static mu_assoc_t aliases;
static void
alias_free (void *data)
{
alias_t al = data;
util_slist_destroy (&al->list);
mu_list_t al = data;
util_slist_destroy (&al);
}
static void
alias_print_group (const char *name, alias_t al)
alias_print_group (const char *name, mu_list_t al)
{
mu_printf ("%s ", name);
util_slist_print (al->list, 0);
util_slist_print (al, 0);
mu_printf ("\n");
}
static alias_t
static mu_list_t
alias_lookup (const char *name)
{
return mu_assoc_ref (aliases, name);
return mu_assoc_get (aliases, name);
}
static void
......@@ -62,7 +55,7 @@ alias_print (char *name)
mu_iterator_next (itr))
{
const char *name;
alias_t al;
mu_list_t al;
if (mu_iterator_current_kv (itr, (const void **)&name, (void**)&al))
continue;
alias_print_group (name, al);
......@@ -70,7 +63,7 @@ alias_print (char *name)
}
else
{
alias_t al;
mu_list_t al;
al = alias_lookup (name);
if (!al)
......@@ -83,21 +76,25 @@ alias_print (char *name)
}
static int
alias_create (const char *name, alias_t *al)
alias_create (const char *name, mu_list_t *al)
{
int rc;
mu_list_t l;
if (!aliases)
{
mu_assoc_create (&aliases, sizeof (struct _alias), 0);
mu_assoc_set_free (aliases, alias_free);
mu_assoc_create (&aliases, 0);
mu_assoc_set_destroy_item (aliases, alias_free);
}
rc = mu_assoc_ref_install (aliases, name, (void**) al);
if (rc == MU_ERR_EXISTS)
if (mu_assoc_lookup_ref (aliases, name, al))
{
rc = mu_list_create (&l);
if (rc)
return rc;
mu_assoc_install (aliases, name, l);
*al = l;
return 0;
if (rc == 0)
return mu_list_create (&(*al)->list);
}
return 1;
}
......@@ -111,7 +108,7 @@ alias_destroy (const char *name)
static void
recursive_alias_expand (const char *name, mu_list_t exlist, mu_list_t origlist)
{
alias_t al;
mu_list_t al;
mu_iterator_t itr;
if ((al = alias_lookup (name)) == NULL)
......@@ -121,7 +118,7 @@ recursive_alias_expand (const char *name, mu_list_t exlist, mu_list_t origlist)
return;
}
mu_list_get_iterator (al->list, &itr);
mu_list_get_iterator (al, &itr);
for (mu_iterator_first (itr);
!mu_iterator_is_done (itr);
mu_iterator_next (itr))
......@@ -148,7 +145,7 @@ string_comp (const void *item, const void *value)
char *
alias_expand (const char *name)
{
alias_t al;
mu_list_t al;
mu_list_t list;
if (mailvar_get (NULL, "recursivealiases", mailvar_type_boolean, 0) == 0)
......@@ -180,7 +177,7 @@ alias_expand (const char *name)
if ((al = alias_lookup (name)) == NULL)
return NULL;
return util_slist_to_string (al->list, ",");
return util_slist_to_string (al, ",");
}
......@@ -198,7 +195,7 @@ alias_iterate_next (alias_iterator_t atr)
while (!mu_iterator_is_done (atr->itr))
{
const char *name;
alias_t al;
mu_list_t al;
if (mu_iterator_current_kv (atr->itr, (const void **)&name, (void**)&al))
continue;
......@@ -259,7 +256,7 @@ mail_alias (int argc, char **argv)
alias_print (argv[1]);
else
{
alias_t al;
mu_list_t al;
if (alias_create (argv[1], &al))
return 1;
......@@ -267,7 +264,7 @@ mail_alias (int argc, char **argv)
argc--;
argv++;
while (--argc)
util_slist_add (&al->list, *++argv);
util_slist_add (&al, *++argv);
}
return 0;
}
......
......@@ -24,13 +24,13 @@ mail_test -message "alias staff" "alias" \
mail_command "alias teeparty alice march.hare hatter"
mail_test -message "alias teeparty" "alias" \
"teeparty alice march.hare hatter"\
"staff alice tweedledum tweedledee"
"staff alice tweedledum tweedledee" \
"teeparty alice march.hare hatter"
mail_command "alias messengers haigha hatta"
mail_test -message "alias messengers" "alias" \
"teeparty alice march.hare hatter"\
"staff alice tweedledum tweedledee"\
"staff alice tweedledum tweedledee" \
"teeparty alice march.hare hatter" \
"messengers haigha hatta"
mail_command "unalias teeparty"
......@@ -46,9 +46,9 @@ mail_test -message "alias teeparty output" \
mail_command "alias pretenders lion unicorn"
mail_test -message "alias pretenders" "alias"\
"pretenders lion unicorn "\
"staff alice tweedledum tweedledee"\
"messengers haigha hatta"
"messengers haigha hatta"\
"pretenders lion unicorn"
mail_stop
......
......@@ -755,10 +755,10 @@ com_id (int argc, char **argv)
{
if (test)
{
void *res = mu_assoc_ref (assoc, test);
if (res)
char *val = mu_assoc_get (assoc, test);
if (val)
{
mu_printf ("%s: %s\n", test, *(char **)res);
mu_printf ("%s: %s\n", test, val);
}
else
mu_printf (_("%s is not set\n"), test);
......@@ -772,10 +772,10 @@ com_id (int argc, char **argv)
!mu_iterator_is_done (itr); mu_iterator_next (itr))
{
char *key;
void *val;
char *val;
mu_iterator_current_kv (itr, (const void**)&key, &val);
mu_printf ("ID: %s %s\n", key, *(char**)val);
mu_iterator_current_kv (itr, (const void**)&key, (void**)&val);
mu_printf ("ID: %s %s\n", key, val);
}
mu_iterator_destroy (&itr);
}
......