xref: /freebsd/contrib/sendmail/libsmdb/smndbm.c (revision d39bd2c1388b520fcba9abed1932acacead60fba)
106f25ae9SGregory Neil Shapiro /*
25dd76dd0SGregory Neil Shapiro ** Copyright (c) 1999-2002 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: smndbm.c,v 8.55 2013-11-22 20:51:49 ca Exp $")
1206f25ae9SGregory Neil Shapiro 
1306f25ae9SGregory Neil Shapiro #include <fcntl.h>
1406f25ae9SGregory Neil Shapiro #include <stdlib.h>
1506f25ae9SGregory Neil Shapiro #include <unistd.h>
1606f25ae9SGregory Neil Shapiro 
1706f25ae9SGregory Neil Shapiro #include <sendmail/sendmail.h>
1806f25ae9SGregory Neil Shapiro #include <libsmdb/smdb.h>
1906f25ae9SGregory Neil Shapiro 
20*d39bd2c1SGregory Neil Shapiro #if NDBM
2106f25ae9SGregory Neil Shapiro 
2206f25ae9SGregory Neil Shapiro # define SMNDB_PAG_FILE_EXTENSION "pag"
2306f25ae9SGregory Neil Shapiro 
2406f25ae9SGregory Neil Shapiro struct smdb_dbm_database_struct
2506f25ae9SGregory Neil Shapiro {
2606f25ae9SGregory Neil Shapiro 	DBM	*smndbm_dbm;
2706f25ae9SGregory Neil Shapiro 	int	smndbm_lock_fd;
2806f25ae9SGregory Neil Shapiro 	bool	smndbm_cursor_in_use;
2906f25ae9SGregory Neil Shapiro };
3006f25ae9SGregory Neil Shapiro typedef struct smdb_dbm_database_struct SMDB_DBM_DATABASE;
3106f25ae9SGregory Neil Shapiro 
3206f25ae9SGregory Neil Shapiro struct smdb_dbm_cursor_struct
3306f25ae9SGregory Neil Shapiro {
3406f25ae9SGregory Neil Shapiro 	SMDB_DBM_DATABASE	*smndbmc_db;
3506f25ae9SGregory Neil Shapiro 	datum			smndbmc_current_key;
3606f25ae9SGregory Neil Shapiro };
3706f25ae9SGregory Neil Shapiro typedef struct smdb_dbm_cursor_struct SMDB_DBM_CURSOR;
3806f25ae9SGregory Neil Shapiro 
3940266059SGregory Neil Shapiro /*
4006f25ae9SGregory Neil Shapiro **  SMDB_PUT_FLAGS_TO_NDBM_FLAGS -- Translates smdb put flags to ndbm put flags.
4106f25ae9SGregory Neil Shapiro **
4206f25ae9SGregory Neil Shapiro **	Parameters:
4306f25ae9SGregory Neil Shapiro **		flags -- The flags to translate.
4406f25ae9SGregory Neil Shapiro **
4506f25ae9SGregory Neil Shapiro **	Returns:
4606f25ae9SGregory Neil Shapiro **		The ndbm flags that are equivalent to the smdb flags.
4706f25ae9SGregory Neil Shapiro **
4806f25ae9SGregory Neil Shapiro **	Notes:
4906f25ae9SGregory Neil Shapiro **		Any invalid flags are ignored.
5006f25ae9SGregory Neil Shapiro **
5106f25ae9SGregory Neil Shapiro */
5206f25ae9SGregory Neil Shapiro 
5306f25ae9SGregory Neil Shapiro int
smdb_put_flags_to_ndbm_flags(flags)5406f25ae9SGregory Neil Shapiro smdb_put_flags_to_ndbm_flags(flags)
5506f25ae9SGregory Neil Shapiro 	SMDB_FLAG flags;
5606f25ae9SGregory Neil Shapiro {
5706f25ae9SGregory Neil Shapiro 	int return_flags;
5806f25ae9SGregory Neil Shapiro 
5906f25ae9SGregory Neil Shapiro 	return_flags = 0;
6006f25ae9SGregory Neil Shapiro 	if (bitset(SMDBF_NO_OVERWRITE, flags))
6106f25ae9SGregory Neil Shapiro 		return_flags = DBM_INSERT;
6206f25ae9SGregory Neil Shapiro 	else
6306f25ae9SGregory Neil Shapiro 		return_flags = DBM_REPLACE;
6406f25ae9SGregory Neil Shapiro 
6506f25ae9SGregory Neil Shapiro 	return return_flags;
6606f25ae9SGregory Neil Shapiro }
6706f25ae9SGregory Neil Shapiro 
6840266059SGregory Neil Shapiro /*
6940266059SGregory Neil Shapiro **  Except for smdb_ndbm_open, the rest of these function correspond to the
7040266059SGregory Neil Shapiro **  interface laid out in smdb.h.
7106f25ae9SGregory Neil Shapiro */
7206f25ae9SGregory Neil Shapiro 
7306f25ae9SGregory Neil Shapiro SMDB_DBM_DATABASE *
smdbm_malloc_database()7406f25ae9SGregory Neil Shapiro smdbm_malloc_database()
7506f25ae9SGregory Neil Shapiro {
7606f25ae9SGregory Neil Shapiro 	SMDB_DBM_DATABASE *db;
7706f25ae9SGregory Neil Shapiro 
7806f25ae9SGregory Neil Shapiro 	db = (SMDB_DBM_DATABASE *) malloc(sizeof(SMDB_DBM_DATABASE));
7906f25ae9SGregory Neil Shapiro 	if (db != NULL)
8006f25ae9SGregory Neil Shapiro 	{
8106f25ae9SGregory Neil Shapiro 		db->smndbm_dbm = NULL;
8206f25ae9SGregory Neil Shapiro 		db->smndbm_lock_fd = -1;
8340266059SGregory Neil Shapiro 		db->smndbm_cursor_in_use = false;
8406f25ae9SGregory Neil Shapiro 	}
8506f25ae9SGregory Neil Shapiro 
8606f25ae9SGregory Neil Shapiro 	return db;
8706f25ae9SGregory Neil Shapiro }
8806f25ae9SGregory Neil Shapiro 
8906f25ae9SGregory Neil Shapiro int
smdbm_close(database)9006f25ae9SGregory Neil Shapiro smdbm_close(database)
9106f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
9206f25ae9SGregory Neil Shapiro {
9306f25ae9SGregory Neil Shapiro 	SMDB_DBM_DATABASE *db = (SMDB_DBM_DATABASE *) database->smdb_impl;
9406f25ae9SGregory Neil Shapiro 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
9506f25ae9SGregory Neil Shapiro 
9606f25ae9SGregory Neil Shapiro 	dbm_close(dbm);
9706f25ae9SGregory Neil Shapiro 	if (db->smndbm_lock_fd != -1)
9806f25ae9SGregory Neil Shapiro 		close(db->smndbm_lock_fd);
9906f25ae9SGregory Neil Shapiro 
10006f25ae9SGregory Neil Shapiro 	free(db);
10106f25ae9SGregory Neil Shapiro 	database->smdb_impl = NULL;
10206f25ae9SGregory Neil Shapiro 
10306f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
10406f25ae9SGregory Neil Shapiro }
10506f25ae9SGregory Neil Shapiro 
10606f25ae9SGregory Neil Shapiro int
smdbm_del(database,key,flags)10706f25ae9SGregory Neil Shapiro smdbm_del(database, key, flags)
10806f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
10906f25ae9SGregory Neil Shapiro 	SMDB_DBENT *key;
11040266059SGregory Neil Shapiro 	unsigned int flags;
11106f25ae9SGregory Neil Shapiro {
11206f25ae9SGregory Neil Shapiro 	int result;
11306f25ae9SGregory Neil Shapiro 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
114193538b7SGregory Neil Shapiro 	datum dbkey;
115193538b7SGregory Neil Shapiro 
11640266059SGregory Neil Shapiro 	(void) memset(&dbkey, '\0', sizeof dbkey);
117193538b7SGregory Neil Shapiro 	dbkey.dptr = key->data;
118193538b7SGregory Neil Shapiro 	dbkey.dsize = key->size;
11906f25ae9SGregory Neil Shapiro 
12006f25ae9SGregory Neil Shapiro 	errno = 0;
121193538b7SGregory Neil Shapiro 	result = dbm_delete(dbm, dbkey);
12206f25ae9SGregory Neil Shapiro 	if (result != 0)
12306f25ae9SGregory Neil Shapiro 	{
12406f25ae9SGregory Neil Shapiro 		int save_errno = errno;
12506f25ae9SGregory Neil Shapiro 
12606f25ae9SGregory Neil Shapiro 		if (dbm_error(dbm))
12706f25ae9SGregory Neil Shapiro 			return SMDBE_IO_ERROR;
12806f25ae9SGregory Neil Shapiro 
12906f25ae9SGregory Neil Shapiro 		if (save_errno != 0)
13006f25ae9SGregory Neil Shapiro 			return save_errno;
13106f25ae9SGregory Neil Shapiro 
13206f25ae9SGregory Neil Shapiro 		return SMDBE_NOT_FOUND;
13306f25ae9SGregory Neil Shapiro 	}
13406f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
13506f25ae9SGregory Neil Shapiro }
13606f25ae9SGregory Neil Shapiro 
13706f25ae9SGregory Neil Shapiro int
smdbm_fd(database,fd)13806f25ae9SGregory Neil Shapiro smdbm_fd(database, fd)
13906f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
14006f25ae9SGregory Neil Shapiro 	int *fd;
14106f25ae9SGregory Neil Shapiro {
14206f25ae9SGregory Neil Shapiro 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
14306f25ae9SGregory Neil Shapiro 
14406f25ae9SGregory Neil Shapiro 	*fd = dbm_dirfno(dbm);
14506f25ae9SGregory Neil Shapiro 	if (*fd <= 0)
14606f25ae9SGregory Neil Shapiro 		return EINVAL;
14706f25ae9SGregory Neil Shapiro 
14806f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
14906f25ae9SGregory Neil Shapiro }
15006f25ae9SGregory Neil Shapiro 
15106f25ae9SGregory Neil Shapiro int
smdbm_lockfd(database)15242e5d165SGregory Neil Shapiro smdbm_lockfd(database)
15342e5d165SGregory Neil Shapiro 	SMDB_DATABASE *database;
15442e5d165SGregory Neil Shapiro {
15542e5d165SGregory Neil Shapiro 	SMDB_DBM_DATABASE *db = (SMDB_DBM_DATABASE *) database->smdb_impl;
15642e5d165SGregory Neil Shapiro 
15742e5d165SGregory Neil Shapiro 	return db->smndbm_lock_fd;
15842e5d165SGregory Neil Shapiro }
15942e5d165SGregory Neil Shapiro 
16042e5d165SGregory Neil Shapiro int
smdbm_get(database,key,data,flags)16106f25ae9SGregory Neil Shapiro smdbm_get(database, key, data, flags)
16206f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
16306f25ae9SGregory Neil Shapiro 	SMDB_DBENT *key;
16406f25ae9SGregory Neil Shapiro 	SMDB_DBENT *data;
16540266059SGregory Neil Shapiro 	unsigned int flags;
16606f25ae9SGregory Neil Shapiro {
16706f25ae9SGregory Neil Shapiro 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
168193538b7SGregory Neil Shapiro 	datum dbkey, dbdata;
169193538b7SGregory Neil Shapiro 
17040266059SGregory Neil Shapiro 	(void) memset(&dbkey, '\0', sizeof dbkey);
17140266059SGregory Neil Shapiro 	(void) memset(&dbdata, '\0', sizeof dbdata);
172193538b7SGregory Neil Shapiro 	dbkey.dptr = key->data;
173193538b7SGregory Neil Shapiro 	dbkey.dsize = key->size;
17406f25ae9SGregory Neil Shapiro 
17506f25ae9SGregory Neil Shapiro 	errno = 0;
176193538b7SGregory Neil Shapiro 	dbdata = dbm_fetch(dbm, dbkey);
177193538b7SGregory Neil Shapiro 	if (dbdata.dptr == NULL)
17806f25ae9SGregory Neil Shapiro 	{
17906f25ae9SGregory Neil Shapiro 		int save_errno = errno;
18006f25ae9SGregory Neil Shapiro 
18106f25ae9SGregory Neil Shapiro 		if (dbm_error(dbm))
18206f25ae9SGregory Neil Shapiro 			return SMDBE_IO_ERROR;
18306f25ae9SGregory Neil Shapiro 
18406f25ae9SGregory Neil Shapiro 		if (save_errno != 0)
18506f25ae9SGregory Neil Shapiro 			return save_errno;
18606f25ae9SGregory Neil Shapiro 
18706f25ae9SGregory Neil Shapiro 		return SMDBE_NOT_FOUND;
18806f25ae9SGregory Neil Shapiro 	}
189193538b7SGregory Neil Shapiro 	data->data = dbdata.dptr;
190193538b7SGregory Neil Shapiro 	data->size = dbdata.dsize;
19106f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
19206f25ae9SGregory Neil Shapiro }
19306f25ae9SGregory Neil Shapiro 
19406f25ae9SGregory Neil Shapiro int
smdbm_put(database,key,data,flags)19506f25ae9SGregory Neil Shapiro smdbm_put(database, key, data, flags)
19606f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
19706f25ae9SGregory Neil Shapiro 	SMDB_DBENT *key;
19806f25ae9SGregory Neil Shapiro 	SMDB_DBENT *data;
19940266059SGregory Neil Shapiro 	unsigned int flags;
20006f25ae9SGregory Neil Shapiro {
20106f25ae9SGregory Neil Shapiro 	int result;
20206f25ae9SGregory Neil Shapiro 	int save_errno;
20306f25ae9SGregory Neil Shapiro 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
204193538b7SGregory Neil Shapiro 	datum dbkey, dbdata;
205193538b7SGregory Neil Shapiro 
20640266059SGregory Neil Shapiro 	(void) memset(&dbkey, '\0', sizeof dbkey);
20740266059SGregory Neil Shapiro 	(void) memset(&dbdata, '\0', sizeof dbdata);
208193538b7SGregory Neil Shapiro 	dbkey.dptr = key->data;
209193538b7SGregory Neil Shapiro 	dbkey.dsize = key->size;
210193538b7SGregory Neil Shapiro 	dbdata.dptr = data->data;
211193538b7SGregory Neil Shapiro 	dbdata.dsize = data->size;
21206f25ae9SGregory Neil Shapiro 
21306f25ae9SGregory Neil Shapiro 	errno = 0;
214193538b7SGregory Neil Shapiro 	result = dbm_store(dbm, dbkey, dbdata,
21506f25ae9SGregory Neil Shapiro 			   smdb_put_flags_to_ndbm_flags(flags));
21606f25ae9SGregory Neil Shapiro 	switch (result)
21706f25ae9SGregory Neil Shapiro 	{
21806f25ae9SGregory Neil Shapiro 	  case 1:
21906f25ae9SGregory Neil Shapiro 		return SMDBE_DUPLICATE;
22006f25ae9SGregory Neil Shapiro 
22106f25ae9SGregory Neil Shapiro 	  case 0:
22206f25ae9SGregory Neil Shapiro 		return SMDBE_OK;
22306f25ae9SGregory Neil Shapiro 
22406f25ae9SGregory Neil Shapiro 	  default:
22506f25ae9SGregory Neil Shapiro 		save_errno = errno;
22606f25ae9SGregory Neil Shapiro 
22706f25ae9SGregory Neil Shapiro 		if (dbm_error(dbm))
22806f25ae9SGregory Neil Shapiro 			return SMDBE_IO_ERROR;
22906f25ae9SGregory Neil Shapiro 
23006f25ae9SGregory Neil Shapiro 		if (save_errno != 0)
23106f25ae9SGregory Neil Shapiro 			return save_errno;
23206f25ae9SGregory Neil Shapiro 
23306f25ae9SGregory Neil Shapiro 		return SMDBE_IO_ERROR;
23406f25ae9SGregory Neil Shapiro 	}
23506f25ae9SGregory Neil Shapiro 	/* NOTREACHED */
23606f25ae9SGregory Neil Shapiro }
23706f25ae9SGregory Neil Shapiro 
23806f25ae9SGregory Neil Shapiro int
smndbm_set_owner(database,uid,gid)23906f25ae9SGregory Neil Shapiro smndbm_set_owner(database, uid, gid)
24006f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
24106f25ae9SGregory Neil Shapiro 	uid_t uid;
24206f25ae9SGregory Neil Shapiro 	gid_t gid;
24306f25ae9SGregory Neil Shapiro {
24406f25ae9SGregory Neil Shapiro # if HASFCHOWN
24506f25ae9SGregory Neil Shapiro 	int fd;
24606f25ae9SGregory Neil Shapiro 	int result;
24706f25ae9SGregory Neil Shapiro 	DBM *dbm = ((SMDB_DBM_DATABASE *) database->smdb_impl)->smndbm_dbm;
24806f25ae9SGregory Neil Shapiro 
24906f25ae9SGregory Neil Shapiro 	fd = dbm_dirfno(dbm);
25006f25ae9SGregory Neil Shapiro 	if (fd <= 0)
25106f25ae9SGregory Neil Shapiro 		return EINVAL;
25206f25ae9SGregory Neil Shapiro 
25306f25ae9SGregory Neil Shapiro 	result = fchown(fd, uid, gid);
25406f25ae9SGregory Neil Shapiro 	if (result < 0)
25506f25ae9SGregory Neil Shapiro 		return errno;
25606f25ae9SGregory Neil Shapiro 
25706f25ae9SGregory Neil Shapiro 	fd = dbm_pagfno(dbm);
25806f25ae9SGregory Neil Shapiro 	if (fd <= 0)
25906f25ae9SGregory Neil Shapiro 		return EINVAL;
26006f25ae9SGregory Neil Shapiro 
26106f25ae9SGregory Neil Shapiro 	result = fchown(fd, uid, gid);
26206f25ae9SGregory Neil Shapiro 	if (result < 0)
26306f25ae9SGregory Neil Shapiro 		return errno;
26406f25ae9SGregory Neil Shapiro # endif /* HASFCHOWN */
26506f25ae9SGregory Neil Shapiro 
26606f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
26706f25ae9SGregory Neil Shapiro }
26806f25ae9SGregory Neil Shapiro 
26906f25ae9SGregory Neil Shapiro int
smdbm_sync(database,flags)27006f25ae9SGregory Neil Shapiro smdbm_sync(database, flags)
27106f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
27240266059SGregory Neil Shapiro 	unsigned int flags;
27306f25ae9SGregory Neil Shapiro {
27406f25ae9SGregory Neil Shapiro 	return SMDBE_UNSUPPORTED;
27506f25ae9SGregory Neil Shapiro }
27606f25ae9SGregory Neil Shapiro 
27706f25ae9SGregory Neil Shapiro int
smdbm_cursor_close(cursor)27806f25ae9SGregory Neil Shapiro smdbm_cursor_close(cursor)
27906f25ae9SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
28006f25ae9SGregory Neil Shapiro {
28106f25ae9SGregory Neil Shapiro 	SMDB_DBM_CURSOR *dbm_cursor = (SMDB_DBM_CURSOR *) cursor->smdbc_impl;
28206f25ae9SGregory Neil Shapiro 	SMDB_DBM_DATABASE *db = dbm_cursor->smndbmc_db;
28306f25ae9SGregory Neil Shapiro 
28406f25ae9SGregory Neil Shapiro 	if (!db->smndbm_cursor_in_use)
28506f25ae9SGregory Neil Shapiro 		return SMDBE_NOT_A_VALID_CURSOR;
28606f25ae9SGregory Neil Shapiro 
28740266059SGregory Neil Shapiro 	db->smndbm_cursor_in_use = false;
28806f25ae9SGregory Neil Shapiro 	free(dbm_cursor);
28906f25ae9SGregory Neil Shapiro 	free(cursor);
29006f25ae9SGregory Neil Shapiro 
29106f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
29206f25ae9SGregory Neil Shapiro }
29306f25ae9SGregory Neil Shapiro 
29406f25ae9SGregory Neil Shapiro int
smdbm_cursor_del(cursor,flags)29506f25ae9SGregory Neil Shapiro smdbm_cursor_del(cursor, flags)
29606f25ae9SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
29740266059SGregory Neil Shapiro 	unsigned int flags;
29806f25ae9SGregory Neil Shapiro {
29906f25ae9SGregory Neil Shapiro 	int result;
30006f25ae9SGregory Neil Shapiro 	SMDB_DBM_CURSOR *dbm_cursor = (SMDB_DBM_CURSOR *) cursor->smdbc_impl;
30106f25ae9SGregory Neil Shapiro 	SMDB_DBM_DATABASE *db = dbm_cursor->smndbmc_db;
30206f25ae9SGregory Neil Shapiro 	DBM *dbm = db->smndbm_dbm;
30306f25ae9SGregory Neil Shapiro 
30406f25ae9SGregory Neil Shapiro 	errno = 0;
30506f25ae9SGregory Neil Shapiro 	result = dbm_delete(dbm, dbm_cursor->smndbmc_current_key);
30606f25ae9SGregory Neil Shapiro 	if (result != 0)
30706f25ae9SGregory Neil Shapiro 	{
30806f25ae9SGregory Neil Shapiro 		int save_errno = errno;
30906f25ae9SGregory Neil Shapiro 
31006f25ae9SGregory Neil Shapiro 		if (dbm_error(dbm))
31106f25ae9SGregory Neil Shapiro 			return SMDBE_IO_ERROR;
31206f25ae9SGregory Neil Shapiro 
31306f25ae9SGregory Neil Shapiro 		if (save_errno != 0)
31406f25ae9SGregory Neil Shapiro 			return save_errno;
31506f25ae9SGregory Neil Shapiro 
31606f25ae9SGregory Neil Shapiro 		return SMDBE_NOT_FOUND;
31706f25ae9SGregory Neil Shapiro 	}
31806f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
31906f25ae9SGregory Neil Shapiro }
32006f25ae9SGregory Neil Shapiro 
32106f25ae9SGregory Neil Shapiro int
smdbm_cursor_get(cursor,key,value,flags)32206f25ae9SGregory Neil Shapiro smdbm_cursor_get(cursor, key, value, flags)
32306f25ae9SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
32406f25ae9SGregory Neil Shapiro 	SMDB_DBENT *key;
32506f25ae9SGregory Neil Shapiro 	SMDB_DBENT *value;
32606f25ae9SGregory Neil Shapiro 	SMDB_FLAG flags;
32706f25ae9SGregory Neil Shapiro {
32806f25ae9SGregory Neil Shapiro 	SMDB_DBM_CURSOR *dbm_cursor = (SMDB_DBM_CURSOR *) cursor->smdbc_impl;
32906f25ae9SGregory Neil Shapiro 	SMDB_DBM_DATABASE *db = dbm_cursor->smndbmc_db;
33006f25ae9SGregory Neil Shapiro 	DBM *dbm = db->smndbm_dbm;
331193538b7SGregory Neil Shapiro 	datum dbkey, dbdata;
332193538b7SGregory Neil Shapiro 
33340266059SGregory Neil Shapiro 	(void) memset(&dbkey, '\0', sizeof dbkey);
33440266059SGregory Neil Shapiro 	(void) memset(&dbdata, '\0', sizeof dbdata);
33506f25ae9SGregory Neil Shapiro 
33606f25ae9SGregory Neil Shapiro 	if (flags == SMDB_CURSOR_GET_RANGE)
33706f25ae9SGregory Neil Shapiro 		return SMDBE_UNSUPPORTED;
33806f25ae9SGregory Neil Shapiro 
33906f25ae9SGregory Neil Shapiro 	if (dbm_cursor->smndbmc_current_key.dptr == NULL)
34006f25ae9SGregory Neil Shapiro 	{
34106f25ae9SGregory Neil Shapiro 		dbm_cursor->smndbmc_current_key = dbm_firstkey(dbm);
34206f25ae9SGregory Neil Shapiro 		if (dbm_cursor->smndbmc_current_key.dptr == NULL)
34306f25ae9SGregory Neil Shapiro 		{
34406f25ae9SGregory Neil Shapiro 			if (dbm_error(dbm))
34506f25ae9SGregory Neil Shapiro 				return SMDBE_IO_ERROR;
34606f25ae9SGregory Neil Shapiro 			return SMDBE_LAST_ENTRY;
34706f25ae9SGregory Neil Shapiro 		}
34806f25ae9SGregory Neil Shapiro 	}
34906f25ae9SGregory Neil Shapiro 	else
35006f25ae9SGregory Neil Shapiro 	{
35106f25ae9SGregory Neil Shapiro 		dbm_cursor->smndbmc_current_key = dbm_nextkey(dbm);
35206f25ae9SGregory Neil Shapiro 		if (dbm_cursor->smndbmc_current_key.dptr == NULL)
35306f25ae9SGregory Neil Shapiro 		{
35406f25ae9SGregory Neil Shapiro 			if (dbm_error(dbm))
35506f25ae9SGregory Neil Shapiro 				return SMDBE_IO_ERROR;
35606f25ae9SGregory Neil Shapiro 			return SMDBE_LAST_ENTRY;
35706f25ae9SGregory Neil Shapiro 		}
35806f25ae9SGregory Neil Shapiro 	}
35906f25ae9SGregory Neil Shapiro 
36006f25ae9SGregory Neil Shapiro 	errno = 0;
361193538b7SGregory Neil Shapiro 	dbdata = dbm_fetch(dbm, dbm_cursor->smndbmc_current_key);
362193538b7SGregory Neil Shapiro 	if (dbdata.dptr == NULL)
36306f25ae9SGregory Neil Shapiro 	{
36406f25ae9SGregory Neil Shapiro 		int save_errno = errno;
36506f25ae9SGregory Neil Shapiro 
36606f25ae9SGregory Neil Shapiro 		if (dbm_error(dbm))
36706f25ae9SGregory Neil Shapiro 			return SMDBE_IO_ERROR;
36806f25ae9SGregory Neil Shapiro 
36906f25ae9SGregory Neil Shapiro 		if (save_errno != 0)
37006f25ae9SGregory Neil Shapiro 			return save_errno;
37106f25ae9SGregory Neil Shapiro 
37206f25ae9SGregory Neil Shapiro 		return SMDBE_NOT_FOUND;
37306f25ae9SGregory Neil Shapiro 	}
374193538b7SGregory Neil Shapiro 	value->data = dbdata.dptr;
375193538b7SGregory Neil Shapiro 	value->size = dbdata.dsize;
376193538b7SGregory Neil Shapiro 	key->data = dbm_cursor->smndbmc_current_key.dptr;
377193538b7SGregory Neil Shapiro 	key->size = dbm_cursor->smndbmc_current_key.dsize;
37806f25ae9SGregory Neil Shapiro 
37906f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
38006f25ae9SGregory Neil Shapiro }
38106f25ae9SGregory Neil Shapiro 
38206f25ae9SGregory Neil Shapiro int
smdbm_cursor_put(cursor,key,value,flags)38306f25ae9SGregory Neil Shapiro smdbm_cursor_put(cursor, key, value, flags)
38406f25ae9SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
38506f25ae9SGregory Neil Shapiro 	SMDB_DBENT *key;
38606f25ae9SGregory Neil Shapiro 	SMDB_DBENT *value;
38706f25ae9SGregory Neil Shapiro 	SMDB_FLAG flags;
38806f25ae9SGregory Neil Shapiro {
38906f25ae9SGregory Neil Shapiro 	int result;
39006f25ae9SGregory Neil Shapiro 	int save_errno;
39106f25ae9SGregory Neil Shapiro 	SMDB_DBM_CURSOR *dbm_cursor = (SMDB_DBM_CURSOR *) cursor->smdbc_impl;
39206f25ae9SGregory Neil Shapiro 	SMDB_DBM_DATABASE *db = dbm_cursor->smndbmc_db;
39306f25ae9SGregory Neil Shapiro 	DBM *dbm = db->smndbm_dbm;
394193538b7SGregory Neil Shapiro 	datum dbdata;
395193538b7SGregory Neil Shapiro 
39640266059SGregory Neil Shapiro 	(void) memset(&dbdata, '\0', sizeof dbdata);
397193538b7SGregory Neil Shapiro 	dbdata.dptr = value->data;
398193538b7SGregory Neil Shapiro 	dbdata.dsize = value->size;
39906f25ae9SGregory Neil Shapiro 
40006f25ae9SGregory Neil Shapiro 	errno = 0;
401193538b7SGregory Neil Shapiro 	result = dbm_store(dbm, dbm_cursor->smndbmc_current_key, dbdata,
40206f25ae9SGregory Neil Shapiro 			   smdb_put_flags_to_ndbm_flags(flags));
40306f25ae9SGregory Neil Shapiro 	switch (result)
40406f25ae9SGregory Neil Shapiro 	{
40506f25ae9SGregory Neil Shapiro 	  case 1:
40606f25ae9SGregory Neil Shapiro 		return SMDBE_DUPLICATE;
40706f25ae9SGregory Neil Shapiro 
40806f25ae9SGregory Neil Shapiro 	  case 0:
40906f25ae9SGregory Neil Shapiro 		return SMDBE_OK;
41006f25ae9SGregory Neil Shapiro 
41106f25ae9SGregory Neil Shapiro 	  default:
41206f25ae9SGregory Neil Shapiro 		save_errno = errno;
41306f25ae9SGregory Neil Shapiro 
41406f25ae9SGregory Neil Shapiro 		if (dbm_error(dbm))
41506f25ae9SGregory Neil Shapiro 			return SMDBE_IO_ERROR;
41606f25ae9SGregory Neil Shapiro 
41706f25ae9SGregory Neil Shapiro 		if (save_errno != 0)
41806f25ae9SGregory Neil Shapiro 			return save_errno;
41906f25ae9SGregory Neil Shapiro 
42006f25ae9SGregory Neil Shapiro 		return SMDBE_IO_ERROR;
42106f25ae9SGregory Neil Shapiro 	}
42206f25ae9SGregory Neil Shapiro 	/* NOTREACHED */
42306f25ae9SGregory Neil Shapiro }
42406f25ae9SGregory Neil Shapiro 
42506f25ae9SGregory Neil Shapiro int
smdbm_cursor(database,cursor,flags)42606f25ae9SGregory Neil Shapiro smdbm_cursor(database, cursor, flags)
42706f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *database;
42806f25ae9SGregory Neil Shapiro 	SMDB_CURSOR **cursor;
42906f25ae9SGregory Neil Shapiro 	SMDB_FLAG flags;
43006f25ae9SGregory Neil Shapiro {
43106f25ae9SGregory Neil Shapiro 	SMDB_DBM_DATABASE *db = (SMDB_DBM_DATABASE *) database->smdb_impl;
43206f25ae9SGregory Neil Shapiro 	SMDB_CURSOR *cur;
43306f25ae9SGregory Neil Shapiro 	SMDB_DBM_CURSOR *dbm_cursor;
43406f25ae9SGregory Neil Shapiro 
43506f25ae9SGregory Neil Shapiro 	if (db->smndbm_cursor_in_use)
43606f25ae9SGregory Neil Shapiro 		return SMDBE_ONLY_SUPPORTS_ONE_CURSOR;
43706f25ae9SGregory Neil Shapiro 
43840266059SGregory Neil Shapiro 	db->smndbm_cursor_in_use = true;
43906f25ae9SGregory Neil Shapiro 	dbm_cursor = (SMDB_DBM_CURSOR *) malloc(sizeof(SMDB_DBM_CURSOR));
4405dd76dd0SGregory Neil Shapiro 	if (dbm_cursor == NULL)
4415dd76dd0SGregory Neil Shapiro 		return SMDBE_MALLOC;
44206f25ae9SGregory Neil Shapiro 	dbm_cursor->smndbmc_db = db;
44306f25ae9SGregory Neil Shapiro 	dbm_cursor->smndbmc_current_key.dptr = NULL;
44406f25ae9SGregory Neil Shapiro 	dbm_cursor->smndbmc_current_key.dsize = 0;
44506f25ae9SGregory Neil Shapiro 
44606f25ae9SGregory Neil Shapiro 	cur = (SMDB_CURSOR*) malloc(sizeof(SMDB_CURSOR));
44706f25ae9SGregory Neil Shapiro 	if (cur == NULL)
4485dd76dd0SGregory Neil Shapiro 	{
4495dd76dd0SGregory Neil Shapiro 		free(dbm_cursor);
45006f25ae9SGregory Neil Shapiro 		return SMDBE_MALLOC;
4515dd76dd0SGregory Neil Shapiro 	}
45206f25ae9SGregory Neil Shapiro 
45306f25ae9SGregory Neil Shapiro 	cur->smdbc_impl = dbm_cursor;
45406f25ae9SGregory Neil Shapiro 	cur->smdbc_close = smdbm_cursor_close;
45506f25ae9SGregory Neil Shapiro 	cur->smdbc_del = smdbm_cursor_del;
45606f25ae9SGregory Neil Shapiro 	cur->smdbc_get = smdbm_cursor_get;
45706f25ae9SGregory Neil Shapiro 	cur->smdbc_put = smdbm_cursor_put;
45806f25ae9SGregory Neil Shapiro 	*cursor = cur;
45906f25ae9SGregory Neil Shapiro 
46006f25ae9SGregory Neil Shapiro 	return SMDBE_OK;
46106f25ae9SGregory Neil Shapiro }
46240266059SGregory Neil Shapiro /*
46306f25ae9SGregory Neil Shapiro **  SMDB_NDBM_OPEN -- Opens a ndbm database.
46406f25ae9SGregory Neil Shapiro **
46506f25ae9SGregory Neil Shapiro **	Parameters:
46606f25ae9SGregory Neil Shapiro **		database -- An unallocated database pointer to a pointer.
46706f25ae9SGregory Neil Shapiro **		db_name -- The name of the database without extension.
468*d39bd2c1SGregory Neil Shapiro **		mode -- File permissions on a created database.
46906f25ae9SGregory Neil Shapiro **		mode_mask -- Mode bits that much match on an opened database.
47006f25ae9SGregory Neil Shapiro **		sff -- Flags to safefile.
47106f25ae9SGregory Neil Shapiro **		type -- The type of database to open.
47206f25ae9SGregory Neil Shapiro **			Only SMDB_NDBM is supported.
47306f25ae9SGregory Neil Shapiro **		user_info -- Information on the user to use for file
47406f25ae9SGregory Neil Shapiro **			    permissions.
47540266059SGregory Neil Shapiro **		db_params -- No params are supported.
47606f25ae9SGregory Neil Shapiro **
47706f25ae9SGregory Neil Shapiro **	Returns:
47806f25ae9SGregory Neil Shapiro **		SMDBE_OK -- Success, otherwise errno:
47906f25ae9SGregory Neil Shapiro **		SMDBE_MALLOC -- Cannot allocate memory.
48006f25ae9SGregory Neil Shapiro **		SMDBE_UNSUPPORTED -- The type is not supported.
48106f25ae9SGregory Neil Shapiro **		SMDBE_GDBM_IS_BAD -- We have detected GDBM and we don't
48206f25ae9SGregory Neil Shapiro **				    like it.
48306f25ae9SGregory Neil Shapiro **		SMDBE_BAD_OPEN -- dbm_open failed and errno was not set.
48406f25ae9SGregory Neil Shapiro **		Anything else: errno
48506f25ae9SGregory Neil Shapiro */
48606f25ae9SGregory Neil Shapiro 
48706f25ae9SGregory Neil Shapiro int
smdb_ndbm_open(database,db_name,mode,mode_mask,sff,type,user_info,db_params)48806f25ae9SGregory Neil Shapiro smdb_ndbm_open(database, db_name, mode, mode_mask, sff, type, user_info,
48906f25ae9SGregory Neil Shapiro 	       db_params)
49006f25ae9SGregory Neil Shapiro 	SMDB_DATABASE **database;
49106f25ae9SGregory Neil Shapiro 	char *db_name;
49206f25ae9SGregory Neil Shapiro 	int mode;
49306f25ae9SGregory Neil Shapiro 	int mode_mask;
49406f25ae9SGregory Neil Shapiro 	long sff;
49506f25ae9SGregory Neil Shapiro 	SMDB_DBTYPE type;
49606f25ae9SGregory Neil Shapiro 	SMDB_USER_INFO *user_info;
49706f25ae9SGregory Neil Shapiro 	SMDB_DBPARAMS *db_params;
49806f25ae9SGregory Neil Shapiro {
499605302a5SGregory Neil Shapiro 	bool lockcreated = false;
50006f25ae9SGregory Neil Shapiro 	int result;
50106f25ae9SGregory Neil Shapiro 	int lock_fd;
50206f25ae9SGregory Neil Shapiro 	SMDB_DATABASE *smdb_db;
50306f25ae9SGregory Neil Shapiro 	SMDB_DBM_DATABASE *db;
50406f25ae9SGregory Neil Shapiro 	DBM *dbm = NULL;
50506f25ae9SGregory Neil Shapiro 	struct stat dir_stat_info;
50606f25ae9SGregory Neil Shapiro 	struct stat pag_stat_info;
50706f25ae9SGregory Neil Shapiro 
50806f25ae9SGregory Neil Shapiro 	result = SMDBE_OK;
50906f25ae9SGregory Neil Shapiro 	*database = NULL;
51006f25ae9SGregory Neil Shapiro 
51106f25ae9SGregory Neil Shapiro 	if (type == NULL)
51206f25ae9SGregory Neil Shapiro 		return SMDBE_UNKNOWN_DB_TYPE;
51306f25ae9SGregory Neil Shapiro 
51406f25ae9SGregory Neil Shapiro 	result = smdb_setup_file(db_name, SMNDB_DIR_FILE_EXTENSION, mode_mask,
51506f25ae9SGregory Neil Shapiro 				 sff, user_info, &dir_stat_info);
51606f25ae9SGregory Neil Shapiro 	if (result != SMDBE_OK)
51706f25ae9SGregory Neil Shapiro 		return result;
51806f25ae9SGregory Neil Shapiro 
51906f25ae9SGregory Neil Shapiro 	result = smdb_setup_file(db_name, SMNDB_PAG_FILE_EXTENSION, mode_mask,
52006f25ae9SGregory Neil Shapiro 				 sff, user_info, &pag_stat_info);
52106f25ae9SGregory Neil Shapiro 	if (result != SMDBE_OK)
52206f25ae9SGregory Neil Shapiro 		return result;
52306f25ae9SGregory Neil Shapiro 
524605302a5SGregory Neil Shapiro 	if ((dir_stat_info.st_mode == ST_MODE_NOFILE ||
525605302a5SGregory Neil Shapiro 	     pag_stat_info.st_mode == ST_MODE_NOFILE) &&
526605302a5SGregory Neil Shapiro 	    bitset(mode, O_CREAT))
527605302a5SGregory Neil Shapiro 		lockcreated = true;
528605302a5SGregory Neil Shapiro 
52906f25ae9SGregory Neil Shapiro 	lock_fd = -1;
53006f25ae9SGregory Neil Shapiro 	result = smdb_lock_file(&lock_fd, db_name, mode, sff,
53106f25ae9SGregory Neil Shapiro 				SMNDB_DIR_FILE_EXTENSION);
53206f25ae9SGregory Neil Shapiro 	if (result != SMDBE_OK)
53306f25ae9SGregory Neil Shapiro 		return result;
534605302a5SGregory Neil Shapiro 
535605302a5SGregory Neil Shapiro 	if (lockcreated)
536605302a5SGregory Neil Shapiro 	{
537605302a5SGregory Neil Shapiro 		int pag_fd;
538605302a5SGregory Neil Shapiro 
539605302a5SGregory Neil Shapiro 		/* Need to pre-open the .pag file as well with O_EXCL */
540605302a5SGregory Neil Shapiro 		result = smdb_lock_file(&pag_fd, db_name, mode, sff,
541605302a5SGregory Neil Shapiro 					SMNDB_PAG_FILE_EXTENSION);
542605302a5SGregory Neil Shapiro 		if (result != SMDBE_OK)
543605302a5SGregory Neil Shapiro 		{
544605302a5SGregory Neil Shapiro 			(void) close(lock_fd);
545605302a5SGregory Neil Shapiro 			return result;
546605302a5SGregory Neil Shapiro 		}
547605302a5SGregory Neil Shapiro 		(void) close(pag_fd);
548605302a5SGregory Neil Shapiro 
549605302a5SGregory Neil Shapiro 		mode |= O_TRUNC;
550605302a5SGregory Neil Shapiro 		mode &= ~(O_CREAT|O_EXCL);
551605302a5SGregory Neil Shapiro 	}
55206f25ae9SGregory Neil Shapiro 
55306f25ae9SGregory Neil Shapiro 	smdb_db = smdb_malloc_database();
55406f25ae9SGregory Neil Shapiro 	if (smdb_db == NULL)
55506f25ae9SGregory Neil Shapiro 		result = SMDBE_MALLOC;
55606f25ae9SGregory Neil Shapiro 
55706f25ae9SGregory Neil Shapiro 	db = smdbm_malloc_database();
55806f25ae9SGregory Neil Shapiro 	if (db == NULL)
55906f25ae9SGregory Neil Shapiro 		result = SMDBE_MALLOC;
56006f25ae9SGregory Neil Shapiro 
56106f25ae9SGregory Neil Shapiro 	/* Try to open database */
56206f25ae9SGregory Neil Shapiro 	if (result == SMDBE_OK)
56306f25ae9SGregory Neil Shapiro 	{
56406f25ae9SGregory Neil Shapiro 		db->smndbm_lock_fd = lock_fd;
56506f25ae9SGregory Neil Shapiro 
56606f25ae9SGregory Neil Shapiro 		errno = 0;
56794c01205SGregory Neil Shapiro 		dbm = dbm_open(db_name, mode, DBMMODE);
56806f25ae9SGregory Neil Shapiro 		if (dbm == NULL)
56906f25ae9SGregory Neil Shapiro 		{
57006f25ae9SGregory Neil Shapiro 			if (errno == 0)
57106f25ae9SGregory Neil Shapiro 				result = SMDBE_BAD_OPEN;
57206f25ae9SGregory Neil Shapiro 			else
57306f25ae9SGregory Neil Shapiro 				result = errno;
57406f25ae9SGregory Neil Shapiro 		}
57506f25ae9SGregory Neil Shapiro 		db->smndbm_dbm = dbm;
57606f25ae9SGregory Neil Shapiro 	}
57706f25ae9SGregory Neil Shapiro 
57806f25ae9SGregory Neil Shapiro 	/* Check for GDBM */
57906f25ae9SGregory Neil Shapiro 	if (result == SMDBE_OK)
58006f25ae9SGregory Neil Shapiro 	{
58106f25ae9SGregory Neil Shapiro 		if (dbm_dirfno(dbm) == dbm_pagfno(dbm))
58206f25ae9SGregory Neil Shapiro 			result = SMDBE_GDBM_IS_BAD;
58306f25ae9SGregory Neil Shapiro 	}
58406f25ae9SGregory Neil Shapiro 
58506f25ae9SGregory Neil Shapiro 	/* Check for filechanged */
58606f25ae9SGregory Neil Shapiro 	if (result == SMDBE_OK)
58706f25ae9SGregory Neil Shapiro 	{
58806f25ae9SGregory Neil Shapiro 		result = smdb_filechanged(db_name, SMNDB_DIR_FILE_EXTENSION,
58906f25ae9SGregory Neil Shapiro 					  dbm_dirfno(dbm), &dir_stat_info);
59006f25ae9SGregory Neil Shapiro 		if (result == SMDBE_OK)
59106f25ae9SGregory Neil Shapiro 		{
59206f25ae9SGregory Neil Shapiro 			result = smdb_filechanged(db_name,
59306f25ae9SGregory Neil Shapiro 						  SMNDB_PAG_FILE_EXTENSION,
59406f25ae9SGregory Neil Shapiro 						  dbm_pagfno(dbm),
59506f25ae9SGregory Neil Shapiro 						  &pag_stat_info);
59606f25ae9SGregory Neil Shapiro 		}
59706f25ae9SGregory Neil Shapiro 	}
59806f25ae9SGregory Neil Shapiro 
59906f25ae9SGregory Neil Shapiro 	/* XXX Got to get fchown stuff in here */
60006f25ae9SGregory Neil Shapiro 
60106f25ae9SGregory Neil Shapiro 	/* Setup driver if everything is ok */
60206f25ae9SGregory Neil Shapiro 	if (result == SMDBE_OK)
60306f25ae9SGregory Neil Shapiro 	{
60406f25ae9SGregory Neil Shapiro 		*database = smdb_db;
60506f25ae9SGregory Neil Shapiro 
60606f25ae9SGregory Neil Shapiro 		smdb_db->smdb_close = smdbm_close;
60706f25ae9SGregory Neil Shapiro 		smdb_db->smdb_del = smdbm_del;
60806f25ae9SGregory Neil Shapiro 		smdb_db->smdb_fd = smdbm_fd;
60942e5d165SGregory Neil Shapiro 		smdb_db->smdb_lockfd = smdbm_lockfd;
61006f25ae9SGregory Neil Shapiro 		smdb_db->smdb_get = smdbm_get;
61106f25ae9SGregory Neil Shapiro 		smdb_db->smdb_put = smdbm_put;
61206f25ae9SGregory Neil Shapiro 		smdb_db->smdb_set_owner = smndbm_set_owner;
61306f25ae9SGregory Neil Shapiro 		smdb_db->smdb_sync = smdbm_sync;
61406f25ae9SGregory Neil Shapiro 		smdb_db->smdb_cursor = smdbm_cursor;
61506f25ae9SGregory Neil Shapiro 
61606f25ae9SGregory Neil Shapiro 		smdb_db->smdb_impl = db;
61706f25ae9SGregory Neil Shapiro 
61806f25ae9SGregory Neil Shapiro 		return SMDBE_OK;
61906f25ae9SGregory Neil Shapiro 	}
62006f25ae9SGregory Neil Shapiro 
62106f25ae9SGregory Neil Shapiro 	/* If we're here, something bad happened, clean up */
62206f25ae9SGregory Neil Shapiro 	if (dbm != NULL)
62306f25ae9SGregory Neil Shapiro 		dbm_close(dbm);
62406f25ae9SGregory Neil Shapiro 
62506f25ae9SGregory Neil Shapiro 	smdb_unlock_file(db->smndbm_lock_fd);
62606f25ae9SGregory Neil Shapiro 	free(db);
62706f25ae9SGregory Neil Shapiro 	smdb_free_database(smdb_db);
62806f25ae9SGregory Neil Shapiro 
62906f25ae9SGregory Neil Shapiro 	return result;
63006f25ae9SGregory Neil Shapiro }
63106f25ae9SGregory Neil Shapiro #endif /* NDBM */
632