7 /* create or open database, SDBM style
11 /* MKMAP *mkmap_sdbm_open(path)
14 /* This module implements support for creating SDBM databases.
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.
21 /* All errors are fatal.
23 /* dict_sdbm(3), SDBM dictionary interface.
27 /* The Secure Mailer license must be distributed with this software.
30 /* IBM T.J. Watson Research
32 /* Yorktown Heights, NY 10598, USA
40 /* Utility library. */
44 #include <stringops.h>
46 #include <dict_sdbm.h>
49 /* Application-specific. */
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 */
63 /* mkmap_sdbm_after_close - clean up after closing database */
65 static void mkmap_sdbm_after_close(MKMAP
*mp
)
67 MKMAP_SDBM
*mkmap
= (MKMAP_SDBM
*) mp
;
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
);
74 /* mkmap_sdbm_open - create or open database */
76 MKMAP
*mkmap_sdbm_open(const char *path
)
78 MKMAP_SDBM
*mkmap
= (MKMAP_SDBM
*) mymalloc(sizeof(*mkmap
));
83 * Fill in the generic members.
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
;
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
95 if ((mkmap
->lock_fd
= open(mkmap
->lock_file
, O_CREAT
| O_RDWR
, 0644)) < 0)
96 msg_fatal("open %s: %m", mkmap
->lock_file
);
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
);
102 msg_warn("close %s: %m", pag_file
);
106 * Get an exclusive lock - we're going to change the database so we can't
107 * have any spectators.
109 if (myflock(mkmap
->lock_fd
, INTERNAL_LOCK
, MYFLOCK_OP_EXCLUSIVE
) < 0)
110 msg_fatal("lock %s: %m", mkmap
->lock_file
);
112 return (&mkmap
->mkmap
);