Revision 351eb643

View differences:

lib/filter-kvs-gdbm.c
1
/* SylFilter - a message filter
2
 *
3
 * Copyright (C) 2011 Hiroyuki Yamamoto
4
 * Copyright (C) 2011 Sylpheed Development Team
5
 */
6

  
7
#include "config.h"
8

  
9
#ifdef USE_GDBM
10

  
11
#include <stdio.h>
12
#include <string.h>
13
#include <stdlib.h>
14
#include <glib.h>
15
#include <gdbm.h>
16

  
17
#include "filter-kvs.h"
18
#include "filter-kvs-gdbm.h"
19

  
20
static XFilterKVS *xf_gdbm_open(const char *dbfile);
21
static int xf_gdbm_close(XFilterKVS *kvs);
22
static int xf_gdbm_insert(XFilterKVS *kvs, const char *key, void *value, int size);
23
static int xf_gdbm_delete(XFilterKVS *kvs, const char *key);
24
static int xf_gdbm_update(XFilterKVS *kvs, const char *key, void *value, int size);
25
static int xf_gdbm_fetch(XFilterKVS *kvs, const char *key, void *vbuf, int vsize);
26
static int xf_gdbm_size(XFilterKVS *kvs);
27
static int xf_gdbm_foreach(XFilterKVS *kvs, XFilterKVSForeachFunc func, void *data);
28

  
29

  
30
int xfilter_kvs_gdbm_set_engine(void)
31
{
32
	XFilterKVSEngine engine = {
33
		xf_gdbm_open,
34
		xf_gdbm_close,
35
		xf_gdbm_insert,
36
		xf_gdbm_delete,
37
		xf_gdbm_update,
38
		xf_gdbm_fetch,
39
		NULL,
40
		NULL,
41
		xf_gdbm_size,
42
		xf_gdbm_foreach
43
	};
44

  
45
	return xfilter_kvs_set_engine(&engine);
46
}
47

  
48
static XFilterKVS *xf_gdbm_open(const char *dbfile)
49
{
50
	GDBM_FILE dbf;
51

  
52
	dbf = gdbm_open((char *)dbfile, 0, GDBM_WRCREAT, 0600, 0);
53
	if (!dbf) {
54
		fprintf(stderr, "xf_gdbm_open: %s: %s\n",
55
			dbfile, gdbm_strerror(gdbm_errno));
56
		return NULL;
57
	}
58
	return xfilter_kvs_new(dbfile, (void *)dbf);
59
}
60

  
61
static int xf_gdbm_close(XFilterKVS *kvs)
62
{
63
	gdbm_close((GDBM_FILE)xfilter_kvs_get_handle(kvs));
64
	return 0;
65
}
66

  
67
static int xf_gdbm_insert(XFilterKVS *kvs, const char *key, void *value, int size)
68
{
69
	GDBM_FILE dbf;
70
	datum dkey, dvalue;
71

  
72
	dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
73

  
74
	dkey.dptr = (char *)key;
75
	dkey.dsize = strlen(key);
76
	dvalue.dptr = (char *)value;
77
	dvalue.dsize = size;
78
	if (gdbm_store(dbf, dkey, dvalue, GDBM_INSERT) != 0)
79
		return -1;
80

  
81
	return 0;
82
}
83

  
84
static int xf_gdbm_delete(XFilterKVS *kvs, const char *key)
85
{
86
	GDBM_FILE dbf;
87
	datum dkey;
88

  
89
	dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
90

  
91
	dkey.dptr = (char *)key;
92
	dkey.dsize = strlen(key);
93
	if (gdbm_delete(dbf, dkey) != 0)
94
		return -1;
95

  
96
	return 0;
97
}
98

  
99
static int xf_gdbm_update(XFilterKVS *kvs, const char *key, void *value, int size)
100
{
101
	GDBM_FILE dbf;
102
	datum dkey, dvalue;
103

  
104
	dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
105

  
106
	dkey.dptr = (char *)key;
107
	dkey.dsize = strlen(key);
108
	dvalue.dptr = (char *)value;
109
	dvalue.dsize = size;
110
	if (gdbm_store(dbf, dkey, dvalue, GDBM_REPLACE) != 0)
111
		return -1;
112

  
113
	return 0;
114
}
115

  
116
static int xf_gdbm_fetch(XFilterKVS *kvs, const char *key, void *vbuf, int vsize)
117
{
118
	GDBM_FILE dbf;
119
	datum dkey, dvalue;
120

  
121
	dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
122

  
123
	dkey.dptr = (char *)key;
124
	dkey.dsize = strlen(key);
125
	dvalue = gdbm_fetch(dbf, dkey);
126
	if (!dvalue.dptr)
127
		return -1;
128

  
129
	memcpy(vbuf, dvalue.dptr, MIN(vsize, dvalue.dsize));
130
	free(dvalue.dptr);
131

  
132
	return dvalue.dsize;
133
}
134

  
135
static int xf_gdbm_size(XFilterKVS *kvs)
136
{
137
	GDBM_FILE dbf;
138
	datum dkey, nkey;
139
	int size = 0;
140

  
141
	dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
142

  
143
	for (dkey = gdbm_firstkey(dbf); dkey.dptr; size++) {
144
		nkey = gdbm_nextkey(dbf, dkey);
145
		free(dkey.dptr);
146
		dkey = nkey;
147
	}
148

  
149
	return size;
150
}
151

  
152
static int xf_gdbm_foreach(XFilterKVS *kvs, XFilterKVSForeachFunc func, void *data)
153
{
154
	GDBM_FILE dbf;
155
	datum dkey, dvalue, nkey;
156
	char key[1024];
157
	int ksize;
158

  
159
	dbf = (GDBM_FILE)xfilter_kvs_get_handle(kvs);
160

  
161
	dkey = gdbm_firstkey(dbf);
162
	for (dkey = gdbm_firstkey(dbf); dkey.dptr; ) {
163
		int r;
164

  
165
		dvalue = gdbm_fetch(dbf, dkey);
166
		if (!dvalue.dptr) {
167
			free(dkey.dptr);
168
			break;
169
		}
170
		ksize = MIN(sizeof(key) - 1, dkey.dsize);
171
		memcpy(key, dkey.dptr, ksize);
172
		key[ksize] = '\0';
173
		r = func(kvs, key, dvalue.dptr, dvalue.dsize, data);
174
		if (r < 0) {
175
			free(dvalue.dptr);
176
			free(dkey.dptr);
177
			break;
178
		}
179
		nkey = gdbm_nextkey(dbf, dkey);
180
		free(dvalue.dptr);
181
		free(dkey.dptr);
182

  
183
		dkey = nkey;
184
	}
185

  
186
	return 0;
187
}
188

  
189
#endif /* USE_GDBM */
lib/filter-kvs-gdbm.h
1
/* SylFilter - a message filter
2
 *
3
 * Copyright (C) 2011 Hiroyuki Yamamoto
4
 * Copyright (C) 2011 Sylpheed Development Team
5
 */
6

  
7
#ifndef __FILTER_KVS_GDBM__
8
#define __FILTER_KVS_GDBM__
9

  
10
int xfilter_kvs_gdbm_set_engine(void);
11

  
12
#endif /* __FILTER_KVS_GDBM__ */

Also available in: Unified diff