-TMIME_STATE
-TMIME_TOKEN
-TMKMAP
+-TMKMAP_DB
+-TMKMAP_DBM
-TMKMAP_OPEN_INFO
-TMULTI_SERVER
-TMVECT
records for finished recipients. Files: *qmgr/qmgr_message.c,
cleanup/cleanup_envelope.c, cleanup/cleanup_extracted.c.
+ Cleanup: further simplified the mkmap wrapper (used by
+ postmap and postalias only) to remove some hurdles for
+ Michael Tokarev's CDB support. Files: global/mkmap*.[hc].
+
Open problems:
Low: revise other local delivery agent duplicate filters.
requires that the recipient UID or GID has write access to the
parent directory of the mailbox file.
- Use the "postconf -m" command to find out what locking methods
+ Use the "postconf -l" command to find out what locking methods
Postfix supports on your system.
virtual_mailbox_limit
* Patches change the patchlevel and the release date. Snapshots change the
* release date only, unless they include the same bugfix as a patch release.
*/
-#define MAIL_RELEASE_DATE "20021101"
+#define MAIL_RELEASE_DATE "20021104"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "1.1.11-" MAIL_RELEASE_DATE
typedef struct MKMAP {
struct DICT *(*open) (const char *, int, int); /* dict_xx_open() */
struct DICT *dict; /* dict_xx_open() result */
- char *lock_file; /* lock file name */
- int lock_fd; /* locked open file, or -1 */
void (*after_open) (struct MKMAP *); /* may be null */
+ void (*after_close) (struct MKMAP *); /* may be null */
} MKMAP;
extern MKMAP *mkmap_open(const char *, const char *, int, int);
extern void mkmap_append(MKMAP *, const char *, const char *);
extern void mkmap_close(MKMAP *);
+#define mkmap_append(map, key, val) dict_put((map)->dict, (key), (val))
+
extern MKMAP *mkmap_dbm_open(const char *);
extern MKMAP *mkmap_hash_open(const char *);
extern MKMAP *mkmap_btree_open(const char *);
#include <db.h>
#endif
+typedef struct MKMAP_DB {
+ MKMAP mkmap; /* parent class */
+ char *lock_file; /* path name */
+ int lock_fd; /* -1 or open locked file */
+} MKMAP_DB;
+
+/* mkmap_db_after_close - clean up after closing database */
+
+static void mkmap_db_after_close(MKMAP *mp)
+{
+ MKMAP_DB *mkmap = (MKMAP_DB *) mp;
+
+ if (mkmap->lock_fd >= 0 && close(mkmap->lock_fd) < 0)
+ msg_warn("close %s: %m", mkmap->lock_file);
+ myfree(mkmap->lock_file);
+}
+
/* mkmap_db_after_open - lock newly created database */
-static void mkmap_db_after_open(MKMAP *mkmap)
+static void mkmap_db_after_open(MKMAP *mp)
{
+ MKMAP_DB *mkmap = (MKMAP_DB *) mp;
+
if (mkmap->lock_fd < 0) {
if ((mkmap->lock_fd = open(mkmap->lock_file, O_RDWR, 0644)) < 0)
msg_fatal("open lockfile %s: %m", mkmap->lock_file);
static MKMAP *mkmap_db_before_open(const char *path,
DICT *(*db_open) (const char *, int, int))
{
- MKMAP *mkmap = (MKMAP *) mymalloc(sizeof(*mkmap));
+ MKMAP_DB *mkmap = (MKMAP_DB *) mymalloc(sizeof(*mkmap));
struct stat st;
/*
* Fill in the generic members.
*/
mkmap->lock_file = concatenate(path, ".db", (char *) 0);
- mkmap->open = db_open;
- mkmap->after_open = mkmap_db_after_open;
+ mkmap->mkmap.open = db_open;
+ mkmap->mkmap.after_open = mkmap_db_after_open;
+ mkmap->mkmap.after_close = mkmap_db_after_close;
/*
* Unfortunately, not all systems that might support db databases do
}
}
- return (mkmap);
+ return (&mkmap->mkmap);
}
/* mkmap_hash_open - create or open hashed DB file */
#include <ndbm.h>
#endif
+typedef struct MKMAP_DBM {
+ MKMAP mkmap; /* parent class */
+ char *lock_file; /* path name */
+ int lock_fd; /* -1 or open locked file */
+} MKMAP_DBM;
+
+/* mkmap_dbm_after_close - clean up after closing database */
+
+static void mkmap_dbm_after_close(MKMAP *mp)
+{
+ MKMAP_DBM *mkmap = (MKMAP_DBM *) mp;
+
+ if (mkmap->lock_fd >= 0 && close(mkmap->lock_fd) < 0)
+ msg_warn("close %s: %m", mkmap->lock_file);
+ myfree(mkmap->lock_file);
+}
+
/* mkmap_dbm_open - create or open database */
MKMAP *mkmap_dbm_open(const char *path)
{
- MKMAP *mkmap = (MKMAP *) mymalloc(sizeof(*mkmap));
+ MKMAP_DBM *mkmap = (MKMAP_DBM *) mymalloc(sizeof(*mkmap));
char *pag_file;
int pag_fd;
* Fill in the generic members.
*/
mkmap->lock_file = concatenate(path, ".dir", (char *) 0);
- mkmap->open = dict_dbm_open;
- mkmap->after_open = 0;
+ mkmap->mkmap.open = dict_dbm_open;
+ mkmap->mkmap.after_open = 0;
+ mkmap->mkmap.after_close = mkmap_dbm_after_close;
/*
* Unfortunately, not all systems support locking on open(), so we open
* have any spectators.
*/
if (myflock(mkmap->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
- msg_fatal("lock %s: %m", mkmap->lock_file);
+ msg_fatal("lock %s: %m", mkmap->lock_file);
- return (mkmap);
+ return (&mkmap->mkmap);
}
#endif
/* MKMAP *mkmap;
/* DESCRIPTION
/* This module implements support for creating Postfix databases.
+/* It is a dict(3) wrapper that adds global locking to dict-level
+/* routines where appropriate.
/*
/* mkmap_open() creates or truncates the named database, after
/* appending the appropriate suffixes to the specified filename.
/* mkmap_append - append entry to map */
+#undef mkmap_append
+
void mkmap_append(MKMAP *mkmap, const char *key, const char *value)
{
dict_put(mkmap->dict, key, value);
{
/*
- * Close the database and the locking file descriptor.
+ * Close the database.
*/
dict_close(mkmap->dict);
- if (close(mkmap->lock_fd) < 0)
- msg_warn("close %s: %m", mkmap->lock_file);
+
+ /*
+ * Do whatever special processing is needed after closing the database,
+ * such as releasing a global exclusive lock on the database file.
+ * Individual Postfix dict modules implement locking only for individual
+ * record operations, because most Postfix applications don't need global
+ * exclusive locks.
+ */
+ if (mkmap->after_close)
+ mkmap->after_close(mkmap);
/*
* Resume signal delivery.
/*
* Cleanup.
*/
- myfree(mkmap->lock_file);
myfree((char *) mkmap);
}
msg_info("open %s %s", type, path);
/*
- * Do whatever before-open initialization is needed.
+ * Do whatever before-open initialization is needed, such as acquiring a
+ * global exclusive lock on an existing database file. Individual Postfix
+ * dict modules implement locking only for individual record operations,
+ * because most Postfix applications don't need global exclusive locks.
*/
mkmap = mp->before_open(path);
mkmap->dict->flags |= DICT_FLAG_DUP_WARN;
/*
- * Do whatever post-open initialization is needed.
+ * Do whatever post-open initialization is needed, such as acquiring a
+ * global exclusive lock on a database file that did not exist.
+ * Individual Postfix dict modules implement locking only for individual
+ * record operations, because most Postfix applications don't need global
+ * exclusive locks.
*/
if (mkmap->after_open)
mkmap->after_open(mkmap);