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