xref: /freebsd/contrib/sendmail/libsmdb/smcdb.c (revision d39bd2c1388b520fcba9abed1932acacead60fba)
15b0945b5SGregory Neil Shapiro /*
25b0945b5SGregory Neil Shapiro **  Copyright (c) 2018 Proofpoint, Inc. and its suppliers.
35b0945b5SGregory Neil Shapiro **	All rights reserved.
45b0945b5SGregory Neil Shapiro **
55b0945b5SGregory Neil Shapiro **  By using this file, you agree to the terms and conditions set
65b0945b5SGregory Neil Shapiro **  forth in the LICENSE file which can be found at the top level of
75b0945b5SGregory Neil Shapiro **  the sendmail distribution.
85b0945b5SGregory Neil Shapiro */
95b0945b5SGregory Neil Shapiro 
105b0945b5SGregory Neil Shapiro #include <sm/gen.h>
115b0945b5SGregory Neil Shapiro SM_RCSID("@(#)$Id: smcdb.c,v 8.55 2013-11-22 20:51:49 ca Exp $")
125b0945b5SGregory Neil Shapiro 
135b0945b5SGregory Neil Shapiro #include <fcntl.h>
145b0945b5SGregory Neil Shapiro #include <stdlib.h>
155b0945b5SGregory Neil Shapiro #include <unistd.h>
165b0945b5SGregory Neil Shapiro 
175b0945b5SGregory Neil Shapiro #include <sendmail/sendmail.h>
185b0945b5SGregory Neil Shapiro #include <libsmdb/smdb.h>
195b0945b5SGregory Neil Shapiro 
205b0945b5SGregory Neil Shapiro #if CDB
215b0945b5SGregory Neil Shapiro #include <assert.h>
225b0945b5SGregory Neil Shapiro #include <cdb.h>
235b0945b5SGregory Neil Shapiro 
245b0945b5SGregory Neil Shapiro typedef struct cdb	cdb_map_T, *cdb_map_P;
255b0945b5SGregory Neil Shapiro typedef struct cdb_make	cdb_make_T, *cdb_make_P;
265b0945b5SGregory Neil Shapiro typedef union sm_cdbs_U sm_cdbs_T, *sm_cdbs_P;
275b0945b5SGregory Neil Shapiro union sm_cdbs_U
285b0945b5SGregory Neil Shapiro {
295b0945b5SGregory Neil Shapiro 	cdb_map_T	 cdbs_cdb_rd;
305b0945b5SGregory Neil Shapiro 	cdb_make_T	 cdbs_cdb_wr;
315b0945b5SGregory Neil Shapiro };
325b0945b5SGregory Neil Shapiro 
335b0945b5SGregory Neil Shapiro struct smdb_cdb_database
345b0945b5SGregory Neil Shapiro {
355b0945b5SGregory Neil Shapiro 	sm_cdbs_T	cdbmap_map;
365b0945b5SGregory Neil Shapiro 	int		cdbmap_fd;
375b0945b5SGregory Neil Shapiro 	int		smcdb_lock_fd;
385b0945b5SGregory Neil Shapiro 	bool		cdbmap_create;
395b0945b5SGregory Neil Shapiro 	unsigned	smcdb_pos;
405b0945b5SGregory Neil Shapiro 	int		smcdb_n;
415b0945b5SGregory Neil Shapiro };
425b0945b5SGregory Neil Shapiro typedef struct smdb_cdb_database SMDB_CDB_DATABASE;
435b0945b5SGregory Neil Shapiro 
445b0945b5SGregory Neil Shapiro /* static int smdb_type_to_cdb_type __P((SMDB_DBTYPE type)); */
455b0945b5SGregory Neil Shapiro static int cdb_error_to_smdb __P((int error));
465b0945b5SGregory Neil Shapiro static SMDB_CDB_DATABASE * smcdb_malloc_database __P((void));
475b0945b5SGregory Neil Shapiro static int smcdb_close __P((SMDB_DATABASE *database));
485b0945b5SGregory Neil Shapiro static int smcdb_del __P((SMDB_DATABASE *database, SMDB_DBENT *key, unsigned int flags));
495b0945b5SGregory Neil Shapiro static int smcdb_fd __P((SMDB_DATABASE *database, int *fd));
505b0945b5SGregory Neil Shapiro static int smcdb_lockfd __P((SMDB_DATABASE *database));
515b0945b5SGregory Neil Shapiro static int smcdb_get __P((SMDB_DATABASE *database, SMDB_DBENT *key, SMDB_DBENT *data, unsigned int flags));
525b0945b5SGregory Neil Shapiro static int smcdb_put __P((SMDB_DATABASE *database, SMDB_DBENT *key, SMDB_DBENT *data, unsigned int flags));
535b0945b5SGregory Neil Shapiro static int smcdb_set_owner __P((SMDB_DATABASE *database, uid_t uid, gid_t gid));
545b0945b5SGregory Neil Shapiro static int smcdb_sync __P((SMDB_DATABASE *database, unsigned int flags));
555b0945b5SGregory Neil Shapiro static int smcdb_cursor_close __P((SMDB_CURSOR *cursor));
565b0945b5SGregory Neil Shapiro static int smcdb_cursor_del __P((SMDB_CURSOR *cursor, SMDB_FLAG flags));
575b0945b5SGregory Neil Shapiro static int smcdb_cursor_get __P((SMDB_CURSOR *cursor, SMDB_DBENT *key, SMDB_DBENT *value, SMDB_FLAG flags));
585b0945b5SGregory Neil Shapiro static int smcdb_cursor_put __P((SMDB_CURSOR *cursor, SMDB_DBENT *key, SMDB_DBENT *value, SMDB_FLAG flags));
595b0945b5SGregory Neil Shapiro static int smcdb_cursor __P((SMDB_DATABASE *database, SMDB_CURSOR **cursor, SMDB_FLAG flags));
605b0945b5SGregory Neil Shapiro 
615b0945b5SGregory Neil Shapiro /*
625b0945b5SGregory Neil Shapiro **  SMDB_TYPE_TO_CDB_TYPE -- Translates smdb database type to cdb type.
635b0945b5SGregory Neil Shapiro **
645b0945b5SGregory Neil Shapiro **	Parameters:
655b0945b5SGregory Neil Shapiro **		type -- The type to translate.
665b0945b5SGregory Neil Shapiro **
675b0945b5SGregory Neil Shapiro **	Returns:
685b0945b5SGregory Neil Shapiro **		The CDB type that corresponsds to the passed in SMDB type.
695b0945b5SGregory Neil Shapiro **		Returns -1 if there is no equivalent type.
705b0945b5SGregory Neil Shapiro **
715b0945b5SGregory Neil Shapiro */
725b0945b5SGregory Neil Shapiro 
735b0945b5SGregory Neil Shapiro # if 0
745b0945b5SGregory Neil Shapiro static int
755b0945b5SGregory Neil Shapiro smdb_type_to_cdb_type(type)
765b0945b5SGregory Neil Shapiro 	SMDB_DBTYPE type;
775b0945b5SGregory Neil Shapiro {
785b0945b5SGregory Neil Shapiro 	return 0;	/* XXX */
795b0945b5SGregory Neil Shapiro }
805b0945b5SGregory Neil Shapiro # endif
815b0945b5SGregory Neil Shapiro 
825b0945b5SGregory Neil Shapiro /*
835b0945b5SGregory Neil Shapiro **  CDB_ERROR_TO_SMDB -- Translates cdb errors to smdbe errors
845b0945b5SGregory Neil Shapiro **
855b0945b5SGregory Neil Shapiro **	Parameters:
865b0945b5SGregory Neil Shapiro **		error -- The error to translate.
875b0945b5SGregory Neil Shapiro **
885b0945b5SGregory Neil Shapiro **	Returns:
895b0945b5SGregory Neil Shapiro **		The SMDBE error corresponding to the cdb error.
905b0945b5SGregory Neil Shapiro **		If we don't have a corresponding error, it returns error.
915b0945b5SGregory Neil Shapiro **
925b0945b5SGregory Neil Shapiro */
935b0945b5SGregory Neil Shapiro 
945b0945b5SGregory Neil Shapiro static int
cdb_error_to_smdb(error)955b0945b5SGregory Neil Shapiro cdb_error_to_smdb(error)
965b0945b5SGregory Neil Shapiro 	int error;
975b0945b5SGregory Neil Shapiro {
985b0945b5SGregory Neil Shapiro 	int result;
995b0945b5SGregory Neil Shapiro 
1005b0945b5SGregory Neil Shapiro 	switch (error)
1015b0945b5SGregory Neil Shapiro 	{
1025b0945b5SGregory Neil Shapiro 		case 0:
1035b0945b5SGregory Neil Shapiro 			result = SMDBE_OK;
1045b0945b5SGregory Neil Shapiro 			break;
1055b0945b5SGregory Neil Shapiro 
1065b0945b5SGregory Neil Shapiro 		default:
1075b0945b5SGregory Neil Shapiro 			result = error;
1085b0945b5SGregory Neil Shapiro 	}
1095b0945b5SGregory Neil Shapiro 	return result;
1105b0945b5SGregory Neil Shapiro }
1115b0945b5SGregory Neil Shapiro 
1125b0945b5SGregory Neil Shapiro SMDB_CDB_DATABASE *
smcdb_malloc_database()1135b0945b5SGregory Neil Shapiro smcdb_malloc_database()
1145b0945b5SGregory Neil Shapiro {
1155b0945b5SGregory Neil Shapiro 	SMDB_CDB_DATABASE *cdb;
1165b0945b5SGregory Neil Shapiro 
1175b0945b5SGregory Neil Shapiro 	cdb = (SMDB_CDB_DATABASE *) malloc(sizeof(SMDB_CDB_DATABASE));
1185b0945b5SGregory Neil Shapiro 	if (cdb != NULL)
1195b0945b5SGregory Neil Shapiro 		cdb->smcdb_lock_fd = -1;
1205b0945b5SGregory Neil Shapiro 
1215b0945b5SGregory Neil Shapiro 	return cdb;
1225b0945b5SGregory Neil Shapiro }
1235b0945b5SGregory Neil Shapiro 
1245b0945b5SGregory Neil Shapiro static int
smcdb_close(database)1255b0945b5SGregory Neil Shapiro smcdb_close(database)
1265b0945b5SGregory Neil Shapiro 	SMDB_DATABASE *database;
1275b0945b5SGregory Neil Shapiro {
1285b0945b5SGregory Neil Shapiro 	int result, fd;
1295b0945b5SGregory Neil Shapiro 	SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
1305b0945b5SGregory Neil Shapiro 
1315b0945b5SGregory Neil Shapiro 	if (NULL == sm_cdbmap)
1325b0945b5SGregory Neil Shapiro 		return -1;
1335b0945b5SGregory Neil Shapiro 	result = 0;
1345b0945b5SGregory Neil Shapiro 	if (sm_cdbmap->cdbmap_create)
1355b0945b5SGregory Neil Shapiro 		result = cdb_make_finish(&sm_cdbmap->cdbmap_map.cdbs_cdb_wr);
1365b0945b5SGregory Neil Shapiro 
1375b0945b5SGregory Neil Shapiro 	fd = sm_cdbmap->cdbmap_fd;
1385b0945b5SGregory Neil Shapiro 	if (fd >= 0)
1395b0945b5SGregory Neil Shapiro 	{
1405b0945b5SGregory Neil Shapiro 		close(fd);
1415b0945b5SGregory Neil Shapiro 		sm_cdbmap->cdbmap_fd = -1;
1425b0945b5SGregory Neil Shapiro 	}
1435b0945b5SGregory Neil Shapiro 
1445b0945b5SGregory Neil Shapiro 	free(sm_cdbmap);
1455b0945b5SGregory Neil Shapiro 	database->smdb_impl = NULL;
1465b0945b5SGregory Neil Shapiro 
1475b0945b5SGregory Neil Shapiro 	return result;
1485b0945b5SGregory Neil Shapiro }
1495b0945b5SGregory Neil Shapiro 
1505b0945b5SGregory Neil Shapiro static int
smcdb_del(database,key,flags)1515b0945b5SGregory Neil Shapiro smcdb_del(database, key, flags)
1525b0945b5SGregory Neil Shapiro 	SMDB_DATABASE *database;
1535b0945b5SGregory Neil Shapiro 	SMDB_DBENT *key;
1545b0945b5SGregory Neil Shapiro 	unsigned int flags;
1555b0945b5SGregory Neil Shapiro {
1565b0945b5SGregory Neil Shapiro 	SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
1575b0945b5SGregory Neil Shapiro 
1585b0945b5SGregory Neil Shapiro 	assert(sm_cdbmap != NULL);
1595b0945b5SGregory Neil Shapiro 	return -1;
1605b0945b5SGregory Neil Shapiro }
1615b0945b5SGregory Neil Shapiro 
1625b0945b5SGregory Neil Shapiro static int
smcdb_fd(database,fd)1635b0945b5SGregory Neil Shapiro smcdb_fd(database, fd)
1645b0945b5SGregory Neil Shapiro 	SMDB_DATABASE *database;
1655b0945b5SGregory Neil Shapiro 	int *fd;
1665b0945b5SGregory Neil Shapiro {
1675b0945b5SGregory Neil Shapiro 	SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
1685b0945b5SGregory Neil Shapiro 	return sm_cdbmap->cdbmap_fd;
1695b0945b5SGregory Neil Shapiro }
1705b0945b5SGregory Neil Shapiro 
1715b0945b5SGregory Neil Shapiro static int
smcdb_lockfd(database)1725b0945b5SGregory Neil Shapiro smcdb_lockfd(database)
1735b0945b5SGregory Neil Shapiro 	SMDB_DATABASE *database;
1745b0945b5SGregory Neil Shapiro {
1755b0945b5SGregory Neil Shapiro 	SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
1765b0945b5SGregory Neil Shapiro 
1775b0945b5SGregory Neil Shapiro 	return sm_cdbmap->smcdb_lock_fd;
1785b0945b5SGregory Neil Shapiro }
1795b0945b5SGregory Neil Shapiro 
1805b0945b5SGregory Neil Shapiro /*
1815b0945b5SGregory Neil Shapiro **  allocate/free: who does it: caller or callee?
1825b0945b5SGregory Neil Shapiro **  If this code does it: the "last" entry will leak.
1835b0945b5SGregory Neil Shapiro */
1845b0945b5SGregory Neil Shapiro 
1855b0945b5SGregory Neil Shapiro #define DBEALLOC(dbe, l)	\
1865b0945b5SGregory Neil Shapiro 	do	\
1875b0945b5SGregory Neil Shapiro 	{	\
1885b0945b5SGregory Neil Shapiro 		if ((dbe)->size > 0 && l > (dbe)->size)	\
1895b0945b5SGregory Neil Shapiro 		{	\
1905b0945b5SGregory Neil Shapiro 			free((dbe)->data);	\
1915b0945b5SGregory Neil Shapiro 			(dbe)->size = 0;	\
1925b0945b5SGregory Neil Shapiro 		}	\
1935b0945b5SGregory Neil Shapiro 		if ((dbe)->size == 0)	\
1945b0945b5SGregory Neil Shapiro 		{	\
1955b0945b5SGregory Neil Shapiro 			(dbe)->data = malloc(l);	\
1965b0945b5SGregory Neil Shapiro 			if ((dbe)->data == NULL)	\
1975b0945b5SGregory Neil Shapiro 				return SMDBE_MALLOC;	\
1985b0945b5SGregory Neil Shapiro 			(dbe)->size = l;	\
1995b0945b5SGregory Neil Shapiro 		}	\
2005b0945b5SGregory Neil Shapiro 		if (l > (dbe)->size)	\
2015b0945b5SGregory Neil Shapiro 			return SMDBE_MALLOC;	/* XXX bogus */	\
2025b0945b5SGregory Neil Shapiro 	} while (0)
2035b0945b5SGregory Neil Shapiro 
2045b0945b5SGregory Neil Shapiro 
2055b0945b5SGregory Neil Shapiro static int
smcdb_get(database,key,data,flags)2065b0945b5SGregory Neil Shapiro smcdb_get(database, key, data, flags)
2075b0945b5SGregory Neil Shapiro 	SMDB_DATABASE *database;
2085b0945b5SGregory Neil Shapiro 	SMDB_DBENT *key;
2095b0945b5SGregory Neil Shapiro 	SMDB_DBENT *data;
2105b0945b5SGregory Neil Shapiro 	unsigned int flags;
2115b0945b5SGregory Neil Shapiro {
2125b0945b5SGregory Neil Shapiro 	SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
2135b0945b5SGregory Neil Shapiro 	size_t l;
2145b0945b5SGregory Neil Shapiro 	int ret;
2155b0945b5SGregory Neil Shapiro 
2165b0945b5SGregory Neil Shapiro 	ret = SM_SUCCESS;
2175b0945b5SGregory Neil Shapiro 
2185b0945b5SGregory Neil Shapiro 	if (NULL == sm_cdbmap )
2195b0945b5SGregory Neil Shapiro 		return -1;
2205b0945b5SGregory Neil Shapiro 	/* SM_ASSERT(!sm_cdbmap->cdbmap_create); */
2215b0945b5SGregory Neil Shapiro 
2225b0945b5SGregory Neil Shapiro 	/* need to lock access? single threaded access! */
2235b0945b5SGregory Neil Shapiro 	ret = cdb_find(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd,
2245b0945b5SGregory Neil Shapiro 			key->data, key->size);
2255b0945b5SGregory Neil Shapiro 	if (ret > 0)
2265b0945b5SGregory Neil Shapiro 	{
2275b0945b5SGregory Neil Shapiro 		l = cdb_datalen(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd);
2285b0945b5SGregory Neil Shapiro 		DBEALLOC(data, l);
2295b0945b5SGregory Neil Shapiro 		ret = cdb_read(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd,
2305b0945b5SGregory Neil Shapiro 				data->data, l,
2315b0945b5SGregory Neil Shapiro 				cdb_datapos(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd));
2325b0945b5SGregory Neil Shapiro 		if (ret < 0)
2335b0945b5SGregory Neil Shapiro 			ret = -1;
2345b0945b5SGregory Neil Shapiro 		else
2355b0945b5SGregory Neil Shapiro 		{
2365b0945b5SGregory Neil Shapiro 			data->size = l;
2375b0945b5SGregory Neil Shapiro 			ret = SM_SUCCESS;
2385b0945b5SGregory Neil Shapiro 		}
2395b0945b5SGregory Neil Shapiro 	}
2405b0945b5SGregory Neil Shapiro 	else
2415b0945b5SGregory Neil Shapiro 		ret = -1;
2425b0945b5SGregory Neil Shapiro 
2435b0945b5SGregory Neil Shapiro 	return ret;
2445b0945b5SGregory Neil Shapiro }
2455b0945b5SGregory Neil Shapiro 
2465b0945b5SGregory Neil Shapiro static int
smcdb_put(database,key,data,flags)2475b0945b5SGregory Neil Shapiro smcdb_put(database, key, data, flags)
2485b0945b5SGregory Neil Shapiro 	SMDB_DATABASE *database;
2495b0945b5SGregory Neil Shapiro 	SMDB_DBENT *key;
2505b0945b5SGregory Neil Shapiro 	SMDB_DBENT *data;
2515b0945b5SGregory Neil Shapiro 	unsigned int flags;
2525b0945b5SGregory Neil Shapiro {
2535b0945b5SGregory Neil Shapiro 	int r, cdb_flags;
2545b0945b5SGregory Neil Shapiro 	SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
2555b0945b5SGregory Neil Shapiro 
2565b0945b5SGregory Neil Shapiro 	assert(sm_cdbmap != NULL);
2575b0945b5SGregory Neil Shapiro 	if (bitset(SMDBF_NO_OVERWRITE, flags))
2585b0945b5SGregory Neil Shapiro 		cdb_flags = CDB_PUT_INSERT;
2595b0945b5SGregory Neil Shapiro 	else
2605b0945b5SGregory Neil Shapiro 		cdb_flags = CDB_PUT_REPLACE;
2615b0945b5SGregory Neil Shapiro 
2625b0945b5SGregory Neil Shapiro 	r = cdb_make_put(&sm_cdbmap->cdbmap_map.cdbs_cdb_wr,
2635b0945b5SGregory Neil Shapiro 			key->data, key->size, data->data, data->size,
2645b0945b5SGregory Neil Shapiro 			cdb_flags);
2655b0945b5SGregory Neil Shapiro 	if (r > 0)
2665b0945b5SGregory Neil Shapiro 	{
2675b0945b5SGregory Neil Shapiro 		if (bitset(SMDBF_NO_OVERWRITE, flags))
2685b0945b5SGregory Neil Shapiro 			return SMDBE_DUPLICATE;
2695b0945b5SGregory Neil Shapiro 		else
2705b0945b5SGregory Neil Shapiro 			return SMDBE_OK;
2715b0945b5SGregory Neil Shapiro 	}
2725b0945b5SGregory Neil Shapiro 	return r;
2735b0945b5SGregory Neil Shapiro }
2745b0945b5SGregory Neil Shapiro 
2755b0945b5SGregory Neil Shapiro 
2765b0945b5SGregory Neil Shapiro static int
smcdb_set_owner(database,uid,gid)2775b0945b5SGregory Neil Shapiro smcdb_set_owner(database, uid, gid)
2785b0945b5SGregory Neil Shapiro 	SMDB_DATABASE *database;
2795b0945b5SGregory Neil Shapiro 	uid_t uid;
2805b0945b5SGregory Neil Shapiro 	gid_t gid;
2815b0945b5SGregory Neil Shapiro {
2825b0945b5SGregory Neil Shapiro # if HASFCHOWN
2835b0945b5SGregory Neil Shapiro 	int fd;
2845b0945b5SGregory Neil Shapiro 	int result;
2855b0945b5SGregory Neil Shapiro 	SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
2865b0945b5SGregory Neil Shapiro 
2875b0945b5SGregory Neil Shapiro 	assert(sm_cdbmap != NULL);
2885b0945b5SGregory Neil Shapiro 	fd = sm_cdbmap->cdbmap_fd;
2895b0945b5SGregory Neil Shapiro 	if (fd >= 0)
2905b0945b5SGregory Neil Shapiro 	{
2915b0945b5SGregory Neil Shapiro 		result = fchown(fd, uid, gid);
2925b0945b5SGregory Neil Shapiro 		if (result < 0)
2935b0945b5SGregory Neil Shapiro 			return errno;
2945b0945b5SGregory Neil Shapiro 	}
2955b0945b5SGregory Neil Shapiro # endif /* HASFCHOWN */
2965b0945b5SGregory Neil Shapiro 
2975b0945b5SGregory Neil Shapiro 	return SMDBE_OK;
2985b0945b5SGregory Neil Shapiro }
2995b0945b5SGregory Neil Shapiro 
3005b0945b5SGregory Neil Shapiro static int
smcdb_sync(database,flags)3015b0945b5SGregory Neil Shapiro smcdb_sync(database, flags)
3025b0945b5SGregory Neil Shapiro 	SMDB_DATABASE *database;
3035b0945b5SGregory Neil Shapiro 	unsigned int flags;
3045b0945b5SGregory Neil Shapiro {
3055b0945b5SGregory Neil Shapiro 	return 0;
3065b0945b5SGregory Neil Shapiro }
3075b0945b5SGregory Neil Shapiro 
3085b0945b5SGregory Neil Shapiro static int
smcdb_cursor_close(cursor)3095b0945b5SGregory Neil Shapiro smcdb_cursor_close(cursor)
3105b0945b5SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
3115b0945b5SGregory Neil Shapiro {
3125b0945b5SGregory Neil Shapiro 	int ret;
3135b0945b5SGregory Neil Shapiro 
3145b0945b5SGregory Neil Shapiro 	ret = SMDBE_OK;
3155b0945b5SGregory Neil Shapiro 	if (cursor != NULL)
3165b0945b5SGregory Neil Shapiro 		free(cursor);
3175b0945b5SGregory Neil Shapiro 	return ret;
3185b0945b5SGregory Neil Shapiro }
3195b0945b5SGregory Neil Shapiro 
3205b0945b5SGregory Neil Shapiro static int
smcdb_cursor_del(cursor,flags)3215b0945b5SGregory Neil Shapiro smcdb_cursor_del(cursor, flags)
3225b0945b5SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
3235b0945b5SGregory Neil Shapiro 	SMDB_FLAG flags;
3245b0945b5SGregory Neil Shapiro {
3255b0945b5SGregory Neil Shapiro 	return -1;
3265b0945b5SGregory Neil Shapiro }
3275b0945b5SGregory Neil Shapiro 
3285b0945b5SGregory Neil Shapiro static int
smcdb_cursor_get(cursor,key,value,flags)3295b0945b5SGregory Neil Shapiro smcdb_cursor_get(cursor, key, value, flags)
3305b0945b5SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
3315b0945b5SGregory Neil Shapiro 	SMDB_DBENT *key;
3325b0945b5SGregory Neil Shapiro 	SMDB_DBENT *value;
3335b0945b5SGregory Neil Shapiro 	SMDB_FLAG flags;
3345b0945b5SGregory Neil Shapiro {
3355b0945b5SGregory Neil Shapiro 	SMDB_CDB_DATABASE *sm_cdbmap;
3365b0945b5SGregory Neil Shapiro 	size_t l;
3375b0945b5SGregory Neil Shapiro 	int ret;
3385b0945b5SGregory Neil Shapiro 
3395b0945b5SGregory Neil Shapiro 	ret = SMDBE_OK;
3405b0945b5SGregory Neil Shapiro 	sm_cdbmap = cursor->smdbc_impl;
3415b0945b5SGregory Neil Shapiro 	ret = cdb_seqnext(&sm_cdbmap->smcdb_pos, &sm_cdbmap->cdbmap_map.cdbs_cdb_rd);
3425b0945b5SGregory Neil Shapiro 	if (ret == 0)
3435b0945b5SGregory Neil Shapiro 		return SMDBE_LAST_ENTRY;
3445b0945b5SGregory Neil Shapiro 	if (ret < 0)
3455b0945b5SGregory Neil Shapiro 		return SMDBE_IO_ERROR;
3465b0945b5SGregory Neil Shapiro 
3475b0945b5SGregory Neil Shapiro 	l = cdb_keylen(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd);
3485b0945b5SGregory Neil Shapiro 	DBEALLOC(key, l);
3495b0945b5SGregory Neil Shapiro 
3505b0945b5SGregory Neil Shapiro 	ret = cdb_read(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd,
3515b0945b5SGregory Neil Shapiro 			key->data, l,
3525b0945b5SGregory Neil Shapiro 			cdb_keypos(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd));
3535b0945b5SGregory Neil Shapiro 	if (ret < 0)
3545b0945b5SGregory Neil Shapiro 		return SMDBE_IO_ERROR;
3555b0945b5SGregory Neil Shapiro 	key->size = l;
3565b0945b5SGregory Neil Shapiro 
3575b0945b5SGregory Neil Shapiro 	l = cdb_datalen(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd);
3585b0945b5SGregory Neil Shapiro 
3595b0945b5SGregory Neil Shapiro 	DBEALLOC(value, l);
3605b0945b5SGregory Neil Shapiro 	ret = cdb_read(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd,
3615b0945b5SGregory Neil Shapiro 			value->data, l,
3625b0945b5SGregory Neil Shapiro 			cdb_datapos(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd));
3635b0945b5SGregory Neil Shapiro 	if (ret < 0)
3645b0945b5SGregory Neil Shapiro 		return SMDBE_IO_ERROR;
3655b0945b5SGregory Neil Shapiro 	value->size = l;
3665b0945b5SGregory Neil Shapiro 
3675b0945b5SGregory Neil Shapiro 	return SMDBE_OK;
3685b0945b5SGregory Neil Shapiro }
3695b0945b5SGregory Neil Shapiro 
3705b0945b5SGregory Neil Shapiro static int
smcdb_cursor_put(cursor,key,value,flags)3715b0945b5SGregory Neil Shapiro smcdb_cursor_put(cursor, key, value, flags)
3725b0945b5SGregory Neil Shapiro 	SMDB_CURSOR *cursor;
3735b0945b5SGregory Neil Shapiro 	SMDB_DBENT *key;
3745b0945b5SGregory Neil Shapiro 	SMDB_DBENT *value;
3755b0945b5SGregory Neil Shapiro 	SMDB_FLAG flags;
3765b0945b5SGregory Neil Shapiro {
3775b0945b5SGregory Neil Shapiro 	return -1;
3785b0945b5SGregory Neil Shapiro }
3795b0945b5SGregory Neil Shapiro 
3805b0945b5SGregory Neil Shapiro static int
smcdb_cursor(database,cursor,flags)3815b0945b5SGregory Neil Shapiro smcdb_cursor(database, cursor, flags)
3825b0945b5SGregory Neil Shapiro 	SMDB_DATABASE *database;
3835b0945b5SGregory Neil Shapiro 	SMDB_CURSOR **cursor;
3845b0945b5SGregory Neil Shapiro 	SMDB_FLAG flags;
3855b0945b5SGregory Neil Shapiro {
3865b0945b5SGregory Neil Shapiro 	int result;
3875b0945b5SGregory Neil Shapiro 	SMDB_CDB_DATABASE *sm_cdbmap;
3885b0945b5SGregory Neil Shapiro 
3895b0945b5SGregory Neil Shapiro 	result = SMDBE_OK;
3905b0945b5SGregory Neil Shapiro 	*cursor = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR));
3915b0945b5SGregory Neil Shapiro 	if (*cursor == NULL)
3925b0945b5SGregory Neil Shapiro 		return SMDBE_MALLOC;
3935b0945b5SGregory Neil Shapiro 
3945b0945b5SGregory Neil Shapiro 	sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
3955b0945b5SGregory Neil Shapiro 	(*cursor)->smdbc_close = smcdb_cursor_close;
3965b0945b5SGregory Neil Shapiro 	(*cursor)->smdbc_del = smcdb_cursor_del;
3975b0945b5SGregory Neil Shapiro 	(*cursor)->smdbc_get = smcdb_cursor_get;
3985b0945b5SGregory Neil Shapiro 	(*cursor)->smdbc_put = smcdb_cursor_put;
3995b0945b5SGregory Neil Shapiro 	(*cursor)->smdbc_impl = sm_cdbmap;
4005b0945b5SGregory Neil Shapiro 
4015b0945b5SGregory Neil Shapiro 	cdb_seqinit(&sm_cdbmap->smcdb_pos, &sm_cdbmap->cdbmap_map.cdbs_cdb_rd);
4025b0945b5SGregory Neil Shapiro 
4035b0945b5SGregory Neil Shapiro 	return result;
4045b0945b5SGregory Neil Shapiro }
4055b0945b5SGregory Neil Shapiro 
4065b0945b5SGregory Neil Shapiro /*
4072fb4f839SGregory Neil Shapiro **  SMDB_CDB_OPEN -- Opens a cdb database.
4085b0945b5SGregory Neil Shapiro **
4095b0945b5SGregory Neil Shapiro **	Parameters:
4105b0945b5SGregory Neil Shapiro **		database -- An unallocated database pointer to a pointer.
4115b0945b5SGregory Neil Shapiro **		db_name -- The name of the database without extension.
412*d39bd2c1SGregory Neil Shapiro **		mode -- File permissions for a created database.
4135b0945b5SGregory Neil Shapiro **		mode_mask -- Mode bits that must match on an opened database.
4145b0945b5SGregory Neil Shapiro **		sff -- Flags for safefile.
4155b0945b5SGregory Neil Shapiro **		type -- The type of database to open
4165b0945b5SGregory Neil Shapiro **			See smdb_type_to_cdb_type for valid types.
4175b0945b5SGregory Neil Shapiro **		user_info -- User information for file permissions.
4182fb4f839SGregory Neil Shapiro **		db_params -- unused
4195b0945b5SGregory Neil Shapiro **
4205b0945b5SGregory Neil Shapiro **	Returns:
4215b0945b5SGregory Neil Shapiro **		SMDBE_OK -- Success, other errno:
4225b0945b5SGregory Neil Shapiro **		SMDBE_MALLOC -- Cannot allocate memory.
4232fb4f839SGregory Neil Shapiro **		SMDBE_BAD_OPEN -- various (OS) errors.
4245b0945b5SGregory Neil Shapiro **		Anything else: translated error from cdb
4255b0945b5SGregory Neil Shapiro */
4265b0945b5SGregory Neil Shapiro 
4275b0945b5SGregory Neil Shapiro int
smdb_cdb_open(database,db_name,mode,mode_mask,sff,type,user_info,db_params)4285b0945b5SGregory Neil Shapiro smdb_cdb_open(database, db_name, mode, mode_mask, sff, type, user_info, db_params)
4295b0945b5SGregory Neil Shapiro 	SMDB_DATABASE **database;
4305b0945b5SGregory Neil Shapiro 	char *db_name;
4315b0945b5SGregory Neil Shapiro 	int mode;
4325b0945b5SGregory Neil Shapiro 	int mode_mask;
4335b0945b5SGregory Neil Shapiro 	long sff;
4345b0945b5SGregory Neil Shapiro 	SMDB_DBTYPE type;
4355b0945b5SGregory Neil Shapiro 	SMDB_USER_INFO *user_info;
4365b0945b5SGregory Neil Shapiro 	SMDB_DBPARAMS *db_params;
4375b0945b5SGregory Neil Shapiro {
4385b0945b5SGregory Neil Shapiro 	bool lockcreated = false;
4395b0945b5SGregory Neil Shapiro 	int result;
4405b0945b5SGregory Neil Shapiro 	int lock_fd;
4415b0945b5SGregory Neil Shapiro 	int db_fd;
4425b0945b5SGregory Neil Shapiro 	SMDB_DATABASE *smdb_db;
4435b0945b5SGregory Neil Shapiro 	SMDB_CDB_DATABASE *sm_cdbmap;
4445b0945b5SGregory Neil Shapiro 	struct stat stat_info;
4455b0945b5SGregory Neil Shapiro 	char db_file_name[MAXPATHLEN];
4465b0945b5SGregory Neil Shapiro 
4475b0945b5SGregory Neil Shapiro 	*database = NULL;
4485b0945b5SGregory Neil Shapiro 	result = smdb_add_extension(db_file_name, sizeof db_file_name,
4495b0945b5SGregory Neil Shapiro 				    db_name, SMCDB_FILE_EXTENSION);
4505b0945b5SGregory Neil Shapiro 	if (result != SMDBE_OK)
4515b0945b5SGregory Neil Shapiro 		return result;
4525b0945b5SGregory Neil Shapiro 
4535b0945b5SGregory Neil Shapiro 	result = smdb_setup_file(db_name, SMCDB_FILE_EXTENSION,
4545b0945b5SGregory Neil Shapiro 				 mode_mask, sff, user_info, &stat_info);
4555b0945b5SGregory Neil Shapiro 	if (result != SMDBE_OK)
4565b0945b5SGregory Neil Shapiro 		return result;
4575b0945b5SGregory Neil Shapiro 
4585b0945b5SGregory Neil Shapiro 	lock_fd = -1;
4595b0945b5SGregory Neil Shapiro 
4605b0945b5SGregory Neil Shapiro 	if (stat_info.st_mode == ST_MODE_NOFILE &&
4615b0945b5SGregory Neil Shapiro 	    bitset(mode, O_CREAT))
4625b0945b5SGregory Neil Shapiro 		lockcreated = true;
4635b0945b5SGregory Neil Shapiro 
4645b0945b5SGregory Neil Shapiro 	result = smdb_lock_file(&lock_fd, db_name, mode, sff,
4655b0945b5SGregory Neil Shapiro 				SMCDB_FILE_EXTENSION);
4665b0945b5SGregory Neil Shapiro 	if (result != SMDBE_OK)
4675b0945b5SGregory Neil Shapiro 		return result;
4685b0945b5SGregory Neil Shapiro 
4695b0945b5SGregory Neil Shapiro 	if (lockcreated)
4705b0945b5SGregory Neil Shapiro 	{
4715b0945b5SGregory Neil Shapiro 		mode |= O_TRUNC;
4725b0945b5SGregory Neil Shapiro 		mode &= ~(O_CREAT|O_EXCL);
4735b0945b5SGregory Neil Shapiro 	}
4745b0945b5SGregory Neil Shapiro 
4755b0945b5SGregory Neil Shapiro 	smdb_db = smdb_malloc_database();
4765b0945b5SGregory Neil Shapiro 	sm_cdbmap = smcdb_malloc_database();
4775b0945b5SGregory Neil Shapiro 	if (sm_cdbmap == NULL || smdb_db == NULL)
4785b0945b5SGregory Neil Shapiro 	{
4795b0945b5SGregory Neil Shapiro 		smdb_unlock_file(lock_fd);
4805b0945b5SGregory Neil Shapiro 		smdb_free_database(smdb_db);	/* ok to be NULL */
4815b0945b5SGregory Neil Shapiro 		if (sm_cdbmap != NULL)
4825b0945b5SGregory Neil Shapiro 			free(sm_cdbmap);
4835b0945b5SGregory Neil Shapiro 		return SMDBE_MALLOC;
4845b0945b5SGregory Neil Shapiro 	}
4855b0945b5SGregory Neil Shapiro 
4865b0945b5SGregory Neil Shapiro 	sm_cdbmap->smcdb_lock_fd = lock_fd;
4875b0945b5SGregory Neil Shapiro 
4885b0945b5SGregory Neil Shapiro # if 0
4895b0945b5SGregory Neil Shapiro 	db = NULL;
4905b0945b5SGregory Neil Shapiro 	db_flags = 0;
4915b0945b5SGregory Neil Shapiro 	if (bitset(O_CREAT, mode))
4925b0945b5SGregory Neil Shapiro 		db_flags |= DB_CREATE;
4935b0945b5SGregory Neil Shapiro 	if (bitset(O_TRUNC, mode))
4945b0945b5SGregory Neil Shapiro 		db_flags |= DB_TRUNCATE;
4955b0945b5SGregory Neil Shapiro 	if (mode == O_RDONLY)
4965b0945b5SGregory Neil Shapiro 		db_flags |= DB_RDONLY;
4975b0945b5SGregory Neil Shapiro 	SM_DB_FLAG_ADD(db_flags);
4985b0945b5SGregory Neil Shapiro # endif
4995b0945b5SGregory Neil Shapiro 
5005b0945b5SGregory Neil Shapiro 	result = -1; /* smdb_db_open_internal(db_file_name, db_type, db_flags, db_params, &db); */
5015b0945b5SGregory Neil Shapiro 	db_fd = open(db_file_name, mode, DBMMODE);
5025b0945b5SGregory Neil Shapiro 	if (db_fd == -1)
5035b0945b5SGregory Neil Shapiro 	{
5045b0945b5SGregory Neil Shapiro 		result = SMDBE_BAD_OPEN;
5055b0945b5SGregory Neil Shapiro 		goto error;
5065b0945b5SGregory Neil Shapiro 	}
5075b0945b5SGregory Neil Shapiro 
5085b0945b5SGregory Neil Shapiro 	sm_cdbmap->cdbmap_create = (mode != O_RDONLY);
5095b0945b5SGregory Neil Shapiro 	if (mode == O_RDONLY)
5105b0945b5SGregory Neil Shapiro 		result = cdb_init(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd, db_fd);
5115b0945b5SGregory Neil Shapiro 	else
5125b0945b5SGregory Neil Shapiro 		result = cdb_make_start(&sm_cdbmap->cdbmap_map.cdbs_cdb_wr, db_fd);
5135b0945b5SGregory Neil Shapiro 	if (result != 0)
5145b0945b5SGregory Neil Shapiro 	{
5155b0945b5SGregory Neil Shapiro 		result = SMDBE_BAD_OPEN;
5165b0945b5SGregory Neil Shapiro 		goto error;
5175b0945b5SGregory Neil Shapiro 	}
5185b0945b5SGregory Neil Shapiro 
5195b0945b5SGregory Neil Shapiro 	if (result == 0)
5205b0945b5SGregory Neil Shapiro 		result = SMDBE_OK;
5215b0945b5SGregory Neil Shapiro 	else
5225b0945b5SGregory Neil Shapiro 	{
5235b0945b5SGregory Neil Shapiro 		/* Try and narrow down on the problem */
5245b0945b5SGregory Neil Shapiro 		if (result != 0)
5255b0945b5SGregory Neil Shapiro 			result = cdb_error_to_smdb(result);
5265b0945b5SGregory Neil Shapiro 		else
5275b0945b5SGregory Neil Shapiro 			result = SMDBE_BAD_OPEN;
5285b0945b5SGregory Neil Shapiro 	}
5295b0945b5SGregory Neil Shapiro 
5305b0945b5SGregory Neil Shapiro 	if (result == SMDBE_OK)
5315b0945b5SGregory Neil Shapiro 		result = smdb_filechanged(db_name, SMCDB_FILE_EXTENSION, db_fd,
5325b0945b5SGregory Neil Shapiro 					  &stat_info);
5335b0945b5SGregory Neil Shapiro 
5345b0945b5SGregory Neil Shapiro 	if (result == SMDBE_OK)
5355b0945b5SGregory Neil Shapiro 	{
5365b0945b5SGregory Neil Shapiro 		/* Everything is ok. Setup driver */
5375b0945b5SGregory Neil Shapiro 		/* smdb_db->smcdb_db = sm_cdbmap; */
5385b0945b5SGregory Neil Shapiro 
5395b0945b5SGregory Neil Shapiro 		smdb_db->smdb_close = smcdb_close;
5405b0945b5SGregory Neil Shapiro 		smdb_db->smdb_del = smcdb_del;
5415b0945b5SGregory Neil Shapiro 		smdb_db->smdb_fd = smcdb_fd;
5425b0945b5SGregory Neil Shapiro 		smdb_db->smdb_lockfd = smcdb_lockfd;
5435b0945b5SGregory Neil Shapiro 		smdb_db->smdb_get = smcdb_get;
5445b0945b5SGregory Neil Shapiro 		smdb_db->smdb_put = smcdb_put;
5455b0945b5SGregory Neil Shapiro 		smdb_db->smdb_set_owner = smcdb_set_owner;
5465b0945b5SGregory Neil Shapiro 		smdb_db->smdb_sync = smcdb_sync;
5475b0945b5SGregory Neil Shapiro 		smdb_db->smdb_cursor = smcdb_cursor;
5485b0945b5SGregory Neil Shapiro 		smdb_db->smdb_impl = sm_cdbmap;
5495b0945b5SGregory Neil Shapiro 
5505b0945b5SGregory Neil Shapiro 		*database = smdb_db;
5515b0945b5SGregory Neil Shapiro 
5525b0945b5SGregory Neil Shapiro 		return SMDBE_OK;
5535b0945b5SGregory Neil Shapiro 	}
5545b0945b5SGregory Neil Shapiro 
5555b0945b5SGregory Neil Shapiro   error:
5565b0945b5SGregory Neil Shapiro 	if (sm_cdbmap != NULL)
5575b0945b5SGregory Neil Shapiro 	{
5585b0945b5SGregory Neil Shapiro 		/* close */
5595b0945b5SGregory Neil Shapiro 	}
5605b0945b5SGregory Neil Shapiro 
5615b0945b5SGregory Neil Shapiro 	smdb_unlock_file(sm_cdbmap->smcdb_lock_fd);
5625b0945b5SGregory Neil Shapiro 	free(sm_cdbmap);
5635b0945b5SGregory Neil Shapiro 	smdb_free_database(smdb_db);
5645b0945b5SGregory Neil Shapiro 
5655b0945b5SGregory Neil Shapiro 	return result;
5665b0945b5SGregory Neil Shapiro }
5675b0945b5SGregory Neil Shapiro 
5685b0945b5SGregory Neil Shapiro #endif /* CDB */
569