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