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