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.59 2004/08/03 20:58:39 ca 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
;
38 static DBTYPE smdb_type_to_db1_type
__P((SMDB_DBTYPE
));
39 static unsigned int smdb_put_flags_to_db1_flags
__P((SMDB_FLAG
));
40 static int smdb_cursor_get_flags_to_smdb1
__P((SMDB_FLAG
));
41 static SMDB_DB1_DATABASE
*smdb1_malloc_database
__P((void));
42 static int smdb1_close
__P((SMDB_DATABASE
*));
43 static int smdb1_del
__P((SMDB_DATABASE
*, SMDB_DBENT
*, unsigned int));
44 static int smdb1_fd
__P((SMDB_DATABASE
*, int *));
45 static int smdb1_lockfd
__P((SMDB_DATABASE
*));
46 static int smdb1_get
__P((SMDB_DATABASE
*, SMDB_DBENT
*, SMDB_DBENT
*, unsigned int));
47 static int smdb1_put
__P((SMDB_DATABASE
*, SMDB_DBENT
*, SMDB_DBENT
*, unsigned int));
48 static int smdb1_set_owner
__P((SMDB_DATABASE
*, uid_t
, gid_t
));
49 static int smdb1_sync
__P((SMDB_DATABASE
*, unsigned int));
50 static int smdb1_cursor_close
__P((SMDB_CURSOR
*));
51 static int smdb1_cursor_del
__P((SMDB_CURSOR
*, unsigned int));
52 static int smdb1_cursor_get
__P((SMDB_CURSOR
*, SMDB_DBENT
*, SMDB_DBENT
*, SMDB_FLAG
));
53 static int smdb1_cursor_put
__P((SMDB_CURSOR
*, SMDB_DBENT
*, SMDB_DBENT
*, SMDB_FLAG
));
54 static int smdb1_cursor
__P((SMDB_DATABASE
*, SMDB_CURSOR
**, unsigned int));
57 ** SMDB_TYPE_TO_DB1_TYPE -- Translates smdb database type to db1 type.
60 ** type -- The type to translate.
63 ** The DB1 type that corresponsds to the passed in SMDB type.
64 ** Returns -1 if there is no equivalent type.
69 smdb_type_to_db1_type(type
)
72 if (type
== SMDB_TYPE_DEFAULT
)
75 if (strncmp(type
, SMDB_TYPE_HASH
, SMDB_TYPE_HASH_LEN
) == 0)
78 if (strncmp(type
, SMDB_TYPE_BTREE
, SMDB_TYPE_BTREE_LEN
) == 0)
81 /* Should never get here thanks to test in smdb_db_open() */
85 ** SMDB_PUT_FLAGS_TO_DB1_FLAGS -- Translates smdb put flags to db1 put flags.
88 ** flags -- The flags to translate.
91 ** The db1 flags that are equivalent to the smdb flags.
94 ** Any invalid flags are ignored.
99 smdb_put_flags_to_db1_flags(flags
)
106 if (bitset(SMDBF_NO_OVERWRITE
, flags
))
107 return_flags
|= R_NOOVERWRITE
;
112 ** SMDB_CURSOR_GET_FLAGS_TO_SMDB1
115 ** flags -- The flags to translate.
118 ** The db1 flags that are equivalent to the smdb flags.
121 ** Returns -1 if we don't support the flag.
126 smdb_cursor_get_flags_to_smdb1(flags
)
131 case SMDB_CURSOR_GET_FIRST
:
134 case SMDB_CURSOR_GET_LAST
:
137 case SMDB_CURSOR_GET_NEXT
:
140 case SMDB_CURSOR_GET_RANGE
:
149 ** The rest of these functions correspond to the interface laid out in smdb.h.
152 static SMDB_DB1_DATABASE
*
153 smdb1_malloc_database()
155 SMDB_DB1_DATABASE
*db1
;
157 db1
= (SMDB_DB1_DATABASE
*) malloc(sizeof(SMDB_DB1_DATABASE
));
161 db1
->smdb1_lock_fd
= -1;
162 db1
->smdb1_cursor_in_use
= false;
169 smdb1_close(database
)
170 SMDB_DATABASE
*database
;
173 SMDB_DB1_DATABASE
*db1
= (SMDB_DB1_DATABASE
*) database
->smdb_impl
;
174 DB
*db
= ((SMDB_DB1_DATABASE
*) database
->smdb_impl
)->smdb1_db
;
176 result
= db
->close(db
);
177 if (db1
->smdb1_lock_fd
!= -1)
178 (void) close(db1
->smdb1_lock_fd
);
181 database
->smdb_impl
= NULL
;
187 smdb1_del(database
, key
, flags
)
188 SMDB_DATABASE
*database
;
192 DB
*db
= ((SMDB_DB1_DATABASE
*) database
->smdb_impl
)->smdb1_db
;
195 (void) memset(&dbkey
, '\0', sizeof dbkey
);
196 dbkey
.data
= key
->data
;
197 dbkey
.size
= key
->size
;
198 return db
->del(db
, &dbkey
, flags
);
202 smdb1_fd(database
, fd
)
203 SMDB_DATABASE
*database
;
206 DB
*db
= ((SMDB_DB1_DATABASE
*) database
->smdb_impl
)->smdb1_db
;
216 smdb1_lockfd(database
)
217 SMDB_DATABASE
*database
;
219 SMDB_DB1_DATABASE
*db1
= (SMDB_DB1_DATABASE
*) database
->smdb_impl
;
221 return db1
->smdb1_lock_fd
;
226 smdb1_get(database
, key
, data
, flags
)
227 SMDB_DATABASE
*database
;
233 DB
*db
= ((SMDB_DB1_DATABASE
*) database
->smdb_impl
)->smdb1_db
;
236 (void) memset(&dbdata
, '\0', sizeof dbdata
);
237 (void) memset(&dbkey
, '\0', sizeof dbkey
);
238 dbkey
.data
= key
->data
;
239 dbkey
.size
= key
->size
;
241 result
= db
->get(db
, &dbkey
, &dbdata
, flags
);
245 return SMDBE_NOT_FOUND
;
248 data
->data
= dbdata
.data
;
249 data
->size
= dbdata
.size
;
254 smdb1_put(database
, key
, data
, flags
)
255 SMDB_DATABASE
*database
;
260 DB
*db
= ((SMDB_DB1_DATABASE
*) database
->smdb_impl
)->smdb1_db
;
263 (void) memset(&dbdata
, '\0', sizeof dbdata
);
264 (void) memset(&dbkey
, '\0', sizeof dbkey
);
265 dbkey
.data
= key
->data
;
266 dbkey
.size
= key
->size
;
267 dbdata
.data
= data
->data
;
268 dbdata
.size
= data
->size
;
270 return db
->put(db
, &dbkey
, &dbdata
,
271 smdb_put_flags_to_db1_flags(flags
));
275 smdb1_set_owner(database
, uid
, gid
)
276 SMDB_DATABASE
*database
;
283 DB
*db
= ((SMDB_DB1_DATABASE
*) database
->smdb_impl
)->smdb1_db
;
289 result
= fchown(fd
, uid
, gid
);
292 # endif /* HASFCHOWN */
298 smdb1_sync(database
, flags
)
299 SMDB_DATABASE
*database
;
302 DB
*db
= ((SMDB_DB1_DATABASE
*) database
->smdb_impl
)->smdb1_db
;
304 return db
->sync(db
, flags
);
308 smdb1_cursor_close(cursor
)
311 SMDB_DB1_CURSOR
*db1_cursor
= (SMDB_DB1_CURSOR
*) cursor
->smdbc_impl
;
312 SMDB_DB1_DATABASE
*db1
= db1_cursor
->db
;
314 if (!db1
->smdb1_cursor_in_use
)
315 return SMDBE_NOT_A_VALID_CURSOR
;
317 db1
->smdb1_cursor_in_use
= false;
324 smdb1_cursor_del(cursor
, flags
)
328 SMDB_DB1_CURSOR
*db1_cursor
= (SMDB_DB1_CURSOR
*) cursor
->smdbc_impl
;
329 SMDB_DB1_DATABASE
*db1
= db1_cursor
->db
;
330 DB
*db
= db1
->smdb1_db
;
332 return db
->del(db
, NULL
, R_CURSOR
);
336 smdb1_cursor_get(cursor
, key
, value
, flags
)
344 SMDB_DB1_CURSOR
*db1_cursor
= (SMDB_DB1_CURSOR
*) cursor
->smdbc_impl
;
345 SMDB_DB1_DATABASE
*db1
= db1_cursor
->db
;
346 DB
*db
= db1
->smdb1_db
;
349 (void) memset(&dbdata
, '\0', sizeof dbdata
);
350 (void) memset(&dbkey
, '\0', sizeof dbkey
);
352 db1_flags
= smdb_cursor_get_flags_to_smdb1(flags
);
353 result
= db
->seq(db
, &dbkey
, &dbdata
, db1_flags
);
357 return SMDBE_LAST_ENTRY
;
358 value
->data
= dbdata
.data
;
359 value
->size
= dbdata
.size
;
360 key
->data
= dbkey
.data
;
361 key
->size
= dbkey
.size
;
366 smdb1_cursor_put(cursor
, key
, value
, flags
)
372 SMDB_DB1_CURSOR
*db1_cursor
= (SMDB_DB1_CURSOR
*) cursor
->smdbc_impl
;
373 SMDB_DB1_DATABASE
*db1
= db1_cursor
->db
;
374 DB
*db
= db1
->smdb1_db
;
377 (void) memset(&dbdata
, '\0', sizeof dbdata
);
378 (void) memset(&dbkey
, '\0', sizeof dbkey
);
379 dbkey
.data
= key
->data
;
380 dbkey
.size
= key
->size
;
381 dbdata
.data
= value
->data
;
382 dbdata
.size
= value
->size
;
384 return db
->put(db
, &dbkey
, &dbdata
, R_CURSOR
);
388 smdb1_cursor(database
, cursor
, flags
)
389 SMDB_DATABASE
*database
;
390 SMDB_CURSOR
**cursor
;
393 SMDB_DB1_DATABASE
*db1
= (SMDB_DB1_DATABASE
*) database
->smdb_impl
;
395 SMDB_DB1_CURSOR
*db1_cursor
;
397 if (db1
->smdb1_cursor_in_use
)
398 return SMDBE_ONLY_SUPPORTS_ONE_CURSOR
;
400 db1
->smdb1_cursor_in_use
= true;
401 db1_cursor
= (SMDB_DB1_CURSOR
*) malloc(sizeof(SMDB_DB1_CURSOR
));
402 db1_cursor
->db
= db1
;
404 cur
= (SMDB_CURSOR
*) malloc(sizeof(SMDB_CURSOR
));
409 cur
->smdbc_impl
= db1_cursor
;
410 cur
->smdbc_close
= smdb1_cursor_close
;
411 cur
->smdbc_del
= smdb1_cursor_del
;
412 cur
->smdbc_get
= smdb1_cursor_get
;
413 cur
->smdbc_put
= smdb1_cursor_put
;
419 ** SMDB_DB_OPEN -- Opens a db1 database.
422 ** database -- An unallocated database pointer to a pointer.
423 ** db_name -- The name of the database without extension.
424 ** mode -- File permisions on the database if created.
425 ** mode_mask -- Mode bits that must match on an existing database.
426 ** sff -- Flags for safefile.
427 ** type -- The type of database to open
428 ** See smdb_type_to_db1_type for valid types.
429 ** user_info -- Information on the user to use for file
432 ** An SMDB_DBPARAMS struct including params. These
433 ** are processed according to the type of the
434 ** database. Currently supported params (only for
440 ** SMDBE_OK -- Success, otherwise errno.
444 smdb_db_open(database
, db_name
, mode
, mode_mask
, sff
, type
, user_info
,
446 SMDB_DATABASE
**database
;
452 SMDB_USER_INFO
*user_info
;
453 SMDB_DBPARAMS
*db_params
;
455 bool lockcreated
= false;
460 SMDB_DATABASE
*smdb_db
;
461 SMDB_DB1_DATABASE
*db1
;
464 BTREEINFO btree_info
;
466 struct stat stat_info
;
467 char db_file_name
[MAXPATHLEN
];
470 (strncmp(SMDB_TYPE_HASH
, type
, SMDB_TYPE_HASH_LEN
) != 0 &&
471 strncmp(SMDB_TYPE_BTREE
, type
, SMDB_TYPE_BTREE_LEN
) != 0))
472 return SMDBE_UNKNOWN_DB_TYPE
;
474 result
= smdb_add_extension(db_file_name
, sizeof db_file_name
,
475 db_name
, SMDB1_FILE_EXTENSION
);
476 if (result
!= SMDBE_OK
)
479 result
= smdb_setup_file(db_name
, SMDB1_FILE_EXTENSION
, mode_mask
,
480 sff
, user_info
, &stat_info
);
481 if (result
!= SMDBE_OK
)
484 if (stat_info
.st_mode
== ST_MODE_NOFILE
&&
485 bitset(mode
, O_CREAT
))
489 result
= smdb_lock_file(&lock_fd
, db_name
, mode
, sff
,
490 SMDB1_FILE_EXTENSION
);
491 if (result
!= SMDBE_OK
)
497 mode
&= ~(O_CREAT
|O_EXCL
);
502 smdb_db
= smdb_malloc_database();
503 db1
= smdb1_malloc_database();
504 if (smdb_db
== NULL
|| db1
== NULL
)
506 db1
->smdb1_lock_fd
= lock_fd
;
509 if (db_params
!= NULL
&&
510 (strncmp(SMDB_TYPE_HASH
, type
, SMDB_TYPE_HASH_LEN
) == 0))
512 (void) memset(&hash_info
, '\0', sizeof hash_info
);
513 hash_info
.nelem
= db_params
->smdbp_num_elements
;
514 hash_info
.cachesize
= db_params
->smdbp_cache_size
;
518 if (db_params
!= NULL
&&
519 (strncmp(SMDB_TYPE_BTREE
, type
, SMDB_TYPE_BTREE_LEN
) == 0))
521 (void) memset(&btree_info
, '\0', sizeof btree_info
);
522 btree_info
.cachesize
= db_params
->smdbp_cache_size
;
523 if (db_params
->smdbp_allow_dup
)
524 btree_info
.flags
|= R_DUP
;
525 params
= &btree_info
;
528 db_type
= smdb_type_to_db1_type(type
);
529 db
= dbopen(db_file_name
, mode
, DBMMODE
, db_type
, params
);
533 result
= smdb_filechanged(db_name
, SMDB1_FILE_EXTENSION
, db_fd
,
539 result
= SMDBE_BAD_OPEN
;
544 if (result
== SMDBE_OK
)
546 /* Everything is ok. Setup driver */
549 smdb_db
->smdb_close
= smdb1_close
;
550 smdb_db
->smdb_del
= smdb1_del
;
551 smdb_db
->smdb_fd
= smdb1_fd
;
552 smdb_db
->smdb_lockfd
= smdb1_lockfd
;
553 smdb_db
->smdb_get
= smdb1_get
;
554 smdb_db
->smdb_put
= smdb1_put
;
555 smdb_db
->smdb_set_owner
= smdb1_set_owner
;
556 smdb_db
->smdb_sync
= smdb1_sync
;
557 smdb_db
->smdb_cursor
= smdb1_cursor
;
558 smdb_db
->smdb_impl
= db1
;
565 (void) db
->close(db
);
567 /* Error opening database */
568 (void) smdb_unlock_file(db1
->smdb1_lock_fd
);
570 smdb_free_database(smdb_db
);
575 #endif /* (DB_VERSION_MAJOR == 1) */