/* Copyright (C) 2015-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk4dbi.ctr */ /** @file dk4dbi.c The dk4dbi module. */ #line 576 "dk4dbi.ctr" #include "dk4conf.h" #if DK4_HAVE_ERRNO_H #ifndef ERRNO_H_INCLUDED #include #define ERRNO_H_INCLUDED 1 #endif #endif #if DK4_HAVE_SYS_STAT_H #ifndef SYS_STAT_H_INCLUDED #include #define SYS_STAT_H_INCLUDED 1 #endif #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif #include "dk4dbi.h" #include "dk4mem.h" #include "dk4memrs.h" #include "dk4strd.h" #include "dk4fopd.h" #include "dk4numco.h" #include "dk4isadm.h" #include "dk4fopt.h" #include "dk4mpl.h" #include "dk4delfile.h" #include "dk4stat.h" #include "dk4statd.h" #include "dk4maadu.h" #include "dk4unused.h" #line 618 "dk4dbi.ctr" /** One storage entry. */ typedef struct { void *kd; /**< Key data. */ void *vd; /**< Value data. */ size_t ks; /**< Key size. */ size_t vs; /**< Value size. */ } dk4_dbi_datum_t; /** Backend type names. */ static const dkChar *dk4dbi_type_names[] = { /* 0 */ dkT("mem"), /* 1 */ dkT("bdb"), /* 2 */ dkT("ndbm"), NULL #line 640 "dk4dbi.ctr" }; /** File name suffixes for NDBM files. */ #if (DK4_CHAR_SIZE == 1) \ && (\ (DK4_HAVE_NDBM_H) \ || ((!(DK4_ON_WINDOWS)) && (DK4_HAVE_CHOWN) && (DK4_HAVE_CHMOD))\ ) static const dkChar *dk4dbi_ndbm_suffixes[] = { dkT(".dir"), dkT(".pag") }; #endif /** Delete one record from an in-memory database, release resources. @param ptr Record to delete @param options The database options. @return 1 on success, 0 on error. */ static int dk4dbi_datum_delete(dk4_dbi_datum_t *ptr, int options) { int back = 0; #line 671 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { back = 1; if (0 != (DK4_DB_OPT_RESET_KEY & options)) { if ((NULL != ptr->kd) && ((size_t)0UL < ptr->ks)) { #line 679 "dk4dbi.ctr" if (0 == dk4mem_reset_secure(ptr->kd, ptr->ks, NULL)) { back = 0; } } } if (0 != (DK4_DB_OPT_RESET_VALUE & options)) { if ((NULL != ptr->vd) && ((size_t)0UL < ptr->vs)) { #line 687 "dk4dbi.ctr" if (0 == dk4mem_reset_secure(ptr->vd, ptr->vs, NULL)) { back = 0; } } } dk4mem_release(ptr->kd); dk4mem_release(ptr->vd); ptr->ks = ptr->vs = (size_t)0UL; dk4mem_free(ptr); } #line 698 "dk4dbi.ctr" return back; } /** Allocate memory for a new record. @param ks @param vs @param erp @return Pointer to new record structure on success, NULL on error. Error codes: - DK4_E_MEMORY_ALLOCATION_FAILED
with mem.elsize and mem.nelem set if there is not enough memory available. */ static dk4_dbi_datum_t * dk4dbi_datum_new( size_t ks, size_t vs, dk4_er_t *erp ) { dk4_dbi_datum_t *back = NULL; #line 725 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(0 < ks); assert(0 < vs); #endif back = dk4mem_new(dk4_dbi_datum_t,1,erp); if (NULL != back) { back->kd = back->vd = NULL; back->ks = back->vs = (size_t)0UL; if (0 < ks) { back->kd = dk4mem_new(char,ks,erp); } if (0 < vs) { back->vd = dk4mem_new(char,vs,erp); } if ((NULL != back->kd) && (NULL != back->vd)) { back->ks = ks; back->vs = vs; } else { dk4mem_release(back->kd); dk4mem_release(back->vd); dk4mem_free(back); back = NULL; } } #line 744 "dk4dbi.ctr" return back; } /** Write in-memory database contents back to file. @param db Database to save. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_SYNTAX
if the database file name does not refer to a regular file, - DK4_E_SEC_CHECK
with failed check id in iDetails1 if access is denied by additional security checks, - DK4_E_OPEN_WRITE_FAILED
with errno value in iDetails1 if fopen() or fwrite() failed, - DK4_E_CLOSE_FAILED
with errno value in iDetails1 if fclose() failed, - DK4_E_WRITE_FAILD
if fwrite() failed. */ static int dk4dbi_mem_to_file( dk4_dbi_t *db, dk4_er_t *erp ) { FILE *fipo = NULL; /* Write text ile */ dk4_dbi_datum_t *rp = NULL; /* Current record */ unsigned char uc[8]; /* Sizes byte array */ size_t nbw = 0; /* Number of bytes */ int tests = DK4_FOPEN_SC_USER; /* Security checks */ int back = 0; #line 783 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); #endif if (dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; } fipo = dk4fopen(db->fn, dkT("wb"), tests, erp); if (NULL != fipo) { #line 789 "dk4dbi.ctr" back = 1; dk4sto_it_reset((db->dt).mem.i); do { rp = (dk4_dbi_datum_t *)dk4sto_it_next((db->dt).mem.i); if (NULL != rp) { #line 794 "dk4dbi.ctr" uc[0] = (unsigned char)(((unsigned long)(rp->ks) >> 24) & 0x000000FFUL); uc[1] = (unsigned char)(((unsigned long)(rp->ks) >> 16) & 0x000000FFUL); uc[2] = (unsigned char)(((unsigned long)(rp->ks) >> 8) & 0x000000FFUL); uc[3] = (unsigned char)(((unsigned long)(rp->ks) ) & 0x000000FFUL); uc[4] = (unsigned char)(((unsigned long)(rp->vs) >> 24) & 0x000000FFUL); uc[5] = (unsigned char)(((unsigned long)(rp->vs) >> 16) & 0x000000FFUL); uc[6] = (unsigned char)(((unsigned long)(rp->vs) >> 8) & 0x000000FFUL); uc[7] = (unsigned char)(((unsigned long)(rp->vs) ) & 0x000000FFUL); nbw = fwrite(uc, 1, 8, fipo); if (8 == nbw) { #line 804 "dk4dbi.ctr" nbw = fwrite(rp->kd, 1, rp->ks, fipo); if (rp->ks == nbw) { #line 806 "dk4dbi.ctr" nbw = fwrite(rp->vd, 1, rp->vs, fipo); if (rp->vs == nbw) { #line 808 "dk4dbi.ctr" } else { back = 0; #line 810 "dk4dbi.ctr" dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); } } else { #line 813 "dk4dbi.ctr" back = 0; dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); } } else { #line 817 "dk4dbi.ctr" back = 0; dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); } } } while (NULL != rp); if (0 != fclose(fipo)) { #line 823 "dk4dbi.ctr" back = 0; dk4error_set_idetails(erp, DK4_E_CLOSE_FAILED, errno); } } else { #line 827 "dk4dbi.ctr" } if (0 != back) { db->uc = 0; } #line 832 "dk4dbi.ctr" return back; } /** Read in-memory database contents back from file. @param db Database to restore. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_SYNTAX
if - the database file name does not refer to a regular file - or the file contents is not an in-memory database - or key/value sizes in the file are in conflict with size restrictions, - DK4_E_SEC_CHECK
with failed check id in iDetails1 if access is denied by additional security checks, - DK4_E_MEMORY_ALLOCATION_FAILED
with mem.elsize and mem.nelem set if there is not enough memory available, - DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen() or fread() failed. */ static int dk4dbi_mem_from_file( dk4_dbi_t *db, dk4_er_t *erp ) { dk4_stat_t stb; /* File stat buffer */ FILE *fipo = NULL; /* Input file */ dk4_dbi_datum_t *rp = NULL; /* Current record to process */ unsigned char uc[8]; /* Buffer to read sizes */ size_t nbr = 0; /* Number of bytes read */ size_t ks = 0; /* Key size */ size_t vs = 0; /* Value size */ unsigned long ul1 = 0UL; /* Key size */ unsigned long ul2 = 0UL; /* Value size */ int back = 0; /* Result */ int cc = 1; /* Flag: Can continue */ #line 876 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); #endif fipo = dk4fopen(db->fn, dkT("rb"), 0, erp); if (NULL != fipo) { back = 1; do { nbr = fread(uc, 1, 8, fipo); if (8 == nbr) { #line 885 "dk4dbi.ctr" ul1 = ((((unsigned long)(uc[0])) << 24) & 0xFF000000UL) | ((((unsigned long)(uc[1])) << 16) & 0x00FF0000UL) | ((((unsigned long)(uc[2])) << 8) & 0x0000FF00UL) | ((((unsigned long)(uc[3])) ) & 0x000000FFUL); ul2 = ((((unsigned long)(uc[4])) << 24) & 0xFF000000UL) | ((((unsigned long)(uc[5])) << 16) & 0x00FF0000UL) | ((((unsigned long)(uc[6])) << 8) & 0x0000FF00UL) | ((((unsigned long)(uc[7])) ) & 0x000000FFUL); #if 0 if ((dk4_um_t)(SIZE_MAX) >= (dk4_um_t)ul1) #endif if (0 != dk4ma_um_isgeq(SIZE_MAX, ul1)) { #if 0 if ((dk4_um_t)(SIZE_MAX) >= (dk4_um_t)ul2) #endif if (0 != dk4ma_um_isgeq(SIZE_MAX, ul2)) { ks = (size_t)ul1; vs = (size_t)ul2; if ( (((size_t)0UL == db->km) || (db->km >= ks)) && (((size_t)0UL == db->vm) || (db->vm >= vs)) && ((size_t)0UL < ks) && ((size_t)0UL < vs) ) { rp = dk4dbi_datum_new(ks, vs, erp); if (NULL != rp) { #line 910 "dk4dbi.ctr" nbr = fread(rp->kd, 1, rp->ks, fipo); if (nbr == rp->ks) { nbr = fread(rp->vd, 1, rp->vs, fipo); if (nbr == rp->vs) { if (0 == dk4sto_add((db->dt).mem.s, rp, erp)) { cc = 0; #line 916 "dk4dbi.ctr" back = 0; dk4dbi_datum_delete(rp, 0); } } else { #line 920 "dk4dbi.ctr" cc = 0; back = 0; dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); dk4dbi_datum_delete(rp, 0); } } else { #line 926 "dk4dbi.ctr" cc = 0; back = 0; dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); dk4dbi_datum_delete(rp, 0); } } else { #line 932 "dk4dbi.ctr" cc = 0; back = 0; } } else { #line 938 "dk4dbi.ctr" cc = 0; back = 0; dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { #line 943 "dk4dbi.ctr" cc = 0; back = 0; dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { #line 948 "dk4dbi.ctr" cc = 0; back = 0; dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { #line 953 "dk4dbi.ctr" cc = 0; if (0 != nbr) { back = 0; dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } } while (0 != cc); (void)fclose(fipo); } else { #line 962 "dk4dbi.ctr" if (0 == dk4stat(&stb, db->fn, NULL)) { back = 1; #line 964 "dk4dbi.ctr" } } #line 967 "dk4dbi.ctr" return back; } /** Compare two entries. @param l Left record. @param r Right record. @param cr Comparison criteria, ignored. @return 1 if l>r, 0 if l==r, -1 if lkd) { if (NULL != pr->kd) { if (pl->ks > pr->ks) { back = 1; } else { if (pl->ks < pr->ks) { back = -1; } else { if (0 < pl->ks) { back = DK4_MEMCMP(pl->kd, pr->kd, pl->ks); if (-1 > back) back = -1; if ( 1 < back) back = 1; } } } } else { back = 1; } } else { if (NULL != pr->kd) { back = -1; } } } else { back = 1; } } else { if (NULL != r) { back = -1; } } #line 1019 "dk4dbi.ctr" return back; } /** Delete base database structure, release resources. @param ptr Database structure to release. */ static void dk4dbi_delete_base(dk4_dbi_t *ptr) { #line 1032 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { dk4mem_release(ptr->fn); dk4mem_free(ptr); } #line 1040 "dk4dbi.ctr" } /** Allocate memory for a database. @param fn File name. @param tp Backend type. @param wa Flag: Write access required. @param km @param vm @param erp Error report, may be NULL. @return Pointer to memory on success, NULL on error. Error codes: - DK4_E_MATH_OVERFLOW
on numeric overflow when calculating size, - DK4_E_MEMORY_ALLOCATION_FAILED
with mem.elsize and mem.nelem set if there is not enough memory available. */ static dk4_dbi_t * dk4dbi_new_base( const dkChar *fn, int tp, int wa, size_t km, size_t vm, dk4_er_t *erp ) { dk4_dbi_t *back = NULL; #line 1073 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != fn); assert((DK4_DB_BE_MEMORY == tp) || (DK4_DB_BE_BDB == tp) || (DK4_DB_BE_NDBM == tp)); #endif back = dk4mem_new(dk4_dbi_t,1,erp); if (NULL != back) { back->tp = tp; back->wa = wa; back->op = 0; back->uc = 0; back->km = km; back->vm = vm; switch (tp) { case DK4_DB_BE_MEMORY : { (back->dt).mem.s = NULL; (back->dt).mem.i = NULL; } break; case DK4_DB_BE_BDB : { #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) (back->dt).bdb.db = NULL; #endif } break; case DK4_DB_BE_NDBM : { #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) (back->dt).ndbm.dbm = NULL; #endif } break; } back->fn = dk4str_dup(fn, erp); if (NULL == back->fn) { #line 1103 "dk4dbi.ctr" dk4mem_free(back); back = NULL; } } #line 1108 "dk4dbi.ctr" return back; } /** Close database, release resources. NOTE: Only release in-memory specific things, the dk4dbi_close() function calls dk4dbi_delete_base() to release the base components. @param db Database to close. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_SYNTAX
if the database file name does not refer to a regular file, - DK4_E_SEC_CHECK
with failed check id in iDetails1 if access is denied by additional security checks, - DK4_E_OPEN_WRITE_FAILED
with errno value in iDetails1 if fopen() or fwrite() failed, - DK4_E_CLOSE_FAILED
with errno value in iDetails1 if fclose() failed, - DK4_E_WRITE_FAILD
if fwrite() failed. */ static int dk4dbi_close_mem( dk4_dbi_t *db, dk4_er_t *erp ) { dk4_dbi_datum_t *rp; /* Current record */ int back = 1; #line 1144 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); #endif if ((NULL != (db->dt).mem.s) && (NULL != (db->dt).mem.i)) { /* Write records to file if there are unsaved changes. */ #line 1152 "dk4dbi.ctr" if ((0 != db->wa) && (0 != db->uc)) { if (0 == dk4dbi_mem_to_file(db, erp)) { back = 0; } } /* Release memory used for the records. */ dk4sto_it_reset((db->dt).mem.i); do { rp = (dk4_dbi_datum_t *)dk4sto_it_next((db->dt).mem.i); if (NULL != rp) { if (0 == dk4dbi_datum_delete(rp, db->op)) { back = 0; } } } while (NULL != rp); } if (NULL != (db->dt).mem.i) { dk4sto_it_close((db->dt).mem.i); } if (NULL != (db->dt).mem.s) { dk4sto_close((db->dt).mem.s); } #line 1176 "dk4dbi.ctr" return back; } /** Open in-memory database. @param fn File name. @param wa Flag: Write access required. @param tr Flag: Truncate existing database. @param km Maximum key size. @param vm Maximum value size. @param erp Error report, may be NULL. @return Pointer to new database structure on success, NULL on error. Error codes: - DK4_E_MATH_OVERFLOW
on numeric overflow when calculating size, - DK4_E_MEMORY_ALLOCATION_FAILED
with mem.elsize and mem.nelem set if there is not enough memory available, - DK4_E_SYNTAX
if - the database file name does not refer to a regular file - or the file contents is not an in-memory database - or key/value sizes in the file are in conflict with size restrictions, - DK4_E_SEC_CHECK
with failed check id in iDetails1 if access is denied by additional security checks, - DK4_E_OPEN_READ_FAILED with errno value in iDetails1 if fopen() or fread() failed, - DK4_E_OPEN_WRITE_FAILED
with errno value in iDetails1 if fopen() or fwrite() failed, - DK4_E_CLOSE_FAILED
with errno value in iDetails1 if fclose() failed. */ static dk4_dbi_t * dk4dbi_open_mem( const dkChar *fn, int wa, int tr, size_t km, size_t vm, dk4_er_t *erp ) { dk4_dbi_t *back = NULL; #line 1224 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != fn); #endif if (0 != tr) { (void)dk4delete_file(fn, NULL); } back = dk4dbi_new_base(fn, DK4_DB_BE_MEMORY, wa, km, vm, erp); if (NULL != back) { (back->dt).mem.s = NULL; (back->dt).mem.i = NULL; (back->dt).mem.s = dk4sto_open(erp); if (NULL != (back->dt).mem.s) { dk4sto_set_comp((back->dt).mem.s, dk4dbi_datum_compare, 0); (back->dt).mem.i = dk4sto_it_open((back->dt).mem.s, erp); } if ((NULL != (back->dt).mem.s) && (NULL != (back->dt).mem.i)) { if (0 == tr) { /* Do not truncate */ if (0 == dk4dbi_mem_from_file(back, erp)) { (void)dk4dbi_close_mem(back, NULL); back = NULL; } } else { /* Truncate */ if (0 == dk4dbi_mem_to_file(back, erp)) { (void)dk4dbi_close_mem(back, NULL); back = NULL; } } } else { (void)dk4dbi_close_mem(back, NULL); back = NULL; } } #line 1257 "dk4dbi.ctr" return back; } #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) /** Close database, release resources. NOTE: Only release in-memory specific things, the dk4dbi_close() function calls dk4dbi_delete_base() to release the base components. @param db Database to close. @return 1 on success, 0 on error. Error codes: - DK4_E_SYNTAX
if the database file name does not refer to a regular file, - DK4_E_SEC_CHECK
with failed check id in iDetails1 if access is denied by additional security checks, - DK4_E_OPEN_WRITE_FAILED
with errno value in iDetails1 if fopen() or fwrite() failed, - DK4_E_CLOSE_FAILED
with errno value in iDetails1 if fclose() failed, - DK4_E_WRITE_FAILD
if fwrite() failed. */ static int dk4dbi_close_bdb( dk4_dbi_t *db ) { int back = 1; #if DK4_USE_ASSERT assert(NULL != db); #endif if (NULL != (db->dt).bdb.db) { if ((0 != db->wa) && (0 != db->uc)) { if (0 != ((db->dt).bdb.db)->sync((db->dt).bdb.db, 0)) { back = 0; } } ((db->dt).bdb.db)->close((db->dt).bdb.db, 0); (db->dt).bdb.db = NULL; } return back; } /** Open BDB database. @param fn File name. @param wa Flag: Write access required. @param tr Flag: Truncate existing database. @param km Maximum key size. @param vm Maximum value size. @param erp Error report, may be NULL. @return Pointer to new database structure on success, NULL on error. Error codes: - DK4_E_MATH_OVERFLOW
on numeric overflow when calculating size, - DK4_E_MEMORY_ALLOCATION_FAILED
with mem.elsize and mem.nelem set if there is not enough memory available, - DK4_E_OPEN_WRITE_FAILED
if the database can not be opened for writing, - DK4_E_OPEN_READ_FAILED
if the database can not be opened or reading, - DK4_E_NOT_SUPPORTED
when attempting to provide a wchar_t file name on non-Windows systems. */ static dk4_dbi_t * dk4dbi_open_bdb( const dkChar *fn, int wa, int tr, size_t km, size_t vm, dk4_er_t *erp ) { #if DK4_CHAR_SIZE > 1 #if DK4_ON_WINDOWS dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return NULL; #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return NULL; #endif #else dk4_dbi_t *back = NULL; int res = 0; int flags = 0; #line 1356 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != fn); #endif back = dk4dbi_new_base(fn, DK4_DB_BE_BDB, wa, km, vm, erp); if (NULL != back) { if (0 != tr) { (void)dk4delete_file(fn, NULL); } res = db_create(&((back->dt).bdb.db), NULL, 0); if (0 == res) { ((back->dt).bdb.db)->set_errfile((back->dt).bdb.db, NULL); flags = ((0 != wa) ? ((0 != tr) ? ((DB_CREATE) | (DB_TRUNCATE)) : (DB_CREATE)) : (DB_RDONLY)); res = ((back->dt).bdb.db)->open( (back->dt).bdb.db, NULL, back->fn, NULL, DB_BTREE, flags, 0600 ); if (0 != res) { ((back->dt).bdb.db)->close((back->dt).bdb.db, 0); (back->dt).bdb.db = NULL; dk4dbi_delete_base(back); back = NULL; dk4error_set_simple_error_code( erp, ((0 != wa) ? (DK4_E_OPEN_WRITE_FAILED) : (DK4_E_OPEN_READ_FAILED)) ); } } else { (back->dt).bdb.db = NULL; dk4dbi_delete_base(back); back = NULL; dk4error_set_simple_error_code( erp, ((0 != wa) ? (DK4_E_OPEN_WRITE_FAILED) : (DK4_E_OPEN_READ_FAILED)) ); } } #line 1394 "dk4dbi.ctr" return back; #endif } #endif /* if DK4_HAVE_DB_H */ #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) /** Close database, release resources. NOTE: Only release in-memory specific things, the dk4dbi_close() function calls dk4dbi_delete_base() to release the base components. @param db Database to close. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_SYNTAX
if the database file name does not refer to a regular file, - DK4_E_SEC_CHECK
with failed check id in iDetails1 if access is denied by additional security checks, - DK4_E_OPEN_WRITE_FAILED
with errno value in iDetails1 if fopen() or fwrite() failed, - DK4_E_CLOSE_FAILED
with errno value in iDetails1 if fclose() failed, - DK4_E_WRITE_FAILD
if fwrite() failed. */ static int dk4dbi_close_ndbm( dk4_dbi_t *db, dk4_er_t *erp ) { int back = 1; #if DK4_USE_ASSERT assert(NULL != db); #endif if (NULL != (db->dt).ndbm.dbm) { dbm_close((db->dt).ndbm.dbm); (db->dt).ndbm.dbm = NULL; } return back; } static void dk4dbi_truncate_ndbm(const dkChar *fn) { dkChar buf[DK4_MAX_PATH]; const size_t szbuf = DK4_SIZEOF(buf,dkChar); #if DK4_USE_ASSERT assert(NULL != fn); #endif if (0 != dk4str_cpy_s(buf, szbuf, fn, NULL)) { if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[0], NULL)) { (void)dk4delete_file(buf, NULL); } } if (0 != dk4str_cpy_s(buf, szbuf, fn, NULL)) { if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[1], NULL)) { (void)dk4delete_file(buf, NULL); } } } /** Open NDBM database. @param fn File name. @param wa Flag: Write access required. @param tr Flag: Truncate existing database. @param km Maximum key size. @param vm Maximum value size. @param erp Error report, may be NULL. @return Pointer to new database structure on success, NULL on error. */ static dk4_dbi_t * dk4dbi_open_ndbm( const dkChar *fn, int wa, int tr, size_t km, size_t vm, dk4_er_t *erp ) { dk4_dbi_t *back = NULL; int flags = 0; /* Flags for opening the DB */ #line 1495 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != fn); #endif if (0 != tr) { dk4dbi_truncate_ndbm(fn); } back = dk4dbi_new_base(fn, DK4_DB_BE_NDBM, wa, km, vm, erp); if (NULL != back) { flags = O_CREAT | ((0 != wa) ? ((0 != tr) ? (O_RDWR | O_TRUNC) : (O_RDWR)) : (O_RDONLY)); (back->dt).ndbm.dbm = dbm_open(fn, flags, 0600); if (NULL == (back->dt).ndbm.dbm) { dk4dbi_delete_base(back); back = NULL; dk4error_set_simple_error_code( erp, ((0 != wa) ? (DK4_E_OPEN_WRITE_FAILED) : (DK4_E_OPEN_READ_FAILED)) ); } } #line 1518 "dk4dbi.ctr" return back; } #endif /* if DK4_HAVE_NDBM_H */ dk4_dbi_t * dk4dbi_open_with_type( const dkChar *fn, int tp, int wa, int tr, size_t km, size_t vm, dk4_er_t *erp ) { dk4_dbi_t *back = NULL; #line 1539 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != fn); assert((DK4_DB_BE_MEMORY == tp) || (DK4_DB_BE_BDB == tp) || (DK4_DB_BE_NDBM == tp)); #endif if (NULL != fn) { switch (tp) { case DK4_DB_BE_MEMORY : { back = dk4dbi_open_mem(fn, wa, tr, km, vm, erp); } break; case DK4_DB_BE_BDB : { #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) back = dk4dbi_open_bdb(fn, wa, tr, km, vm, erp); #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; case DK4_DB_BE_NDBM : { #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) back = dk4dbi_open_ndbm(fn, wa, tr, km, vm, erp); #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; default : { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } break; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 1570 "dk4dbi.ctr" return back; } dk4_dbi_t * dk4dbi_open( const dkChar *fn, int wa, int tr, size_t km, size_t vm, dk4_er_t *erp ) { dk4_dbi_t *back = NULL; dkChar *mycopy = NULL; /* Private copy of fn */ dkChar *colon = NULL; /* First colon in mycopy */ const dkChar *fnp = NULL; /* File name pointer */ int tp = DK4_DB_BE_MEMORY ; /* Database type */ #line 1592 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != fn); #endif if (NULL != fn) { mycopy = dk4str_dup(fn, erp); if (NULL != mycopy) { #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) tp = DK4_DB_BE_NDBM; #endif #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) tp = DK4_DB_BE_BDB; #endif fnp = fn; colon = dk4str_chr(mycopy, dkT(':')); if (NULL != colon) { if (dkT(':') == colon[1]) { fnp = &(colon[2]); *colon = dkT('\0'); tp = dk4str_array_index(dk4dbi_type_names, mycopy, 0); if (DK4_DB_BE_UNKNOWN == tp) { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } } if (DK4_DB_BE_UNKNOWN != tp) { back = dk4dbi_open_with_type(fnp, tp, wa, tr, km, vm, erp); } dk4mem_free(mycopy); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 1625 "dk4dbi.ctr" return back; } const dkChar * dk4dbi_filename_part(const dkChar *filename) { const dkChar *back = NULL; #if DK4_USE_ASSERT assert(NULL != filename); #endif if (NULL != filename) { back = dk4str_chr(filename, dkT(':')); if (NULL != back) { back++; if (dkT(':') == *back) { back++; } else { back = filename; } } else { back = filename; } } return back; } int dk4dbi_close( dk4_dbi_t *db, dk4_er_t *erp ) { int back = 0; #line 1663 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); #endif if (NULL != db) { switch (db->tp) { case DK4_DB_BE_MEMORY : { back = dk4dbi_close_mem(db, erp); } break; case DK4_DB_BE_BDB : { #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) back = dk4dbi_close_bdb(db); #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; case DK4_DB_BE_NDBM : { #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) back = dk4dbi_close_ndbm(db, erp); #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; } dk4dbi_delete_base(db); } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 1691 "dk4dbi.ctr" return back; } int dk4dbi_set_option( dk4_dbi_t *db, int opt, int val ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != db); assert((DK4_DB_OPT_RESET_KEY == opt) || (DK4_DB_OPT_RESET_VALUE == opt)); #endif if (NULL != db) { switch (opt) { case DK4_DB_OPT_RESET_KEY : case DK4_DB_OPT_RESET_VALUE : { if (0 != val) { db->op |= opt; } else { db->op &= (~(opt)); } back = 1; } break; } } return back; } int dk4dbi_delete( dk4_dbi_t *db, const void *kp, size_t ks, dk4_er_t *erp ) { int back = 0; #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) DBT k; /* Key */ #endif #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) datum datk; /* Key */ #endif dk4_dbi_datum_t dat; /* Key for comparison */ dk4_dbi_datum_t *rp; /* Result found in db */ #line 1746 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); assert(0 != db->wa); #endif if ((NULL != db) && (NULL != kp) && ((size_t)0UL < ks)) { if ((0 != db->wa) && (((size_t)0UL == db->km) || (db->km >= ks))) { switch (db->tp) { case DK4_DB_BE_MEMORY : { db->uc = 1; dat.kd = (void *)kp; dat.ks = ks; rp = (dk4_dbi_datum_t *)dk4sto_it_find_like( (db->dt).mem.i, &dat, 0 ); if (NULL != rp) { back = dk4sto_remove((db->dt).mem.s, rp, erp); if (0 != back) { if (0 == dk4dbi_datum_delete(rp, db->op)) { back = 0; } } else { dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); } } else { dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); } } break; case DK4_DB_BE_BDB : { #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) if (NULL != (db->dt).bdb.db) { db->uc = 1; DK4_MEMRES(&k, sizeof(DBT)); k.data = (void *)kp; k.size = ks; if (0 == ((db->dt).bdb.db)->del((db->dt).bdb.db, NULL, &k, 0)) { back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; case DK4_DB_BE_NDBM : { #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) if (NULL != (db->dt).ndbm.dbm) { db->uc = 1; DK4_MEMRES(&datk, sizeof(datum)); datk.dptr = (char *)kp; datk.dsize = ks; if (0 == dbm_delete((db->dt).ndbm.dbm, datk)) { back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; } } else { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 1816 "dk4dbi.ctr" return back; } int dk4dbi_set( dk4_dbi_t *db, const void *kp, size_t ks, const void *vp, size_t vs, dk4_er_t *erp ) { dk4_dbi_datum_t dat; /* Key for comparison */ #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) DBT k; /* Key */ DBT v; /* Value */ #endif #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) datum datk; /* Key */ datum datv; /* Value */ #endif dk4_dbi_datum_t *rp = NULL; /* Result record */ char *nb = NULL; /* New value buffer */ int back = 0; #line 1845 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); assert(0 != db->wa); #endif if ((NULL != db) && (NULL != kp) && ((size_t)0UL < ks)) { #line 1850 "dk4dbi.ctr" if ((NULL != vp) && ((size_t)0UL < vs)) { #line 1851 "dk4dbi.ctr" if( (((size_t)0UL == db->km) || (db->km >= ks)) && (((size_t)0UL == db->vm) || (db->vm >= vs)) && (0 != db->wa) ) { #line 1857 "dk4dbi.ctr" switch (db->tp) { case DK4_DB_BE_MEMORY : { #line 1859 "dk4dbi.ctr" db->uc = 1; dat.kd = (void *)kp; dat.ks = ks; rp = (dk4_dbi_datum_t *)dk4sto_it_find_like( (db->dt).mem.i, &dat, 0 ); if (NULL != rp) { nb = dk4mem_new(char,vs,erp); if (NULL != nb) { back = 1; if (NULL != rp->vd) { if (0 != (DK4_DB_OPT_RESET_VALUE & (db->op))) { if ((size_t)0UL < rp->vs) { back = dk4mem_reset_secure(rp->vd, rp->vs, NULL); } } dk4mem_free(rp->vd); } rp->vd = nb; DK4_MEMCPY(rp->vd,vp,vs); rp->vs = vs; } } else { rp = dk4dbi_datum_new(ks, vs, erp); if (NULL != rp) { DK4_MEMCPY(rp->kd,kp,ks); DK4_MEMCPY(rp->vd,vp,vs); if (0 != dk4sto_add((db->dt).mem.s, rp, erp)) { back = 1; } else { dk4dbi_datum_delete(rp, db->op); } } } } break; case DK4_DB_BE_BDB : { #line 1894 "dk4dbi.ctr" #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) #line 1896 "dk4dbi.ctr" if (NULL != (db->dt).bdb.db) { #line 1897 "dk4dbi.ctr" db->uc = 1; DK4_MEMRES(&k, sizeof(DBT)); DK4_MEMRES(&v, sizeof(DBT)); k.data = (void *)kp; v.data = (void *)vp; k.size = ks; v.size = vs; #line 1903 "dk4dbi.ctr" ((db->dt).bdb.db)->del((db->dt).bdb.db, NULL, &k, 0); DK4_MEMRES(&k, sizeof(DBT)); k.data = (void *)kp; k.size = ks; #line 1907 "dk4dbi.ctr" if (0 == ((db->dt).bdb.db)->put((db->dt).bdb.db,NULL,&k,&v,0)) { back = 1; #line 1909 "dk4dbi.ctr" } else { #line 1910 "dk4dbi.ctr" dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); } } else { #line 1913 "dk4dbi.ctr" dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; case DK4_DB_BE_NDBM : { #line 1920 "dk4dbi.ctr" #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) if (NULL != (db->dt).ndbm.dbm) { db->uc = 1; DK4_MEMRES(&datk, sizeof(datum)); DK4_MEMRES(&datv, sizeof(datum)); datk.dptr = (char *)kp; datk.dsize = ks; datv.dptr = (char *)vp; datv.dsize = vs; if (0 == dbm_store((db->dt).ndbm.dbm, datk, datv, DBM_INSERT)) { back = 1; } else { DK4_MEMRES(&datk, sizeof(datum)); DK4_MEMRES(&datv, sizeof(datum)); datk.dptr = (char *)kp; datk.dsize = ks; datv.dptr = (char *)vp; datv.dsize = vs; if (0 == dbm_store((db->dt).ndbm.dbm,datk,datv,DBM_REPLACE)) { back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; } } else { #line 1951 "dk4dbi.ctr" dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { #line 1954 "dk4dbi.ctr" back = dk4dbi_delete(db, kp, ks, erp); } } else { #line 1957 "dk4dbi.ctr" dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 1960 "dk4dbi.ctr" return back; } int dk4dbi_sync( dk4_dbi_t *db, dk4_er_t *erp ) { int back = 0; #line 1973 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); #endif if (NULL != db) { switch (db->tp) { case DK4_DB_BE_MEMORY : { if ((0 != db->wa) && (0 != db->uc)) { back = dk4dbi_mem_to_file(db, erp); } else { back = 1; } } break; case DK4_DB_BE_BDB : { #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) if (NULL != (db->dt).bdb.db) { if ((0 != db->wa) && (0 != db->uc)) { if (0 == ((db->dt).bdb.db)->sync((db->dt).bdb.db, 0)) { back = 1; db->uc = 0; } else { dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); } } else { back = 1; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; case DK4_DB_BE_NDBM : { #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) if (NULL != (db->dt).ndbm.dbm) { back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 2021 "dk4dbi.ctr" return back; } int dk4dbi_get( dk4_dbi_t *db, const void *kp, size_t ks, void *vp, size_t *vs, dk4_er_t *erp ) { dk4_dbi_datum_t dat; /* Key for comparison */ #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) DBT k; /* Key */ DBT v; /* Value */ #endif #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) datum datk; /* Key */ datum datv; /* Value */ #endif dk4_dbi_datum_t *rp; /* Search result pointer */ int back = 0; #line 2049 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); assert(NULL != vp); assert(NULL != vs); #endif if ( (NULL != db) && (NULL != kp) && ((size_t)0 < ks) && (NULL != vp) && (NULL != vs) ) { if ((size_t)0UL < *vs) { if (((size_t)0UL == db->km) || (db->km >= ks)) { switch (db->tp) { case DK4_DB_BE_MEMORY : { #line 2063 "dk4dbi.ctr" dat.kd = (void *)kp; dat.ks = ks; rp = (dk4_dbi_datum_t *)dk4sto_it_find_like( (db->dt).mem.i, &dat, 0 ); if (NULL != rp) { if ((NULL != rp->vd) && ((size_t)0UL < rp->vs)) { if (*vs >= rp->vs) { DK4_MEMCPY(vp,rp->vd,rp->vs); *vs = rp->vs; back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL); } } else { dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); } } else { dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); } } break; case DK4_DB_BE_BDB : { #line 2084 "dk4dbi.ctr" #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) #line 2086 "dk4dbi.ctr" if (NULL != (db->dt).bdb.db) { #line 2087 "dk4dbi.ctr" DK4_MEMRES(&k, sizeof(DBT)); DK4_MEMRES(&v, sizeof(DBT)); k.data = (void *)kp; k.size = ks; v.data = (void *)vp; v.ulen = *vs; v.flags = DB_DBT_USERMEM; if (0 == ((db->dt).bdb.db)->get((db->dt).bdb.db,NULL,&k,&v,0)) { *vs = v.size; #line 2093 "dk4dbi.ctr" back = 1; } else { #line 2095 "dk4dbi.ctr" dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); } } else { #line 2098 "dk4dbi.ctr" dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #else #line 2102 "dk4dbi.ctr" dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; case DK4_DB_BE_NDBM : { #line 2106 "dk4dbi.ctr" #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) if (NULL != (db->dt).ndbm.dbm) { DK4_MEMRES(&datk, sizeof(datum)); DK4_MEMRES(&datv, sizeof(datum)); datk.dptr = (char *)kp; datk.dsize = ks; datv = dbm_fetch((db->dt).ndbm.dbm, datk); if ((NULL != datv.dptr) && (0 < datv.dsize)) { if (*vs >= datv.dsize) { DK4_MEMCPY(vp,datv.dptr,datv.dsize); *vs = datv.dsize; back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL); } } else { dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; } } else { #line 2132 "dk4dbi.ctr" dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } } else { #line 2135 "dk4dbi.ctr" dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } } else { #line 2138 "dk4dbi.ctr" dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 2141 "dk4dbi.ctr" return back; } int dk4dbi_traverse( dk4_dbi_t *db, void *obj, dk4dbi_traverse_fct_t *fct ) { #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) DBT dbtk; /* Key */ DBT dbtv; /* Value */ DBC *cp = NULL; /* Cursor for traversal */ #endif #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) datum datk; /* Key */ datum datv; /* Value */ #endif dk4_dbi_datum_t *dddt = NULL; /* Pointer for traversal */ int res = 0; /* Operation result */ #if (DK4_CHAR_SIZE == 1) && ((DK4_HAVE_NDBM_H) || (DK4_HAVE_DB_H)) int first = 1; /* Flag: Retrieving first record */ #endif int back = -1; #line 2170 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); assert(NULL != fct); #endif if ((NULL != db) && (NULL != fct)) { switch (db->tp) { case DK4_DB_BE_MEMORY : { back = 1; dk4sto_it_reset((db->dt).mem.i); do { dddt = (dk4_dbi_datum_t *)dk4sto_it_next((db->dt).mem.i); if (NULL != dddt) { res = (*fct)(obj, dddt->kd, dddt->ks, dddt->vd, dddt->vs); if (res < back) { back = res; } } } while((NULL != dddt) && (-1 < back)); } break; case DK4_DB_BE_BDB : { #if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) res = ((db->dt).bdb.db)->cursor((db->dt).bdb.db, NULL, &cp, 0); if (0 == res) { if (NULL != cp) { back = 1; DK4_MEMRES(&dbtk, sizeof(DBT)); DK4_MEMRES(&dbtv, sizeof(DBT)); do { #if DK4_HAVE_DB_CURSOR_C_GET res = cp->c_get( cp, &dbtk, &dbtv, ((0 != first) ? (DB_FIRST) : (DB_NEXT)) ); #else res = cp->get( cp, &dbtk, &dbtv, ((0 != first) ? (DB_FIRST) : (DB_NEXT)) ); #endif first = 0; if (0 == res) { res = (*fct)(obj, dbtk.data, dbtk.size, dbtv.data, dbtv.size); if (res < back) { back = res; } } else { res = -1; /* Failed to obtain a record, stop */ } } while((-1 < res) && (-1 < back)); cp->c_close(cp); } else { #line 2215 "dk4dbi.ctr" } } else { #line 2217 "dk4dbi.ctr" } #endif } break; case DK4_DB_BE_NDBM : { #if DK4_HAVE_NDBM_H && (DK4_CHAR_SIZE == 1) back = 1; do { if (0 != first) { datk = dbm_firstkey((db->dt).ndbm.dbm); first = 0; } else { datk = dbm_nextkey((db->dt).ndbm.dbm); } if ((NULL != datk.dptr) && (0 < datk.dsize)) { datv = dbm_fetch((db->dt).ndbm.dbm, datk); if ((NULL != datv.dptr) && (0 < datv.dsize)) { res = (*fct)(obj, datk.dptr, datk.dsize, datv.dptr, datv.dsize); if (res < back) { back = res; } } else { res = -1; } } else { res = -1; } } while((-1 < res) && (-1 < back)); #endif } break; } } #line 2246 "dk4dbi.ctr" return back; } #if !DK4_ON_WINDOWS #if DK4_CHAR_SIZE == 1 #if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD /** Change ownership and mode for a file. @param fn File name. @param user New owner. @param group New owner group. @param mode New file permissions. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: - DK4_E_SYSTEM
with errno value in iDetails1 if chown or chmod failed. */ static int dk4dbi_change_file_owner_and_mode( const dkChar *fn, uid_t user, gid_t group, mode_t mode, dk4_er_t *erp ) { int back = 0; #line 2282 "dk4dbi.ctr" errno = 0; if (0 == chown(fn, user, group)) { errno = 0; if (0 == chmod(fn, mode)) { back = 1; } else { dk4error_set_idetails(erp, DK4_E_SYSTEM, errno); } } else { dk4error_set_idetails(erp, DK4_E_SYSTEM, errno); } #line 2293 "dk4dbi.ctr" return back; } int dk4dbi_change_owner_and_mode( dk4_dbi_t *db, uid_t user, gid_t group, mode_t mode, dk4_er_t *erp ) { dkChar buf[DK4_MAX_PATH]; /* File names construction */ const size_t szbuf = DK4_SIZEOF(buf,dkChar); /* Buffer size */ int back = 0; #line 2311 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); #endif if (NULL != db) { switch (db->tp) { case DK4_DB_BE_MEMORY : case DK4_DB_BE_BDB : { back = dk4dbi_change_file_owner_and_mode( db->fn, user, group, mode, erp ); } break; case DK4_DB_BE_NDBM : { if (0 != dk4str_cpy_s(buf, szbuf, db->fn, erp)) { if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[0], erp)) { back = dk4dbi_change_file_owner_and_mode(buf,user,group,mode,erp); (void)dk4str_cpy_s(buf, szbuf, db->fn, erp); if (0 != dk4str_cat_s(buf, szbuf, dk4dbi_ndbm_suffixes[1], erp)) { if (0 == dk4dbi_change_file_owner_and_mode(buf,user,group,mode,erp) ) { back = 0; } } } } } break; default : { dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); } break; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 2346 "dk4dbi.ctr" return back; } #endif /* if DK4_HAVE_CHOWN && DK4_HAVE_CHMOD */ #endif /* if DK4_CHAR_SIZE == 1 */ #endif /* if !DK4_ON_WINDOWS */ size_t dk4dbi_get_key_max( const dk4_dbi_t *db, dk4_er_t *erp ) { size_t back = 0; #line 2366 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); #endif if (NULL != db) { back = db->km; } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 2374 "dk4dbi.ctr" return back; } size_t dk4dbi_get_val_max( const dk4_dbi_t *db, dk4_er_t *erp ) { size_t back = 0; #line 2387 "dk4dbi.ctr" #if DK4_USE_ASSERT assert(NULL != db); #endif if (NULL != db) { back = db->vm; } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 2395 "dk4dbi.ctr" return back; } int dk4dbi_get_type(const dk4_dbi_t *db) { int back = DK4_DB_BE_UNKNOWN; #if DK4_USE_ASSERT assert(NULL != db); #endif if (NULL != db) { back = db->tp; } return back; }