Commit a1b914b0 a1b914b0c326dd4d5bb4d4fde83ca694e820bc40 by Wojciech Polak

Add Tokyo Cabinet DBM support.

* configure.ac: Add new option --with-tokyocabinet.
* lib/mu_dbm.c: Add Tokyo Cabinet support.
* lib/mu_dbm.h: Likewise.
* pop3d/popauth.c: Likewise.
1 parent 6c358357
...@@ -274,6 +274,10 @@ use DBM-based mail box quotas with maildag. ...@@ -274,6 +274,10 @@ use DBM-based mail box quotas with maildag.
274 274
275 Use NDBM 275 Use NDBM
276 276
277 --with-tokyocabinet
278
279 Use Tokyo Cabinet DBM
280
277 Only one dbm option may be specified. Which one depends on 281 Only one dbm option may be specified. Which one depends on
278 the flavor of DBM you are using. GDBM is most common for GNU 282 the flavor of DBM you are using. GDBM is most common for GNU
279 system. 283 system.
...@@ -312,7 +316,7 @@ by visiting http://mail.gnu.org/mailman/listinfo/bug-mailutils. ...@@ -312,7 +316,7 @@ by visiting http://mail.gnu.org/mailman/listinfo/bug-mailutils.
312 316
313 * Copyright information: 317 * Copyright information:
314 318
315 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 319 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
316 320
317 Permission is granted to anyone to make or distribute verbatim 321 Permission is granted to anyone to make or distribute verbatim
318 copies of this document as received, in any medium, provided that 322 copies of this document as received, in any medium, provided that
......
...@@ -378,6 +378,16 @@ case "${withval}" in ...@@ -378,6 +378,16 @@ case "${withval}" in
378 *) AC_MSG_ERROR(bad value ${withval} for --with-ndbm) ;; 378 *) AC_MSG_ERROR(bad value ${withval} for --with-ndbm) ;;
379 esac]) 379 esac])
380 380
381 AC_ARG_WITH([tokyocabinet],
382 AC_HELP_STRING([--with-tokyocabinet],
383 [use Tokyo Cabinet]),
384 [
385 case "${withval}" in
386 yes) use_dbm=TC ;;
387 no) use_dbm=no ;;
388 *) AC_MSG_ERROR(bad value ${withval} for --with-tokyocabinet) ;;
389 esac])
390
381 AC_MSG_CHECKING(for log facility) 391 AC_MSG_CHECKING(for log facility)
382 log_facility="LOG_MAIL" 392 log_facility="LOG_MAIL"
383 AC_ARG_WITH([log-facility], 393 AC_ARG_WITH([log-facility],
...@@ -1043,6 +1053,14 @@ NDBM) ...@@ -1043,6 +1053,14 @@ NDBM)
1043 [Enable use of NDBM])) 1053 [Enable use of NDBM]))
1044 LIBS="$LIBS -lndbm" 1054 LIBS="$LIBS -lndbm"
1045 status_dbm="NDBM"]);; 1055 status_dbm="NDBM"]);;
1056
1057 TC)
1058 AC_CHECK_LIB(tokyocabinet, tchdbnew,
1059 [AC_CHECK_HEADERS(tchdb.h,
1060 AC_DEFINE(WITH_TOKYOCABINET,1,
1061 [Enable use of Tokyo Cabinet]))
1062 LIBS="$LIBS -ltokyocabinet -lz -lbz2 -lrt"
1063 status_dbm="Tokyo Cabinet"]);;
1046 esac 1064 esac
1047 1065
1048 AC_SUBST(POPAUTH) 1066 AC_SUBST(POPAUTH)
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2002, 2006, 2 Copyright (C) 1999, 2000, 2001, 2002, 2006, 2007, 2009
3 2007 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5 GNU Mailutils is free software; you can redistribute it and/or modify 5 GNU Mailutils is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
...@@ -141,7 +141,7 @@ mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode) ...@@ -141,7 +141,7 @@ mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode)
141 errno = EINVAL; 141 errno = EINVAL;
142 return 1; 142 return 1;
143 } 143 }
144 *db = gdbm_open(pfname, 512, f, mode, NULL); 144 *db = gdbm_open (pfname, 512, f, mode, NULL);
145 free (pfname); 145 free (pfname);
146 return *db == NULL; 146 return *db == NULL;
147 } 147 }
...@@ -156,7 +156,7 @@ mu_dbm_close (DBM_FILE db) ...@@ -156,7 +156,7 @@ mu_dbm_close (DBM_FILE db)
156 int 156 int
157 mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) 157 mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret)
158 { 158 {
159 *ret = gdbm_fetch(db, key); 159 *ret = gdbm_fetch (db, key);
160 return ret->dptr == NULL; 160 return ret->dptr == NULL;
161 } 161 }
162 162
...@@ -169,7 +169,7 @@ mu_dbm_delete (DBM_FILE db, DBM_DATUM key) ...@@ -169,7 +169,7 @@ mu_dbm_delete (DBM_FILE db, DBM_DATUM key)
169 int 169 int
170 mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) 170 mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace)
171 { 171 {
172 return gdbm_store(db, key, contents, 172 return gdbm_store (db, key, contents,
173 replace ? GDBM_REPLACE : GDBM_INSERT); 173 replace ? GDBM_REPLACE : GDBM_INSERT);
174 } 174 }
175 175
...@@ -304,16 +304,16 @@ mu_dbm_firstkey (DBM_FILE db) ...@@ -304,16 +304,16 @@ mu_dbm_firstkey (DBM_FILE db)
304 DBT key, data; 304 DBT key, data;
305 int ret; 305 int ret;
306 306
307 memset(&key, 0, sizeof key); 307 memset (&key, 0, sizeof key);
308 memset(&data, 0, sizeof data); 308 memset (&data, 0, sizeof data);
309 309
310 if (!db->dbc) 310 if (!db->dbc)
311 { 311 {
312 if (db->db->cursor(db->db, NULL, &db->dbc BDB2_CURSOR_LASTARG) != 0) 312 if (db->db->cursor (db->db, NULL, &db->dbc BDB2_CURSOR_LASTARG) != 0)
313 return key; 313 return key;
314 } 314 }
315 315
316 if ((ret = db->dbc->c_get(db->dbc, &key, &data, DB_FIRST)) != 0) 316 if ((ret = db->dbc->c_get (db->dbc, &key, &data, DB_FIRST)) != 0)
317 { 317 {
318 key.data = NULL; 318 key.data = NULL;
319 key.size = 0; 319 key.size = 0;
...@@ -331,13 +331,13 @@ mu_dbm_nextkey (DBM_FILE db, DBM_DATUM pkey /*unused*/) ...@@ -331,13 +331,13 @@ mu_dbm_nextkey (DBM_FILE db, DBM_DATUM pkey /*unused*/)
331 DBT key, data; 331 DBT key, data;
332 int ret; 332 int ret;
333 333
334 memset(&key, 0, sizeof key); 334 memset (&key, 0, sizeof key);
335 memset(&data, 0, sizeof data); 335 memset (&data, 0, sizeof data);
336 336
337 if (!db->dbc) 337 if (!db->dbc)
338 return key; 338 return key;
339 339
340 if ((ret = db->dbc->c_get(db->dbc, &key, &data, DB_NEXT)) != 0) 340 if ((ret = db->dbc->c_get (db->dbc, &key, &data, DB_NEXT)) != 0)
341 { 341 {
342 key.data = NULL; 342 key.data = NULL;
343 key.size = 0; 343 key.size = 0;
...@@ -452,5 +452,125 @@ mu_dbm_datum_free (DBM_DATUM *datum) ...@@ -452,5 +452,125 @@ mu_dbm_datum_free (DBM_DATUM *datum)
452 { 452 {
453 /* empty */ 453 /* empty */
454 } 454 }
455
456 #elif defined(WITH_TOKYOCABINET)
457
458 #define DB_SUFFIX ".tch"
459
460 int
461 mu_dbm_stat (char *name, struct stat *sb)
462 {
463 int rc;
464 char *pfname = make_db_name (name, DB_SUFFIX);
465 rc = stat (pfname, sb);
466 free (pfname);
467 return rc;
468 }
469
470 int
471 mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode)
472 {
473 int f, ecode;
474 char *pfname = make_db_name (name, DB_SUFFIX);
475
476 if (mu_check_perm (pfname, mode))
477 {
478 free (pfname);
479 return -1;
480 }
481
482 switch (flags)
483 {
484 case MU_STREAM_CREAT:
485 f = HDBOWRITER | HDBOCREAT;
486 break;
487
488 case MU_STREAM_READ:
489 f = HDBOREADER;
490 break;
491
492 case MU_STREAM_RDWR:
493 f = HDBOREADER | HDBOWRITER;
494 break;
495
496 default:
497 free (pfname);
498 errno = EINVAL;
499 return 1;
500 }
501
502 *db = malloc (sizeof **db);
503 if (!*db)
504 {
505 errno = ENOMEM;
506 return -1;
507 }
508 (*db)->hdb = tchdbnew ();
509
510 if (!tchdbopen ((*db)->hdb, pfname, f))
511 ecode = tchdbecode ((*db)->hdb);
512
513 free (pfname);
514 return 0;
515 }
516
517 int
518 mu_dbm_close (DBM_FILE db)
519 {
520 tchdbclose (db->hdb);
521 tchdbdel (db->hdb);
522 return 0;
523 }
524
525 int
526 mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret)
527 {
528 ret->data = tchdbget (db->hdb, key.data, key.size, &ret->size);
529 return ret->data == NULL;
530 }
531
532 int
533 mu_dbm_delete (DBM_FILE db, DBM_DATUM key)
534 {
535 return !tchdbout (db->hdb, key.data, key.size);
536 }
537
538 int
539 mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace)
540 {
541 if (replace)
542 return !tchdbput (db->hdb, key.data, key.size, contents.data, contents.size);
543 else
544 return !tchdbputkeep (db->hdb, key.data, key.size,
545 contents.data, contents.size);
546 }
547
548 DBM_DATUM
549 mu_dbm_firstkey (DBM_FILE db)
550 {
551 DBM_DATUM key;
552 memset (&key, 0, sizeof key);
553
554 tchdbiterinit (db->hdb);
555 key.data = tchdbiternext (db->hdb, &key.size);
556 return key;
557 }
558
559 DBM_DATUM
560 mu_dbm_nextkey (DBM_FILE db, DBM_DATUM unused)
561 {
562 DBM_DATUM key;
563 memset (&key, 0, sizeof key);
564
565 key.data = tchdbiternext (db->hdb, &key.size);
566 return key;
567 }
568
569 void
570 mu_dbm_datum_free (DBM_DATUM *datum)
571 {
572 /* empty */
573 }
574
455 #endif 575 #endif
456 576
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2002, 2005, 2007 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001, 2002, 2005, 2007, 2009
3 Free Software Foundation, Inc.
3 4
4 GNU Mailutils is free software; you can redistribute it and/or modify 5 GNU Mailutils 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 it under the terms of the GNU General Public License as published by
...@@ -52,6 +53,27 @@ typedef datum DBM_DATUM; ...@@ -52,6 +53,27 @@ typedef datum DBM_DATUM;
52 #define MU_DATUM_SIZE(d) (d).dsize 53 #define MU_DATUM_SIZE(d) (d).dsize
53 #define MU_DATUM_PTR(d) (d).dptr 54 #define MU_DATUM_PTR(d) (d).dptr
54 55
56 #elif defined(WITH_TOKYOCABINET)
57
58 #include <tcutil.h>
59 #include <tchdb.h>
60 #define USE_DBM
61
62 struct tokyocabinet_file
63 {
64 TCHDB *hdb;
65 };
66
67 struct tokyocabinet_datum {
68 void *data;
69 int size;
70 };
71
72 typedef struct tokyocabinet_file *DBM_FILE;
73 typedef struct tokyocabinet_datum DBM_DATUM;
74 #define MU_DATUM_SIZE(d) (d).size
75 #define MU_DATUM_PTR(d) (d).data
76
55 #endif 77 #endif
56 78
57 #ifdef USE_DBM 79 #ifdef USE_DBM
...@@ -65,7 +87,7 @@ int mu_dbm_delete (DBM_FILE db, DBM_DATUM key); ...@@ -65,7 +87,7 @@ int mu_dbm_delete (DBM_FILE db, DBM_DATUM key);
65 DBM_DATUM mu_dbm_firstkey (DBM_FILE db); 87 DBM_DATUM mu_dbm_firstkey (DBM_FILE db);
66 DBM_DATUM mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key); 88 DBM_DATUM mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key);
67 void mu_dbm_datum_free(DBM_DATUM *datum); 89 void mu_dbm_datum_free(DBM_DATUM *datum);
68 #endif 90 #endif /* USE_DBM */
69 91
70 int mu_fcheck_perm (int fd, int mode); 92 int mu_fcheck_perm (int fd, int mode);
71 int mu_check_perm (const char *name, int mode); 93 int mu_check_perm (const char *name, int mode);
......
...@@ -595,6 +595,8 @@ popauth_version (FILE *stream, struct argp_state *state) ...@@ -595,6 +595,8 @@ popauth_version (FILE *stream, struct argp_state *state)
595 # define FORMAT "NDBM" 595 # define FORMAT "NDBM"
596 #elif defined(WITH_OLD_DBM) 596 #elif defined(WITH_OLD_DBM)
597 # define FORMAT "Old DBM" 597 # define FORMAT "Old DBM"
598 #elif defined(WITH_TOKYOCABINET)
599 # define FORMAT "Tokyo Cabinet"
598 #endif 600 #endif
599 printf ("%s\n", argp_program_version); 601 printf ("%s\n", argp_program_version);
600 printf (_("Database format: %s\n"), FORMAT); 602 printf (_("Database format: %s\n"), FORMAT);
......