Commit 77d2867d 77d2867d07ba9d1c5b8b0af1ba8b0543cf57f384 by Sergey Poznyakoff

Rewrite property support.

* configure.ac: Add libmailutils/property/Makefile to config files.

* include/mailutils/property.h (mu_property_create)
(mu_property_destroy): Change signature.
(mu_property_get_owner): Remove.
(mu_property_create_init)
(mu_property_set_init, mu_property_set_init_data)
(mu_property_ref, mu_property_unref)
(mu_property_save): New protos.
(mu_property_get_iterator)
(mu_assoc_property_init): New protos.
* include/mailutils/sys/property.h (property_item): Remove definition.
(MU_PROP_INIT, MU_PROP_FILL, MU_PROP_MODIFIED): New flags.
(_mu_property): Rewrite from scratch.
(_mu_property_check): New proto.

* libmailutils/property/Makefile.am: New file.
* libmailutils/property/assocprop.c: New file.
* libmailutils/property/create.c: New file.
* libmailutils/property/propget.c: New file.
* libmailutils/property/propitr.c: New file.
* libmailutils/property/propset.c: New file.

* libmailutils/Makefile.am (SUBDIRS): Add property.
(libmailutils_la_LIBADD): Add property/libproperty.la.

* libmailutils/base/property.c: Remove.
* libmailutils/base/Makefile.am (libbase_la_SOURCES): Remove property.c

* libmailutils/base/assoc.c (first): Avoid coredumping on empty
hash table.

* include/mailutils/folder.h (mu_folder_set_property)
(mu_folder_get_property): New protos.
* include/mailutils/sys/folder.h (_mu_folder) <property>
<_get_property>: New members.
* libmailutils/mailbox/folder.c (mu_folder_destroy): Destroy the
property.
(mu_folder_get_property)
(mu_folder_set_property): New functions.

* include/mailutils/mailbox.h (mu_mailbox_set_property): New proto.
* libmailutils/mailbox/mailbox.c (mu_mailbox_set_property): New function.
(mu_mailbox_get_property): Use _get_property method.

* include/mailutils/mailer.h (mu_mailer_set_property): New proto.
* include/mailutils/sys/mailer.h (_mu_mailer) <_get_property>: New member.
* libmailutils/mailer/mailer.c (mu_mailer_set_property): New function.
(mu_mailer_get_property): Use _get_property method.

* include/mailutils/iterator.h (mu_iterator_set_dataptr): New proto.
* include/mailutils/sys/iterator.h (_mu_iterator) <dataptr>: New method.
* libmailutils/base/iterator.c (mu_iterator_set_dataptr): New function.
(mu_iterator_current): Rewrite as a wrapper around mu_iterator_current_kv.
(mu_iterator_current_kv): Use dataptr method (if defined) to extract the
data pointer.

* libmailutils/tests/prop.c: New file.
* libmailutils/tests/prop.at: New file.
* libmailutils/tests/Makefile.am (noinst_PROGRAMS): Add prop.
(TESTSUITE_AT): Add prop.at.
* libmailutils/tests/testsuite.at: Include prop.at.
1 parent 33a277e9
......@@ -1389,6 +1389,7 @@ AC_CONFIG_FILES([
libmailutils/mailbox/Makefile
libmailutils/mailer/Makefile
libmailutils/mime/Makefile
libmailutils/property/Makefile
libmailutils/server/Makefile
libmailutils/string/Makefile
libmailutils/stream/Makefile
......
......@@ -89,6 +89,10 @@ extern int mu_folder_set_authority (mu_folder_t, mu_authority_t);
extern int mu_folder_get_url (mu_folder_t, mu_url_t *);
extern int mu_folder_set_url (mu_folder_t, mu_url_t);
/* Property */
extern int mu_folder_set_property (mu_folder_t, mu_property_t);
extern int mu_folder_get_property (mu_folder_t, mu_property_t *);
/* FIXME: not implemented */
extern int mu_folder_decrement (mu_folder_t);
......
......@@ -72,6 +72,8 @@ extern int mu_iterator_set_itrctl (mu_iterator_t itr,
int (*itrctl) (void *,
enum mu_itrctl_req,
void *));
extern int mu_iterator_set_dataptr (mu_iterator_t itr,
void *(*dataptr) (void *));
#ifdef __cplusplus
}
#endif
......
......@@ -97,6 +97,7 @@ extern int mu_mailbox_set_locker (mu_mailbox_t, mu_locker_t);
/* Property. */
extern int mu_mailbox_get_flags (mu_mailbox_t, int *);
extern int mu_mailbox_get_property (mu_mailbox_t, mu_property_t *);
extern int mu_mailbox_set_property (mu_mailbox_t, mu_property_t);
/* URL. */
extern int mu_mailbox_get_url (mu_mailbox_t, mu_url_t *);
......
......@@ -50,6 +50,8 @@ extern int mu_mailer_get_url_default (const char** url);
/* Accessor functions. */
extern int mu_mailer_get_property (mu_mailer_t, mu_property_t *);
int mu_mailer_set_property (mu_mailer_t, mu_property_t);
extern int mu_mailer_get_stream (mu_mailer_t, mu_stream_t *)
__attribute__ ((deprecated));
extern int mu_mailer_get_streamref (mu_mailer_t, mu_stream_t *);
......
......@@ -27,23 +27,36 @@
extern "C" {
#endif
extern int mu_property_create (mu_property_t *, void *);
extern void mu_property_destroy (mu_property_t *, void *);
extern void *mu_property_get_owner (mu_property_t);
extern int mu_property_set_value (mu_property_t, const char *, const char *, int);
extern int mu_property_get_value (mu_property_t, const char *, char *, size_t,
size_t *);
extern int mu_property_sget_value (mu_property_t prop, const char *key,
const char **buffer);
extern int mu_property_aget_value (mu_property_t prop, const char *key,
char **buffer);
int mu_property_create (mu_property_t *);
int mu_property_create_init (mu_property_t *pprop,
int (*initfun) (mu_property_t), void *initdata);
int mu_property_set_init (mu_property_t prop,
int (*initfun) (mu_property_t), void *initdata);
int mu_property_set_init_data (mu_property_t prop, void *data,
void **old_data);
void mu_property_destroy (mu_property_t *pprop);
void mu_property_ref (mu_property_t prop);
void mu_property_unref (mu_property_t prop);
int mu_property_save (mu_property_t prop);
int mu_property_set_value (mu_property_t, const char *, const char *, int);
int mu_property_get_value (mu_property_t, const char *, char *, size_t,
size_t *);
int mu_property_sget_value (mu_property_t prop, const char *key,
const char **buffer);
int mu_property_aget_value (mu_property_t prop, const char *key,
char **buffer);
/* Helper functions. */
extern int mu_property_set (mu_property_t, const char *);
extern int mu_property_unset (mu_property_t, const char *);
extern int mu_property_is_set (mu_property_t, const char *);
int mu_property_set (mu_property_t, const char *);
int mu_property_unset (mu_property_t, const char *);
int mu_property_is_set (mu_property_t, const char *);
int mu_property_get_iterator (mu_property_t, mu_iterator_t *itr);
/* Implementation init functions */
int mu_assoc_property_init (mu_property_t);
#ifdef __cplusplus
}
#endif
......
......@@ -38,6 +38,7 @@ struct _mu_folder
mu_authority_t authority;
mu_observable_t observable;
mu_debug_t debug;
mu_property_t property;
mu_stream_t stream;
mu_monitor_t monitor;
mu_url_t url;
......@@ -63,6 +64,7 @@ struct _mu_folder
int (*_rename) (mu_folder_t, const char *, const char *);
int (*_subscribe) (mu_folder_t, const char *);
int (*_unsubscribe) (mu_folder_t, const char *);
int (*_get_property)(mu_folder_t, mu_property_t *);
};
# ifdef __cplusplus
......
......@@ -39,6 +39,7 @@ struct _mu_iterator
int (*curitem_p) (void *owner, void *item);
int (*finished_p) (void *owner);
int (*itrctl) (void *owner, enum mu_itrctl_req req, void *arg);
void *(*dataptr) (void *);
};
# ifdef __cplusplus
......
......@@ -51,6 +51,7 @@ struct _mu_mailer
int (*_open) (mu_mailer_t, int flags);
int (*_close) (mu_mailer_t);
int (*_send_message) (mu_mailer_t, mu_message_t, mu_address_t, mu_address_t);
int (*_get_property) (mu_mailer_t, mu_property_t *);
};
int _mu_mailer_mailbox_init (mu_mailbox_t mailbox);
......
......@@ -31,18 +31,41 @@
extern "C" {
# endif
struct property_item
{
char *value;
};
#define MU_PROP_INIT 0x01
#define MU_PROP_FILL 0x02
#define MU_PROP_MODIFIED 0x04
struct _mu_property
{
mu_assoc_t assoc;
void *owner;
mu_monitor_t lock;
size_t _prop_ref_count; /* Reference counter */
int _prop_flags; /* Flags describing the state of this object */
void *_prop_data; /* Implementation-specific data */
void *_prop_init_data; /* Initialization data */
/* Methods */
/* Delayed initialization. This function must allocate _prop_data,
if needed, and initialize the rest of _prop_* methods. */
int (*_prop_init) (struct _mu_property *);
/* Free memory allocated in _prop_data */
void (*_prop_done) (struct _mu_property *);
/* Fill in the properties from an external storage */
int (*_prop_fill) (struct _mu_property *);
/* Write the properties to an external storage */
int (*_prop_save) (struct _mu_property *);
/* Get the value of the property named in the 2nd argument. If 3rd
arg is NULL, _prop_getval tests whether the given property is set. */
int (*_prop_getval) (struct _mu_property *, const char *, const char **);
/* Set the property */
int (*_prop_setval) (struct _mu_property *, const char *, const char *, int);
/* Unset (delete) the property */
int (*_prop_unset) (struct _mu_property *, const char *);
/* Return iterator for this property object */
int (*_prop_getitr) (struct _mu_property *, mu_iterator_t *);
};
int _mu_property_check (mu_property_t prop);
# ifdef __cplusplus
}
# endif
......
......@@ -17,7 +17,7 @@
# <http://www.gnu.org/licenses/>.
SUBDIRS = auth base address cfg diag filter mailbox mailer mime\
server string stream url . tests
server string stream property url . tests
lib_LTLIBRARIES = libmailutils.la
......@@ -34,6 +34,7 @@ libmailutils_la_LIBADD = \
mailbox/libmailbox.la\
mailer/libmailer.la\
mime/libmime.la\
property/libproperty.la\
server/libserver.la\
string/libstring.la\
stream/libstream.la\
......
......@@ -52,7 +52,6 @@ libbase_la_SOURCES = \
opool.c\
parsedate.c\
permstr.c\
property.c\
registrar.c\
refcount.c\
rfc2047.c\
......
......@@ -391,10 +391,11 @@ first (void *owner)
mu_assoc_t assoc = itr->assoc;
unsigned hash_max = hash_size[assoc->hash_num];
unsigned i;
for (i = 0; i < hash_max; i++)
if ((ASSOC_ELEM (assoc, i))->name)
break;
if (assoc->tab)
for (i = 0; i < hash_max; i++)
if ((ASSOC_ELEM (assoc, i))->name)
break;
itr->index = i;
return 0;
}
......
......@@ -103,6 +103,15 @@ mu_iterator_set_itrctl (mu_iterator_t itr,
}
int
mu_iterator_set_dataptr (mu_iterator_t itr, void *(*dataptr) (void *))
{
if (!itr)
return EINVAL;
itr->dataptr = dataptr;
return 0;
}
int
mu_iterator_set_destroy (mu_iterator_t itr, int (*destroy) (mu_iterator_t, void *))
{
if (!itr)
......@@ -202,14 +211,23 @@ mu_iterator_skip (mu_iterator_t iterator, ssize_t count)
int
mu_iterator_current (mu_iterator_t iterator, void **pitem)
{
return iterator->getitem (iterator->owner, pitem, NULL);
return mu_iterator_current_kv (iterator, NULL, pitem);
}
int
mu_iterator_current_kv (mu_iterator_t iterator,
const void **pkey, void **pitem)
{
return iterator->getitem (iterator->owner, (void**)pitem, pkey);
void *ptr;
int rc = iterator->getitem (iterator->owner, &ptr, pkey);
if (rc == 0)
{
if (iterator->dataptr)
*pitem = iterator->dataptr (ptr);
else
*pitem = ptr;
}
return rc;
}
int
......
......@@ -35,6 +35,7 @@
#include <mailutils/stream.h>
#include <mailutils/url.h>
#include <mailutils/errno.h>
#include <mailutils/property.h>
#include <mailutils/sys/folder.h>
......@@ -208,6 +209,8 @@ mu_folder_destroy (mu_folder_t *pfolder)
mu_stream_destroy (&folder->stream);
if (folder->url)
mu_url_destroy (&folder->url);
if (folder->property)
mu_property_destroy (&folder->property);
free (folder);
}
mu_monitor_unlock (monitor);
......@@ -217,6 +220,31 @@ mu_folder_destroy (mu_folder_t *pfolder)
}
}
int
mu_folder_get_property (mu_folder_t folder, mu_property_t *prop)
{
if (folder == NULL)
return EINVAL;
if (prop == NULL)
return MU_ERR_OUT_PTR_NULL;
if (folder->property == NULL)
{
int status;
if (folder->_get_property)
status = folder->_get_property (folder, &folder->property);
else
status = mu_property_create_init (&folder->property,
mu_assoc_property_init, NULL);
if (status != 0)
return status;
}
*prop = folder->property;
return 0;
}
/* Cover functions. */
int
mu_folder_open (mu_folder_t folder, int flags)
......
......@@ -272,7 +272,7 @@ mu_mailbox_destroy (mu_mailbox_t *pmbox)
mu_folder_destroy (&mbox->folder);
if (mbox->property)
mu_property_destroy (&mbox->property, mbox);
mu_property_destroy (&mbox->property);
free (mbox);
*pmbox = NULL;
......@@ -648,6 +648,18 @@ mu_mailbox_get_observable (mu_mailbox_t mbox, mu_observable_t *pobservable)
}
int
mu_mailbox_set_property (mu_mailbox_t mbox, mu_property_t property)
{
if (mbox == NULL)
return MU_ERR_MBX_NULL;
if (mbox->property)
mu_property_unref (mbox->property);
mbox->property = property;
mu_property_ref (property);
return 0;
}
int
mu_mailbox_get_property (mu_mailbox_t mbox, mu_property_t *pproperty)
{
if (mbox == NULL)
......@@ -657,7 +669,13 @@ mu_mailbox_get_property (mu_mailbox_t mbox, mu_property_t *pproperty)
if (mbox->property == NULL)
{
int status = mu_property_create (&mbox->property, mbox);
int status;
if (mbox->_get_property)
status = mbox->_get_property (mbox, &mbox->property);
else
status = mu_property_create_init (&mbox->property,
mu_assoc_property_init, NULL);
if (status != 0)
return status;
}
......
......@@ -210,7 +210,7 @@ mu_mailer_destroy (mu_mailer_t * pmailer)
mu_debug_destroy (&(mailer->debug), mailer);
if (mailer->property)
mu_property_destroy (&(mailer->property), mailer);
mu_property_destroy (&mailer->property);
free (mailer);
*pmailer = NULL;
......@@ -706,6 +706,18 @@ mu_mailer_get_observable (mu_mailer_t mailer, mu_observable_t * pobservable)
}
int
mu_mailer_set_property (mu_mailer_t mailer, mu_property_t property)
{
if (mailer == NULL)
return EINVAL;
if (mailer->property)
mu_property_unref (mailer->property);
mailer->property = property;
mu_property_ref (property);
return 0;
}
int
mu_mailer_get_property (mu_mailer_t mailer, mu_property_t * pproperty)
{
if (mailer == NULL)
......@@ -714,7 +726,13 @@ mu_mailer_get_property (mu_mailer_t mailer, mu_property_t * pproperty)
return MU_ERR_OUT_PTR_NULL;
if (mailer->property == NULL)
{
int status = mu_property_create (&(mailer->property), mailer);
int status;
if (mailer->_get_property)
status = mailer->_get_property (mailer, &mailer->property);
else
status = mu_property_create_init (&mailer->property,
mu_assoc_property_init, NULL);
if (status != 0)
return status;
}
......
# GNU Mailutils -- a suite of utilities for electronic mail
# Copyright (C) 2010 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/>.
noinst_LTLIBRARIES = libproperty.la
libproperty_la_SOURCES = \
assocprop.c\
create.c\
propget.c\
propitr.c\
propset.c
INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010 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/>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <mailutils/sys/property.h>
#include <mailutils/errno.h>
#include <mailutils/assoc.h>
#include <mailutils/stream.h>
#include <mailutils/iterator.h>
#include <stdlib.h>
struct property_item
{
char *value;
};
static void
_assoc_prop_done (struct _mu_property *prop)
{
mu_assoc_t assoc = prop->_prop_data;
mu_stream_t str = prop->_prop_init_data;
mu_assoc_destroy (&assoc);
mu_stream_destroy (&str);
}
static int
_assoc_prop_getval (struct _mu_property *prop,
const char *key, const char **pval)
{
mu_assoc_t assoc = prop->_prop_data;
struct property_item *item;
item = mu_assoc_ref (assoc, key);
if (item == NULL)
return MU_ERR_NOENT;
if (pval)
*pval = item->value;
return 0;
}
static int
_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;
int rc;
rc = mu_assoc_ref_install (assoc, key, (void **)&item);
if (rc == MU_ERR_NOENT)
{
item->value = strdup (val);
if (!item->value)
{
mu_assoc_remove (assoc, key);
return ENOMEM;
}
}
else if (overwrite)
{
char *newval = strdup (val);
if (!newval)
return ENOMEM;
free (item->value);
item->value = newval;
}
else
return MU_ERR_EXISTS;
return 0;
}
static int
_assoc_prop_unset (struct _mu_property *prop, const char *key)
{
mu_assoc_t assoc = prop->_prop_data;
return mu_assoc_remove (assoc, key);
}
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)
{
int rc;
mu_iterator_t itr;
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)
{
int rc;
mu_stream_t str = prop->_prop_init_data;
int state = 0;
char *buf[2] = { NULL, NULL };
size_t size[2] = { 0, 0 }, n;
if (!str)
return EINVAL;
mu_stream_seek (str, 0, MU_SEEK_SET, NULL);
while ((rc = mu_stream_getdelim (str, &buf[state], &size[state],
0, &n)) == 0 &&
n > 0)
{
if (state == 1)
_assoc_prop_setval (prop, buf[0], buf[1], 1);
state = !state;
}
free (buf[0]);
free (buf[1]);
return rc;
}
static int
_assoc_prop_save (struct _mu_property *prop)
{
mu_stream_t str = prop->_prop_init_data;
mu_iterator_t itr;
int rc;
mu_off_t off;
if (!str)
return EINVAL;
rc = mu_property_get_iterator (prop, &itr);
if (rc)
return rc;
mu_stream_seek (str, 0, MU_SEEK_SET, NULL);
for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
mu_iterator_next (itr))
{
const char *name, *val;
mu_iterator_current_kv (itr, (const void **)&name, (void**)&val);
rc = mu_stream_write (str, name, strlen (name) + 1, NULL);
if (rc)
break;
rc = mu_stream_write (str, val, strlen (val) + 1, NULL);
if (rc)
break;
}
mu_iterator_destroy (&itr);
rc = mu_stream_seek (str, 0, MU_SEEK_CUR, &off);
if (rc == 0)
rc = mu_stream_truncate (str, off);
return rc;
}
int
mu_assoc_property_init (struct _mu_property *prop)
{
mu_assoc_t assoc;
int rc;
rc = mu_assoc_create (&assoc, sizeof (struct property_item), 0);
if (rc)
return rc;
mu_assoc_set_free (assoc, prop_free_value);
prop->_prop_data = assoc;
prop->_prop_done = _assoc_prop_done;
if (prop->_prop_init_data)
{
mu_stream_t str = prop->_prop_init_data;
mu_stream_ref (str);
prop->_prop_fill = _assoc_prop_fill;
prop->_prop_save = _assoc_prop_save;
}
else
{
prop->_prop_fill = NULL;
prop->_prop_save = NULL;
}
prop->_prop_getval = _assoc_prop_getval;
prop->_prop_setval = _assoc_prop_setval;
prop->_prop_unset = _assoc_prop_unset;
prop->_prop_getitr = _assoc_prop_getitr;
return 0;
}
......@@ -19,173 +19,148 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <mailutils/sys/property.h>
#include <mailutils/types.h>
#include <mailutils/errno.h>
#include <mailutils/assoc.h>
#include <stdlib.h>
#include <mailutils/sys/property.h>
static void
prop_free_value (void *data)
int
mu_property_create (mu_property_t *pprop)
{
struct property_item *item = data;
free (item->value);
mu_property_t prop = calloc (1, sizeof (prop[0]));
if (!prop)
return ENOMEM;
*pprop = prop;
return 0;
}
int
mu_property_create (mu_property_t *pp, void *owner)
mu_property_create_init (mu_property_t *pprop,
int (*initfun) (mu_property_t), void *initdata)
{
int rc;
mu_property_t prop;
if (pp == NULL)
return MU_ERR_OUT_PTR_NULL;
prop = calloc (1, sizeof *prop);
if (prop == NULL)
return ENOMEM;
rc = mu_assoc_create (&prop->assoc, sizeof (struct property_item), 0);
if (rc)
int rc = mu_property_create (&prop);
if (rc == 0)
{
free (prop);
return rc;
mu_property_set_init (prop, initfun, initdata);
*pprop = prop;
}
mu_assoc_set_free (prop->assoc, prop_free_value);
mu_monitor_create (&prop->lock, 0, prop);
prop->owner = owner;
*pp = prop;
return 0;
}
int
mu_property_set_init (mu_property_t prop,
int (*initfun) (mu_property_t), void *initdata)
{
if (!prop)
return ENOMEM;
if (prop->_prop_flags & MU_PROP_INIT)
return MU_ERR_SEQ;
prop->_prop_init = initfun;
prop->_prop_init_data = initdata;
return 0;
}
int
mu_property_set_init_data (mu_property_t prop, void *data, void **old_data)
{
if (!prop)
return ENOMEM;
if (prop->_prop_flags & MU_PROP_INIT)
return MU_ERR_SEQ;
if (old_data)
*old_data = prop->_prop_init_data;
prop->_prop_init_data = data;
return 0;
}
void
mu_property_destroy (mu_property_t *pp, void *owner)
mu_property_destroy (mu_property_t *pprop)
{
if (pp && *pp)
if (pprop)
{
mu_property_t prop = *pp;
if (prop->owner == owner)
mu_property_t prop = *pprop;
if (prop && (prop->_prop_ref_count == 0 || --prop->_prop_ref_count == 0))
{
/* Destroy the list and is properties. */
mu_monitor_wrlock (prop->lock);
mu_assoc_destroy (&prop->assoc);
mu_monitor_unlock (prop->lock);
mu_monitor_destroy (&prop->lock, prop);
mu_property_save (prop);
if (prop->_prop_done)
prop->_prop_done (prop);
free (prop);
*pprop = NULL;
}
*pp = NULL;
}
}
void *
mu_property_get_owner (mu_property_t prop)
void
mu_property_ref (mu_property_t prop)
{
return (prop == NULL) ? NULL : prop->owner;
if (prop)
prop->_prop_ref_count++;
}
int
mu_property_set_value (mu_property_t prop, const char *key, const char *value,
int overwrite)
void
mu_property_unref (mu_property_t prop)
{
struct property_item *item;
int rc;
if (!prop)
return EINVAL;
rc = mu_assoc_ref_install (prop->assoc, key, (void **)&item);
if (rc == MU_ERR_NOENT)
{
item->value = strdup (value);
}
else if (overwrite)
{
free (item->value);
item->value = strdup (value);
}
else
return 0;
if (!item->value)
{
mu_assoc_remove (prop->assoc, key);
return ENOMEM;
}
return 0;
mu_property_destroy (&prop);
}
int
mu_property_sget_value (mu_property_t prop, const char *key,
const char **buffer)
mu_property_save (mu_property_t prop)
{
struct property_item *item;
int rc = 0;
if (!prop)
return EINVAL;
item = mu_assoc_ref (prop->assoc, key);
if (item == NULL)
return MU_ERR_NOENT;
if (buffer)
*buffer = item->value;
return 0;
}
int
mu_property_aget_value (mu_property_t prop, const char *key,
char **buffer)
{
const char *value;
int rc = mu_property_sget_value (prop, key, &value);
if (rc == 0)
if (prop->_prop_flags & MU_PROP_MODIFIED)
{
if ((*buffer = strdup (value)) == NULL)
return ENOMEM;
if (prop->_prop_save)
rc = prop->_prop_save (prop);
if (rc == 0)
prop->_prop_flags &= ~MU_PROP_MODIFIED;
}
return rc;
}
int
mu_property_get_value (mu_property_t prop, const char *key, char *buffer,
size_t buflen, size_t *n)
static int
_mu_property_init (mu_property_t prop)
{
size_t len = 0;
const char *value;
int rc = mu_property_sget_value (prop, key, &value);
if (rc == 0)
int rc = 0;
if (!(prop->_prop_flags & MU_PROP_INIT))
{
len = strlen (value) + 1;
if (buffer && buflen)
{
if (buflen < len)
len = buflen;
len--;
memcpy (buffer, value, len);
buffer[len] = 0;
}
if (prop->_prop_init)
rc = prop->_prop_init (prop);
if (rc == 0)
prop->_prop_flags |= MU_PROP_INIT;
}
if (n)
*n = len;
return rc;
}
int
mu_property_is_set (mu_property_t prop, const char *key)
{
struct property_item *item = mu_assoc_ref (prop->assoc, key);
return (item == NULL) ? 0 : 1;
}
int
mu_property_set (mu_property_t prop, const char *key)
static int
_mu_property_fill (mu_property_t prop)
{
return mu_property_set_value (prop, key, "", 1);
int rc = 0;
if (!(prop->_prop_flags & MU_PROP_FILL))
{
if (prop->_prop_fill)
rc = prop->_prop_fill (prop);
if (rc == 0)
prop->_prop_flags |= MU_PROP_FILL;
}
return rc;
}
int
mu_property_unset (mu_property_t prop, const char *key)
_mu_property_check (mu_property_t prop)
{
int rc;
if (!prop)
return EINVAL;
return mu_assoc_remove (prop->assoc, key);
rc = _mu_property_init (prop);
if (rc == 0)
rc = _mu_property_fill (prop);
return rc;
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010 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/>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <mailutils/types.h>
#include <mailutils/errno.h>
#include <mailutils/sys/property.h>
int
mu_property_sget_value (mu_property_t prop, const char *key,
const char **pval)
{
int rc = _mu_property_check (prop);
if (rc)
return rc;
if (!prop->_prop_getval)
return MU_ERR_EMPTY_VFN;
return prop->_prop_getval (prop, key, pval);
}
int
mu_property_aget_value (mu_property_t prop, const char *key,
char **buffer)
{
const char *value;
int rc = mu_property_sget_value (prop, key, &value);
if (rc == 0)
{
if ((*buffer = strdup (value)) == NULL)
return ENOMEM;
}
return rc;
}
int
mu_property_get_value (mu_property_t prop, const char *key, char *buffer,
size_t buflen, size_t *n)
{
size_t len = 0;
const char *value;
int rc = mu_property_sget_value (prop, key, &value);
if (rc == 0)
{
len = strlen (value) + 1;
if (buffer && buflen)
{
if (buflen < len)
len = buflen;
len--;
memcpy (buffer, value, len);
buffer[len] = 0;
}
}
if (n)
*n = len;
return rc;
}
int
mu_property_is_set (mu_property_t prop, const char *key)
{
if (_mu_property_check (prop))
return 0;
return mu_property_sget_value (prop, key, NULL) == 0;
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010 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/>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <mailutils/types.h>
#include <mailutils/errno.h>
#include <mailutils/sys/property.h>
int
mu_property_get_iterator (mu_property_t prop, mu_iterator_t *pitr)
{
int rc = _mu_property_check (prop);
if (rc)
return rc;
if (!prop->_prop_getitr)
return MU_ERR_EMPTY_VFN;
return prop->_prop_getitr (prop, pitr);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2004, 2005, 2007, 2008, 2010 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/>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <mailutils/types.h>
#include <mailutils/errno.h>
#include <mailutils/sys/property.h>
int
mu_property_set_value (mu_property_t prop, const char *key,
const char *value, int overwrite)
{
int rc = _mu_property_check (prop);
if (rc)
return rc;
if (!prop->_prop_setval)
return MU_ERR_EMPTY_VFN;
rc = prop->_prop_setval (prop, key, value, overwrite);
if (rc == 0)
prop->_prop_flags |= MU_PROP_MODIFIED;
return rc;
}
int
mu_property_unset (mu_property_t prop, const char *key)
{
int rc = _mu_property_check (prop);
if (rc)
return rc;
if (!prop->_prop_unset)
return MU_ERR_EMPTY_VFN;
rc = prop->_prop_unset (prop, key);
if (rc == 0)
prop->_prop_flags |= MU_PROP_MODIFIED;
return rc;
}
int
mu_property_set (mu_property_t prop, const char *key)
{
return mu_property_set_value (prop, key, "", 1);
}
......@@ -11,6 +11,7 @@ encode2047
fltst
listop
mailcap
prop
url-parse
wicket
wsp
......
......@@ -47,6 +47,7 @@ noinst_PROGRAMS = \
fltst\
listop\
mailcap\
prop\
url-parse\
wicket\
wsp
......@@ -69,6 +70,7 @@ TESTSUITE_AT = \
fromflt.at\
list.at\
mailcap.at\
prop.at\
testsuite.at\
url.at\
wicket.at\
......
# This file is part of GNU Mailutils. -*- Autotest -*-
# Copyright (C) 2010 Free Software Foundation, Inc.
#
# GNU Mailutils is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3, or (at
# your option) any later version.
#
# This program 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
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
# This file is part of Mailfromd testsuite.
dnl ------------------------------------------------------------------
dnl TESTPROP([NAME], [KW = `'], [PROG], [STDOUT = `'], [STDERR = `'])
dnl
m4_pushdef([TESTPROP],[
AT_SETUP([prop: $1])
AT_KEYWORDS([prop $2])
AT_CHECK([$3],[0],[$4],[$5])
AT_CLEANUP])
TESTPROP([set],[prop00],[
prop foo=bar ?foo +foo
],
[0: foo=bar: Success
1: foo is set
2: foo=bar
])
TESTPROP([overwrite],[prop01],[
prop foo=bar foo=baz +foo
],
[0: foo=bar: Success
1: foo=baz: Success
2: foo=baz
])
TESTPROP([set without overwrite],[prop03],[
prop foo=bar foo:=baz +foo
],
[0: foo=bar: Success
1: foo=baz: Item already exists
2: foo=bar
])
TESTPROP([set/unset],[prop04],[
prop foo=bar ?foo +foo -foo ?foo
],
[0: foo=bar: Success
1: foo is set
2: foo=bar
3: unset foo: Success
4: foo is not set
])
TESTPROP([read/save],[prop06],[
prop --file=db user=gray package=mailutils org=GNU test=6.a
if test -f db; then
prop --file=db | sort
else
echo 2>&1 "failed to create file"
exit 1
fi
prop --file=db -test
prop --file=db | sort
prop --file=db test=6.b descr="New test"
prop --file=db | sort
],
[0: user=gray: Success
1: package=mailutils: Success
2: org=GNU: Success
3: test=6.a: Success
Property dump:
org=GNU
package=mailutils
test=6.a
user=gray
0: unset test: Success
Property dump:
org=GNU
package=mailutils
user=gray
0: test=6.b: Success
1: descr=New test: Success
Property dump:
descr=New test
org=GNU
package=mailutils
test=6.b
user=gray
])
m4_popdef([TESTPROP])
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2010 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <mailutils/mailutils.h>
void
help (char *progname)
{
printf ("usage: %s [--file=NAME] [--dump] [COMMAND...]\n", progname);
printf ("Valid COMMANDs are:\n");
printf (" X=Y set property X to value Y\n");
printf (" X:=Y same, but fail if X has already been set\n");
printf (" ?X query whether X is set\n");
printf (" +X query the value of the property X\n");
printf (" -X unset property X\n");
exit (0);
}
int
main (int argc, char **argv)
{
mu_property_t prop;
mu_iterator_t itr;
int i, j, rc;
char *filename = NULL;
int dumpit = 0;
mu_stream_t str = NULL;
if (argc == 1)
help (argv[0]);
for (i = 1; i < argc; i++)
{
if (!(argv[i][0] == '-' && argv[i][1] == '-'))
break;
if (strcmp (argv[i], "--help") == 0)
help (argv[0]);
else if (strncmp (argv[i], "--file=", 7) == 0)
filename = argv[i] + 7;
else if (strcmp (argv[i], "--dump") == 0)
dumpit = 1;
else
{
mu_error ("unknown switch: %s", argv[i]);
return 1;
}
}
if (filename)
{
MU_ASSERT (mu_file_stream_create (&str, filename,
MU_STREAM_RDWR|MU_STREAM_CREAT));
mu_stream_unref (str);
if (i == argc)
dumpit = 1;
}
MU_ASSERT (mu_property_create_init (&prop, mu_assoc_property_init, str));
for (j = 0; i < argc; i++, j++)
{
char *key = argv[i];
char *p = strchr (key, '=');
if (p)
{
int override;
if (p > key && p[-1] == ':')
{
override = 0;
p[-1] = 0;
}
else
{
override = 1;
*p = 0;
}
p++;
rc = mu_property_set_value (prop, key, p, override);
printf ("%d: %s=%s: %s\n",
j, key, p, mu_strerror (rc));
}
else if (key[0] == '?')
{
key++;
rc = mu_property_is_set (prop, key);
printf ("%d: %s is %s\n", j, key, rc ? "set" : "not set");
}
else if (key[0] == '-')
{
key++;
rc = mu_property_unset (prop, key);
printf ("%d: unset %s: %s\n", j, key, mu_strerror (rc));
}
else if (key[0] == '+')
{
const char *val;
key++;
rc = mu_property_sget_value (prop, key, &val);
if (rc)
printf ("%d: cannot get %s: %s\n", j, key, mu_strerror (rc));
else
printf ("%d: %s=%s\n", j, key, val);
}
else
{
mu_error ("%d: unrecognized command", i);
}
}
if (dumpit)
{
if (mu_property_get_iterator (prop, &itr) == 0)
{
printf ("Property dump:\n");
for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
mu_iterator_next (itr))
{
const char *name, *val;
mu_iterator_current_kv (itr, (const void **)&name, (void**)&val);
printf ("%s=%s\n", name, val);
}
mu_iterator_destroy (&itr);
}
}
mu_property_destroy (&prop);
return 0;
}
......@@ -65,4 +65,5 @@ m4_include([decode2047.at])
m4_include([encode2047.at])
m4_include([fromflt.at])
m4_include([wicket.at])
m4_include([prop.at])
......