These functions provide an intermediate layer between the DBM API and
mailutils' applications.
Showing
2 changed files
with
493 additions
and
0 deletions
lib/mu_dbm.c
0 → 100644
1 | /* GNU mailutils - a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include <config.h> | ||
21 | #endif | ||
22 | |||
23 | #include <stdlib.h> | ||
24 | #include <unistd.h> | ||
25 | #include <fcntl.h> | ||
26 | #include <sys/types.h> | ||
27 | #include <sys/stat.h> | ||
28 | #include <string.h> | ||
29 | #ifdef HAVE_STRINGS_H | ||
30 | # include <strings.h> | ||
31 | #endif | ||
32 | #include <mu_dbm.h> | ||
33 | |||
34 | int | ||
35 | mu_fcheck_perm (int fd, int mode) | ||
36 | { | ||
37 | struct stat st; | ||
38 | |||
39 | if (fstat (fd, &st) == -1) | ||
40 | { | ||
41 | if (errno == ENOENT) | ||
42 | return 0; | ||
43 | else | ||
44 | return 1; | ||
45 | } | ||
46 | if ((st.st_mode & 0777) != mode) | ||
47 | return 1; | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | int | ||
52 | mu_check_perm (char *name, int mode) | ||
53 | { | ||
54 | struct stat st; | ||
55 | |||
56 | if (stat (name, &st) == -1) | ||
57 | { | ||
58 | if (errno == ENOENT) | ||
59 | return 0; | ||
60 | else | ||
61 | return 1; | ||
62 | } | ||
63 | if ((st.st_mode & 0777) != mode) | ||
64 | return 1; | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | #if defined(WITH_GDBM) | ||
69 | |||
70 | #define DB_SUFFIX ".db" | ||
71 | |||
72 | int | ||
73 | mu_dbm_open(char *name, DBM_FILE *db, int flags, int mode) | ||
74 | { | ||
75 | int f; | ||
76 | char *pfname; | ||
77 | |||
78 | pfname = xmalloc (strlen (name) + sizeof DB_SUFFIX); | ||
79 | strcat (strcpy (pfname, name), DB_SUFFIX); | ||
80 | if (mu_check_perm (pfname, mode)) | ||
81 | { | ||
82 | free (pfname); | ||
83 | return -1; | ||
84 | } | ||
85 | |||
86 | switch (flags) | ||
87 | { | ||
88 | case MU_STREAM_CREAT: | ||
89 | f = GDBM_NEWDB; | ||
90 | break; | ||
91 | case MU_STREAM_READ: | ||
92 | f = GDBM_READER; | ||
93 | break; | ||
94 | case MU_STREAM_RDWR: | ||
95 | f = GDBM_WRCREAT; | ||
96 | break; | ||
97 | default: | ||
98 | free (pfname); | ||
99 | errno = EINVAL; | ||
100 | return 1; | ||
101 | } | ||
102 | *db = gdbm_open(pfname, 512, f, mode, NULL); | ||
103 | free (pfname); | ||
104 | return *db == NULL; | ||
105 | } | ||
106 | |||
107 | int | ||
108 | mu_dbm_close(DBM_FILE db) | ||
109 | { | ||
110 | gdbm_close(db); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | int | ||
115 | mu_dbm_fetch(DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) | ||
116 | { | ||
117 | *ret = gdbm_fetch(db, key); | ||
118 | return ret->dptr == NULL; | ||
119 | } | ||
120 | |||
121 | int | ||
122 | mu_dbm_insert(DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) | ||
123 | { | ||
124 | return gdbm_store(db, key, contents, | ||
125 | replace ? GDBM_REPLACE : GDBM_INSERT); | ||
126 | } | ||
127 | |||
128 | DBM_DATUM | ||
129 | mu_dbm_firstkey (DBM_FILE db) | ||
130 | { | ||
131 | return gdbm_firstkey (db); | ||
132 | } | ||
133 | |||
134 | DBM_DATUM | ||
135 | mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key) | ||
136 | { | ||
137 | return gdbm_nextkey (db, key); | ||
138 | } | ||
139 | |||
140 | #elif defined(WITH_BDB2) | ||
141 | |||
142 | #define DB_SUFFIX ".db" | ||
143 | |||
144 | int | ||
145 | mu_dbm_open(char *name, DBM_FILE *dbm, int flags, int mode) | ||
146 | { | ||
147 | int f, rc; | ||
148 | DB *db; | ||
149 | char *pfname; | ||
150 | |||
151 | pfname = xmalloc (strlen (name) + sizeof DB_SUFFIX); | ||
152 | strcat (strcpy (pfname, name), DB_SUFFIX); | ||
153 | if (mu_check_perm (pfname, mode)) | ||
154 | { | ||
155 | free (pfname); | ||
156 | return -1; | ||
157 | } | ||
158 | |||
159 | switch (flags) | ||
160 | { | ||
161 | case MU_STREAM_CREAT: | ||
162 | f = DB_CREATE|DB_TRUNCATE; | ||
163 | break; | ||
164 | case MU_STREAM_READ: | ||
165 | f = DB_RDONLY; | ||
166 | break; | ||
167 | case MU_STREAM_RDWR: | ||
168 | f = DB_CREATE; | ||
169 | break; | ||
170 | default: | ||
171 | free (pfname); | ||
172 | errno = EINVAL; | ||
173 | return -1; | ||
174 | } | ||
175 | |||
176 | rc = db_open (pfname, DB_HASH, f, mode, NULL, NULL, &db); | ||
177 | free (pfname); | ||
178 | if (rc) | ||
179 | return -1; | ||
180 | |||
181 | *dbm = malloc (sizeof **dbm); | ||
182 | if (!*dbm) | ||
183 | { | ||
184 | db->close (db, 0); | ||
185 | errno = ENOMEM; | ||
186 | return -1; | ||
187 | } | ||
188 | (*dbm)->db = db; | ||
189 | (*dbm)->dbc = NULL; | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | int | ||
194 | mu_dbm_close(DBM_FILE db) | ||
195 | { | ||
196 | db->db->close (db->db, 0); | ||
197 | free (db); | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | int | ||
202 | mu_dbm_fetch(DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) | ||
203 | { | ||
204 | return db->db->get (db->db, NULL, &key, ret, 0); | ||
205 | } | ||
206 | |||
207 | int | ||
208 | mu_dbm_insert(DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) | ||
209 | { | ||
210 | /*FIXME: replace unused*/ | ||
211 | return db->db->put (db->db, NULL, &key, &contents, 0); | ||
212 | } | ||
213 | |||
214 | DBM_DATUM | ||
215 | mu_dbm_firstkey (DBM_FILE db) | ||
216 | { | ||
217 | DBT key, data; | ||
218 | int ret; | ||
219 | |||
220 | memset(&key, 0, sizeof key); | ||
221 | memset(&data, 0, sizeof data); | ||
222 | |||
223 | if (!db->dbc) | ||
224 | { | ||
225 | if (db->db->cursor(db->db, NULL, &db->dbc, 0) != 0) | ||
226 | return key; | ||
227 | } | ||
228 | |||
229 | if ((ret = db->dbc->c_get(db->dbc, &key, &data, DB_FIRST)) != 0) | ||
230 | { | ||
231 | key.data = NULL; | ||
232 | key.size = 0; | ||
233 | if (ret == DB_NOTFOUND) | ||
234 | errno = ENOENT; | ||
235 | else | ||
236 | errno = ret; | ||
237 | } | ||
238 | return key; | ||
239 | } | ||
240 | |||
241 | DBM_DATUM | ||
242 | mu_dbm_nextkey (DBM_FILE db, DBM_DATUM pkey /*unused*/) | ||
243 | { | ||
244 | DBT key, data; | ||
245 | int ret; | ||
246 | |||
247 | memset(&key, 0, sizeof key); | ||
248 | memset(&data, 0, sizeof data); | ||
249 | |||
250 | if (!db->dbc) | ||
251 | return key; | ||
252 | |||
253 | if ((ret = db->dbc->c_get(db->dbc, &key, &data, DB_NEXT)) != 0) | ||
254 | { | ||
255 | key.data = NULL; | ||
256 | key.size = 0; | ||
257 | if (ret == DB_NOTFOUND) | ||
258 | errno = ENOENT; | ||
259 | else | ||
260 | errno = ret; | ||
261 | } | ||
262 | return key; | ||
263 | } | ||
264 | |||
265 | #elif defined(WITH_NDBM) | ||
266 | |||
267 | #define DB_SUFFIX ".db" | ||
268 | |||
269 | int | ||
270 | mu_dbm_open(char *name, DBM_FILE *db, int flags, int mode) | ||
271 | { | ||
272 | int f; | ||
273 | |||
274 | switch (flags) | ||
275 | { | ||
276 | case MU_STREAM_CREAT: | ||
277 | f = O_CREAT|O_TRUNC|O_RDWR; | ||
278 | break; | ||
279 | case MU_STREAM_READ: | ||
280 | f = O_RDONLY; | ||
281 | break; | ||
282 | case MU_STREAM_RDWR: | ||
283 | f = O_CREAT|O_RDWR; | ||
284 | break; | ||
285 | default: | ||
286 | errno = EINVAL; | ||
287 | return -1; | ||
288 | } | ||
289 | *db = dbm_open (name, f, mode); | ||
290 | if (!*db) | ||
291 | return -1; | ||
292 | |||
293 | if (mu_fcheck_perm (dbm_dirfno (*db), mode) | ||
294 | || mu_fcheck_perm (dbm_pagfno (*db), mode)) | ||
295 | { | ||
296 | dbm_close (*db); | ||
297 | return 1; | ||
298 | } | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | int | ||
304 | mu_dbm_close(DBM_FILE db) | ||
305 | { | ||
306 | dbm_close(db); | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | int | ||
311 | mu_dbm_fetch(DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) | ||
312 | { | ||
313 | *ret = dbm_fetch(db, key); | ||
314 | return ret->dptr == NULL; | ||
315 | } | ||
316 | |||
317 | int | ||
318 | mu_dbm_insert(DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) | ||
319 | { | ||
320 | return dbm_store(db, key, contents, replace ? DBM_REPLACE : DBM_INSERT); | ||
321 | } | ||
322 | |||
323 | DBM_DATUM | ||
324 | mu_dbm_firstkey (DBM_FILE db) | ||
325 | { | ||
326 | return dbm_firstkey (db); | ||
327 | } | ||
328 | |||
329 | DBM_DATUM | ||
330 | mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key) | ||
331 | { | ||
332 | return dbm_nextkey (db, key); | ||
333 | } | ||
334 | |||
335 | #elif defined(WITH_OLD_DBM) | ||
336 | |||
337 | /*ARGSUSED*/ | ||
338 | int | ||
339 | mu_dbm_open(char *name, DBM_FILE *db, int flags, int mode) | ||
340 | { | ||
341 | int f; | ||
342 | |||
343 | switch (flags) | ||
344 | { | ||
345 | case MU_STREAM_CREAT: | ||
346 | f = O_CREAT|O_TRUNC|O_RDWR; | ||
347 | break; | ||
348 | case MU_STREAM_READ: | ||
349 | f = O_RDONLY; | ||
350 | break; | ||
351 | case MU_STREAM_RDWR: | ||
352 | f = O_CREAT|O_RDWR; | ||
353 | break; | ||
354 | default: | ||
355 | return -1; | ||
356 | } | ||
357 | |||
358 | if (f & O_CREAT) | ||
359 | { | ||
360 | char *p; | ||
361 | int fd; | ||
362 | |||
363 | p = xmalloc(strlen(name)+5); | ||
364 | strcat(strcpy(p, name), ".pag"); | ||
365 | fd = open(p, f, mode); | ||
366 | free(p); | ||
367 | if (fd < 0) | ||
368 | return -1; | ||
369 | close(fd); | ||
370 | |||
371 | p = xmalloc(strlen(name)+5); | ||
372 | strcat(strcpy(p, name), ".dir"); | ||
373 | fd = open(p, f, mode); | ||
374 | free(p); | ||
375 | if (fd < 0) | ||
376 | return -1; | ||
377 | close(fd); | ||
378 | } | ||
379 | |||
380 | return dbminit(name); | ||
381 | } | ||
382 | |||
383 | /*ARGSUSED*/ | ||
384 | int | ||
385 | mu_dbm_close(DBM_FILE db) | ||
386 | { | ||
387 | dbmclose(); | ||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | /*ARGSUSED*/ | ||
392 | int | ||
393 | mu_dbm_fetch(DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) | ||
394 | { | ||
395 | *ret = fetch(key); | ||
396 | return ret->dptr == NULL; | ||
397 | } | ||
398 | |||
399 | int | ||
400 | mu_dbm_insert(DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) | ||
401 | { | ||
402 | return store(key, contents); | ||
403 | } | ||
404 | |||
405 | DBM_DATUM | ||
406 | mu_dbm_firstkey (DBM_FILE db) | ||
407 | { | ||
408 | return firstkey (); | ||
409 | } | ||
410 | |||
411 | DBM_DATUM | ||
412 | mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key) | ||
413 | { | ||
414 | return nextkey (key); | ||
415 | } | ||
416 | |||
417 | #endif | ||
418 |
lib/mu_dbm.h
0 → 100644
1 | /* GNU mailutils - a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include <mailutils/stream.h> | ||
19 | |||
20 | #if defined(WITH_GDBM) | ||
21 | |||
22 | #include <gdbm.h> | ||
23 | #define USE_DBM | ||
24 | typedef GDBM_FILE DBM_FILE; | ||
25 | typedef datum DBM_DATUM; | ||
26 | #define MU_DATUM_SIZE(d) d.dsize | ||
27 | #define MU_DATUM_PTR(d) d.dptr | ||
28 | |||
29 | #elif defined(WITH_BDB2) | ||
30 | |||
31 | #include <db.h> | ||
32 | #define USE_DBM | ||
33 | |||
34 | struct db2_file | ||
35 | { | ||
36 | DB *db; | ||
37 | DBC *dbc; | ||
38 | }; | ||
39 | |||
40 | typedef struct db2_file *DBM_FILE; | ||
41 | typedef DBT DBM_DATUM; | ||
42 | #define MU_DATUM_SIZE(d) d.size | ||
43 | #define MU_DATUM_PTR(d) d.data | ||
44 | |||
45 | #elif defined(WITH_NDBM) | ||
46 | |||
47 | #include <ndbm.h> | ||
48 | #define USE_DBM | ||
49 | typedef DBM *DBM_FILE; | ||
50 | typedef datum DBM_DATUM; | ||
51 | #define MU_DATUM_SIZE(d) d.dsize | ||
52 | #define MU_DATUM_PTR(d) d.dptr | ||
53 | |||
54 | #elif defined(WITH_OLD_DBM) | ||
55 | |||
56 | #include <dbm.h> | ||
57 | #define USE_DBM | ||
58 | typedef int DBM_FILE; | ||
59 | typedef datum DBM_DATUM; | ||
60 | #define MU_DATUM_SIZE(d) d.dsize | ||
61 | #define MU_DATUM_PTR(d) d.dptr | ||
62 | |||
63 | #endif | ||
64 | |||
65 | #ifdef USE_DBM | ||
66 | int mu_dbm_open __P((char *name, DBM_FILE *db, int flags, int mode)); | ||
67 | int mu_dbm_close __P((DBM_FILE db)); | ||
68 | int mu_dbm_fetch __P((DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret)); | ||
69 | int mu_dbm_insert __P((DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace)); | ||
70 | DBM_DATUM mu_dbm_firstkey __P((DBM_FILE db)); | ||
71 | DBM_DATUM mu_dbm_nextkey __P((DBM_FILE db, DBM_DATUM key)); | ||
72 | #endif | ||
73 | |||
74 | int mu_fcheck_perm __P((int fd, int mode)); | ||
75 | int mu_check_perm __P((char *name, int mode)); |
-
Please register or sign in to post a comment