Commit df905e61 df905e61a7c77f02203c3445757a6f59a02a85b0 by Wojciech Polak

Add Kyoto Cabinet DBM support.

* libmu_dbm/kyoto.c: New file.
* libmu_dbm/dbm.c: Update.
* libmu_dbm/mudbm.h: Update.
* libmu_dbm/Makefile.am: (libmu_dbm_la_SOURCES): Add kyoto.c
* configure.ac: Add --with-kyotocabinet.
* README: Update.
* doc/texinfo/programs.texi: Likewise.
* libmailutils/base/version.c: Likewise.
1 parent 65f1d1f2
...@@ -287,6 +287,11 @@ use DBM-based mail box quotas with maildag. ...@@ -287,6 +287,11 @@ use DBM-based mail box quotas with maildag.
287 287
288 Use Tokyo Cabinet DBM 288 Use Tokyo Cabinet DBM
289 289
290 --with-kyotocabinet
291
292 Use Kyoto Cabinet DBM
293
294
290 Use following options to disable support for particular protocols or 295 Use following options to disable support for particular protocols or
291 features: 296 features:
292 297
......
...@@ -413,6 +413,16 @@ case "${withval}" in ...@@ -413,6 +413,16 @@ case "${withval}" in
413 *) AC_MSG_ERROR(bad value ${withval} for --with-tokyocabinet) ;; 413 *) AC_MSG_ERROR(bad value ${withval} for --with-tokyocabinet) ;;
414 esac]) 414 esac])
415 415
416 AC_ARG_WITH([kyotocabinet],
417 AC_HELP_STRING([--with-kyotocabinet],
418 [use Kyoto Cabinet]),
419 [
420 case "${withval}" in
421 yes) enable_dbm="$enable_dbm KC";;
422 no) disable_dbm="$disable_dbm KC";;
423 *) AC_MSG_ERROR(bad value ${withval} for --with-kyotocabinet) ;;
424 esac])
425
416 dnl Check for DBM 426 dnl Check for DBM
417 427
418 AH_TEMPLATE([WITH_BDB], 428 AH_TEMPLATE([WITH_BDB],
...@@ -551,6 +561,15 @@ check_dbm_impl() { ...@@ -551,6 +561,15 @@ check_dbm_impl() {
551 DBMLIB_DEPENDENCY="$DBMLIB_DEPENDENCY -lz -lbz2 -lrt" 561 DBMLIB_DEPENDENCY="$DBMLIB_DEPENDENCY -lz -lbz2 -lrt"
552 DBMLIBS="$DBMLIBS -ltokyocabinet" 562 DBMLIBS="$DBMLIBS -ltokyocabinet"
553 status_dbm="$status_dbm,Tokyo Cabinet"]);; 563 status_dbm="$status_dbm,Tokyo Cabinet"]);;
564
565 KC)
566 AC_CHECK_LIB(kyotocabinet, kcdbnew,
567 [AC_CHECK_HEADERS(kclangc.h,
568 AC_DEFINE(WITH_KYOTOCABINET,1,
569 [Enable use of Kyoto Cabinet]))
570 DBMLIB_DEPENDENCY="$DBMLIB_DEPENDENCY -lz -lbz2 -lrt"
571 DBMLIBS="$DBMLIBS -lkyotocabinet"
572 status_dbm="$status_dbm,Kyoto Cabinet"]);;
554 esac 573 esac
555 } 574 }
556 575
......
...@@ -5649,8 +5649,8 @@ The mailbox quota can be retrieved from the following sources: ...@@ -5649,8 +5649,8 @@ The mailbox quota can be retrieved from the following sources:
5649 To use @acronym{DBM} quota database, GNU Mailutils must 5649 To use @acronym{DBM} quota database, GNU Mailutils must
5650 be compiled with one of the following command line options: 5650 be compiled with one of the following command line options:
5651 @option{--with-gdbm}, @option{--with-berkeley-db}, @option{--with-ndbm}, 5651 @option{--with-gdbm}, @option{--with-berkeley-db}, @option{--with-ndbm},
5652 or @option{--with-tokyocabinet}. Examine the output of @command{maidag 5652 @option{--with-tokyocabinet}, or @option{--with-kyotocabinet}.
5653 --show-config-options}, if not sure. 5653 Examine the output of @command{maidag --show-config-options}, if not sure.
5654 5654
5655 The quota database should have the following structure: 5655 The quota database should have the following structure:
5656 5656
......
...@@ -61,6 +61,9 @@ static struct mu_conf_option mu_conf_option[] = { ...@@ -61,6 +61,9 @@ static struct mu_conf_option mu_conf_option[] = {
61 #ifdef WITH_TOKYOCABINET 61 #ifdef WITH_TOKYOCABINET
62 { "WITH_TOKYOCABINET", N_("Tokyo Cabinet DBM") }, 62 { "WITH_TOKYOCABINET", N_("Tokyo Cabinet DBM") },
63 #endif 63 #endif
64 #ifdef WITH_KYOTOCABINET
65 { "WITH_KYOTOCABINET", N_("Kyoto Cabinet DBM") },
66 #endif
64 #ifdef WITH_GNUTLS 67 #ifdef WITH_GNUTLS
65 { "WITH_GNUTLS", N_("TLS support using GNU TLS") }, 68 { "WITH_GNUTLS", N_("TLS support using GNU TLS") },
66 #endif 69 #endif
......
...@@ -36,6 +36,7 @@ libmu_dbm_la_SOURCES = \ ...@@ -36,6 +36,7 @@ libmu_dbm_la_SOURCES = \
36 store.c\ 36 store.c\
37 berkeley.c\ 37 berkeley.c\
38 gdbm.c\ 38 gdbm.c\
39 kyoto.c\
39 ndbm.c\ 40 ndbm.c\
40 tokyo.c 41 tokyo.c
41 42
......
...@@ -83,6 +83,9 @@ mu_dbm_init () ...@@ -83,6 +83,9 @@ mu_dbm_init ()
83 #ifdef WITH_TOKYOCABINET 83 #ifdef WITH_TOKYOCABINET
84 mu_dbm_register (&_mu_dbm_tokyocabinet); 84 mu_dbm_register (&_mu_dbm_tokyocabinet);
85 #endif 85 #endif
86 #ifdef WITH_KYOTOCABINET
87 mu_dbm_register (&_mu_dbm_kyotocabinet);
88 #endif
86 if (!mu_dbm_hint) 89 if (!mu_dbm_hint)
87 { 90 {
88 struct mu_dbm_impl *impl; 91 struct mu_dbm_impl *impl;
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library 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 GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 #include <fcntl.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/stat.h>
25 #include <mailutils/types.h>
26 #include <mailutils/dbm.h>
27 #include <mailutils/util.h>
28 #include <mailutils/errno.h>
29 #include <mailutils/error.h>
30 #include <mailutils/stream.h>
31 #include <mailutils/io.h>
32 #include "mudbm.h"
33
34 #if defined(WITH_KYOTOCABINET)
35 #include <kclangc.h>
36
37 struct kc_descr
38 {
39 KCDB *db; /* db */
40 KCCUR *cur; /* cursor */
41 };
42
43 static int
44 _kc_file_safety (mu_dbm_file_t db, int mode, uid_t owner)
45 {
46 return mu_file_safety_check (db->db_name, mode, owner, NULL);
47 }
48
49 int
50 _kc_get_fd (mu_dbm_file_t db, int *pag, int *dir)
51 {
52 return ENOSYS;
53 }
54
55 static int
56 _kc_open (mu_dbm_file_t db, int flags, int mode)
57 {
58 struct kc_descr *kcd;
59 int f, result;
60 mode_t save_um;
61 KCDB *kdb;
62
63 switch (flags)
64 {
65 case MU_STREAM_CREAT:
66 f = KCOWRITER | KCOCREATE;
67 break;
68
69 case MU_STREAM_READ:
70 f = KCOREADER;
71 break;
72
73 case MU_STREAM_RDWR:
74 f = KCOREADER | KCOWRITER;
75 break;
76
77 default:
78 return EINVAL;
79 }
80
81 kdb = kcdbnew ();
82
83 save_um = umask (0666 & ~mode);
84 result = kcdbopen (kdb, db->db_name, f);
85 umask (save_um);
86 if (!result)
87 {
88 db->db_errno.n = kcdbecode (kdb);
89 return MU_ERR_FAILURE;
90 }
91
92 kcd = calloc (1, sizeof (*kcd));
93 kcd->db = kdb;
94 kcd->cur = NULL;
95 db->db_descr = kcd;
96 return 0;
97 }
98
99 static int
100 _kc_close (mu_dbm_file_t db)
101 {
102 if (db->db_descr)
103 {
104 struct kc_descr *kcd = db->db_descr;
105 kcdbclose (kcd->db);
106 kcdbdel (kcd->db);
107 free (kcd);
108 db->db_descr = NULL;
109 }
110 return 0;
111 }
112
113 static int
114 _kc_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key,
115 struct mu_dbm_datum *ret)
116 {
117 struct kc_descr *kcd = db->db_descr;
118 void *ptr;
119 size_t retsize;
120
121 ptr = kcdbget (kcd->db, key->mu_dptr, key->mu_dsize, &retsize);
122 if (ptr)
123 {
124 mu_dbm_datum_free (ret);
125 ret->mu_dptr = ptr;
126 ret->mu_dsize = retsize;
127 return 0;
128 }
129 else if ((db->db_errno.n = kcdbecode (kcd->db)) == KCENOREC)
130 return MU_ERR_NOENT;
131 return MU_ERR_FAILURE;
132 }
133
134 static int
135 _kc_store (mu_dbm_file_t db,
136 struct mu_dbm_datum const *key,
137 struct mu_dbm_datum const *contents,
138 int replace)
139 {
140 struct kc_descr *kcd = db->db_descr;
141 int result;
142
143 if (replace)
144 result = kcdbreplace (kcd->db, key->mu_dptr, key->mu_dsize,
145 contents->mu_dptr, contents->mu_dsize);
146 else
147 result = kcdbadd (kcd->db, key->mu_dptr, key->mu_dsize,
148 contents->mu_dptr, contents->mu_dsize);
149 if (result)
150 return 0;
151 db->db_errno.n = kcdbecode (kcd->db);
152 if (db->db_errno.n == KCEDUPREC)
153 return MU_ERR_EXISTS;
154 return MU_ERR_FAILURE;
155 }
156
157 static int
158 _kc_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
159 {
160 struct kc_descr *kcd = db->db_descr;
161
162 if (kcdbremove (kcd->db, key->mu_dptr, key->mu_dsize))
163 return 0;
164 db->db_errno.n = kcdbecode (kcd->db);
165 if (db->db_errno.n == KCENOREC)
166 return MU_ERR_NOENT;
167 return MU_ERR_FAILURE;
168 }
169
170 static int
171 _kc_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
172 {
173 struct kc_descr *kcd = db->db_descr;
174 void *ptr;
175 size_t retsize;
176
177 kcd->cur = kcdbcursor (kcd->db);
178 kccurjump (kcd->cur);
179
180 ptr = kccurgetkey (kcd->cur, &retsize, 1);
181 if (ptr)
182 {
183 mu_dbm_datum_free (ret);
184 ret->mu_dptr = ptr;
185 ret->mu_dsize = retsize;
186 return 0;
187 }
188 else if ((db->db_errno.n = kcdbecode (kcd->db)) == KCENOREC)
189 {
190 kccurdel (kcd->cur);
191 kcd->cur = NULL;
192 return MU_ERR_NOENT;
193 }
194 return MU_ERR_FAILURE;
195 }
196
197 static int
198 _kc_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
199 {
200 struct kc_descr *kcd = db->db_descr;
201 void *ptr;
202 size_t retsize;
203
204 ptr = kccurgetkey (kcd->cur, &retsize, 1);
205 if (ptr)
206 {
207 mu_dbm_datum_free (ret);
208 ret->mu_dptr = ptr;
209 ret->mu_dsize = retsize;
210 return 0;
211 }
212 else if ((db->db_errno.n = kcdbecode (kcd->db)) == KCENOREC)
213 {
214 kccurdel (kcd->cur);
215 kcd->cur = NULL;
216 return MU_ERR_NOENT;
217 }
218 return MU_ERR_FAILURE;
219 }
220
221 static void
222 _kc_datum_free (struct mu_dbm_datum *datum)
223 {
224 free (datum->mu_dptr);
225 }
226
227 static char const *
228 _kc_strerror (mu_dbm_file_t db)
229 {
230 return kcecodename (db->db_errno.n);
231 }
232
233 struct mu_dbm_impl _mu_dbm_kyotocabinet = {
234 "kc",
235 _kc_file_safety,
236 _kc_get_fd,
237 _kc_open,
238 _kc_close,
239 _kc_fetch,
240 _kc_store,
241 _kc_delete,
242 _kc_firstkey,
243 _kc_nextkey,
244 _kc_datum_free,
245 _kc_strerror
246 };
247 #endif
...@@ -42,6 +42,9 @@ extern struct mu_dbm_impl _mu_dbm_ndbm; ...@@ -42,6 +42,9 @@ extern struct mu_dbm_impl _mu_dbm_ndbm;
42 #ifdef WITH_TOKYOCABINET 42 #ifdef WITH_TOKYOCABINET
43 extern struct mu_dbm_impl _mu_dbm_tokyocabinet; 43 extern struct mu_dbm_impl _mu_dbm_tokyocabinet;
44 #endif 44 #endif
45 #ifdef WITH_KYOTOCABINET
46 extern struct mu_dbm_impl _mu_dbm_kyotocabinet;
47 #endif
45 48
46 void _mu_dbm_init (void); 49 void _mu_dbm_init (void);
47 50
......