1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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;
}
|