Postfix3.3.1
dict_open.c
[詳解]
1 /*++
2 /* NAME
3 /* dict_open 3
4 /* SUMMARY
5 /* low-level dictionary interface
6 /* SYNOPSIS
7 /* #include <dict.h>
8 /*
9 /* DICT *dict_open(dict_spec, open_flags, dict_flags)
10 /* const char *dict_spec;
11 /* int open_flags;
12 /* int dict_flags;
13 /*
14 /* DICT *dict_open3(dict_type, dict_name, open_flags, dict_flags)
15 /* const char *dict_type;
16 /* const char *dict_name;
17 /* int open_flags;
18 /* int dict_flags;
19 /*
20 /* int dict_put(dict, key, value)
21 /* DICT *dict;
22 /* const char *key;
23 /* const char *value;
24 /*
25 /* const char *dict_get(dict, key)
26 /* DICT *dict;
27 /* const char *key;
28 /*
29 /* int dict_del(dict, key)
30 /* DICT *dict;
31 /* const char *key;
32 /*
33 /* int dict_seq(dict, func, key, value)
34 /* DICT *dict;
35 /* int func;
36 /* const char **key;
37 /* const char **value;
38 /*
39 /* void dict_close(dict)
40 /* DICT *dict;
41 /*
42 /* typedef DICT *(*DICT_OPEN_FN) (const char *, int, int);
43 /*
44 /* dict_open_register(type, open)
45 /* const char *type;
46 /* DICT_OPEN_FN open;
47 /*
48 /* typedef DICT_OPEN_FN (*DICT_OPEN_EXTEND_FN)(const char *type);
49 /*
50 /* DICT_OPEN_EXTEND_FN dict_open_extend(call_back)
51 /* DICT_OPEN_EXTEND_FN call_back;
52 /*
53 /* ARGV *dict_mapnames()
54 /*
55 /* typedef ARGV *(*DICT_MAPNAMES_EXTEND_FN)(ARGV *names);
56 /*
57 /* DICT_MAPNAMES_EXTEND_FN dict_mapnames_extend(call_back)
58 /* DICT_MAPNAMES_EXTEND_FN call_back;
59 /*
60 /* int dict_isjmp(dict)
61 /* DICT *dict;
62 /*
63 /* int dict_setjmp(dict)
64 /* DICT *dict;
65 /*
66 /* int dict_longjmp(dict, val)
67 /* DICT *dict;
68 /* int val;
69 /*
70 /* void dict_type_override(dict, type)
71 /* DICT *dict;
72 /* const char *type;
73 /* DESCRIPTION
74 /* This module implements a low-level interface to multiple
75 /* physical dictionary types.
76 /*
77 /* dict_open() takes a type:name pair that specifies a dictionary type
78 /* and dictionary name, opens the dictionary, and returns a dictionary
79 /* handle. The \fIopen_flags\fR arguments are as in open(2). The
80 /* \fIdict_flags\fR are the bit-wise OR of zero or more of the following:
81 /* .IP DICT_FLAG_DUP_WARN
82 /* Warn about duplicate keys, if the underlying database does not
83 /* support duplicate keys. The default is to terminate with a fatal
84 /* error.
85 /* .IP DICT_FLAG_DUP_IGNORE
86 /* Ignore duplicate keys if the underlying database does not
87 /* support duplicate keys. The default is to terminate with a fatal
88 /* error.
89 /* .IP DICT_FLAG_DUP_REPLACE
90 /* Replace duplicate keys if the underlying database supports such
91 /* an operation. The default is to terminate with a fatal error.
92 /* .IP DICT_FLAG_TRY0NULL
93 /* With maps where this is appropriate, append no null byte to
94 /* keys and values.
95 /* When neither DICT_FLAG_TRY0NULL nor DICT_FLAG_TRY1NULL are
96 /* specified, the software guesses what format to use for reading;
97 /* and in the absence of definite information, a system-dependent
98 /* default is chosen for writing.
99 /* .IP DICT_FLAG_TRY1NULL
100 /* With maps where this is appropriate, append one null byte to
101 /* keys and values.
102 /* When neither DICT_FLAG_TRY0NULL nor DICT_FLAG_TRY1NULL are
103 /* specified, the software guesses what format to use for reading;
104 /* and in the absence of definite information, a system-dependent
105 /* default is chosen for writing.
106 /* .IP DICT_FLAG_LOCK
107 /* With maps where this is appropriate, acquire an exclusive lock
108 /* before writing, and acquire a shared lock before reading.
109 /* Release the lock when the operation completes.
110 /* .IP DICT_FLAG_OPEN_LOCK
111 /* The behavior of this flag depends on whether a database
112 /* sets the DICT_FLAG_MULTI_WRITER flag to indicate that it
113 /* is multi-writer safe.
114 /*
115 /* With databases that are not multi-writer safe, dict_open()
116 /* acquires a persistent exclusive lock, or it terminates with
117 /* a fatal run-time error.
118 /*
119 /* With databases that are multi-writer safe, dict_open()
120 /* downgrades the DICT_FLAG_OPEN_LOCK flag (persistent lock)
121 /* to DICT_FLAG_LOCK (temporary lock).
122 /* .IP DICT_FLAG_FOLD_FIX
123 /* With databases whose lookup fields are fixed-case strings,
124 /* fold the search string to lower case before accessing the
125 /* database. This includes hash:, cdb:, dbm:. nis:, ldap:,
126 /* *sql. WARNING: case folding is supported only for ASCII or
127 /* valid UTF-8.
128 /* .IP DICT_FLAG_FOLD_MUL
129 /* With databases where one lookup field can match both upper
130 /* and lower case, fold the search key to lower case before
131 /* accessing the database. This includes regexp: and pcre:.
132 /* WARNING: case folding is supported only for ASCII or valid
133 /* UTF-8.
134 /* .IP DICT_FLAG_FOLD_ANY
135 /* Short-hand for (DICT_FLAG_FOLD_FIX | DICT_FLAG_FOLD_MUL).
136 /* .IP DICT_FLAG_SYNC_UPDATE
137 /* With file-based maps, flush I/O buffers to file after each update.
138 /* Thus feature is not supported with some file-based dictionaries.
139 /* .IP DICT_FLAG_NO_REGSUB
140 /* Disallow regular expression substitution from the lookup string
141 /* into the lookup result, to block data injection attacks.
142 /* .IP DICT_FLAG_NO_PROXY
143 /* Disallow access through the unprivileged \fBproxymap\fR
144 /* service, to block privilege escalation attacks.
145 /* .IP DICT_FLAG_NO_UNAUTH
146 /* Disallow lookup mechanisms that lack any form of authentication,
147 /* to block privilege escalation attacks (example: tcp_table;
148 /* even NIS can be secured to some extent by requiring that
149 /* the server binds to a privileged port).
150 /* .IP DICT_FLAG_PARANOID
151 /* A combination of all the paranoia flags: DICT_FLAG_NO_REGSUB,
152 /* DICT_FLAG_NO_PROXY and DICT_FLAG_NO_UNAUTH.
153 /* .IP DICT_FLAG_BULK_UPDATE
154 /* Enable preliminary code for bulk-mode database updates.
155 /* The caller must create an exception handler with dict_jmp_alloc()
156 /* and must trap exceptions from the database client with dict_setjmp().
157 /* .IP DICT_FLAG_DEBUG
158 /* Enable additional logging.
159 /* .IP DICT_FLAG_UTF8_REQUEST
160 /* With util_utf8_enable != 0, require that lookup/update/delete
161 /* keys and values are valid UTF-8. Skip a lookup/update/delete
162 /* request with a non-UTF-8 key, skip an update request with
163 /* a non-UTF-8 value, and fail a lookup request with a non-UTF-8
164 /* value.
165 /* .PP
166 /* Specify DICT_FLAG_NONE for no special processing.
167 /*
168 /* The dictionary types are as follows:
169 /* .IP environ
170 /* The process environment array. The \fIdict_name\fR argument is ignored.
171 /* .IP dbm
172 /* DBM file.
173 /* .IP hash
174 /* Berkeley DB file in hash format.
175 /* .IP btree
176 /* Berkeley DB file in btree format.
177 /* .IP nis
178 /* NIS map. Only read access is supported.
179 /* .IP nisplus
180 /* NIS+ map. Only read access is supported.
181 /* .IP netinfo
182 /* NetInfo table. Only read access is supported.
183 /* .IP ldap
184 /* LDAP ("light-weight" directory access protocol) database access.
185 /* .IP pcre
186 /* PERL-compatible regular expressions.
187 /* .IP regexp
188 /* POSIX-compatible regular expressions.
189 /* .IP texthash
190 /* Flat text in postmap(1) input format.
191 /* .PP
192 /* dict_open3() takes separate arguments for dictionary type and
193 /* name, but otherwise performs the same functions as dict_open().
194 /*
195 /* The dict_get(), dict_put(), dict_del(), and dict_seq()
196 /* macros evaluate their first argument multiple times.
197 /* These names should have been in uppercase.
198 /*
199 /* dict_get() retrieves the value stored in the named dictionary
200 /* under the given key. A null pointer means the value was not found.
201 /* As with dict_lookup(), the result is owned by the lookup table
202 /* implementation. Make a copy if the result is to be modified,
203 /* or if the result is to survive multiple table lookups.
204 /*
205 /* dict_put() stores the specified key and value into the named
206 /* dictionary. A zero (DICT_STAT_SUCCESS) result means the
207 /* update was made.
208 /*
209 /* dict_del() removes a dictionary entry, and returns
210 /* DICT_STAT_SUCCESS in case of success.
211 /*
212 /* dict_seq() iterates over all members in the named dictionary.
213 /* func is define DICT_SEQ_FUN_FIRST (select first member) or
214 /* DICT_SEQ_FUN_NEXT (select next member). A zero (DICT_STAT_SUCCESS)
215 /* result means that an entry was found.
216 /*
217 /* dict_close() closes the specified dictionary and cleans up the
218 /* associated data structures.
219 /*
220 /* dict_open_register() adds support for a new dictionary type.
221 /*
222 /* dict_open_extend() registers a call-back function that looks
223 /* up the dictionary open() function for a type that is not
224 /* registered, or null in case of error. The result value is
225 /* the last previously-registered call-back or null.
226 /*
227 /* dict_mapnames() returns a sorted list with the names of all available
228 /* dictionary types.
229 /*
230 /* dict_mapnames_extend() registers a call-back function that
231 /* enumerates additional dictionary type names. The result
232 /* will be sorted by dict_mapnames(). The result value
233 /* is the last previously-registered call-back or null.
234 /*
235 /* dict_setjmp() saves processing context and makes that context
236 /* available for use with dict_longjmp(). Normally, dict_setjmp()
237 /* returns zero. A non-zero result means that dict_setjmp()
238 /* returned through a dict_longjmp() call; the result is the
239 /* \fIval\fR argument given to dict_longjmp(). dict_isjmp()
240 /* returns non-zero when dict_setjmp() and dict_longjmp()
241 /* are enabled for a given dictionary.
242 /*
243 /* NB: non-local jumps such as dict_longjmp() are not safe for
244 /* jumping out of any routine that manipulates DICT data.
245 /* longjmp() like calls are best avoided in signal handlers.
246 /*
247 /* dict_type_override() changes the symbolic dictionary type.
248 /* This is used by dictionaries whose internals are based on
249 /* some other dictionary type.
250 /* DIAGNOSTICS
251 /* Fatal error: open error, unsupported dictionary type, attempt to
252 /* update non-writable dictionary.
253 /*
254 /* The lookup routine returns non-null when the request is
255 /* satisfied. The update, delete and sequence routines return
256 /* zero (DICT_STAT_SUCCESS) when the request is satisfied.
257 /* The dict->errno value is non-zero only when the last operation
258 /* was not satisfied due to a dictionary access error. This
259 /* can have the following values:
260 /* .IP DICT_ERR_NONE(zero)
261 /* There was no dictionary access error. For example, the
262 /* request was satisfied, the requested information did not
263 /* exist in the dictionary, or the information already existed
264 /* when it should not exist (collision).
265 /* .IP DICT_ERR_RETRY(<0)
266 /* The dictionary was temporarily unavailable. This can happen
267 /* with network-based services.
268 /* .IP DICT_ERR_CONFIG(<0)
269 /* The dictionary was unavailable due to a configuration error.
270 /* .PP
271 /* Generally, a program is expected to test the function result
272 /* value for "success" first. If the operation was not successful,
273 /* a program is expected to test for a non-zero dict->error
274 /* status to distinguish between a data notfound/collision
275 /* condition or a dictionary access error.
276 /* LICENSE
277 /* .ad
278 /* .fi
279 /* The Secure Mailer license must be distributed with this software.
280 /* AUTHOR(S)
281 /* Wietse Venema
282 /* IBM T.J. Watson Research
283 /* P.O. Box 704
284 /* Yorktown Heights, NY 10598, USA
285 /*
286 /* Wietse Venema
287 /* Google, Inc.
288 /* 111 8th Avenue
289 /* New York, NY 10011, USA
290 /*--*/
291 
292 /* System library. */
293 
294 #include <sys_defs.h>
295 #include <string.h>
296 #include <stdlib.h>
297 
298 /* Utility library. */
299 
300 #include <argv.h>
301 #include <mymalloc.h>
302 #include <msg.h>
303 #include <dict.h>
304 #include <dict_cdb.h>
305 #include <dict_env.h>
306 #include <dict_unix.h>
307 #include <dict_tcp.h>
308 #include <dict_sdbm.h>
309 #include <dict_dbm.h>
310 #include <dict_db.h>
311 #include <dict_lmdb.h>
312 #include <dict_nis.h>
313 #include <dict_nisplus.h>
314 #include <dict_ni.h>
315 #include <dict_pcre.h>
316 #include <dict_regexp.h>
317 #include <dict_static.h>
318 #include <dict_cidr.h>
319 #include <dict_ht.h>
320 #include <dict_thash.h>
321 #include <dict_sockmap.h>
322 #include <dict_fail.h>
323 #include <dict_pipe.h>
324 #include <dict_random.h>
325 #include <dict_union.h>
326 #include <dict_inline.h>
327 #include <stringops.h>
328 #include <split_at.h>
329 #include <htable.h>
330 #include <myflock.h>
331 
332  /*
333  * lookup table for available map types.
334  */
335 typedef struct {
336  char *type;
339 
340 static const DICT_OPEN_INFO dict_open_info[] = {
345 #ifdef HAS_DBM
347 #endif
348 #ifdef HAS_DB
351 #endif
352 #ifdef HAS_NIS
354 #endif
355 #ifdef HAS_NISPLUS
357 #endif
358 #ifdef HAS_NETINFO
360 #endif
361 #ifdef HAS_POSIX_REGEXP
363 #endif
373 #ifndef USE_DYNAMIC_MAPS
374 #ifdef HAS_PCRE
376 #endif
377 #ifdef HAS_CDB
379 #endif
380 #ifdef HAS_SDBM
382 #endif
383 #ifdef HAS_LMDB
385 #endif
386 #endif /* !USE_DYNAMIC_MAPS */
387  0,
388 };
389 
390 static HTABLE *dict_open_hash;
391 
392  /*
393  * Extension hooks.
394  */
395 static DICT_OPEN_EXTEND_FN dict_open_extend_hook;
396 static DICT_MAPNAMES_EXTEND_FN dict_mapnames_extend_hook;
397 
398  /*
399  * Workaround.
400  */
403 
404 /* dict_open_init - one-off initialization */
405 
406 static void dict_open_init(void)
407 {
408  const char *myname = "dict_open_init";
409  const DICT_OPEN_INFO *dp;
410 
411  if (dict_open_hash != 0)
412  msg_panic("%s: multiple initialization", myname);
413  dict_open_hash = htable_create(10);
414 
415  for (dp = dict_open_info; dp->type; dp++)
416  htable_enter(dict_open_hash, dp->type, (void *) dp);
417 }
418 
419 /* dict_open - open dictionary */
420 
421 DICT *dict_open(const char *dict_spec, int open_flags, int dict_flags)
422 {
423  char *saved_dict_spec = mystrdup(dict_spec);
424  char *dict_name;
425  DICT *dict;
426 
427  if ((dict_name = split_at(saved_dict_spec, ':')) == 0)
428  msg_fatal("open dictionary: expecting \"type:name\" form instead of \"%s\"",
429  dict_spec);
430 
431  dict = dict_open3(saved_dict_spec, dict_name, open_flags, dict_flags);
432  myfree(saved_dict_spec);
433  return (dict);
434 }
435 
436 
437 /* dict_open3 - open dictionary */
438 
439 DICT *dict_open3(const char *dict_type, const char *dict_name,
440  int open_flags, int dict_flags)
441 {
442  const char *myname = "dict_open";
443  DICT_OPEN_INFO *dp;
444  DICT_OPEN_FN open_fn;
445  DICT *dict;
446 
447  if (*dict_type == 0 || *dict_name == 0)
448  msg_fatal("open dictionary: expecting \"type:name\" form instead of \"%s:%s\"",
449  dict_type, dict_name);
450  if (dict_open_hash == 0)
451  dict_open_init();
452  if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0) {
453  if (dict_open_extend_hook != 0
454  && (open_fn = dict_open_extend_hook(dict_type)) != 0) {
455  dict_open_register(dict_type, open_fn);
456  dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type);
457  }
458  if (dp == 0)
459  return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags,
460  "unsupported dictionary type: %s", dict_type));
461  }
462  if ((dict = dp->open(dict_name, open_flags, dict_flags)) == 0)
463  return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags,
464  "cannot open %s:%s: %m", dict_type, dict_name));
465  if (msg_verbose)
466  msg_info("%s: %s:%s", myname, dict_type, dict_name);
467  /* XXX The choice between wait-for-lock or no-wait is hard-coded. */
468  if (dict->flags & DICT_FLAG_OPEN_LOCK) {
469  if (dict->flags & DICT_FLAG_LOCK)
470  msg_panic("%s: attempt to open %s:%s with both \"open\" lock and \"access\" lock",
471  myname, dict_type, dict_name);
472  /* Multi-writer safe map: downgrade persistent lock to temporary. */
473  if (dict->flags & DICT_FLAG_MULTI_WRITER) {
474  dict->flags &= ~DICT_FLAG_OPEN_LOCK;
475  dict->flags |= DICT_FLAG_LOCK;
476  }
477  /* Multi-writer unsafe map: acquire exclusive lock or bust. */
478  else if (dict->lock(dict, MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT) < 0)
479  msg_fatal("%s:%s: unable to get exclusive lock: %m",
480  dict_type, dict_name);
481  }
482  /* Last step: insert proxy for UTF-8 syntax checks and casefolding. */
483  if ((dict->flags & DICT_FLAG_UTF8_ACTIVE) == 0
485  dict = dict_utf8_activate(dict);
486  return (dict);
487 }
488 
489 /* dict_open_register - register dictionary type */
490 
491 void dict_open_register(const char *type, DICT_OPEN_FN open)
492 {
493  const char *myname = "dict_open_register";
494  DICT_OPEN_INFO *dp;
495  HTABLE_INFO *ht;
496 
497  if (dict_open_hash == 0)
498  dict_open_init();
499  if (htable_find(dict_open_hash, type))
500  msg_panic("%s: dictionary type exists: %s", myname, type);
501  dp = (DICT_OPEN_INFO *) mymalloc(sizeof(*dp));
502  dp->open = open;
503  ht = htable_enter(dict_open_hash, type, (void *) dp);
504  dp->type = ht->key;
505 }
506 
507 /* dict_open_extend - register alternate dictionary search routine */
508 
510 {
511  DICT_OPEN_EXTEND_FN old_cb;
512 
513  old_cb = dict_open_extend_hook;
514  dict_open_extend_hook = new_cb;
515  return (old_cb);
516 }
517 
518 /* dict_sort_alpha_cpp - qsort() callback */
519 
520 static int dict_sort_alpha_cpp(const void *a, const void *b)
521 {
522  return (strcmp(((char **) a)[0], ((char **) b)[0]));
523 }
524 
525 /* dict_mapnames - return an ARGV of available map_names */
526 
528 {
529  HTABLE_INFO **ht_info;
530  HTABLE_INFO **ht;
531  DICT_OPEN_INFO *dp;
532  ARGV *mapnames;
533 
534  if (dict_open_hash == 0)
535  dict_open_init();
536  mapnames = argv_alloc(dict_open_hash->used + 1);
537  for (ht_info = ht = htable_list(dict_open_hash); *ht; ht++) {
538  dp = (DICT_OPEN_INFO *) ht[0]->value;
539  argv_add(mapnames, dp->type, ARGV_END);
540  }
541  if (dict_mapnames_extend_hook != 0)
542  (void) dict_mapnames_extend_hook(mapnames);
543  qsort((void *) mapnames->argv, mapnames->argc, sizeof(mapnames->argv[0]),
544  dict_sort_alpha_cpp);
545  myfree((void *) ht_info);
546  argv_terminate(mapnames);
547  return mapnames;
548 }
549 
550 /* dict_mapnames_extend - register alternate dictionary type list routine */
551 
553 {
555 
556  old_cb = dict_mapnames_extend_hook;
557  dict_mapnames_extend_hook = new_cb;
558  return (old_cb);
559 }
560 
561 /* dict_type_override - disguise a dictionary type */
562 
563 void dict_type_override(DICT *dict, const char *type)
564 {
565  myfree(dict->type);
566  dict->type = mystrdup(type);
567 }
568 
569 #ifdef TEST
570 
571  /*
572  * Proof-of-concept test program.
573  */
574 int main(int argc, char **argv)
575 {
576  dict_test(argc, argv);
577  return (0);
578 }
579 
580 #endif
int msg_verbose
Definition: msg.c:177
void myfree(void *ptr)
Definition: mymalloc.c:207
#define DICT_TYPE_STATIC
Definition: dict_static.h:22
#define ARGV_END
Definition: argv.h:52
#define DICT_NEED_UTF8_ACTIVATION(enable, flags)
Definition: dict.h:171
char * mystrdup(const char *str)
Definition: mymalloc.c:225
DICT_OPEN_EXTEND_FN dict_open_extend(DICT_OPEN_EXTEND_FN new_cb)
Definition: dict_open.c:509
#define DICT_TYPE_HT
Definition: dict_ht.h:23
Definition: argv.h:17
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define DICT_TYPE_NIS
Definition: dict_nis.h:22
DICT * dict_nisplus_open(const char *, int, int)
#define DICT_TYPE_TCP
Definition: dict_tcp.h:22
ssize_t used
Definition: htable.h:27
int flags
Definition: dict.h:81
int main(int argc, char **argv)
Definition: anvil.c:1010
#define MYFLOCK_OP_EXCLUSIVE
Definition: myflock.h:30
DICT * dict_ni_open(const char *, int, int)
DICT * dict_tcp_open(const char *map, int open_flags, int dict_flags)
Definition: dict_tcp.c:285
char ** argv
Definition: argv.h:20
DEFINE_DICT_LMDB_MAP_SIZE
Definition: dict_open.c:401
void argv_add(ARGV *argvp,...)
Definition: argv.c:197
#define DICT_TYPE_SOCKMAP
Definition: dict_sockmap.h:22
DICT_OPEN_FN(* DICT_OPEN_EXTEND_FN)(const char *)
Definition: dict.h:230
DICT * dict_nis_open(const char *, int, int)
ARGV * argv_alloc(ssize_t len)
Definition: argv.c:149
#define DICT_FLAG_MULTI_WRITER
Definition: dict.h:129
Definition: htable.h:25
#define DICT_TYPE_FAIL
Definition: dict_fail.h:22
DICT * dict_inline_open(const char *name, int open_flags, int dict_flags)
Definition: dict_inline.c:54
#define DICT_TYPE_PIPE
Definition: dict_pipe.h:22
#define DICT_TYPE_LMDB
Definition: dict_lmdb.h:22
HTABLE * htable_create(ssize_t size)
Definition: htable.c:179
Definition: dict.h:78
int(* lock)(struct DICT *, int)
Definition: dict.h:86
DICT_OPEN_FN open
Definition: dict_open.c:337
DICT * dict_pipe_open(const char *name, int open_flags, int dict_flags)
Definition: dict_pipe.c:106
#define DICT_TYPE_ENVIRON
Definition: dict_env.h:22
char * type
Definition: dict.h:79
DICT * dict_static_open(const char *name, int open_flags, int dict_flags)
Definition: dict_static.c:60
HTABLE_INFO ** htable_list(HTABLE *table)
Definition: htable.c:330
DICT * dict_lmdb_open(const char *, int, int)
DICT * dict_open(const char *dict_spec, int open_flags, int dict_flags)
Definition: dict_open.c:421
#define MYFLOCK_OP_NOWAIT
Definition: myflock.h:31
DICT * dict_fail_open(const char *name, int open_flags, int dict_flags)
Definition: dict_fail.c:94
#define DICT_TYPE_SDBM
Definition: dict_sdbm.h:22
#define DICT_FLAG_LOCK
Definition: dict.h:116
char * key
Definition: htable.h:17
void dict_type_override(DICT *dict, const char *type)
Definition: dict_open.c:563
DICT * dict_thash_open(const char *path, int open_flags, int dict_flags)
Definition: dict_thash.c:64
void * htable_find(HTABLE *table, const char *key)
Definition: htable.c:227
DICT * dict_ht_open(const char *name, int unused_open_flags, int dict_flags)
Definition: dict_ht.c:155
#define DICT_TYPE_NISPLUS
Definition: dict_nisplus.h:22
struct DICT *(* open)(const char *, int, int)
Definition: mail_dict.c:56
DICT * dict_unix_open(const char *map, int open_flags, int dict_flags)
Definition: dict_unix.c:162
#define DICT_TYPE_RANDOM
Definition: dict_random.h:22
DICT * dict_regexp_open(const char *, int, int)
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
#define DICT_TYPE_UNION
Definition: dict_union.h:22
DEFINE_DICT_DB_CACHE_SIZE
Definition: dict_open.c:402
void(* DICT_MAPNAMES_EXTEND_FN)(ARGV *)
Definition: dict.h:207
char * type
Definition: mail_dict.c:55
void dict_test(int, char **)
Definition: dict_test.c:36
DICT * dict_btree_open(const char *, int, int)
DICT *(* DICT_OPEN_FN)(const char *, int, int)
Definition: dict.h:229
#define DICT_TYPE_HASH
Definition: dict_db.h:22
DICT * dict_pcre_open(const char *, int, int)
void dict_open_register(const char *type, DICT_OPEN_FN open)
Definition: dict_open.c:491
#define DICT_TYPE_REGEXP
Definition: dict_regexp.h:22
#define DICT_TYPE_BTREE
Definition: dict_db.h:23
#define DICT_TYPE_NETINFO
Definition: dict_ni.h:22
DICT * dict_union_open(const char *name, int open_flags, int dict_flags)
Definition: dict_union.c:119
DICT * dict_env_open(const char *name, int unused_flags, int dict_flags)
Definition: dict_env.c:99
DICT * dict_cidr_open(const char *mapname, int open_flags, int dict_flags)
Definition: dict_cidr.c:234
#define DICT_TYPE_DBM
Definition: dict_dbm.h:22
DICT * dict_random_open(const char *name, int open_flags, int dict_flags)
Definition: dict_random.c:80
char * split_at(char *string, int delimiter)
Definition: split_at.c:53
DICT * dict_sdbm_open(const char *, int, int)
DICT * dict_dbm_open(const char *, int, int)
ssize_t argc
Definition: argv.h:19
DICT * dict_utf8_activate(DICT *)
Definition: dict_utf8.c:248
int util_utf8_enable
Definition: printable.c:47
ARGV * dict_mapnames()
Definition: dict_open.c:527
#define DICT_TYPE_CDB
Definition: dict_cdb.h:22
DICT * dict_sockmap_open(const char *mapname, int open_flags, int dict_flags)
Definition: dict_sockmap.c:309
#define DICT_TYPE_PCRE
Definition: dict_pcre.h:22
#define DICT_TYPE_UNIX
Definition: dict_unix.h:22
DICT * dict_open3(const char *dict_type, const char *dict_name, int open_flags, int dict_flags)
Definition: dict_open.c:439
DICT * dict_cdb_open(const char *, int, int)
DICT_MAPNAMES_EXTEND_FN dict_mapnames_extend(DICT_MAPNAMES_EXTEND_FN new_cb)
Definition: dict_open.c:552
#define DICT_TYPE_INLINE
Definition: dict_inline.h:22
DICT * dict_hash_open(const char *, int, int)
#define DICT_FLAG_OPEN_LOCK
Definition: dict.h:127
DICT * dict_surrogate(const char *dict_type, const char *dict_name, int open_flags, int dict_flags, const char *fmt,...)
#define DICT_FLAG_UTF8_ACTIVE
Definition: dict.h:131
#define DICT_TYPE_CIDR
Definition: dict_cidr.h:24
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150
void argv_terminate(ARGV *argvp)
Definition: argv.c:242
HTABLE_INFO * htable_enter(HTABLE *table, const char *key, void *value)
Definition: htable.c:212
void msg_info(const char *fmt,...)
Definition: msg.c:199
#define DICT_TYPE_THASH
Definition: dict_thash.h:22