1 /* $NetBSD: mkmap_sdbm.c,v 1.1.1.1 2009/06/23 10:08:47 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* mkmap_sdbm 3 6 /* SUMMARY 7 /* create or open database, SDBM style 8 /* SYNOPSIS 9 /* #include <mkmap.h> 10 /* 11 /* MKMAP *mkmap_sdbm_open(path) 12 /* const char *path; 13 /* DESCRIPTION 14 /* This module implements support for creating SDBM databases. 15 /* 16 /* mkmap_sdbm_open() takes a file name, appends the ".dir" and ".pag" 17 /* suffixes, and creates or opens the named SDBM database. 18 /* This routine is a SDBM-specific helper for the more general 19 /* mkmap_open() routine. 20 /* 21 /* All errors are fatal. 22 /* SEE ALSO 23 /* dict_sdbm(3), SDBM dictionary interface. 24 /* LICENSE 25 /* .ad 26 /* .fi 27 /* The Secure Mailer license must be distributed with this software. 28 /* AUTHOR(S) 29 /* Wietse Venema 30 /* IBM T.J. Watson Research 31 /* P.O. Box 704 32 /* Yorktown Heights, NY 10598, USA 33 /*--*/ 34 35 /* System library. */ 36 37 #include <sys_defs.h> 38 #include <unistd.h> 39 40 /* Utility library. */ 41 42 #include <msg.h> 43 #include <mymalloc.h> 44 #include <stringops.h> 45 #include <dict.h> 46 #include <dict_sdbm.h> 47 #include <myflock.h> 48 49 /* Application-specific. */ 50 51 #include "mkmap.h" 52 53 #ifdef HAS_SDBM 54 55 #include <sdbm.h> 56 57 typedef struct MKMAP_SDBM { 58 MKMAP mkmap; /* parent class */ 59 char *lock_file; /* path name */ 60 int lock_fd; /* -1 or open locked file */ 61 } MKMAP_SDBM; 62 63 /* mkmap_sdbm_after_close - clean up after closing database */ 64 65 static void mkmap_sdbm_after_close(MKMAP *mp) 66 { 67 MKMAP_SDBM *mkmap = (MKMAP_SDBM *) mp; 68 69 if (mkmap->lock_fd >= 0 && close(mkmap->lock_fd) < 0) 70 msg_warn("close %s: %m", mkmap->lock_file); 71 myfree(mkmap->lock_file); 72 } 73 74 /* mkmap_sdbm_open - create or open database */ 75 76 MKMAP *mkmap_sdbm_open(const char *path) 77 { 78 MKMAP_SDBM *mkmap = (MKMAP_SDBM *) mymalloc(sizeof(*mkmap)); 79 char *pag_file; 80 int pag_fd; 81 82 /* 83 * Fill in the generic members. 84 */ 85 mkmap->lock_file = concatenate(path, ".dir", (char *) 0); 86 mkmap->mkmap.open = dict_sdbm_open; 87 mkmap->mkmap.after_open = 0; 88 mkmap->mkmap.after_close = mkmap_sdbm_after_close; 89 90 /* 91 * Unfortunately, not all systems support locking on open(), so we open 92 * the .dir and .pag files before truncating them. Keep one file open for 93 * locking. 94 */ 95 if ((mkmap->lock_fd = open(mkmap->lock_file, O_CREAT | O_RDWR, 0644)) < 0) 96 msg_fatal("open %s: %m", mkmap->lock_file); 97 98 pag_file = concatenate(path, ".pag", (char *) 0); 99 if ((pag_fd = open(pag_file, O_CREAT | O_RDWR, 0644)) < 0) 100 msg_fatal("open %s: %m", pag_file); 101 if (close(pag_fd)) 102 msg_warn("close %s: %m", pag_file); 103 myfree(pag_file); 104 105 /* 106 * Get an exclusive lock - we're going to change the database so we can't 107 * have any spectators. 108 */ 109 if (myflock(mkmap->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0) 110 msg_fatal("lock %s: %m", mkmap->lock_file); 111 112 return (&mkmap->mkmap); 113 } 114 115 #endif 116