summaryrefslogtreecommitdiff
path: root/support/dktools/dk4dbi.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4dbi.c
Initial commit
Diffstat (limited to 'support/dktools/dk4dbi.c')
-rw-r--r--support/dktools/dk4dbi.c1983
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;
+}
+