diff options
Diffstat (limited to 'support/dktools/dk4dbi.c')
-rw-r--r-- | support/dktools/dk4dbi.c | 1983 |
1 files changed, 1983 insertions, 0 deletions
diff --git a/support/dktools/dk4dbi.c b/support/dktools/dk4dbi.c new file mode 100644 index 0000000000..f7c3a349ad --- /dev/null +++ b/support/dktools/dk4dbi.c @@ -0,0 +1,1983 @@ +/* + WARNING: This file was generated by dkct. + 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 +*/ + +/* +Copyright (C) 2015-2017, Dirk Krause + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above opyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of the author nor the names of contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** @file dk4dbi.c The dk4dbi module. +*/ + + +#line 556 "dk4dbi.ctr" + +#include "dk4conf.h" + +#if DK4_HAVE_ERRNO_H +#ifndef ERRNO_H_INCLUDED +#include <errno.h> +#define ERRNO_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_SYS_STAT_H +#ifndef SYS_STAT_H_INCLUDED +#include <sys/stat.h> +#define SYS_STAT_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" + + + + + +#line 589 "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 611 "dk4dbi.ctr" +}; + + + +/** File name suffixes for NDBM files. +*/ +static const dkChar *dk4dbi_ndbm_suffixes[] = { +dkT(".dir"), dkT(".pag") +}; + + + +/** Maximum size of key or value. +*/ +static const unsigned long dk4dbi_max_size = 4294967295UL; + + + +/** 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 641 "dk4dbi.ctr" + if (NULL != ptr) { + back = 1; + if (0 != (DK4_DB_OPT_RESET_KEY & options)) { + if ((NULL != ptr->kd) && ((size_t)0UL < ptr->ks)) { + + +#line 646 "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 654 "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 665 "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<br> + 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 691 "dk4dbi.ctr" + back = dk4mem_new(dk4_dbi_datum_t,1,erp); + if (NULL != back) { + back->kd = back->vd = NULL; + back->ks = back->vs = (size_t)0UL; + back->kd = dk4mem_new(char,ks,erp); + 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 706 "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<br> + if the database file name does not refer to a regular file, + - DK4_E_SEC_CHECK<br> + with failed check id in iDetails1 if access is denied by additional + security checks, + - DK4_E_OPEN_WRITE_FAILED<br> + with errno value in iDetails1 if fopen() or fwrite() failed, + - DK4_E_CLOSE_FAILED<br> + with errno value in iDetails1 if fclose() failed, + - DK4_E_WRITE_FAILD<br> + 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 745 "dk4dbi.ctr" + if (dk4isadmin()) { tests = DK4_FOPEN_SC_PRIVILEGED; } + fipo = dk4fopen(db->fn, dkT("wb"), tests, erp); + if (NULL != fipo) { + +#line 748 "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 753 "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 763 "dk4dbi.ctr" + nbw = fwrite(rp->kd, 1, rp->ks, fipo); + if (rp->ks == nbw) { + +#line 765 "dk4dbi.ctr" + nbw = fwrite(rp->vd, 1, rp->vs, fipo); + if (rp->vs == nbw) { + +#line 767 "dk4dbi.ctr" + } else { + back = 0; + +#line 769 "dk4dbi.ctr" + dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); + } + } else { + +#line 772 "dk4dbi.ctr" + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); + } + } else { + +#line 776 "dk4dbi.ctr" + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); + } + } + } while (NULL != rp); + if (0 != fclose(fipo)) { + +#line 782 "dk4dbi.ctr" + back = 0; + dk4error_set_idetails(erp, DK4_E_CLOSE_FAILED, errno); + } + } else { + +#line 786 "dk4dbi.ctr" + } + if (0 != back) { + db->uc = 0; + } + + +#line 791 "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<br> + 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<br> + with failed check id in iDetails1 if access is denied by additional + security checks, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + 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 835 "dk4dbi.ctr" + fipo = dk4fopen(db->fn, dkT("rb"), 0, erp); + if (NULL != fipo) { + back = 1; + do { + nbr = fread(uc, 1, 8, fipo); + if (8 == nbr) { + +#line 841 "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 ((dk4_um_t)(SIZE_MAX) >= (dk4_um_t)ul1) { + if ((dk4_um_t)(SIZE_MAX) >= (dk4_um_t)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 860 "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 866 "dk4dbi.ctr" + back = 0; + dk4dbi_datum_delete(rp, 0); + } + } else { + +#line 870 "dk4dbi.ctr" + cc = 0; + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + dk4dbi_datum_delete(rp, 0); + } + } else { + +#line 876 "dk4dbi.ctr" + cc = 0; + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + dk4dbi_datum_delete(rp, 0); + } + } else { + +#line 882 "dk4dbi.ctr" + cc = 0; + back = 0; + } + } + else + { + +#line 888 "dk4dbi.ctr" + cc = 0; + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + } + } else { + +#line 893 "dk4dbi.ctr" + cc = 0; + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + } + } else { + +#line 898 "dk4dbi.ctr" + cc = 0; + back = 0; + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + } + } else { + +#line 903 "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 912 "dk4dbi.ctr" + if (0 == dk4stat(&stb, db->fn, NULL)) { + back = 1; + +#line 914 "dk4dbi.ctr" + } + } + + +#line 917 "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 l<r. +*/ +static +int +dk4dbi_datum_compare(const void *l, const void *r, int cr) +{ + dk4_dbi_datum_t *pl; /* Left pointer */ + dk4_dbi_datum_t *pr; /* Right pointer */ + int back = 0; + + +#line 936 "dk4dbi.ctr" + if (NULL != l) { + if (NULL != r) { + pl = (dk4_dbi_datum_t *)l; + pr = (dk4_dbi_datum_t *)r; + if (NULL != pl->kd) { + 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 968 "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 981 "dk4dbi.ctr" + if (NULL != ptr) { + dk4mem_release(ptr->fn); + dk4mem_free(ptr); + } + + +#line 986 "dk4dbi.ctr" +} + + + +/** Allocate memory for a database. + @param fn File name. + @param tp Backend type. + @param wa Flag: Write access required. + @param erp Error report, may be NULL. + @return Pointer to memory on success, NULL on error. + + Error codes: + - DK4_E_MATH_OVERFLOW<br> + on numeric overflow when calculating size, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + 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 1017 "dk4dbi.ctr" + 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 1043 "dk4dbi.ctr" + dk4mem_free(back); + back = NULL; + } + } + + +#line 1048 "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<br> + if the database file name does not refer to a regular file, + - DK4_E_SEC_CHECK<br> + with failed check id in iDetails1 if access is denied by additional + security checks, + - DK4_E_OPEN_WRITE_FAILED<br> + with errno value in iDetails1 if fopen() or fwrite() failed, + - DK4_E_CLOSE_FAILED<br> + with errno value in iDetails1 if fclose() failed, + - DK4_E_WRITE_FAILD<br> + 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 1084 "dk4dbi.ctr" + if ((NULL != (db->dt).mem.s) && (NULL != (db->dt).mem.i)) { + /* + Write records to file if there are unsaved changes. + */ + + +#line 1089 "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 1113 "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<br> + on numeric overflow when calculating size, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + with mem.elsize and mem.nelem + set if there is not enough memory available, + - DK4_E_SYNTAX<br> + 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<br> + 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<br> + with errno value in iDetails1 if fopen() or fwrite() failed, + - DK4_E_CLOSE_FAILED<br> + 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 1161 "dk4dbi.ctr" + 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 1191 "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. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + Error codes: + - DK4_E_SYNTAX<br> + if the database file name does not refer to a regular file, + - DK4_E_SEC_CHECK<br> + with failed check id in iDetails1 if access is denied by additional + security checks, + - DK4_E_OPEN_WRITE_FAILED<br> + with errno value in iDetails1 if fopen() or fwrite() failed, + - DK4_E_CLOSE_FAILED<br> + with errno value in iDetails1 if fclose() failed, + - DK4_E_WRITE_FAILD<br> + if fwrite() failed. +*/ +static +int +dk4dbi_close_bdb( + dk4_dbi_t *db, + dk4_er_t *erp +) +{ + int back = 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 = 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<br> + on numeric overflow when calculating size, + - DK4_E_MEMORY_ALLOCATION_FAILED<br> + with mem.elsize and mem.nelem + set if there is not enough memory available, + - DK4_E_OPEN_WRITE_FAILED<br> + if the database can not be opened for writing, + - DK4_E_OPEN_READ_FAILED<br> + if the database can not be opened or reading, + - DK4_E_NOT_SUPPORTED<br> + 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 1289 "dk4dbi.ctr" + 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 1324 "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<br> + if the database file name does not refer to a regular file, + - DK4_E_SEC_CHECK<br> + with failed check id in iDetails1 if access is denied by additional + security checks, + - DK4_E_OPEN_WRITE_FAILED<br> + with errno value in iDetails1 if fopen() or fwrite() failed, + - DK4_E_CLOSE_FAILED<br> + with errno value in iDetails1 if fclose() failed, + - DK4_E_WRITE_FAILD<br> + if fwrite() failed. +*/ +static +int +dk4dbi_close_ndbm( + dk4_dbi_t *db, + dk4_er_t *erp +) +{ + int back = 1; + 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 (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 1420 "dk4dbi.ctr" + + 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 1441 "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 1462 "dk4dbi.ctr" + 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 1489 "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 1511 "dk4dbi.ctr" + 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 1541 "dk4dbi.ctr" + return back; +} + + + +const dkChar * +dk4dbi_filename_part(const dkChar *filename) +{ + const dkChar *back = NULL; + 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 1576 "dk4dbi.ctr" + 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, 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_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 1601 "dk4dbi.ctr" + return back; +} + + + +int +dk4dbi_set_option( + dk4_dbi_t *db, + int opt, + int val +) +{ + int back = 0; + 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 1652 "dk4dbi.ctr" + 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 1718 "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 1747 "dk4dbi.ctr" + if ((NULL != db) && (NULL != kp) && ((size_t)0UL < ks)) { + +#line 1748 "dk4dbi.ctr" + if ((NULL != vp) && ((size_t)0UL < vs)) { + +#line 1749 "dk4dbi.ctr" + if( + (((size_t)0UL == db->km) || (db->km >= ks)) + && (((size_t)0UL == db->vm) || (db->vm >= vs)) + && (0 != db->wa) + ) + { + +#line 1755 "dk4dbi.ctr" + switch (db->tp) { + case DK4_DB_BE_MEMORY : { + +#line 1757 "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 1792 "dk4dbi.ctr" +#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) + + +#line 1794 "dk4dbi.ctr" + if (NULL != (db->dt).bdb.db) { + +#line 1795 "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 1801 "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 1805 "dk4dbi.ctr" + if (0 == ((db->dt).bdb.db)->put((db->dt).bdb.db,NULL,&k,&v,0)) { + back = 1; + +#line 1807 "dk4dbi.ctr" + } else { + +#line 1808 "dk4dbi.ctr" + dk4error_set_simple_error_code(erp, DK4_E_WRITE_FAILED); + } + } else { + +#line 1811 "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 1818 "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 1849 "dk4dbi.ctr" + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + } + } else { + +#line 1852 "dk4dbi.ctr" + back = dk4dbi_delete(db, kp, ks, erp); + } + } else { + +#line 1855 "dk4dbi.ctr" + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + + +#line 1858 "dk4dbi.ctr" + return back; +} + + + +int +dk4dbi_sync( + dk4_dbi_t *db, + dk4_er_t *erp +) +{ + int back = 0; + + +#line 1871 "dk4dbi.ctr" + 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 1916 "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 1944 "dk4dbi.ctr" + 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 1953 "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 1974 "dk4dbi.ctr" +#if DK4_HAVE_DB_H && (DK4_CHAR_SIZE == 1) + + +#line 1976 "dk4dbi.ctr" + if (NULL != (db->dt).bdb.db) { + +#line 1977 "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 1983 "dk4dbi.ctr" + back = 1; + } else { + +#line 1985 "dk4dbi.ctr" + dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); + } + } else { + +#line 1988 "dk4dbi.ctr" + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } +#else + + +#line 1992 "dk4dbi.ctr" + dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); +#endif + } break; + case DK4_DB_BE_NDBM : { + +#line 1996 "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 2022 "dk4dbi.ctr" + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + +#line 2025 "dk4dbi.ctr" + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + +#line 2028 "dk4dbi.ctr" + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + + +#line 2031 "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 */ + int first = 1; /* Flag: Retrieving first record */ + int back = -1; + + + +#line 2058 "dk4dbi.ctr" + if ((NULL != db) && (NULL != fct)) { + switch (db->tp) { + case DK4_DB_BE_MEMORY : { + back = 1; + dk4sto_it_reset((db->dt).mem.i); + do { + dddt = 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 2099 "dk4dbi.ctr" + } + } else { + +#line 2101 "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 2130 "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<br> + 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 2166 "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 2177 "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 2195 "dk4dbi.ctr" + 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 2227 "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 2247 "dk4dbi.ctr" + if (NULL != db) { + back = db->km; + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + +#line 2252 "dk4dbi.ctr" + return back; +} + + + +size_t +dk4dbi_get_val_max( + const dk4_dbi_t *db, + dk4_er_t *erp +) +{ + size_t back = 0; + + +#line 2265 "dk4dbi.ctr" + if (NULL != db) { + back = db->vm; + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + +#line 2270 "dk4dbi.ctr" + return back; +} + + + +int +dk4dbi_get_type(const dk4_dbi_t *db) +{ + int back = DK4_DB_BE_UNKNOWN; + if (NULL != db) { + back = db->tp; + } + return back; +} + |