xref: /freebsd/contrib/sendmail/libsmdb/smdb1.c (revision d39bd2c1388b520fcba9abed1932acacead60fba)
106f25ae9SGregory Neil Shapiro /*
25dd76dd0SGregory Neil Shapiro ** Copyright (c) 1999-2002, 2004, 2009 Proofpoint, Inc. and its suppliers.
306f25ae9SGregory Neil Shapiro **	All rights reserved.
406f25ae9SGregory Neil Shapiro **
506f25ae9SGregory Neil Shapiro ** By using this file, you agree to the terms and conditions set
606f25ae9SGregory Neil Shapiro ** forth in the LICENSE file which can be found at the top level of
706f25ae9SGregory Neil Shapiro ** the sendmail distribution.
806f25ae9SGregory Neil Shapiro */
906f25ae9SGregory Neil Shapiro 
1040266059SGregory Neil Shapiro #include <sm/gen.h>
114313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: smdb1.c,v 8.63 2013-11-22 20:51:49 ca Exp $")
1206f25ae9SGregory Neil Shapiro 
1306f25ae9SGregory Neil Shapiro #include <unistd.h>
1406f25ae9SGregory Neil Shapiro #include <stdlib.h>
1506f25ae9SGregory Neil Shapiro #include <fcntl.h>
1606f25ae9SGregory Neil Shapiro 
1706f25ae9SGregory Neil Shapiro #include <sendmail/sendmail.h>
1806f25ae9SGregory Neil Shapiro #include <libsmdb/smdb.h>
1906f25ae9SGregory Neil Shapiro 
2006f25ae9SGregory Neil Shapiro #if (DB_VERSION_MAJOR == 1)
2106f25ae9SGregory Neil Shapiro 
2206f25ae9SGregory Neil Shapiro struct smdb_db1_struct
2306f25ae9SGregory Neil Shapiro {
2406f25ae9SGregory Neil Shapiro 	DB	*smdb1_db;
2506f25ae9SGregory Neil Shapiro 	int	smdb1_lock_fd;
2606f25ae9SGregory Neil Shapiro 	bool	smdb1_cursor_in_use;
2706f25ae9SGregory Neil Shapiro };
2806f25ae9SGregory Neil Shapiro typedef struct smdb_db1_struct SMDB_DB1_DATABASE;
2906f25ae9SGregory Neil Shapiro 
3006f25ae9SGregory Neil Shapiro struct smdb_db1_cursor
3106f25ae9SGregory Neil Shapiro {
3206f25ae9SGregory Neil Shapiro 	SMDB_DB1_DATABASE	*db;
3306f25ae9SGregory Neil Shapiro };
3406f25ae9SGregory Neil Shapiro typedef struct smdb_db1_cursor SMDB_DB1_CURSOR;
3506f25ae9SGregory Neil Shapiro 
36b6bacd31SGregory Neil Shapiro static DBTYPE		smdb_type_to_db1_type __P((SMDB_DBTYPE));
37b6bacd31SGregory Neil Shapiro static unsigned int	smdb_put_flags_to_db1_flags __P((SMDB_FLAG));
38b6bacd31SGregory Neil Shapiro static int		smdb_cursor_get_flags_to_smdb1 __P((SMDB_FLAG));
39b6bacd31SGregory Neil Shapiro static SMDB_DB1_DATABASE *smdb1_malloc_database __P((void));
40b6bacd31SGregory Neil Shapiro static int		smdb1_close __P((SMDB_DATABASE *));
41b6bacd31SGregory Neil Shapiro static int		smdb1_del __P((SMDB_DATABASE *, SMDB_DBENT *, unsigned int));
42b6bacd31SGregory Neil Shapiro static int		smdb1_fd __P((SMDB_DATABASE *, int *));
43b6bacd31SGregory Neil Shapiro static int		smdb1_lockfd __P((SMDB_DATABASE *));
44b6bacd31SGregory Neil Shapiro static int		smdb1_get __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int));
45b6bacd31SGregory Neil Shapiro static int		smdb1_put __P((SMDB_DATABASE *, SMDB_DBENT *, SMDB_DBENT *, unsigned int));
46b6bacd31SGregory Neil Shapiro static int		smdb1_set_owner __P((SMDB_DATABASE *, uid_t, gid_t));
47b6bacd31SGregory Neil Shapiro static int		smdb1_sync __P((SMDB_DATABASE *, unsigned int));
48b6bacd31SGregory Neil Shapiro static int		smdb1_cursor_close __P((SMDB_CURSOR *));
49b6bacd31SGregory Neil Shapiro static int		smdb1_cursor_del __P((SMDB_CURSOR *, unsigned int));
50b6bacd31SGregory Neil Shapiro static int		smdb1_cursor_get __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG));
51b6bacd31SGregory Neil Shapiro static int		smdb1_cursor_put __P((SMDB_CURSOR *, SMDB_DBENT *, SMDB_DBENT *, SMDB_FLAG));
52b6bacd31SGregory Neil Shapiro static int		smdb1_cursor __P((SMDB_DATABASE *, SMDB_CURSOR **, unsigned int));
53b6bacd31SGregory Neil Shapiro 
5440266059SGregory Neil Shapiro /*
5506f25ae9SGregory Neil Shapiro **  SMDB_TYPE_TO_DB1_TYPE -- Translates smdb database type to db1 type.
5606f25ae9SGregory Neil Shapiro **
5706f25ae9SGregory Neil Shapiro **	Parameters:
5806f25ae9SGregory Neil Shapiro **		type -- The type to translate.
5906f25ae9SGregory Neil Shapiro **
6006f25ae9SGregory Neil Shapiro **	Returns:
6106f25ae9SGregory Neil Shapiro **		The DB1 type that corresponsds to the passed in SMDB type.
6206f25ae9SGregory Neil Shapiro **		Returns -1 if there is no equivalent type.
6306f25ae9SGregory Neil Shapiro **
6406f25ae9SGregory Neil Shapiro */
6506f25ae9SGregory Neil Shapiro 
66b6bacd31SGregory Neil Shapiro static DBTYPE
smdb_type_to_db1_type(type)6706f25ae9SGregory Neil Shapiro smdb_type_to_db1_type(type)
6806f25ae9SGregory Neil Shapiro 	SMDB_DBTYPE type;
6906f25ae9SGregory Neil Shapiro {
7006f25ae9SGregory Neil Shapiro 	if (type == SMDB_TYPE_DEFAULT)
7106f25ae9SGregory Neil Shapiro 		return DB_HASH;
7206f25ae9SGregory Neil Shapiro 
735b0945b5SGregory Neil Shapiro 	if (SMDB_IS_TYPE_HASH(type))
7406f25ae9SGregory Neil Shapiro 		return DB_HASH;
7506f25ae9SGregory Neil Shapiro 
765b0945b5SGregory Neil Shapiro 	if (SMDB_IS_TYPE_BTREE(type))
7706f25ae9SGregory Neil Shapiro 		return DB_BTREE;
7806f25ae9SGregory Neil Shapiro 
7906f25ae9SGregory Neil Shapiro 	/* Should never get here thanks to test in smdb_db_open() */
8006f25ae9SGregory Neil Shapiro 	return DB_HASH;
8106f25ae9SGregory Neil Shapiro }
8240266059SGregory Neil Shapiro /*
8306f25ae9SGregory Neil Shapiro **  SMDB_PUT_FLAGS_TO_DB1_FLAGS -- Translates smdb put flags to db1 put flags.
8406f25ae9SGregory Neil Shapiro **
8506f25ae9SGregory Neil Shapiro **	Parameters:
8606f25ae9SGregory Neil Shapiro **		flags -- The flags to translate.
8706f25ae9SGregory Neil Shapiro **
8806f25ae9SGregory Neil Shapiro **	Returns:
8906f25ae9SGregory Neil Shapiro **		The db1 flags that are equivalent to the smdb flags.
9006f25ae9SGregory Neil Shapiro **
9106f25ae9SGregory Neil Shapiro **	Notes:
9206f25ae9SGregory Neil Shapiro **		Any invalid flags are ignored.
9306f25ae9SGregory Neil Shapiro **
9406f25ae9SGregory Neil Shapiro */
9506f25ae9SGregory Neil Shapiro 
96b6bacd31SGregory Neil Shapiro static unsigned int
smdb_put_flags_to_db1_flags(flags)9706f25ae9SGregory Neil Shapiro smdb_put_flags_to_db1_flags(flags)
9806f25ae9SGregory Neil Shapiro 	SMDB_FLAG flags;
9906f25ae9SGregory Neil Shapiro {
10006f25ae9SGregory Neil Shapiro 	int return_flags;
10106f25ae9SGregory Neil Shapiro 
10206f25ae9SGregory Neil Shapiro 	return_flags = 0;
10306f25ae9SGregory Neil Shapiro 
10406f25ae9SGregory Neil Shapiro 	if (bitset(SMDBF_NO_OVERWRITE, flags))
10506f25ae9SGregory Neil Shapiro 		return_flags |= R_NOOVERWRITE;
10606f25ae9SGregory Neil Shapiro 
10706f25ae9SGregory Neil Shapiro 	return return_flags;
10806f25ae9SGregory Neil Shapiro }
10940266059SGregory Neil Shapiro /*
11006f25ae9SGregory Neil Shapiro **  SMDB_CURSOR_GET_FLAGS_TO_SMDB1
11106f25ae9SGregory Neil Shapiro **
11206f25ae9SGregory Neil Shapiro **	Parameters:
11306f25ae9SGregory Neil Shapiro **		flags -- The flags to translate.
11406f25ae9SGregory Neil Shapiro **
11506f25ae9SGregory Neil Shapiro **	Returns:
11606f25ae9SGregory Neil Shapiro **		The db1 flags that are equivalent to the smdb flags.
11706f25ae9SGregory Neil Shapiro **
11806f25ae9SGregory Neil Shapiro **	Notes:
11906f25ae9SGregory Neil Shapiro **		Returns -1 if we don't support the flag.
12006f25ae9SGregory Neil Shapiro **
12106f25ae9SGregory Neil Shapiro */
12206f25ae9SGregory Neil Shapiro 
123b6bacd31SGregory Neil Shapiro static int
smdb_cursor_get_flags_to_smdb1(flags)12406f25ae9SGregory Neil Shapiro smdb_cursor_get_flags_to_smdb1(flags)
12506f25ae9SGregory Neil Shapiro 	SMDB_FLAG flags;
12606f25ae9SGregory Neil Shapiro {
12706f25ae9SGregory Neil Shapiro 	switch(flags)
12806f25ae9SGregory Neil Shapiro 	{
12906f25ae9SGregory Neil Shapiro 		case SMDB_CURSOR_GET_FIRST:
13006f25ae9SGregory Neil Shapiro 			return R_FIRST;
13106f25ae9SGregory Neil Shapiro 
13206f25ae9SGregory Neil Shapiro 		case SMDB_CURSOR_GET_LAST:
13306f25ae9SGregory Neil Shapiro 			return R_LAST;
13406f25ae9SGregory Neil Shapiro 
13506f25ae9SGregory Neil Shapiro 		case SMDB_CURSOR_GET_NEXT:
13606f25ae9SGregory Neil Shapiro 			return R_NEXT;
13706f25ae9SGregory Neil Shapiro 
13806f25ae9SGregory Neil Shapiro 		case SMDB_CURSOR_GET_RANGE:
13906f25ae9SGregory Neil Shapiro 			return R_CURSOR;
14006f25ae9SGregory Neil Shapiro 
14106f25ae9SGregory Neil Shapiro 		default:
14206f25ae9SGregory Neil Shapiro 			return -1;
14306f25ae9SGregory Neil Shapiro 	}
14406f25ae9SGregory Neil Shapiro }
14506f25ae9SGregory Neil Shapiro 
14640266059SGregory Neil Shapiro /*
14740266059SGregory Neil Shapiro **  The rest of these functions correspond to the interface laid out in smdb.h.
14840266059SGregory Neil Shapiro */
14940266059SGregory Neil Shapiro 
150b6bacd31SGregory Neil Shapiro static SMDB_DB1_DATABASE *
smdb1_malloc_database()15106f25ae9SGregory Neil Shapiro smdb1_malloc_database()
15206f25ae9SGregory Neil Shapiro {
15306f25ae9SGregory Neil Shapiro 	SMDB_DB1_DATABASE *db1;
15406f25ae9SGregory Neil Shapiro 
15506f25ae9SGregory Neil Shapiro 	db1 = (SMDB_DB1_DATABASE *) malloc(sizeof(SMDB_DB1_DATABASE));
15606f25ae9SGregory Neil Shapiro 
15706f25ae9SGregory Neil Shapiro 	if (db1 != NULL)
15806f25ae9SGregory Neil Shapiro 	{
15906f25ae9SGregory Neil Shapiro 		db1->smdb1_lock_fd = -1;
16040266059SGregory Neil Shapiro 		db1->smdb1_cursor_in_use = false;
16106f25ae9SGregory Neil Shapiro 	}
16206f25ae9SGregory Neil Shapiro 
16306f25ae9SGregory Neil Shapiro 	return db1;
16406f25ae9SGregory Neil Shapiro }
16506f25ae9SGregory Neil Shapiro 
166b6bacd31SGregory Neil Shapiro static int
smdb1_close(database)16706f25ae9SGregory Neil Shapiro smdb1_close(database)
16806f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
16906f25ae9SGregory Neil Shapiro {
17040266059SGregory Neil Shapiro 	int result;
17106f25ae9SGregory Neil Shapiro 	SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
17206f25ae9SGregory Neil Shapiro 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
17306f25ae9SGregory Neil Shapiro 
17440266059SGregory Neil Shapiro 	result = db->close(db);
17506f25ae9SGregory Neil Shapiro 	if (db1->smdb1_lock_fd != -1)
17606f25ae9SGregory Neil Shapiro 		(void) close(db1->smdb1_lock_fd);
17706f25ae9SGregory Neil Shapiro 
17806f25ae9SGregory Neil Shapiro 	free(db1);
17906f25ae9SGregory Neil Shapiro 	database->smdb_impl = NULL;
18006f25ae9SGregory Neil Shapiro 
18140266059SGregory Neil Shapiro 	return result;
18206f25ae9SGregory Neil Shapiro }
18306f25ae9SGregory Neil Shapiro 
184b6bacd31SGregory Neil Shapiro static int
smdb1_del(database,key,flags)18506f25ae9SGregory Neil Shapiro smdb1_del(database, key, flags)
18606f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
18706f25ae9SGregory Neil Shapiro 	SMDB_DBENT *key;
18840266059SGregory Neil Shapiro 	unsigned int flags;
18906f25ae9SGregory Neil Shapiro {
19006f25ae9SGregory Neil Shapiro 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
191193538b7SGregory Neil Shapiro 	DBT dbkey;
19206f25ae9SGregory Neil Shapiro 
19340266059SGregory Neil Shapiro 	(void) memset(&dbkey, '\0', sizeof dbkey);
194193538b7SGregory Neil Shapiro 	dbkey.data = key->data;
195193538b7SGregory Neil Shapiro 	dbkey.size = key->size;
196193538b7SGregory Neil Shapiro 	return db->del(db, &dbkey, flags);
19706f25ae9SGregory Neil Shapiro }
19806f25ae9SGregory Neil Shapiro 
199b6bacd31SGregory Neil Shapiro static int
smdb1_fd(database,fd)20006f25ae9SGregory Neil Shapiro smdb1_fd(database, fd)
20106f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
20206f25ae9SGregory Neil Shapiro 	int *fd;
20306f25ae9SGregory Neil Shapiro {
20406f25ae9SGregory Neil Shapiro 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
20506f25ae9SGregory Neil Shapiro 
20606f25ae9SGregory Neil Shapiro 	*fd = db->fd(db);
20706f25ae9SGregory Neil Shapiro 	if (*fd == -1)
20806f25ae9SGregory Neil Shapiro 		return errno;
20906f25ae9SGregory Neil Shapiro 
21006f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
21106f25ae9SGregory Neil Shapiro }
21206f25ae9SGregory Neil Shapiro 
213b6bacd31SGregory Neil Shapiro static int
smdb1_lockfd(database)21442e5d165SGregory Neil Shapiro smdb1_lockfd(database)
21542e5d165SGregory Neil Shapiro 	SMDB_DATABASE *database;
21642e5d165SGregory Neil Shapiro {
21742e5d165SGregory Neil Shapiro 	SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
21842e5d165SGregory Neil Shapiro 
21942e5d165SGregory Neil Shapiro 	return db1->smdb1_lock_fd;
22042e5d165SGregory Neil Shapiro }
22142e5d165SGregory Neil Shapiro 
22242e5d165SGregory Neil Shapiro 
223b6bacd31SGregory Neil Shapiro static int
smdb1_get(database,key,data,flags)22406f25ae9SGregory Neil Shapiro smdb1_get(database, key, data, flags)
22506f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
22606f25ae9SGregory Neil Shapiro 	SMDB_DBENT *key;
22706f25ae9SGregory Neil Shapiro 	SMDB_DBENT *data;
22840266059SGregory Neil Shapiro 	unsigned int flags;
22906f25ae9SGregory Neil Shapiro {
23006f25ae9SGregory Neil Shapiro 	int result;
23106f25ae9SGregory Neil Shapiro 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
232193538b7SGregory Neil Shapiro 	DBT dbkey, dbdata;
23306f25ae9SGregory Neil Shapiro 
23440266059SGregory Neil Shapiro 	(void) memset(&dbdata, '\0', sizeof dbdata);
23540266059SGregory Neil Shapiro 	(void) memset(&dbkey, '\0', sizeof dbkey);
236193538b7SGregory Neil Shapiro 	dbkey.data = key->data;
237193538b7SGregory Neil Shapiro 	dbkey.size = key->size;
238193538b7SGregory Neil Shapiro 
239193538b7SGregory Neil Shapiro 	result = db->get(db, &dbkey, &dbdata, flags);
24006f25ae9SGregory Neil Shapiro 	if (result != 0)
24106f25ae9SGregory Neil Shapiro 	{
24206f25ae9SGregory Neil Shapiro 		if (result == 1)
24306f25ae9SGregory Neil Shapiro 			return SMDBE_NOT_FOUND;
24406f25ae9SGregory Neil Shapiro 		return errno;
24506f25ae9SGregory Neil Shapiro 	}
246193538b7SGregory Neil Shapiro 	data->data = dbdata.data;
247193538b7SGregory Neil Shapiro 	data->size = dbdata.size;
24806f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
24906f25ae9SGregory Neil Shapiro }
25006f25ae9SGregory Neil Shapiro 
251b6bacd31SGregory Neil Shapiro static int
smdb1_put(database,key,data,flags)25206f25ae9SGregory Neil Shapiro smdb1_put(database, key, data, flags)
25306f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
25406f25ae9SGregory Neil Shapiro 	SMDB_DBENT *key;
25506f25ae9SGregory Neil Shapiro 	SMDB_DBENT *data;
25640266059SGregory Neil Shapiro 	unsigned int flags;
25706f25ae9SGregory Neil Shapiro {
25806f25ae9SGregory Neil Shapiro 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
259193538b7SGregory Neil Shapiro 	DBT dbkey, dbdata;
26006f25ae9SGregory Neil Shapiro 
26140266059SGregory Neil Shapiro 	(void) memset(&dbdata, '\0', sizeof dbdata);
26240266059SGregory Neil Shapiro 	(void) memset(&dbkey, '\0', sizeof dbkey);
263193538b7SGregory Neil Shapiro 	dbkey.data = key->data;
264193538b7SGregory Neil Shapiro 	dbkey.size = key->size;
265193538b7SGregory Neil Shapiro 	dbdata.data = data->data;
266193538b7SGregory Neil Shapiro 	dbdata.size = data->size;
267193538b7SGregory Neil Shapiro 
268193538b7SGregory Neil Shapiro 	return db->put(db, &dbkey, &dbdata,
26906f25ae9SGregory Neil Shapiro 		       smdb_put_flags_to_db1_flags(flags));
27006f25ae9SGregory Neil Shapiro }
27106f25ae9SGregory Neil Shapiro 
272b6bacd31SGregory Neil Shapiro static int
smdb1_set_owner(database,uid,gid)27306f25ae9SGregory Neil Shapiro smdb1_set_owner(database, uid, gid)
27406f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
27506f25ae9SGregory Neil Shapiro 	uid_t uid;
27606f25ae9SGregory Neil Shapiro 	gid_t gid;
27706f25ae9SGregory Neil Shapiro {
27806f25ae9SGregory Neil Shapiro # if HASFCHOWN
27906f25ae9SGregory Neil Shapiro 	int fd;
28006f25ae9SGregory Neil Shapiro 	int result;
28106f25ae9SGregory Neil Shapiro 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
28206f25ae9SGregory Neil Shapiro 
28306f25ae9SGregory Neil Shapiro 	fd = db->fd(db);
28406f25ae9SGregory Neil Shapiro 	if (fd == -1)
28506f25ae9SGregory Neil Shapiro 		return errno;
28606f25ae9SGregory Neil Shapiro 
28706f25ae9SGregory Neil Shapiro 	result = fchown(fd, uid, gid);
28806f25ae9SGregory Neil Shapiro 	if (result < 0)
28906f25ae9SGregory Neil Shapiro 		return errno;
29006f25ae9SGregory Neil Shapiro # endif /* HASFCHOWN */
29106f25ae9SGregory Neil Shapiro 
29206f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
29306f25ae9SGregory Neil Shapiro }
29406f25ae9SGregory Neil Shapiro 
295b6bacd31SGregory Neil Shapiro static int
smdb1_sync(database,flags)29606f25ae9SGregory Neil Shapiro smdb1_sync(database, flags)
29706f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
29840266059SGregory Neil Shapiro 	unsigned int flags;
29906f25ae9SGregory Neil Shapiro {
30006f25ae9SGregory Neil Shapiro 	DB *db = ((SMDB_DB1_DATABASE *) database->smdb_impl)->smdb1_db;
30106f25ae9SGregory Neil Shapiro 
30206f25ae9SGregory Neil Shapiro 	return db->sync(db, flags);
30306f25ae9SGregory Neil Shapiro }
30406f25ae9SGregory Neil Shapiro 
305b6bacd31SGregory Neil Shapiro static int
smdb1_cursor_close(cursor)30606f25ae9SGregory Neil Shapiro smdb1_cursor_close(cursor)
30706f25ae9SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
30806f25ae9SGregory Neil Shapiro {
30906f25ae9SGregory Neil Shapiro 	SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
31006f25ae9SGregory Neil Shapiro 	SMDB_DB1_DATABASE *db1 = db1_cursor->db;
31106f25ae9SGregory Neil Shapiro 
31206f25ae9SGregory Neil Shapiro 	if (!db1->smdb1_cursor_in_use)
31306f25ae9SGregory Neil Shapiro 		return SMDBE_NOT_A_VALID_CURSOR;
31406f25ae9SGregory Neil Shapiro 
31540266059SGregory Neil Shapiro 	db1->smdb1_cursor_in_use = false;
31606f25ae9SGregory Neil Shapiro 	free(cursor);
31706f25ae9SGregory Neil Shapiro 
31806f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
31906f25ae9SGregory Neil Shapiro }
32006f25ae9SGregory Neil Shapiro 
321b6bacd31SGregory Neil Shapiro static int
smdb1_cursor_del(cursor,flags)32206f25ae9SGregory Neil Shapiro smdb1_cursor_del(cursor, flags)
32306f25ae9SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
32440266059SGregory Neil Shapiro 	unsigned int flags;
32506f25ae9SGregory Neil Shapiro {
32606f25ae9SGregory Neil Shapiro 	SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
32706f25ae9SGregory Neil Shapiro 	SMDB_DB1_DATABASE *db1 = db1_cursor->db;
32806f25ae9SGregory Neil Shapiro 	DB *db = db1->smdb1_db;
32906f25ae9SGregory Neil Shapiro 
33006f25ae9SGregory Neil Shapiro 	return db->del(db, NULL, R_CURSOR);
33106f25ae9SGregory Neil Shapiro }
33206f25ae9SGregory Neil Shapiro 
333b6bacd31SGregory Neil Shapiro static int
smdb1_cursor_get(cursor,key,value,flags)33406f25ae9SGregory Neil Shapiro smdb1_cursor_get(cursor, key, value, flags)
33506f25ae9SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
33606f25ae9SGregory Neil Shapiro 	SMDB_DBENT *key;
33706f25ae9SGregory Neil Shapiro 	SMDB_DBENT *value;
33806f25ae9SGregory Neil Shapiro 	SMDB_FLAG flags;
33906f25ae9SGregory Neil Shapiro {
34006f25ae9SGregory Neil Shapiro 	int db1_flags;
34106f25ae9SGregory Neil Shapiro 	int result;
34206f25ae9SGregory Neil Shapiro 	SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
34306f25ae9SGregory Neil Shapiro 	SMDB_DB1_DATABASE *db1 = db1_cursor->db;
34406f25ae9SGregory Neil Shapiro 	DB *db = db1->smdb1_db;
345193538b7SGregory Neil Shapiro 	DBT dbkey, dbdata;
346193538b7SGregory Neil Shapiro 
34740266059SGregory Neil Shapiro 	(void) memset(&dbdata, '\0', sizeof dbdata);
34840266059SGregory Neil Shapiro 	(void) memset(&dbkey, '\0', sizeof dbkey);
34906f25ae9SGregory Neil Shapiro 
35006f25ae9SGregory Neil Shapiro 	db1_flags = smdb_cursor_get_flags_to_smdb1(flags);
351193538b7SGregory Neil Shapiro 	result = db->seq(db, &dbkey, &dbdata, db1_flags);
35206f25ae9SGregory Neil Shapiro 	if (result == -1)
35306f25ae9SGregory Neil Shapiro 		return errno;
35406f25ae9SGregory Neil Shapiro 	if (result == 1)
35506f25ae9SGregory Neil Shapiro 		return SMDBE_LAST_ENTRY;
356193538b7SGregory Neil Shapiro 	value->data = dbdata.data;
357193538b7SGregory Neil Shapiro 	value->size = dbdata.size;
358193538b7SGregory Neil Shapiro 	key->data = dbkey.data;
359193538b7SGregory Neil Shapiro 	key->size = dbkey.size;
36006f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
36106f25ae9SGregory Neil Shapiro }
36206f25ae9SGregory Neil Shapiro 
363b6bacd31SGregory Neil Shapiro static int
smdb1_cursor_put(cursor,key,value,flags)36406f25ae9SGregory Neil Shapiro smdb1_cursor_put(cursor, key, value, flags)
36506f25ae9SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
36606f25ae9SGregory Neil Shapiro 	SMDB_DBENT *key;
36706f25ae9SGregory Neil Shapiro 	SMDB_DBENT *value;
36806f25ae9SGregory Neil Shapiro 	SMDB_FLAG flags;
36906f25ae9SGregory Neil Shapiro {
37006f25ae9SGregory Neil Shapiro 	SMDB_DB1_CURSOR *db1_cursor = (SMDB_DB1_CURSOR *) cursor->smdbc_impl;
37106f25ae9SGregory Neil Shapiro 	SMDB_DB1_DATABASE *db1 = db1_cursor->db;
37206f25ae9SGregory Neil Shapiro 	DB *db = db1->smdb1_db;
373193538b7SGregory Neil Shapiro 	DBT dbkey, dbdata;
37406f25ae9SGregory Neil Shapiro 
37540266059SGregory Neil Shapiro 	(void) memset(&dbdata, '\0', sizeof dbdata);
37640266059SGregory Neil Shapiro 	(void) memset(&dbkey, '\0', sizeof dbkey);
377193538b7SGregory Neil Shapiro 	dbkey.data = key->data;
378193538b7SGregory Neil Shapiro 	dbkey.size = key->size;
379193538b7SGregory Neil Shapiro 	dbdata.data = value->data;
380193538b7SGregory Neil Shapiro 	dbdata.size = value->size;
381193538b7SGregory Neil Shapiro 
382193538b7SGregory Neil Shapiro 	return db->put(db, &dbkey, &dbdata, R_CURSOR);
38306f25ae9SGregory Neil Shapiro }
38406f25ae9SGregory Neil Shapiro 
385b6bacd31SGregory Neil Shapiro static int
smdb1_cursor(database,cursor,flags)38606f25ae9SGregory Neil Shapiro smdb1_cursor(database, cursor, flags)
38706f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
38806f25ae9SGregory Neil Shapiro 	SMDB_CURSOR **cursor;
38940266059SGregory Neil Shapiro 	unsigned int flags;
39006f25ae9SGregory Neil Shapiro {
39106f25ae9SGregory Neil Shapiro 	SMDB_DB1_DATABASE *db1 = (SMDB_DB1_DATABASE *) database->smdb_impl;
39206f25ae9SGregory Neil Shapiro 	SMDB_CURSOR *cur;
39306f25ae9SGregory Neil Shapiro 	SMDB_DB1_CURSOR *db1_cursor;
39406f25ae9SGregory Neil Shapiro 
39506f25ae9SGregory Neil Shapiro 	if (db1->smdb1_cursor_in_use)
39606f25ae9SGregory Neil Shapiro 		return SMDBE_ONLY_SUPPORTS_ONE_CURSOR;
39706f25ae9SGregory Neil Shapiro 
39806f25ae9SGregory Neil Shapiro 	db1_cursor = (SMDB_DB1_CURSOR *) malloc(sizeof(SMDB_DB1_CURSOR));
3999bd497b8SGregory Neil Shapiro 	if (db1_cursor == NULL)
40006f25ae9SGregory Neil Shapiro 		return SMDBE_MALLOC;
40106f25ae9SGregory Neil Shapiro 
4029bd497b8SGregory Neil Shapiro 	cur = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR));
4039bd497b8SGregory Neil Shapiro 	if (cur == NULL)
4049bd497b8SGregory Neil Shapiro 	{
4059bd497b8SGregory Neil Shapiro 		free(db1_cursor);
4069bd497b8SGregory Neil Shapiro 		return SMDBE_MALLOC;
4079bd497b8SGregory Neil Shapiro 	}
4089bd497b8SGregory Neil Shapiro 
4099bd497b8SGregory Neil Shapiro 	db1->smdb1_cursor_in_use = true;
4109bd497b8SGregory Neil Shapiro 	db1_cursor->db = db1;
41106f25ae9SGregory Neil Shapiro 	cur->smdbc_impl = db1_cursor;
41206f25ae9SGregory Neil Shapiro 	cur->smdbc_close = smdb1_cursor_close;
41306f25ae9SGregory Neil Shapiro 	cur->smdbc_del = smdb1_cursor_del;
41406f25ae9SGregory Neil Shapiro 	cur->smdbc_get = smdb1_cursor_get;
41506f25ae9SGregory Neil Shapiro 	cur->smdbc_put = smdb1_cursor_put;
41606f25ae9SGregory Neil Shapiro 	*cursor = cur;
41706f25ae9SGregory Neil Shapiro 
41806f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
41906f25ae9SGregory Neil Shapiro }
42040266059SGregory Neil Shapiro /*
42106f25ae9SGregory Neil Shapiro **  SMDB_DB_OPEN -- Opens a db1 database.
42206f25ae9SGregory Neil Shapiro **
42306f25ae9SGregory Neil Shapiro **	Parameters:
42406f25ae9SGregory Neil Shapiro **		database -- An unallocated database pointer to a pointer.
42506f25ae9SGregory Neil Shapiro **		db_name -- The name of the database without extension.
426*d39bd2c1SGregory Neil Shapiro **		mode -- File permissions on the database if created.
42706f25ae9SGregory Neil Shapiro **		mode_mask -- Mode bits that must match on an existing database.
42806f25ae9SGregory Neil Shapiro **		sff -- Flags for safefile.
42906f25ae9SGregory Neil Shapiro **		type -- The type of database to open
43006f25ae9SGregory Neil Shapiro **			See smdb_type_to_db1_type for valid types.
43106f25ae9SGregory Neil Shapiro **		user_info -- Information on the user to use for file
43206f25ae9SGregory Neil Shapiro **			    permissions.
43306f25ae9SGregory Neil Shapiro **		db_params --
43406f25ae9SGregory Neil Shapiro **			An SMDB_DBPARAMS struct including params. These
43506f25ae9SGregory Neil Shapiro **			are processed according to the type of the
43606f25ae9SGregory Neil Shapiro **			database. Currently supported params (only for
43706f25ae9SGregory Neil Shapiro **			HASH type) are:
43806f25ae9SGregory Neil Shapiro **			   num_elements
43906f25ae9SGregory Neil Shapiro **			   cache_size
44006f25ae9SGregory Neil Shapiro **
44106f25ae9SGregory Neil Shapiro **	Returns:
44206f25ae9SGregory Neil Shapiro **		SMDBE_OK -- Success, otherwise errno.
44306f25ae9SGregory Neil Shapiro */
44406f25ae9SGregory Neil Shapiro 
44506f25ae9SGregory Neil Shapiro int
smdb_db_open(database,db_name,mode,mode_mask,sff,type,user_info,db_params)44606f25ae9SGregory Neil Shapiro smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info,
44706f25ae9SGregory Neil Shapiro 	     db_params)
44806f25ae9SGregory Neil Shapiro 	SMDB_DATABASE **database;
44906f25ae9SGregory Neil Shapiro 	char *db_name;
45006f25ae9SGregory Neil Shapiro 	int mode;
45106f25ae9SGregory Neil Shapiro 	int mode_mask;
45206f25ae9SGregory Neil Shapiro 	long sff;
45306f25ae9SGregory Neil Shapiro 	SMDB_DBTYPE type;
45406f25ae9SGregory Neil Shapiro 	SMDB_USER_INFO *user_info;
45506f25ae9SGregory Neil Shapiro 	SMDB_DBPARAMS *db_params;
45606f25ae9SGregory Neil Shapiro {
457605302a5SGregory Neil Shapiro 	bool lockcreated = false;
45806f25ae9SGregory Neil Shapiro 	int db_fd;
45906f25ae9SGregory Neil Shapiro 	int lock_fd;
46006f25ae9SGregory Neil Shapiro 	int result;
46106f25ae9SGregory Neil Shapiro 	void *params;
46206f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *smdb_db;
46306f25ae9SGregory Neil Shapiro 	SMDB_DB1_DATABASE *db1;
46406f25ae9SGregory Neil Shapiro 	DB *db;
46506f25ae9SGregory Neil Shapiro 	HASHINFO hash_info;
46606f25ae9SGregory Neil Shapiro 	BTREEINFO btree_info;
46706f25ae9SGregory Neil Shapiro 	DBTYPE db_type;
46806f25ae9SGregory Neil Shapiro 	struct stat stat_info;
46994c01205SGregory Neil Shapiro 	char db_file_name[MAXPATHLEN];
47006f25ae9SGregory Neil Shapiro 
47106f25ae9SGregory Neil Shapiro 	if (type == NULL ||
4725b0945b5SGregory Neil Shapiro 	    (!SMDB_IS_TYPE_HASH(type) && !SMDB_IS_TYPE_BTREE(type)
4735b0945b5SGregory Neil Shapiro 	     ))
47406f25ae9SGregory Neil Shapiro 		return SMDBE_UNKNOWN_DB_TYPE;
47506f25ae9SGregory Neil Shapiro 
47694c01205SGregory Neil Shapiro 	result = smdb_add_extension(db_file_name, sizeof db_file_name,
47706f25ae9SGregory Neil Shapiro 				    db_name, SMDB1_FILE_EXTENSION);
47806f25ae9SGregory Neil Shapiro 	if (result != SMDBE_OK)
47906f25ae9SGregory Neil Shapiro 		return result;
48006f25ae9SGregory Neil Shapiro 
48106f25ae9SGregory Neil Shapiro 	result = smdb_setup_file(db_name, SMDB1_FILE_EXTENSION, mode_mask,
48206f25ae9SGregory Neil Shapiro 				 sff, user_info, &stat_info);
48306f25ae9SGregory Neil Shapiro 	if (result != SMDBE_OK)
48406f25ae9SGregory Neil Shapiro 		return result;
48506f25ae9SGregory Neil Shapiro 
486605302a5SGregory Neil Shapiro 	if (stat_info.st_mode == ST_MODE_NOFILE &&
487605302a5SGregory Neil Shapiro 	    bitset(mode, O_CREAT))
488605302a5SGregory Neil Shapiro 		lockcreated = true;
489605302a5SGregory Neil Shapiro 
49006f25ae9SGregory Neil Shapiro 	lock_fd = -1;
49106f25ae9SGregory Neil Shapiro 	result = smdb_lock_file(&lock_fd, db_name, mode, sff,
49206f25ae9SGregory Neil Shapiro 				SMDB1_FILE_EXTENSION);
49306f25ae9SGregory Neil Shapiro 	if (result != SMDBE_OK)
49406f25ae9SGregory Neil Shapiro 		return result;
495605302a5SGregory Neil Shapiro 
496605302a5SGregory Neil Shapiro 	if (lockcreated)
497605302a5SGregory Neil Shapiro 	{
498605302a5SGregory Neil Shapiro 		mode |= O_TRUNC;
499605302a5SGregory Neil Shapiro 		mode &= ~(O_CREAT|O_EXCL);
500605302a5SGregory Neil Shapiro 	}
50106f25ae9SGregory Neil Shapiro 
50206f25ae9SGregory Neil Shapiro 	*database = NULL;
50306f25ae9SGregory Neil Shapiro 
50406f25ae9SGregory Neil Shapiro 	smdb_db = smdb_malloc_database();
50506f25ae9SGregory Neil Shapiro 	db1 = smdb1_malloc_database();
50606f25ae9SGregory Neil Shapiro 	if (smdb_db == NULL || db1 == NULL)
5079bd497b8SGregory Neil Shapiro 	{
5089bd497b8SGregory Neil Shapiro 		(void) smdb_unlock_file(lock_fd);
5099bd497b8SGregory Neil Shapiro 		smdb_free_database(smdb_db);
5109bd497b8SGregory Neil Shapiro 		free(db1);
51106f25ae9SGregory Neil Shapiro 		return SMDBE_MALLOC;
5129bd497b8SGregory Neil Shapiro 	}
51306f25ae9SGregory Neil Shapiro 	db1->smdb1_lock_fd = lock_fd;
51406f25ae9SGregory Neil Shapiro 
51506f25ae9SGregory Neil Shapiro 	params = NULL;
5165b0945b5SGregory Neil Shapiro 	if (db_params != NULL && SMDB_IS_TYPE_HASH(type))
51706f25ae9SGregory Neil Shapiro 	{
51840266059SGregory Neil Shapiro 		(void) memset(&hash_info, '\0', sizeof hash_info);
51906f25ae9SGregory Neil Shapiro 		hash_info.nelem = db_params->smdbp_num_elements;
52006f25ae9SGregory Neil Shapiro 		hash_info.cachesize = db_params->smdbp_cache_size;
52106f25ae9SGregory Neil Shapiro 		params = &hash_info;
52206f25ae9SGregory Neil Shapiro 	}
52306f25ae9SGregory Neil Shapiro 
5245b0945b5SGregory Neil Shapiro 	if (db_params != NULL && SMDB_IS_TYPE_BTREE(type))
52506f25ae9SGregory Neil Shapiro 	{
52640266059SGregory Neil Shapiro 		(void) memset(&btree_info, '\0', sizeof btree_info);
52706f25ae9SGregory Neil Shapiro 		btree_info.cachesize = db_params->smdbp_cache_size;
52806f25ae9SGregory Neil Shapiro 		if (db_params->smdbp_allow_dup)
52906f25ae9SGregory Neil Shapiro 			btree_info.flags |= R_DUP;
53006f25ae9SGregory Neil Shapiro 		params = &btree_info;
53106f25ae9SGregory Neil Shapiro 	}
53206f25ae9SGregory Neil Shapiro 
53306f25ae9SGregory Neil Shapiro 	db_type = smdb_type_to_db1_type(type);
53494c01205SGregory Neil Shapiro 	db = dbopen(db_file_name, mode, DBMMODE, db_type, params);
53506f25ae9SGregory Neil Shapiro 	if (db != NULL)
53606f25ae9SGregory Neil Shapiro 	{
53706f25ae9SGregory Neil Shapiro 		db_fd = db->fd(db);
53806f25ae9SGregory Neil Shapiro 		result = smdb_filechanged(db_name, SMDB1_FILE_EXTENSION, db_fd,
53906f25ae9SGregory Neil Shapiro 					  &stat_info);
54006f25ae9SGregory Neil Shapiro 	}
54106f25ae9SGregory Neil Shapiro 	else
54206f25ae9SGregory Neil Shapiro 	{
54306f25ae9SGregory Neil Shapiro 		if (errno == 0)
54406f25ae9SGregory Neil Shapiro 			result = SMDBE_BAD_OPEN;
54506f25ae9SGregory Neil Shapiro 		else
54606f25ae9SGregory Neil Shapiro 			result = errno;
54706f25ae9SGregory Neil Shapiro 	}
54806f25ae9SGregory Neil Shapiro 
54906f25ae9SGregory Neil Shapiro 	if (result == SMDBE_OK)
55006f25ae9SGregory Neil Shapiro 	{
55106f25ae9SGregory Neil Shapiro 		/* Everything is ok. Setup driver */
55206f25ae9SGregory Neil Shapiro 		db1->smdb1_db = db;
55306f25ae9SGregory Neil Shapiro 
55406f25ae9SGregory Neil Shapiro 		smdb_db->smdb_close = smdb1_close;
55506f25ae9SGregory Neil Shapiro 		smdb_db->smdb_del = smdb1_del;
55606f25ae9SGregory Neil Shapiro 		smdb_db->smdb_fd = smdb1_fd;
55742e5d165SGregory Neil Shapiro 		smdb_db->smdb_lockfd = smdb1_lockfd;
55806f25ae9SGregory Neil Shapiro 		smdb_db->smdb_get = smdb1_get;
55906f25ae9SGregory Neil Shapiro 		smdb_db->smdb_put = smdb1_put;
56006f25ae9SGregory Neil Shapiro 		smdb_db->smdb_set_owner = smdb1_set_owner;
56106f25ae9SGregory Neil Shapiro 		smdb_db->smdb_sync = smdb1_sync;
56206f25ae9SGregory Neil Shapiro 		smdb_db->smdb_cursor = smdb1_cursor;
56306f25ae9SGregory Neil Shapiro 		smdb_db->smdb_impl = db1;
56406f25ae9SGregory Neil Shapiro 
56506f25ae9SGregory Neil Shapiro 		*database = smdb_db;
56606f25ae9SGregory Neil Shapiro 		return SMDBE_OK;
56706f25ae9SGregory Neil Shapiro 	}
56806f25ae9SGregory Neil Shapiro 
56906f25ae9SGregory Neil Shapiro 	if (db != NULL)
57006f25ae9SGregory Neil Shapiro 		(void) db->close(db);
57106f25ae9SGregory Neil Shapiro 
57206f25ae9SGregory Neil Shapiro 	/* Error opening database */
57306f25ae9SGregory Neil Shapiro 	(void) smdb_unlock_file(db1->smdb1_lock_fd);
57406f25ae9SGregory Neil Shapiro 	free(db1);
57506f25ae9SGregory Neil Shapiro 	smdb_free_database(smdb_db);
57606f25ae9SGregory Neil Shapiro 
57706f25ae9SGregory Neil Shapiro 	return result;
57806f25ae9SGregory Neil Shapiro }
57906f25ae9SGregory Neil Shapiro 
58006f25ae9SGregory Neil Shapiro #endif /* (DB_VERSION_MAJOR == 1) */
581