/
dbopt.c
executable file
·203 lines (163 loc) · 4.74 KB
/
dbopt.c
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#include "dbopt.h"
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include "utility.h"
#include <ctype.h>
int create_db( const char *DBName ){
int ret = ERR_OK;
if( NULL == DBName )
return ERR_STRING_NULL;
if( 0 == access( DBName , 0 ) )
{
unlink(DBName);
// return ERR_DB_DUPLICATE;
}
make_dir_needed( DBName );
struct tdb_context *tdb = tdb_open(DBName, 0, 0, O_CREAT | O_TRUNC | O_RDWR, 0600);
if (!tdb)
return ERR_DB_NEW_FAIL;
char *value = "1.0";
char *key = "version";
int size = strlen(value) + 1;
TDB_DATA dkey, data;
dkey.dptr = (unsigned char *) key;
dkey.dsize = strlen(key) + 1;
data.dptr = (unsigned char *) value;
data.dsize = size;
if (tdb_store(tdb, dkey, data, 0))
ret = ERR_DB_STORE_FAIL;
tdb_close(tdb);
return ret;
}
DATABASE* open_db( const char *DBName ){
if( NULL == DBName )
return NULL;
struct tdb_context *tdb = tdb_open(DBName, 0, 0, O_RDWR | O_CREAT, 0666);
if( NULL == tdb )
return NULL;
DATABASE *db = (DATABASE*)malloc(sizeof(DATABASE));
db->tdb = tdb;
sem_init( &db->sem, 0, 1 );
db->stamp = time(NULL);
// printf("time is %u\n", db->stamp );
return db;
}
int close_db( DATABASE *db )
{
int ret = ERR_OK;
if( NULL == db )
return ERR_DB_INVALID;
tdb_close(db->tdb);
sem_close(&db->sem);
return ret;
}
/**
* Returns a single value from the database
*
* @warning The caller must free the returned data.
*
* @param [out] value pointer to the value being read
* @param [out] size number of bytes of @c value parameter
* @param [in] key pointer to a string containing the key in the ENV db
* @param [in] db pointer of a tdb object;
*
* @return error code
* @retval ERR_OK = OK
* @retval ERR_DB_INVALID = failed to access tdb
* @retval ERR_STRING_NULL = key not found
*/
int get_value(const unsigned char *key,
unsigned char **value,
int *size,
DATABASE *db){
int ret = ERR_OK;
TDB_DATA dkey,dvalue ;
if( NULL == db )
return ERR_DB_INVALID;
dkey = string_to_tdb(key);
if( 0 == dkey.dsize )
return ERR_STRING_NULL;
while( sem_wait( &db->sem ) == -1 && errno == EINTR );
dvalue = tdb_fetch(db->tdb, dkey);
sem_post( &db->sem );
if (NULL == dvalue.dptr)
ret = ERR_STRING_NULL;
*value = dvalue.dptr;
*size = dvalue.dsize;
free(dkey.dptr);
return ret;
}
int delete_key(const unsigned char *key, DATABASE *db){
if( NULL == db || NULL == db->tdb)
return ERR_DB_INVALID;
TDB_DATA dkey;
dkey = string_to_tdb(key);
while( sem_wait(&db->sem) == -1 && errno == EINTR );
int err = tdb_delete(db->tdb, dkey);
free(dkey.dptr);
sem_post(&db->sem);
if (err)
return ERR_FAIL;
return 0;
}
/**
* Returns the key structure of the database properly filled
*
* @warning The caller must free the returned data.
*
* @param [in] key string containing the value of the key
* @return @c TBD_DATA struct ready to be used
*/
TDB_DATA string_to_tdb(const unsigned char *key){
TDB_DATA data;
data.dptr = NULL;
data.dsize = 0;
if( NULL == key )
return data;
int size = strlen( (char*)key ) + 1;
data.dptr = (unsigned char *)calloc( size , sizeof(unsigned char));
memcpy( data.dptr, key, size );
data.dsize = size;
return data;
}
/**
* Writes a single value into the database
*
* @param [in] key pointer to a string containing the key in the ENV db
* @param [in] value string to be written into the ENV db
* @param [in] size length of @c value (including trailing '\0')
* @param [in,out] db pointer of an open tdb object
*
* @return error code
* @retval 0 = OK
* @retval 1 = cannot write data into database
*/
int set_key( const unsigned char *key,
const unsigned char *value,
int size,
DATABASE *db){
int ret = ERR_OK;
if(NULL == db || NULL == key || NULL == value )
return ERR_STRING_NULL;
TDB_DATA dkey, data;
dkey.dptr = (unsigned char *) key;
dkey.dsize = strlen((char*)key) + 1;
data.dptr = (unsigned char *) value;
data.dsize = size;
while( sem_wait( &db->sem ) == -1 && errno == EINTR );
if (tdb_store(db->tdb, dkey, data, 0))
ret = ERR_DB_STORE_FAIL;
sem_post( &db->sem );
return ret;
}
int dump_tdb(DATABASE *db, tdb_traverse_func fn)
{
if (!db || !db->tdb) {
return ERR_DB_INVALID;
}
tdb_traverse(db->tdb, fn, NULL);
return ERR_OK;
}