Commit 87e973dd 87e973ddd0b24493db0b316890360a2fdb028626 by Wojciech Polak

Re-add Tokyo Cabinet DBM support.

* libmu_dbm/tokyo.c: New file.
* libmu_dbm/Makefile.am (libmu_dbm_la_SOURCES): Add tokyo.c.
* doc/texinfo/programs.texi: Update.
* README: Update.
1 parent 1145460e
...@@ -287,10 +287,6 @@ use DBM-based mail box quotas with maildag. ...@@ -287,10 +287,6 @@ use DBM-based mail box quotas with maildag.
287 287
288 Use Tokyo Cabinet DBM 288 Use Tokyo Cabinet DBM
289 289
290 Only one dbm option may be specified. Which one depends on
291 the flavor of DBM you are using. GDBM is most common for GNU
292 system.
293
294 Use following options to disable support for particular protocols or 290 Use following options to disable support for particular protocols or
295 features: 291 features:
296 292
......
...@@ -5648,8 +5648,8 @@ The mailbox quota can be retrieved from the following sources: ...@@ -5648,8 +5648,8 @@ The mailbox quota can be retrieved from the following sources:
5648 5648
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}, or 5651 @option{--with-gdbm}, @option{--with-berkeley-db}, @option{--with-ndbm},
5652 @option{--with-ndbm}. Examine the output of @command{maidag 5652 or @option{--with-tokyocabinet}. Examine the output of @command{maidag
5653 --show-config-options}, if not sure. 5653 --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:
......
...@@ -36,7 +36,8 @@ libmu_dbm_la_SOURCES = \ ...@@ -36,7 +36,8 @@ libmu_dbm_la_SOURCES = \
36 store.c\ 36 store.c\
37 berkeley.c\ 37 berkeley.c\
38 gdbm.c\ 38 gdbm.c\
39 ndbm.c 39 ndbm.c\
40 tokyo.c
40 41
41 noinst_HEADERS = mudbm.h 42 noinst_HEADERS = mudbm.h
42 43
......
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_TOKYOCABINET)
35 #include <tcutil.h>
36 #include <tchdb.h>
37
38 static int
39 _tc_file_safety (mu_dbm_file_t db, int mode, uid_t owner)
40 {
41 return mu_file_safety_check (db->db_name, mode, owner, NULL);
42 }
43
44 int
45 _tc_get_fd (mu_dbm_file_t db, int *pag, int *dir)
46 {
47 TCHDB *hdb = db->db_descr;
48 *pag = hdb->fd;
49 if (dir)
50 *dir = *pag;
51 return 0;
52 }
53
54 static int
55 _tc_open (mu_dbm_file_t db, int flags, int mode)
56 {
57 int f;
58 bool result;
59 mode_t save_um;
60 TCHDB *hdb;
61
62 switch (flags)
63 {
64 case MU_STREAM_CREAT:
65 f = HDBOWRITER | HDBOCREAT;
66 break;
67
68 case MU_STREAM_READ:
69 f = HDBOREADER;
70 break;
71
72 case MU_STREAM_RDWR:
73 f = HDBOREADER | HDBOWRITER;
74 break;
75
76 default:
77 return EINVAL;
78 }
79
80 hdb = tchdbnew ();
81
82 save_um = umask (0666 & ~mode);
83 result = tchdbopen (hdb, db->db_name, f);
84 umask (save_um);
85 if (!result)
86 {
87 db->db_errno.n = tchdbecode (hdb);
88 return MU_ERR_FAILURE;
89 }
90 db->db_descr = hdb;
91 return 0;
92 }
93
94 static int
95 _tc_close (mu_dbm_file_t db)
96 {
97 if (db->db_descr)
98 {
99 TCHDB *hdb = db->db_descr;
100 tchdbclose (hdb);
101 tchdbdel (hdb);
102 db->db_descr = NULL;
103 }
104 return 0;
105 }
106
107 static int
108 _tc_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key,
109 struct mu_dbm_datum *ret)
110 {
111 TCHDB *hdb = db->db_descr;
112 void *ptr;
113 int retsize;
114
115 ptr = tchdbget (hdb, key->mu_dptr, key->mu_dsize, &retsize);
116 if (ptr)
117 {
118 mu_dbm_datum_free (ret);
119 ret->mu_dptr = ptr;
120 ret->mu_dsize = retsize;
121 return 0;
122 }
123 else if ((db->db_errno.n = tchdbecode (hdb)) == TCENOREC)
124 return MU_ERR_NOENT;
125 return MU_ERR_FAILURE;
126 }
127
128 static int
129 _tc_store (mu_dbm_file_t db,
130 struct mu_dbm_datum const *key,
131 struct mu_dbm_datum const *contents,
132 int replace)
133 {
134 TCHDB *hdb = db->db_descr;
135 bool result;
136
137 if (replace)
138 result = tchdbput (hdb, key->mu_dptr, key->mu_dsize,
139 contents->mu_dptr, contents->mu_dsize);
140 else
141 result = tchdbputkeep (hdb, key->mu_dptr, key->mu_dsize,
142 contents->mu_dptr, contents->mu_dsize);
143 if (result)
144 return 0;
145 db->db_errno.n = tchdbecode (hdb);
146 if (db->db_errno.n == TCEKEEP)
147 return MU_ERR_EXISTS;
148 return MU_ERR_FAILURE;
149 }
150
151 static int
152 _tc_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
153 {
154 TCHDB *hdb = db->db_descr;
155
156 if (tchdbout (hdb, key->mu_dptr, key->mu_dsize))
157 return 0;
158 db->db_errno.n = tchdbecode (hdb);
159 if (db->db_errno.n == TCENOREC)
160 return MU_ERR_NOENT;
161 return MU_ERR_FAILURE;
162 }
163
164 static int
165 _tc_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
166 {
167 TCHDB *hdb = db->db_descr;
168 void *ptr;
169 int retsize;
170
171 tchdbiterinit (hdb);
172 ptr = tchdbiternext (hdb, &retsize);
173 if (ptr)
174 {
175 mu_dbm_datum_free (ret);
176 ret->mu_dptr = ptr;
177 ret->mu_dsize = retsize;
178 return 0;
179 }
180 else if ((db->db_errno.n = tchdbecode (hdb)) == TCENOREC)
181 return MU_ERR_NOENT;
182 return MU_ERR_FAILURE;
183 }
184
185 static int
186 _tc_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
187 {
188 TCHDB *hdb = db->db_descr;
189 void *ptr;
190 int retsize;
191
192 ptr = tchdbiternext (hdb, &retsize);
193 if (ptr)
194 {
195 mu_dbm_datum_free (ret);
196 ret->mu_dptr = ptr;
197 ret->mu_dsize = retsize;
198 return 0;
199 }
200 else if ((db->db_errno.n = tchdbecode (hdb)) == TCENOREC)
201 return MU_ERR_NOENT;
202 return MU_ERR_FAILURE;
203 }
204
205 static void
206 _tc_datum_free (struct mu_dbm_datum *datum)
207 {
208 free (datum->mu_dptr);
209 }
210
211 static char const *
212 _tc_strerror (mu_dbm_file_t db)
213 {
214 return tchdberrmsg (db->db_errno.n);
215 }
216
217 struct mu_dbm_impl _mu_dbm_tokyokabinet = {
218 "tc",
219 _tc_file_safety,
220 _tc_get_fd,
221 _tc_open,
222 _tc_close,
223 _tc_fetch,
224 _tc_store,
225 _tc_delete,
226 _tc_firstkey,
227 _tc_nextkey,
228 _tc_datum_free,
229 _tc_strerror
230 };
231 #endif