/*++ /* 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