aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-11-10 00:21:13 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2011-11-10 00:52:54 +0200
commit4926ea635ee23341615c351db3e4949553ca4dfb (patch)
treea1a8c4aede69cf55b5e27fa1dc1630aeeda70329 /src
parent7e4d54bd39368b36e8451d52975052c00e745f7a (diff)
downloadmailfromd-4926ea635ee23341615c351db3e4949553ca4dfb.tar.gz
mailfromd-4926ea635ee23341615c351db3e4949553ca4dfb.tar.bz2
Switch to libmu_dbm for DBM support.
* configure.ac (DEFAULT_DB_TYPE): New variable. Use mu info to determine which DBM is supported. * lib/Makefile.am (noinst_LIBRARIES): Remove libdbm.a * lib/mf-dbm.c: remove. * lib/mf-dbm.h: remove. * lib/cache.c: Use libmu_dbm functions. * lib/db.c: Likewise. * lib/dbcfg.c: Likewise. * lib/greylist.c: Likewise. * lib/rate.c: Likewise. * lib/tbf_rate.c: Likewise. * src/builtin/db.bi: Likewise. * src/savsrv.c: Likewise. * src/srvcfg.c (srv_cfg_param) <database-type>: New statement. * lib/libmf.h (config_cb_ignore): New proto. * lib/mfdb.h (db_item_printer_t): Change signature. * lib/utils.c (config_cb_ignore): New function. * po/POTFILES.in: Update. * src/Makefile.am (mailfromd_LDADD) (calloutd_LDADD): Remove libdbm.a. * src/calloutd.c: Update. * src/main.c (mf_cfg_param): lock-retry-count and lock-retry-timeout are no-op now. * src/mfdbtool.c: Likewise.
Diffstat (limited to 'src')
-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
7 files changed, 328 insertions, 235 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 4400f8d4..af404ca5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -39,59 +39,56 @@ mailfromd_SOURCES = \
pragma.c\
prog.c\
prog.h\
spf.c\
stack.c\
symbols.c
mailfromd_LDADD = \
./libcallout.a\
builtin/libbuiltin.a\
../lib/libmfdb.a\
../lib/libmf.a\
- ../lib/libdbm.a\
../gnu/libgnu.a\
$(MAILUTILS_LIBS)\
$(MILTER)\
$(GEOIP_LIBS)\
$(DSPAM_LIBS)
noinst_HEADERS = \
bitmask.h\
callout-dbgmod.h\
mailfromd.h\
spf.h\
drivers.c\
mfd-dbgmod.h\
srvcfg.h
calloutd_SOURCES = \
calloutd.c
calloutd_LDADD = \
./libcallout.a\
../lib/libmfdb.a\
../lib/libmf.a\
- ../lib/libdbm.a\
../gnu/libgnu.a\
$(MAILUTILS_LIBS)\
$(MILTER)
mfdbtool_SOURCES = \
mfdbtool.c
mfdbtool_LDADD = \
../lib/libmfdb.a\
../lib/libmf.a\
- ../lib/libdbm.a\
../gnu/libgnu.a\
$(MAILUTILS_LIBS)
EXTRA_DIST = \
dbgmod.awk\
drv.awk\
gram.h\
node-tab.c\
node-type.h\
opcode.awk\
opcodes\
optab.opc\
diff --git a/src/builtin/db.bi b/src/builtin/db.bi
index a734dc10..90d926eb 100644
--- a/src/builtin/db.bi
+++ b/src/builtin/db.bi
@@ -7,25 +7,24 @@
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#define DEFAULT_DB_MODE 0640
#include <fnmatch.h>
-#include "mf-dbm.h"
struct db_prop { /* Database properties */
char *pat; /* Database name pattern */
mode_t mode; /* File mode */
int null; /* Null byte */
};
static mu_list_t db_prop_list;
static int
db_prop_compare(const void *item, const void *data)
{
@@ -134,76 +133,112 @@ db_prop_lookup(const char *name)
const struct db_prop *p;
mu_iterator_current(itr, (void**)&p);
if (strcmp(p->pat, name) == 0) {
found = p;
break;
} else if (fnmatch(p->pat, name, 0) == 0)
found = p;
}
mu_iterator_destroy(&itr);
}
return found;
}
+
+int
+_mf_dbm_open(mu_dbm_file_t *pdb, 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)
+ return rc;
+
+ 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 rc;
+ }
+ /* FIXME: Safety checking */
+ rc = mu_dbm_open(db, access, mode);
+ if (rc)
+ return rc;
+ *pdb = db;
+ return rc;
+}
#define LOOKUP_NULL_BYTE 0x1
#define LOOKUP_TEST_ONLY 0x2
MF_DSEXP_SUPPRESS([<dbmap_lookup>],[<
static int
dbmap_lookup(eval_environ_t env, char *dbname, const char *keystr,
const char *defval, int flags)
{
int 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;
if (!defval)
defval = "";
- if (mf_dbm_open(dbname, &db, MU_STREAM_READ, 0, NULL))
+ rc = _mf_dbm_open(&db, dbname, MU_STREAM_READ, 0);
+ if (rc)
MF_THROW(mfe_dbfailure,
_("mf_dbm_open(%s) failed: %s"),
dbname,
- mf_dbm_strerror());
+ mu_strerror(rc));
memset(&key, 0, sizeof key);
memset(&contents, 0, sizeof contents);
- MF_DATUM_PTR(key) = (void*) keystr;
- MF_DATUM_SIZE(key) = strlen(keystr);
+ key.mu_dptr = (void*) keystr;
+ key.mu_dsize = strlen(keystr);
if (flags & LOOKUP_NULL_BYTE)
- MF_DATUM_SIZE(key)++;
- rc = mf_dbm_fetch(&db, key, &contents) == 0;
+ key.mu_dsize++;
+ rc = mu_dbm_fetch(db, &key, &contents);
+ if (rc && rc != MU_ERR_NOENT) {
+ mu_dbm_destroy(&db);
+ MF_THROW(mfe_dbfailure,
+ _("cannot fetch data: %s"),
+ mu_dbm_strerror(db));
+ }
MF_DEBUG(MU_DEBUG_TRACE5,
- ("Looking up %s: %s", keystr, rc ? "true" : "false"));
+ ("Looking up %s: %s", keystr, rc ? "false" : "true"));
if (flags & LOOKUP_TEST_ONLY)
push(env, (STKVAL)rc);
else {
if (!rc) {
if (defval)
pushs(env, (STKVAL)defval);
else
push(env, 0);
- } else if (((char*)MF_DATUM_PTR(contents))[MF_DATUM_SIZE(contents)-1]) {
+ } else if (((char*)contents.mu_dptr)[contents.mu_dsize-1]) {
size_t off;
- size_t len = MF_DATUM_SIZE(contents);
+ size_t len = contents.mu_dsize;
char *s = MF_ALLOC_HEAP(off, len + 1);
- memcpy(s, MF_DATUM_PTR(contents), len);
+ memcpy(s, contents.mu_dptr, len);
s[len] = 0;
push(env, (STKVAL) off);
} else
- pushs(env, MF_DATUM_PTR(contents));
+ pushs(env, contents.mu_dptr);
}
- mf_dbm_datum_free(&contents);
- mf_dbm_close(&db);
+ mu_dbm_datum_free(&contents);
+ mu_dbm_destroy(&db);
return rc;
}
>])
MF_DSEXP
MF_DEFUN(dbmap, NUMBER, STRING dbname, STRING key, OPTIONAL, NUMBER null)
{
const struct db_prop *prop = db_prop_lookup(dbname);
dbmap_lookup(env, dbname, key, NULL,
LOOKUP_TEST_ONLY |
(MF_OPTVAL(null, prop && prop->null)
? LOOKUP_NULL_BYTE : 0));
@@ -216,151 +251,163 @@ MF_DEFUN(dbget, STRING, STRING dbname, STRING key, OPTIONAL,
const struct db_prop *prop = db_prop_lookup(dbname);
dbmap_lookup(env, dbname, key,
MF_OPTVAL(defval),
MF_OPTVAL(null, prop && prop->null)
? LOOKUP_NULL_BYTE : 0);
}
END
MF_DEFUN(dbput, VOID, STRING dbname, STRING keystr, STRING value,
OPTIONAL, NUMBER null, NUMBER mode)
{
int 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;
const struct db_prop *prop = db_prop_lookup(dbname);
- if (mf_dbm_open(dbname, &db, MU_STREAM_RDWR,
- MF_OPTVAL(mode, (prop ? prop->mode : DEFAULT_DB_MODE)),
- NULL))
+ rc = _mf_dbm_open(&db, dbname, MU_STREAM_RDWR,
+ MF_OPTVAL(mode,
+ (prop ? prop->mode : DEFAULT_DB_MODE)));
+ if (rc)
MF_THROW(mfe_dbfailure,
_("mf_dbm_open(%s) failed: %s"),
dbname,
- mf_dbm_strerror());
+ mu_strerror(rc));
memset(&key, 0, sizeof key);
- MF_DATUM_PTR(key) = keystr;
- MF_DATUM_SIZE(key) = strlen(keystr);
+ key.mu_dptr = keystr;
+ key.mu_dsize = strlen(keystr);
if (MF_OPTVAL(null, prop && prop->null))
- MF_DATUM_SIZE(key)++;
+ key.mu_dsize++;
memset(&contents, 0, sizeof contents);
- MF_DATUM_PTR(contents) = value;
- MF_DATUM_SIZE(contents) = strlen(value) + 1;
+ contents.mu_dptr = value;
+ contents.mu_dsize = strlen(value) + 1;
- rc = mf_dbm_insert(&db, key, contents, 1);
- mf_dbm_close(&db);
- MF_ASSERT(rc == 0,
- mfe_dbfailure,
- _("failed to insert data to %s: %s %s: %s"),
- dbname,
- keystr,
- value,
- mf_dbm_strerror());
+ rc = mu_dbm_store(db, &key, &contents, 1);
+ if (rc) {
+ const char *errstr = mu_dbm_strerror(db);
+ mu_dbm_destroy(&db);
+ MF_THROW(mfe_dbfailure,
+ _("failed to insert data to %s: %s %s: %s"),
+ dbname,
+ keystr,
+ value,
+ errstr);
+ }
+ mu_dbm_destroy(&db);
}
END
MF_DEFUN(dbinsert, VOID, STRING dbname, STRING keystr, STRING value,
OPTIONAL, NUMBER replace, NUMBER null, NUMBER mode)
{
int 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;
const struct db_prop *prop = db_prop_lookup(dbname);
+ const char *errstr;
- if (mf_dbm_open(dbname, &db, MU_STREAM_RDWR,
- MF_OPTVAL(mode, (prop ? prop->mode : DEFAULT_DB_MODE)),
- NULL))
+ rc = _mf_dbm_open(&db, dbname, MU_STREAM_RDWR,
+ MF_OPTVAL(mode,
+ (prop ? prop->mode : DEFAULT_DB_MODE)));
+ if (rc)
MF_THROW(mfe_dbfailure,
_("mf_dbm_open(%s) failed: %s"),
dbname,
- mf_dbm_strerror());
+ mu_strerror(rc));
memset(&key, 0, sizeof key);
- MF_DATUM_PTR(key) = keystr;
- MF_DATUM_SIZE(key) = strlen(keystr);
+ key.mu_dptr = keystr;
+ key.mu_dsize = strlen(keystr);
if (MF_OPTVAL(null, prop && prop->null))
- MF_DATUM_SIZE(key)++;
+ key.mu_dsize++;
memset(&contents, 0, sizeof contents);
- MF_DATUM_PTR(contents) = value;
- MF_DATUM_SIZE(contents) = strlen(value) + 1;
+ contents.mu_dptr = value;
+ contents.mu_dsize = strlen(value) + 1;
- rc = mf_dbm_insert(&db, key, contents, MF_OPTVAL(replace));
- mf_dbm_close(&db);
+ rc = mu_dbm_store(db, &key, &contents, MF_OPTVAL(replace));
+ if (rc && rc != MU_ERR_EXISTS)
+ errstr = mu_dbm_strerror(db);
+ mu_dbm_destroy(&db);
if (rc == MU_ERR_EXISTS)
MF_THROW(mfe_exists, _("record already exists"));
MF_ASSERT(rc == 0,
mfe_dbfailure,
_("failed to insert data to %s: %s %s: %s"),
dbname,
keystr,
value,
- mf_dbm_strerror());
+ errstr);
}
END
MF_DEFUN(dbdel, VOID, STRING dbname, STRING keystr, OPTIONAL, NUMBER null,
NUMBER mode)
{
- MF_DBM_FILE db;
- MF_DBM_DATUM key;
+ mu_dbm_file_t db;
+ struct mu_dbm_datum key;
int rc;
const struct db_prop *prop = db_prop_lookup(dbname);
- if (mf_dbm_open(dbname, &db, MU_STREAM_RDWR,
- MF_OPTVAL(mode, (prop ? prop->mode : DEFAULT_DB_MODE)),
- NULL))
- MF_THROW(mfe_dbfailure,
- _("mf_dbm_open(%s) failed: %s"),
- dbname,
- mf_dbm_strerror());
+ rc = _mf_dbm_open(&db, dbname, MU_STREAM_RDWR,
+ MF_OPTVAL(mode,
+ (prop ? prop->mode : DEFAULT_DB_MODE)));
+ MF_ASSERT(rc == 0,
+ mfe_dbfailure,
+ _("mf_dbm_open(%s) failed: %s"),
+ dbname,
+ mu_strerror(rc));
memset(&key, 0, sizeof key);
- MF_DATUM_PTR(key) = keystr;
- MF_DATUM_SIZE(key) = strlen(keystr);
+ key.mu_dptr = keystr;
+ key.mu_dsize = strlen(keystr);
if (MF_OPTVAL(null, prop && prop->null))
- MF_DATUM_SIZE(key)++;
- rc = mf_dbm_delete(&db, key);
- mf_dbm_close(&db);
+ key.mu_dsize++;
+ rc = mu_dbm_delete(db, &key);
+ if (rc && rc != MU_ERR_FAILURE)
+ mu_error(_("error deleting %s from %s: %s"),
+ keystr, dbname, mu_dbm_strerror(db));
+ mu_dbm_destroy(&db);
MF_ASSERT(rc == 0,
mfe_dbfailure,
_("failed to delete data `%s' from `%s': %s"),
keystr,
dbname,
- mf_dbm_strerror());
+ mu_strerror(rc));
}
END
#define NUMDB 128
struct db_tab {
int used;
- MF_DBM_FILE db;
- MF_DBM_DATUM key;
+ mu_dbm_file_t db;
+ struct mu_dbm_datum key;
};
static void *
alloc_db_tab()
{
return xcalloc(NUMDB, sizeof(struct db_tab));
}
static void
close_db_tab(struct db_tab *dbt)
{
if (dbt->used) {
- mf_dbm_datum_free(&dbt->key);
- mf_dbm_close(&dbt->db);
+ mu_dbm_datum_free(&dbt->key);
+ mu_dbm_destroy(&dbt->db);
dbt->used = 0;
}
}
static void
destroy_db_tab(void *data)
{
int i;
struct db_tab *db = data;
for (i = 0; i < NUMDB; i++)
close_db_tab(db + i);
free(db);
@@ -378,110 +425,124 @@ new_db_tab(struct db_tab *dbt)
return i;
}
return -1;
}
MF_DEFUN(dbfirst, NUMBER, STRING dbname)
{
int rc;
int n;
struct db_tab *dbt = MF_GET_DATA;
- MF_DBM_FILE db;
- MF_DBM_DATUM key;
-
- if (mf_dbm_open(dbname, &db, MU_STREAM_READ, 0, NULL))
- MF_THROW(mfe_dbfailure,
- _("mf_dbm_open(%s) failed: %s"),
- dbname,
- mf_dbm_strerror());
- rc = mf_dbm_firstkey(&db, &key);
- MF_ASSERT(rc == 0, mfe_dbfailure,
- _("mf_dbm_firstkey failed: %s"),
- mf_dbm_strerror());
+ mu_dbm_file_t db;
+ struct mu_dbm_datum key;
+
+ rc = _mf_dbm_open(&db, dbname, MU_STREAM_READ, 0);
+ MF_ASSERT(rc == 0,
+ mfe_dbfailure,
+ _("mf_dbm_open(%s) failed: %s"),
+ dbname,
+ mu_strerror(rc));
+ memset(&key, 0, sizeof key);
+ rc = mu_dbm_firstkey(db, &key);
+ if (rc) {
+ if (rc == MU_ERR_NOENT) {
+ mu_dbm_destroy(&db);
+ MF_RETURN(0);
+ } else if (rc) {
+ mu_dbm_destroy(&db);
+ MF_THROW(mfe_dbfailure,
+ _("mf_dbm_firstkey failed: %s"),
+ mu_strerror(rc));
+ }
+ }
n = new_db_tab(dbt);
MF_ASSERT(n >= 0,
mfe_failure,
_("no more database entries available"));
dbt += n;
dbt->db = db;
dbt->key = key;
MF_RETURN(n);
}
END
MF_DEFUN(dbnext, NUMBER, NUMBER dn)
{
struct db_tab *dbt = MF_GET_DATA + dn;
- MF_DBM_DATUM nextkey;
+ struct mu_dbm_datum nextkey;
int rc;
MF_ASSERT(dn >= 0 && dn < NUMDB && dbt->used,
mfe_range,
_("invalid database descriptor"));
- rc = mf_dbm_nextkey(&dbt->db, dbt->key, &nextkey);
+ rc = mu_dbm_nextkey(dbt->db, &nextkey);
if (rc) {
+ if (rc == MU_ERR_FAILURE)
+ mu_error(_("mu_dbm_nextkey: %s"),
+ mu_dbm_strerror(dbt->db));
close_db_tab(dbt);
MF_RETURN(0);
}
- mf_dbm_datum_free(&dbt->key);
+ mu_dbm_datum_free(&nextkey);
dbt->key = nextkey;
MF_RETURN(1);
}
END
MF_DEFUN(dbkey, STRING, NUMBER dn)
{
size_t off, len;
char *s;
struct db_tab *dbt = MF_GET_DATA + dn;
MF_ASSERT(dn >= 0 && dn < NUMDB && dbt->used,
mfe_range,
_("invalid database descriptor"));
- len = MF_DATUM_SIZE(dbt->key);
+ len = dbt->key.mu_dsize;
s = MF_ALLOC_HEAP(off, len + 1);
- memcpy(s, MF_DATUM_PTR(dbt->key), len);
+ memcpy(s, dbt->key.mu_dptr, len);
s[len] = 0;
MF_RETURN(off);
}
END
MF_DEFUN(dbvalue, STRING, NUMBER dn)
{
int rc;
size_t off, len;
char *s;
struct db_tab *dbt = MF_GET_DATA + dn;
- MF_DBM_DATUM contents;
+ struct mu_dbm_datum contents;
MF_ASSERT(dn >= 0 && dn < NUMDB && dbt->used,
mfe_range,
_("invalid database descriptor"));
memset(&contents, 0, sizeof contents);
- rc = mf_dbm_fetch(&dbt->db, dbt->key, &contents);
+ rc = mu_dbm_fetch(dbt->db, &dbt->key, &contents);
MF_ASSERT(rc == 0,
mfe_dbfailure,
- _("key not found: %s"),
- mf_dbm_strerror());
+ _("cannot fetch key: %s"),
+ rc == MU_ERR_FAILURE ?
+ mu_dbm_strerror(dbt->db) : mu_strerror (rc));
- len = MF_DATUM_SIZE(contents);
+ len = contents.mu_dsize;
s = MF_ALLOC_HEAP(off, len + 1);
- memcpy(s, MF_DATUM_PTR(contents), len);
+ memcpy(s, contents.mu_dptr, len);
s[len] = 0;
- mf_dbm_datum_free(&contents);
+ mu_dbm_datum_free(&contents);
MF_RETURN(off);
}
END
enum greylist_semantics
{
greylist_traditional,
greylist_ct
};
static enum greylist_semantics greylist_semantics = greylist_traditional;
@@ -513,113 +574,122 @@ format_timestr(time_t timestamp, char *timebuf, size_t bufsize)
return timebuf;
}
MF_VAR(greylist_seconds_left, NUMBER);
/* The traditional (aka gray's) greylist implementation: the greylist
database keeps the time the greylisting was activated.
*/
static int
do_greylist_traditional(eval_environ_t env, char *email, long interval)
{
int rc;
- MF_DBM_FILE db;
- MF_DBM_DATUM key;
- MF_DBM_DATUM contents;
- int readonly;
+ mu_dbm_file_t db;
+ struct mu_dbm_datum key;
+ struct mu_dbm_datum contents;
+ int readonly = 0;
time_t now;
- rc = mf_dbm_open(greylist_format->dbname, &db, MU_STREAM_RDWR, 0600,
- &readonly);
+ rc = _mf_dbm_open(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600);
+ if (rc) {
+ rc = _mf_dbm_open(&db, greylist_format->dbname,
+ MU_STREAM_READ, 0);
+ readonly = 1;
+ }
MF_ASSERT(rc == 0, mfe_dbfailure, _("mf_dbm_open(%s) failed: %s"),
- greylist_format->dbname, mf_dbm_strerror());
+ greylist_format->dbname, mu_strerror(rc));
memset(&key, 0, sizeof key);
memset(&contents, 0, sizeof contents);
- MF_DATUM_PTR(key) = email;
- MF_DATUM_SIZE(key) = strlen(email)+1;
+ key.mu_dptr = email;
+ key.mu_dsize = strlen(email)+1;
time(&now);
- if (mf_dbm_fetch(&db, key, &contents) == 0) {
+ rc = mu_dbm_fetch(db, &key, &contents);
+ if (rc == 0) {
time_t timestamp, diff;
- MF_ASSERT(MF_DATUM_SIZE(contents) == sizeof timestamp,
+ MF_ASSERT(contents.mu_dsize == sizeof timestamp,
mfe_dbfailure,
_("greylist database %s has wrong data size"),
- greylist_format->dbname);
+ greylist_format->dbname);
- timestamp = *(time_t*) MF_DATUM_PTR(contents);
+ timestamp = *(time_t*) contents.mu_dptr;
diff = now - timestamp;
if (mu_debug_level_p(debug_handle, MU_DEBUG_TRACE5)) {
char timebuf[32];
mu_debug_log("%s entered greylist database on %s, "
"%ld seconds ago",
email,
format_timestr(timestamp, timebuf,
sizeof timebuf),
(long) diff);
}
-
+
if (diff < interval) {
diff = interval - diff;
-
+
MF_VAR_REF(greylist_seconds_left, diff);
MF_DEBUG(MU_DEBUG_TRACE6,
("%s still greylisted (for %lu sec.)",
email,
(unsigned long) diff));
rc = 1;
} else if (diff > greylist_format->expire_interval) {
MF_DEBUG(MU_DEBUG_TRACE6,
("greylist record for %s expired", email));
MF_VAR_REF(greylist_seconds_left, interval);
if (!readonly) {
- memcpy(MF_DATUM_PTR(contents),
- &now, sizeof now);
- if (mf_dbm_insert(&db, key, contents, 1))
+ memcpy(contents.mu_dptr, &now, sizeof now);
+ rc = mu_dbm_store(db, &key, &contents, 1);
+ if (rc)
mu_error(_("cannot insert datum `%-.*s' in "
"greylist database %s: %s"),
- MF_DATUM_SIZE(key),
- (char*)MF_DATUM_PTR(key),
+ key.mu_dsize,
+ (char*)key.mu_dptr,
greylist_format->dbname,
- mf_dbm_strerror());
+ rc == MU_ERR_FAILURE ?
+ mu_dbm_strerror(db) :
+ mu_strerror(rc));
} else
MF_DEBUG(MU_DEBUG_TRACE6,
("database opened in readonly mode: "
"not updating"));
rc = 1;
} else {
MF_DEBUG(MU_DEBUG_TRACE6,
("%s finished greylisting period", email));
rc = 0;
}
- mf_dbm_datum_free(&contents);
+ mu_dbm_datum_free(&contents);
} else if (!readonly) {
MF_DEBUG(MU_DEBUG_TRACE6, ("greylisting %s", email));
MF_VAR_REF(greylist_seconds_left, interval);
- MF_DATUM_PTR(contents) = (void*)&now;
- MF_DATUM_SIZE(contents) = sizeof now;
- if (mf_dbm_insert(&db, key, contents, 1))
+ contents.mu_dptr = (void*)&now;
+ contents.mu_dsize = sizeof now;
+ rc = mu_dbm_store(db, &key, &contents, 1);
+ if (rc)
mu_error(_("Cannot insert datum `%-.*s' in greylist "
"database %s: %s"),
- MF_DATUM_SIZE(key), (char*)MF_DATUM_PTR(key),
+ key.mu_dsize, (char*)key.mu_dptr,
greylist_format->dbname,
- mf_dbm_strerror());
+ rc == MU_ERR_FAILURE ?
+ mu_dbm_strerror(db) : mu_strerror(rc));
rc = 1;
} else
rc = 0;
- mf_dbm_close(&db);
+ mu_dbm_destroy(&db);
return rc;
}
/* Implementation of the is_greylisted predicate has no sense for
traditional greylist databases, because greylisting interval is
not known beforehand.
FIXME: keep the reference below up to date.
*/
static int
is_greylisted_traditional(eval_environ_t env, char *email)
{
@@ -629,150 +699,164 @@ is_greylisted_traditional(eval_environ_t env, char *email)
"4.12.1.23", "Greylisting functions");
return 0;
}
/* New greylist implementation (by Con Tassios): the database keeps
the time the greylisting period is set to expire (`interval' seconds
from now)
*/
static int
do_greylist_ct(eval_environ_t env, char *email, long interval)
{
int rc;
- MF_DBM_FILE db;
- MF_DBM_DATUM key;
- MF_DBM_DATUM contents;
- int readonly;
+ mu_dbm_file_t db;
+ struct mu_dbm_datum key;
+ struct mu_dbm_datum contents;
+ int readonly = 0;
time_t now;
- rc = mf_dbm_open(greylist_format->dbname, &db, MU_STREAM_RDWR, 0600,
- &readonly);
+ rc = _mf_dbm_open(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600);
+ if (rc) {
+ rc = _mf_dbm_open(&db, greylist_format->dbname,
+ MU_STREAM_READ, 0);
+ readonly = 1;
+ }
MF_ASSERT(rc == 0, mfe_dbfailure, _("mf_dbm_open(%s) failed: %s"),
- greylist_format->dbname, mf_dbm_strerror());
+ greylist_format->dbname, mu_strerror(rc));
memset(&key, 0, sizeof key);
memset(&contents, 0, sizeof contents);
- MF_DATUM_PTR(key) = email;
- MF_DATUM_SIZE(key) = strlen(email)+1;
+ key.mu_dptr = email;
+ key.mu_dsize = strlen(email) + 1;
time(&now);
- if (mf_dbm_fetch(&db, key, &contents) == 0) {
+ rc = mu_dbm_fetch(db, &key, &contents);
+ if (rc == 0) {
time_t timestamp;
- MF_ASSERT(MF_DATUM_SIZE(contents) == sizeof timestamp,
+ MF_ASSERT(contents.mu_dsize == sizeof timestamp,
mfe_dbfailure,
_("greylist database %s has wrong data size"),
greylist_format->dbname);
- timestamp = *(time_t*) MF_DATUM_PTR(contents);
+ timestamp = *(time_t*) contents.mu_dptr;
if (now < timestamp) {
time_t diff = timestamp - now;
MF_VAR_REF(greylist_seconds_left, diff);
MF_DEBUG(MU_DEBUG_TRACE6,
("%s still greylisted (for %lu sec.)",
email,
(unsigned long) diff));
rc = 1;
} else if (now - timestamp >
greylist_format->expire_interval) {
MF_DEBUG(MU_DEBUG_TRACE6,
("greylist record for %s expired", email));
MF_VAR_REF(greylist_seconds_left, interval);
if (!readonly) {
now += interval;
- memcpy(MF_DATUM_PTR(contents),
- &now, sizeof now);
- if (mf_dbm_insert(&db, key, contents, 1))
+ memcpy(contents.mu_dptr, &now, sizeof now);
+ rc = mu_dbm_store(db, &key, &contents, 1);
+ if (rc)
mu_error(_("Cannot insert datum "
"`%-.*s' in greylist "
"database %s: %s"),
- MF_DATUM_SIZE(key),
- (char*)MF_DATUM_PTR(key),
+ key.mu_dsize,
+ (char*)key.mu_dptr,
greylist_format->dbname,
- mf_dbm_strerror());
+ rc == MU_ERR_FAILURE ?
+ mu_dbm_strerror(db) :
+ mu_strerror(rc));
} else
MF_DEBUG(MU_DEBUG_TRACE6,
("database opened in readonly mode: "
"not updating"));
rc = 1;
} else {
MF_DEBUG(MU_DEBUG_TRACE6,
("%s finished greylisting period", email));
rc = 0;
}
- mf_dbm_datum_free(&contents);
+ mu_dbm_datum_free(&contents);
} else if (!readonly) {
MF_DEBUG(MU_DEBUG_TRACE6, ("greylisting %s", email));
MF_VAR_REF(greylist_seconds_left, interval);
now += interval;
- MF_DATUM_PTR(contents) = (void*)&now;
- MF_DATUM_SIZE(contents) = sizeof now;
- if (mf_dbm_insert(&db, key, contents, 1))
+ contents.mu_dptr = (void*)&now;
+ contents.mu_dsize = sizeof now;
+ rc = mu_dbm_store(db, &key, &contents, 1);
+ if (rc)
mu_error(_("Cannot insert datum `%-.*s' in greylist "
"database %s: %s"),
- MF_DATUM_SIZE(key), (char*)MF_DATUM_PTR(key),
+ key.mu_dsize, (char*)key.mu_dptr,
greylist_format->dbname,
- mf_dbm_strerror());
+ rc == MU_ERR_FAILURE ?
+ mu_dbm_strerror(db) : mu_strerror(rc));
rc = 1;
} else
rc = 0;
- mf_dbm_close(&db);
+ mu_dbm_destroy(&db);
return rc;
}
/* The `is_greylisted' predicate for new databases */
static int
is_greylisted_ct(eval_environ_t env, char *email)
{
int rc;
- MF_DBM_FILE db;
- MF_DBM_DATUM key;
- MF_DBM_DATUM contents;
- int readonly;
+ mu_dbm_file_t db;
+ struct mu_dbm_datum key;
+ struct mu_dbm_datum contents;
+ int readonly = 0;
time_t now;
- rc = mf_dbm_open(greylist_format->dbname, &db, MU_STREAM_RDWR, 0600,
- &readonly);
+ rc = _mf_dbm_open(&db, greylist_format->dbname, MU_STREAM_RDWR, 0600);
+ if (rc) {
+ rc = _mf_dbm_open(&db, greylist_format->dbname,
+ MU_STREAM_READ, 0);
+ readonly = 1;
+ }
MF_ASSERT(rc == 0, mfe_dbfailure, _("mf_dbm_open(%s) failed: %s"),
- greylist_format->dbname, mf_dbm_strerror());
+ greylist_format->dbname, mu_strerror(rc));
memset(&key, 0, sizeof key);
memset(&contents, 0, sizeof contents);
- MF_DATUM_PTR(key) = email;
- MF_DATUM_SIZE(key) = strlen(email) + 1;
+ key.mu_dptr = email;
+ key.mu_dsize = strlen(email) + 1;
time(&now);
- if (mf_dbm_fetch(&db, key, &contents) == 0) {
+ rc = mu_dbm_fetch(db, &key, &contents);
+ if (rc == 0) {
time_t timestamp;
- MF_ASSERT(MF_DATUM_SIZE(contents) == sizeof timestamp,
+ MF_ASSERT(contents.mu_dsize == sizeof timestamp,
mfe_dbfailure,
_("greylist database %s has wrong data size"),
greylist_format->dbname);
- timestamp = *(time_t*) MF_DATUM_PTR(contents);
+ timestamp = *(time_t*) contents.mu_dptr;
rc = timestamp > now;
if (rc)
MF_VAR_REF(greylist_seconds_left, timestamp - now);
- mf_dbm_datum_free(&contents);
+ mu_dbm_datum_free(&contents);
} else
rc = 0;
- mf_dbm_close(&db);
+ mu_dbm_destroy(&db);
return rc;
}
struct greylist_class {
int (*gl_fun)(eval_environ_t, char *, long);
int (*gl_pred)(eval_environ_t, char *);
};
struct greylist_class greylist_class[] = {
{ do_greylist_traditional, is_greylisted_traditional },
{ do_greylist_ct, is_greylisted_ct }
diff --git a/src/calloutd.c b/src/calloutd.c
index cd054125..c3753593 100644
--- a/src/calloutd.c
+++ b/src/calloutd.c
@@ -30,25 +30,24 @@
#include <sysexits.h>
#include <mailutils/mailutils.h>
#include <mailutils/libcfg.h>
#include <mailutils/libargp.h>
#include <mailutils/daemon.h>
#include "libmf.h"
#include "callout.h"
#include "srvman.h"
#include "srvcfg.h"
#include "mfdb.h"
-#include "mf-dbm.h"
void
xalloc_die()
{
mu_error(_("not enough memory"));
abort();
}
static void
version(FILE *stream, struct argp_state *state)
{
@@ -116,25 +115,24 @@ main(int argc, char **argv)
mf_init_nls();
mf_proctitle_init(argc, argv, environ);
if (!program_invocation_short_name)
program_invocation_short_name = argv[0];
argp_program_version_hook = version;
/* Set default logging */
mu_log_facility = DEFAULT_LOG_FACILITY;
mu_stdstream_setup(MU_STDSTREAM_RESET_NONE);
mf_srvcfg_log_setup(stderr_closed_p() ? "syslog" : "stderr");
libcallout_init();
- libdbm_init();
db_format_setup();
mf_server_save_cmdline(argc, argv);
dnsbase_init();
database_cfg_init();
mu_acl_cfg_init();
srvman_init();
mf_srvcfg_init(argv[0], NULL);
mu_argp_init(program_version, "<" PACKAGE_BUGREPORT ">");
mu_site_rcfile = SYSCONFDIR "/calloutd.conf";
rc = mu_app_init(&argp, capa, callout_cfg_param, argc, argv,
diff --git a/src/main.c b/src/main.c
index c277aa45..ba0c0f56 100644
--- a/src/main.c
+++ b/src/main.c
@@ -28,32 +28,32 @@
#include <signal.h>
#include <pwd.h>
#include <grp.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <mailutils/mailutils.h>
#include <mailutils/server.h>
#include <mailutils/syslog.h>
#include <mailutils/libargp.h>
+#include <mailutils/dbm.h>
#include "mailfromd.h"
#include "callout.h"
#include "srvman.h"
#include "inttostr.h"
#include "srvcfg.h"
#include "filenames.h"
-#include "mf-dbm.h"
#include "builtin.h"
#include "prog.h"
/* Configurable options */
int mode = MAILFROMD_DAEMON; /* Default operation mode */
enum smtp_state test_state = smtp_state_envfrom; /* State for --test mode */
int need_script = 1; /* Set if the current mode requires reading the
script file */
char *script_file = DEFAULT_SCRIPT_FILE;
int script_check; /* Check config file syntax and exit */
@@ -909,29 +909,28 @@ struct mu_cfg_param mf_cfg_param[] = {
N_("Trace executed actions.") },
{ "trace-program", mu_cfg_callback, NULL, 0, cb_trace_program,
N_("Enable filter program tracing."),
N_("modules: list") },
{ "relayed-domain-file", mu_cfg_callback, NULL, 0,
cb_relayed_domain_file,
N_("Read relayed domain names from the file"),
N_("file: string") },
{ "database", mu_cfg_section, NULL },
- { "lock-retry-count", mu_cfg_size, &lock_retry_count_option, 0, NULL,
- N_("Retry acquiring DBM file lock this number of times.") },
- { "lock-retry-timeout", mu_cfg_callback, &lock_retry_timeout_option, 0,
- config_cb_time_t,
- N_("Set the time span between the two DBM locking attempts."),
+ { "lock-retry-count", mu_cfg_callback, 0, 0, config_cb_ignore,
+ N_("Ignored for backward compatibility.") },
+ { "lock-retry-timeout", mu_cfg_callback, 0,0, config_cb_ignore,
+ N_("Ignored for backward compatibility."),
N_("time") },
{ "max-match-mx", mu_cfg_size, &max_match_mx, 0, NULL,
N_("Maximum number of MXs used by MFL \"mx match\" operation.") },
{ "runtime", mu_cfg_section, NULL },
{ NULL }
};
static struct mu_cfg_param *runtime_param;
@@ -994,49 +993,73 @@ db_format_enumerator(struct db_format *fmt, void *data)
printf("%s database: %s\n", fmt->name, fmt->dbname);
if (strcmp(fmt->name, "cache") == 0) {
printf("%s positive expiration: %lu\n", fmt->name,