aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac199
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/cache.c106
-rw-r--r--lib/db.c294
-rw-r--r--lib/dbcfg.c15
-rw-r--r--lib/greylist.c12
-rw-r--r--lib/libmf.h1
-rw-r--r--lib/mf-dbm.c658
-rw-r--r--lib/mf-dbm.h75
-rw-r--r--lib/mfdb.h9
-rw-r--r--lib/rate.c67
-rw-r--r--lib/tbf_rate.c60
-rw-r--r--lib/utils.c9
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/Makefile.am3
-rw-r--r--src/builtin/db.bi410
-rw-r--r--src/calloutd.c2
-rw-r--r--src/main.c52
-rw-r--r--src/mfdbtool.c76
-rw-r--r--src/savsrv.c1
-rw-r--r--src/srvcfg.c19
21 files changed, 670 insertions, 1403 deletions
diff --git a/configure.ac b/configure.ac
index 0e975fc6..136e037b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -105,13 +105,13 @@ gl_INIT
AH_BOTTOM([
/* program_name is used by lib/error.c */
#define program_name program_invocation_name
])
# Check for GNU Mailutils
-AM_GNU_MAILUTILS([2.99.94], [all auth sieve cfg argp], [:])
+AM_GNU_MAILUTILS([2.99.94], [all auth dbm sieve cfg argp], [:])
AC_CHECK_TYPES([struct mu_argp_node_list],,,[#include <mailutils/libargp.h>])
### Check for Emacs site-lisp directory
AM_PATH_LISPDIR
if test "$EMACS" != "no"; then
@@ -142,200 +142,47 @@ if test $syslog_async = "yes"; then
AC_DEFINE_UNQUOTED([DEFAULT_SYSLOG_ASYNC],$DEFAULT_SYSLOG_ASYNC,
[Define to 1 to use syslog_async by default])
AC_SUBST([BUILD_SYSLOG_ASYNC], '$(SYSLOG_ASYNC_O)')
AC_DEFINE([USE_SYSLOG_ASYNC], [1], [Define if syslog-async is being used])
fi
-# Check for DBM flavor
-AH_TEMPLATE(BDB2_CURSOR_LASTARG,
- [Last argument to the cursor member of Berkeley 2 DB structure])
-
-dnl The cursor member of DB structure used to take three arguments in older
-dnl implementations of Berkeley DB. Newer versions (>= 4.0) declare
-dnl it as taking four arguments.
-dnl This macro checks which of the variants we have.
-AC_DEFUN([MU_DB2_CURSOR],
- [AC_CACHE_CHECK([whether db->cursor takes 4 arguments],
- [mu_cv_bdb2_cursor_four_args],
- [AC_TRY_COMPILE([#include <db.h>],
- [
-DB *db;
-db->cursor(NULL, NULL, NULL, 0)
- ],
- [mu_cv_bdb2_cursor_four_args=yes],
- [mu_cv_bdb2_cursor_four_args=no])])
- if test $mu_cv_bdb2_cursor_four_args = yes; then
- AC_DEFINE(BDB2_CURSOR_LASTARG,[,0])
- else
- AC_DEFINE(BDB2_CURSOR_LASTARG,[])
- fi])
-
-AH_TEMPLATE([WITH_BDB],
- [Define to the major version of Berkeley DB library to use])
-
-use_dbm=no
-status_dbm=no
-
+AC_ARG_VAR([DEFAULT_DB_TYPE],[Set default database type])
+
AC_ARG_WITH([gdbm],
- AC_HELP_STRING([--with-gdbm],
- [use GNU DBM]),
+ AC_HELP_STRING([--with-gdbm],
+ [use GNU DBM by default]),
[
case "${withval}" in
- yes) use_dbm=GDBM ;;
- no) use_dbm=no ;;
+ yes) DEFAULT_DB_TYPE=gdbm;;
+ no) ;;
*) AC_MSG_ERROR(bad value ${withval} for --with-gdbm) ;;
esac])
-## Support --with-db2 for backward compatibility
-if test "${with_db2+set}" = set; then
- case "${with_db2}" in
- yes) use_dbm=BDB2 ;;
- no) use_dbm=no ;;
- *) AC_MSG_ERROR(bad value ${with_db2} for --with-db2) ;;
- esac
-fi
-
AC_ARG_WITH([berkeley-db],
- AC_HELP_STRING([--with-berkeley-db@<:@=version@:>@],
- [use Berkeley DB]),
+ AC_HELP_STRING([--with-berkeley-db],
+ [use Berkeley DB by default]),
[
case "${withval}" in
- yes) use_dbm=BDB ;;
- no) use_dbm=no ;;
- *) use_dbm=BDB="${withval}";;
+ no) ;;
+ *) DEFAULT_DB_TYPE=bdb;;
esac])
-## Set the variable status_dbm to $1 if:
-##
-## 1. Function $3 is defined in the library $2
-## 2. Header file db.h is available
-##
-## Then check if the major version, minor version and patchlevel of the
-## library matches those from the header. If so, define WITH_BDB
-## to the version (i.e. $1 with all dots removed). Otherwise, report
-## an error and stop.
-##
-check_bdb() {
- ver=`echo $1 | tr -d '.'`
- major=`expr $ver : '\(.\).*'`
- AC_CHECK_LIB($2, $3,
- [AC_CHECK_HEADERS(db.h)
- if test $ac_cv_header_db_h = yes; then
- LIBS="$LIBS -l$2"
- MU_DB2_CURSOR
- status_dbm=$1
- fi])
- if test $status_dbm = no; then
- :
- else
- AC_RUN_IFELSE(
- [AC_LANG_PROGRAM([#include "db.h"],
- [int v_major, v_minor, v_patch;
- db_version(&v_major, &v_minor, &v_patch);
- return !(DB_VERSION_MAJOR == $major
- && v_major == DB_VERSION_MAJOR
- && v_minor == DB_VERSION_MINOR
- && v_patch == DB_VERSION_PATCH);
- ])],
- [AC_DEFINE_UNQUOTED(WITH_BDB,$ver)],
- [status_dbm=no])
- fi
-}
-
-AC_SUBST(MU_COMMON_INCLUDES)
-
-## Check for the Berkeley DB library version $1, assuming Slackware-like
-## installation layout (header files in /usr/incude/db$vn and library named
-## libdb-$version.so, where $version is the library version and $vn is
-## $version with all dots removed.
-##
-check_slackware_bdb() {
- dir=db`echo $1|tr -d '.'`
- save_CPPFLAGS=$CPPFLAGS
- while test -n "$dir"
- do
- if test -d /usr/include/$dir; then
- CPPFLAGS="$CPPFLAGS -I/usr/include/$dir"
- break
- elif test -d /usr/local/include/$dir; then
- CPPFLAGS="$CPPFLAGS -I/usr/local/include/$dir"
- break
- fi
- dir=`expr "$dir" : '\(.*\)[[0-9]]$'`
- done
- check_bdb $1 db-$1 db_create
- CPPFLAGS=$save_CPPFLAGS
- if test $status_dbm = "$1"; then
- MU_COMMON_INCLUDES="$MU_COMMON_INCLUDES -I/usr/include/$dir"
- fi
-}
-
-try_dbm() {
- case "$1" in
- GDBM)
- AC_CHECK_LIB(gdbm, gdbm_open,
- [AC_CHECK_HEADERS(gdbm.h,
- AC_DEFINE(WITH_GDBM,1,
- [Enable use of GNU DBM library]))
- LIBS="$LIBS -lgdbm"
- POPAUTH='popauth$(EXEEXT)'
- status_dbm=GDBM]);;
-
- BDB2) check_bdb 2 db db_open
- test "$status_dbm" != "no" && status_dbm="Berkeley DB v. $status_dbm";;
-
- BDB) for version in 4 3 2
- do
- case $version in
- 4|3) func=db_create;;
- 2) func=db_open;;
- esac
- check_bdb $version db $func
- if test "$status_dbm" != no; then
- status_dbm="Berkeley DB v. $status_dbm"
- break;
- fi
- done;;
-
- BDB=*)
- name=`expr $1 : 'BDB=\(.*\)'`
- case $name in
- [[0-9]]*) check_slackware_bdb $name;;
- *) for version in 4 3 2
- do
- case $version in
- 4|3) func=db_create;;
- 2) func=db_open;;
- esac
- check_bdb $version $name $func
- if test "$status_dbm" != no; then
- break;
- fi
- done
- ;;
- esac
- test "$status_dbm" != "no" && status_dbm="Berkeley DB v. $status_dbm"
- ;;
- esac
-}
-
-if test $use_dbm = no; then
- # Try all possible DBM values
- for use_dbm in BDB GDBM
- do
- try_dbm $use_dbm
- if test "$status_dbm" != no; then
- break
- fi
- done
+AH_TEMPLATE([DEFAULT_DB_TYPE], [Define default database type])
+if test -n "$DEFAULT_DB_TYPE"; then
+ if mu info $DEFAULT_DB_TYPE >/dev/null; then
+ AC_MSG_ERROR([requested DBM type $DEFAULT_DB_TYPE not supported by Mailutils])
+ fi
else
- try_dbm $use_dbm
+ # Traditionally Mailfromd preferred Berkeley DB over GDBM
+ DEFAULT_DB_TYPE=`mu info bdb gdbm | head -n 1 | sed 's/WITH_//' | tr A-Z a-z`
fi
-
-if test "$status_dbm" = "no"; then
- AC_MSG_ERROR([Cannot find DBM library to link with.])
+if test -n "$DEFAULT_DB_TYPE"; then
+ AC_DEFINE_UNQUOTED([DEFAULT_DB_TYPE], "$DEFAULT_DB_TYPE")
+ status_dbm=$DEFAULT_DB_TYPE
+else
+ AC_DEFINE_UNQUOTED([DEFAULT_DB_TYPE], NULL)
fi
## Preprocessor
AC_ARG_WITH([preprocessor],
AC_HELP_STRING([--without-preprocessor],
[do not use external preprocessor]),
diff --git a/lib/Makefile.am b/lib/Makefile.am
index d3854538..42025942 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -12,13 +12,13 @@
# 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 this program. If not, see <http://www.gnu.org/licenses/>.
-noinst_LIBRARIES=libmf.a libdbm.a libmfdb.a
+noinst_LIBRARIES=libmf.a libmfdb.a
noinst_HEADERS = \
libmf.h\
syslog_async.h\
mudefs.h\
dns.h\
@@ -52,14 +52,12 @@ libmf_a_SOURCES=\
vercmp.c\
version.c
libmf_a_LIBADD=$(LIBOBJS) $(BUILD_SYSLOG_ASYNC)
libmf_a_DEPENDENCIES=$(BUILD_SYSLOG_ASYNC)
-libdbm_a_SOURCES = mf-dbm.c mf-dbm.h
-
libmfdb_a_SOURCES = \
db.c\
dbcfg.c\
cache.c\
greylist.c\
rate.c\
diff --git a/lib/cache.c b/lib/cache.c
index 0abd7141..b15cbf9a 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -19,21 +19,20 @@
# include <config.h>
#endif
#include <mailutils/mailutils.h>
#include "libmf.h"
#include "mfdb.h"
-#include "mf-dbm.h"
#include "filenames.h"
time_t negative_expire_interval;//FIXME
time_t tempfail_expire_interval = 37*60;/* FIXME: Equals to the sum of the
``hard'' timeouts */
-static void cache_print_item(const char *email, size_t size,
- const void *content, size_t contsize);
+static void cache_print_item(struct mu_dbm_datum const *key,
+ struct mu_dbm_datum const *val);
static int cache_expire_item(const void *content);
static struct db_format cache_format_struct = {
"cache",
DEFAULT_DATABASE,
1,
@@ -66,42 +65,39 @@ format_timestr(time_t timestamp, char *timebuf, size_t bufsize)
}
mf_status
cache_get(const char *email)
{
mf_status rc;
- MF_DBM_FILE db;
- MF_DBM_DATUM key;
- MF_DBM_DATUM contents;
+ mu_dbm_file_t db;
+ struct mu_dbm_datum key;
+ struct mu_dbm_datum contents;
+ int result;
int readonly = 0;
- int res;
-
+
if (!cache_format->enabled)
return mf_failure;
-
+
mu_debug(cache_format->debug_handle, MU_DEBUG_TRACE5,
("getting cache info for %s", email));
- if (mf_dbm_open(cache_format->dbname, &db, MU_STREAM_RDWR, 0600,
- &readonly)) {
- mu_error(_("mf_dbm_open(%s) failed: %s"), cache_format->dbname,
- mf_dbm_strerror());
- return mf_failure;
+ db = mf_dbm_open(cache_format->dbname, MU_STREAM_RDWR, 0600);
+ if (!db) {
+ db = mf_dbm_open(cache_format->dbname, MU_STREAM_READ, 0600);
+ if (!db)
+ return mf_failure;
+ readonly = 1;
}
- if (readonly)
- mu_debug(cache_format->debug_handle, MU_DEBUG_TRACE0,
- ("cannot lock %s: switching to read-only mode",
- cache_format->dbname));
memset (&key, 0, sizeof key);
memset (&contents, 0, sizeof contents);
- MF_DATUM_PTR (key) = (void*) email;
- MF_DATUM_SIZE (key) = strlen (email) + 1;
- if ((res = mf_dbm_fetch(&db, key, &contents)) == 0) {
+ key.mu_dptr = (void*) email;
+ key.mu_dsize = strlen (email) + 1;
+ if ((result = mu_dbm_fetch(db, &key, &contents)) == 0) {
char timebuf[80];
struct cache_result *res = (struct cache_result *)
- MF_DATUM_PTR(contents);
+ contents.mu_dptr;
time_t t = time(NULL);
mu_debug(cache_format->debug_handle, MU_DEBUG_TRACE5,
("found status: %s (%d), time: %s",
mf_status_str(res->status), res->status,
format_timestr(res->timestamp,
timebuf, sizeof timebuf)));
@@ -109,78 +105,84 @@ cache_get(const char *email)
if (t - res->timestamp > EXPIRE_INTERVAL(res->status)) {
if (!readonly) {
mu_debug(cache_format->debug_handle,
MU_DEBUG_TRACE5,
("removing expired entry for %s",
email));
- if (mf_dbm_delete(&db, key))
+ result = mu_dbm_delete(db, &key);
+ if (result)
mu_error(_("cannot remove record `%s' from `%s': %s"),
- email, db.name,
- mf_dbm_strerror());
+ email, cache_format->dbname,
+ result == MU_ERR_FAILURE ?
+ mu_dbm_strerror(db) :
+ mu_strerror(result));
+
}
rc = mf_failure;
} else {
rc = res->status;
}
} else {
- if (res != MU_ERR_NOENT)
+ if (result == MU_ERR_FAILURE)
mu_error(_("cannot fetch record `%s' from `%s': %s"),
- email, db.name, mf_dbm_strerror());
+ email, cache_format->dbname,
+ mu_dbm_strerror(db));
rc = mf_failure;
}
- mf_dbm_datum_free(&contents);
- mf_dbm_close(&db);
+ mu_dbm_datum_free(&contents);
+ mu_dbm_destroy(&db);
return rc;
}
void
cache_insert(const char *email, mf_status rc)
{
- MF_DBM_FILE db;
- MF_DBM_DATUM key;
- MF_DBM_DATUM contents;
+ mu_dbm_file_t db;
+ struct mu_dbm_datum key;
+ struct mu_dbm_datum contents;
struct cache_result res;
char timebuf[80];
+ int result;
if (!cache_format->enabled)
return;
time(&res.timestamp);
res.status = rc;
mu_debug(cache_format->debug_handle, MU_DEBUG_TRACE5,
("inserting cache info for %s. status=%s (%d), time=%s",
email, mf_status_str(rc), rc,
format_timestr(res.timestamp, timebuf, sizeof timebuf)));
- if (mf_dbm_open(cache_format->dbname, &db, MU_STREAM_RDWR,
- 0600, NULL)) {
- mu_error(_("mf_dbm_open(%s) failed: %s"), cache_format->dbname,
- mf_dbm_strerror());
+ db = mf_dbm_open(cache_format->dbname, MU_STREAM_RDWR, 0600);
+ if (!db)
return;
- }
-
+
memset(&key, 0, sizeof key);
memset(&contents, 0, sizeof contents);
- MF_DATUM_PTR(key) = (void*) email;
- MF_DATUM_SIZE(key) = strlen (email) + 1;
- MF_DATUM_PTR(contents) = (void*)&res;
- MF_DATUM_SIZE(contents) = sizeof(res);
- if (mf_dbm_insert(&db, key, contents, 1))
- mu_error(_("cannot insert datum `%s' into `%s': %s"),
- email, db.name, mf_dbm_strerror());
+ key.mu_dptr = (void*) email;
+ key.mu_dsize = strlen (email) + 1;
+ contents.mu_dptr = (void*)&res;
+ contents.mu_dsize = sizeof(res);
+ result = mu_dbm_store(db, &key, &contents, 1);
+ if (result)
+ mu_error(_("cannot store datum `%s' into `%s': %s"),
+ email, cache_format->dbname,
+ result == MU_ERR_FAILURE ?
+ mu_dbm_strerror(db) : mu_strerror(result));
- mf_dbm_close(&db);
+ mu_dbm_destroy(&db);
}
static void
-cache_print_item(const char *email, size_t size, const void *content,
- size_t contsize)
+cache_print_item(struct mu_dbm_datum const *key,
+ struct mu_dbm_datum const *val)
{
- const struct cache_result *res = content;
-
- size--; /* Size includes the trailing nul */
- printf("%*.*s", size, size, email);
+ const struct cache_result *res = (const struct cache_result *)
+ val->mu_dptr;
+ int size = key->mu_dsize - 1; /* Size includes the trailing nul */
+ printf("%*.*s", size, size, key->mu_dptr);
printf(" %10.10s ", mf_status_str(res->status));
format_time_str(stdout, res->timestamp);
putchar('\n');
}
static int
diff --git a/lib/db.c b/lib/db.c
index ffcab16f..944dc3da 100644
--- a/lib/db.c
+++ b/lib/db.c
@@ -25,13 +25,12 @@
#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
#include "obstack.h"
#include "libmf.h"
#include "mfdb.h"
-#include "mf-dbm.h"
int ignore_failed_reads_option;//FIXME;
struct db_fmt_list {
struct db_fmt_list *next;
struct db_format fmt;
@@ -85,149 +84,191 @@ db_format_setup()
cache_format = db_format_install(cache_format);
rate_format = db_format_install(rate_format);
tbf_rate_format = db_format_install(tbf_rate_format);
greylist_format = db_format_install(greylist_format);
}
+int
+mf_file_mode_to_safety_criteria(int mode)
+{
+ int fl = 0;
+
+ if (!(mode & 0002))
+ fl |= MU_FILE_SAFETY_WORLD_WRITABLE;
+ if (!(mode & 0004))
+ fl |= MU_FILE_SAFETY_WORLD_READABLE;
+ if (!(mode & 0020))
+ fl |= MU_FILE_SAFETY_GROUP_WRITABLE;
+ if (!(mode & 0040))
+ fl |= MU_FILE_SAFETY_GROUP_READABLE;
+ return fl;
+}
+
+mu_dbm_file_t
+mf_dbm_open(char *dbname, int access, int mode)
+{
+ mu_dbm_file_t db;
+ int rc;
+ int sflg = MU_FILE_SAFETY_LINKED_WRDIR |
+ MU_FILE_SAFETY_DIR_IWOTH;
+
+ rc = mu_dbm_create(dbname, &db);
+ if (rc) {
+ mu_error(_("unable to create database %s: %s"),
+ dbname, mu_strerror (rc));
+ return NULL;
+ }
+
+ mu_dbm_safety_set_flags (db,
+ sflg | mf_file_mode_to_safety_criteria(mode));
+ rc = mu_dbm_safety_check (db);
+ if (rc && rc != ENOENT) {
+ mu_error(_("%s fails safety check: %s"),
+ dbname, mu_strerror(rc));
+ mu_dbm_destroy(&db);
+ return NULL;
+ }
+
+ rc = mu_dbm_open(db, access, mode);
+ if (rc) {
+ mu_error(_("mu_dbm_open(%s) failed: %s (%s)"), dbname,
+ mu_strerror (rc), mu_strerror (errno));
+ return NULL;
+ }
+ return db;
+}
int
db_list_item(char *dbname, char *email, db_item_printer_t fun)
{
- MF_DBM_FILE db;
- MF_DBM_DATUM key, contents;
+ mu_dbm_file_t db;
+ struct mu_dbm_datum key, contents;
int rc = 1;
- int res;
-
- if (mf_dbm_open(dbname, &db, MU_STREAM_READ, 0600, NULL)) {
- mu_error(_("mf_dbm_open(%s) failed: %s"), dbname,
- mf_dbm_strerror());
+
+ db = mf_dbm_open(dbname, MU_STREAM_READ, 0600);
+ if (!db)
return 1;
- }
- memset (&contents, 0, sizeof contents);
+ memset(&contents, 0, sizeof contents);
memset(&key, 0, sizeof key);
- MF_DATUM_PTR(key) = email;
- MF_DATUM_SIZE(key) = strlen (email) + 1;
- if ((res = mf_dbm_fetch(&db, key, &contents)) == 0) {
- fun(MF_DATUM_PTR(key),
- MF_DATUM_SIZE(key),
- MF_DATUM_PTR(contents),
- MF_DATUM_SIZE(contents));
- rc = 0;
- } else if (res != MU_ERR_NOENT)
+ key.mu_dptr = email;
+ key.mu_dsize = strlen (email) + 1;
+ rc = mu_dbm_fetch(db, &key, &contents);
+ if (rc == 0) {
+ fun(&key, &contents);
+ } else if (rc != MU_ERR_NOENT) {
mu_error(_("cannot fetch record `%s' from `%s': %s"),
- email, db.name, mf_dbm_strerror());
-
- mf_dbm_close(&db);
+ email, dbname, mu_dbm_strerror(db));
+ rc = 0;
+ }
+ mu_dbm_destroy(&db);
return rc;
}
-typedef int (*db_enum_func)(MF_DBM_DATUM key, MF_DBM_DATUM cnt, void *data);
+typedef int (*db_enum_func)(struct mu_dbm_datum *key,
+ struct mu_dbm_datum *cnt, void *data);
int
-db_enumerate(MF_DBM_FILE *db, db_enum_func fun, void *data)
+db_enumerate(mu_dbm_file_t db, db_enum_func fun, void *data)
{
int rc = 0;
- int res;
- MF_DBM_DATUM key, prev, contents;
-
- for (res = mf_dbm_firstkey (db, &key); res == 0;
- prev = key,
- res = mf_dbm_nextkey (db, prev, &key),
- mf_dbm_datum_free(&prev)) {
- memset (&contents, 0, sizeof contents);
- if (mf_dbm_fetch (db, key, &contents) == 0) {
- int fr = fun(key, contents, data);
- mf_dbm_datum_free(&contents);
- if (fr) {
- mf_dbm_datum_free(&key);
+ int ret = 0;
+ struct mu_dbm_datum key, contents;
+ const char *name = "";
+
+ mu_dbm_get_name(db, &name);
+
+ memset(&key, 0, sizeof key);
+ memset(&contents, 0, sizeof contents);
+ for (rc = mu_dbm_firstkey(db, &key); rc == 0;
+ rc = mu_dbm_nextkey(db, &key)) {
+ int res = mu_dbm_fetch(db, &key, &contents);
+ if (res == 0) {
+ res = fun(&key, &contents, data);
+ if (res) {
+ mu_dbm_datum_free(&key);
break;
}
+ mu_dbm_datum_free(&contents);
} else {
mu_error(_("cannot fetch data `%*.*s' from `%s': %s"),
- MF_DATUM_SIZE(key), MF_DATUM_SIZE(key),
- (char*) MF_DATUM_PTR(key),
- db->name,
- mf_dbm_strerror());
- rc = 1;
+ key.mu_dsize, key.mu_dsize, key.mu_dptr,
+ name,
+ mu_dbm_strerror(db));
+ ret = 1;
}
}
- if (res != MU_ERR_NOENT) {
+ if (rc != MU_ERR_NOENT) {
mu_error(_("unexpected error scanning database %s: %s"),
- db->name, mf_dbm_strerror());
- rc = 1;
+ name, mu_dbm_strerror(db));
+ ret = 1;
}
- return rc;
+ return ret;
}
static int
-db_list_func(MF_DBM_DATUM key, MF_DBM_DATUM contents, void *data)
+db_list_func(struct mu_dbm_datum *key, struct mu_dbm_datum *contents,
+ void *data)
{
db_item_printer_t fun = data;
- fun(MF_DATUM_PTR(key), MF_DATUM_SIZE(key),
- MF_DATUM_PTR(contents), MF_DATUM_SIZE(contents));
+ fun(key, contents);
return 0;
}
int
db_list(char *dbname, db_item_printer_t fun)
{
- MF_DBM_FILE db;
-
- if (mf_dbm_open(dbname, &db, MU_STREAM_READ, 0600, NULL)) {
- mu_error(_("mf_dbm_open(%s) failed: %s"), dbname,
- mf_dbm_strerror());
+ mu_dbm_file_t db = mf_dbm_open(dbname, MU_STREAM_READ, 0600);
+ if (!db)
return 1;
- }
- db_enumerate(&db, db_list_func, fun);
- mf_dbm_close(&db);
+ db_enumerate(db, db_list_func, fun);
+ mu_dbm_destroy(&db);
return 1;
}
struct expire_data {
db_expire_t fun;
struct obstack stk;
size_t key_count;
};
static int
-db_expire_func(MF_DBM_DATUM key, MF_DBM_DATUM contents, void *data)
+db_expire_func(struct mu_dbm_datum *key, struct mu_dbm_datum *contents,
+ void *data)
{
struct expire_data *dp = data;
- if (dp->fun(MF_DATUM_PTR(contents))) {
- size_t size = MF_DATUM_SIZE(key);
- obstack_grow(&dp->stk, &size, sizeof size);
- obstack_grow(&dp->stk, MF_DATUM_PTR(key), size);
+ if (dp->fun(contents)) {
+ obstack_grow(&dp->stk, &contents->mu_dsize,
+ sizeof contents->mu_dsize);
+ obstack_grow(&dp->stk, key->mu_dptr, key->mu_dsize);
dp->key_count++;
}
return 0;
}
int
db_expire(char *dbname, db_expire_t fun)
{
- MF_DBM_FILE db;
- MF_DBM_DATUM key;
+ mu_dbm_file_t db;
+ struct mu_dbm_datum key;
struct expire_data ed;
size_t size;
char *base, *p;
size_t i;
int rc = 0;
-
- if (mf_dbm_open(dbname, &db, MU_STREAM_RDWR, 0600, NULL)) {
- mu_error(_("mf_dbm_open(%s) failed: %s"), dbname,
- mf_dbm_strerror());
+
+ db = mf_dbm_open(dbname, MU_STREAM_RDWR, 0600);
+ if (!db)
return 1;
- }
ed.fun = fun;
obstack_init(&ed.stk);
ed.key_count = 0;
mu_debug(debug_handle, MU_DEBUG_TRACE0,
("Expiring %s: mark phase", dbname));
- if (db_enumerate(&db, db_expire_func, &ed))
+ if (db_enumerate(db, db_expire_func, &ed))
rc = !ignore_failed_reads_option;
size = 0;
obstack_grow(&ed.stk, &size, sizeof size);
mu_debug(debug_handle, MU_DEBUG_TRACE0,
@@ -236,57 +277,56 @@ db_expire(char *dbname, db_expire_t fun)
(unsigned) obstack_memory_used(&ed.stk)));
mu_debug(debug_handle, MU_DEBUG_TRACE0,
("Expiring %s: sweep phase", dbname));
base = obstack_finish(&ed.stk);
+ memset(&key, 0, sizeof key);
for (i = 0, p = base; i < ed.key_count; i++) {
size = *(size_t*)p;
p += sizeof(size_t);
mu_debug(debug_handle, MU_DEBUG_TRACE5,
("Remove: %*.*s", size, size, p));
- MF_DATUM_PTR(key) = p;
- MF_DATUM_SIZE(key) = size;
- if (mf_dbm_delete(&db, key)) {
+ key.mu_dptr = p;
+ key.mu_dsize = size;
+ rc = mu_dbm_delete(db, &key);
+ if (rc && rc != MU_ERR_NOENT) {
mu_error (_("cannot remove record `%*.*s' from `%s': %s"),
- size, size, p, db.name, mf_dbm_strerror());
+ size, size, p, dbname, mu_dbm_strerror(db));
rc = 1;
}
p += size;
}
mu_debug(debug_handle, MU_DEBUG_TRACE0,
("Finished expiring %s", dbname));
obstack_free(&ed.stk, NULL);
- mf_dbm_close(&db);
+ mu_dbm_destroy(&db);
return rc;
}
int
db_delete(char *dbname, char *id)
{
- MF_DBM_FILE db;
- MF_DBM_DATUM key;
+ mu_dbm_file_t db;
+ struct mu_dbm_datum key;
int rc;
- if (mf_dbm_open(dbname, &db, MU_STREAM_RDWR, 0600, NULL)) {
- mu_error(_("mf_dbm_open(%s) failed: %s"), dbname,
- mf_dbm_strerror());
+ db = mf_dbm_open(dbname, MU_STREAM_RDWR, 0600);
+ if (!db)
return 1;
- }
memset(&key, 0, sizeof key);
- MF_DATUM_PTR(key) = id;
- MF_DATUM_SIZE(key) = strlen (id) + 1;
- if (mf_dbm_delete(&db, key)) {
+ key.mu_dptr = id;
+ key.mu_dsize = strlen (id) + 1;
+ rc = mu_dbm_delete(db, &key);
+ if (rc) {
mu_error(_("cannot remove record `%s' from `%s': %s"), id,
- dbname, mf_dbm_strerror());
- rc = 1;
- } else
- rc = 0;
- mf_dbm_close(&db);
+ dbname, mu_dbm_strerror(db));
+ }
+ mu_dbm_destroy(&db);
return rc;
}
static char *
make_tmp_name(char *dbname)
{
@@ -310,88 +350,90 @@ make_tmp_name(char *dbname)
return newname;
}
struct compact_data {
int rc;
db_expire_t fun;
- MF_DBM_FILE ndb;
+ mu_dbm_file_t ndb;
};
static int
-db_compact_func(MF_DBM_DATUM key, MF_DBM_DATUM contents, void *data)
+db_compact_func(struct mu_dbm_datum *key, struct mu_dbm_datum *contents,
+ void *data)
{
struct compact_data *dp = data;
-
- if (!dp->fun || dp->fun(MF_DATUM_PTR(contents)) == 0) {
- if (((char*)MF_DATUM_PTR(key))[MF_DATUM_SIZE(key) - 1]) {
+ int rc;
+ const char *name;
+
+ mu_dbm_get_name(dp->ndb, &name);
+
+ if (!dp->fun || dp->fun(contents) == 0) {
+ if (((char*)key->mu_dptr)[key->mu_dsize - 1]) {
/* Old database format. Convert. */
- size_t size;
char *p;
- MF_DBM_DATUM newkey;
-
- size = MF_DATUM_SIZE(key);
- p = malloc(size+1);
- if (!MF_DATUM_PTR(newkey)) {
+ struct mu_dbm_datum newkey;
+
+ p = malloc(key->mu_dsize + 1);
+ if (!p) {
mu_error(_("not enough memory"));
return 1;
}
- memcpy(p, MF_DATUM_PTR(key), size);
- p[size] = 0;
-
+ memcpy(p, key->mu_dptr, key->mu_dsize);
+ p[key->mu_dsize] = 0;
+
memset(&newkey, 0, sizeof newkey);
- MF_DATUM_SIZE(newkey) = size+1;
- MF_DATUM_PTR(newkey) = p;
- if (mf_dbm_insert(&dp->ndb, newkey, contents, 1)) {
+ newkey.mu_dptr = p;
+ newkey.mu_dsize = key->mu_dsize + 1;
+ rc = mu_dbm_store(dp->ndb, &newkey, contents, 1);
+ if (rc) {
mu_error(_("cannot insert datum `%s' into `%s': %s"),
- p, dp->ndb.name,
- mf_dbm_strerror());
+ p, name,
+ rc == MU_ERR_FAILURE ?
+ mu_dbm_strerror(dp->ndb) :
+ mu_strerror(rc));
dp->rc = 1;
}
free(p);
- } else if (mf_dbm_insert(&dp->ndb, key, contents, 1)) {
+ } else if ((rc = mu_dbm_store(dp->ndb, key, contents, 1))) {
mu_error(_("cannot insert datum `%*.*s' into `%s': %s"),
- MF_DATUM_SIZE(key), MF_DATUM_SIZE(key),
- (char*) MF_DATUM_PTR(key),
- dp->ndb.name,
- mf_dbm_strerror());
+ key->mu_dsize, key->mu_dsize,
+ (char*) key->mu_dsize,
+ name,
+ rc == MU_ERR_FAILURE ?
+ mu_dbm_strerror(dp->ndb) :
+ mu_strerror(rc));
dp->rc = 1;
}
}
return 0;
}
int
db_compact(char *dbname, db_expire_t fun)
{
- MF_DBM_FILE odb;
+ mu_dbm_file_t odb;
char *tmpname;
struct compact_data dat;
mu_debug(debug_handle, MU_DEBUG_TRACE0,
("Compacting database `%s'", dbname));
tmpname = make_tmp_name(dbname);
- if (mf_dbm_open(dbname, &odb, MU_STREAM_READ, 0600, NULL)) {
- mu_error(_("mf_dbm_open(%s) failed: %s"), dbname,
- mf_dbm_strerror());
- return 1;
- }
+ odb = mf_dbm_open(dbname, MU_STREAM_READ, 0600);
dat.rc = 0;
dat.fun = fun;
- if (mf_dbm_open(tmpname, &dat.ndb, MU_STREAM_CREAT, 0600, NULL)) {
- mu_error(_("mf_dbm_open(%s) failed: %s"), tmpname,
- mf_dbm_strerror());
+ dat.ndb = mf_dbm_open(tmpname, MU_STREAM_CREAT, 0600);
+ if (!dat.ndb)
return 1;
- }
- db_enumerate(&odb, db_compact_func, &dat);
+ db_enumerate(odb, db_compact_func, &dat);
- mf_dbm_close(&dat.ndb);
- mf_dbm_close(&odb);
+ mu_dbm_destroy(&dat.ndb);
+ mu_dbm_destroy(&odb);
if (dat.rc == 0) {
if (unlink(dbname)) {
mu_error(_("cannot unlink %s: %s"),
dbname, mu_strerror(errno));
dat.rc = 1;
diff --git a/lib/dbcfg.c b/lib/dbcfg.c
index 96700e6b..39daee56 100644
--- a/lib/dbcfg.c
+++ b/lib/dbcfg.c
@@ -58,19 +58,19 @@ cb_db_positive_expire_interval(void *data, mu_config_value_t *arg)
static int
cb_db_negative_expire_interval(void *data, mu_config_value_t *arg)
{
struct db_format *fmt = data;
struct timeval tv;
- int rc = config_cb_timeout (&tv, arg);
+ int rc = config_cb_timeout(&tv, arg);
if (fmt == cache_format)
negative_expire_interval = tv.tv_sec;
else
- mu_error (_("negative-expire-interval is valid only "
- "for cache database"));
+ mu_error(_("negative-expire-interval is valid only "
+ "for cache database"));
return rc;
}
int
cb_database_file(void *data, mu_config_value_t *arg)
{
@@ -106,27 +106,26 @@ database_section_parser (enum mu_cfg_section_stage stage,
const mu_cfg_node_t *node,
const char *section_label, void **section_data,
void *call_data,
mu_cfg_tree_t *tree)
{
switch (stage) {
- case mu_cfg_section_start:
- {
+ case mu_cfg_section_start: {
struct db_format *fmt;
if (mu_cfg_assert_value_type(node->label, MU_CFG_STRING))
return 0;
fmt = db_format_lookup(node->label->v.string);