From b7c15c31519dc44c1f691e0466badd556ffe9423 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 18:18:56 +0200 Subject: Adding upstream version 3.7.10. Signed-off-by: Daniel Baumann --- src/global/mkmap_sdbm.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/global/mkmap_sdbm.c (limited to 'src/global/mkmap_sdbm.c') diff --git a/src/global/mkmap_sdbm.c b/src/global/mkmap_sdbm.c new file mode 100644 index 0000000..7e87e4e --- /dev/null +++ b/src/global/mkmap_sdbm.c @@ -0,0 +1,113 @@ +/*++ +/* NAME +/* mkmap_sdbm 3 +/* SUMMARY +/* create or open database, SDBM style +/* SYNOPSIS +/* #include +/* +/* MKMAP *mkmap_sdbm_open(path) +/* const char *path; +/* DESCRIPTION +/* This module implements support for creating SDBM databases. +/* +/* mkmap_sdbm_open() takes a file name, appends the ".dir" and ".pag" +/* suffixes, and creates or opens the named SDBM database. +/* This routine is a SDBM-specific helper for the more general +/* mkmap_open() routine. +/* +/* All errors are fatal. +/* SEE ALSO +/* dict_sdbm(3), SDBM dictionary interface. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include +#include + +/* Utility library. */ + +#include +#include +#include +#include +#include +#include + +/* Application-specific. */ + +#include "mkmap.h" + +#ifdef HAS_SDBM + +#include + +typedef struct MKMAP_SDBM { + MKMAP mkmap; /* parent class */ + char *lock_file; /* path name */ + int lock_fd; /* -1 or open locked file */ +} MKMAP_SDBM; + +/* mkmap_sdbm_after_close - clean up after closing database */ + +static void mkmap_sdbm_after_close(MKMAP *mp) +{ + MKMAP_SDBM *mkmap = (MKMAP_SDBM *) mp; + + if (mkmap->lock_fd >= 0 && close(mkmap->lock_fd) < 0) + msg_warn("close %s: %m", mkmap->lock_file); + myfree(mkmap->lock_file); +} + +/* mkmap_sdbm_open - create or open database */ + +MKMAP *mkmap_sdbm_open(const char *path) +{ + MKMAP_SDBM *mkmap = (MKMAP_SDBM *) mymalloc(sizeof(*mkmap)); + char *pag_file; + int pag_fd; + + /* + * Fill in the generic members. + */ + mkmap->lock_file = concatenate(path, ".dir", (char *) 0); + mkmap->mkmap.open = dict_sdbm_open; + mkmap->mkmap.after_open = 0; + mkmap->mkmap.after_close = mkmap_sdbm_after_close; + + /* + * Unfortunately, not all systems support locking on open(), so we open + * the .dir and .pag files before truncating them. Keep one file open for + * locking. + */ + if ((mkmap->lock_fd = open(mkmap->lock_file, O_CREAT | O_RDWR, 0644)) < 0) + msg_fatal("open %s: %m", mkmap->lock_file); + + pag_file = concatenate(path, ".pag", (char *) 0); + if ((pag_fd = open(pag_file, O_CREAT | O_RDWR, 0644)) < 0) + msg_fatal("open %s: %m", pag_file); + if (close(pag_fd)) + msg_warn("close %s: %m", pag_file); + myfree(pag_file); + + /* + * Get an exclusive lock - we're going to change the database so we can't + * have any spectators. + */ + if (myflock(mkmap->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0) + msg_fatal("lock %s: %m", mkmap->lock_file); + + return (&mkmap->mkmap); +} + +#endif -- cgit v1.2.3