2 ** Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers.
3 ** All rights reserved.
5 ** By using this file, you agree to the terms and conditions set
6 ** forth in the LICENSE file which can be found at the top level of
7 ** the sendmail distribution.
11 SM_RCSID("@(#)$Id: smdb1.c,v 8.58 2002/05/24 23:09:11 gshapiro Exp $")
17 #include <sendmail/sendmail.h>
18 #include <libsmdb/smdb.h>
20 #if (DB_VERSION_MAJOR == 1)
22 # define SMDB1_FILE_EXTENSION "db"
24 struct smdb_db1_struct
28 bool smdb1_cursor_in_use;
30 typedef struct smdb_db1_struct SMDB_DB1_DATABASE;
32 struct smdb_db1_cursor
34 SMDB_DB1_DATABASE *db;
36 typedef struct smdb_db1_cursor SMDB_DB1_CURSOR;
39 ** SMDB_TYPE_TO_DB1_TYPE -- Translates smdb database type to db1 type.
42 ** type -- The type to translate.
45 ** The DB1 type that corresponsds to the passed in SMDB type.
46 ** Returns -1 if there is no equivalent type.
51 smdb_type_to_db1_type(type)
54 if (type == SMDB_TYPE_DEFAULT)
57 if (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0)
60 if (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0)
63 /* Should never get here thanks to test in smdb_db_open() */
67 ** SMDB_PUT_FLAGS_TO_DB1_FLAGS -- Translates smdb put flags to db1 put flags.
70 ** flags -- The flags to translate.
73 ** The db1 flags that are equivalent to the smdb flags.
76 ** Any invalid flags are ignored.
81 smdb_put_flags_to_db1_flags(flags)
88 if (bitset(SMDBF_NO_OVERWRITE, flags))
89 return_flags |= R_NOOVERWRITE;
94 ** SMDB_CURSOR_GET_FLAGS_TO_SMDB1
97 ** flags -- The flags to translate.
100 ** The db1 flags that are equivalent to the smdb flags.
103 ** Returns -1 if we don't support the flag.
108 smdb_cursor_get_flags_to_smdb1(flags)
113 case SMDB_CURSOR_GET_FIRST:
116 case SMDB_CURSOR_GET_LAST:
119 case SMDB_CURSOR_GET_NEXT:
122 case SMDB_CURSOR_GET_RANGE:
131 ** The rest of these functions correspond to the interface laid out in smdb.h.
135 smdb1_malloc_database()
137 SMDB_DB1_DATABASE *db1;
139 db1 = (SMDB_DB1_DATABASE *) malloc(sizeof(SMDB_DB1_DATABASE));
143 db1->smdb1_lock_fd = -1;
144 db1->smdb1_cursor_in_use = false;
151 smdb1_close(database)
152 SMDB_DATABASE *database;
155 SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
156 DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
158 result = db->close(db);
159 if (db1->smdb1_lock_fd != -1)
160 (void) close(db1->smdb1_lock_fd);
163 database->smdb_impl = NULL;
169 smdb1_del(database, key, flags)
170 SMDB_DATABASE *database;
174 DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
177 (void) memset(&dbkey, '\0', sizeof dbkey);
178 dbkey.data = key->data;
179 dbkey.size = key->size;
180 return db->del(db, &dbkey, flags);
184 smdb1_fd(database, fd)
185 SMDB_DATABASE *database;
188 DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
198 smdb1_lockfd(database)
199 SMDB_DATABASE *database;
201 SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
203 return db1->smdb1_lock_fd;
208 smdb1_get(database, key, data, flags)
209 SMDB_DATABASE *database;
215 DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
218 (void) memset(&dbdata, '\0', sizeof dbdata);
219 (void) memset(&dbkey, '\0', sizeof dbkey);
220 dbkey.data = key->data;
221 dbkey.size = key->size;
223 result = db->get(db, &dbkey, &dbdata, flags);
227 return SMDBE_NOT_FOUND;
230 data->data = dbdata.data;
231 data->size = dbdata.size;
236 smdb1_put(database, key, data, flags)
237 SMDB_DATABASE *database;
242 DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
245 (void) memset(&dbdata, '\0', sizeof dbdata);
246 (void) memset(&dbkey, '\0', sizeof dbkey);
247 dbkey.data = key->data;
248 dbkey.size = key->size;
249 dbdata.data = data->data;
250 dbdata.size = data->size;
252 return db->put(db, &dbkey, &dbdata,
253 smdb_put_flags_to_db1_flags(flags));
257 smdb1_set_owner(database, uid, gid)
258 SMDB_DATABASE *database;
265 DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
271 result = fchown(fd, uid, gid);
274 # endif /* HASFCHOWN */
280 smdb1_sync(database, flags)
281 SMDB_DATABASE *database;
284 DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
286 return db->sync(db, flags);
290 smdb1_cursor_close(cursor)
293 SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
294 SMDB_DB1_DATABASE *db1 = db1_cursor->db;
296 if (!db1->smdb1_cursor_in_use)
297 return SMDBE_NOT_A_VALID_CURSOR;
299 db1->smdb1_cursor_in_use = false;
306 smdb1_cursor_del(cursor, flags)
310 SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
311 SMDB_DB1_DATABASE *db1 = db1_cursor->db;
312 DB *db = db1->smdb1_db;
314 return db->del(db, NULL, R_CURSOR);
318 smdb1_cursor_get(cursor, key, value, flags)
326 SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
327 SMDB_DB1_DATABASE *db1 = db1_cursor->db;
328 DB *db = db1->smdb1_db;
331 (void) memset(&dbdata, '\0', sizeof dbdata);
332 (void) memset(&dbkey, '\0', sizeof dbkey);
334 db1_flags = smdb_cursor_get_flags_to_smdb1(flags);
335 result = db->seq(db, &dbkey, &dbdata, db1_flags);
339 return SMDBE_LAST_ENTRY;
340 value->data = dbdata.data;
341 value->size = dbdata.size;
342 key->data = dbkey.data;
343 key->size = dbkey.size;
348 smdb1_cursor_put(cursor, key, value, flags)
354 SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
355 SMDB_DB1_DATABASE *db1 = db1_cursor->db;
356 DB *db = db1->smdb1_db;
359 (void) memset(&dbdata, '\0', sizeof dbdata);
360 (void) memset(&dbkey, '\0', sizeof dbkey);
361 dbkey.data = key->data;
362 dbkey.size = key->size;
363 dbdata.data = value->data;
364 dbdata.size = value->size;
366 return db->put(db, &dbkey, &dbdata, R_CURSOR);
370 smdb1_cursor(database, cursor, flags)
371 SMDB_DATABASE *database;
372 SMDB_CURSOR **cursor;
375 SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
377 SMDB_DB1_CURSOR *db1_cursor;
379 if (db1->smdb1_cursor_in_use)
380 return SMDBE_ONLY_SUPPORTS_ONE_CURSOR;
382 db1->smdb1_cursor_in_use = true;
383 db1_cursor = (SMDB_DB1_CURSOR *) malloc(sizeof(SMDB_DB1_CURSOR));
384 db1_cursor->db = db1;
386 cur = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR));
391 cur->smdbc_impl = db1_cursor;
392 cur->smdbc_close = smdb1_cursor_close;
393 cur->smdbc_del = smdb1_cursor_del;
394 cur->smdbc_get = smdb1_cursor_get;
395 cur->smdbc_put = smdb1_cursor_put;
401 ** SMDB_DB_OPEN -- Opens a db1 database.
404 ** database -- An unallocated database pointer to a pointer.
405 ** db_name -- The name of the database without extension.
406 ** mode -- File permisions on the database if created.
407 ** mode_mask -- Mode bits that must match on an existing database.
408 ** sff -- Flags for safefile.
409 ** type -- The type of database to open
410 ** See smdb_type_to_db1_type for valid types.
411 ** user_info -- Information on the user to use for file
414 ** An SMDB_DBPARAMS struct including params. These
415 ** are processed according to the type of the
416 ** database. Currently supported params (only for
422 ** SMDBE_OK -- Success, otherwise errno.
426 smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info,
428 SMDB_DATABASE **database;
434 SMDB_USER_INFO *user_info;
435 SMDB_DBPARAMS *db_params;
437 bool lockcreated = false;
442 SMDB_DATABASE *smdb_db;
443 SMDB_DB1_DATABASE *db1;
446 BTREEINFO btree_info;
448 struct stat stat_info;
449 char db_file_name[MAXPATHLEN];
452 (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) != 0 &&
453 strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) != 0))
454 return SMDBE_UNKNOWN_DB_TYPE;
456 result = smdb_add_extension(db_file_name, sizeof db_file_name,
457 db_name, SMDB1_FILE_EXTENSION);
458 if (result != SMDBE_OK)
461 result = smdb_setup_file(db_name, SMDB1_FILE_EXTENSION, mode_mask,
462 sff, user_info, &stat_info);
463 if (result != SMDBE_OK)
466 if (stat_info.st_mode == ST_MODE_NOFILE &&
467 bitset(mode, O_CREAT))
471 result = smdb_lock_file(&lock_fd, db_name, mode, sff,
472 SMDB1_FILE_EXTENSION);
473 if (result != SMDBE_OK)
479 mode &= ~(O_CREAT|O_EXCL);
484 smdb_db = smdb_malloc_database();
485 db1 = smdb1_malloc_database();
486 if (smdb_db == NULL || db1 == NULL)
488 db1->smdb1_lock_fd = lock_fd;
491 if (db_params != NULL &&
492 (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) == 0))
494 (void) memset(&hash_info, '\0', sizeof hash_info);
495 hash_info.nelem = db_params->smdbp_num_elements;
496 hash_info.cachesize = db_params->smdbp_cache_size;
500 if (db_params != NULL &&
501 (strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) == 0))
503 (void) memset(&btree_info, '\0', sizeof btree_info);
504 btree_info.cachesize = db_params->smdbp_cache_size;
505 if (db_params->smdbp_allow_dup)
506 btree_info.flags |= R_DUP;
507 params = &btree_info;
510 db_type = smdb_type_to_db1_type(type);
511 db = dbopen(db_file_name, mode, DBMMODE, db_type, params);
515 result = smdb_filechanged(db_name, SMDB1_FILE_EXTENSION, db_fd,
521 result = SMDBE_BAD_OPEN;
526 if (result == SMDBE_OK)
528 /* Everything is ok. Setup driver */
531 smdb_db->smdb_close = smdb1_close;
532 smdb_db->smdb_del = smdb1_del;
533 smdb_db->smdb_fd = smdb1_fd;
534 smdb_db->smdb_lockfd = smdb1_lockfd;
535 smdb_db->smdb_get = smdb1_get;
536 smdb_db->smdb_put = smdb1_put;
537 smdb_db->smdb_set_owner = smdb1_set_owner;
538 smdb_db->smdb_sync = smdb1_sync;
539 smdb_db->smdb_cursor = smdb1_cursor;
540 smdb_db->smdb_impl = db1;
547 (void) db->close(db);
549 /* Error opening database */
550 (void) smdb_unlock_file(db1->smdb1_lock_fd);
552 smdb_free_database(smdb_db);
557 #endif /* (DB_VERSION_MAJOR == 1) */