summaryrefslogtreecommitdiffstats
path: root/src/db.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/db.c')
-rw-r--r--src/db.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/db.c b/src/db.c
new file mode 100644
index 0000000..a0443c9
--- /dev/null
+++ b/src/db.c
@@ -0,0 +1,138 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright © 2020 rsiddharth <s@ricketyspace.net>
+ */
+
+#include <db.h>
+
+static const char *DB_FILE = "nserver.db";
+
+datum *mk_datum(char *data)
+{
+ datum *d = NULL;
+
+ check(data != NULL, "data invalid");
+
+ d = calloc(1, sizeof(datum));
+ check(d != NULL, "datum mem alloc failed");
+
+ d->dptr = data;
+ d->dsize = strlen(data);
+
+ return d;
+ error:
+ if (d) {
+ free(d);
+ }
+ return NULL;
+}
+
+GDBM_FILE db_open(int flags)
+{
+ return gdbm_open(DB_FILE, 0,flags, S_IRUSR|S_IWUSR, NULL);
+}
+
+int db_init()
+{
+ // Create DB if it's not already created.
+ GDBM_FILE gf = db_open(GDBM_WRCREAT);
+ check(gf != NULL, "unable to init db");
+
+ // Close the DB.
+ int rc = gdbm_close(gf);
+ check(rc == 0, "error closing db after init");
+
+ return 0;
+ error:
+ return -1;
+}
+
+int db_store(char *key, char *value)
+{
+ datum *k_datum = NULL, *v_datum = NULL;
+ GDBM_FILE gf = NULL;
+
+ check(key != NULL && strlen(key) > 0, "key invalid");
+ check(value != NULL && strlen(value) > 0, "data invalid");
+
+ // make key value datum
+ k_datum = mk_datum(key);
+ check(k_datum != NULL, "key datum init failed");
+
+ v_datum = mk_datum(value);
+ check(v_datum != NULL, "value datum init failed");
+
+ // init db.
+ int rc = db_init();
+ check(rc == 0, "db init failed");
+
+ // open the gdbm data in write mode
+ gf = db_open(GDBM_WRITER|GDBM_SYNC);
+ check(gf != NULL, "unable to open db in write mode");
+
+ // write key -> data to db.
+ rc = gdbm_store(gf, *k_datum, *v_datum, GDBM_REPLACE);
+ check(rc == 0, "gdbm store failed");
+
+ // close db
+ rc = gdbm_close(gf);
+ check(rc == 0, "gdbm close failed");
+
+ // cleanup.
+ free(k_datum);
+ free(v_datum);
+
+ return 0;
+ error:
+ if (k_datum) {
+ free(k_datum);
+ }
+ if (v_datum) {
+ free(v_datum);
+ }
+ if (gf) {
+ gdbm_close(gf);
+ }
+ return -1;
+}
+
+char *db_load(char *key)
+{
+ datum *k_datum = NULL;
+ GDBM_FILE gf = NULL;
+
+ check(key != NULL && strlen(key) > 0, "key invalid");
+
+ // make key datum
+ k_datum = mk_datum(key);
+ check(k_datum != NULL, "key datum init failed");
+
+ // init db.
+ int rc = db_init();
+ check(rc == 0, "db init failed");
+
+ // open the gdbm data in read mode
+ gf = db_open(GDBM_READER|GDBM_SYNC);
+ check(gf != NULL, "unable to open db in read mode");
+
+ // try to fetch value for key.
+ datum v_datum = gdbm_fetch(gf, *k_datum);
+ check(v_datum.dptr != NULL, "key not found");
+
+ // close db
+ rc = gdbm_close(gf);
+ check(rc == 0, "gdbm close failed");
+
+ // clean up.
+ free(k_datum);
+
+ return v_datum.dptr;
+ error:
+ if (k_datum) {
+ free(k_datum);
+ }
+ if (gf) {
+ gdbm_close(gf);
+ }
+ return NULL;
+}