Postfix3.3.1
mkmap_sdbm.c
[詳解]
1 /*++
2 /* NAME
3 /* mkmap_sdbm 3
4 /* SUMMARY
5 /* create or open database, SDBM style
6 /* SYNOPSIS
7 /* #include <mkmap.h>
8 /*
9 /* MKMAP *mkmap_sdbm_open(path)
10 /* const char *path;
11 /* DESCRIPTION
12 /* This module implements support for creating SDBM databases.
13 /*
14 /* mkmap_sdbm_open() takes a file name, appends the ".dir" and ".pag"
15 /* suffixes, and creates or opens the named SDBM database.
16 /* This routine is a SDBM-specific helper for the more general
17 /* mkmap_open() routine.
18 /*
19 /* All errors are fatal.
20 /* SEE ALSO
21 /* dict_sdbm(3), SDBM 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_sdbm.h>
45 #include <myflock.h>
46 
47 /* Application-specific. */
48 
49 #include "mkmap.h"
50 
51 #ifdef HAS_SDBM
52 
53 #include <sdbm.h>
54 
55 typedef struct MKMAP_SDBM {
56  MKMAP mkmap; /* parent class */
57  char *lock_file; /* path name */
58  int lock_fd; /* -1 or open locked file */
59 } MKMAP_SDBM;
60 
61 /* mkmap_sdbm_after_close - clean up after closing database */
62 
63 static void mkmap_sdbm_after_close(MKMAP *mp)
64 {
65  MKMAP_SDBM *mkmap = (MKMAP_SDBM *) mp;
66 
67  if (mkmap->lock_fd >= 0 && close(mkmap->lock_fd) < 0)
68  msg_warn("close %s: %m", mkmap->lock_file);
69  myfree(mkmap->lock_file);
70 }
71 
72 /* mkmap_sdbm_open - create or open database */
73 
74 MKMAP *mkmap_sdbm_open(const char *path)
75 {
76  MKMAP_SDBM *mkmap = (MKMAP_SDBM *) mymalloc(sizeof(*mkmap));
77  char *pag_file;
78  int pag_fd;
79 
80  /*
81  * Fill in the generic members.
82  */
83  mkmap->lock_file = concatenate(path, ".dir", (char *) 0);
84  mkmap->mkmap.open = dict_sdbm_open;
85  mkmap->mkmap.after_open = 0;
86  mkmap->mkmap.after_close = mkmap_sdbm_after_close;
87 
88  /*
89  * Unfortunately, not all systems support locking on open(), so we open
90  * the .dir and .pag files before truncating them. Keep one file open for
91  * locking.
92  */
93  if ((mkmap->lock_fd = open(mkmap->lock_file, O_CREAT | O_RDWR, 0644)) < 0)
94  msg_fatal("open %s: %m", mkmap->lock_file);
95 
96  pag_file = concatenate(path, ".pag", (char *) 0);
97  if ((pag_fd = open(pag_file, O_CREAT | O_RDWR, 0644)) < 0)
98  msg_fatal("open %s: %m", pag_file);
99  if (close(pag_fd))
100  msg_warn("close %s: %m", pag_file);
101  myfree(pag_file);
102 
103  /*
104  * Get an exclusive lock - we're going to change the database so we can't
105  * have any spectators.
106  */
107  if (myflock(mkmap->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
108  msg_fatal("lock %s: %m", mkmap->lock_file);
109 
110  return (&mkmap->mkmap);
111 }
112 
113 #endif
void myfree(void *ptr)
Definition: mymalloc.c:207
MKMAP * mkmap_sdbm_open(const char *)
#define MYFLOCK_OP_EXCLUSIVE
Definition: myflock.h:30
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_sdbm_open(const char *, int, int)
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150