Commit 0cb608de 0cb608de0ac37bfe71e06f4d592c232c78ac4db1 by Sergey Poznyakoff

Reimplement DBM support.

* lib/mu_dbm.c: Remove.
* lib/mu_dbm.h: Remove.
* lib/Makefile.am: Remove mu_dbm.[ch].
* include/mailutils/sys/dbm.h: New file.
* include/mailutils/sys/Makefile.am: Add dbm.h
* include/mailutils/dbm.h: New file.
* include/mailutils/Makefile.am (pkginclude_HEADERS): Add dbm.h.
* include/mailutils/types.hin (mu_dbm_file_t): New data type.

* libmu_dbm/Makefile.am: New file.
* libmu_dbm/berkeley.c: New file.
* libmu_dbm/close.c: New file.
* libmu_dbm/create.c: New file.
* libmu_dbm/datumfree.c: New file.
* libmu_dbm/dbm.c: New file.
* libmu_dbm/delete.c: New file.
* libmu_dbm/destroy.c: New file.
* libmu_dbm/errstr.c: New file.
* libmu_dbm/fetch.c: New file.
* libmu_dbm/firstkey.c: New file.
* libmu_dbm/gdbm.c: New file.
* libmu_dbm/mudbm.h: New file.
* libmu_dbm/ndbm.c: New file.
* libmu_dbm/nextkey.c: New file.
* libmu_dbm/open.c: New file.
* libmu_dbm/safety.c: New file.
* libmu_dbm/store.c: New file.

* Makefile.am [MU_COND_DBM]: Define LIBMU_DBM_DIR
(SUBDIRS): Add $(LIBMU_DBM_DIR)
* configure.ac: Revamp DBM support: several database types can
be specified at once.
(AC_CONFIG_FILES): Build libmu_dbm/Makefile

* libmu_sieve/extensions/vacation.c: Remove inclusion of mu_dbm.h.
* maidag/Makefile.am (maidag_LDADD): Add DBM libraries.
* maidag/maidag.c: ENABLE_DBM instead of USE_DBM
* maidag/maidag.h: Include <mailutils/dbm.h> instead of mu_dbm.h.
* maidag/mailquota.c (dbm_retrieve_quota): Rewrite using libmu_dbm
library calls.
* mu/Makefile.am [MU_COND_DBM]: Define DBM_C.
(MODULES): Add $(DBM_C).
(AM_CPPFLAGS): Define DBMLIBS.
* mu/ldflags.c (NEEDAUTH): Change definition.
(lib_descr) <weight>: New member. All uses changed.
(add_entry): Null arguments ignored.
(mutool_ldflags): Rewrite traversal of lib_descr.
* mu/dbm.c: New file.

* pop3d/Makefile.am (pop3d_LDADD, popauth_LDADD): Add DBM libraries.
* pop3d/apop.c: Rewrite using libmu_dbm library calls.
* pop3d/bulletin.c: Likewise.
* pop3d/logindelay.c: Likewise.
* pop3d/pop3d.c: Change USE_DBM to ENABLE_DBM.
* pop3d/pop3d.h: Include mailutils/dbm.h instead of mu_dbm.h
* pop3d/popauth.c: Rewrite using libmu_dbm library calls.

* include/mailutils/cctype.h (MU_CTYPE_ENDLN): New character class.
(mu_isendln): New macro.
* libmailutils/string/muctype.c (mu_c_tab): Mark \r and \n as
MU_CTYPE_ENDLN.
1 parent f70ebb8c
......@@ -83,6 +83,10 @@ if MU_COND_SUPPORT_CXX
LIBMU_CPP_DIR = libmu_cpp
endif
if MU_COND_DBM
LIBMU_DBM_DIR = libmu_dbm
endif
SUBDIRS = . \
mu-aux\
include\
......@@ -99,6 +103,7 @@ SUBDIRS = . \
$(LIBMU_CPP_DIR)\
$(GINT_DIR)\
$(LIBMU_SCM_DIR)\
$(LIBMU_DBM_DIR)\
libmu_sieve\
$(PYTHON_DIR)\
doc\
......
......@@ -39,6 +39,7 @@ pkginclude_HEADERS = \
cidr.h\
cstr.h\
daemon.h\
dbm.h\
debug.h\
diag.h\
envelope.h\
......
......@@ -35,6 +35,7 @@ extern "C" {
#define MU_CTYPE_PUNCT 0x100
#define MU_CTYPE_SPACE 0x200
#define MU_CTYPE_XLETR 0x400
#define MU_CTYPE_ENDLN 0x800
#define MU_C_TAB_MAX 128
......@@ -56,6 +57,7 @@ extern int mu_c_tab[MU_C_TAB_MAX];
#define mu_isalnum(c) mu_c_is_class (c, MU_CTYPE_ALPHA|MU_CTYPE_DIGIT)
#define mu_isascii(c) (((unsigned)c) < MU_C_TAB_MAX)
#define mu_isblank(c) ((c) == ' ' || (c) == '\t')
#define mu_isendln(c) mu_c_is_class (c, MU_CTYPE_ENDLN)
#define mu_tolower(c) \
({ int __c = (c); \
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011
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/>. */
#ifndef _MAILUTILS_DBM_H
#define _MAILUTILS_DBM_H
#include <mailutils/types.h>
struct mu_dbm_datum
{
char *mu_dptr; /* Data pointer */
size_t mu_dsize; /* Data size */
void *mu_data; /* Implementation-dependent data */
struct mu_dbm_impl *mu_sys; /* Pointer to implementation */
};
struct mu_dbm_impl
{
char *_dbm_name;
int (*_dbm_file_safety) (mu_dbm_file_t db, int mode, uid_t owner);
int (*_dbm_get_fd) (mu_dbm_file_t db, int *pag, int *dir);
int (*_dbm_open) (mu_dbm_file_t db, int flags, int mode);
int (*_dbm_close) (mu_dbm_file_t db);
int (*_dbm_fetch) (mu_dbm_file_t db, struct mu_dbm_datum const *key,
struct mu_dbm_datum *ret);
int (*_dbm_store) (mu_dbm_file_t db, struct mu_dbm_datum const *key,
struct mu_dbm_datum const *contents, int replace);
int (*_dbm_delete) (mu_dbm_file_t db,
struct mu_dbm_datum const *key);
int (*_dbm_firstkey) (mu_dbm_file_t db, struct mu_dbm_datum *ret);
int (*_dbm_nextkey) (mu_dbm_file_t db, struct mu_dbm_datum *ret);
void (*_dbm_datum_free) (struct mu_dbm_datum *datum);
char const *(*_dbm_strerror) (mu_dbm_file_t db);
};
extern mu_url_t mu_dbm_hint;
int mu_dbm_register (struct mu_dbm_impl *impl);
int mu_dbm_create_from_url (mu_url_t url, mu_dbm_file_t *db);
int mu_dbm_create (char *name, mu_dbm_file_t *db);
int mu_dbm_close (mu_dbm_file_t db);
void mu_dbm_datum_free (struct mu_dbm_datum *datum);
int mu_dbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key);
void mu_dbm_destroy (mu_dbm_file_t *pdb);
int mu_dbm_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key,
struct mu_dbm_datum *ret);
int mu_dbm_store (mu_dbm_file_t db, struct mu_dbm_datum const *key,
struct mu_dbm_datum const *contents, int replace);
int mu_dbm_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret);
int mu_dbm_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret);
int mu_dbm_open (mu_dbm_file_t db, int flags, int mode);
int mu_dbm_safety_get_owner (mu_dbm_file_t db, uid_t *uid);
int mu_dbm_safety_get_flags (mu_dbm_file_t db, int *flags);
int mu_dbm_safety_set_owner (mu_dbm_file_t db, uid_t uid);
int mu_dbm_safety_set_flags (mu_dbm_file_t db, int flags);
int mu_dbm_safety_check (mu_dbm_file_t db);
char const *mu_dbm_strerror (mu_dbm_file_t db);
int mu_dbm_get_fd (mu_dbm_file_t db, int *pag, int *dir);
int mu_dbm_impl_iterator (mu_iterator_t *itr);
#endif
......@@ -21,6 +21,7 @@ sysinclude_HEADERS = \
attribute.h\
auth.h\
body.h\
dbm.h\
debcat.h\
envelope.h\
file_stream.h\
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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/>. */
#ifndef _MAILUTILS_SYS_DBM_H
# define _MAILUTILS_SYS_DBM_H
union _mu_dbm_errno
{
int n;
void *p;
};
struct _mu_dbm_file
{
char *db_name; /* Database name */
void *db_descr; /* Database descriptor */
int db_safety_flags; /* Safety checks */
uid_t db_owner; /* Database owner UID */
struct mu_dbm_impl *db_sys; /* Pointer to the database implementation */
union _mu_dbm_errno db_errno;
};
#endif
......@@ -75,7 +75,8 @@ struct _mu_assoc;
struct _mu_acl;
struct _mu_server;
struct _mu_tcp_server;
struct _mu_dbm_file;
struct mu_sockaddr; /* defined in mailutils/sockaddr.h */
struct mu_cidr; /* defined in mailutils/cidr.h */
......@@ -121,6 +122,7 @@ typedef struct _mu_opool *mu_opool_t;
typedef struct _mu_progmailer *mu_progmailer_t;
typedef struct _mu_secret *mu_secret_t;
typedef struct _mu_mime_io_buffer *mu_mime_io_buffer_t;
typedef struct _mu_dbm_file *mu_dbm_file_t;
typedef void (*mu_onexit_t) (void*);
typedef unsigned int mu_debug_handle_t;
......
......@@ -24,7 +24,6 @@ libmuaux_a_SOURCES += \
daemon.c\
mailcap.c\
manlock.c\
mu_dbm.c\
signal.c\
strexit.c\
tcpwrap.c\
......@@ -34,7 +33,6 @@ libmuaux_a_SOURCES += \
noinst_HEADERS +=\
mailcap.h\
muaux.h\
mu_dbm.h\
tcpwrap.h
EXTRA_DIST += utmp.c
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2002, 2006, 2007, 2009, 2010, 2011
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 <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <errno.h>
#include <mailutils/errno.h>
#include <mailutils/stream.h>
#include <mu_dbm.h>
#include <xalloc.h>
int
mu_fcheck_perm (int fd, int mode)
{
struct stat st;
if (mode == 0)
return 0;
if (fstat (fd, &st) == -1)
{
if (errno == ENOENT)
return 0;
else
return 1;
}
if ((st.st_mode & 0777) != mode)
{
errno = MU_ERR_UNSAFE_PERMS;
return 1;
}
return 0;
}
int
mu_check_perm (const char *name, int mode)
{
struct stat st;
if (mode == 0)
return 0;
if (stat (name, &st) == -1)
{
if (errno == ENOENT)
return 0;
else
return 1;
}
if ((st.st_mode & 0777) != mode)
{
errno = MU_ERR_UNSAFE_PERMS;
return 1;
}
return 0;
}
static char *
make_db_name (const char *name, const char *suffix)
{
int nlen = strlen (name);
int slen = strlen (suffix);
char *p;
if (nlen > slen && strcmp (name + nlen - slen, suffix) == 0)
p = xstrdup (name);
else
{
p = xmalloc (strlen (name) + slen + 1);
strcat (strcpy (p, name), suffix);
}
return p;
}
#if defined(WITH_GDBM)
#define DB_SUFFIX ".db"
int
mu_dbm_stat (char *name, struct stat *sb)
{
int rc;
char *pfname = make_db_name (name, DB_SUFFIX);
rc = stat (pfname, sb);
free (pfname);
return rc;
}
int
mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode)
{
int f;
char *pfname = make_db_name (name, DB_SUFFIX);
if (mu_check_perm (pfname, mode))
{
free (pfname);
return -1;
}
switch (flags)
{
case MU_STREAM_CREAT:
f = GDBM_NEWDB;
break;
case MU_STREAM_READ:
f = GDBM_READER;
break;
case MU_STREAM_RDWR:
f = GDBM_WRCREAT;
break;
default:
free (pfname);
errno = EINVAL;
return 1;
}
*db = gdbm_open (pfname, 512, f, mode, NULL);
free (pfname);
return *db == NULL;
}
int
mu_dbm_close (DBM_FILE db)
{
gdbm_close(db);
return 0;
}
int
mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret)
{
*ret = gdbm_fetch (db, key);
return ret->dptr == NULL;
}
int
mu_dbm_delete (DBM_FILE db, DBM_DATUM key)
{
return gdbm_delete (db, key);
}
int
mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace)
{
return gdbm_store (db, key, contents,
replace ? GDBM_REPLACE : GDBM_INSERT);
}
DBM_DATUM
mu_dbm_firstkey (DBM_FILE db)
{
return gdbm_firstkey (db);
}
DBM_DATUM
mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key)
{
return gdbm_nextkey (db, key);
}
void
mu_dbm_datum_free (DBM_DATUM *datum)
{
void *ptr = MU_DATUM_PTR (*datum);
if (ptr)
free (ptr);
MU_DATUM_PTR (*datum) = 0;
}
#elif defined(WITH_BDB)
#define DB_SUFFIX ".db"
int
mu_dbm_stat (char *name, struct stat *sb)
{
int rc;
char *pfname = make_db_name (name, DB_SUFFIX);
rc = stat (pfname, sb);
free (pfname);
return rc;
}
int
mu_dbm_open (char *name, DBM_FILE *dbm, int flags, int mode)
{
int f, rc;
DB *db;
char *pfname = make_db_name (name, DB_SUFFIX);
if (mu_check_perm (pfname, mode))
{
free (pfname);
errno = MU_ERR_UNSAFE_PERMS;
return -1;
}
switch (flags)
{
case MU_STREAM_CREAT:
f = DB_CREATE|DB_TRUNCATE;
break;
case MU_STREAM_READ:
f = DB_RDONLY;
break;
case MU_STREAM_RDWR:
f = DB_CREATE;
break;
default:
free (pfname);
errno = EINVAL;
return -1;
}
#if WITH_BDB == 2
rc = db_open (pfname, DB_HASH, f, mode, NULL, NULL, &db);
#else
rc = db_create (&db, NULL, 0);
if (rc != 0 || db == NULL)
return rc;
# if DB_VERSION_MAJOR == 3
rc = db->open (db, pfname, NULL, DB_HASH, f, mode);
# else
rc = db->open (db, NULL, pfname, NULL, DB_HASH, f, mode);
# endif
#endif
free (pfname);
if (rc)
return -1;
*dbm = malloc (sizeof **dbm);
if (!*dbm)
{
db->close (db, 0);
errno = ENOMEM;
return -1;
}
(*dbm)->db = db;
(*dbm)->dbc = NULL;
return 0;
}
int
mu_dbm_close (DBM_FILE db)
{
db->db->close (db->db, 0);
free (db);
return 0;
}
int
mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret)
{
return db->db->get (db->db, NULL, &key, ret, 0);
}
int
mu_dbm_delete (DBM_FILE db, DBM_DATUM key)
{
return db->db->del (db->db, NULL, &key, 0);
}
int
mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace)
{
/*FIXME: replace unused*/
return db->db->put (db->db, NULL, &key, &contents, 0);
}
DBM_DATUM
mu_dbm_firstkey (DBM_FILE db)
{
DBT key, data;
int ret;
memset (&key, 0, sizeof key);
memset (&data, 0, sizeof data);
if (!db->dbc)
{
if (db->db->cursor (db->db, NULL, &db->dbc BDB2_CURSOR_LASTARG) != 0)
return key;
}
if ((ret = db->dbc->c_get (db->dbc, &key, &data, DB_FIRST)) != 0)
{
key.data = NULL;
key.size = 0;
if (ret == DB_NOTFOUND)
errno = MU_ERR_NOENT;
else
errno = ret;
}
return key;
}
DBM_DATUM
mu_dbm_nextkey (DBM_FILE db, DBM_DATUM pkey /*unused*/)
{
DBT key, data;
int ret;
memset (&key, 0, sizeof key);
memset (&data, 0, sizeof data);
if (!db->dbc)
return key;
if ((ret = db->dbc->c_get (db->dbc, &key, &data, DB_NEXT)) != 0)
{
key.data = NULL;
key.size = 0;
if (ret == DB_NOTFOUND)
errno = MU_ERR_NOENT;
else
errno = ret;
}
return key;
}
void
mu_dbm_datum_free (DBM_DATUM *datum)
{
/* empty */
}
#elif defined(WITH_NDBM)
#define DB_SUFFIX ".pag"
int
mu_dbm_stat (char *name, struct stat *sb)
{
int rc;
char *pfname = make_db_name (name, DB_SUFFIX);
rc = stat (pfname, sb);
free (pfname);
return rc;
}
int
mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode)
{
int f;
char *pfname;
switch (flags)
{
case MU_STREAM_CREAT:
f = O_CREAT|O_TRUNC|O_RDWR;
break;
case MU_STREAM_READ:
f = O_RDONLY;
break;
case MU_STREAM_RDWR:
f = O_CREAT|O_RDWR;
break;
default:
errno = EINVAL;
return -1;
}
pfname = strip_suffix (name, DB_SUFFIX);
*db = dbm_open (pfname, f, mode);
free (pfname);
if (!*db)
return -1;
if (mu_fcheck_perm (dbm_dirfno (*db), mode)
|| mu_fcheck_perm (dbm_pagfno (*db), mode))
{
dbm_close (*db);
return 1;
}
return 0;
}
int
mu_dbm_close (DBM_FILE db)
{
dbm_close (db);
return 0;
}
int
mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret)
{
*ret = dbm_fetch (db, key);
return ret->dptr == NULL;
}
int
mu_dbm_delete (DBM_FILE db, DBM_DATUM key)
{
return dbm_delete (db, key);
}
int
mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace)
{
return dbm_store (db, key, contents, replace ? DBM_REPLACE : DBM_INSERT);
}
DBM_DATUM
mu_dbm_firstkey (DBM_FILE db)
{
return dbm_firstkey (db);
}
DBM_DATUM
mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key)
{
return dbm_nextkey (db, key);
}
void
mu_dbm_datum_free (DBM_DATUM *datum)
{
/* empty */
}
#elif defined(WITH_TOKYOCABINET)
#define DB_SUFFIX ".tch"
int
mu_dbm_stat (char *name, struct stat *sb)
{
int rc;
char *pfname = make_db_name (name, DB_SUFFIX);
rc = stat (pfname, sb);
free (pfname);
return rc;
}
int
mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode)
{
int f, ecode;
char *pfname = make_db_name (name, DB_SUFFIX);
if (mu_check_perm (pfname, mode))
{
free (pfname);
return -1;
}
switch (flags)
{
case MU_STREAM_CREAT:
f = HDBOWRITER | HDBOCREAT;
break;
case MU_STREAM_READ:
f = HDBOREADER;
break;
case MU_STREAM_RDWR:
f = HDBOREADER | HDBOWRITER;
break;
default:
free (pfname);
errno = EINVAL;
return 1;
}
*db = malloc (sizeof **db);
if (!*db)
{
errno = ENOMEM;
return -1;
}
(*db)->hdb = tchdbnew ();
if (!tchdbopen ((*db)->hdb, pfname, f))
ecode = tchdbecode ((*db)->hdb);
free (pfname);
return 0;
}
int
mu_dbm_close (DBM_FILE db)
{
tchdbclose (db->hdb);
tchdbdel (db->hdb);
return 0;
}
int
mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret)
{
ret->data = tchdbget (db->hdb, key.data, key.size, &ret->size);
return ret->data == NULL;
}
int
mu_dbm_delete (DBM_FILE db, DBM_DATUM key)
{
return !tchdbout (db->hdb, key.data, key.size);
}
int
mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace)
{
if (replace)
return !tchdbput (db->hdb, key.data, key.size, contents.data, contents.size);
else
return !tchdbputkeep (db->hdb, key.data, key.size,
contents.data, contents.size);
}
DBM_DATUM
mu_dbm_firstkey (DBM_FILE db)
{
DBM_DATUM key;
memset (&key, 0, sizeof key);
tchdbiterinit (db->hdb);
key.data = tchdbiternext (db->hdb, &key.size);
return key;
}
DBM_DATUM
mu_dbm_nextkey (DBM_FILE db, DBM_DATUM unused)
{
DBM_DATUM key;
memset (&key, 0, sizeof key);
key.data = tchdbiternext (db->hdb, &key.size);
return key;
}
void
mu_dbm_datum_free (DBM_DATUM *datum)
{
/* empty */
}
#endif
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2002, 2005, 2007, 2009, 2010, 2011
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/>. */
#if defined(WITH_GDBM)
#include <gdbm.h>
#define USE_DBM
typedef GDBM_FILE DBM_FILE;
typedef datum DBM_DATUM;
#define MU_DATUM_SIZE(d) (d).dsize
#define MU_DATUM_PTR(d) (d).dptr
#elif defined(WITH_BDB)
#include <db.h>
#define USE_DBM
struct db2_file
{
DB *db;
DBC *dbc;
};
typedef struct db2_file *DBM_FILE;
typedef DBT DBM_DATUM;
#define MU_DATUM_SIZE(d) (d).size
#define MU_DATUM_PTR(d) (d).data
#elif defined(WITH_NDBM)
#include <ndbm.h>
#define USE_DBM
typedef DBM *DBM_FILE;
typedef datum DBM_DATUM;
#define MU_DATUM_SIZE(d) (d).dsize
#define MU_DATUM_PTR(d) (d).dptr
#elif defined(WITH_TOKYOCABINET)
#include <tcutil.h>
#include <tchdb.h>
#define USE_DBM
struct tokyocabinet_file
{
TCHDB *hdb;
};
struct tokyocabinet_datum {
void *data;
int size;
};
typedef struct tokyocabinet_file *DBM_FILE;
typedef struct tokyocabinet_datum DBM_DATUM;
#define MU_DATUM_SIZE(d) (d).size
#define MU_DATUM_PTR(d) (d).data
#endif
#ifdef USE_DBM
struct stat;
int mu_dbm_stat (char *name, struct stat *sb);
int mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode);
int mu_dbm_close (DBM_FILE db);
int mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret);
int mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace);
int mu_dbm_delete (DBM_FILE db, DBM_DATUM key);
DBM_DATUM mu_dbm_firstkey (DBM_FILE db);
DBM_DATUM mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key);
void mu_dbm_datum_free(DBM_DATUM *datum);
#endif /* USE_DBM */
int mu_fcheck_perm (int fd, int mode);
int mu_check_perm (const char *name, int mode);
......@@ -31,10 +31,10 @@ int mu_c_tab[MU_C_TAB_MAX] = {
MU_CTYPE_CNTRL,
MU_CTYPE_CNTRL,
MU_CTYPE_CNTRL|MU_CTYPE_SPACE,
MU_CTYPE_CNTRL|MU_CTYPE_SPACE|MU_CTYPE_ENDLN,
MU_CTYPE_CNTRL|MU_CTYPE_SPACE,
MU_CTYPE_CNTRL|MU_CTYPE_SPACE,
MU_CTYPE_CNTRL|MU_CTYPE_SPACE,
MU_CTYPE_CNTRL|MU_CTYPE_SPACE,
MU_CTYPE_CNTRL|MU_CTYPE_SPACE|MU_CTYPE_ENDLN,
MU_CTYPE_CNTRL,
MU_CTYPE_CNTRL,
MU_CTYPE_CNTRL,
......
## This file is part of GNU Mailutils.
## Copyright (C) 2011 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/>.
INCLUDES = @MU_LIB_COMMON_INCLUDES@ @DBMINCLUDES@
lib_LTLIBRARIES = libmu_dbm.la
libmu_dbm_la_SOURCES = \
close.c\
create.c\
datumfree.c\
dbm.c\
delete.c\
destroy.c\
errstr.c\
fetch.c\
firstkey.c\
getfd.c\
nextkey.c\
open.c\
safety.c\
store.c\
berkeley.c\
gdbm.c\
ndbm.c
noinst_HEADERS = mudbm.h
libmu_dbm_la_LIBADD = ${MU_LIB_MAILUTILS} @MU_AUTHLIBS@ @DBMLIBS@ @LTLIBINTL@
libmu_dbm_la_LDFLAGS = -version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@
libmu_dbm_la_DEPENDENCIES = @DBMLIB_DEPENDENCY@
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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 <stdlib.h>
#include <string.h>
#include <mailutils/types.h>
#include <mailutils/dbm.h>
#include <mailutils/util.h>
#include <mailutils/errno.h>
#include <mailutils/error.h>
#include <mailutils/stream.h>
#include "mudbm.h"
#if defined(WITH_BDB)
#include <db.h>
struct bdb_file
{
DB *db;
DBC *dbc;
};
static int
_bdb_file_safety (mu_dbm_file_t db, int mode, uid_t owner)
{
return mu_file_safety_check (db->db_name, mode, owner, NULL);
}
static int
_bdb_get_fd (mu_dbm_file_t db, int *pag, int *dir)
{
struct bdb_file *bdb_file = db->db_descr;
int rc = bdb_file->db->fd (bdb_file->db, pag);
if (rc)
{
db->db_errno.n = rc;
return MU_ERR_FAILURE;
}
if (dir)
*dir = *pag;
return 0;
}
static int
_bdb_open (mu_dbm_file_t mdb, int flags, int mode)
{
struct bdb_file *bdb_file;
int f, rc;
DB *db;
switch (flags)
{
case MU_STREAM_CREAT:
f = DB_CREATE|DB_TRUNCATE;
break;
case MU_STREAM_READ:
f = DB_RDONLY;
break;
case MU_STREAM_RDWR:
f = DB_CREATE;
break;
default:
return EINVAL;
}
#if WITH_BDB == 2
rc = db_open (db->db_name, DB_HASH, f, mode, NULL, NULL, &db);
#else
rc = db_create (&db, NULL, 0);
if (rc != 0 || db == NULL)
return MU_ERR_FAILURE;
# if DB_VERSION_MAJOR == 3
rc = db->open (db, mdb->db_name, NULL, DB_HASH, f, mode);
# else
rc = db->open (db, NULL, mdb->db_name, NULL, DB_HASH, f, mode);
# endif
#endif
if (rc)
return MU_ERR_FAILURE;
bdb_file = malloc (sizeof *bdb_file);
if (!bdb_file)
{
db->close (db, 0);
return ENOMEM;
}
bdb_file->db = db;
bdb_file->dbc = NULL;
mdb->db_descr = bdb_file;
return 0;
}
static int
_bdb_close (mu_dbm_file_t db)
{
if (db->db_descr)
{
struct bdb_file *bdb_file = db->db_descr;
bdb_file->db->close (bdb_file->db, 0);
free (bdb_file);
db->db_descr = NULL;
}
return 0;
}
static int
_bdb_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key,
struct mu_dbm_datum *ret)
{
DBT keydat, content;
struct bdb_file *bdb_file = db->db_descr;
int rc;
memset (&keydat, 0, sizeof keydat);
keydat.data = key->mu_dptr;
keydat.size = key->mu_dsize;
memset (&content, 0, sizeof content);
content.flags = DB_DBT_MALLOC;
rc = bdb_file->db->get (bdb_file->db, NULL, &keydat, &content, 0);
mu_dbm_datum_free (ret);
switch (rc)
{
case 0:
ret->mu_dptr = content.data;
ret->mu_dsize = content.size;
ret->mu_sys = db->db_sys;
break;
case DB_NOTFOUND:
db->db_errno.n = rc;
rc = MU_ERR_NOENT;
break;
default:
db->db_errno.n = rc;
rc = MU_ERR_FAILURE;
}
return rc;
}
static int
_bdb_store (mu_dbm_file_t db,
struct mu_dbm_datum const *key,
struct mu_dbm_datum const *contents,
int replace)
{
struct bdb_file *bdb_file = db->db_descr;
int rc;
DBT keydat, condat;
memset (&keydat, 0, sizeof keydat);
keydat.data = key->mu_dptr;
keydat.size = key->mu_dsize;
memset (&condat, 0, sizeof condat);
condat.data = contents->mu_dptr;
condat.size = contents->mu_dsize;
rc = bdb_file->db->put (bdb_file->db, NULL, &keydat, &condat,
replace ? 0 : DB_NOOVERWRITE);
db->db_errno.n = rc;
switch (rc)
{
case 0:
break;
case DB_KEYEXIST:
rc = MU_ERR_EXISTS;
break;
default:
rc = MU_ERR_FAILURE;
break;
}
return rc;
}
static int
_bdb_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
{
DBT keydat;
struct bdb_file *bdb_file = db->db_descr;
int rc;
memset (&keydat, 0, sizeof keydat);
keydat.data = key->mu_dptr;
keydat.size = key->mu_dsize;
rc = bdb_file->db->del (bdb_file->db, NULL, &keydat, 0);
switch (rc)
{
case 0:
break;
case DB_NOTFOUND:
db->db_errno.n = rc;
rc = MU_ERR_NOENT;
break;
default:
db->db_errno.n = rc;
rc = MU_ERR_FAILURE;
}
return rc;
}
static int
_bdb_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
struct bdb_file *bdb_file = db->db_descr;
int rc;
DBT key, dbt;
if (!bdb_file->dbc)
{
rc = bdb_file->db->cursor (bdb_file->db, NULL, &bdb_file->dbc
BDB2_CURSOR_LASTARG);
if (rc)
{
db->db_errno.n = rc;
return MU_ERR_FAILURE;
}
}
memset (&key, 0, sizeof key);
key.flags = DB_DBT_MALLOC;
memset (&dbt, 0, sizeof dbt);
dbt.flags = DB_DBT_MALLOC;
rc = bdb_file->dbc->c_get (bdb_file->dbc, &key, &dbt, DB_FIRST);
mu_dbm_datum_free (ret);
switch (rc)
{
case 0:
free (dbt.data); /* FIXME: cache it for the eventual fetch that can
follow */
ret->mu_dptr = key.data;
ret->mu_dsize = key.size;
ret->mu_sys = db->db_sys;
break;
case DB_NOTFOUND:
db->db_errno.n = rc;
rc = MU_ERR_NOENT;
break;
default:
db->db_errno.n = rc;
rc = MU_ERR_FAILURE;
}
return rc;
}
static int
_bdb_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
struct bdb_file *bdb_file = db->db_descr;
int rc;
DBT key, dbt;
if (!bdb_file->dbc)
return MU_ERR_SEQ;
memset (&key, 0, sizeof key);
key.flags = DB_DBT_MALLOC;
memset (&dbt, 0, sizeof dbt);
dbt.flags = DB_DBT_MALLOC;
rc = bdb_file->dbc->c_get (bdb_file->dbc, &key, &dbt, DB_NEXT);
mu_dbm_datum_free (ret);
switch (rc)
{
case 0:
free (dbt.data); /* FIXME: cache it for the eventual fetch that can
follow */
ret->mu_dptr = key.data;
ret->mu_dsize = key.size;
ret->mu_sys = db->db_sys;
break;
case DB_NOTFOUND:
db->db_errno.n = rc;
rc = MU_ERR_NOENT;
break;
default:
db->db_errno.n = rc;
rc = MU_ERR_FAILURE;
}
return rc;
}
static void
_bdb_datum_free (struct mu_dbm_datum *datum)
{
free (datum->mu_dptr);
}
static char const *
_bdb_strerror (mu_dbm_file_t db)
{
return db_strerror (db->db_errno.n);
}
struct mu_dbm_impl _mu_dbm_bdb = {
"bdb",
_bdb_file_safety,
_bdb_get_fd,
_bdb_open,
_bdb_close,
_bdb_fetch,
_bdb_store,
_bdb_delete,
_bdb_firstkey,
_bdb_nextkey,
_bdb_datum_free,
_bdb_strerror
};
#endif
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
int
mu_dbm_close (mu_dbm_file_t db)
{
DBMSYSCK (db, _dbm_close);
if (!db->db_descr)
return 0;
return db->db_sys->_dbm_close (db);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011
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 <unistd.h>
#include <stdlib.h>
#include <mailutils/types.h>
#include <mailutils/list.h>
#include <mailutils/url.h>
#include <mailutils/dbm.h>
#include <mailutils/errno.h>
#include <mailutils/util.h>
#include "mudbm.h"
int
mu_dbm_create (char *name, mu_dbm_file_t *db)
{
int rc;
mu_url_t url;
_mu_dbm_init ();
rc = mu_url_create_hint (&url, name, 0, mu_dbm_hint);
if (rc)
return rc;
rc = mu_dbm_create_from_url (url, db);
mu_url_destroy (&url);
return rc;
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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 <stdlib.h>
#include <mailutils/types.h>
#include <mailutils/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
void
mu_dbm_datum_free (struct mu_dbm_datum *datum)
{
if (datum && datum->mu_data &&
datum->mu_sys && datum->mu_sys->_dbm_datum_free)
{
datum->mu_sys->_dbm_datum_free (datum);
datum->mu_data = NULL;
}
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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 <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <mailutils/types.h>
#include <mailutils/list.h>
#include <mailutils/url.h>
#include <mailutils/dbm.h>
#include <mailutils/util.h>
#include <mailutils/errno.h>
#include <mailutils/error.h>
#include <mailutils/nls.h>
#include <mailutils/mu_auth.h>
#include "mudbm.h"
static mu_list_t implist;
mu_url_t mu_dbm_hint;
static void
_implist_free (void *p)
{
struct mu_dbm_impl *impl = p;
free (impl->_dbm_name);
free (impl);
}
static int
_implist_cmp (const void *a, const void *b)
{
struct mu_dbm_impl const *ia = a;
struct mu_dbm_impl const *ib = b;
return strcmp (ia->_dbm_name, ib->_dbm_name);
}
void
_mu_dbm_init ()
{
int rc;
if (implist)
return;
rc = mu_list_create (&implist);
if (rc)
{
mu_error (_("cannot initialize DBM subsystem: %s"),
mu_strerror (rc));
abort ();
}
mu_list_set_destroy_item (implist, _implist_free);
mu_list_set_comparator (implist, _implist_cmp);
/* Add built-in entries */
#ifdef WITH_GDBM
mu_dbm_register (&_mu_dbm_gdbm);
#endif
#ifdef WITH_BDB
mu_dbm_register (&_mu_dbm_bdb);
#endif
#ifdef WITH_NDBM
mu_dbm_register (&_mu_dbm_ndbm);
#endif
#ifdef WITH_TOKYOCABINET
mu_dbm_register (&_mu_dbm_tokyokabinet);
#endif
if (!mu_dbm_hint)
{
struct mu_dbm_impl *impl;
char *urlbuf;
rc = mu_list_get (implist, 0, (void**) &impl);
if (rc)
{
mu_error (_("cannot initialize DBM hint: %s"),
mu_strerror (rc));
abort ();
}
urlbuf = malloc (strlen (impl->_dbm_name) + 4);
if (urlbuf)
{
strcpy (urlbuf, impl->_dbm_name);
strcat (urlbuf, "://");
rc = mu_url_create (&mu_dbm_hint, urlbuf);
free (urlbuf);
}
else
rc = ENOMEM;
if (rc)
{
mu_error (_("cannot initialize DBM hint: %s"),
mu_strerror (rc));
abort ();
}
}
}
int
mu_dbm_register (struct mu_dbm_impl *impl)
{
int rc;
struct mu_dbm_impl *ptr;
_mu_dbm_init ();
ptr = calloc (1, sizeof (*ptr));
if (!ptr)
return ENOMEM;
*ptr = *impl;
ptr->_dbm_name = strdup (impl->_dbm_name);
if (!ptr->_dbm_name)
{
free (ptr);
return ENOMEM;
}
rc = mu_list_append (implist, ptr);
if (rc)
_implist_free (ptr);
return rc;
}
int
mu_dbm_create_from_url (mu_url_t url, mu_dbm_file_t *db)
{
mu_dbm_file_t p;
int flags;
int rc;
const char *db_name;
struct mu_dbm_impl impl_key;
struct mu_dbm_impl *impl;
struct mu_auth_data *auth;
int safety_flags = 0;
uid_t owner_uid = getuid ();
_mu_dbm_init ();
mu_url_get_flags (url, &flags);
if ((flags & (MU_URL_HOST | MU_URL_PATH)) == (MU_URL_HOST | MU_URL_PATH))
return MU_ERR_URL_EXTRA_PARTS;
if (flags & MU_URL_HOST)
rc = mu_url_sget_host (url, &db_name);
else
rc = mu_url_sget_path (url, &db_name);
if (rc)
return rc;
rc = mu_url_sget_scheme (url, (const char**)&impl_key._dbm_name);
if (rc)
return rc;
rc = mu_list_locate (implist, (void *) &impl_key, (void **) &impl);
if (rc)
return rc;
if (flags & MU_URL_PARAM)
{
size_t fvc, i;
char **fvp;
mu_url_sget_fvpairs (url, &fvc, &fvp);
for (i = 0; i < fvc; i++)
{
const char *name = fvp[i];
int negate = 0;
int val;
if (*name == '-')
{
negate = 1;
name++;
}
else if (*name == '+')
name++;
if (strncmp (name, "owner", 5) == 0)
{
val = MU_FILE_SAFETY_OWNER_MISMATCH;
if (name[5] == '=')
{
auth = mu_get_auth_by_name (name + 6);
if (!auth)
{
char *end;
unsigned long uid;
errno = 0;
uid = strtoul (name + 6, &end, 0);
if (*end || errno)
return MU_ERR_NO_SUCH_USER;
auth = mu_get_auth_by_uid (uid);
if (!auth)
return MU_ERR_NO_SUCH_USER;
owner_uid = auth->uid;
mu_auth_data_free (auth);
}
}
else if (name[5])
return MU_ERR_URL_EXTRA_PARTS;//FIXME: better error code
}
else if (strcmp (name, "none") == 0)
{
safety_flags = negate ? MU_FILE_SAFETY_ALL : MU_FILE_SAFETY_NONE;
continue;
}
else if (strcmp (name, "all") == 0)
{
safety_flags = negate ? MU_FILE_SAFETY_NONE : MU_FILE_SAFETY_ALL;
continue;
}
else if (strcmp (name, "default") == 0)
{
val = DEFAULT_DBM_SAFETY_FLAGS;
}
else if (mu_file_safety_name_to_code (name, &val))
return MU_ERR_URL_EXTRA_PARTS;//FIXME: better error code
if (negate)
safety_flags &= ~val;
else
safety_flags |= val;
}
}
p = calloc (1, sizeof (*p));
if (!p)
return ENOMEM;
p->db_name = strdup (db_name);
if (!p->db_name)
{
free (p);
return ENOMEM;
}
p->db_safety_flags = safety_flags;
p->db_owner = owner_uid;
p->db_sys = impl;
*db = p;
return 0;
}
int
mu_dbm_impl_iterator (mu_iterator_t *itr)
{
_mu_dbm_init ();
return mu_list_get_iterator (implist, itr);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
int
mu_dbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
{
DBMSYSCK (db, _dbm_delete);
if (!db->db_descr)
return EINVAL;
return db->db_sys->_dbm_delete (db, key);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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 <stdlib.h>
#include <mailutils/types.h>
#include <mailutils/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
void
mu_dbm_destroy (mu_dbm_file_t *pdb)
{
if (pdb && *pdb)
{
mu_dbm_file_t db = *pdb;
if (db->db_descr)
mu_dbm_close (db);
free (db->db_name);
free (db);
*pdb = NULL;
}
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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 <stdlib.h>
#include <mailutils/types.h>
#include <mailutils/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
char const *
mu_dbm_strerror (mu_dbm_file_t db)
{
if (!db)
return NULL;
if (!db->db_sys || !db->db_sys->_dbm_strerror)
return NULL;
if (!db->db_descr)
return mu_strerror (MU_ERR_NOT_OPEN);
return db->db_sys->_dbm_strerror (db);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
int
mu_dbm_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key,
struct mu_dbm_datum *ret)
{
DBMSYSCK (db, _dbm_fetch);
if (!db->db_descr)
return EINVAL;
return db->db_sys->_dbm_fetch (db, key, ret);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
int
mu_dbm_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
DBMSYSCK (db, _dbm_firstkey);
if (!db->db_descr)
return EINVAL;
return db->db_sys->_dbm_firstkey (db, ret);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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 <stdlib.h>
#include <string.h>
#include <mailutils/types.h>
#include <mailutils/dbm.h>
#include <mailutils/util.h>
#include <mailutils/errno.h>
#include <mailutils/error.h>
#include <mailutils/stream.h>
#include "mudbm.h"
#if defined(WITH_GDBM)
#include <gdbm.h>
struct gdbm_descr
{
GDBM_FILE file; /* GDBM file */
datum prev; /* Previous key for sequential access */
};
static int
_gdbm_file_safety (mu_dbm_file_t db, int mode, uid_t owner)
{
return mu_file_safety_check (db->db_name, mode, owner, NULL);
}
int
_gdbm_get_fd (mu_dbm_file_t db, int *pag, int *dir)
{
struct gdbm_descr *gd = db->db_descr;
*pag = gdbm_fdesc (gd->file);
if (dir)
*dir = *pag;
return 0;
}
static int
_gdbm_open (mu_dbm_file_t db, int flags, int mode)
{
int f;
struct gdbm_descr *gd;
GDBM_FILE file;
switch (flags)
{
case MU_STREAM_CREAT:
f = GDBM_NEWDB;
break;
case MU_STREAM_READ:
f = GDBM_READER;
break;
case MU_STREAM_RDWR:
f = GDBM_WRCREAT;
break;
default:
return EINVAL;
}
file = gdbm_open (db->db_name, 512, f, mode, NULL);
if (!file)
return MU_ERR_FAILURE;
gd = calloc (1, sizeof (*gd));
gd->file = file;
db->db_descr = gd;
return 0;
}
static int
_gdbm_close (mu_dbm_file_t db)
{
if (db->db_descr)
{
struct gdbm_descr *gd = db->db_descr;
gdbm_close (gd->file);
free (gd);
db->db_descr = NULL;
}
return 0;
}
static int
_gdbm_conv_datum (mu_dbm_file_t db, struct mu_dbm_datum *ret, datum content,
int copy)
{
if (copy)
{
ret->mu_dptr = malloc (content.dsize);
if (!ret->mu_dptr)
return errno;
memcpy (ret->mu_dptr, content.dptr, content.dsize);
}
else
{
ret->mu_dptr = content.dptr;
}
ret->mu_dsize = content.dsize;
ret->mu_sys = db->db_sys;
return 0;
}
static int
_gdbm_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key,
struct mu_dbm_datum *ret)
{
struct gdbm_descr *gd = db->db_descr;
int rc;
datum keydat, content;
keydat.dptr = key->mu_dptr;
keydat.dsize = key->mu_dsize;
gdbm_errno = 0;
content = gdbm_fetch (gd->file, keydat);
if (content.dptr == NULL)
{
if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
return MU_ERR_NOENT;
else
{
db->db_errno.n = gdbm_errno;
return MU_ERR_FAILURE;
}
}
mu_dbm_datum_free (ret);
rc = _gdbm_conv_datum (db, ret, content, 1);
if (rc)
{
free (content.dptr);
return rc;
}
return 0;
}
static int
_gdbm_store (mu_dbm_file_t db,
struct mu_dbm_datum const *key,
struct mu_dbm_datum const *contents,
int replace)
{
struct gdbm_descr *gd = db->db_descr;
datum keydat, condat;
keydat.dptr = key->mu_dptr;
keydat.dsize = key->mu_dsize;
condat.dptr = contents->mu_dptr;
condat.dsize = contents->mu_dsize;
switch (gdbm_store (gd->file, keydat, condat, replace))
{
case 0:
break;
case 1:
return MU_ERR_EXISTS;
case -1:
db->db_errno.n = gdbm_errno;
return MU_ERR_FAILURE;
}
return 0;
}
static int
_gdbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
{
struct gdbm_descr *gd = db->db_descr;
datum keydat;
keydat.dptr = key->mu_dptr;
keydat.dsize = key->mu_dsize;
gdbm_errno = 0;
if (gdbm_delete (gd->file, keydat))
{
if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
return MU_ERR_NOENT;
else
{
db->db_errno.n = gdbm_errno;
return MU_ERR_FAILURE;
}
}
return 0;
}
static int
_gdbm_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
struct gdbm_descr *gd = db->db_descr;
int rc;
datum key = gdbm_firstkey (gd->file);
if (key.dptr == NULL)
{
if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
return MU_ERR_NOENT;
else
{
db->db_errno.n = gdbm_errno;
return MU_ERR_FAILURE;
}
}
mu_dbm_datum_free (ret);
rc = _gdbm_conv_datum (db, ret, key, 0);
if (rc)
{
free (key.dptr);
return rc;
}
free (gd->prev.dptr);
gd->prev = key;
return 0;
}
static int
_gdbm_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
struct gdbm_descr *gd = db->db_descr;
int rc;
datum key;
if (!gd->prev.dptr)
return MU_ERR_NOENT;
key = gdbm_nextkey (gd->file, gd->prev);
if (key.dptr == NULL)
{
if (gdbm_errno == GDBM_ITEM_NOT_FOUND)
return MU_ERR_NOENT;
else
{
db->db_errno.n = gdbm_errno;
return MU_ERR_FAILURE;
}
}
mu_dbm_datum_free (ret);
rc = _gdbm_conv_datum (db, ret, key, 0);
if (rc)
{
free (key.dptr);
return rc;
}
free (gd->prev.dptr);
gd->prev = key;
return 0;
}
static void
_gdbm_datum_free (struct mu_dbm_datum *datum)
{
free (datum->mu_dptr);
}
static char const *
_gdbm_strerror (mu_dbm_file_t db)
{
return gdbm_strerror (db->db_errno.n);
}
struct mu_dbm_impl _mu_dbm_gdbm = {
"gdbm",
_gdbm_file_safety,
_gdbm_get_fd,
_gdbm_open,
_gdbm_close,
_gdbm_fetch,
_gdbm_store,
_gdbm_delete,
_gdbm_firstkey,
_gdbm_nextkey,
_gdbm_datum_free,
_gdbm_strerror
};
#endif
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
int
mu_dbm_get_fd (mu_dbm_file_t db, int *pag, int *dir)
{
DBMSYSCK (db, _dbm_get_fd);
if (!db->db_descr || !pag)
return EINVAL;
return db->db_sys->_dbm_get_fd (db, pag, dir);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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/>. */
#include <mailutils/sys/dbm.h>
#define DBMSYSCK(db,meth) do \
{ \
if (!(db)) \
return EINVAL; \
if (!(db)->db_descr) \
return MU_ERR_NOT_OPEN; \
if (!(db)->db_sys || !(db)->db_sys->meth) \
return ENOSYS; \
} \
while (0)
#define DEFAULT_DBM_SAFETY_FLAGS MU_FILE_SAFETY_ALL
#ifdef WITH_GDBM
extern struct mu_dbm_impl _mu_dbm_gdbm;
#endif
#ifdef WITH_BDB
extern struct mu_dbm_impl _mu_dbm_bdb;
#endif
#ifdef WITH_NDBM
extern struct mu_dbm_impl _mu_dbm_ndbm;
#endif
#ifdef WITH_TOKYOCABINET
extern struct mu_dbm_impl _mu_dbm_tokyokabinet;
#endif
void _mu_dbm_init (void);
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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 <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <mailutils/types.h>
#include <mailutils/dbm.h>
#include <mailutils/util.h>
#include <mailutils/errno.h>
#include <mailutils/error.h>
#include <mailutils/stream.h>
#include <mailutils/io.h>
#include "mudbm.h"
#if defined(WITH_NDBM)
#include <ndbm.h>
static int
_ndbm_file_safety (mu_dbm_file_t db, int mode, uid_t owner)
{
int rc;
char *name;
rc = mu_asprintf (&name, "%s.pag", db->db_name);
if (rc)
return rc;
rc = mu_file_safety_check (name, mode, owner, NULL);
if (rc)
{
free (name);
return rc;
}
strcpy (name + strlen (name) - 3, "dir");
rc = mu_file_safety_check (name, mode, owner, NULL);
free (name);
return rc;
}
int
_ndbm_get_fd (mu_dbm_file_t db, int *pag, int *dir)
{
DBM *dbm = db->db_descr;
*pag = dbm_pagfno (dbm);
if (dir)
*dir = dbm_dirfno (dbm);
return 0;
}
static int
_ndbm_open (mu_dbm_file_t db, int flags, int mode)
{
int f;
DBM *dbm;
switch (flags)
{
case MU_STREAM_CREAT:
f = O_CREAT|O_TRUNC|O_RDWR;
break;
case MU_STREAM_READ:
f = O_RDONLY;
break;
case MU_STREAM_RDWR:
f = O_CREAT|O_RDWR;
break;
default:
errno = EINVAL;
return -1;
}
dbm = dbm_open (db->db_name, f, mode);
if (!dbm)
return MU_ERR_FAILURE;
db->db_descr = dbm;
return 0;
}
static int
_ndbm_close (mu_dbm_file_t db)
{
if (db->db_descr)
{
dbm_close ((DBM *) db->db_descr);
db->db_descr = NULL;
}
return 0;
}
static int
_ndbm_conv_datum (mu_dbm_file_t db, struct mu_dbm_datum *ret, datum content)
{
ret->mu_dptr = malloc (content.dsize);
if (!ret->mu_dptr)
return errno;
memcpy (ret->mu_dptr, content.dptr, content.dsize);
ret->mu_dsize = content.dsize;
ret->mu_sys = db->db_sys;
return 0;
}
static int
_ndbm_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key,
struct mu_dbm_datum *ret)
{
datum keydat, content;
keydat.dptr = key->mu_dptr;
keydat.dsize = key->mu_dsize;
errno = 0;
content = dbm_fetch (db->db_descr, keydat);
mu_dbm_datum_free (ret);
if (content.dptr == NULL)
return MU_ERR_NOENT;
return _ndbm_conv_datum (db, ret, content);
}
static int
_ndbm_store (mu_dbm_file_t db,
struct mu_dbm_datum const *key,
struct mu_dbm_datum const *contents,
int replace)
{
DBM *dbm = db->db_descr;
datum keydat, condat;
keydat.dptr = key->mu_dptr;
keydat.dsize = key->mu_dsize;
condat.dptr = contents->mu_dptr;
condat.dsize = contents->mu_dsize;
errno = 0;
switch (dbm_store (dbm, keydat, condat,
replace ? DBM_REPLACE : DBM_INSERT))
{
case 0:
break;
case 1:
return MU_ERR_EXISTS;
case -1:
db->db_errno.n = errno;
return MU_ERR_FAILURE;
}
return 0;
}
static int
_ndbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
{
DBM *dbm = db->db_descr;
datum keydat;
keydat.dptr = key->mu_dptr;
keydat.dsize = key->mu_dsize;
errno = 0;
switch (dbm_delete (dbm, keydat))
{
case 0:
break;
case 1:
return MU_ERR_NOENT;
case -1:
db->db_errno.n = errno;
return MU_ERR_FAILURE;
}
return 0;
}
static int
_ndbm_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
DBM *dbm = db->db_descr;
datum keydat;
errno = 0;
keydat = dbm_firstkey (dbm);
if (keydat.dptr == NULL)
return MU_ERR_NOENT;
return _ndbm_conv_datum (db, ret, keydat);
}
static int
_ndbm_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
DBM *dbm = db->db_descr;
datum keydat;
keydat = dbm_nextkey (dbm);
if (keydat.dptr == NULL)
return MU_ERR_NOENT;
return _ndbm_conv_datum (db, ret, keydat);
}
static void
_ndbm_datum_free (struct mu_dbm_datum *datum)
{
free (datum->mu_dptr);
}
static char const *
_ndbm_strerror (mu_dbm_file_t db)
{
return strerror (db->db_errno.n);
}
struct mu_dbm_impl _mu_dbm_ndbm = {
"ndbm",
_ndbm_file_safety,
_ndbm_get_fd,
_ndbm_open,
_ndbm_close,
_ndbm_fetch,
_ndbm_store,
_ndbm_delete,
_ndbm_firstkey,
_ndbm_nextkey,
_ndbm_datum_free,
_ndbm_strerror
};
#endif
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
int
mu_dbm_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
DBMSYSCK (db, _dbm_nextkey);
if (!db->db_descr)
return EINVAL;
return db->db_sys->_dbm_nextkey (db, ret);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
int
mu_dbm_open (mu_dbm_file_t db, int flags, int mode)
{
if (!db)
return EINVAL;
if (!db->db_sys || !db->db_sys->_dbm_open)
return ENOSYS;
return db->db_sys->_dbm_open (db, flags, mode);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
int
mu_dbm_safety_set_owner (mu_dbm_file_t db, uid_t uid)
{
if (!db)
return EINVAL;
db->db_owner = uid;
return 0;
}
int
mu_dbm_safety_get_owner (mu_dbm_file_t db, uid_t *uid)
{
if (!db)
return EINVAL;
*uid = db->db_owner;
return 0;
}
int
mu_dbm_safety_set_flags (mu_dbm_file_t db, int flags)
{
if (!db)
return EINVAL;
db->db_safety_flags = flags;
return 0;
}
int
mu_dbm_safety_get_flags (mu_dbm_file_t db, int *flags)
{
if (!db)
return EINVAL;
*flags = db->db_safety_flags;
return 0;
}
int
mu_dbm_safety_check (mu_dbm_file_t db)
{
if (!db)
return EINVAL;
if (!db->db_sys || !db->db_sys->_dbm_file_safety)
return ENOSYS;
return db->db_sys->_dbm_file_safety (db, db->db_safety_flags,
db->db_owner);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 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/dbm.h>
#include <mailutils/errno.h>
#include "mudbm.h"
int
mu_dbm_store (mu_dbm_file_t db, struct mu_dbm_datum const *key,
struct mu_dbm_datum const *contents, int replace)
{
DBMSYSCK (db, _dbm_store);
if (!db->db_descr)
return EINVAL;
return db->db_sys->_dbm_store (db, key, contents, replace);
}
......@@ -36,7 +36,6 @@
#include <string.h>
#include <signal.h>
#include <regex.h>
#include <mu_dbm.h>
#include <mailutils/sieve.h>
#include <mailutils/mu_auth.h>
......
......@@ -46,6 +46,8 @@ maidag_LDADD = \
@MU_AUTHLIBS@\
${MU_LIB_MAILUTILS} \
@MU_COMMON_LIBRARIES@\
../libmu_dbm/libmu_dbm.la\
@DBMLIBS@\
@TCPWRAP_LIBRARIES@
INCLUDES = -I${top_srcdir} @MU_APP_COMMON_INCLUDES@ @GUILE_INCLUDES@ \
......
......@@ -457,7 +457,7 @@ struct mu_cfg_param maidag_cfg_param[] = {
{ "exit-quota-tempfail", mu_cfg_bool, &ex_quota_tempfail, 0, NULL,
N_("Indicate temporary failure if the recipient is over his mail quota.")
},
#ifdef USE_DBM
#ifdef ENABLE_DBM
{ "quota-db", mu_cfg_string, &quotadbname, 0, NULL,
N_("Name of DBM quota database file."),
N_("file") },
......
......@@ -86,10 +86,9 @@
#include <mailutils/server.h>
#include <mailutils/cctype.h>
#include <mailutils/io.h>
#include <mailutils/dbm.h>
#include <mu_dbm.h>
#if defined (USE_DBM) || defined (USE_SQL)
#if defined (ENABLE_DBM) || defined (USE_SQL)
# define USE_MAILBOX_QUOTAS 1
#endif
......
......@@ -64,64 +64,85 @@ fail_retrieve_quota (char *name, mu_off_t *quota)
return RETR_FAILURE;
}
#ifdef USE_DBM
#ifdef ENABLE_DBM
int
dbm_retrieve_quota (char *name, mu_off_t *quota)
{
DBM_FILE db;
DBM_DATUM named, contentd;
mu_dbm_file_t db;
struct mu_dbm_datum named, contentd;
char buffer[64];
int unlimited = 0;
int rc;
if (!quotadbname)
return RETR_FAILURE;
if (mu_dbm_open (quotadbname, &db, MU_STREAM_READ, 0600))
rc = mu_dbm_create (quotadbname, &db);
if (rc)
{
mu_error (_("unable to create quota db"));
return RETR_FAILURE;
}
rc = mu_dbm_safety_check (db);
if (rc && rc != ENOENT)
{
mu_error (_("cannot open file %s: %s"), quotadbname, mu_strerror (errno));
mu_error (_("quota db fails safety check: %s"),
mu_strerror (rc));
mu_dbm_destroy (&db);
return RETR_FAILURE;
}
rc = mu_dbm_open (db, MU_STREAM_READ, 0600);
if (rc)
{
mu_error (_("cannot open file %s: %s"),
quotadbname, mu_strerror (rc));
mu_dbm_destroy (&db);
return RETR_FAILURE;
}
memset (&named, 0, sizeof named);
memset (&contentd, 0, sizeof contentd);
MU_DATUM_PTR (named) = name;
MU_DATUM_SIZE (named) = strlen (name);
rc = mu_dbm_fetch (db, named, &contentd);
if (rc || !MU_DATUM_PTR (contentd))
named.mu_dptr = name;
named.mu_dsize = strlen (name);
rc = mu_dbm_fetch (db, &named, &contentd);
if (rc)
{
/* User not in database, try default quota */
memset (&named, 0, sizeof named);
MU_DATUM_PTR (named) = "DEFAULT";
MU_DATUM_SIZE (named) = strlen ("DEFAULT");
rc = mu_dbm_fetch (db, named, &contentd);
if (rc)
mu_dbm_datum_free (&named);
named.mu_dptr = "DEFAULT";
named.mu_dsize = strlen ("DEFAULT");
rc = mu_dbm_fetch (db, &named, &contentd);
if (rc == MU_ERR_NOENT)
{
/*mu_error (_("can't fetch data: %s"), strerror (rc));*/
mu_dbm_destroy (&db);
return RETR_FAILURE;
}
else if (rc)
{
mu_error (_("can't fetch data: %s"), mu_dbm_strerror (db));
mu_dbm_destroy (&db);
return RETR_FAILURE;
}
if (!MU_DATUM_PTR (contentd))
return RETR_FAILURE;
}
if (mu_c_strncasecmp("none",
MU_DATUM_PTR (contentd),
MU_DATUM_SIZE (contentd)) == 0)
if (mu_c_strncasecmp("none", contentd.mu_dptr, contentd.mu_dsize) == 0)
unlimited = 1;
else if (MU_DATUM_SIZE (contentd) > sizeof(buffer)-1)
else if (contentd.mu_dsize > sizeof (buffer) - 1)
{
mu_error (ngettext ("mailbox quota for `%s' is too big: %d digit",
"mailbox quota for `%s' is too big: %d digits",
MU_DATUM_SIZE (contentd)),
name, MU_DATUM_SIZE (contentd));
contentd.mu_dsize),
name, contentd.mu_dsize);
*quota = groupquota;
}
else
{
char *p;
strncpy(buffer, MU_DATUM_PTR (contentd), MU_DATUM_SIZE (contentd));
buffer[MU_DATUM_SIZE (contentd)] = 0;
strncpy (buffer, contentd.mu_dptr, contentd.mu_dsize);
buffer[contentd.mu_dsize] = 0;
*quota = strtoul (buffer, &p, 0);
if (get_size (buffer, quota, &p))
{
......@@ -129,8 +150,9 @@ dbm_retrieve_quota (char *name, mu_off_t *quota)
*quota = groupquota;
}
}
mu_dbm_close (db);
mu_dbm_datum_free (&contentd);
mu_dbm_destroy (&db);
return unlimited ? RETR_UNLIMITED : RETR_OK;
}
......
......@@ -32,9 +32,17 @@ else
IDLE_MODULES+=imap.c
endif
if MU_COND_DBM
DBM_C=dbm.c
LIBMU_DBM=../libmu_dbm/libmu_dbm.la
else
IDLE_MODULES+=dbm.c
endif
MODULES = \
acl.c\
cflags.c\
$(DBM_C)\
$(IMAP_C)\
filter.c\
flt2047.c\
......@@ -67,6 +75,7 @@ mu_LDADD = \
${MU_LIB_AUTH}\
@MU_AUTHLIBS@\
${MU_LIB_MAILUTILS}\
${LIBMU_DBM} @DBMLIBS@\
@READLINE_LIBS@ @MU_COMMON_LIBRARIES@
INCLUDES = @MU_APP_COMMON_INCLUDES@ @MU_AUTHINCS@
......@@ -77,7 +86,8 @@ AM_CPPFLAGS = \
-DAUTHLIBS="\"$(MU_AUTHLIBS)\"" \
-DGUILE_LIBS="\"$(GUILE_LIBS)\"" \
-DPYTHON_LIBS="\"$(PYTHON_LIBS)\"" \
-DI18NLIBS="\"$(LIBINTL)\""
-DI18NLIBS="\"$(LIBINTL)\"" \
-DDBMLIBS="\"$(DBMLIBS)\""
BUILT_SOURCES=mu-setup.c mu-setup.h
EXTRA_DIST=mu-setup.awk mu-setup.c mu-setup.h template.c
......
This diff is collapsed. Click to expand it.
......@@ -38,36 +38,52 @@ static struct argp ldflags_argp = {
#ifdef WITH_TLS
# define NEEDAUTH 1
# define NEEDAUTH "-lmu_auth " AUTHLIBS
#else
# define NEEDAUTH 0
# define NEEDAUTH NULL
#endif
#define NOTALL 2
#define NOTALL 1
struct lib_descr {
char *name;
char *libname;
int weight;
int flags;
} lib_descr[] = {
{ "mbox", "mu_mbox", 0 },
{ "mbox", "-lmu_mbox", 0 },
#ifdef ENABLE_MH
{ "mh", "mu_mh", 0 },
{ "mh", "-lmu_mh", 0 },
#endif
#ifdef ENABLE_MAILDIR
{ "maildir","mu_maildir", 0 },
{ "maildir", "-lmu_maildir", 0 },
#endif
#ifdef ENABLE_IMAP
{ "imap", "mu_imap", NEEDAUTH },
{ "imap", "-lmu_imap", 0 },
{ "imap", NEEDAUTH, 2 },
#endif
#ifdef ENABLE_POP
{ "pop", "mu_pop", NEEDAUTH },
{ "pop", "-lmu_pop", 0 },
{ "pop", NEEDAUTH, 2 },
#endif
#ifdef ENABLE_NNTP
{ "nntp", "mu_nntp", 0 },
{ "nntp", "-lmu_nntp", 0 },
#endif
{ "mailer", "mu_mailer", 0 },
{ "sieve", "mu_sieve", NOTALL },
{ "compat", "mu_compat" },
#ifdef ENABLE_DBM
{ "dbm", "-lmu_dbm", 0 },
{ "dbm", DBMLIBS, 2 },
#endif
{ "mailer", "-lmu_mailer", 0 },
{ "sieve", "-lmu_sieve", 0, NOTALL },
{ "compat", "-lmu_compat", 0 },
{ "auth", "-lmu_auth " AUTHLIBS, 2 },
#ifdef WITH_GUILE
{ "guile", "-lmu_scm " GUILE_LIBS, -1, NOTALL },
#endif
#ifdef WITH_PYTHON
{ "python", "-lmu_py " PYTHON_LIBS, -1, NOTALL },
#endif
{ "cfg", "-lmu_cfg", -1, NOTALL },
{ "argp", "-lmu_argp", -2, NOTALL },
{ NULL }
};
......@@ -82,6 +98,9 @@ void
add_entry (int level, char *ptr)
{
int i;
if (!ptr || !*ptr)
return;
if (nentry >= sizeof(lib_entry)/sizeof(lib_entry[0]))
{
mu_error (_("too many arguments"));
......@@ -122,7 +141,6 @@ int
mutool_ldflags (int argc, char **argv)
{
int i, j;
char *ptr;
if (argp_parse (&ldflags_argp, argc, argv, ARGP_IN_ORDER, &i, NULL))
return 1;
......@@ -140,21 +158,7 @@ mutool_ldflags (int argc, char **argv)
for ( ; argc > 0; argc--, argv++)
{
if (strcmp (argv[0], "auth") == 0)
add_entry (2, "-lmu_auth " AUTHLIBS);
#ifdef WITH_GUILE
else if (strcmp (argv[0], "guile") == 0)
add_entry (-1, "-lmu_scm " GUILE_LIBS);
#endif
#ifdef WITH_PYTHON
else if (strcmp (argv[0], "python") == 0)
add_entry (-1, "-lmu_py " PYTHON_LIBS);
#endif
else if (strcmp (argv[0], "cfg") == 0)
add_entry (-1, "-lmu_cfg");
else if (strcmp (argv[0], "argp") == 0)
add_entry (-2, "-lmu_argp");
else if (strcmp (argv[0], "all") == 0)
if (strcmp (argv[0], "all") == 0)
{
struct lib_descr *p;
......@@ -162,28 +166,24 @@ mutool_ldflags (int argc, char **argv)
{
if (p->flags & NOTALL)
continue;
mu_asprintf (&ptr, "-l%s", p->libname);
add_entry (0, ptr);
if (p->flags & NEEDAUTH)
add_entry (2, "-lmu_auth " AUTHLIBS);
add_entry (p->weight, p->libname);
}
}
else
{
struct lib_descr *p;
int found = 0;
for (p = lib_descr; p->name; p++)
if (mu_c_strcasecmp (p->name, argv[0]) == 0)
break;
if (p->name)
{
mu_asprintf (&ptr, "-l%s", p->libname);
add_entry (0, ptr);
if (p->flags & NEEDAUTH)
add_entry (2, "-lmu_auth " AUTHLIBS);
if (mu_c_strcasecmp (p->name, argv[0]) == 0)
{
add_entry (p->weight, p->libname);
found = 1;
}
}
else
if (!found)
{
mu_error (_("unknown keyword: %s"), argv[0]);
return 1;
......
......@@ -46,6 +46,10 @@ pop3d_SOURCES =\
uidl.c\
user.c
if MU_COND_DBM
LIBMU_DBM=../libmu_dbm/libmu_dbm.la
endif
pop3d_LDADD = \
${MU_APP_LIBRARIES}\
${MU_LIB_MBOX}\
......@@ -54,15 +58,25 @@ pop3d_LDADD = \
${MU_LIB_AUTH}\
@MU_AUTHLIBS@ \
${MU_LIB_MAILUTILS}\
@MU_COMMON_LIBRARIES@ @TCPWRAP_LIBRARIES@
@MU_COMMON_LIBRARIES@\
${LIBMU_DBM}\
@DBMLIBS@\
@TCPWRAP_LIBRARIES@
popauth_SOURCES = popauth.c
popauth_LDADD = ${MU_APP_LIBRARIES} ${MU_LIB_MAILUTILS} @MU_COMMON_LIBRARIES@
popauth_LDADD = \
${MU_APP_LIBRARIES}\
${MU_LIB_MAILUTILS}\
@MU_COMMON_LIBRARIES@\
${LIBMU_DBM}\
@DBMLIBS@
pop3d_DEPENDENCIES = \
@MU_AUTHLIBS_DEPENDENCY@ \
../lib/libmuaux.a \
${MU_LIB_MBOX}\
${MU_LIB_MH}\
${MU_LIB_MAILDIR}\
${MU_LIB_MAILUTILS}
${MU_LIB_MAILUTILS}\
${LIBMU_DBM}
......
......@@ -43,59 +43,85 @@ pop3d_apopuser (const char *user)
{
char *password = NULL;
#ifdef USE_DBM
#ifdef ENABLE_DBM
{
size_t len;
DBM_FILE db;
DBM_DATUM key, data;
mu_dbm_file_t db;
struct mu_dbm_datum key, data;
int rc;
int rc = mu_dbm_open (APOP_PASSFILE, &db, MU_STREAM_READ, 0600);
rc = mu_dbm_create (APOP_PASSFILE, &db);
if (rc)
{
mu_diag_output (MU_DIAG_ERROR, _("unable to create APOP db"));
return NULL;
}
rc = mu_dbm_safety_check (db);
if (rc)
{
mu_diag_output (MU_DIAG_ERROR,
_("APOP file %s fails safety check: %s"),
APOP_PASSFILE, mu_strerror (rc));
mu_dbm_destroy (&db);
return NULL;
}
rc = mu_dbm_open (db, MU_STREAM_READ, 0600);
if (rc)
{
mu_diag_output (MU_DIAG_ERROR, _("unable to open APOP db: %s"),
mu_strerror (errno));
mu_strerror (rc));
return NULL;
}
memset (&key, 0, sizeof key);
memset (&data, 0, sizeof data);
MU_DATUM_PTR (key) = (void*) user;
MU_DATUM_SIZE (key) = strlen (user);
key.mu_dptr = (void *)user;
key.mu_dsize = strlen (user);
rc = mu_dbm_fetch (db, key, &data);
mu_dbm_close (db);
if (rc)
rc = mu_dbm_fetch (db, &key, &data);
if (rc == MU_ERR_NOENT)
{
mu_dbm_destroy (&db);
return NULL;
}
else if (rc)
{
mu_diag_output (MU_DIAG_ERROR,
_("cannot fetch APOP data: %s"), mu_strerror (errno));
_("cannot fetch APOP data: %s"),
mu_dbm_strerror (db));
mu_dbm_destroy (&db);
return NULL;
}
len = MU_DATUM_SIZE (data);
mu_dbm_destroy (&db);
len = data.mu_dsize;
password = malloc (len + 1);
if (password == NULL)
{
mu_dbm_datum_free (&data);
return NULL;
}
memcpy (password, MU_DATUM_PTR (data), len);
memcpy (password, data.mu_dptr, len);
password[len] = 0;
mu_dbm_datum_free (&data);
return password;
}
#else /* !USE_DBM */
#else /* !ENABLE_DBM */
{
char *buf = NULL;
size_t size = 0;
size_t ulen;
FILE *apop_file;
if (mu_check_perm (APOP_PASSFILE, 0600))
{
mu_diag_output (MU_DIAG_INFO,
_("bad permissions on APOP password file"));
return NULL;
}
/* FIXME */
/* if (mu_check_perm (APOP_PASSFILE, 0600)) */
/* { */
/* mu_diag_output (MU_DIAG_INFO, */
/* _("bad permissions on APOP password file")); */
/* return NULL; */
/* } */
apop_file = fopen (APOP_PASSFILE, "r");
if (apop_file == NULL)
......
......@@ -113,58 +113,72 @@ write_popbull_file (size_t num)
return rc;
}
#ifdef USE_DBM
#ifdef ENABLE_DBM
int
read_bulletin_db (size_t *pnum)
{
DBM_FILE db;
DBM_DATUM key, data;
mu_dbm_file_t db;
struct mu_dbm_datum key, data;
int rc;
char sbuf[128];
char *bufptr;
char *buf = NULL;
size_t s;
char *p;
rc = mu_dbm_open (bulletin_db_name, &db, MU_STREAM_READ, 0660);
rc = mu_dbm_create (bulletin_db_name, &db);
if (rc)
{
if (errno == ENOENT)
mu_diag_output (MU_DIAG_ERROR, _("unable to create bulletin db"));
return rc;
}
rc = mu_dbm_safety_check (db);
if (rc)
{
if (rc == ENOENT)
{
*pnum = 0;
return 0;
}
else
{
mu_error (_("unable to open bulletin db for reading: %s"),
mu_strerror (errno));
return rc;
}
mu_diag_output (MU_DIAG_ERROR,
_("bulletin db %s fails safety check: %s"),
bulletin_db_name, mu_strerror (rc));
mu_dbm_destroy (&db);
return 1;
}
rc = mu_dbm_open (db, MU_STREAM_READ, 0660);
if (rc)
{
mu_error (_("unable to open bulletin db for reading: %s"),
mu_strerror (rc));
return rc;
}
memset (&key, 0, sizeof key);
memset (&data, 0, sizeof data);
MU_DATUM_PTR(key) = username;
MU_DATUM_SIZE(key) = strlen (username);
key.mu_dptr = username;
key.mu_dsize = strlen (username);
rc = mu_dbm_fetch (db, key, &data);
rc = mu_dbm_fetch (db, &key, &data);
if (rc)
if (rc == MU_ERR_NOENT)
{
*pnum = 0;
return 0;
}
else if (rc)
{
int ec = errno;
if (ec == ENOENT)
{
*pnum = 0;
return 0;
}
mu_error (_("cannot fetch bulletin db data: %s"),
mu_strerror (ec));
mu_dbm_close (db);
mu_dbm_strerror (db));
mu_dbm_destroy (&db);
return 1;
}
mu_dbm_destroy (&db);
s = MU_DATUM_SIZE (data);
s = data.mu_dsize;
if (s < sizeof sbuf)
bufptr = sbuf;
else
......@@ -172,16 +186,15 @@ read_bulletin_db (size_t *pnum)
buf = malloc (s + 1);
if (!buf)
{
mu_error("%s", mu_strerror (errno));
mu_error ("%s", mu_strerror (errno));
return 1;
}
bufptr = buf;
}
memcpy (bufptr, MU_DATUM_PTR (data), s);
memcpy (bufptr, data.mu_dptr, s);
bufptr[s] = 0;
mu_dbm_datum_free(&data);
mu_dbm_close (db);
mu_dbm_datum_free (&data);
rc = 1;
*pnum = strtoul (bufptr, &p, 0);
......@@ -189,26 +202,8 @@ read_bulletin_db (size_t *pnum)
rc = 0;
else
{
#ifdef QPOPPER_COMPAT
if (s == sizeof long)
{
long n;
n = *(long*)MU_DATUM_PTR (data);
if (n >= 0)
{
mu_diag_output (MU_DIAG_INFO,
_("assuming bulletin database is in qpopper format"));
*pnum = n;
rc = 0;
}
}
else
#endif /* QPOPPER_COMPAT */
{
mu_error (_("wrong bulletin database format for `%s'"),
username);
}
mu_error (_("wrong bulletin database format for `%s'"),
username);
}
free (buf);
......@@ -218,41 +213,60 @@ read_bulletin_db (size_t *pnum)
int
write_bulletin_db (size_t num)
{
DBM_FILE db;
DBM_DATUM key, data;
mu_dbm_file_t db;
struct mu_dbm_datum key, data;
int rc;
const char *p;
rc = mu_dbm_open (bulletin_db_name, &db, MU_STREAM_RDWR, 0660);
rc = mu_dbm_create (bulletin_db_name, &db);
if (rc)
{
mu_diag_output (MU_DIAG_ERROR, _("unable to create bulletin db"));
return rc;
}
rc = mu_dbm_safety_check (db);
if (rc && rc != ENOENT)
{
mu_diag_output (MU_DIAG_ERROR,
_("bulletin db %s fails safety check: %s"),
bulletin_db_name, mu_strerror (rc));
mu_dbm_destroy (&db);
return rc;
}
rc = mu_dbm_open (db, MU_STREAM_RDWR, 0660);
if (rc)
{
mu_error (_("unable to open bulletin db for writing: %s"),
mu_strerror (errno));
mu_strerror (rc));
mu_dbm_destroy (&db);
return rc;
}
memset (&key, 0, sizeof key);
memset (&data, 0, sizeof data);
MU_DATUM_PTR (key) = username;
MU_DATUM_SIZE (key) = strlen (username);
key.mu_dptr = username;
key.mu_dsize = strlen (username);
p = mu_umaxtostr (0, num);
MU_DATUM_PTR (data) = (char *) p;
MU_DATUM_SIZE (data) = strlen (p);
data.mu_dptr = (char *) p;
data.mu_dsize = strlen (p);
rc = mu_dbm_insert (db, key, data, 1);
rc = mu_dbm_store (db, &key, &data, 1);
if (rc)
mu_error (_("cannot store datum in bulletin db"));
mu_dbm_close (db);
mu_error (_("cannot store datum in bulletin db: %s"),
mu_dbm_strerror (db));
mu_dbm_destroy (&db);
return rc;
}
#endif /* USE_DBM */
#endif /* ENABLE_DBM */
int
get_last_delivered_num (size_t *pret)
{
#ifdef USE_DBM
#ifdef ENABLE_DBM
if (bulletin_db_name && read_bulletin_db (pret) == 0)
return 0;
#endif
......@@ -262,7 +276,7 @@ get_last_delivered_num (size_t *pret)
void
store_last_delivered_num (size_t num)
{
#ifdef USE_DBM
#ifdef ENABLE_DBM
if (bulletin_db_name && write_bulletin_db (num) == 0)
return;
#endif
......
......@@ -19,27 +19,45 @@
#ifdef ENABLE_LOGIN_DELAY
static int
open_stat_db (DBM_FILE *db, int mode)
static mu_dbm_file_t
open_stat_db (int mode)
{
int rc = mu_dbm_open (login_stat_file, db, mode, 0660);
mu_dbm_file_t db;
int rc;
rc = mu_dbm_create (login_stat_file, &db);
if (rc)
{
if (rc == -1)
mu_diag_output (MU_DIAG_INFO, _("bad permissions on statistics db"));
else
mu_diag_output (MU_DIAG_ERROR, _("unable to open statistics db: %s"),
mu_strerror (rc));
mu_diag_output (MU_DIAG_ERROR, _("unable to create statistics db"));
return NULL;
}
rc = mu_dbm_safety_check (db);
if (rc)
{
mu_diag_output (MU_DIAG_ERROR,
_("statistics db fails safety check: %s"),
mu_strerror (rc));
mu_dbm_destroy (&db);
return NULL;
}
return rc;
rc = mu_dbm_open (db, mode, 0660);
if (rc)
{
mu_diag_output (MU_DIAG_ERROR, _("unable to open statistics db: %s"),
mu_dbm_strerror (db));
mu_dbm_destroy (&db);
}
return db;
}
int
check_login_delay (char *username)
{
time_t now, prev_time;
DBM_FILE db;
DBM_DATUM key, data;
mu_dbm_file_t db;
struct mu_dbm_datum key, data;
char text[64], *p;
int rc;
......@@ -47,42 +65,45 @@ check_login_delay (char *username)
return 0;
time (&now);
if (open_stat_db (&db, MU_STREAM_RDWR))
db = open_stat_db (MU_STREAM_READ);
if (!db)
return 0;
memset (&key, 0, sizeof key);
MU_DATUM_PTR(key) = username;
MU_DATUM_SIZE(key) = strlen (username);
key.mu_dptr = username;
key.mu_dsize = strlen (username);
memset (&data, 0, sizeof data);
rc = mu_dbm_fetch (db, key, &data);
rc = mu_dbm_fetch (db, &key, &data);
if (rc)
{
mu_diag_output (MU_DIAG_ERROR, _("cannot fetch login delay data: %s"),
mu_strerror (rc));
mu_dbm_close (db);
if (rc != MU_ERR_NOENT)
mu_diag_output (MU_DIAG_ERROR, _("cannot fetch login delay data: %s"),
mu_dbm_strerror (db));
mu_dbm_destroy (&db);
return 0;
}
if (MU_DATUM_SIZE(data) > sizeof (text) - 1)
if (data.mu_dsize > sizeof (text) - 1)
{
mu_diag_output (MU_DIAG_ERROR,
_("invalid entry for '%s': wrong timestamp size"),
username);
mu_dbm_close (db);
username);
mu_dbm_destroy (&db);
return 0;
}
mu_dbm_destroy (&db);
memcpy (text, MU_DATUM_PTR(data), MU_DATUM_SIZE(data));
text[MU_DATUM_SIZE(data)] = 0;
mu_dbm_close (db);
memcpy (text, data.mu_dptr, data.mu_dsize);
text[data.mu_dsize] = 0;
mu_dbm_datum_free (&data);
prev_time = strtoul (text, &p, 0);
if (*p)
{
mu_diag_output (MU_DIAG_ERROR,
_("malformed timestamp for '%s': %s"),
username, text);
username, text);
return 0;
}
......@@ -93,40 +114,42 @@ void
update_login_delay (char *username)
{
time_t now;
DBM_FILE db;
DBM_DATUM key, data;
mu_dbm_file_t db;
struct mu_dbm_datum key, data;
char text[64];
if (login_delay == 0 || username == NULL)
return;
time (&now);
if (open_stat_db (&db, MU_STREAM_RDWR))
db = open_stat_db (MU_STREAM_RDWR);
if (!db)
return;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
MU_DATUM_PTR(key) = username;
MU_DATUM_SIZE(key) = strlen (username);
key.mu_dptr = username;
key.mu_dsize = strlen (username);
snprintf (text, sizeof text, "%lu", (unsigned long) now);
MU_DATUM_PTR(data) = text;
MU_DATUM_SIZE(data) = strlen (text);
if (mu_dbm_insert (db, key, data, 1))
mu_error (_("%s: cannot store datum %s/%s"),
login_stat_file, username, text);
data.mu_dptr = text;
data.mu_dsize = strlen (text);
if (mu_dbm_store (db, &key, &data, 1))
mu_error (_("%s: cannot store datum %s/%s: %s"),
login_stat_file, username, text,
mu_dbm_strerror (db));
mu_dbm_close (db);
mu_dbm_destroy (&db);
}
void
login_delay_capa ()
{
DBM_FILE db;
mu_dbm_file_t db;
if (login_delay && open_stat_db (&db, MU_STREAM_RDWR) == 0)
if (login_delay && (db = open_stat_db (MU_STREAM_RDWR)) != NULL)
{
pop3d_outf ("LOGIN-DELAY %s\n", mu_umaxtostr (0, login_delay));
mu_dbm_close (db);
mu_dbm_destroy (&db);
}
}
#endif
......
......@@ -77,7 +77,7 @@ cb_bulletin_source (void *data, mu_config_value_t *val)
return 0;
}
#ifdef USE_DBM
#ifdef ENABLE_DBM
static int
cb_bulletin_db (void *data, mu_config_value_t *val)
{
......@@ -111,7 +111,7 @@ static struct mu_cfg_param pop3d_cfg_param[] = {
{ "bulletin-source", mu_cfg_callback, NULL, 0, cb_bulletin_source,
N_("Get bulletins from the specified mailbox."),
N_("url") },
#ifdef USE_DBM
#ifdef ENABLE_DBM
{ "bulletin-db", mu_cfg_callback, NULL, 0, cb_bulletin_db,
N_("Set the bulletin database file name."),
N_("file") },
......
......@@ -24,7 +24,7 @@
#include <mailutils/types.h>
#include <mailutils/stream.h>
#include <mailutils/io.h>
#include <mu_dbm.h>
#include <mailutils/dbm.h>
#include <mu_umaxtostr.h>
#include <muaux.h>
......@@ -35,7 +35,7 @@
type automatically */
#define APOP_PASSFILE_NAME "apop"
#ifdef USE_DBM
#ifdef ENABLE_DBM
# define APOP_PASSFILE SYSCONFDIR "/" APOP_PASSFILE_NAME
# define ENABLE_LOGIN_DELAY
#else
......