Reimplement DBM support.
* lib/mu_dbm.c: Remove. * lib/mu_dbm.h: Remove. * lib/Makefile.am: Remove mu_dbm.[ch]. * include/mailutils/sys/dbm.h: New file. * include/mailutils/sys/Makefile.am: Add dbm.h * include/mailutils/dbm.h: New file. * include/mailutils/Makefile.am (pkginclude_HEADERS): Add dbm.h. * include/mailutils/types.hin (mu_dbm_file_t): New data type. * libmu_dbm/Makefile.am: New file. * libmu_dbm/berkeley.c: New file. * libmu_dbm/close.c: New file. * libmu_dbm/create.c: New file. * libmu_dbm/datumfree.c: New file. * libmu_dbm/dbm.c: New file. * libmu_dbm/delete.c: New file. * libmu_dbm/destroy.c: New file. * libmu_dbm/errstr.c: New file. * libmu_dbm/fetch.c: New file. * libmu_dbm/firstkey.c: New file. * libmu_dbm/gdbm.c: New file. * libmu_dbm/mudbm.h: New file. * libmu_dbm/ndbm.c: New file. * libmu_dbm/nextkey.c: New file. * libmu_dbm/open.c: New file. * libmu_dbm/safety.c: New file. * libmu_dbm/store.c: New file. * Makefile.am [MU_COND_DBM]: Define LIBMU_DBM_DIR (SUBDIRS): Add $(LIBMU_DBM_DIR) * configure.ac: Revamp DBM support: several database types can be specified at once. (AC_CONFIG_FILES): Build libmu_dbm/Makefile * libmu_sieve/extensions/vacation.c: Remove inclusion of mu_dbm.h. * maidag/Makefile.am (maidag_LDADD): Add DBM libraries. * maidag/maidag.c: ENABLE_DBM instead of USE_DBM * maidag/maidag.h: Include <mailutils/dbm.h> instead of mu_dbm.h. * maidag/mailquota.c (dbm_retrieve_quota): Rewrite using libmu_dbm library calls. * mu/Makefile.am [MU_COND_DBM]: Define DBM_C. (MODULES): Add $(DBM_C). (AM_CPPFLAGS): Define DBMLIBS. * mu/ldflags.c (NEEDAUTH): Change definition. (lib_descr) <weight>: New member. All uses changed. (add_entry): Null arguments ignored. (mutool_ldflags): Rewrite traversal of lib_descr. * mu/dbm.c: New file. * pop3d/Makefile.am (pop3d_LDADD, popauth_LDADD): Add DBM libraries. * pop3d/apop.c: Rewrite using libmu_dbm library calls. * pop3d/bulletin.c: Likewise. * pop3d/logindelay.c: Likewise. * pop3d/pop3d.c: Change USE_DBM to ENABLE_DBM. * pop3d/pop3d.h: Include mailutils/dbm.h instead of mu_dbm.h * pop3d/popauth.c: Rewrite using libmu_dbm library calls. * include/mailutils/cctype.h (MU_CTYPE_ENDLN): New character class. (mu_isendln): New macro. * libmailutils/string/muctype.c (mu_c_tab): Mark \r and \n as MU_CTYPE_ENDLN.
Showing
46 changed files
with
3366 additions
and
1142 deletions
... | @@ -83,6 +83,10 @@ if MU_COND_SUPPORT_CXX | ... | @@ -83,6 +83,10 @@ if MU_COND_SUPPORT_CXX |
83 | LIBMU_CPP_DIR = libmu_cpp | 83 | LIBMU_CPP_DIR = libmu_cpp |
84 | endif | 84 | endif |
85 | 85 | ||
86 | if MU_COND_DBM | ||
87 | LIBMU_DBM_DIR = libmu_dbm | ||
88 | endif | ||
89 | |||
86 | SUBDIRS = . \ | 90 | SUBDIRS = . \ |
87 | mu-aux\ | 91 | mu-aux\ |
88 | include\ | 92 | include\ |
... | @@ -99,6 +103,7 @@ SUBDIRS = . \ | ... | @@ -99,6 +103,7 @@ SUBDIRS = . \ |
99 | $(LIBMU_CPP_DIR)\ | 103 | $(LIBMU_CPP_DIR)\ |
100 | $(GINT_DIR)\ | 104 | $(GINT_DIR)\ |
101 | $(LIBMU_SCM_DIR)\ | 105 | $(LIBMU_SCM_DIR)\ |
106 | $(LIBMU_DBM_DIR)\ | ||
102 | libmu_sieve\ | 107 | libmu_sieve\ |
103 | $(PYTHON_DIR)\ | 108 | $(PYTHON_DIR)\ |
104 | doc\ | 109 | doc\ | ... | ... |
... | @@ -88,7 +88,7 @@ AM_PROG_LIBTOOL | ... | @@ -88,7 +88,7 @@ AM_PROG_LIBTOOL |
88 | ## Predefine several variables used to display configuration status | 88 | ## Predefine several variables used to display configuration status |
89 | status_pam=no | 89 | status_pam=no |
90 | status_ltdl=no | 90 | status_ltdl=no |
91 | status_dbm=no | 91 | status_dbm= |
92 | status_gsasl=no | 92 | status_gsasl=no |
93 | status_mysql=no | 93 | status_mysql=no |
94 | status_pgsql=no | 94 | status_pgsql=no |
... | @@ -354,22 +354,31 @@ AH_BOTTOM( | ... | @@ -354,22 +354,31 @@ AH_BOTTOM( |
354 | # define MU_PATH_MAILDIR PATH_MAILDIR "/" | 354 | # define MU_PATH_MAILDIR PATH_MAILDIR "/" |
355 | #endif]) | 355 | #endif]) |
356 | 356 | ||
357 | use_dbm=no | 357 | ################################## |
358 | # DBM Support | ||
359 | ################################## | ||
360 | AC_SUBST(DBMLIBS) | ||
361 | AC_SUBST(DBMLIB_DEPENDENCY) | ||
362 | AC_SUBST(DBMINCLUDES) | ||
363 | |||
364 | enable_dbm=no | ||
365 | disable_dbm=no | ||
366 | |||
358 | AC_ARG_WITH([gdbm], | 367 | AC_ARG_WITH([gdbm], |
359 | AC_HELP_STRING([--with-gdbm], | 368 | AC_HELP_STRING([--with-gdbm], |
360 | [use GNU DBM]), | 369 | [use GNU DBM]), |
361 | [ | 370 | [ |
362 | case "${withval}" in | 371 | case "${withval}" in |
363 | yes) use_dbm=GDBM ;; | 372 | yes) enable_dbm="$enable_dbm GDBM";; |
364 | no) use_dbm=no ;; | 373 | no) disable_dbm="$disable_dbm GDBM";; |
365 | *) AC_MSG_ERROR(bad value ${withval} for --with-gdbm) ;; | 374 | *) AC_MSG_ERROR(bad value ${withval} for --with-gdbm) ;; |
366 | esac]) | 375 | esac]) |
367 | 376 | ||
368 | ## Support --with-db2 for backward compatibility | 377 | ## Support --with-db2 for backward compatibility |
369 | if test "${with_db2+set}" = set; then | 378 | if test "${with_db2+set}" = set; then |
370 | case "${with_db2}" in | 379 | case "${with_db2}" in |
371 | yes) use_dbm=BDB2 ;; | 380 | yes) enable_dbm="$enable_dbm BDB2";; |
372 | no) use_dbm=no ;; | 381 | no) disable_dbm="$disable_dbm BDB2";; |
373 | *) AC_MSG_ERROR(bad value ${with_db2} for --with-db2) ;; | 382 | *) AC_MSG_ERROR(bad value ${with_db2} for --with-db2) ;; |
374 | esac | 383 | esac |
375 | fi | 384 | fi |
... | @@ -379,9 +388,9 @@ AC_ARG_WITH([berkeley-db], | ... | @@ -379,9 +388,9 @@ AC_ARG_WITH([berkeley-db], |
379 | [use Berkeley DB]), | 388 | [use Berkeley DB]), |
380 | [ | 389 | [ |
381 | case "${withval}" in | 390 | case "${withval}" in |
382 | yes) use_dbm=BDB ;; | 391 | yes) enable_dbm="$enable_dbm BDB";; |
383 | no) use_dbm=no ;; | 392 | no) disable_dbm="$disable_dbm BDB";; |
384 | *) use_dbm=BDB="${withval}";; | 393 | *) enable_dbm="$enable_dbm BDB=${withval}";; |
385 | esac]) | 394 | esac]) |
386 | 395 | ||
387 | AC_ARG_WITH([ndbm], | 396 | AC_ARG_WITH([ndbm], |
... | @@ -389,8 +398,8 @@ AC_ARG_WITH([ndbm], | ... | @@ -389,8 +398,8 @@ AC_ARG_WITH([ndbm], |
389 | [use NDBM]), | 398 | [use NDBM]), |
390 | [ | 399 | [ |
391 | case "${withval}" in | 400 | case "${withval}" in |
392 | yes) use_dbm=NDBM ;; | 401 | yes) enable_dbm="$enable_dbm NDBM";; |
393 | no) use_dbm=no ;; | 402 | no) disable_dbm="$disable_dbm NDBM";; |
394 | *) AC_MSG_ERROR(bad value ${withval} for --with-ndbm) ;; | 403 | *) AC_MSG_ERROR(bad value ${withval} for --with-ndbm) ;; |
395 | esac]) | 404 | esac]) |
396 | 405 | ||
... | @@ -399,11 +408,174 @@ AC_ARG_WITH([tokyocabinet], | ... | @@ -399,11 +408,174 @@ AC_ARG_WITH([tokyocabinet], |
399 | [use Tokyo Cabinet]), | 408 | [use Tokyo Cabinet]), |
400 | [ | 409 | [ |
401 | case "${withval}" in | 410 | case "${withval}" in |
402 | yes) use_dbm=TC ;; | 411 | yes) enable_dbm="$enable_dbm TC";; |
403 | no) use_dbm=no ;; | 412 | no) disable_dbm="$disable_dbm TC";; |
404 | *) AC_MSG_ERROR(bad value ${withval} for --with-tokyocabinet) ;; | 413 | *) AC_MSG_ERROR(bad value ${withval} for --with-tokyocabinet) ;; |
405 | esac]) | 414 | esac]) |
406 | 415 | ||
416 | dnl Check for DBM | ||
417 | |||
418 | AH_TEMPLATE([WITH_BDB], | ||
419 | [Define to the major version of Berkeley DB library to use]) | ||
420 | |||
421 | status_bdb=no | ||
422 | |||
423 | ## Set the variable status_bdb to $1 if: | ||
424 | ## | ||
425 | ## 1. Function $3 is defined in the library $2 | ||
426 | ## 2. Header file db.h is available | ||
427 | ## | ||
428 | ## Then check if the major version, minor version and patchlevel of the | ||
429 | ## library matches those from the header. If so, define WITH_BDB | ||
430 | ## to the version (i.e. $1 with all dots removed). Otherwise, report | ||
431 | ## an error and stop. | ||
432 | ## | ||
433 | check_bdb() { | ||
434 | ver=`echo $1 | tr -d '.'` | ||
435 | major=`expr $ver : '\(.\).*'` | ||
436 | status_bdb=no | ||
437 | AC_CHECK_LIB($2, $3, | ||
438 | [AC_CHECK_HEADERS(db.h) | ||
439 | if test $ac_cv_header_db_h = yes; then | ||
440 | DBMLIBS="$DBMLIBS -l$2" | ||
441 | MU_DB2_CURSOR | ||
442 | status_bdb="$1" | ||
443 | fi]) | ||
444 | if test "$status_bdb" = no; then | ||
445 | : | ||
446 | else | ||
447 | save_LIBS=$LIBS | ||
448 | LIBS="$LIBS $DBMLIBS" | ||
449 | AC_RUN_IFELSE( | ||
450 | [AC_LANG_PROGRAM([#include "db.h"], | ||
451 | [int v_major, v_minor, v_patch; | ||
452 | db_version(&v_major, &v_minor, &v_patch); | ||
453 | return !(DB_VERSION_MAJOR == $major | ||
454 | && v_major == DB_VERSION_MAJOR | ||
455 | && v_minor == DB_VERSION_MINOR | ||
456 | && v_patch == DB_VERSION_PATCH); | ||
457 | ])], | ||
458 | [], | ||
459 | [status_bdb=no]) | ||
460 | LIBS=$save_LIBS | ||
461 | if test "$status_bdb" != no; then | ||
462 | AC_DEFINE_UNQUOTED(WITH_BDB,$ver) | ||
463 | fi | ||
464 | fi | ||
465 | } | ||
466 | |||
467 | ## Check for the Berkeley DB library version $1, assuming Slackware-like | ||
468 | ## installation layout (header files in /usr/incude/db$vn and library named | ||
469 | ## libdb-$version.so, where $version is the library version and $vn is | ||
470 | ## $version with all dots removed. | ||
471 | ## | ||
472 | check_slackware_bdb() { | ||
473 | dir=db`echo $1|tr -d '.'` | ||
474 | save_CPPFLAGS=$CPPFLAGS | ||
475 | CPPFLAGS="$CPPFLAGS -I/usr/include/$dir" | ||
476 | check_bdb "$1" db-$1 db_create | ||
477 | CPPFLAGS=$save_CPPFLAGS | ||
478 | if test "$status_bdb" = "$1"; then | ||
479 | DBMINCLUDES="$DBMINCLUDES -I/usr/include/$dir" | ||
480 | status_dbm="$status_dbm,Berkeley DB v. $status_bdb" | ||
481 | fi | ||
482 | } | ||
483 | |||
484 | check_dbm_impl() { | ||
485 | case "$1" in | ||
486 | GDBM) | ||
487 | AC_CHECK_LIB(gdbm, gdbm_open, | ||
488 | [AC_CHECK_HEADERS(gdbm.h, | ||
489 | AC_DEFINE(WITH_GDBM,1, | ||
490 | [Enable use of GNU DBM library])) | ||
491 | DBMLIBS="$DBMLIBS -lgdbm" | ||
492 | status_dbm="$status_dbm,GDBM"]);; | ||
493 | |||
494 | BDB2) check_bdb 2 db db_open | ||
495 | test -n "$status_bdb" && status_dbm="$status_dbm,Berkeley DB v. $status_bdb";; | ||
496 | |||
497 | BDB) for version in 4 3 2 | ||
498 | do | ||
499 | case $version in | ||
500 | 4|3) func=db_create;; | ||
501 | 2) func=db_open;; | ||
502 | esac | ||
503 | check_bdb $version db $func | ||
504 | if test "$status_bdb" != no; then | ||
505 | status_dbm="$status_dbm,Berkeley DB v. $status_bdb" | ||
506 | break; | ||
507 | fi | ||
508 | done;; | ||
509 | |||
510 | BDB=*) | ||
511 | name=`expr $use_dbm : 'BDB=\(.*\)'` | ||
512 | case $name in | ||
513 | [[0-9]]*) check_slackware_bdb $name;; | ||
514 | *) for version in 4 3 2 | ||
515 | do | ||
516 | case $version in | ||
517 | 4|3) func=db_create;; | ||
518 | 2) func=db_open;; | ||
519 | esac | ||
520 | check_bdb $version $name $func | ||
521 | if test "$status_bdb" != no; then | ||
522 | status_dbm="$status_dbm,Berkeley DB v. $status_bdb" | ||
523 | break; | ||
524 | fi | ||
525 | done | ||
526 | ;; | ||
527 | esac | ||
528 | ;; | ||
529 | |||
530 | NDBM) | ||
531 | has_ndbm=no | ||
532 | AC_CHECK_HEADERS(ndbm.h,[has_ndbm=yes]) | ||
533 | if test $has_ndbm = yes; then | ||
534 | AC_CHECK_FUNC(dbm_open,:,[has_ndbm=no]) | ||
535 | if test $has_ndbm = no; then | ||
536 | AC_CHECK_LIB(ndbm, dbm_open, | ||
537 | [DBMLIBS="$DBMLIBS -lndbm"]) | ||
538 | fi | ||
539 | fi | ||
540 | if test $has_ndbm = yes; then | ||
541 | AC_DEFINE(WITH_NDBM,1,[Enable use of NDBM]) | ||
542 | status_dbm="$status_dbm,NDBM" | ||
543 | fi | ||
544 | ;; | ||
545 | |||
546 | TC) | ||
547 | AC_CHECK_LIB(tokyocabinet, tchdbnew, | ||
548 | [AC_CHECK_HEADERS(tchdb.h, | ||
549 | AC_DEFINE(WITH_TOKYOCABINET,1, | ||
550 | [Enable use of Tokyo Cabinet])) | ||
551 | DBMLIB_DEPENDENCY="$DBMLIB_DEPENDENCY -lz -lbz2 -lrt" | ||
552 | DBMLIBS="$DBMLIBS -ltokyocabinet" | ||
553 | status_dbm="$status_dbm,Tokyo Cabinet"]);; | ||
554 | esac | ||
555 | } | ||
556 | |||
557 | if test "$enable_dbm" = no; then | ||
558 | enable_dbm="GDBM BDB TC NDBM" | ||
559 | fi | ||
560 | |||
561 | for impl in $enable_dbm | ||
562 | do | ||
563 | if echo "$disable_dbm" | grep $impl >/dev/null; then | ||
564 | : # skip it | ||
565 | else | ||
566 | check_dbm_impl $impl | ||
567 | fi | ||
568 | done | ||
569 | |||
570 | if test -z "$status_dbm"; then | ||
571 | status_dbm=no | ||
572 | else | ||
573 | status_dbm=`echo "$status_dbm" | sed 's/^,//'` | ||
574 | AC_DEFINE([ENABLE_DBM], 1, [Define if DBM interface is compiled]) | ||
575 | fi | ||
576 | AM_CONDITIONAL([MU_COND_DBM], [test "$status_dbm" != no]) | ||
577 | |||
578 | #################### | ||
407 | AC_MSG_CHECKING(for log facility) | 579 | AC_MSG_CHECKING(for log facility) |
408 | log_facility="LOG_MAIL" | 580 | log_facility="LOG_MAIL" |
409 | AC_ARG_WITH([log-facility], | 581 | AC_ARG_WITH([log-facility], |
... | @@ -938,129 +1110,6 @@ AH_BOTTOM([ | ... | @@ -938,129 +1110,6 @@ AH_BOTTOM([ |
938 | # define rl_completion_matches completion_matches | 1110 | # define rl_completion_matches completion_matches |
939 | #endif]) | 1111 | #endif]) |
940 | 1112 | ||
941 | dnl Check for DBM | ||
942 | |||
943 | AH_TEMPLATE([WITH_BDB], | ||
944 | [Define to the major version of Berkeley DB library to use]) | ||
945 | |||
946 | ## Set the variable status_dbm to $1 if: | ||
947 | ## | ||
948 | ## 1. Function $3 is defined in the library $2 | ||
949 | ## 2. Header file db.h is available | ||
950 | ## | ||
951 | ## Then check if the major version, minor version and patchlevel of the | ||
952 | ## library matches those from the header. If so, define WITH_BDB | ||
953 | ## to the version (i.e. $1 with all dots removed). Otherwise, report | ||
954 | ## an error and stop. | ||
955 | ## | ||
956 | check_bdb() { | ||
957 | ver=`echo $1 | tr -d '.'` | ||
958 | major=`expr $ver : '\(.\).*'` | ||
959 | AC_CHECK_LIB($2, $3, | ||
960 | [AC_CHECK_HEADERS(db.h) | ||
961 | if test $ac_cv_header_db_h = yes; then | ||
962 | LIBS="$LIBS -l$2" | ||
963 | MU_DB2_CURSOR | ||
964 | status_dbm=$1 | ||
965 | fi]) | ||
966 | if test "$status_dbm" = no; then | ||
967 | : | ||
968 | else | ||
969 | AC_RUN_IFELSE( | ||
970 | [AC_LANG_PROGRAM([#include "db.h"], | ||
971 | [int v_major, v_minor, v_patch; | ||
972 | db_version(&v_major, &v_minor, &v_patch); | ||
973 | return !(DB_VERSION_MAJOR == $major | ||
974 | && v_major == DB_VERSION_MAJOR | ||
975 | && v_minor == DB_VERSION_MINOR | ||
976 | && v_patch == DB_VERSION_PATCH); | ||
977 | ])], | ||
978 | [], | ||
979 | [status_dbm=no]) | ||
980 | if test "$status_dbm" != no; then | ||
981 | AC_DEFINE_UNQUOTED(WITH_BDB,$ver) | ||
982 | fi | ||
983 | fi | ||
984 | } | ||
985 | |||
986 | ## Check for the Berkeley DB library version $1, assuming Slackware-like | ||
987 | ## installation layout (header files in /usr/incude/db$vn and library named | ||
988 | ## libdb-$version.so, where $version is the library version and $vn is | ||
989 | ## $version with all dots removed. | ||
990 | ## | ||
991 | check_slackware_bdb() { | ||
992 | dir=db`echo $1|tr -d '.'` | ||
993 | save_CPPFLAGS=$CPPFLAGS | ||
994 | CPPFLAGS="$CPPFLAGS -I/usr/include/$dir" | ||
995 | check_bdb "$1" db-$1 db_create | ||
996 | CPPFLAGS=$save_CPPFLAGS | ||
997 | if test "$status_dbm" = "$1"; then | ||
998 | MU_COMMON_INCLUDES="$MU_COMMON_INCLUDES -I/usr/include/$dir" | ||
999 | fi | ||
1000 | } | ||
1001 | |||
1002 | case "$use_dbm" in | ||
1003 | GDBM) | ||
1004 | AC_CHECK_LIB(gdbm, gdbm_open, | ||
1005 | [AC_CHECK_HEADERS(gdbm.h, | ||
1006 | AC_DEFINE(WITH_GDBM,1, | ||
1007 | [Enable use of GNU DBM library])) | ||
1008 | LIBS="$LIBS -lgdbm" | ||
1009 | status_dbm="GDBM"]);; | ||
1010 | |||
1011 | BDB2) check_bdb 2 db db_open | ||
1012 | test -n "$status_dbm" && status_dbm="Berkeley DB v. $status_dbm";; | ||
1013 | |||
1014 | BDB) for version in 4 3 2 | ||
1015 | do | ||
1016 | case $version in | ||
1017 | 4|3) func=db_create;; | ||
1018 | 2) func=db_open;; | ||
1019 | esac | ||
1020 | check_bdb $version db $func | ||
1021 | if test "$status_dbm" != no; then | ||
1022 | status_dbm="Berkeley DB v. $status_dbm" | ||
1023 | break; | ||
1024 | fi | ||
1025 | done;; | ||
1026 | |||
1027 | BDB=*) | ||
1028 | name=`expr $use_dbm : 'BDB=\(.*\)'` | ||
1029 | case $name in | ||
1030 | [[0-9]]*) check_slackware_bdb $name;; | ||
1031 | *) for version in 4 3 2 | ||
1032 | do | ||
1033 | case $version in | ||
1034 | 4|3) func=db_create;; | ||
1035 | 2) func=db_open;; | ||
1036 | esac | ||
1037 | check_bdb $version $name $func | ||
1038 | if test "$status_dbm" != no; then | ||
1039 | status_dbm="Berkeley DB v. $status_dbm" | ||
1040 | break; | ||
1041 | fi | ||
1042 | done | ||
1043 | ;; | ||
1044 | esac | ||
1045 | ;; | ||
1046 | |||
1047 | NDBM) | ||
1048 | AC_CHECK_LIB(ndbm, dbm_open, | ||
1049 | [AC_CHECK_HEADERS(ndbm.h, | ||
1050 | AC_DEFINE(WITH_NDBM,1, | ||
1051 | [Enable use of NDBM])) | ||
1052 | LIBS="$LIBS -lndbm" | ||
1053 | status_dbm="NDBM"]);; | ||
1054 | |||
1055 | TC) | ||
1056 | AC_CHECK_LIB(tokyocabinet, tchdbnew, | ||
1057 | [AC_CHECK_HEADERS(tchdb.h, | ||
1058 | AC_DEFINE(WITH_TOKYOCABINET,1, | ||
1059 | [Enable use of Tokyo Cabinet])) | ||
1060 | LIBS="$LIBS -ltokyocabinet -lz -lbz2 -lrt" | ||
1061 | status_dbm="Tokyo Cabinet"]);; | ||
1062 | esac | ||
1063 | |||
1064 | AC_SUBST(POPAUTH) | 1113 | AC_SUBST(POPAUTH) |
1065 | if test "$status_dbm" != no; then | 1114 | if test "$status_dbm" != no; then |
1066 | POPAUTH='popauth$(EXEEXT)' | 1115 | POPAUTH='popauth$(EXEEXT)' |
... | @@ -1397,6 +1446,7 @@ AC_CONFIG_FILES([ | ... | @@ -1397,6 +1446,7 @@ AC_CONFIG_FILES([ |
1397 | libmu_cpp/Makefile | 1446 | libmu_cpp/Makefile |
1398 | libmu_scm/Makefile | 1447 | libmu_scm/Makefile |
1399 | libmu_scm/mailutils/Makefile | 1448 | libmu_scm/mailutils/Makefile |
1449 | libmu_dbm/Makefile | ||
1400 | libmu_sieve/Makefile | 1450 | libmu_sieve/Makefile |
1401 | libmu_sieve/extensions/Makefile | 1451 | libmu_sieve/extensions/Makefile |
1402 | libproto/Makefile | 1452 | libproto/Makefile | ... | ... |
... | @@ -35,6 +35,7 @@ extern "C" { | ... | @@ -35,6 +35,7 @@ extern "C" { |
35 | #define MU_CTYPE_PUNCT 0x100 | 35 | #define MU_CTYPE_PUNCT 0x100 |
36 | #define MU_CTYPE_SPACE 0x200 | 36 | #define MU_CTYPE_SPACE 0x200 |
37 | #define MU_CTYPE_XLETR 0x400 | 37 | #define MU_CTYPE_XLETR 0x400 |
38 | #define MU_CTYPE_ENDLN 0x800 | ||
38 | 39 | ||
39 | #define MU_C_TAB_MAX 128 | 40 | #define MU_C_TAB_MAX 128 |
40 | 41 | ||
... | @@ -56,6 +57,7 @@ extern int mu_c_tab[MU_C_TAB_MAX]; | ... | @@ -56,6 +57,7 @@ extern int mu_c_tab[MU_C_TAB_MAX]; |
56 | #define mu_isalnum(c) mu_c_is_class (c, MU_CTYPE_ALPHA|MU_CTYPE_DIGIT) | 57 | #define mu_isalnum(c) mu_c_is_class (c, MU_CTYPE_ALPHA|MU_CTYPE_DIGIT) |
57 | #define mu_isascii(c) (((unsigned)c) < MU_C_TAB_MAX) | 58 | #define mu_isascii(c) (((unsigned)c) < MU_C_TAB_MAX) |
58 | #define mu_isblank(c) ((c) == ' ' || (c) == '\t') | 59 | #define mu_isblank(c) ((c) == ' ' || (c) == '\t') |
60 | #define mu_isendln(c) mu_c_is_class (c, MU_CTYPE_ENDLN) | ||
59 | 61 | ||
60 | #define mu_tolower(c) \ | 62 | #define mu_tolower(c) \ |
61 | ({ int __c = (c); \ | 63 | ({ int __c = (c); \ | ... | ... |
include/mailutils/dbm.h
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2011 | ||
3 | Free Software Foundation, Inc. | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 3 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General | ||
16 | Public License along with this library. If not, see | ||
17 | <http://www.gnu.org/licenses/>. */ | ||
18 | |||
19 | #ifndef _MAILUTILS_DBM_H | ||
20 | #define _MAILUTILS_DBM_H | ||
21 | |||
22 | #include <mailutils/types.h> | ||
23 | |||
24 | struct mu_dbm_datum | ||
25 | { | ||
26 | char *mu_dptr; /* Data pointer */ | ||
27 | size_t mu_dsize; /* Data size */ | ||
28 | void *mu_data; /* Implementation-dependent data */ | ||
29 | struct mu_dbm_impl *mu_sys; /* Pointer to implementation */ | ||
30 | }; | ||
31 | |||
32 | struct mu_dbm_impl | ||
33 | { | ||
34 | char *_dbm_name; | ||
35 | int (*_dbm_file_safety) (mu_dbm_file_t db, int mode, uid_t owner); | ||
36 | int (*_dbm_get_fd) (mu_dbm_file_t db, int *pag, int *dir); | ||
37 | int (*_dbm_open) (mu_dbm_file_t db, int flags, int mode); | ||
38 | int (*_dbm_close) (mu_dbm_file_t db); | ||
39 | int (*_dbm_fetch) (mu_dbm_file_t db, struct mu_dbm_datum const *key, | ||
40 | struct mu_dbm_datum *ret); | ||
41 | int (*_dbm_store) (mu_dbm_file_t db, struct mu_dbm_datum const *key, | ||
42 | struct mu_dbm_datum const *contents, int replace); | ||
43 | int (*_dbm_delete) (mu_dbm_file_t db, | ||
44 | struct mu_dbm_datum const *key); | ||
45 | int (*_dbm_firstkey) (mu_dbm_file_t db, struct mu_dbm_datum *ret); | ||
46 | int (*_dbm_nextkey) (mu_dbm_file_t db, struct mu_dbm_datum *ret); | ||
47 | void (*_dbm_datum_free) (struct mu_dbm_datum *datum); | ||
48 | char const *(*_dbm_strerror) (mu_dbm_file_t db); | ||
49 | }; | ||
50 | |||
51 | extern mu_url_t mu_dbm_hint; | ||
52 | |||
53 | int mu_dbm_register (struct mu_dbm_impl *impl); | ||
54 | int mu_dbm_create_from_url (mu_url_t url, mu_dbm_file_t *db); | ||
55 | int mu_dbm_create (char *name, mu_dbm_file_t *db); | ||
56 | int mu_dbm_close (mu_dbm_file_t db); | ||
57 | void mu_dbm_datum_free (struct mu_dbm_datum *datum); | ||
58 | int mu_dbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key); | ||
59 | void mu_dbm_destroy (mu_dbm_file_t *pdb); | ||
60 | int mu_dbm_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key, | ||
61 | struct mu_dbm_datum *ret); | ||
62 | int mu_dbm_store (mu_dbm_file_t db, struct mu_dbm_datum const *key, | ||
63 | struct mu_dbm_datum const *contents, int replace); | ||
64 | int mu_dbm_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret); | ||
65 | int mu_dbm_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret); | ||
66 | int mu_dbm_open (mu_dbm_file_t db, int flags, int mode); | ||
67 | int mu_dbm_safety_get_owner (mu_dbm_file_t db, uid_t *uid); | ||
68 | int mu_dbm_safety_get_flags (mu_dbm_file_t db, int *flags); | ||
69 | int mu_dbm_safety_set_owner (mu_dbm_file_t db, uid_t uid); | ||
70 | int mu_dbm_safety_set_flags (mu_dbm_file_t db, int flags); | ||
71 | int mu_dbm_safety_check (mu_dbm_file_t db); | ||
72 | char const *mu_dbm_strerror (mu_dbm_file_t db); | ||
73 | int mu_dbm_get_fd (mu_dbm_file_t db, int *pag, int *dir); | ||
74 | |||
75 | int mu_dbm_impl_iterator (mu_iterator_t *itr); | ||
76 | |||
77 | #endif |
include/mailutils/sys/dbm.h
0 → 100644
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 | #ifndef _MAILUTILS_SYS_DBM_H | ||
19 | # define _MAILUTILS_SYS_DBM_H | ||
20 | |||
21 | union _mu_dbm_errno | ||
22 | { | ||
23 | int n; | ||
24 | void *p; | ||
25 | }; | ||
26 | |||
27 | struct _mu_dbm_file | ||
28 | { | ||
29 | char *db_name; /* Database name */ | ||
30 | void *db_descr; /* Database descriptor */ | ||
31 | int db_safety_flags; /* Safety checks */ | ||
32 | uid_t db_owner; /* Database owner UID */ | ||
33 | struct mu_dbm_impl *db_sys; /* Pointer to the database implementation */ | ||
34 | union _mu_dbm_errno db_errno; | ||
35 | }; | ||
36 | |||
37 | #endif |
... | @@ -75,7 +75,8 @@ struct _mu_assoc; | ... | @@ -75,7 +75,8 @@ struct _mu_assoc; |
75 | struct _mu_acl; | 75 | struct _mu_acl; |
76 | struct _mu_server; | 76 | struct _mu_server; |
77 | struct _mu_tcp_server; | 77 | struct _mu_tcp_server; |
78 | 78 | struct _mu_dbm_file; | |
79 | |||
79 | struct mu_sockaddr; /* defined in mailutils/sockaddr.h */ | 80 | struct mu_sockaddr; /* defined in mailutils/sockaddr.h */ |
80 | struct mu_cidr; /* defined in mailutils/cidr.h */ | 81 | struct mu_cidr; /* defined in mailutils/cidr.h */ |
81 | 82 | ||
... | @@ -121,6 +122,7 @@ typedef struct _mu_opool *mu_opool_t; | ... | @@ -121,6 +122,7 @@ typedef struct _mu_opool *mu_opool_t; |
121 | typedef struct _mu_progmailer *mu_progmailer_t; | 122 | typedef struct _mu_progmailer *mu_progmailer_t; |
122 | typedef struct _mu_secret *mu_secret_t; | 123 | typedef struct _mu_secret *mu_secret_t; |
123 | typedef struct _mu_mime_io_buffer *mu_mime_io_buffer_t; | 124 | typedef struct _mu_mime_io_buffer *mu_mime_io_buffer_t; |
125 | typedef struct _mu_dbm_file *mu_dbm_file_t; | ||
124 | 126 | ||
125 | typedef void (*mu_onexit_t) (void*); | 127 | typedef void (*mu_onexit_t) (void*); |
126 | typedef unsigned int mu_debug_handle_t; | 128 | typedef unsigned int mu_debug_handle_t; | ... | ... |
... | @@ -24,7 +24,6 @@ libmuaux_a_SOURCES += \ | ... | @@ -24,7 +24,6 @@ libmuaux_a_SOURCES += \ |
24 | daemon.c\ | 24 | daemon.c\ |
25 | mailcap.c\ | 25 | mailcap.c\ |
26 | manlock.c\ | 26 | manlock.c\ |
27 | mu_dbm.c\ | ||
28 | signal.c\ | 27 | signal.c\ |
29 | strexit.c\ | 28 | strexit.c\ |
30 | tcpwrap.c\ | 29 | tcpwrap.c\ |
... | @@ -34,7 +33,6 @@ libmuaux_a_SOURCES += \ | ... | @@ -34,7 +33,6 @@ libmuaux_a_SOURCES += \ |
34 | noinst_HEADERS +=\ | 33 | noinst_HEADERS +=\ |
35 | mailcap.h\ | 34 | mailcap.h\ |
36 | muaux.h\ | 35 | muaux.h\ |
37 | mu_dbm.h\ | ||
38 | tcpwrap.h | 36 | tcpwrap.h |
39 | 37 | ||
40 | EXTRA_DIST += utmp.c | 38 | EXTRA_DIST += utmp.c | ... | ... |
lib/mu_dbm.c
deleted
100644 → 0
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2002, 2006, 2007, 2009, 2010, 2011 | ||
3 | Free Software Foundation, Inc. | ||
4 | |||
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 | ||
7 | the Free Software Foundation; either version 3, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | GNU Mailutils is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | |||
22 | #include <stdlib.h> | ||
23 | #include <unistd.h> | ||
24 | #include <fcntl.h> | ||
25 | #include <sys/types.h> | ||
26 | #include <sys/stat.h> | ||
27 | #include <string.h> | ||
28 | #ifdef HAVE_STRINGS_H | ||
29 | # include <strings.h> | ||
30 | #endif | ||
31 | #include <errno.h> | ||
32 | #include <mailutils/errno.h> | ||
33 | #include <mailutils/stream.h> | ||
34 | #include <mu_dbm.h> | ||
35 | #include <xalloc.h> | ||
36 | |||
37 | int | ||
38 | mu_fcheck_perm (int fd, int mode) | ||
39 | { | ||
40 | struct stat st; | ||
41 | |||
42 | if (mode == 0) | ||
43 | return 0; | ||
44 | if (fstat (fd, &st) == -1) | ||
45 | { | ||
46 | if (errno == ENOENT) | ||
47 | return 0; | ||
48 | else | ||
49 | return 1; | ||
50 | } | ||
51 | if ((st.st_mode & 0777) != mode) | ||
52 | { | ||
53 | errno = MU_ERR_UNSAFE_PERMS; | ||
54 | return 1; | ||
55 | } | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | int | ||
60 | mu_check_perm (const char *name, int mode) | ||
61 | { | ||
62 | struct stat st; | ||
63 | |||
64 | if (mode == 0) | ||
65 | return 0; | ||
66 | if (stat (name, &st) == -1) | ||
67 | { | ||
68 | if (errno == ENOENT) | ||
69 | return 0; | ||
70 | else | ||
71 | return 1; | ||
72 | } | ||
73 | if ((st.st_mode & 0777) != mode) | ||
74 | { | ||
75 | errno = MU_ERR_UNSAFE_PERMS; | ||
76 | return 1; | ||
77 | } | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static char * | ||
82 | make_db_name (const char *name, const char *suffix) | ||
83 | { | ||
84 | int nlen = strlen (name); | ||
85 | int slen = strlen (suffix); | ||
86 | char *p; | ||
87 | |||
88 | if (nlen > slen && strcmp (name + nlen - slen, suffix) == 0) | ||
89 | p = xstrdup (name); | ||
90 | else | ||
91 | { | ||
92 | p = xmalloc (strlen (name) + slen + 1); | ||
93 | strcat (strcpy (p, name), suffix); | ||
94 | } | ||
95 | return p; | ||
96 | } | ||
97 | |||
98 | #if defined(WITH_GDBM) | ||
99 | |||
100 | #define DB_SUFFIX ".db" | ||
101 | |||
102 | int | ||
103 | mu_dbm_stat (char *name, struct stat *sb) | ||
104 | { | ||
105 | int rc; | ||
106 | char *pfname = make_db_name (name, DB_SUFFIX); | ||
107 | rc = stat (pfname, sb); | ||
108 | free (pfname); | ||
109 | return rc; | ||
110 | } | ||
111 | |||
112 | int | ||
113 | mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode) | ||
114 | { | ||
115 | int f; | ||
116 | char *pfname = make_db_name (name, DB_SUFFIX); | ||
117 | |||
118 | if (mu_check_perm (pfname, mode)) | ||
119 | { | ||
120 | free (pfname); | ||
121 | return -1; | ||
122 | } | ||
123 | |||
124 | switch (flags) | ||
125 | { | ||
126 | case MU_STREAM_CREAT: | ||
127 | f = GDBM_NEWDB; | ||
128 | break; | ||
129 | |||
130 | case MU_STREAM_READ: | ||
131 | f = GDBM_READER; | ||
132 | break; | ||
133 | |||
134 | case MU_STREAM_RDWR: | ||
135 | f = GDBM_WRCREAT; | ||
136 | break; | ||
137 | |||
138 | default: | ||
139 | free (pfname); | ||
140 | errno = EINVAL; | ||
141 | return 1; | ||
142 | } | ||
143 | *db = gdbm_open (pfname, 512, f, mode, NULL); | ||
144 | free (pfname); | ||
145 | return *db == NULL; | ||
146 | } | ||
147 | |||
148 | int | ||
149 | mu_dbm_close (DBM_FILE db) | ||
150 | { | ||
151 | gdbm_close(db); | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | int | ||
156 | mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) | ||
157 | { | ||
158 | *ret = gdbm_fetch (db, key); | ||
159 | return ret->dptr == NULL; | ||
160 | } | ||
161 | |||
162 | int | ||
163 | mu_dbm_delete (DBM_FILE db, DBM_DATUM key) | ||
164 | { | ||
165 | return gdbm_delete (db, key); | ||
166 | } | ||
167 | |||
168 | int | ||
169 | mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) | ||
170 | { | ||
171 | return gdbm_store (db, key, contents, | ||
172 | replace ? GDBM_REPLACE : GDBM_INSERT); | ||
173 | } | ||
174 | |||
175 | DBM_DATUM | ||
176 | mu_dbm_firstkey (DBM_FILE db) | ||
177 | { | ||
178 | return gdbm_firstkey (db); | ||
179 | } | ||
180 | |||
181 | DBM_DATUM | ||
182 | mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key) | ||
183 | { | ||
184 | return gdbm_nextkey (db, key); | ||
185 | } | ||
186 | |||
187 | void | ||
188 | mu_dbm_datum_free (DBM_DATUM *datum) | ||
189 | { | ||
190 | void *ptr = MU_DATUM_PTR (*datum); | ||
191 | if (ptr) | ||
192 | free (ptr); | ||
193 | MU_DATUM_PTR (*datum) = 0; | ||
194 | } | ||
195 | |||
196 | #elif defined(WITH_BDB) | ||
197 | |||
198 | #define DB_SUFFIX ".db" | ||
199 | |||
200 | int | ||
201 | mu_dbm_stat (char *name, struct stat *sb) | ||
202 | { | ||
203 | int rc; | ||
204 | char *pfname = make_db_name (name, DB_SUFFIX); | ||
205 | rc = stat (pfname, sb); | ||
206 | free (pfname); | ||
207 | return rc; | ||
208 | } | ||
209 | |||
210 | int | ||
211 | mu_dbm_open (char *name, DBM_FILE *dbm, int flags, int mode) | ||
212 | { | ||
213 | int f, rc; | ||
214 | DB *db; | ||
215 | char *pfname = make_db_name (name, DB_SUFFIX); | ||
216 | |||
217 | if (mu_check_perm (pfname, mode)) | ||
218 | { | ||
219 | free (pfname); | ||
220 | errno = MU_ERR_UNSAFE_PERMS; | ||
221 | return -1; | ||
222 | } | ||
223 | |||
224 | switch (flags) | ||
225 | { | ||
226 | case MU_STREAM_CREAT: | ||
227 | f = DB_CREATE|DB_TRUNCATE; | ||
228 | break; | ||
229 | |||
230 | case MU_STREAM_READ: | ||
231 | f = DB_RDONLY; | ||
232 | break; | ||
233 | |||
234 | case MU_STREAM_RDWR: | ||
235 | f = DB_CREATE; | ||
236 | break; | ||
237 | |||
238 | default: | ||
239 | free (pfname); | ||
240 | errno = EINVAL; | ||
241 | return -1; | ||
242 | } | ||
243 | |||
244 | #if WITH_BDB == 2 | ||
245 | rc = db_open (pfname, DB_HASH, f, mode, NULL, NULL, &db); | ||
246 | #else | ||
247 | rc = db_create (&db, NULL, 0); | ||
248 | if (rc != 0 || db == NULL) | ||
249 | return rc; | ||
250 | # if DB_VERSION_MAJOR == 3 | ||
251 | rc = db->open (db, pfname, NULL, DB_HASH, f, mode); | ||
252 | # else | ||
253 | rc = db->open (db, NULL, pfname, NULL, DB_HASH, f, mode); | ||
254 | # endif | ||
255 | #endif | ||
256 | |||
257 | free (pfname); | ||
258 | if (rc) | ||
259 | return -1; | ||
260 | |||
261 | *dbm = malloc (sizeof **dbm); | ||
262 | if (!*dbm) | ||
263 | { | ||
264 | db->close (db, 0); | ||
265 | errno = ENOMEM; | ||
266 | return -1; | ||
267 | } | ||
268 | (*dbm)->db = db; | ||
269 | (*dbm)->dbc = NULL; | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | int | ||
274 | mu_dbm_close (DBM_FILE db) | ||
275 | { | ||
276 | db->db->close (db->db, 0); | ||
277 | free (db); | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | int | ||
282 | mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) | ||
283 | { | ||
284 | return db->db->get (db->db, NULL, &key, ret, 0); | ||
285 | } | ||
286 | |||
287 | int | ||
288 | mu_dbm_delete (DBM_FILE db, DBM_DATUM key) | ||
289 | { | ||
290 | return db->db->del (db->db, NULL, &key, 0); | ||
291 | } | ||
292 | |||
293 | int | ||
294 | mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) | ||
295 | { | ||
296 | /*FIXME: replace unused*/ | ||
297 | return db->db->put (db->db, NULL, &key, &contents, 0); | ||
298 | } | ||
299 | |||
300 | DBM_DATUM | ||
301 | mu_dbm_firstkey (DBM_FILE db) | ||
302 | { | ||
303 | DBT key, data; | ||
304 | int ret; | ||
305 | |||
306 | memset (&key, 0, sizeof key); | ||
307 | memset (&data, 0, sizeof data); | ||
308 | |||
309 | if (!db->dbc) | ||
310 | { | ||
311 | if (db->db->cursor (db->db, NULL, &db->dbc BDB2_CURSOR_LASTARG) != 0) | ||
312 | return key; | ||
313 | } | ||
314 | |||
315 | if ((ret = db->dbc->c_get (db->dbc, &key, &data, DB_FIRST)) != 0) | ||
316 | { | ||
317 | key.data = NULL; | ||
318 | key.size = 0; | ||
319 | if (ret == DB_NOTFOUND) | ||
320 | errno = MU_ERR_NOENT; | ||
321 | else | ||
322 | errno = ret; | ||
323 | } | ||
324 | return key; | ||
325 | } | ||
326 | |||
327 | DBM_DATUM | ||
328 | mu_dbm_nextkey (DBM_FILE db, DBM_DATUM pkey /*unused*/) | ||
329 | { | ||
330 | DBT key, data; | ||
331 | int ret; | ||
332 | |||
333 | memset (&key, 0, sizeof key); | ||
334 | memset (&data, 0, sizeof data); | ||
335 | |||
336 | if (!db->dbc) | ||
337 | return key; | ||
338 | |||
339 | if ((ret = db->dbc->c_get (db->dbc, &key, &data, DB_NEXT)) != 0) | ||
340 | { | ||
341 | key.data = NULL; | ||
342 | key.size = 0; | ||
343 | if (ret == DB_NOTFOUND) | ||
344 | errno = MU_ERR_NOENT; | ||
345 | else | ||
346 | errno = ret; | ||
347 | } | ||
348 | return key; | ||
349 | } | ||
350 | |||
351 | void | ||
352 | mu_dbm_datum_free (DBM_DATUM *datum) | ||
353 | { | ||
354 | /* empty */ | ||
355 | } | ||
356 | |||
357 | #elif defined(WITH_NDBM) | ||
358 | |||
359 | #define DB_SUFFIX ".pag" | ||
360 | |||
361 | int | ||
362 | mu_dbm_stat (char *name, struct stat *sb) | ||
363 | { | ||
364 | int rc; | ||
365 | char *pfname = make_db_name (name, DB_SUFFIX); | ||
366 | rc = stat (pfname, sb); | ||
367 | free (pfname); | ||
368 | return rc; | ||
369 | } | ||
370 | |||
371 | int | ||
372 | mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode) | ||
373 | { | ||
374 | int f; | ||
375 | char *pfname; | ||
376 | |||
377 | switch (flags) | ||
378 | { | ||
379 | case MU_STREAM_CREAT: | ||
380 | f = O_CREAT|O_TRUNC|O_RDWR; | ||
381 | break; | ||
382 | |||
383 | case MU_STREAM_READ: | ||
384 | f = O_RDONLY; | ||
385 | break; | ||
386 | |||
387 | case MU_STREAM_RDWR: | ||
388 | f = O_CREAT|O_RDWR; | ||
389 | break; | ||
390 | |||
391 | default: | ||
392 | errno = EINVAL; | ||
393 | return -1; | ||
394 | } | ||
395 | pfname = strip_suffix (name, DB_SUFFIX); | ||
396 | *db = dbm_open (pfname, f, mode); | ||
397 | free (pfname); | ||
398 | if (!*db) | ||
399 | return -1; | ||
400 | |||
401 | if (mu_fcheck_perm (dbm_dirfno (*db), mode) | ||
402 | || mu_fcheck_perm (dbm_pagfno (*db), mode)) | ||
403 | { | ||
404 | dbm_close (*db); | ||
405 | return 1; | ||
406 | } | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | int | ||
412 | mu_dbm_close (DBM_FILE db) | ||
413 | { | ||
414 | dbm_close (db); | ||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | int | ||
419 | mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) | ||
420 | { | ||
421 | *ret = dbm_fetch (db, key); | ||
422 | return ret->dptr == NULL; | ||
423 | } | ||
424 | |||
425 | int | ||
426 | mu_dbm_delete (DBM_FILE db, DBM_DATUM key) | ||
427 | { | ||
428 | return dbm_delete (db, key); | ||
429 | } | ||
430 | |||
431 | int | ||
432 | mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) | ||
433 | { | ||
434 | return dbm_store (db, key, contents, replace ? DBM_REPLACE : DBM_INSERT); | ||
435 | } | ||
436 | |||
437 | DBM_DATUM | ||
438 | mu_dbm_firstkey (DBM_FILE db) | ||
439 | { | ||
440 | return dbm_firstkey (db); | ||
441 | } | ||
442 | |||
443 | DBM_DATUM | ||
444 | mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key) | ||
445 | { | ||
446 | return dbm_nextkey (db, key); | ||
447 | } | ||
448 | |||
449 | void | ||
450 | mu_dbm_datum_free (DBM_DATUM *datum) | ||
451 | { | ||
452 | /* empty */ | ||
453 | } | ||
454 | |||
455 | #elif defined(WITH_TOKYOCABINET) | ||
456 | |||
457 | #define DB_SUFFIX ".tch" | ||
458 | |||
459 | int | ||
460 | mu_dbm_stat (char *name, struct stat *sb) | ||
461 | { | ||
462 | int rc; | ||
463 | char *pfname = make_db_name (name, DB_SUFFIX); | ||
464 | rc = stat (pfname, sb); | ||
465 | free (pfname); | ||
466 | return rc; | ||
467 | } | ||
468 | |||
469 | int | ||
470 | mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode) | ||
471 | { | ||
472 | int f, ecode; | ||
473 | char *pfname = make_db_name (name, DB_SUFFIX); | ||
474 | |||
475 | if (mu_check_perm (pfname, mode)) | ||
476 | { | ||
477 | free (pfname); | ||
478 | return -1; | ||
479 | } | ||
480 | |||
481 | switch (flags) | ||
482 | { | ||
483 | case MU_STREAM_CREAT: | ||
484 | f = HDBOWRITER | HDBOCREAT; | ||
485 | break; | ||
486 | |||
487 | case MU_STREAM_READ: | ||
488 | f = HDBOREADER; | ||
489 | break; | ||
490 | |||
491 | case MU_STREAM_RDWR: | ||
492 | f = HDBOREADER | HDBOWRITER; | ||
493 | break; | ||
494 | |||
495 | default: | ||
496 | free (pfname); | ||
497 | errno = EINVAL; | ||
498 | return 1; | ||
499 | } | ||
500 | |||
501 | *db = malloc (sizeof **db); | ||
502 | if (!*db) | ||
503 | { | ||
504 | errno = ENOMEM; | ||
505 | return -1; | ||
506 | } | ||
507 | (*db)->hdb = tchdbnew (); | ||
508 | |||
509 | if (!tchdbopen ((*db)->hdb, pfname, f)) | ||
510 | ecode = tchdbecode ((*db)->hdb); | ||
511 | |||
512 | free (pfname); | ||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | int | ||
517 | mu_dbm_close (DBM_FILE db) | ||
518 | { | ||
519 | tchdbclose (db->hdb); | ||
520 | tchdbdel (db->hdb); | ||
521 | return 0; | ||
522 | } | ||
523 | |||
524 | int | ||
525 | mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret) | ||
526 | { | ||
527 | ret->data = tchdbget (db->hdb, key.data, key.size, &ret->size); | ||
528 | return ret->data == NULL; | ||
529 | } | ||
530 | |||
531 | int | ||
532 | mu_dbm_delete (DBM_FILE db, DBM_DATUM key) | ||
533 | { | ||
534 | return !tchdbout (db->hdb, key.data, key.size); | ||
535 | } | ||
536 | |||
537 | int | ||
538 | mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace) | ||
539 | { | ||
540 | if (replace) | ||
541 | return !tchdbput (db->hdb, key.data, key.size, contents.data, contents.size); | ||
542 | else | ||
543 | return !tchdbputkeep (db->hdb, key.data, key.size, | ||
544 | contents.data, contents.size); | ||
545 | } | ||
546 | |||
547 | DBM_DATUM | ||
548 | mu_dbm_firstkey (DBM_FILE db) | ||
549 | { | ||
550 | DBM_DATUM key; | ||
551 | memset (&key, 0, sizeof key); | ||
552 | |||
553 | tchdbiterinit (db->hdb); | ||
554 | key.data = tchdbiternext (db->hdb, &key.size); | ||
555 | return key; | ||
556 | } | ||
557 | |||
558 | DBM_DATUM | ||
559 | mu_dbm_nextkey (DBM_FILE db, DBM_DATUM unused) | ||
560 | { | ||
561 | DBM_DATUM key; | ||
562 | memset (&key, 0, sizeof key); | ||
563 | |||
564 | key.data = tchdbiternext (db->hdb, &key.size); | ||
565 | return key; | ||
566 | } | ||
567 | |||
568 | void | ||
569 | mu_dbm_datum_free (DBM_DATUM *datum) | ||
570 | { | ||
571 | /* empty */ | ||
572 | } | ||
573 | |||
574 | #endif | ||
575 |
lib/mu_dbm.h
deleted
100644 → 0
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2002, 2005, 2007, 2009, 2010, 2011 | ||
3 | Free Software Foundation, Inc. | ||
4 | |||
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 | ||
7 | the Free Software Foundation; either version 3, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | GNU Mailutils is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #if defined(WITH_GDBM) | ||
19 | |||
20 | #include <gdbm.h> | ||
21 | #define USE_DBM | ||
22 | typedef GDBM_FILE DBM_FILE; | ||
23 | typedef datum DBM_DATUM; | ||
24 | #define MU_DATUM_SIZE(d) (d).dsize | ||
25 | #define MU_DATUM_PTR(d) (d).dptr | ||
26 | |||
27 | #elif defined(WITH_BDB) | ||
28 | |||
29 | #include <db.h> | ||
30 | #define USE_DBM | ||
31 | |||
32 | struct db2_file | ||
33 | { | ||
34 | DB *db; | ||
35 | DBC *dbc; | ||
36 | }; | ||
37 | |||
38 | typedef struct db2_file *DBM_FILE; | ||
39 | typedef DBT DBM_DATUM; | ||
40 | #define MU_DATUM_SIZE(d) (d).size | ||
41 | #define MU_DATUM_PTR(d) (d).data | ||
42 | |||
43 | #elif defined(WITH_NDBM) | ||
44 | |||
45 | #include <ndbm.h> | ||
46 | #define USE_DBM | ||
47 | typedef DBM *DBM_FILE; | ||
48 | typedef datum DBM_DATUM; | ||
49 | #define MU_DATUM_SIZE(d) (d).dsize | ||
50 | #define MU_DATUM_PTR(d) (d).dptr | ||
51 | |||
52 | #elif defined(WITH_TOKYOCABINET) | ||
53 | |||
54 | #include <tcutil.h> | ||
55 | #include <tchdb.h> | ||
56 | #define USE_DBM | ||
57 | |||
58 | struct tokyocabinet_file | ||
59 | { | ||
60 | TCHDB *hdb; | ||
61 | }; | ||
62 | |||
63 | struct tokyocabinet_datum { | ||
64 | void *data; | ||
65 | int size; | ||
66 | }; | ||
67 | |||
68 | typedef struct tokyocabinet_file *DBM_FILE; | ||
69 | typedef struct tokyocabinet_datum DBM_DATUM; | ||
70 | #define MU_DATUM_SIZE(d) (d).size | ||
71 | #define MU_DATUM_PTR(d) (d).data | ||
72 | |||
73 | #endif | ||
74 | |||
75 | #ifdef USE_DBM | ||
76 | struct stat; | ||
77 | int mu_dbm_stat (char *name, struct stat *sb); | ||
78 | int mu_dbm_open (char *name, DBM_FILE *db, int flags, int mode); | ||
79 | int mu_dbm_close (DBM_FILE db); | ||
80 | int mu_dbm_fetch (DBM_FILE db, DBM_DATUM key, DBM_DATUM *ret); | ||
81 | int mu_dbm_insert (DBM_FILE db, DBM_DATUM key, DBM_DATUM contents, int replace); | ||
82 | int mu_dbm_delete (DBM_FILE db, DBM_DATUM key); | ||
83 | DBM_DATUM mu_dbm_firstkey (DBM_FILE db); | ||
84 | DBM_DATUM mu_dbm_nextkey (DBM_FILE db, DBM_DATUM key); | ||
85 | void mu_dbm_datum_free(DBM_DATUM *datum); | ||
86 | #endif /* USE_DBM */ | ||
87 | |||
88 | int mu_fcheck_perm (int fd, int mode); | ||
89 | int mu_check_perm (const char *name, int mode); |
... | @@ -31,10 +31,10 @@ int mu_c_tab[MU_C_TAB_MAX] = { | ... | @@ -31,10 +31,10 @@ int mu_c_tab[MU_C_TAB_MAX] = { |
31 | MU_CTYPE_CNTRL, | 31 | MU_CTYPE_CNTRL, |
32 | MU_CTYPE_CNTRL, | 32 | MU_CTYPE_CNTRL, |
33 | MU_CTYPE_CNTRL|MU_CTYPE_SPACE, | 33 | MU_CTYPE_CNTRL|MU_CTYPE_SPACE, |
34 | MU_CTYPE_CNTRL|MU_CTYPE_SPACE|MU_CTYPE_ENDLN, | ||
34 | MU_CTYPE_CNTRL|MU_CTYPE_SPACE, | 35 | MU_CTYPE_CNTRL|MU_CTYPE_SPACE, |
35 | MU_CTYPE_CNTRL|MU_CTYPE_SPACE, | 36 | MU_CTYPE_CNTRL|MU_CTYPE_SPACE, |
36 | MU_CTYPE_CNTRL|MU_CTYPE_SPACE, | 37 | MU_CTYPE_CNTRL|MU_CTYPE_SPACE|MU_CTYPE_ENDLN, |
37 | MU_CTYPE_CNTRL|MU_CTYPE_SPACE, | ||
38 | MU_CTYPE_CNTRL, | 38 | MU_CTYPE_CNTRL, |
39 | MU_CTYPE_CNTRL, | 39 | MU_CTYPE_CNTRL, |
40 | MU_CTYPE_CNTRL, | 40 | MU_CTYPE_CNTRL, | ... | ... |
libmu_dbm/Makefile.am
0 → 100644
1 | ## This file is part of GNU Mailutils. | ||
2 | ## Copyright (C) 2011 Free Software Foundation, Inc. | ||
3 | ## | ||
4 | ## GNU Mailutils is free software; you can redistribute it and/or | ||
5 | ## modify it under the terms of the GNU General Public License as | ||
6 | ## published by the Free Software Foundation; either version 3, or (at | ||
7 | ## your option) any later version. | ||
8 | ## | ||
9 | ## GNU Mailutils is distributed in the hope that it will be useful, but | ||
10 | ## WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | ## General Public License for more details. | ||
13 | ## | ||
14 | ## You should have received a copy of the GNU General Public License | ||
15 | ## along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | INCLUDES = @MU_LIB_COMMON_INCLUDES@ @DBMINCLUDES@ | ||
18 | |||
19 | lib_LTLIBRARIES = libmu_dbm.la | ||
20 | |||
21 | libmu_dbm_la_SOURCES = \ | ||
22 | close.c\ | ||
23 | create.c\ | ||
24 | datumfree.c\ | ||
25 | dbm.c\ | ||
26 | delete.c\ | ||
27 | destroy.c\ | ||
28 | errstr.c\ | ||
29 | fetch.c\ | ||
30 | firstkey.c\ | ||
31 | getfd.c\ | ||
32 | nextkey.c\ | ||
33 | open.c\ | ||
34 | safety.c\ | ||
35 | store.c\ | ||
36 | berkeley.c\ | ||
37 | gdbm.c\ | ||
38 | ndbm.c | ||
39 | |||
40 | noinst_HEADERS = mudbm.h | ||
41 | |||
42 | libmu_dbm_la_LIBADD = ${MU_LIB_MAILUTILS} @MU_AUTHLIBS@ @DBMLIBS@ @LTLIBINTL@ | ||
43 | libmu_dbm_la_LDFLAGS = -version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@ | ||
44 | libmu_dbm_la_DEPENDENCIES = @DBMLIB_DEPENDENCY@ |
libmu_dbm/berkeley.c
0 → 100644
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 <stdlib.h> | ||
22 | #include <string.h> | ||
23 | #include <mailutils/types.h> | ||
24 | #include <mailutils/dbm.h> | ||
25 | #include <mailutils/util.h> | ||
26 | #include <mailutils/errno.h> | ||
27 | #include <mailutils/error.h> | ||
28 | #include <mailutils/stream.h> | ||
29 | #include "mudbm.h" | ||
30 | |||
31 | #if defined(WITH_BDB) | ||
32 | #include <db.h> | ||
33 | |||
34 | struct bdb_file | ||
35 | { | ||
36 | DB *db; | ||
37 | DBC *dbc; | ||
38 | }; | ||
39 | |||
40 | static int | ||
41 | _bdb_file_safety (mu_dbm_file_t db, int mode, uid_t owner) | ||
42 | { | ||
43 | return mu_file_safety_check (db->db_name, mode, owner, NULL); | ||
44 | } | ||
45 | |||
46 | static int | ||
47 | _bdb_get_fd (mu_dbm_file_t db, int *pag, int *dir) | ||
48 | { | ||
49 | struct bdb_file *bdb_file = db->db_descr; | ||
50 | int rc = bdb_file->db->fd (bdb_file->db, pag); | ||
51 | if (rc) | ||
52 | { | ||
53 | db->db_errno.n = rc; | ||
54 | return MU_ERR_FAILURE; | ||
55 | } | ||
56 | if (dir) | ||
57 | *dir = *pag; | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int | ||
62 | _bdb_open (mu_dbm_file_t mdb, int flags, int mode) | ||
63 | { | ||
64 | struct bdb_file *bdb_file; | ||
65 | int f, rc; | ||
66 | DB *db; | ||
67 | |||
68 | switch (flags) | ||
69 | { | ||
70 | case MU_STREAM_CREAT: | ||
71 | f = DB_CREATE|DB_TRUNCATE; | ||
72 | break; | ||
73 | |||
74 | case MU_STREAM_READ: | ||
75 | f = DB_RDONLY; | ||
76 | break; | ||
77 | |||
78 | case MU_STREAM_RDWR: | ||
79 | f = DB_CREATE; | ||
80 | break; | ||
81 | |||
82 | default: | ||
83 | return EINVAL; | ||
84 | } | ||
85 | |||
86 | #if WITH_BDB == 2 | ||
87 | rc = db_open (db->db_name, DB_HASH, f, mode, NULL, NULL, &db); | ||
88 | #else | ||
89 | rc = db_create (&db, NULL, 0); | ||
90 | if (rc != 0 || db == NULL) | ||
91 | return MU_ERR_FAILURE; | ||
92 | # if DB_VERSION_MAJOR == 3 | ||
93 | rc = db->open (db, mdb->db_name, NULL, DB_HASH, f, mode); | ||
94 | # else | ||
95 | rc = db->open (db, NULL, mdb->db_name, NULL, DB_HASH, f, mode); | ||
96 | # endif | ||
97 | #endif | ||
98 | |||
99 | if (rc) | ||
100 | return MU_ERR_FAILURE; | ||
101 | |||
102 | bdb_file = malloc (sizeof *bdb_file); | ||
103 | if (!bdb_file) | ||
104 | { | ||
105 | db->close (db, 0); | ||
106 | return ENOMEM; | ||
107 | } | ||
108 | bdb_file->db = db; | ||
109 | bdb_file->dbc = NULL; | ||
110 | |||
111 | mdb->db_descr = bdb_file; | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int | ||
117 | _bdb_close (mu_dbm_file_t db) | ||
118 | { | ||
119 | if (db->db_descr) | ||
120 | { | ||
121 | struct bdb_file *bdb_file = db->db_descr; | ||
122 | bdb_file->db->close (bdb_file->db, 0); | ||
123 | free (bdb_file); | ||
124 | db->db_descr = NULL; | ||
125 | } | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int | ||
130 | _bdb_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key, | ||
131 | struct mu_dbm_datum *ret) | ||
132 | { | ||
133 | DBT keydat, content; | ||
134 | struct bdb_file *bdb_file = db->db_descr; | ||
135 | int rc; | ||
136 | |||
137 | memset (&keydat, 0, sizeof keydat); | ||
138 | keydat.data = key->mu_dptr; | ||
139 | keydat.size = key->mu_dsize; | ||
140 | memset (&content, 0, sizeof content); | ||
141 | content.flags = DB_DBT_MALLOC; | ||
142 | rc = bdb_file->db->get (bdb_file->db, NULL, &keydat, &content, 0); | ||
143 | mu_dbm_datum_free (ret); | ||
144 | switch (rc) | ||
145 | { | ||
146 | case 0: | ||
147 | ret->mu_dptr = content.data; | ||
148 | ret->mu_dsize = content.size; | ||
149 | ret->mu_sys = db->db_sys; | ||
150 | break; | ||
151 | |||
152 | case DB_NOTFOUND: | ||
153 | db->db_errno.n = rc; | ||
154 | rc = MU_ERR_NOENT; | ||
155 | break; | ||
156 | |||
157 | default: | ||
158 | db->db_errno.n = rc; | ||
159 | rc = MU_ERR_FAILURE; | ||
160 | } | ||
161 | return rc; | ||
162 | } | ||
163 | |||
164 | static int | ||
165 | _bdb_store (mu_dbm_file_t db, | ||
166 | struct mu_dbm_datum const *key, | ||
167 | struct mu_dbm_datum const *contents, | ||
168 | int replace) | ||
169 | { | ||
170 | struct bdb_file *bdb_file = db->db_descr; | ||
171 | int rc; | ||
172 | DBT keydat, condat; | ||
173 | |||
174 | memset (&keydat, 0, sizeof keydat); | ||
175 | keydat.data = key->mu_dptr; | ||
176 | keydat.size = key->mu_dsize; | ||
177 | |||
178 | memset (&condat, 0, sizeof condat); | ||
179 | condat.data = contents->mu_dptr; | ||
180 | condat.size = contents->mu_dsize; | ||
181 | |||
182 | rc = bdb_file->db->put (bdb_file->db, NULL, &keydat, &condat, | ||
183 | replace ? 0 : DB_NOOVERWRITE); | ||
184 | db->db_errno.n = rc; | ||
185 | switch (rc) | ||
186 | { | ||
187 | case 0: | ||
188 | break; | ||
189 | |||
190 | case DB_KEYEXIST: | ||
191 | rc = MU_ERR_EXISTS; | ||
192 | break; | ||
193 | |||
194 | default: | ||
195 | rc = MU_ERR_FAILURE; | ||
196 | break; | ||
197 | } | ||
198 | return rc; | ||
199 | } | ||
200 | |||
201 | static int | ||
202 | _bdb_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key) | ||
203 | { | ||
204 | DBT keydat; | ||
205 | struct bdb_file *bdb_file = db->db_descr; | ||
206 | int rc; | ||
207 | |||
208 | memset (&keydat, 0, sizeof keydat); | ||
209 | keydat.data = key->mu_dptr; | ||
210 | keydat.size = key->mu_dsize; | ||
211 | rc = bdb_file->db->del (bdb_file->db, NULL, &keydat, 0); | ||
212 | switch (rc) | ||
213 | { | ||
214 | case 0: | ||
215 | break; | ||
216 | |||
217 | case DB_NOTFOUND: | ||
218 | db->db_errno.n = rc; | ||
219 | rc = MU_ERR_NOENT; | ||
220 | break; | ||
221 | |||
222 | default: | ||
223 | db->db_errno.n = rc; | ||
224 | rc = MU_ERR_FAILURE; | ||
225 | } | ||
226 | return rc; | ||
227 | } | ||
228 | |||
229 | static int | ||
230 | _bdb_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret) | ||
231 | { | ||
232 | struct bdb_file *bdb_file = db->db_descr; | ||
233 | int rc; | ||
234 | DBT key, dbt; | ||
235 | |||
236 | if (!bdb_file->dbc) | ||
237 | { | ||
238 | rc = bdb_file->db->cursor (bdb_file->db, NULL, &bdb_file->dbc | ||
239 | BDB2_CURSOR_LASTARG); | ||
240 | if (rc) | ||
241 | { | ||
242 | db->db_errno.n = rc; | ||
243 | return MU_ERR_FAILURE; | ||
244 | } | ||
245 | } | ||
246 | memset (&key, 0, sizeof key); | ||
247 | key.flags = DB_DBT_MALLOC; | ||
248 | |||
249 | memset (&dbt, 0, sizeof dbt); | ||
250 | dbt.flags = DB_DBT_MALLOC; | ||
251 | rc = bdb_file->dbc->c_get (bdb_file->dbc, &key, &dbt, DB_FIRST); | ||
252 | mu_dbm_datum_free (ret); | ||
253 | switch (rc) | ||
254 | { | ||
255 | case 0: | ||
256 | free (dbt.data); /* FIXME: cache it for the eventual fetch that can | ||
257 | follow */ | ||
258 | ret->mu_dptr = key.data; | ||
259 | ret->mu_dsize = key.size; | ||
260 | ret->mu_sys = db->db_sys; | ||
261 | break; | ||
262 | |||
263 | case DB_NOTFOUND: | ||
264 | db->db_errno.n = rc; | ||
265 | rc = MU_ERR_NOENT; | ||
266 | break; | ||
267 | |||
268 | default: | ||
269 | db->db_errno.n = rc; | ||
270 | rc = MU_ERR_FAILURE; | ||
271 | } | ||
272 | return rc; | ||
273 | } | ||
274 | |||
275 | static int | ||
276 | _bdb_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret) | ||
277 | { | ||
278 | struct bdb_file *bdb_file = db->db_descr; | ||
279 | int rc; | ||
280 | DBT key, dbt; | ||
281 | |||
282 | if (!bdb_file->dbc) | ||
283 | return MU_ERR_SEQ; | ||
284 | |||
285 | memset (&key, 0, sizeof key); | ||
286 | key.flags = DB_DBT_MALLOC; | ||
287 | |||
288 | memset (&dbt, 0, sizeof dbt); | ||
289 | dbt.flags = DB_DBT_MALLOC; | ||
290 | rc = bdb_file->dbc->c_get (bdb_file->dbc, &key, &dbt, DB_NEXT); | ||
291 | mu_dbm_datum_free (ret); | ||
292 | switch (rc) | ||
293 | { | ||
294 | case 0: | ||
295 | free (dbt.data); /* FIXME: cache it for the eventual fetch that can | ||
296 | follow */ | ||
297 | ret->mu_dptr = key.data; | ||
298 | ret->mu_dsize = key.size; | ||
299 | ret->mu_sys = db->db_sys; | ||
300 | break; | ||
301 | |||
302 | case DB_NOTFOUND: | ||
303 | db->db_errno.n = rc; | ||
304 | rc = MU_ERR_NOENT; | ||
305 | break; | ||
306 | |||
307 | default: | ||
308 | db->db_errno.n = rc; | ||
309 | rc = MU_ERR_FAILURE; | ||
310 | } | ||
311 | return rc; | ||
312 | } | ||
313 | |||
314 | static void | ||
315 | _bdb_datum_free (struct mu_dbm_datum *datum) | ||
316 | { | ||
317 | free (datum->mu_dptr); | ||
318 | } | ||
319 | |||
320 | static char const * | ||
321 | _bdb_strerror (mu_dbm_file_t db) | ||
322 | { | ||
323 | return db_strerror (db->db_errno.n); | ||
324 | } | ||
325 | |||
326 | struct mu_dbm_impl _mu_dbm_bdb = { | ||
327 | "bdb", | ||
328 | _bdb_file_safety, | ||
329 | _bdb_get_fd, | ||
330 | _bdb_open, | ||
331 | _bdb_close, | ||
332 | _bdb_fetch, | ||
333 | _bdb_store, | ||
334 | _bdb_delete, | ||
335 | _bdb_firstkey, | ||
336 | _bdb_nextkey, | ||
337 | _bdb_datum_free, | ||
338 | _bdb_strerror | ||
339 | }; | ||
340 | #endif |
libmu_dbm/close.c
0 → 100644
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 | |||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | int | ||
28 | mu_dbm_close (mu_dbm_file_t db) | ||
29 | { | ||
30 | DBMSYSCK (db, _dbm_close); | ||
31 | if (!db->db_descr) | ||
32 | return 0; | ||
33 | return db->db_sys->_dbm_close (db); | ||
34 | } | ||
35 |
libmu_dbm/create.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2011 | ||
3 | Free Software Foundation, Inc. | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 3 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General | ||
16 | Public License along with this library. If not, see | ||
17 | <http://www.gnu.org/licenses/>. */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include <config.h> | ||
21 | #endif | ||
22 | #include <unistd.h> | ||
23 | #include <stdlib.h> | ||
24 | #include <mailutils/types.h> | ||
25 | #include <mailutils/list.h> | ||
26 | #include <mailutils/url.h> | ||
27 | #include <mailutils/dbm.h> | ||
28 | #include <mailutils/errno.h> | ||
29 | #include <mailutils/util.h> | ||
30 | #include "mudbm.h" | ||
31 | |||
32 | int | ||
33 | mu_dbm_create (char *name, mu_dbm_file_t *db) | ||
34 | { | ||
35 | int rc; | ||
36 | mu_url_t url; | ||
37 | |||
38 | _mu_dbm_init (); | ||
39 | rc = mu_url_create_hint (&url, name, 0, mu_dbm_hint); | ||
40 | if (rc) | ||
41 | return rc; | ||
42 | rc = mu_dbm_create_from_url (url, db); | ||
43 | mu_url_destroy (&url); | ||
44 | return rc; | ||
45 | } |
libmu_dbm/datumfree.c
0 → 100644
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 <stdlib.h> | ||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | void | ||
28 | mu_dbm_datum_free (struct mu_dbm_datum *datum) | ||
29 | { | ||
30 | if (datum && datum->mu_data && | ||
31 | datum->mu_sys && datum->mu_sys->_dbm_datum_free) | ||
32 | { | ||
33 | datum->mu_sys->_dbm_datum_free (datum); | ||
34 | datum->mu_data = NULL; | ||
35 | } | ||
36 | } |
libmu_dbm/dbm.c
0 → 100644
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 <unistd.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <string.h> | ||
24 | #include <mailutils/types.h> | ||
25 | #include <mailutils/list.h> | ||
26 | #include <mailutils/url.h> | ||
27 | #include <mailutils/dbm.h> | ||
28 | #include <mailutils/util.h> | ||
29 | #include <mailutils/errno.h> | ||
30 | #include <mailutils/error.h> | ||
31 | #include <mailutils/nls.h> | ||
32 | #include <mailutils/mu_auth.h> | ||
33 | #include "mudbm.h" | ||
34 | |||
35 | static mu_list_t implist; | ||
36 | mu_url_t mu_dbm_hint; | ||
37 | |||
38 | static void | ||
39 | _implist_free (void *p) | ||
40 | { | ||
41 | struct mu_dbm_impl *impl = p; | ||
42 | |||
43 | free (impl->_dbm_name); | ||
44 | free (impl); | ||
45 | } | ||
46 | |||
47 | static int | ||
48 | _implist_cmp (const void *a, const void *b) | ||
49 | { | ||
50 | struct mu_dbm_impl const *ia = a; | ||
51 | struct mu_dbm_impl const *ib = b; | ||
52 | |||
53 | return strcmp (ia->_dbm_name, ib->_dbm_name); | ||
54 | } | ||
55 | |||
56 | void | ||
57 | _mu_dbm_init () | ||
58 | { | ||
59 | int rc; | ||
60 | |||
61 | if (implist) | ||
62 | return; | ||
63 | |||
64 | rc = mu_list_create (&implist); | ||
65 | if (rc) | ||
66 | { | ||
67 | mu_error (_("cannot initialize DBM subsystem: %s"), | ||
68 | mu_strerror (rc)); | ||
69 | abort (); | ||
70 | } | ||
71 | mu_list_set_destroy_item (implist, _implist_free); | ||
72 | mu_list_set_comparator (implist, _implist_cmp); | ||
73 | /* Add built-in entries */ | ||
74 | #ifdef WITH_GDBM | ||
75 | mu_dbm_register (&_mu_dbm_gdbm); | ||
76 | #endif | ||
77 | #ifdef WITH_BDB | ||
78 | mu_dbm_register (&_mu_dbm_bdb); | ||
79 | #endif | ||
80 | #ifdef WITH_NDBM | ||
81 | mu_dbm_register (&_mu_dbm_ndbm); | ||
82 | #endif | ||
83 | #ifdef WITH_TOKYOCABINET | ||
84 | mu_dbm_register (&_mu_dbm_tokyokabinet); | ||
85 | #endif | ||
86 | if (!mu_dbm_hint) | ||
87 | { | ||
88 | struct mu_dbm_impl *impl; | ||
89 | char *urlbuf; | ||
90 | |||
91 | rc = mu_list_get (implist, 0, (void**) &impl); | ||
92 | if (rc) | ||
93 | { | ||
94 | mu_error (_("cannot initialize DBM hint: %s"), | ||
95 | mu_strerror (rc)); | ||
96 | abort (); | ||
97 | } | ||
98 | urlbuf = malloc (strlen (impl->_dbm_name) + 4); | ||
99 | if (urlbuf) | ||
100 | { | ||
101 | strcpy (urlbuf, impl->_dbm_name); | ||
102 | strcat (urlbuf, "://"); | ||
103 | rc = mu_url_create (&mu_dbm_hint, urlbuf); | ||
104 | free (urlbuf); | ||
105 | } | ||
106 | else | ||
107 | rc = ENOMEM; | ||
108 | |||
109 | if (rc) | ||
110 | { | ||
111 | mu_error (_("cannot initialize DBM hint: %s"), | ||
112 | mu_strerror (rc)); | ||
113 | abort (); | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | |||
118 | int | ||
119 | mu_dbm_register (struct mu_dbm_impl *impl) | ||
120 | { | ||
121 | int rc; | ||
122 | struct mu_dbm_impl *ptr; | ||
123 | |||
124 | _mu_dbm_init (); | ||
125 | ptr = calloc (1, sizeof (*ptr)); | ||
126 | if (!ptr) | ||
127 | return ENOMEM; | ||
128 | *ptr = *impl; | ||
129 | ptr->_dbm_name = strdup (impl->_dbm_name); | ||
130 | if (!ptr->_dbm_name) | ||
131 | { | ||
132 | free (ptr); | ||
133 | return ENOMEM; | ||
134 | } | ||
135 | rc = mu_list_append (implist, ptr); | ||
136 | if (rc) | ||
137 | _implist_free (ptr); | ||
138 | return rc; | ||
139 | } | ||
140 | |||
141 | int | ||
142 | mu_dbm_create_from_url (mu_url_t url, mu_dbm_file_t *db) | ||
143 | { | ||
144 | mu_dbm_file_t p; | ||
145 | int flags; | ||
146 | int rc; | ||
147 | const char *db_name; | ||
148 | struct mu_dbm_impl impl_key; | ||
149 | struct mu_dbm_impl *impl; | ||
150 | struct mu_auth_data *auth; | ||
151 | int safety_flags = 0; | ||
152 | uid_t owner_uid = getuid (); | ||
153 | |||
154 | _mu_dbm_init (); | ||
155 | |||
156 | mu_url_get_flags (url, &flags); | ||
157 | if ((flags & (MU_URL_HOST | MU_URL_PATH)) == (MU_URL_HOST | MU_URL_PATH)) | ||
158 | return MU_ERR_URL_EXTRA_PARTS; | ||
159 | if (flags & MU_URL_HOST) | ||
160 | rc = mu_url_sget_host (url, &db_name); | ||
161 | else | ||
162 | rc = mu_url_sget_path (url, &db_name); | ||
163 | if (rc) | ||
164 | return rc; | ||
165 | |||
166 | rc = mu_url_sget_scheme (url, (const char**)&impl_key._dbm_name); | ||
167 | if (rc) | ||
168 | return rc; | ||
169 | |||
170 | rc = mu_list_locate (implist, (void *) &impl_key, (void **) &impl); | ||
171 | if (rc) | ||
172 | return rc; | ||
173 | |||
174 | if (flags & MU_URL_PARAM) | ||
175 | { | ||
176 | size_t fvc, i; | ||
177 | char **fvp; | ||
178 | |||
179 | mu_url_sget_fvpairs (url, &fvc, &fvp); | ||
180 | for (i = 0; i < fvc; i++) | ||
181 | { | ||
182 | const char *name = fvp[i]; | ||
183 | int negate = 0; | ||
184 | int val; | ||
185 | |||
186 | if (*name == '-') | ||
187 | { | ||
188 | negate = 1; | ||
189 | name++; | ||
190 | } | ||
191 | else if (*name == '+') | ||
192 | name++; | ||
193 | |||
194 | if (strncmp (name, "owner", 5) == 0) | ||
195 | { | ||
196 | val = MU_FILE_SAFETY_OWNER_MISMATCH; | ||
197 | if (name[5] == '=') | ||
198 | { | ||
199 | auth = mu_get_auth_by_name (name + 6); | ||
200 | if (!auth) | ||
201 | { | ||
202 | char *end; | ||
203 | unsigned long uid; | ||
204 | |||
205 | errno = 0; | ||
206 | uid = strtoul (name + 6, &end, 0); | ||
207 | if (*end || errno) | ||
208 | return MU_ERR_NO_SUCH_USER; | ||
209 | auth = mu_get_auth_by_uid (uid); | ||
210 | if (!auth) | ||
211 | return MU_ERR_NO_SUCH_USER; | ||
212 | owner_uid = auth->uid; | ||
213 | mu_auth_data_free (auth); | ||
214 | } | ||
215 | } | ||
216 | else if (name[5]) | ||
217 | return MU_ERR_URL_EXTRA_PARTS;//FIXME: better error code | ||
218 | } | ||
219 | else if (strcmp (name, "none") == 0) | ||
220 | { | ||
221 | safety_flags = negate ? MU_FILE_SAFETY_ALL : MU_FILE_SAFETY_NONE; | ||
222 | continue; | ||
223 | } | ||
224 | else if (strcmp (name, "all") == 0) | ||
225 | { | ||
226 | safety_flags = negate ? MU_FILE_SAFETY_NONE : MU_FILE_SAFETY_ALL; | ||
227 | continue; | ||
228 | } | ||
229 | else if (strcmp (name, "default") == 0) | ||
230 | { | ||
231 | val = DEFAULT_DBM_SAFETY_FLAGS; | ||
232 | } | ||
233 | else if (mu_file_safety_name_to_code (name, &val)) | ||
234 | return MU_ERR_URL_EXTRA_PARTS;//FIXME: better error code | ||
235 | |||
236 | if (negate) | ||
237 | safety_flags &= ~val; | ||
238 | else | ||
239 | safety_flags |= val; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | p = calloc (1, sizeof (*p)); | ||
244 | if (!p) | ||
245 | return ENOMEM; | ||
246 | p->db_name = strdup (db_name); | ||
247 | if (!p->db_name) | ||
248 | { | ||
249 | free (p); | ||
250 | return ENOMEM; | ||
251 | } | ||
252 | p->db_safety_flags = safety_flags; | ||
253 | p->db_owner = owner_uid; | ||
254 | p->db_sys = impl; | ||
255 | |||
256 | *db = p; | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | int | ||
261 | mu_dbm_impl_iterator (mu_iterator_t *itr) | ||
262 | { | ||
263 | _mu_dbm_init (); | ||
264 | return mu_list_get_iterator (implist, itr); | ||
265 | } |
libmu_dbm/delete.c
0 → 100644
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 | |||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | int | ||
28 | mu_dbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key) | ||
29 | { | ||
30 | DBMSYSCK (db, _dbm_delete); | ||
31 | if (!db->db_descr) | ||
32 | return EINVAL; | ||
33 | return db->db_sys->_dbm_delete (db, key); | ||
34 | } | ||
35 |
libmu_dbm/destroy.c
0 → 100644
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 <stdlib.h> | ||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | void | ||
28 | mu_dbm_destroy (mu_dbm_file_t *pdb) | ||
29 | { | ||
30 | if (pdb && *pdb) | ||
31 | { | ||
32 | mu_dbm_file_t db = *pdb; | ||
33 | if (db->db_descr) | ||
34 | mu_dbm_close (db); | ||
35 | free (db->db_name); | ||
36 | free (db); | ||
37 | *pdb = NULL; | ||
38 | } | ||
39 | } |
libmu_dbm/errstr.c
0 → 100644
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 <stdlib.h> | ||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | char const * | ||
28 | mu_dbm_strerror (mu_dbm_file_t db) | ||
29 | { | ||
30 | if (!db) | ||
31 | return NULL; | ||
32 | if (!db->db_sys || !db->db_sys->_dbm_strerror) | ||
33 | return NULL; | ||
34 | if (!db->db_descr) | ||
35 | return mu_strerror (MU_ERR_NOT_OPEN); | ||
36 | return db->db_sys->_dbm_strerror (db); | ||
37 | } |
libmu_dbm/fetch.c
0 → 100644
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 | |||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | int | ||
28 | mu_dbm_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key, | ||
29 | struct mu_dbm_datum *ret) | ||
30 | { | ||
31 | DBMSYSCK (db, _dbm_fetch); | ||
32 | if (!db->db_descr) | ||
33 | return EINVAL; | ||
34 | return db->db_sys->_dbm_fetch (db, key, ret); | ||
35 | } | ||
36 |
libmu_dbm/firstkey.c
0 → 100644
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 | |||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | int | ||
28 | mu_dbm_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret) | ||
29 | { | ||
30 | DBMSYSCK (db, _dbm_firstkey); | ||
31 | if (!db->db_descr) | ||
32 | return EINVAL; | ||
33 | return db->db_sys->_dbm_firstkey (db, ret); | ||
34 | } |
libmu_dbm/gdbm.c
0 → 100644
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 <stdlib.h> | ||
22 | #include <string.h> | ||
23 | #include <mailutils/types.h> | ||
24 | #include <mailutils/dbm.h> | ||
25 | #include <mailutils/util.h> | ||
26 | #include <mailutils/errno.h> | ||
27 | #include <mailutils/error.h> | ||
28 | #include <mailutils/stream.h> | ||
29 | #include "mudbm.h" | ||
30 | |||
31 | #if defined(WITH_GDBM) | ||
32 | #include <gdbm.h> | ||
33 | |||
34 | struct gdbm_descr | ||
35 | { | ||
36 | GDBM_FILE file; /* GDBM file */ | ||
37 | datum prev; /* Previous key for sequential access */ | ||
38 | }; | ||
39 | |||
40 | static int | ||
41 | _gdbm_file_safety (mu_dbm_file_t db, int mode, uid_t owner) | ||
42 | { | ||
43 | return mu_file_safety_check (db->db_name, mode, owner, NULL); | ||
44 | } | ||
45 | |||
46 | int | ||
47 | _gdbm_get_fd (mu_dbm_file_t db, int *pag, int *dir) | ||
48 | { | ||
49 | struct gdbm_descr *gd = db->db_descr; | ||
50 | *pag = gdbm_fdesc (gd->file); | ||
51 | if (dir) | ||
52 | *dir = *pag; | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static int | ||
57 | _gdbm_open (mu_dbm_file_t db, int flags, int mode) | ||
58 | { | ||
59 | int f; | ||
60 | struct gdbm_descr *gd; | ||
61 | GDBM_FILE file; | ||
62 | |||
63 | switch (flags) | ||
64 | { | ||
65 | case MU_STREAM_CREAT: | ||
66 | f = GDBM_NEWDB; | ||
67 | break; | ||
68 | |||
69 | case MU_STREAM_READ: | ||
70 | f = GDBM_READER; | ||
71 | break; | ||
72 | |||
73 | case MU_STREAM_RDWR: | ||
74 | f = GDBM_WRCREAT; | ||
75 | break; | ||
76 | |||
77 | default: | ||
78 | return EINVAL; | ||
79 | } | ||
80 | file = gdbm_open (db->db_name, 512, f, mode, NULL); | ||
81 | if (!file) | ||
82 | return MU_ERR_FAILURE; | ||
83 | gd = calloc (1, sizeof (*gd)); | ||
84 | gd->file = file; | ||
85 | db->db_descr = gd; | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int | ||
90 | _gdbm_close (mu_dbm_file_t db) | ||
91 | { | ||
92 | if (db->db_descr) | ||
93 | { | ||
94 | struct gdbm_descr *gd = db->db_descr; | ||
95 | gdbm_close (gd->file); | ||
96 | free (gd); | ||
97 | db->db_descr = NULL; | ||
98 | } | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static int | ||
103 | _gdbm_conv_datum (mu_dbm_file_t db, struct mu_dbm_datum *ret, datum content, | ||
104 | int copy) | ||
105 | { | ||
106 | if (copy) | ||
107 | { | ||
108 | ret->mu_dptr = malloc (content.dsize); | ||
109 | if (!ret->mu_dptr) | ||
110 | return errno; | ||
111 | memcpy (ret->mu_dptr, content.dptr, content.dsize); | ||
112 | } | ||
113 | else | ||
114 | { | ||
115 | ret->mu_dptr = content.dptr; | ||
116 | } | ||
117 | ret->mu_dsize = content.dsize; | ||
118 | ret->mu_sys = db->db_sys; | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static int | ||
123 | _gdbm_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key, | ||
124 | struct mu_dbm_datum *ret) | ||
125 | { | ||
126 | struct gdbm_descr *gd = db->db_descr; | ||
127 | int rc; | ||
128 | datum keydat, content; | ||
129 | |||
130 | keydat.dptr = key->mu_dptr; | ||
131 | keydat.dsize = key->mu_dsize; | ||
132 | gdbm_errno = 0; | ||
133 | content = gdbm_fetch (gd->file, keydat); | ||
134 | if (content.dptr == NULL) | ||
135 | { | ||
136 | if (gdbm_errno == GDBM_ITEM_NOT_FOUND) | ||
137 | return MU_ERR_NOENT; | ||
138 | else | ||
139 | { | ||
140 | db->db_errno.n = gdbm_errno; | ||
141 | return MU_ERR_FAILURE; | ||
142 | } | ||
143 | } | ||
144 | mu_dbm_datum_free (ret); | ||
145 | rc = _gdbm_conv_datum (db, ret, content, 1); | ||
146 | if (rc) | ||
147 | { | ||
148 | free (content.dptr); | ||
149 | return rc; | ||
150 | } | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static int | ||
155 | _gdbm_store (mu_dbm_file_t db, | ||
156 | struct mu_dbm_datum const *key, | ||
157 | struct mu_dbm_datum const *contents, | ||
158 | int replace) | ||
159 | { | ||
160 | struct gdbm_descr *gd = db->db_descr; | ||
161 | datum keydat, condat; | ||
162 | |||
163 | keydat.dptr = key->mu_dptr; | ||
164 | keydat.dsize = key->mu_dsize; | ||
165 | condat.dptr = contents->mu_dptr; | ||
166 | condat.dsize = contents->mu_dsize; | ||
167 | switch (gdbm_store (gd->file, keydat, condat, replace)) | ||
168 | { | ||
169 | case 0: | ||
170 | break; | ||
171 | |||
172 | case 1: | ||
173 | return MU_ERR_EXISTS; | ||
174 | |||
175 | case -1: | ||
176 | db->db_errno.n = gdbm_errno; | ||
177 | return MU_ERR_FAILURE; | ||
178 | } | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int | ||
183 | _gdbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key) | ||
184 | { | ||
185 | struct gdbm_descr *gd = db->db_descr; | ||
186 | datum keydat; | ||
187 | |||
188 | keydat.dptr = key->mu_dptr; | ||
189 | keydat.dsize = key->mu_dsize; | ||
190 | gdbm_errno = 0; | ||
191 | if (gdbm_delete (gd->file, keydat)) | ||
192 | { | ||
193 | if (gdbm_errno == GDBM_ITEM_NOT_FOUND) | ||
194 | return MU_ERR_NOENT; | ||
195 | else | ||
196 | { | ||
197 | db->db_errno.n = gdbm_errno; | ||
198 | return MU_ERR_FAILURE; | ||
199 | } | ||
200 | } | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int | ||
205 | _gdbm_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret) | ||
206 | { | ||
207 | struct gdbm_descr *gd = db->db_descr; | ||
208 | int rc; | ||
209 | datum key = gdbm_firstkey (gd->file); | ||
210 | if (key.dptr == NULL) | ||
211 | { | ||
212 | if (gdbm_errno == GDBM_ITEM_NOT_FOUND) | ||
213 | return MU_ERR_NOENT; | ||
214 | else | ||
215 | { | ||
216 | db->db_errno.n = gdbm_errno; | ||
217 | return MU_ERR_FAILURE; | ||
218 | } | ||
219 | } | ||
220 | mu_dbm_datum_free (ret); | ||
221 | rc = _gdbm_conv_datum (db, ret, key, 0); | ||
222 | if (rc) | ||
223 | { | ||
224 | free (key.dptr); | ||
225 | return rc; | ||
226 | } | ||
227 | free (gd->prev.dptr); | ||
228 | gd->prev = key; | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | static int | ||
233 | _gdbm_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret) | ||
234 | { | ||
235 | struct gdbm_descr *gd = db->db_descr; | ||
236 | int rc; | ||
237 | datum key; | ||
238 | |||
239 | if (!gd->prev.dptr) | ||
240 | return MU_ERR_NOENT; | ||
241 | key = gdbm_nextkey (gd->file, gd->prev); | ||
242 | if (key.dptr == NULL) | ||
243 | { | ||
244 | if (gdbm_errno == GDBM_ITEM_NOT_FOUND) | ||
245 | return MU_ERR_NOENT; | ||
246 | else | ||
247 | { | ||
248 | db->db_errno.n = gdbm_errno; | ||
249 | return MU_ERR_FAILURE; | ||
250 | } | ||
251 | } | ||
252 | mu_dbm_datum_free (ret); | ||
253 | rc = _gdbm_conv_datum (db, ret, key, 0); | ||
254 | if (rc) | ||
255 | { | ||
256 | free (key.dptr); | ||
257 | return rc; | ||
258 | } | ||
259 | free (gd->prev.dptr); | ||
260 | gd->prev = key; | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static void | ||
265 | _gdbm_datum_free (struct mu_dbm_datum *datum) | ||
266 | { | ||
267 | free (datum->mu_dptr); | ||
268 | } | ||
269 | |||
270 | static char const * | ||
271 | _gdbm_strerror (mu_dbm_file_t db) | ||
272 | { | ||
273 | return gdbm_strerror (db->db_errno.n); | ||
274 | } | ||
275 | |||
276 | struct mu_dbm_impl _mu_dbm_gdbm = { | ||
277 | "gdbm", | ||
278 | _gdbm_file_safety, | ||
279 | _gdbm_get_fd, | ||
280 | _gdbm_open, | ||
281 | _gdbm_close, | ||
282 | _gdbm_fetch, | ||
283 | _gdbm_store, | ||
284 | _gdbm_delete, | ||
285 | _gdbm_firstkey, | ||
286 | _gdbm_nextkey, | ||
287 | _gdbm_datum_free, | ||
288 | _gdbm_strerror | ||
289 | }; | ||
290 | #endif |
libmu_dbm/getfd.c
0 → 100644
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 | |||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | int | ||
28 | mu_dbm_get_fd (mu_dbm_file_t db, int *pag, int *dir) | ||
29 | { | ||
30 | DBMSYSCK (db, _dbm_get_fd); | ||
31 | if (!db->db_descr || !pag) | ||
32 | return EINVAL; | ||
33 | return db->db_sys->_dbm_get_fd (db, pag, dir); | ||
34 | } |
libmu_dbm/mudbm.h
0 → 100644
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 | #include <mailutils/sys/dbm.h> | ||
19 | |||
20 | #define DBMSYSCK(db,meth) do \ | ||
21 | { \ | ||
22 | if (!(db)) \ | ||
23 | return EINVAL; \ | ||
24 | if (!(db)->db_descr) \ | ||
25 | return MU_ERR_NOT_OPEN; \ | ||
26 | if (!(db)->db_sys || !(db)->db_sys->meth) \ | ||
27 | return ENOSYS; \ | ||
28 | } \ | ||
29 | while (0) | ||
30 | |||
31 | #define DEFAULT_DBM_SAFETY_FLAGS MU_FILE_SAFETY_ALL | ||
32 | |||
33 | #ifdef WITH_GDBM | ||
34 | extern struct mu_dbm_impl _mu_dbm_gdbm; | ||
35 | #endif | ||
36 | #ifdef WITH_BDB | ||
37 | extern struct mu_dbm_impl _mu_dbm_bdb; | ||
38 | #endif | ||
39 | #ifdef WITH_NDBM | ||
40 | extern struct mu_dbm_impl _mu_dbm_ndbm; | ||
41 | #endif | ||
42 | #ifdef WITH_TOKYOCABINET | ||
43 | extern struct mu_dbm_impl _mu_dbm_tokyokabinet; | ||
44 | #endif | ||
45 | |||
46 | void _mu_dbm_init (void); | ||
47 | |||
48 |
libmu_dbm/ndbm.c
0 → 100644
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 <mailutils/types.h> | ||
25 | #include <mailutils/dbm.h> | ||
26 | #include <mailutils/util.h> | ||
27 | #include <mailutils/errno.h> | ||
28 | #include <mailutils/error.h> | ||
29 | #include <mailutils/stream.h> | ||
30 | #include <mailutils/io.h> | ||
31 | #include "mudbm.h" | ||
32 | |||
33 | #if defined(WITH_NDBM) | ||
34 | #include <ndbm.h> | ||
35 | |||
36 | static int | ||
37 | _ndbm_file_safety (mu_dbm_file_t db, int mode, uid_t owner) | ||
38 | { | ||
39 | int rc; | ||
40 | char *name; | ||
41 | |||
42 | rc = mu_asprintf (&name, "%s.pag", db->db_name); | ||
43 | if (rc) | ||
44 | return rc; | ||
45 | rc = mu_file_safety_check (name, mode, owner, NULL); | ||
46 | if (rc) | ||
47 | { | ||
48 | free (name); | ||
49 | return rc; | ||
50 | } | ||
51 | |||
52 | strcpy (name + strlen (name) - 3, "dir"); | ||
53 | rc = mu_file_safety_check (name, mode, owner, NULL); | ||
54 | free (name); | ||
55 | return rc; | ||
56 | } | ||
57 | |||
58 | int | ||
59 | _ndbm_get_fd (mu_dbm_file_t db, int *pag, int *dir) | ||
60 | { | ||
61 | DBM *dbm = db->db_descr; | ||
62 | *pag = dbm_pagfno (dbm); | ||
63 | if (dir) | ||
64 | *dir = dbm_dirfno (dbm); | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static int | ||
69 | _ndbm_open (mu_dbm_file_t db, int flags, int mode) | ||
70 | { | ||
71 | int f; | ||
72 | DBM *dbm; | ||
73 | |||
74 | switch (flags) | ||
75 | { | ||
76 | case MU_STREAM_CREAT: | ||
77 | f = O_CREAT|O_TRUNC|O_RDWR; | ||
78 | break; | ||
79 | |||
80 | case MU_STREAM_READ: | ||
81 | f = O_RDONLY; | ||
82 | break; | ||
83 | |||
84 | case MU_STREAM_RDWR: | ||
85 | f = O_CREAT|O_RDWR; | ||
86 | break; | ||
87 | |||
88 | default: | ||
89 | errno = EINVAL; | ||
90 | return -1; | ||
91 | } | ||
92 | dbm = dbm_open (db->db_name, f, mode); | ||
93 | if (!dbm) | ||
94 | return MU_ERR_FAILURE; | ||
95 | db->db_descr = dbm; | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static int | ||
100 | _ndbm_close (mu_dbm_file_t db) | ||
101 | { | ||
102 | if (db->db_descr) | ||
103 | { | ||
104 | dbm_close ((DBM *) db->db_descr); | ||
105 | db->db_descr = NULL; | ||
106 | } | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int | ||
111 | _ndbm_conv_datum (mu_dbm_file_t db, struct mu_dbm_datum *ret, datum content) | ||
112 | { | ||
113 | ret->mu_dptr = malloc (content.dsize); | ||
114 | if (!ret->mu_dptr) | ||
115 | return errno; | ||
116 | memcpy (ret->mu_dptr, content.dptr, content.dsize); | ||
117 | ret->mu_dsize = content.dsize; | ||
118 | ret->mu_sys = db->db_sys; | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static int | ||
123 | _ndbm_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key, | ||
124 | struct mu_dbm_datum *ret) | ||
125 | { | ||
126 | datum keydat, content; | ||
127 | |||
128 | keydat.dptr = key->mu_dptr; | ||
129 | keydat.dsize = key->mu_dsize; | ||
130 | errno = 0; | ||
131 | content = dbm_fetch (db->db_descr, keydat); | ||
132 | mu_dbm_datum_free (ret); | ||
133 | if (content.dptr == NULL) | ||
134 | return MU_ERR_NOENT; | ||
135 | return _ndbm_conv_datum (db, ret, content); | ||
136 | } | ||
137 | |||
138 | static int | ||
139 | _ndbm_store (mu_dbm_file_t db, | ||
140 | struct mu_dbm_datum const *key, | ||
141 | struct mu_dbm_datum const *contents, | ||
142 | int replace) | ||
143 | { | ||
144 | DBM *dbm = db->db_descr; | ||
145 | datum keydat, condat; | ||
146 | |||
147 | keydat.dptr = key->mu_dptr; | ||
148 | keydat.dsize = key->mu_dsize; | ||
149 | condat.dptr = contents->mu_dptr; | ||
150 | condat.dsize = contents->mu_dsize; | ||
151 | errno = 0; | ||
152 | switch (dbm_store (dbm, keydat, condat, | ||
153 | replace ? DBM_REPLACE : DBM_INSERT)) | ||
154 | { | ||
155 | case 0: | ||
156 | break; | ||
157 | |||
158 | case 1: | ||
159 | return MU_ERR_EXISTS; | ||
160 | |||
161 | case -1: | ||
162 | db->db_errno.n = errno; | ||
163 | return MU_ERR_FAILURE; | ||
164 | } | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static int | ||
169 | _ndbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key) | ||
170 | { | ||
171 | DBM *dbm = db->db_descr; | ||
172 | datum keydat; | ||
173 | |||
174 | keydat.dptr = key->mu_dptr; | ||
175 | keydat.dsize = key->mu_dsize; | ||
176 | errno = 0; | ||
177 | switch (dbm_delete (dbm, keydat)) | ||
178 | { | ||
179 | case 0: | ||
180 | break; | ||
181 | |||
182 | case 1: | ||
183 | return MU_ERR_NOENT; | ||
184 | |||
185 | case -1: | ||
186 | db->db_errno.n = errno; | ||
187 | return MU_ERR_FAILURE; | ||
188 | } | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int | ||
193 | _ndbm_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret) | ||
194 | { | ||
195 | DBM *dbm = db->db_descr; | ||
196 | datum keydat; | ||
197 | |||
198 | errno = 0; | ||
199 | keydat = dbm_firstkey (dbm); | ||
200 | if (keydat.dptr == NULL) | ||
201 | return MU_ERR_NOENT; | ||
202 | return _ndbm_conv_datum (db, ret, keydat); | ||
203 | } | ||
204 | |||
205 | static int | ||
206 | _ndbm_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret) | ||
207 | { | ||
208 | DBM *dbm = db->db_descr; | ||
209 | datum keydat; | ||
210 | |||
211 | keydat = dbm_nextkey (dbm); | ||
212 | if (keydat.dptr == NULL) | ||
213 | return MU_ERR_NOENT; | ||
214 | return _ndbm_conv_datum (db, ret, keydat); | ||
215 | } | ||
216 | |||
217 | static void | ||
218 | _ndbm_datum_free (struct mu_dbm_datum *datum) | ||
219 | { | ||
220 | free (datum->mu_dptr); | ||
221 | } | ||
222 | |||
223 | static char const * | ||
224 | _ndbm_strerror (mu_dbm_file_t db) | ||
225 | { | ||
226 | return strerror (db->db_errno.n); | ||
227 | } | ||
228 | |||
229 | struct mu_dbm_impl _mu_dbm_ndbm = { | ||
230 | "ndbm", | ||
231 | _ndbm_file_safety, | ||
232 | _ndbm_get_fd, | ||
233 | _ndbm_open, | ||
234 | _ndbm_close, | ||
235 | _ndbm_fetch, | ||
236 | _ndbm_store, | ||
237 | _ndbm_delete, | ||
238 | _ndbm_firstkey, | ||
239 | _ndbm_nextkey, | ||
240 | _ndbm_datum_free, | ||
241 | _ndbm_strerror | ||
242 | }; | ||
243 | |||
244 | #endif |
libmu_dbm/nextkey.c
0 → 100644
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 | |||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | int | ||
28 | mu_dbm_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret) | ||
29 | { | ||
30 | DBMSYSCK (db, _dbm_nextkey); | ||
31 | if (!db->db_descr) | ||
32 | return EINVAL; | ||
33 | return db->db_sys->_dbm_nextkey (db, ret); | ||
34 | } |
libmu_dbm/open.c
0 → 100644
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 | |||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | int | ||
28 | mu_dbm_open (mu_dbm_file_t db, int flags, int mode) | ||
29 | { | ||
30 | if (!db) | ||
31 | return EINVAL; | ||
32 | if (!db->db_sys || !db->db_sys->_dbm_open) | ||
33 | return ENOSYS; | ||
34 | return db->db_sys->_dbm_open (db, flags, mode); | ||
35 | } | ||
36 |
libmu_dbm/safety.c
0 → 100644
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 | |||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | int | ||
28 | mu_dbm_safety_set_owner (mu_dbm_file_t db, uid_t uid) | ||
29 | { | ||
30 | if (!db) | ||
31 | return EINVAL; | ||
32 | db->db_owner = uid; | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | int | ||
37 | mu_dbm_safety_get_owner (mu_dbm_file_t db, uid_t *uid) | ||
38 | { | ||
39 | if (!db) | ||
40 | return EINVAL; | ||
41 | *uid = db->db_owner; | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | int | ||
46 | mu_dbm_safety_set_flags (mu_dbm_file_t db, int flags) | ||
47 | { | ||
48 | if (!db) | ||
49 | return EINVAL; | ||
50 | db->db_safety_flags = flags; | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | int | ||
55 | mu_dbm_safety_get_flags (mu_dbm_file_t db, int *flags) | ||
56 | { | ||
57 | if (!db) | ||
58 | return EINVAL; | ||
59 | *flags = db->db_safety_flags; | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | int | ||
64 | mu_dbm_safety_check (mu_dbm_file_t db) | ||
65 | { | ||
66 | if (!db) | ||
67 | return EINVAL; | ||
68 | if (!db->db_sys || !db->db_sys->_dbm_file_safety) | ||
69 | return ENOSYS; | ||
70 | return db->db_sys->_dbm_file_safety (db, db->db_safety_flags, | ||
71 | db->db_owner); | ||
72 | } |
libmu_dbm/store.c
0 → 100644
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 | |||
22 | #include <mailutils/types.h> | ||
23 | #include <mailutils/dbm.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include "mudbm.h" | ||
26 | |||
27 | int | ||
28 | mu_dbm_store (mu_dbm_file_t db, struct mu_dbm_datum const *key, | ||
29 | struct mu_dbm_datum const *contents, int replace) | ||
30 | { | ||
31 | DBMSYSCK (db, _dbm_store); | ||
32 | if (!db->db_descr) | ||
33 | return EINVAL; | ||
34 | return db->db_sys->_dbm_store (db, key, contents, replace); | ||
35 | } |
... | @@ -36,7 +36,6 @@ | ... | @@ -36,7 +36,6 @@ |
36 | #include <string.h> | 36 | #include <string.h> |
37 | #include <signal.h> | 37 | #include <signal.h> |
38 | #include <regex.h> | 38 | #include <regex.h> |
39 | #include <mu_dbm.h> | ||
40 | #include <mailutils/sieve.h> | 39 | #include <mailutils/sieve.h> |
41 | #include <mailutils/mu_auth.h> | 40 | #include <mailutils/mu_auth.h> |
42 | 41 | ... | ... |
... | @@ -46,6 +46,8 @@ maidag_LDADD = \ | ... | @@ -46,6 +46,8 @@ maidag_LDADD = \ |
46 | @MU_AUTHLIBS@\ | 46 | @MU_AUTHLIBS@\ |
47 | ${MU_LIB_MAILUTILS} \ | 47 | ${MU_LIB_MAILUTILS} \ |
48 | @MU_COMMON_LIBRARIES@\ | 48 | @MU_COMMON_LIBRARIES@\ |
49 | ../libmu_dbm/libmu_dbm.la\ | ||
50 | @DBMLIBS@\ | ||
49 | @TCPWRAP_LIBRARIES@ | 51 | @TCPWRAP_LIBRARIES@ |
50 | 52 | ||
51 | INCLUDES = -I${top_srcdir} @MU_APP_COMMON_INCLUDES@ @GUILE_INCLUDES@ \ | 53 | INCLUDES = -I${top_srcdir} @MU_APP_COMMON_INCLUDES@ @GUILE_INCLUDES@ \ | ... | ... |
... | @@ -457,7 +457,7 @@ struct mu_cfg_param maidag_cfg_param[] = { | ... | @@ -457,7 +457,7 @@ struct mu_cfg_param maidag_cfg_param[] = { |
457 | { "exit-quota-tempfail", mu_cfg_bool, &ex_quota_tempfail, 0, NULL, | 457 | { "exit-quota-tempfail", mu_cfg_bool, &ex_quota_tempfail, 0, NULL, |
458 | N_("Indicate temporary failure if the recipient is over his mail quota.") | 458 | N_("Indicate temporary failure if the recipient is over his mail quota.") |
459 | }, | 459 | }, |
460 | #ifdef USE_DBM | 460 | #ifdef ENABLE_DBM |
461 | { "quota-db", mu_cfg_string, "adbname, 0, NULL, | 461 | { "quota-db", mu_cfg_string, "adbname, 0, NULL, |
462 | N_("Name of DBM quota database file."), | 462 | N_("Name of DBM quota database file."), |
463 | N_("file") }, | 463 | N_("file") }, | ... | ... |
... | @@ -86,10 +86,9 @@ | ... | @@ -86,10 +86,9 @@ |
86 | #include <mailutils/server.h> | 86 | #include <mailutils/server.h> |
87 | #include <mailutils/cctype.h> | 87 | #include <mailutils/cctype.h> |
88 | #include <mailutils/io.h> | 88 | #include <mailutils/io.h> |
89 | #include <mailutils/dbm.h> | ||
89 | 90 | ||
90 | #include <mu_dbm.h> | 91 | #if defined (ENABLE_DBM) || defined (USE_SQL) |
91 | |||
92 | #if defined (USE_DBM) || defined (USE_SQL) | ||
93 | # define USE_MAILBOX_QUOTAS 1 | 92 | # define USE_MAILBOX_QUOTAS 1 |
94 | #endif | 93 | #endif |
95 | 94 | ... | ... |
... | @@ -64,64 +64,85 @@ fail_retrieve_quota (char *name, mu_off_t *quota) | ... | @@ -64,64 +64,85 @@ fail_retrieve_quota (char *name, mu_off_t *quota) |
64 | return RETR_FAILURE; | 64 | return RETR_FAILURE; |
65 | } | 65 | } |
66 | 66 | ||
67 | #ifdef USE_DBM | 67 | #ifdef ENABLE_DBM |
68 | int | 68 | int |
69 | dbm_retrieve_quota (char *name, mu_off_t *quota) | 69 | dbm_retrieve_quota (char *name, mu_off_t *quota) |
70 | { | 70 | { |
71 | DBM_FILE db; | 71 | mu_dbm_file_t db; |
72 | DBM_DATUM named, contentd; | 72 | struct mu_dbm_datum named, contentd; |
73 | char buffer[64]; | 73 | char buffer[64]; |
74 | int unlimited = 0; | 74 | int unlimited = 0; |
75 | int rc; | 75 | int rc; |
76 | 76 | ||
77 | if (!quotadbname) | 77 | if (!quotadbname) |
78 | return RETR_FAILURE; | 78 | return RETR_FAILURE; |
79 | 79 | ||
80 | if (mu_dbm_open (quotadbname, &db, MU_STREAM_READ, 0600)) | 80 | rc = mu_dbm_create (quotadbname, &db); |
81 | if (rc) | ||
82 | { | ||
83 | mu_error (_("unable to create quota db")); | ||
84 | return RETR_FAILURE; | ||
85 | } | ||
86 | |||
87 | rc = mu_dbm_safety_check (db); | ||
88 | if (rc && rc != ENOENT) | ||
81 | { | 89 | { |
82 | mu_error (_("cannot open file %s: %s"), quotadbname, mu_strerror (errno)); | 90 | mu_error (_("quota db fails safety check: %s"), |
91 | mu_strerror (rc)); | ||
92 | mu_dbm_destroy (&db); | ||
93 | return RETR_FAILURE; | ||
94 | } | ||
95 | |||
96 | rc = mu_dbm_open (db, MU_STREAM_READ, 0600); | ||
97 | if (rc) | ||
98 | { | ||
99 | mu_error (_("cannot open file %s: %s"), | ||
100 | quotadbname, mu_strerror (rc)); | ||
101 | mu_dbm_destroy (&db); | ||
83 | return RETR_FAILURE; | 102 | return RETR_FAILURE; |
84 | } | 103 | } |
85 | 104 | ||
86 | memset (&named, 0, sizeof named); | 105 | memset (&named, 0, sizeof named); |
87 | memset (&contentd, 0, sizeof contentd); | 106 | memset (&contentd, 0, sizeof contentd); |
88 | MU_DATUM_PTR (named) = name; | 107 | named.mu_dptr = name; |
89 | MU_DATUM_SIZE (named) = strlen (name); | 108 | named.mu_dsize = strlen (name); |
90 | rc = mu_dbm_fetch (db, named, &contentd); | 109 | rc = mu_dbm_fetch (db, &named, &contentd); |
91 | if (rc || !MU_DATUM_PTR (contentd)) | 110 | if (rc) |
92 | { | 111 | { |
93 | /* User not in database, try default quota */ | 112 | /* User not in database, try default quota */ |
94 | memset (&named, 0, sizeof named); | 113 | mu_dbm_datum_free (&named); |
95 | MU_DATUM_PTR (named) = "DEFAULT"; | 114 | named.mu_dptr = "DEFAULT"; |
96 | MU_DATUM_SIZE (named) = strlen ("DEFAULT"); | 115 | named.mu_dsize = strlen ("DEFAULT"); |
97 | rc = mu_dbm_fetch (db, named, &contentd); | 116 | rc = mu_dbm_fetch (db, &named, &contentd); |
98 | if (rc) | 117 | if (rc == MU_ERR_NOENT) |
99 | { | 118 | { |
100 | /*mu_error (_("can't fetch data: %s"), strerror (rc));*/ | 119 | mu_dbm_destroy (&db); |
120 | return RETR_FAILURE; | ||
121 | } | ||
122 | else if (rc) | ||
123 | { | ||
124 | mu_error (_("can't fetch data: %s"), mu_dbm_strerror (db)); | ||
125 | mu_dbm_destroy (&db); | ||
101 | return RETR_FAILURE; | 126 | return RETR_FAILURE; |
102 | } | 127 | } |
103 | if (!MU_DATUM_PTR (contentd)) | ||
104 | return RETR_FAILURE; | ||
105 | } | 128 | } |
106 | 129 | ||
107 | if (mu_c_strncasecmp("none", | 130 | if (mu_c_strncasecmp("none", contentd.mu_dptr, contentd.mu_dsize) == 0) |
108 | MU_DATUM_PTR (contentd), | ||
109 | MU_DATUM_SIZE (contentd)) == 0) | ||
110 | unlimited = 1; | 131 | unlimited = 1; |
111 | else if (MU_DATUM_SIZE (contentd) > sizeof(buffer)-1) | 132 | else if (contentd.mu_dsize > sizeof (buffer) - 1) |
112 | { | 133 | { |
113 | mu_error (ngettext ("mailbox quota for `%s' is too big: %d digit", | 134 | mu_error (ngettext ("mailbox quota for `%s' is too big: %d digit", |
114 | "mailbox quota for `%s' is too big: %d digits", | 135 | "mailbox quota for `%s' is too big: %d digits", |
115 | MU_DATUM_SIZE (contentd)), | 136 | contentd.mu_dsize), |
116 | name, MU_DATUM_SIZE (contentd)); | 137 | name, contentd.mu_dsize); |
117 | *quota = groupquota; | 138 | *quota = groupquota; |
118 | } | 139 | } |
119 | else | 140 | else |
120 | { | 141 | { |
121 | char *p; | 142 | char *p; |
122 | 143 | ||
123 | strncpy(buffer, MU_DATUM_PTR (contentd), MU_DATUM_SIZE (contentd)); | 144 | strncpy (buffer, contentd.mu_dptr, contentd.mu_dsize); |
124 | buffer[MU_DATUM_SIZE (contentd)] = 0; | 145 | buffer[contentd.mu_dsize] = 0; |
125 | *quota = strtoul (buffer, &p, 0); | 146 | *quota = strtoul (buffer, &p, 0); |
126 | if (get_size (buffer, quota, &p)) | 147 | if (get_size (buffer, quota, &p)) |
127 | { | 148 | { |
... | @@ -129,8 +150,9 @@ dbm_retrieve_quota (char *name, mu_off_t *quota) | ... | @@ -129,8 +150,9 @@ dbm_retrieve_quota (char *name, mu_off_t *quota) |
129 | *quota = groupquota; | 150 | *quota = groupquota; |
130 | } | 151 | } |
131 | } | 152 | } |
132 | 153 | ||
133 | mu_dbm_close (db); | 154 | mu_dbm_datum_free (&contentd); |
155 | mu_dbm_destroy (&db); | ||
134 | 156 | ||
135 | return unlimited ? RETR_UNLIMITED : RETR_OK; | 157 | return unlimited ? RETR_UNLIMITED : RETR_OK; |
136 | } | 158 | } | ... | ... |
... | @@ -32,9 +32,17 @@ else | ... | @@ -32,9 +32,17 @@ else |
32 | IDLE_MODULES+=imap.c | 32 | IDLE_MODULES+=imap.c |
33 | endif | 33 | endif |
34 | 34 | ||
35 | if MU_COND_DBM | ||
36 | DBM_C=dbm.c | ||
37 | LIBMU_DBM=../libmu_dbm/libmu_dbm.la | ||
38 | else | ||
39 | IDLE_MODULES+=dbm.c | ||
40 | endif | ||
41 | |||
35 | MODULES = \ | 42 | MODULES = \ |
36 | acl.c\ | 43 | acl.c\ |
37 | cflags.c\ | 44 | cflags.c\ |
45 | $(DBM_C)\ | ||
38 | $(IMAP_C)\ | 46 | $(IMAP_C)\ |
39 | filter.c\ | 47 | filter.c\ |
40 | flt2047.c\ | 48 | flt2047.c\ |
... | @@ -67,6 +75,7 @@ mu_LDADD = \ | ... | @@ -67,6 +75,7 @@ mu_LDADD = \ |
67 | ${MU_LIB_AUTH}\ | 75 | ${MU_LIB_AUTH}\ |
68 | @MU_AUTHLIBS@\ | 76 | @MU_AUTHLIBS@\ |
69 | ${MU_LIB_MAILUTILS}\ | 77 | ${MU_LIB_MAILUTILS}\ |
78 | ${LIBMU_DBM} @DBMLIBS@\ | ||
70 | @READLINE_LIBS@ @MU_COMMON_LIBRARIES@ | 79 | @READLINE_LIBS@ @MU_COMMON_LIBRARIES@ |
71 | 80 | ||
72 | INCLUDES = @MU_APP_COMMON_INCLUDES@ @MU_AUTHINCS@ | 81 | INCLUDES = @MU_APP_COMMON_INCLUDES@ @MU_AUTHINCS@ |
... | @@ -77,7 +86,8 @@ AM_CPPFLAGS = \ | ... | @@ -77,7 +86,8 @@ AM_CPPFLAGS = \ |
77 | -DAUTHLIBS="\"$(MU_AUTHLIBS)\"" \ | 86 | -DAUTHLIBS="\"$(MU_AUTHLIBS)\"" \ |
78 | -DGUILE_LIBS="\"$(GUILE_LIBS)\"" \ | 87 | -DGUILE_LIBS="\"$(GUILE_LIBS)\"" \ |
79 | -DPYTHON_LIBS="\"$(PYTHON_LIBS)\"" \ | 88 | -DPYTHON_LIBS="\"$(PYTHON_LIBS)\"" \ |
80 | -DI18NLIBS="\"$(LIBINTL)\"" | 89 | -DI18NLIBS="\"$(LIBINTL)\"" \ |
90 | -DDBMLIBS="\"$(DBMLIBS)\"" | ||
81 | 91 | ||
82 | BUILT_SOURCES=mu-setup.c mu-setup.h | 92 | BUILT_SOURCES=mu-setup.c mu-setup.h |
83 | EXTRA_DIST=mu-setup.awk mu-setup.c mu-setup.h template.c | 93 | EXTRA_DIST=mu-setup.awk mu-setup.c mu-setup.h template.c | ... | ... |
mu/dbm.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2010, 2011 Free Software Foundation, Inc. | ||
3 | |||
4 | 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 | the Free Software Foundation; either version 3, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | GNU Mailutils 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 GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | #if defined(HAVE_CONFIG_H) | ||
18 | # include <config.h> | ||
19 | #endif | ||
20 | #include <sys/types.h> | ||
21 | #include <sys/stat.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <string.h> | ||
24 | #include <grp.h> | ||
25 | #include <sysexits.h> | ||
26 | #include <fnmatch.h> | ||
27 | #include <regex.h> | ||
28 | #include <mailutils/mailutils.h> | ||
29 | #include <mailutils/dbm.h> | ||
30 | #include "argp.h" | ||
31 | #include "mu.h" | ||
32 | #include "xalloc.h" | ||
33 | |||
34 | static char dbm_doc[] = N_("mu dbm - DBM management tool"); | ||
35 | char dbm_docstring[] = N_("DBM management tool"); | ||
36 | static char dbm_args_doc[] = N_("FILE [KEY...]"); | ||
37 | |||
38 | enum mode | ||
39 | { | ||
40 | mode_list, | ||
41 | mode_create, | ||
42 | mode_delete, | ||
43 | mode_add, | ||
44 | mode_replace, | ||
45 | }; | ||
46 | |||
47 | enum key_type | ||
48 | { | ||
49 | key_literal, | ||
50 | key_glob, | ||
51 | key_regex | ||
52 | }; | ||
53 | |||
54 | enum mode mode; | ||
55 | char *db_name; | ||
56 | char *input_file; | ||
57 | int permissions = 0600; | ||
58 | struct mu_auth_data *auth; | ||
59 | uid_t owner_uid = -1; | ||
60 | gid_t owner_gid = -1; | ||
61 | int copy_permissions; | ||
62 | enum key_type key_type = key_literal; | ||
63 | int case_sensitive = 1; | ||
64 | int include_zero = -1; | ||
65 | |||
66 | void | ||
67 | init_datum (struct mu_dbm_datum *key, char *str) | ||
68 | { | ||
69 | memset (key, 0, sizeof *key); | ||
70 | key->mu_dptr = str; | ||
71 | key->mu_dsize = strlen (str) + !!include_zero; | ||
72 | } | ||
73 | |||
74 | mu_dbm_file_t | ||
75 | open_db_file (int mode) | ||
76 | { | ||
77 | int rc; | ||
78 | mu_dbm_file_t db; | ||
79 | |||
80 | rc = mu_dbm_create (db_name, &db); | ||
81 | if (rc) | ||
82 | { | ||
83 | mu_diag_output (MU_DIAG_ERROR, _("unable to create database %s: %s"), | ||
84 | db_name, mu_strerror (rc)); | ||
85 | exit (EX_SOFTWARE); | ||
86 | } | ||
87 | |||
88 | rc = mu_dbm_open (db, mode, permissions); | ||
89 | if (rc) | ||
90 | { | ||
91 | mu_diag_funcall (MU_DIAG_ERROR, "mu_dbm_open", db_name, rc); | ||
92 | exit (EX_SOFTWARE); | ||
93 | } | ||
94 | |||
95 | if (mode == MU_STREAM_CREAT && (owner_uid != -1 || owner_gid != -1)) | ||
96 | { | ||
97 | int dirfd, pagfd; | ||
98 | |||
99 | rc = mu_dbm_get_fd (db, &pagfd, &dirfd); | ||
100 | if (rc) | ||
101 | { | ||
102 | mu_diag_funcall (MU_DIAG_ERROR, "mu_dbm_get_fd", db_name, rc); | ||
103 | exit (EX_SOFTWARE); | ||
104 | } | ||
105 | if (owner_uid == -1 || owner_gid == -1) | ||
106 | { | ||
107 | struct stat st; | ||
108 | |||
109 | if (fstat (dirfd, &st)) | ||
110 | { | ||
111 | mu_diag_funcall (MU_DIAG_ERROR, "fstat", db_name, errno); | ||
112 | exit (EX_SOFTWARE); | ||
113 | } | ||
114 | if (owner_uid == -1) | ||
115 | owner_uid = st.st_uid; | ||
116 | if (owner_gid == -1) | ||
117 | owner_gid = st.st_gid; | ||
118 | } | ||
119 | if (fchown (pagfd, owner_uid, owner_gid)) | ||
120 | { | ||
121 | mu_diag_funcall (MU_DIAG_ERROR, "fchown", db_name, errno); | ||
122 | exit (EX_SOFTWARE); | ||
123 | } | ||
124 | if (pagfd != dirfd && | ||
125 | fchown (dirfd, owner_uid, owner_gid)) | ||
126 | { | ||
127 | mu_diag_funcall (MU_DIAG_ERROR, "fchown", db_name, errno); | ||
128 | exit (EX_SOFTWARE); | ||
129 | } | ||
130 | } | ||
131 | return db; | ||
132 | } | ||
133 | |||
134 | struct print_data | ||
135 | { | ||
136 | mu_dbm_file_t db; | ||
137 | mu_stream_t stream; | ||
138 | }; | ||
139 | |||
140 | static int | ||
141 | print_action (struct mu_dbm_datum const *key, void *data) | ||
142 | { | ||
143 | int rc; | ||
144 | struct mu_dbm_datum contents; | ||
145 | struct print_data *pd = data; | ||
146 | size_t len; | ||
147 | |||
148 | memset (&contents, 0, sizeof contents); | ||
149 | rc = mu_dbm_fetch (pd->db, key, &contents); | ||
150 | if (rc) | ||
151 | { | ||
152 | mu_error (_("database fetch error: %s"), mu_dbm_strerror (pd->db)); | ||
153 | exit (EX_UNAVAILABLE); | ||
154 | } | ||
155 | |||
156 | len = key->mu_dsize; | ||
157 | if (key->mu_dptr[len - 1] == 0) | ||
158 | len--; | ||
159 | mu_stream_write (pd->stream, key->mu_dptr, len, NULL); | ||
160 | mu_stream_write (pd->stream, "\t", 1, NULL); | ||
161 | |||
162 | len = contents.mu_dsize; | ||
163 | if (contents.mu_dptr[len - 1] == 0) | ||
164 | len--; | ||
165 | mu_stream_write (pd->stream, contents.mu_dptr, len, NULL); | ||
166 | mu_stream_write (pd->stream, "\n", 1, NULL); | ||
167 | mu_dbm_datum_free (&contents); | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | static void | ||
172 | iterate_database (mu_dbm_file_t db, | ||
173 | int (*matcher) (const char *, void *), void *matcher_data, | ||
174 | int (*action) (struct mu_dbm_datum const *, void *), | ||
175 | void *action_data) | ||
176 | { | ||
177 | int rc; | ||
178 | struct mu_dbm_datum key; | ||
179 | char *buf = NULL; | ||
180 | size_t bufsize = 0; | ||
181 | |||
182 | memset (&key, 0, sizeof key); | ||
183 | for (rc = mu_dbm_firstkey (db, &key); rc == 0; | ||
184 | rc = mu_dbm_nextkey (db, &key)) | ||
185 | { | ||
186 | if (include_zero == -1) | ||
187 | include_zero = key.mu_dptr[key.mu_dsize-1] == 0; | ||
188 | |||
189 | if (matcher) | ||
190 | { | ||
191 | if (key.mu_dsize + 1 > bufsize) | ||
192 | { | ||
193 | bufsize = key.mu_dsize + 1; | ||
194 | buf = xrealloc (buf, bufsize); | ||
195 | } | ||
196 | memcpy (buf, key.mu_dptr, key.mu_dsize); | ||
197 | buf[key.mu_dsize] = 0; | ||
198 | if (!matcher (buf, matcher_data)) | ||
199 | continue; | ||
200 | } | ||
201 | if (action (&key, action_data)) | ||
202 | break; | ||
203 | } | ||
204 | free (buf); | ||
205 | } | ||
206 | |||
207 | static int | ||
208 | match_literal (const char *str, void *data) | ||
209 | { | ||
210 | char **argv = data; | ||
211 | |||
212 | for (; *argv; argv++) | ||
213 | { | ||
214 | if ((case_sensitive ? strcmp : strcasecmp) (str, *argv) == 0) | ||
215 | return 1; | ||
216 | } | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | #ifndef FNM_CASEFOLD | ||
221 | # define FNM_CASEFOLD 0 | ||
222 | #endif | ||
223 | |||
224 | static int | ||
225 | match_glob (const char *str, void *data) | ||
226 | { | ||
227 | char **argv = data; | ||
228 | |||
229 | for (; *argv; argv++) | ||
230 | { | ||
231 | if (fnmatch (*argv, str, case_sensitive ? FNM_CASEFOLD : 0) == 0) | ||
232 | return 1; | ||
233 | } | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | struct regmatch | ||
238 | { | ||
239 | int regc; | ||
240 | regex_t *regs; | ||
241 | }; | ||
242 | |||
243 | static int | ||
244 | match_regex (const char *str, void *data) | ||
245 | { | ||
246 | struct regmatch *match = data; | ||
247 | int i; | ||
248 | |||
249 | for (i = 0; i < match->regc; i++) | ||
250 | { | ||
251 | if (regexec (&match->regs[i], str, 0, NULL, 0) == 0) | ||
252 | return 1; | ||
253 | } | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | void | ||
258 | compile_regexes (int argc, char **argv, struct regmatch *match) | ||
259 | { | ||
260 | regex_t *regs = xcalloc (argc, sizeof (regs[0])); | ||
261 | int i; | ||
262 | int cflags = (case_sensitive ? 0: REG_ICASE) | REG_EXTENDED | REG_NOSUB; | ||
263 | int errors = 0; | ||
264 | |||
265 | for (i = 0; i < argc; i++) | ||
266 | { | ||
267 | int rc = regcomp (®s[i], argv[i], cflags); | ||
268 | if (rc) | ||
269 | { | ||
270 | char errbuf[512]; | ||
271 | regerror (rc, ®s[i], errbuf, sizeof (errbuf)); | ||
272 | mu_error (_("error compiling `%s': %s"), argv[i], errbuf); | ||
273 | errors++; | ||
274 | } | ||
275 | } | ||
276 | if (errors) | ||
277 | exit (EX_USAGE); | ||
278 | match->regc = argc; | ||
279 | match->regs = regs; | ||
280 | } | ||
281 | |||
282 | static void | ||
283 | free_regexes (struct regmatch *match) | ||
284 | { | ||
285 | int i; | ||
286 | for (i = 0; i < match->regc; i++) | ||
287 | regfree (&match->regs[i]); | ||
288 | free (match->regs); | ||
289 | } | ||
290 | |||
291 | static void | ||
292 | list_database (int argc, char **argv) | ||
293 | { | ||
294 | mu_dbm_file_t db = open_db_file (MU_STREAM_READ); | ||
295 | struct print_data pdata; | ||
296 | |||
297 | pdata.db = db; | ||
298 | pdata.stream = mu_strout; | ||
299 | |||
300 | if (argc == 0) | ||
301 | iterate_database (db, NULL, NULL, print_action, &pdata); | ||
302 | else | ||
303 | { | ||
304 | switch (key_type) | ||
305 | { | ||
306 | case key_literal: | ||
307 | iterate_database (db, match_literal, argv, print_action, &pdata); | ||
308 | break; | ||
309 | |||
310 | case key_glob: | ||
311 | iterate_database (db, match_glob, argv, print_action, &pdata); | ||
312 | break; | ||
313 | |||
314 | case key_regex: | ||
315 | { | ||
316 | struct regmatch m; | ||
317 | compile_regexes (argc, argv, &m); | ||
318 | iterate_database (db, match_regex, &m, print_action, &pdata); | ||
319 | free_regexes (&m); | ||
320 | } | ||
321 | } | ||
322 | } | ||
323 | mu_dbm_destroy (&db); | ||
324 | } | ||
325 | |||
326 | void | ||
327 | add_records (int mode, int replace) | ||
328 | { | ||
329 | mu_dbm_file_t db; | ||
330 | mu_stream_t input, flt; | ||
331 | const char *flt_argv[] = { "inline-comment", "#", "-S", "-i", "#", NULL }; | ||
332 | char *buf = NULL; | ||
333 | size_t size = 0; | ||
334 | size_t len; | ||
335 | unsigned long line; | ||
336 | int rc; | ||
337 | |||
338 | if (input_file) | ||
339 | { | ||
340 | rc = mu_file_stream_create (&input, input_file, MU_STREAM_READ); | ||
341 | if (rc) | ||
342 | { | ||
343 | mu_error (_("cannot open input file %s: %s"), input_file, | ||
344 | mu_strerror (rc)); | ||
345 | exit (EX_UNAVAILABLE); | ||
346 | } | ||
347 | } | ||
348 | else | ||
349 | input = mu_strin; | ||
350 | |||
351 | rc = mu_filter_create_args (&flt, input, "inline-comment", | ||
352 | MU_ARRAY_SIZE (flt_argv) - 1, flt_argv, | ||
353 | MU_FILTER_DECODE, MU_STREAM_READ); | ||
354 | if (rc) | ||
355 | { | ||
356 | mu_diag_funcall (MU_DIAG_ERROR, "mu_filter_create_args", input_file, rc); | ||
357 | exit (EX_UNAVAILABLE); | ||
358 | } | ||
359 | mu_stream_unref (input); | ||
360 | input = flt; | ||
361 | |||
362 | db = open_db_file (mode); | ||
363 | |||
364 | line = 1; | ||
365 | if (!input_file) | ||
366 | input_file = "<stdin>"; | ||
367 | while ((rc = mu_stream_getline (input, &buf, &size, &len)) == 0 | ||
368 | && len > 0) | ||
369 | { | ||
370 | struct mu_dbm_datum key, contents; | ||
371 | char *kstr, *val; | ||
372 | |||
373 | mu_rtrim_class (buf, MU_CTYPE_ENDLN); | ||
374 | if (buf[0] == '#') | ||
375 | { | ||
376 | line = strtoul (buf + 1, NULL, 10); | ||
377 | continue; | ||
378 | } | ||
379 | kstr = mu_str_stripws (buf); | ||
380 | val = mu_str_skip_class_comp (kstr, MU_CTYPE_SPACE); | ||
381 | *val++ = 0; | ||
382 | val = mu_str_skip_class (val, MU_CTYPE_SPACE); | ||
383 | if (*val == 0) | ||
384 | { | ||
385 | mu_error (_("%s:%lu: malformed line"), input_file, line); | ||
386 | line++; | ||
387 | continue; | ||
388 | } | ||
389 | |||
390 | init_datum (&key, kstr); | ||
391 | init_datum (&contents, val); | ||
392 | |||
393 | rc = mu_dbm_store (db, &key, &contents, replace); | ||
394 | if (rc) | ||
395 | mu_error (_("%s:%lu: cannot store datum: %s"), | ||
396 | input_file, line, | ||
397 | rc == MU_ERR_FAILURE ? | ||
398 | mu_dbm_strerror (db) : mu_strerror (rc)); | ||
399 | line++; | ||
400 | } | ||
401 | mu_dbm_destroy (&db); | ||
402 | |||
403 | mu_stream_unref (input); | ||
404 | } | ||
405 | |||
406 | static void | ||
407 | create_database () | ||
408 | { | ||
409 | if (copy_permissions) | ||
410 | { | ||
411 | struct stat st; | ||
412 | |||
413 | if (!input_file) | ||
414 | { | ||
415 | mu_error (_("--copy-permissions used without --file")); | ||
416 | exit (EX_USAGE); | ||
417 | } | ||
418 | if (stat (input_file, &st)) | ||
419 | { | ||
420 | mu_diag_funcall (MU_DIAG_ERROR, "stat", input_file, errno); | ||
421 | exit (EX_UNAVAILABLE); | ||
422 | } | ||
423 | owner_uid = st.st_uid; | ||
424 | owner_gid = st.st_gid; | ||
425 | permissions = st.st_mode & 0777; | ||
426 | } | ||
427 | else if (auth) | ||
428 | { | ||
429 | if (owner_uid == -1) | ||
430 | owner_uid = auth->uid; | ||
431 | if (owner_gid == -1) | ||
432 | owner_gid = auth->gid; | ||
433 | } | ||
434 | add_records (MU_STREAM_CREAT, 0); | ||
435 | } | ||
436 | |||
437 | static int | ||
438 | store_to_list (struct mu_dbm_datum const *key, void *data) | ||
439 | { | ||
440 | int rc; | ||
441 | mu_list_t list = data; | ||
442 | char *p = xmalloc (key->mu_dsize + 1); | ||
443 | memcpy (p, key->mu_dptr, key->mu_dsize); | ||
444 | p[key->mu_dsize] = 0; | ||
445 | rc = mu_list_append (list, p); | ||
446 | if (rc) | ||
447 | { | ||
448 | mu_diag_funcall (MU_DIAG_ERROR, "mu_list_append", p, rc); | ||
449 | exit (EX_SOFTWARE); | ||
450 | } | ||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static int | ||
455 | do_delete (void *item, void *data) | ||
456 | { | ||
457 | char *str = item; | ||
458 | mu_dbm_file_t db = data; | ||
459 | struct mu_dbm_datum key; | ||
460 | int rc; | ||
461 | |||
462 | init_datum (&key, str); | ||
463 | rc = mu_dbm_delete (db, &key); | ||
464 | if (rc == MU_ERR_NOENT) | ||
465 | { | ||
466 | mu_error (_("cannot remove record for %s: %s"), | ||
467 | str, mu_strerror (rc)); | ||
468 | } | ||
469 | else if (rc) | ||
470 | { | ||
471 | mu_error (_("cannot remove record for %s: %s"), | ||
472 | str, mu_dbm_strerror (db)); | ||
473 | if (rc != MU_ERR_NOENT) | ||
474 | exit (EX_UNAVAILABLE); | ||
475 | } | ||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static void | ||
480 | delete_database (int argc, char **argv) | ||
481 | { | ||
482 | mu_dbm_file_t db = open_db_file (MU_STREAM_RDWR); | ||
483 | mu_list_t templist = NULL; | ||
484 | int rc, i; | ||
485 | |||
486 | if (argc == 0) | ||
487 | { | ||
488 | mu_error (_("not enough arguments for delete")); | ||
489 | exit (EX_USAGE); | ||
490 | } | ||
491 | |||
492 | /* Collect matching keys */ | ||
493 | rc = mu_list_create (&templist); | ||
494 | if (rc) | ||
495 | { | ||
496 | mu_diag_funcall (MU_DIAG_ERROR, "mu_list_create", NULL, rc); | ||
497 | exit (EX_SOFTWARE); | ||
498 | } | ||
499 | mu_list_set_destroy_item (templist, mu_list_free_item); | ||
500 | switch (key_type) | ||
501 | { | ||
502 | case key_literal: | ||
503 | for (i = 0; i < argc; i++) | ||
504 | { | ||
505 | char *p = xstrdup (argv[i]); | ||
506 | rc = mu_list_append (templist, p); | ||
507 | if (rc) | ||
508 | { | ||
509 | mu_diag_funcall (MU_DIAG_ERROR, "mu_list_append", p, rc); | ||
510 | exit (EX_SOFTWARE); | ||
511 | } | ||
512 | } | ||
513 | break; | ||
514 | |||
515 | case key_glob: | ||
516 | iterate_database (db, match_glob, argv, | ||
517 | store_to_list, templist); | ||
518 | break; | ||
519 | |||
520 | case key_regex: | ||
521 | { | ||
522 | struct regmatch m; | ||
523 | |||
524 | compile_regexes (argc, argv, &m); | ||
525 | iterate_database (db, match_regex, &m, store_to_list, templist); | ||
526 | free_regexes (&m); | ||
527 | } | ||
528 | } | ||
529 | mu_list_do (templist, do_delete, db); | ||
530 | mu_list_destroy (&templist); | ||
531 | mu_dbm_destroy (&db); | ||
532 | } | ||
533 | |||
534 | /* | ||
535 | mu dbm --create a.db < input | ||
536 | mu dbm --list a.db | ||
537 | mu dbm --delete a.db key [key...] | ||
538 | mu dbm --add a.db < input | ||
539 | mu dbm --replace a.db < input | ||
540 | */ | ||
541 | |||
542 | static struct argp_option dbm_options[] = { | ||
543 | { NULL, 0, NULL, 0, N_("Operation mode"), 0}, | ||
544 | { "create", 'c', NULL, 0, N_("create the database") }, | ||
545 | { "list", 'l', NULL, 0, N_("list contents of the database") }, | ||
546 | { "delete", 'd', NULL, 0, N_("delete specified keys from the database") }, | ||
547 | { "add", 'a', NULL, 0, N_("add records to the database") }, | ||
548 | { "replace",'r', NULL, 0, N_("add records replacing ones with matching keys") }, | ||
549 | |||
550 | { NULL, 0, NULL, 0, N_("Create modifiers"), 0}, | ||
551 | { "file", 'f', N_("FILE"), 0, | ||
552 | N_("read input from FILE (with --create, --delete, --add and --replace)") }, | ||
553 | { "permissions", 'p', N_("NUM"), 0, | ||
554 | N_("set permissions on the created database") }, | ||
555 | { "user", 'u', N_("USER"), 0, | ||
556 | N_("set database owner name") }, | ||
557 | { "group", 'g', N_("GROUP"), 0, | ||
558 | N_("set database owner group") }, | ||
559 | { "copy-permissions", 'P', NULL, 0, | ||
560 | N_("copy database permissions and ownership from the input file") }, | ||
561 | { NULL, 0, NULL, 0, N_("List and Delete modifiers"), 0}, | ||
562 | { "glob", 'G', NULL, 0, | ||
563 | N_("treat keys as globbing patterns") }, | ||
564 | { "regex", 'R', NULL, 0, | ||
565 | N_("treat keys as regular expressions") }, | ||
566 | { "ignore-case", 'i', NULL, 0, | ||
567 | N_("case-insensitive matches") }, | ||
568 | { NULL, 0, NULL, 0, N_("Data length modifiers"), 0 }, | ||
569 | { "count-null", 'N', NULL, 0, | ||
570 | N_("data length accounts for terminating zero") }, | ||
571 | { "no-count-null", 'n', NULL, 0, | ||
572 | N_("data length does not account for terminating zero") }, | ||
573 | { NULL } | ||
574 | }; | ||
575 | |||
576 | static error_t | ||
577 | dbm_parse_opt (int key, char *arg, struct argp_state *state) | ||
578 | { | ||
579 | switch (key) | ||
580 | { | ||
581 | case 'c': | ||
582 | mode = mode_create; | ||
583 | break; | ||
584 | |||
585 | case 'l': | ||
586 | mode = mode_list; | ||
587 | break; | ||
588 | |||
589 | case 'd': | ||
590 | mode = mode_delete; | ||
591 | break; | ||
592 | |||
593 | case 'a': | ||
594 | mode = mode_add; | ||
595 | break; | ||
596 | |||
597 | case 'r': | ||
598 | mode = mode_replace; | ||
599 | break; | ||
600 | |||
601 | case 'f': | ||
602 | input_file = arg; | ||
603 | break; | ||
604 | |||
605 | case 'p': | ||
606 | { | ||
607 | char *p; | ||
608 | unsigned long d = strtoul (arg, &p, 8); | ||
609 | if (*p || (d & ~0777)) | ||
610 | argp_error (state, _("invalid file mode: %s"), arg); | ||
611 | permissions = d; | ||
612 | } | ||
613 | break; | ||
614 | |||
615 | case 'P': | ||
616 | copy_permissions = 1; | ||
617 | break; | ||
618 | |||
619 | case 'u': | ||
620 | auth = mu_get_auth_by_name (arg); | ||
621 | if (!auth) | ||
622 | { | ||
623 | char *p; | ||
624 | unsigned long n = strtoul (arg, &p, 0); | ||
625 | if (*p == 0) | ||
626 | owner_uid = n; | ||
627 | else | ||
628 | argp_error (state, _("no such user: %s"), arg); | ||
629 | } | ||
630 | break; | ||
631 | |||
632 | case 'g': | ||
633 | { | ||
634 | struct group *gr = getgrnam (arg); | ||
635 | if (!gr) | ||
636 | { | ||
637 | char *p; | ||
638 | unsigned long n = strtoul (arg, &p, 0); | ||
639 | if (*p == 0) | ||
640 | owner_gid = n; | ||
641 | else | ||
642 | argp_error (state, _("no such group: %s"), arg); | ||
643 | } | ||
644 | else | ||
645 | owner_gid = gr->gr_gid; | ||
646 | } | ||
647 | break; | ||
648 | |||
649 | case 'G': | ||
650 | key_type = key_glob; | ||
651 | break; | ||
652 | |||
653 | case 'R': | ||
654 | key_type = key_regex; | ||
655 | break; | ||
656 | |||
657 | case 'i': | ||
658 | case_sensitive = 0; | ||
659 | break; | ||
660 | |||
661 | case 'N': | ||
662 | include_zero = 1; | ||
663 | break; | ||
664 | |||
665 | case 'n': | ||
666 | include_zero = 0; | ||
667 | break; | ||
668 | |||
669 | default: | ||
670 | return ARGP_ERR_UNKNOWN; | ||
671 | } | ||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | static struct argp dbm_argp = { | ||
676 | dbm_options, | ||
677 | dbm_parse_opt, | ||
678 | dbm_args_doc, | ||
679 | dbm_doc, | ||
680 | NULL, | ||
681 | NULL, | ||
682 | NULL | ||
683 | }; | ||
684 | |||
685 | int | ||
686 | mutool_dbm (int argc, char **argv) | ||
687 | { | ||
688 | int index; | ||
689 | |||
690 | if (argp_parse (&dbm_argp, argc, argv, ARGP_IN_ORDER, &index, NULL)) | ||
691 | return 1; | ||
692 | |||
693 | argc -= index; | ||
694 | argv += index; | ||
695 | |||
696 | if (argc == 0) | ||
697 | { | ||
698 | mu_error (_("database name not given")); | ||
699 | exit (EX_USAGE); | ||
700 | } | ||
701 | db_name = *argv++; | ||
702 | --argc; | ||
703 | |||
704 | switch (mode) | ||
705 | { | ||
706 | case mode_list: | ||
707 | list_database (argc, argv); | ||
708 | break; | ||
709 | |||
710 | case mode_create: | ||
711 | if (argc) | ||
712 | { | ||
713 | mu_error (_("too many arguments for create")); | ||
714 | exit (EX_USAGE); | ||
715 | } | ||
716 | create_database (); | ||
717 | break; | ||
718 | |||
719 | case mode_delete: | ||
720 | delete_database (argc, argv); | ||
721 | break; | ||
722 | |||
723 | case mode_add: | ||
724 | if (argc) | ||
725 | { | ||
726 | mu_error (_("too many arguments for add")); | ||
727 | exit (EX_USAGE); | ||
728 | } | ||
729 | add_records (MU_STREAM_RDWR, 0); | ||
730 | break; | ||
731 | |||
732 | case mode_replace: | ||
733 | if (argc) | ||
734 | { | ||
735 | mu_error (_("too many arguments for replace")); | ||
736 | exit (EX_USAGE); | ||
737 | } | ||
738 | add_records (MU_STREAM_RDWR, 1); | ||
739 | break; | ||
740 | } | ||
741 | return 0; | ||
742 | } | ||
743 | |||
744 | /* | ||
745 | MU Setup: dbm | ||
746 | mu-handler: mutool_dbm | ||
747 | mu-docstring: dbm_docstring | ||
748 | End MU Setup: | ||
749 | */ | ||
750 | |||
751 |
... | @@ -38,36 +38,52 @@ static struct argp ldflags_argp = { | ... | @@ -38,36 +38,52 @@ static struct argp ldflags_argp = { |
38 | 38 | ||
39 | 39 | ||
40 | #ifdef WITH_TLS | 40 | #ifdef WITH_TLS |
41 | # define NEEDAUTH 1 | 41 | # define NEEDAUTH "-lmu_auth " AUTHLIBS |
42 | #else | 42 | #else |
43 | # define NEEDAUTH 0 | 43 | # define NEEDAUTH NULL |
44 | #endif | 44 | #endif |
45 | #define NOTALL 2 | 45 | #define NOTALL 1 |
46 | 46 | ||
47 | struct lib_descr { | 47 | struct lib_descr { |
48 | char *name; | 48 | char *name; |
49 | char *libname; | 49 | char *libname; |
50 | int weight; | ||
50 | int flags; | 51 | int flags; |
51 | } lib_descr[] = { | 52 | } lib_descr[] = { |
52 | { "mbox", "mu_mbox", 0 }, | 53 | { "mbox", "-lmu_mbox", 0 }, |
53 | #ifdef ENABLE_MH | 54 | #ifdef ENABLE_MH |
54 | { "mh", "mu_mh", 0 }, | 55 | { "mh", "-lmu_mh", 0 }, |
55 | #endif | 56 | #endif |
56 | #ifdef ENABLE_MAILDIR | 57 | #ifdef ENABLE_MAILDIR |
57 | { "maildir","mu_maildir", 0 }, | 58 | { "maildir", "-lmu_maildir", 0 }, |
58 | #endif | 59 | #endif |
59 | #ifdef ENABLE_IMAP | 60 | #ifdef ENABLE_IMAP |
60 | { "imap", "mu_imap", NEEDAUTH }, | 61 | { "imap", "-lmu_imap", 0 }, |
62 | { "imap", NEEDAUTH, 2 }, | ||
61 | #endif | 63 | #endif |
62 | #ifdef ENABLE_POP | 64 | #ifdef ENABLE_POP |
63 | { "pop", "mu_pop", NEEDAUTH }, | 65 | { "pop", "-lmu_pop", 0 }, |
66 | { "pop", NEEDAUTH, 2 }, | ||
64 | #endif | 67 | #endif |
65 | #ifdef ENABLE_NNTP | 68 | #ifdef ENABLE_NNTP |
66 | { "nntp", "mu_nntp", 0 }, | 69 | { "nntp", "-lmu_nntp", 0 }, |
67 | #endif | 70 | #endif |
68 | { "mailer", "mu_mailer", 0 }, | 71 | #ifdef ENABLE_DBM |
69 | { "sieve", "mu_sieve", NOTALL }, | 72 | { "dbm", "-lmu_dbm", 0 }, |
70 | { "compat", "mu_compat" }, | 73 | { "dbm", DBMLIBS, 2 }, |
74 | #endif | ||
75 | { "mailer", "-lmu_mailer", 0 }, | ||
76 | { "sieve", "-lmu_sieve", 0, NOTALL }, | ||
77 | { "compat", "-lmu_compat", 0 }, | ||
78 | { "auth", "-lmu_auth " AUTHLIBS, 2 }, | ||
79 | #ifdef WITH_GUILE | ||
80 | { "guile", "-lmu_scm " GUILE_LIBS, -1, NOTALL }, | ||
81 | #endif | ||
82 | #ifdef WITH_PYTHON | ||
83 | { "python", "-lmu_py " PYTHON_LIBS, -1, NOTALL }, | ||
84 | #endif | ||
85 | { "cfg", "-lmu_cfg", -1, NOTALL }, | ||
86 | { "argp", "-lmu_argp", -2, NOTALL }, | ||
71 | { NULL } | 87 | { NULL } |
72 | }; | 88 | }; |
73 | 89 | ||
... | @@ -82,6 +98,9 @@ void | ... | @@ -82,6 +98,9 @@ void |
82 | add_entry (int level, char *ptr) | 98 | add_entry (int level, char *ptr) |
83 | { | 99 | { |
84 | int i; | 100 | int i; |
101 | |||
102 | if (!ptr || !*ptr) | ||
103 | return; | ||
85 | if (nentry >= sizeof(lib_entry)/sizeof(lib_entry[0])) | 104 | if (nentry >= sizeof(lib_entry)/sizeof(lib_entry[0])) |
86 | { | 105 | { |
87 | mu_error (_("too many arguments")); | 106 | mu_error (_("too many arguments")); |
... | @@ -122,7 +141,6 @@ int | ... | @@ -122,7 +141,6 @@ int |
122 | mutool_ldflags (int argc, char **argv) | 141 | mutool_ldflags (int argc, char **argv) |
123 | { | 142 | { |
124 | int i, j; | 143 | int i, j; |
125 | char *ptr; | ||
126 | 144 | ||
127 | if (argp_parse (&ldflags_argp, argc, argv, ARGP_IN_ORDER, &i, NULL)) | 145 | if (argp_parse (&ldflags_argp, argc, argv, ARGP_IN_ORDER, &i, NULL)) |
128 | return 1; | 146 | return 1; |
... | @@ -140,21 +158,7 @@ mutool_ldflags (int argc, char **argv) | ... | @@ -140,21 +158,7 @@ mutool_ldflags (int argc, char **argv) |
140 | 158 | ||
141 | for ( ; argc > 0; argc--, argv++) | 159 | for ( ; argc > 0; argc--, argv++) |
142 | { | 160 | { |
143 | if (strcmp (argv[0], "auth") == 0) | 161 | if (strcmp (argv[0], "all") == 0) |
144 | add_entry (2, "-lmu_auth " AUTHLIBS); | ||
145 | #ifdef WITH_GUILE | ||
146 | else if (strcmp (argv[0], "guile") == 0) | ||
147 | add_entry (-1, "-lmu_scm " GUILE_LIBS); | ||
148 | #endif | ||
149 | #ifdef WITH_PYTHON | ||
150 | else if (strcmp (argv[0], "python") == 0) | ||
151 | add_entry (-1, "-lmu_py " PYTHON_LIBS); | ||
152 | #endif | ||
153 | else if (strcmp (argv[0], "cfg") == 0) | ||
154 | add_entry (-1, "-lmu_cfg"); | ||
155 | else if (strcmp (argv[0], "argp") == 0) | ||
156 | add_entry (-2, "-lmu_argp"); | ||
157 | else if (strcmp (argv[0], "all") == 0) | ||
158 | { | 162 | { |
159 | struct lib_descr *p; | 163 | struct lib_descr *p; |
160 | 164 | ||
... | @@ -162,28 +166,24 @@ mutool_ldflags (int argc, char **argv) | ... | @@ -162,28 +166,24 @@ mutool_ldflags (int argc, char **argv) |
162 | { | 166 | { |
163 | if (p->flags & NOTALL) | 167 | if (p->flags & NOTALL) |
164 | continue; | 168 | continue; |
165 | mu_asprintf (&ptr, "-l%s", p->libname); | 169 | add_entry (p->weight, p->libname); |
166 | add_entry (0, ptr); | ||
167 | if (p->flags & NEEDAUTH) | ||
168 | add_entry (2, "-lmu_auth " AUTHLIBS); | ||
169 | } | 170 | } |
170 | } | 171 | } |
171 | else | 172 | else |
172 | { | 173 | { |
173 | struct lib_descr *p; | 174 | struct lib_descr *p; |
175 | int found = 0; | ||
174 | 176 | ||
175 | for (p = lib_descr; p->name; p++) | 177 | for (p = lib_descr; p->name; p++) |
176 | if (mu_c_strcasecmp (p->name, argv[0]) == 0) | ||
177 | break; | ||
178 | |||
179 | if (p->name) | ||
180 | { | 178 | { |
181 | mu_asprintf (&ptr, "-l%s", p->libname); | 179 | if (mu_c_strcasecmp (p->name, argv[0]) == 0) |
182 | add_entry (0, ptr); | 180 | { |
183 | if (p->flags & NEEDAUTH) | 181 | add_entry (p->weight, p->libname); |
184 | add_entry (2, "-lmu_auth " AUTHLIBS); | 182 | found = 1; |
183 | } | ||
185 | } | 184 | } |
186 | else | 185 | |
186 | if (!found) | ||
187 | { | 187 | { |
188 | mu_error (_("unknown keyword: %s"), argv[0]); | 188 | mu_error (_("unknown keyword: %s"), argv[0]); |
189 | return 1; | 189 | return 1; | ... | ... |
... | @@ -46,6 +46,10 @@ pop3d_SOURCES =\ | ... | @@ -46,6 +46,10 @@ pop3d_SOURCES =\ |
46 | uidl.c\ | 46 | uidl.c\ |
47 | user.c | 47 | user.c |
48 | 48 | ||
49 | if MU_COND_DBM | ||
50 | LIBMU_DBM=../libmu_dbm/libmu_dbm.la | ||
51 | endif | ||
52 | |||
49 | pop3d_LDADD = \ | 53 | pop3d_LDADD = \ |
50 | ${MU_APP_LIBRARIES}\ | 54 | ${MU_APP_LIBRARIES}\ |
51 | ${MU_LIB_MBOX}\ | 55 | ${MU_LIB_MBOX}\ |
... | @@ -54,15 +58,25 @@ pop3d_LDADD = \ | ... | @@ -54,15 +58,25 @@ pop3d_LDADD = \ |
54 | ${MU_LIB_AUTH}\ | 58 | ${MU_LIB_AUTH}\ |
55 | @MU_AUTHLIBS@ \ | 59 | @MU_AUTHLIBS@ \ |
56 | ${MU_LIB_MAILUTILS}\ | 60 | ${MU_LIB_MAILUTILS}\ |
57 | @MU_COMMON_LIBRARIES@ @TCPWRAP_LIBRARIES@ | 61 | @MU_COMMON_LIBRARIES@\ |
62 | ${LIBMU_DBM}\ | ||
63 | @DBMLIBS@\ | ||
64 | @TCPWRAP_LIBRARIES@ | ||
58 | 65 | ||
59 | popauth_SOURCES = popauth.c | 66 | popauth_SOURCES = popauth.c |
60 | popauth_LDADD = ${MU_APP_LIBRARIES} ${MU_LIB_MAILUTILS} @MU_COMMON_LIBRARIES@ | 67 | popauth_LDADD = \ |
68 | ${MU_APP_LIBRARIES}\ | ||
69 | ${MU_LIB_MAILUTILS}\ | ||
70 | @MU_COMMON_LIBRARIES@\ | ||
71 | ${LIBMU_DBM}\ | ||
72 | @DBMLIBS@ | ||
73 | |||
61 | pop3d_DEPENDENCIES = \ | 74 | pop3d_DEPENDENCIES = \ |
62 | @MU_AUTHLIBS_DEPENDENCY@ \ | 75 | @MU_AUTHLIBS_DEPENDENCY@ \ |
63 | ../lib/libmuaux.a \ | 76 | ../lib/libmuaux.a \ |
64 | ${MU_LIB_MBOX}\ | 77 | ${MU_LIB_MBOX}\ |
65 | ${MU_LIB_MH}\ | 78 | ${MU_LIB_MH}\ |
66 | ${MU_LIB_MAILDIR}\ | 79 | ${MU_LIB_MAILDIR}\ |
67 | ${MU_LIB_MAILUTILS} | 80 | ${MU_LIB_MAILUTILS}\ |
81 | ${LIBMU_DBM} | ||
68 | 82 | ... | ... |
... | @@ -43,59 +43,85 @@ pop3d_apopuser (const char *user) | ... | @@ -43,59 +43,85 @@ pop3d_apopuser (const char *user) |
43 | { | 43 | { |
44 | char *password = NULL; | 44 | char *password = NULL; |
45 | 45 | ||
46 | #ifdef USE_DBM | 46 | #ifdef ENABLE_DBM |
47 | { | 47 | { |
48 | size_t len; | 48 | size_t len; |
49 | DBM_FILE db; | 49 | mu_dbm_file_t db; |
50 | DBM_DATUM key, data; | 50 | struct mu_dbm_datum key, data; |
51 | int rc; | ||
51 | 52 | ||
52 | int rc = mu_dbm_open (APOP_PASSFILE, &db, MU_STREAM_READ, 0600); | 53 | rc = mu_dbm_create (APOP_PASSFILE, &db); |
54 | if (rc) | ||
55 | { | ||
56 | mu_diag_output (MU_DIAG_ERROR, _("unable to create APOP db")); | ||
57 | return NULL; | ||
58 | } | ||
59 | |||
60 | rc = mu_dbm_safety_check (db); | ||
61 | if (rc) | ||
62 | { | ||
63 | mu_diag_output (MU_DIAG_ERROR, | ||
64 | _("APOP file %s fails safety check: %s"), | ||
65 | APOP_PASSFILE, mu_strerror (rc)); | ||
66 | mu_dbm_destroy (&db); | ||
67 | return NULL; | ||
68 | } | ||
69 | |||
70 | rc = mu_dbm_open (db, MU_STREAM_READ, 0600); | ||
53 | if (rc) | 71 | if (rc) |
54 | { | 72 | { |
55 | mu_diag_output (MU_DIAG_ERROR, _("unable to open APOP db: %s"), | 73 | mu_diag_output (MU_DIAG_ERROR, _("unable to open APOP db: %s"), |
56 | mu_strerror (errno)); | 74 | mu_strerror (rc)); |
57 | return NULL; | 75 | return NULL; |
58 | } | 76 | } |
59 | 77 | ||
60 | memset (&key, 0, sizeof key); | 78 | memset (&key, 0, sizeof key); |
61 | memset (&data, 0, sizeof data); | 79 | memset (&data, 0, sizeof data); |
62 | 80 | ||
63 | MU_DATUM_PTR (key) = (void*) user; | 81 | key.mu_dptr = (void *)user; |
64 | MU_DATUM_SIZE (key) = strlen (user); | 82 | key.mu_dsize = strlen (user); |
65 | 83 | ||
66 | rc = mu_dbm_fetch (db, key, &data); | 84 | rc = mu_dbm_fetch (db, &key, &data); |
67 | mu_dbm_close (db); | 85 | if (rc == MU_ERR_NOENT) |
68 | if (rc) | 86 | { |
87 | mu_dbm_destroy (&db); | ||
88 | return NULL; | ||
89 | } | ||
90 | else if (rc) | ||
69 | { | 91 | { |
70 | mu_diag_output (MU_DIAG_ERROR, | 92 | mu_diag_output (MU_DIAG_ERROR, |
71 | _("cannot fetch APOP data: %s"), mu_strerror (errno)); | 93 | _("cannot fetch APOP data: %s"), |
94 | mu_dbm_strerror (db)); | ||
95 | mu_dbm_destroy (&db); | ||
72 | return NULL; | 96 | return NULL; |
73 | } | 97 | } |
74 | len = MU_DATUM_SIZE (data); | 98 | mu_dbm_destroy (&db); |
99 | len = data.mu_dsize; | ||
75 | password = malloc (len + 1); | 100 | password = malloc (len + 1); |
76 | if (password == NULL) | 101 | if (password == NULL) |
77 | { | 102 | { |
78 | mu_dbm_datum_free (&data); | 103 | mu_dbm_datum_free (&data); |
79 | return NULL; | 104 | return NULL; |
80 | } | 105 | } |
81 | memcpy (password, MU_DATUM_PTR (data), len); | 106 | memcpy (password, data.mu_dptr, len); |
82 | password[len] = 0; | 107 | password[len] = 0; |
83 | mu_dbm_datum_free (&data); | 108 | mu_dbm_datum_free (&data); |
84 | return password; | 109 | return password; |
85 | } | 110 | } |
86 | #else /* !USE_DBM */ | 111 | #else /* !ENABLE_DBM */ |
87 | { | 112 | { |
88 | char *buf = NULL; | 113 | char *buf = NULL; |
89 | size_t size = 0; | 114 | size_t size = 0; |
90 | size_t ulen; | 115 | size_t ulen; |
91 | FILE *apop_file; | 116 | FILE *apop_file; |
92 | 117 | ||
93 | if (mu_check_perm (APOP_PASSFILE, 0600)) | 118 | /* FIXME */ |
94 | { | 119 | /* if (mu_check_perm (APOP_PASSFILE, 0600)) */ |
95 | mu_diag_output (MU_DIAG_INFO, | 120 | /* { */ |
96 | _("bad permissions on APOP password file")); | 121 | /* mu_diag_output (MU_DIAG_INFO, */ |
97 | return NULL; | 122 | /* _("bad permissions on APOP password file")); */ |
98 | } | 123 | /* return NULL; */ |
124 | /* } */ | ||
99 | 125 | ||
100 | apop_file = fopen (APOP_PASSFILE, "r"); | 126 | apop_file = fopen (APOP_PASSFILE, "r"); |
101 | if (apop_file == NULL) | 127 | if (apop_file == NULL) | ... | ... |
... | @@ -113,58 +113,72 @@ write_popbull_file (size_t num) | ... | @@ -113,58 +113,72 @@ write_popbull_file (size_t num) |
113 | return rc; | 113 | return rc; |
114 | } | 114 | } |
115 | 115 | ||
116 | #ifdef USE_DBM | 116 | #ifdef ENABLE_DBM |
117 | int | 117 | int |
118 | read_bulletin_db (size_t *pnum) | 118 | read_bulletin_db (size_t *pnum) |
119 | { | 119 | { |
120 | DBM_FILE db; | 120 | mu_dbm_file_t db; |
121 | DBM_DATUM key, data; | 121 | struct mu_dbm_datum key, data; |
122 | int rc; | 122 | int rc; |
123 | char sbuf[128]; | 123 | char sbuf[128]; |
124 | char *bufptr; | 124 | char *bufptr; |
125 | char *buf = NULL; | 125 | char *buf = NULL; |
126 | size_t s; | 126 | size_t s; |
127 | char *p; | 127 | char *p; |
128 | 128 | ||
129 | rc = mu_dbm_open (bulletin_db_name, &db, MU_STREAM_READ, 0660); | 129 | rc = mu_dbm_create (bulletin_db_name, &db); |
130 | if (rc) | 130 | if (rc) |
131 | { | 131 | { |
132 | if (errno == ENOENT) | 132 | mu_diag_output (MU_DIAG_ERROR, _("unable to create bulletin db")); |
133 | return rc; | ||
134 | } | ||
135 | |||
136 | rc = mu_dbm_safety_check (db); | ||
137 | if (rc) | ||
138 | { | ||
139 | if (rc == ENOENT) | ||
133 | { | 140 | { |
134 | *pnum = 0; | 141 | *pnum = 0; |
135 | return 0; | 142 | return 0; |
136 | } | 143 | } |
137 | else | 144 | mu_diag_output (MU_DIAG_ERROR, |
138 | { | 145 | _("bulletin db %s fails safety check: %s"), |
139 | mu_error (_("unable to open bulletin db for reading: %s"), | 146 | bulletin_db_name, mu_strerror (rc)); |
140 | mu_strerror (errno)); | 147 | mu_dbm_destroy (&db); |
141 | return rc; | 148 | return 1; |
142 | } | 149 | } |
150 | |||
151 | rc = mu_dbm_open (db, MU_STREAM_READ, 0660); | ||
152 | if (rc) | ||
153 | { | ||
154 | mu_error (_("unable to open bulletin db for reading: %s"), | ||
155 | mu_strerror (rc)); | ||
156 | return rc; | ||
143 | } | 157 | } |
144 | 158 | ||
145 | memset (&key, 0, sizeof key); | 159 | memset (&key, 0, sizeof key); |
146 | memset (&data, 0, sizeof data); | 160 | memset (&data, 0, sizeof data); |
147 | 161 | ||
148 | MU_DATUM_PTR(key) = username; | 162 | key.mu_dptr = username; |
149 | MU_DATUM_SIZE(key) = strlen (username); | 163 | key.mu_dsize = strlen (username); |
150 | 164 | ||
151 | rc = mu_dbm_fetch (db, key, &data); | 165 | rc = mu_dbm_fetch (db, &key, &data); |
152 | 166 | ||
153 | if (rc) | 167 | if (rc == MU_ERR_NOENT) |
168 | { | ||
169 | *pnum = 0; | ||
170 | return 0; | ||
171 | } | ||
172 | else if (rc) | ||
154 | { | 173 | { |
155 | int ec = errno; | ||
156 | if (ec == ENOENT) | ||
157 | { | ||
158 | *pnum = 0; | ||
159 | return 0; | ||
160 | } | ||
161 | mu_error (_("cannot fetch bulletin db data: %s"), | 174 | mu_error (_("cannot fetch bulletin db data: %s"), |
162 | mu_strerror (ec)); | 175 | mu_dbm_strerror (db)); |
163 | mu_dbm_close (db); | 176 | mu_dbm_destroy (&db); |
164 | return 1; | 177 | return 1; |
165 | } | 178 | } |
179 | mu_dbm_destroy (&db); | ||
166 | 180 | ||
167 | s = MU_DATUM_SIZE (data); | 181 | s = data.mu_dsize; |
168 | if (s < sizeof sbuf) | 182 | if (s < sizeof sbuf) |
169 | bufptr = sbuf; | 183 | bufptr = sbuf; |
170 | else | 184 | else |
... | @@ -172,16 +186,15 @@ read_bulletin_db (size_t *pnum) | ... | @@ -172,16 +186,15 @@ read_bulletin_db (size_t *pnum) |
172 | buf = malloc (s + 1); | 186 | buf = malloc (s + 1); |
173 | if (!buf) | 187 | if (!buf) |
174 | { | 188 | { |
175 | mu_error("%s", mu_strerror (errno)); | 189 | mu_error ("%s", mu_strerror (errno)); |
176 | return 1; | 190 | return 1; |
177 | } | 191 | } |
178 | bufptr = buf; | 192 | bufptr = buf; |
179 | } | 193 | } |
180 | 194 | ||
181 | memcpy (bufptr, MU_DATUM_PTR (data), s); | 195 | memcpy (bufptr, data.mu_dptr, s); |
182 | bufptr[s] = 0; | 196 | bufptr[s] = 0; |
183 | mu_dbm_datum_free(&data); | 197 | mu_dbm_datum_free (&data); |
184 | mu_dbm_close (db); | ||
185 | 198 | ||
186 | rc = 1; | 199 | rc = 1; |
187 | *pnum = strtoul (bufptr, &p, 0); | 200 | *pnum = strtoul (bufptr, &p, 0); |
... | @@ -189,26 +202,8 @@ read_bulletin_db (size_t *pnum) | ... | @@ -189,26 +202,8 @@ read_bulletin_db (size_t *pnum) |
189 | rc = 0; | 202 | rc = 0; |
190 | else | 203 | else |
191 | { | 204 | { |
192 | #ifdef QPOPPER_COMPAT | 205 | mu_error (_("wrong bulletin database format for `%s'"), |
193 | if (s == sizeof long) | 206 | username); |
194 | { | ||
195 | long n; | ||
196 | |||
197 | n = *(long*)MU_DATUM_PTR (data); | ||
198 | if (n >= 0) | ||
199 | { | ||
200 | mu_diag_output (MU_DIAG_INFO, | ||
201 | _("assuming bulletin database is in qpopper format")); | ||
202 | *pnum = n; | ||
203 | rc = 0; | ||
204 | } | ||
205 | } | ||
206 | else | ||
207 | #endif /* QPOPPER_COMPAT */ | ||
208 | { | ||
209 | mu_error (_("wrong bulletin database format for `%s'"), | ||
210 | username); | ||
211 | } | ||
212 | } | 207 | } |
213 | 208 | ||
214 | free (buf); | 209 | free (buf); |
... | @@ -218,41 +213,60 @@ read_bulletin_db (size_t *pnum) | ... | @@ -218,41 +213,60 @@ read_bulletin_db (size_t *pnum) |
218 | int | 213 | int |
219 | write_bulletin_db (size_t num) | 214 | write_bulletin_db (size_t num) |
220 | { | 215 | { |
221 | DBM_FILE db; | 216 | mu_dbm_file_t db; |
222 | DBM_DATUM key, data; | 217 | struct mu_dbm_datum key, data; |
223 | int rc; | 218 | int rc; |
224 | const char *p; | 219 | const char *p; |
225 | 220 | ||
226 | rc = mu_dbm_open (bulletin_db_name, &db, MU_STREAM_RDWR, 0660); | 221 | rc = mu_dbm_create (bulletin_db_name, &db); |
222 | if (rc) | ||
223 | { | ||
224 | mu_diag_output (MU_DIAG_ERROR, _("unable to create bulletin db")); | ||
225 | return rc; | ||
226 | } | ||
227 | |||
228 | rc = mu_dbm_safety_check (db); | ||
229 | if (rc && rc != ENOENT) | ||
230 | { | ||
231 | mu_diag_output (MU_DIAG_ERROR, | ||
232 | _("bulletin db %s fails safety check: %s"), | ||
233 | bulletin_db_name, mu_strerror (rc)); | ||
234 | mu_dbm_destroy (&db); | ||
235 | return rc; | ||
236 | } | ||
237 | |||
238 | rc = mu_dbm_open (db, MU_STREAM_RDWR, 0660); | ||
227 | if (rc) | 239 | if (rc) |
228 | { | 240 | { |
229 | mu_error (_("unable to open bulletin db for writing: %s"), | 241 | mu_error (_("unable to open bulletin db for writing: %s"), |
230 | mu_strerror (errno)); | 242 | mu_strerror (rc)); |
243 | mu_dbm_destroy (&db); | ||
231 | return rc; | 244 | return rc; |
232 | } | 245 | } |
233 | 246 | ||
234 | memset (&key, 0, sizeof key); | 247 | memset (&key, 0, sizeof key); |
235 | memset (&data, 0, sizeof data); | 248 | memset (&data, 0, sizeof data); |
236 | 249 | ||
237 | MU_DATUM_PTR (key) = username; | 250 | key.mu_dptr = username; |
238 | MU_DATUM_SIZE (key) = strlen (username); | 251 | key.mu_dsize = strlen (username); |
239 | p = mu_umaxtostr (0, num); | 252 | p = mu_umaxtostr (0, num); |
240 | MU_DATUM_PTR (data) = (char *) p; | 253 | data.mu_dptr = (char *) p; |
241 | MU_DATUM_SIZE (data) = strlen (p); | 254 | data.mu_dsize = strlen (p); |
242 | 255 | ||
243 | rc = mu_dbm_insert (db, key, data, 1); | 256 | rc = mu_dbm_store (db, &key, &data, 1); |
244 | if (rc) | 257 | if (rc) |
245 | mu_error (_("cannot store datum in bulletin db")); | 258 | mu_error (_("cannot store datum in bulletin db: %s"), |
246 | 259 | mu_dbm_strerror (db)); | |
247 | mu_dbm_close (db); | 260 | |
261 | mu_dbm_destroy (&db); | ||
248 | return rc; | 262 | return rc; |
249 | } | 263 | } |
250 | #endif /* USE_DBM */ | 264 | #endif /* ENABLE_DBM */ |
251 | 265 | ||
252 | int | 266 | int |
253 | get_last_delivered_num (size_t *pret) | 267 | get_last_delivered_num (size_t *pret) |
254 | { | 268 | { |
255 | #ifdef USE_DBM | 269 | #ifdef ENABLE_DBM |
256 | if (bulletin_db_name && read_bulletin_db (pret) == 0) | 270 | if (bulletin_db_name && read_bulletin_db (pret) == 0) |
257 | return 0; | 271 | return 0; |
258 | #endif | 272 | #endif |
... | @@ -262,7 +276,7 @@ get_last_delivered_num (size_t *pret) | ... | @@ -262,7 +276,7 @@ get_last_delivered_num (size_t *pret) |
262 | void | 276 | void |
263 | store_last_delivered_num (size_t num) | 277 | store_last_delivered_num (size_t num) |
264 | { | 278 | { |
265 | #ifdef USE_DBM | 279 | #ifdef ENABLE_DBM |
266 | if (bulletin_db_name && write_bulletin_db (num) == 0) | 280 | if (bulletin_db_name && write_bulletin_db (num) == 0) |
267 | return; | 281 | return; |
268 | #endif | 282 | #endif | ... | ... |
... | @@ -19,27 +19,45 @@ | ... | @@ -19,27 +19,45 @@ |
19 | 19 | ||
20 | #ifdef ENABLE_LOGIN_DELAY | 20 | #ifdef ENABLE_LOGIN_DELAY |
21 | 21 | ||
22 | static int | 22 | static mu_dbm_file_t |
23 | open_stat_db (DBM_FILE *db, int mode) | 23 | open_stat_db (int mode) |
24 | { | 24 | { |
25 | int rc = mu_dbm_open (login_stat_file, db, mode, 0660); | 25 | mu_dbm_file_t db; |
26 | int rc; | ||
27 | |||
28 | rc = mu_dbm_create (login_stat_file, &db); | ||
26 | if (rc) | 29 | if (rc) |
27 | { | 30 | { |
28 | if (rc == -1) | 31 | mu_diag_output (MU_DIAG_ERROR, _("unable to create statistics db")); |
29 | mu_diag_output (MU_DIAG_INFO, _("bad permissions on statistics db")); | 32 | return NULL; |
30 | else | 33 | } |
31 | mu_diag_output (MU_DIAG_ERROR, _("unable to open statistics db: %s"), | 34 | |
32 | mu_strerror (rc)); | 35 | rc = mu_dbm_safety_check (db); |
36 | if (rc) | ||
37 | { | ||
38 | mu_diag_output (MU_DIAG_ERROR, | ||
39 | _("statistics db fails safety check: %s"), | ||
40 | mu_strerror (rc)); | ||
41 | mu_dbm_destroy (&db); | ||
42 | return NULL; | ||
33 | } | 43 | } |
34 | return rc; | 44 | |
45 | rc = mu_dbm_open (db, mode, 0660); | ||
46 | if (rc) | ||
47 | { | ||
48 | mu_diag_output (MU_DIAG_ERROR, _("unable to open statistics db: %s"), | ||
49 | mu_dbm_strerror (db)); | ||
50 | mu_dbm_destroy (&db); | ||
51 | } | ||
52 | return db; | ||
35 | } | 53 | } |
36 | 54 | ||
37 | int | 55 | int |
38 | check_login_delay (char *username) | 56 | check_login_delay (char *username) |
39 | { | 57 | { |
40 | time_t now, prev_time; | 58 | time_t now, prev_time; |
41 | DBM_FILE db; | 59 | mu_dbm_file_t db; |
42 | DBM_DATUM key, data; | 60 | struct mu_dbm_datum key, data; |
43 | char text[64], *p; | 61 | char text[64], *p; |
44 | int rc; | 62 | int rc; |
45 | 63 | ||
... | @@ -47,42 +65,45 @@ check_login_delay (char *username) | ... | @@ -47,42 +65,45 @@ check_login_delay (char *username) |
47 | return 0; | 65 | return 0; |
48 | 66 | ||
49 | time (&now); | 67 | time (&now); |
50 | if (open_stat_db (&db, MU_STREAM_RDWR)) | 68 | db = open_stat_db (MU_STREAM_READ); |
69 | if (!db) | ||
51 | return 0; | 70 | return 0; |
52 | 71 | ||
53 | memset (&key, 0, sizeof key); | 72 | memset (&key, 0, sizeof key); |
54 | MU_DATUM_PTR(key) = username; | 73 | key.mu_dptr = username; |
55 | MU_DATUM_SIZE(key) = strlen (username); | 74 | key.mu_dsize = strlen (username); |
56 | memset (&data, 0, sizeof data); | 75 | memset (&data, 0, sizeof data); |
57 | 76 | ||
58 | rc = mu_dbm_fetch (db, key, &data); | 77 | rc = mu_dbm_fetch (db, &key, &data); |
59 | if (rc) | 78 | if (rc) |
60 | { | 79 | { |
61 | mu_diag_output (MU_DIAG_ERROR, _("cannot fetch login delay data: %s"), | 80 | if (rc != MU_ERR_NOENT) |
62 | mu_strerror (rc)); | 81 | mu_diag_output (MU_DIAG_ERROR, _("cannot fetch login delay data: %s"), |
63 | mu_dbm_close (db); | 82 | mu_dbm_strerror (db)); |
83 | mu_dbm_destroy (&db); | ||
64 | return 0; | 84 | return 0; |
65 | } | 85 | } |
66 | 86 | ||
67 | if (MU_DATUM_SIZE(data) > sizeof (text) - 1) | 87 | if (data.mu_dsize > sizeof (text) - 1) |
68 | { | 88 | { |
69 | mu_diag_output (MU_DIAG_ERROR, | 89 | mu_diag_output (MU_DIAG_ERROR, |
70 | _("invalid entry for '%s': wrong timestamp size"), | 90 | _("invalid entry for '%s': wrong timestamp size"), |
71 | username); | 91 | username); |
72 | mu_dbm_close (db); | 92 | mu_dbm_destroy (&db); |
73 | return 0; | 93 | return 0; |
74 | } | 94 | } |
95 | mu_dbm_destroy (&db); | ||
75 | 96 | ||
76 | memcpy (text, MU_DATUM_PTR(data), MU_DATUM_SIZE(data)); | 97 | memcpy (text, data.mu_dptr, data.mu_dsize); |
77 | text[MU_DATUM_SIZE(data)] = 0; | 98 | text[data.mu_dsize] = 0; |
78 | mu_dbm_close (db); | 99 | mu_dbm_datum_free (&data); |
79 | 100 | ||
80 | prev_time = strtoul (text, &p, 0); | 101 | prev_time = strtoul (text, &p, 0); |
81 | if (*p) | 102 | if (*p) |
82 | { | 103 | { |
83 | mu_diag_output (MU_DIAG_ERROR, | 104 | mu_diag_output (MU_DIAG_ERROR, |
84 | _("malformed timestamp for '%s': %s"), | 105 | _("malformed timestamp for '%s': %s"), |
85 | username, text); | 106 | username, text); |
86 | return 0; | 107 | return 0; |
87 | } | 108 | } |
88 | 109 | ||
... | @@ -93,40 +114,42 @@ void | ... | @@ -93,40 +114,42 @@ void |
93 | update_login_delay (char *username) | 114 | update_login_delay (char *username) |
94 | { | 115 | { |
95 | time_t now; | 116 | time_t now; |
96 | DBM_FILE db; | 117 | mu_dbm_file_t db; |
97 | DBM_DATUM key, data; | 118 | struct mu_dbm_datum key, data; |
98 | char text[64]; | 119 | char text[64]; |
99 | 120 | ||
100 | if (login_delay == 0 || username == NULL) | 121 | if (login_delay == 0 || username == NULL) |
101 | return; | 122 | return; |
102 | 123 | ||
103 | time (&now); | 124 | time (&now); |
104 | if (open_stat_db (&db, MU_STREAM_RDWR)) | 125 | db = open_stat_db (MU_STREAM_RDWR); |
126 | if (!db) | ||
105 | return; | 127 | return; |
106 | 128 | ||
107 | memset(&key, 0, sizeof(key)); | 129 | memset(&key, 0, sizeof(key)); |
108 | memset(&data, 0, sizeof(data)); | 130 | memset(&data, 0, sizeof(data)); |
109 | MU_DATUM_PTR(key) = username; | 131 | key.mu_dptr = username; |
110 | MU_DATUM_SIZE(key) = strlen (username); | 132 | key.mu_dsize = strlen (username); |
111 | snprintf (text, sizeof text, "%lu", (unsigned long) now); | 133 | snprintf (text, sizeof text, "%lu", (unsigned long) now); |
112 | MU_DATUM_PTR(data) = text; | 134 | data.mu_dptr = text; |
113 | MU_DATUM_SIZE(data) = strlen (text); | 135 | data.mu_dsize = strlen (text); |
114 | if (mu_dbm_insert (db, key, data, 1)) | 136 | if (mu_dbm_store (db, &key, &data, 1)) |
115 | mu_error (_("%s: cannot store datum %s/%s"), | 137 | mu_error (_("%s: cannot store datum %s/%s: %s"), |
116 | login_stat_file, username, text); | 138 | login_stat_file, username, text, |
139 | mu_dbm_strerror (db)); | ||
117 | 140 | ||
118 | mu_dbm_close (db); | 141 | mu_dbm_destroy (&db); |
119 | } | 142 | } |
120 | 143 | ||
121 | void | 144 | void |
122 | login_delay_capa () | 145 | login_delay_capa () |
123 | { | 146 | { |
124 | DBM_FILE db; | 147 | mu_dbm_file_t db; |
125 | 148 | ||
126 | if (login_delay && open_stat_db (&db, MU_STREAM_RDWR) == 0) | 149 | if (login_delay && (db = open_stat_db (MU_STREAM_RDWR)) != NULL) |
127 | { | 150 | { |
128 | pop3d_outf ("LOGIN-DELAY %s\n", mu_umaxtostr (0, login_delay)); | 151 | pop3d_outf ("LOGIN-DELAY %s\n", mu_umaxtostr (0, login_delay)); |
129 | mu_dbm_close (db); | 152 | mu_dbm_destroy (&db); |
130 | } | 153 | } |
131 | } | 154 | } |
132 | #endif | 155 | #endif | ... | ... |
... | @@ -77,7 +77,7 @@ cb_bulletin_source (void *data, mu_config_value_t *val) | ... | @@ -77,7 +77,7 @@ cb_bulletin_source (void *data, mu_config_value_t *val) |
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | 79 | ||
80 | #ifdef USE_DBM | 80 | #ifdef ENABLE_DBM |
81 | static int | 81 | static int |
82 | cb_bulletin_db (void *data, mu_config_value_t *val) | 82 | cb_bulletin_db (void *data, mu_config_value_t *val) |
83 | { | 83 | { |
... | @@ -111,7 +111,7 @@ static struct mu_cfg_param pop3d_cfg_param[] = { | ... | @@ -111,7 +111,7 @@ static struct mu_cfg_param pop3d_cfg_param[] = { |
111 | { "bulletin-source", mu_cfg_callback, NULL, 0, cb_bulletin_source, | 111 | { "bulletin-source", mu_cfg_callback, NULL, 0, cb_bulletin_source, |
112 | N_("Get bulletins from the specified mailbox."), | 112 | N_("Get bulletins from the specified mailbox."), |
113 | N_("url") }, | 113 | N_("url") }, |
114 | #ifdef USE_DBM | 114 | #ifdef ENABLE_DBM |
115 | { "bulletin-db", mu_cfg_callback, NULL, 0, cb_bulletin_db, | 115 | { "bulletin-db", mu_cfg_callback, NULL, 0, cb_bulletin_db, |
116 | N_("Set the bulletin database file name."), | 116 | N_("Set the bulletin database file name."), |
117 | N_("file") }, | 117 | N_("file") }, | ... | ... |
... | @@ -24,7 +24,7 @@ | ... | @@ -24,7 +24,7 @@ |
24 | #include <mailutils/types.h> | 24 | #include <mailutils/types.h> |
25 | #include <mailutils/stream.h> | 25 | #include <mailutils/stream.h> |
26 | #include <mailutils/io.h> | 26 | #include <mailutils/io.h> |
27 | #include <mu_dbm.h> | 27 | #include <mailutils/dbm.h> |
28 | #include <mu_umaxtostr.h> | 28 | #include <mu_umaxtostr.h> |
29 | #include <muaux.h> | 29 | #include <muaux.h> |
30 | 30 | ||
... | @@ -35,7 +35,7 @@ | ... | @@ -35,7 +35,7 @@ |
35 | type automatically */ | 35 | type automatically */ |
36 | #define APOP_PASSFILE_NAME "apop" | 36 | #define APOP_PASSFILE_NAME "apop" |
37 | 37 | ||
38 | #ifdef USE_DBM | 38 | #ifdef ENABLE_DBM |
39 | # define APOP_PASSFILE SYSCONFDIR "/" APOP_PASSFILE_NAME | 39 | # define APOP_PASSFILE SYSCONFDIR "/" APOP_PASSFILE_NAME |
40 | # define ENABLE_LOGIN_DELAY | 40 | # define ENABLE_LOGIN_DELAY |
41 | #else | 41 | #else | ... | ... |
... | @@ -73,7 +73,7 @@ static struct argp_option options[] = | ... | @@ -73,7 +73,7 @@ static struct argp_option options[] = |
73 | 73 | ||
74 | { NULL, 0, NULL, 0, | 74 | { NULL, 0, NULL, 0, |
75 | N_("Default action is:\n" | 75 | N_("Default action is:\n" |
76 | " For the file owner: --list\n" | 76 | " For root: --list\n" |
77 | " For a user: --modify --user <username>\n"), 2 }, | 77 | " For a user: --modify --user <username>\n"), 2 }, |
78 | 78 | ||
79 | { NULL, 0, NULL, 0, N_("Options are:"), 3 }, | 79 | { NULL, 0, NULL, 0, N_("Options are:"), 3 }, |
... | @@ -197,7 +197,7 @@ popauth_parse_opt (int key, char *arg, struct argp_state *astate) | ... | @@ -197,7 +197,7 @@ popauth_parse_opt (int key, char *arg, struct argp_state *astate) |
197 | } | 197 | } |
198 | 198 | ||
199 | int | 199 | int |
200 | main(int argc, char **argv) | 200 | main (int argc, char **argv) |
201 | { | 201 | { |
202 | struct action_data adata; | 202 | struct action_data adata; |
203 | 203 | ||
... | @@ -223,41 +223,121 @@ check_action (int action) | ... | @@ -223,41 +223,121 @@ check_action (int action) |
223 | } | 223 | } |
224 | } | 224 | } |
225 | 225 | ||
226 | int | 226 | mu_dbm_file_t |
227 | check_user_perm (int action, struct action_data *ap) | 227 | open_db_file (int action, struct action_data *ap, int *my_file) |
228 | { | 228 | { |
229 | struct stat sb; | 229 | mu_dbm_file_t db; |
230 | struct passwd *pw; | 230 | struct passwd *pw; |
231 | uid_t uid; | 231 | uid_t uid; |
232 | int rc; | ||
233 | int flags = 0; | ||
234 | char *db_name = NULL; | ||
235 | int fd; | ||
236 | struct stat sb; | ||
237 | int safety_flags = MU_FILE_SAFETY_ALL & ~MU_FILE_SAFETY_OWNER_MISMATCH; | ||
232 | 238 | ||
233 | if (!ap->input_name) | 239 | switch (action) |
234 | ap->input_name = APOP_PASSFILE; | ||
235 | |||
236 | if (mu_dbm_stat (ap->input_name, &sb)) | ||
237 | { | 240 | { |
238 | if (ap->action == ACT_ADD) | 241 | case ACT_CREATE: |
239 | { | 242 | flags = MU_STREAM_CREAT; |
240 | DBM_FILE db; | 243 | safety_flags = MU_FILE_SAFETY_NONE; |
241 | if (mu_dbm_open (ap->input_name, &db, MU_STREAM_CREAT, permissions)) | 244 | db_name = ap->output_name; |
242 | { | 245 | break; |
243 | mu_diag_funcall (MU_DIAG_ERROR, "mu_dbm_open", | 246 | |
244 | ap->input_name, errno); | 247 | case ACT_ADD: |
245 | exit (EX_SOFTWARE); | 248 | case ACT_DELETE: |
246 | } | 249 | if (!ap->input_name) |
247 | mu_dbm_close (db); | 250 | ap->input_name = APOP_PASSFILE; |
248 | mu_dbm_stat (ap->input_name, &sb); | 251 | flags = MU_STREAM_RDWR; |
249 | } | 252 | db_name = ap->input_name; |
250 | else | 253 | break; |
251 | { | 254 | |
252 | mu_diag_funcall (MU_DIAG_ERROR, "stat", ap->input_name, errno); | 255 | case ACT_LIST: |
253 | exit (EX_OSERR); | 256 | if (!ap->input_name) |
254 | } | 257 | ap->input_name = APOP_PASSFILE; |
258 | flags = MU_STREAM_READ; | ||
259 | safety_flags = MU_FILE_SAFETY_NONE; | ||
260 | db_name = ap->input_name; | ||
261 | break; | ||
262 | |||
263 | case ACT_CHPASS: | ||
264 | if (!ap->input_name) | ||
265 | ap->input_name = APOP_PASSFILE; | ||
266 | flags = MU_STREAM_RDWR; | ||
267 | db_name = ap->input_name; | ||
268 | break; | ||
269 | |||
270 | default: | ||
271 | abort (); | ||
255 | } | 272 | } |
256 | 273 | ||
257 | uid = getuid (); | 274 | uid = getuid (); |
258 | if (uid == 0 || sb.st_uid == uid) | ||
259 | return 0; | ||
260 | 275 | ||
276 | rc = mu_dbm_create (db_name, &db); | ||
277 | if (rc) | ||
278 | { | ||
279 | mu_diag_output (MU_DIAG_ERROR, _("unable to create database %s: %s"), | ||
280 | db_name, mu_strerror (rc)); | ||
281 | exit (EX_SOFTWARE); | ||
282 | } | ||
283 | |||
284 | // mu_dbm_safety_set_owner (db, uid); | ||
285 | /* Adjust safety flags */ | ||
286 | if (permissions & 0002) | ||
287 | safety_flags &= ~MU_FILE_SAFETY_WORLD_WRITABLE; | ||
288 | if (permissions & 0004) | ||
289 | safety_flags &= ~MU_FILE_SAFETY_WORLD_READABLE; | ||
290 | if (permissions & 0020) | ||
291 | safety_flags &= ~MU_FILE_SAFETY_GROUP_WRITABLE; | ||
292 | if (permissions & 0040) | ||
293 | safety_flags &= ~MU_FILE_SAFETY_GROUP_READABLE; | ||
294 | |||
295 | mu_dbm_safety_set_flags (db, safety_flags); | ||
296 | rc = mu_dbm_safety_check (db); | ||
297 | if (rc && rc != ENOENT) | ||
298 | { | ||
299 | mu_diag_output (MU_DIAG_ERROR, | ||
300 | _("%s fails safety check: %s"), | ||
301 | db_name, mu_strerror (rc)); | ||
302 | mu_dbm_destroy (&db); | ||
303 | exit (EX_UNAVAILABLE); | ||
304 | } | ||
305 | |||
306 | rc = mu_dbm_open (db, flags, permissions); | ||
307 | if (rc) | ||
308 | { | ||
309 | mu_diag_funcall (MU_DIAG_ERROR, "mu_dbm_open", | ||
310 | db_name, rc); | ||
311 | exit (EX_SOFTWARE); | ||
312 | } | ||
313 | |||
314 | if (uid == 0) | ||
315 | return db; | ||
316 | |||
317 | rc = mu_dbm_get_fd (db, &fd, NULL); | ||
318 | if (rc) | ||
319 | { | ||
320 | mu_diag_funcall (MU_DIAG_ERROR, "mu_dbm_get_fd", | ||
321 | db_name, rc); | ||
322 | exit (EX_SOFTWARE); | ||
323 | } | ||
324 | |||
325 | if (fstat (fd, &sb)) | ||
326 | { | ||
327 | mu_diag_funcall (MU_DIAG_ERROR, "fstat", | ||
328 | db_name, errno); | ||
329 | exit (EX_SOFTWARE); | ||
330 | } | ||
331 | |||
332 | if (sb.st_uid == uid) | ||
333 | { | ||
334 | if (my_file) | ||
335 | *my_file = 1; | ||
336 | return db; | ||
337 | } | ||
338 | if (my_file) | ||
339 | *my_file = 0; | ||
340 | |||
261 | if (ap->username) | 341 | if (ap->username) |
262 | { | 342 | { |
263 | mu_error (_("Only the file owner can use --username")); | 343 | mu_error (_("Only the file owner can use --username")); |
... | @@ -273,41 +353,36 @@ check_user_perm (int action, struct action_data *ap) | ... | @@ -273,41 +353,36 @@ check_user_perm (int action, struct action_data *ap) |
273 | if (!pw) | 353 | if (!pw) |
274 | exit (EX_OSERR); | 354 | exit (EX_OSERR); |
275 | ap->username = pw->pw_name; | 355 | ap->username = pw->pw_name; |
276 | return 1; | 356 | return db; |
277 | } | 357 | } |
278 | 358 | ||
279 | static void | 359 | static void |
280 | print_entry (mu_stream_t str, DBM_DATUM key, DBM_DATUM contents) | 360 | print_entry (mu_stream_t str, struct mu_dbm_datum const *key, |
361 | struct mu_dbm_datum const *contents) | ||
281 | { | 362 | { |
282 | if (compatibility_option) | 363 | if (compatibility_option) |
283 | mu_stream_printf (str, "%.*s: %.*s\n", | 364 | mu_stream_printf (str, "%.*s: %.*s\n", |
284 | (int) MU_DATUM_SIZE (key), | 365 | (int) key->mu_dsize, |
285 | (char*) MU_DATUM_PTR (key), | 366 | (char*) key->mu_dptr, |
286 | (int) MU_DATUM_SIZE (contents), | 367 | (int) contents->mu_dsize, |
287 | (char*) MU_DATUM_PTR (contents)); | 368 | (char*) contents->mu_dptr); |
288 | else | 369 | else |
289 | mu_stream_printf (str, "%.*s %.*s\n", | 370 | mu_stream_printf (str, "%.*s %.*s\n", |
290 | (int) MU_DATUM_SIZE (key), | 371 | (int) key->mu_dsize, |
291 | (char*) MU_DATUM_PTR (key), | 372 | (char*) key->mu_dptr, |
292 | (int) MU_DATUM_SIZE (contents), | 373 | (int) contents->mu_dsize, |
293 | (char*) MU_DATUM_PTR (contents)); | 374 | (char*) contents->mu_dptr); |
294 | } | 375 | } |
295 | 376 | ||
296 | int | 377 | int |
297 | action_list (struct action_data *ap) | 378 | action_list (struct action_data *ap) |
298 | { | 379 | { |
299 | mu_stream_t str; | 380 | mu_stream_t str; |
300 | DBM_FILE db; | 381 | mu_dbm_file_t db; |
301 | DBM_DATUM key; | 382 | struct mu_dbm_datum key, contents; |
302 | DBM_DATUM contents; | 383 | int rc; |
303 | 384 | ||
304 | check_user_perm (ACT_LIST, ap); | 385 | db = open_db_file (ACT_LIST, ap, NULL); |
305 | if (mu_dbm_open (ap->input_name, &db, MU_STREAM_READ, 0)) | ||
306 | { | ||
307 | mu_error (_("cannot open file %s: %s"), | ||
308 | ap->input_name, mu_strerror (errno)); | ||
309 | return 1; | ||
310 | } | ||
311 | 386 | ||
312 | if (ap->output_name) | 387 | if (ap->output_name) |
313 | { | 388 | { |
... | @@ -331,32 +406,47 @@ action_list (struct action_data *ap) | ... | @@ -331,32 +406,47 @@ action_list (struct action_data *ap) |
331 | { | 406 | { |
332 | memset (&key, 0, sizeof key); | 407 | memset (&key, 0, sizeof key); |
333 | memset (&contents, 0, sizeof contents); | 408 | memset (&contents, 0, sizeof contents); |
334 | MU_DATUM_PTR (key) = ap->username; | 409 | key.mu_dptr = ap->username; |
335 | MU_DATUM_SIZE (key) = strlen (ap->username); | 410 | key.mu_dsize = strlen (ap->username); |
336 | if (mu_dbm_fetch (db, key, &contents)) | 411 | rc = mu_dbm_fetch (db, &key, &contents); |
412 | if (rc == MU_ERR_NOENT) | ||
337 | { | 413 | { |
338 | mu_error (_("no such user: %s"), ap->username); | 414 | mu_error (_("no such user: %s"), ap->username); |
339 | } | 415 | } |
416 | else if (rc) | ||
417 | { | ||
418 | mu_error (_("database fetch error: %s"), mu_dbm_strerror (db)); | ||
419 | exit (EX_UNAVAILABLE); | ||
420 | } | ||
340 | else | 421 | else |
341 | { | 422 | { |
342 | print_entry (str, key, contents); | 423 | print_entry (str, &key, &contents); |
343 | mu_dbm_datum_free (&contents); | 424 | mu_dbm_datum_free (&contents); |
344 | } | 425 | } |
345 | } | 426 | } |
346 | else | 427 | else |
347 | { | 428 | { |
348 | for (key = mu_dbm_firstkey (db); MU_DATUM_PTR(key); | 429 | memset (&key, 0, sizeof key); |
349 | key = mu_dbm_nextkey (db, key)) | 430 | for (rc = mu_dbm_firstkey (db, &key); rc == 0; |
431 | rc = mu_dbm_nextkey (db, &key)) | ||
350 | { | 432 | { |
351 | memset (&contents, 0, sizeof contents); | 433 | memset (&contents, 0, sizeof contents); |
352 | mu_dbm_fetch (db, key, &contents); | 434 | rc = mu_dbm_fetch (db, &key, &contents); |
353 | print_entry (str, key, contents); | 435 | if (rc == 0) |
354 | mu_dbm_datum_free (&contents); | 436 | { |
437 | print_entry (str, &key, &contents); | ||
438 | mu_dbm_datum_free (&contents); | ||
439 | } | ||
440 | else | ||
441 | { | ||
442 | mu_error (_("database fetch error: %s"), mu_dbm_strerror (db)); | ||
443 | exit (EX_UNAVAILABLE); | ||
444 | } | ||
445 | mu_dbm_datum_free (&key); | ||
355 | } | 446 | } |
356 | } | 447 | } |
357 | 448 | ||
358 | mu_dbm_close (db); | 449 | mu_dbm_destroy (&db); |
359 | mu_stream_destroy (&str); | ||
360 | return 0; | 450 | return 0; |
361 | } | 451 | } |
362 | 452 | ||
... | @@ -365,9 +455,8 @@ action_create (struct action_data *ap) | ... | @@ -365,9 +455,8 @@ action_create (struct action_data *ap) |
365 | { | 455 | { |
366 | int rc; | 456 | int rc; |
367 | mu_stream_t in; | 457 | mu_stream_t in; |
368 | DBM_FILE db; | 458 | mu_dbm_file_t db; |
369 | DBM_DATUM key; | 459 | struct mu_dbm_datum key, contents; |
370 | DBM_DATUM contents; | ||
371 | char *buf = NULL; | 460 | char *buf = NULL; |
372 | size_t size = 0, len; | 461 | size_t size = 0, len; |
373 | int line = 0; | 462 | int line = 0; |
... | @@ -399,12 +488,8 @@ action_create (struct action_data *ap) | ... | @@ -399,12 +488,8 @@ action_create (struct action_data *ap) |
399 | 488 | ||
400 | if (!ap->output_name) | 489 | if (!ap->output_name) |
401 | ap->output_name = APOP_PASSFILE; | 490 | ap->output_name = APOP_PASSFILE; |
402 | if (mu_dbm_open (ap->output_name, &db, MU_STREAM_CREAT, permissions)) | 491 | |
403 | { | 492 | db = open_db_file (ACT_CREATE, ap, NULL); |
404 | mu_error (_("cannot create database %s: %s"), | ||
405 | ap->output_name, mu_strerror (errno)); | ||
406 | return 1; | ||
407 | } | ||
408 | 493 | ||
409 | line = 0; | 494 | line = 0; |
410 | while ((rc = mu_stream_getline (in, &buf, &size, &len)) == 0 | 495 | while ((rc = mu_stream_getline (in, &buf, &size, &len)) == 0 |
... | @@ -435,20 +520,25 @@ action_create (struct action_data *ap) | ... | @@ -435,20 +520,25 @@ action_create (struct action_data *ap) |
435 | 520 | ||
436 | memset (&key, 0, sizeof key); | 521 | memset (&key, 0, sizeof key); |
437 | memset (&contents, 0, sizeof contents); | 522 | memset (&contents, 0, sizeof contents); |
438 | MU_DATUM_PTR (key) = str; | 523 | key.mu_dptr = str; |
439 | MU_DATUM_SIZE (key) = strlen (str); | 524 | key.mu_dsize = strlen (str); |
440 | MU_DATUM_PTR (contents) = pass; | 525 | contents.mu_dptr = pass; |
441 | MU_DATUM_SIZE (contents) = strlen (pass); | 526 | contents.mu_dsize = strlen (pass); |
442 | 527 | ||
443 | if (mu_dbm_insert (db, key, contents, 1)) | 528 | rc = mu_dbm_store (db, &key, &contents, 1); |
444 | mu_error (_("%s:%d: cannot store datum"), ap->input_name, line); | 529 | if (rc) |
530 | mu_error (_("%s:%d: cannot store datum: %s"), | ||
531 | ap->input_name, line, | ||
532 | rc == MU_ERR_FAILURE ? | ||
533 | mu_dbm_strerror (db) : mu_strerror (rc)); | ||
445 | } | 534 | } |
446 | free (buf); | 535 | free (buf); |
447 | mu_dbm_close (db); | 536 | mu_dbm_destroy (&db); |
448 | mu_stream_destroy (&in); | 537 | mu_stream_destroy (&in); |
449 | return 0; | 538 | return 0; |
450 | } | 539 | } |
451 | 540 | ||
541 | /*FIXME | ||
452 | int | 542 | int |
453 | open_io (int action, struct action_data *ap, DBM_FILE *db, int *not_owner) | 543 | open_io (int action, struct action_data *ap, DBM_FILE *db, int *not_owner) |
454 | { | 544 | { |
... | @@ -463,6 +553,7 @@ open_io (int action, struct action_data *ap, DBM_FILE *db, int *not_owner) | ... | @@ -463,6 +553,7 @@ open_io (int action, struct action_data *ap, DBM_FILE *db, int *not_owner) |
463 | } | 553 | } |
464 | return 0; | 554 | return 0; |
465 | } | 555 | } |
556 | */ | ||
466 | 557 | ||
467 | void | 558 | void |
468 | fill_pass (struct action_data *ap) | 559 | fill_pass (struct action_data *ap) |
... | @@ -527,9 +618,8 @@ fill_pass (struct action_data *ap) | ... | @@ -527,9 +618,8 @@ fill_pass (struct action_data *ap) |
527 | int | 618 | int |
528 | action_add (struct action_data *ap) | 619 | action_add (struct action_data *ap) |
529 | { | 620 | { |
530 | DBM_FILE db; | 621 | mu_dbm_file_t db; |
531 | DBM_DATUM key; | 622 | struct mu_dbm_datum key, contents; |
532 | DBM_DATUM contents; | ||
533 | int rc; | 623 | int rc; |
534 | 624 | ||
535 | if (!ap->username) | 625 | if (!ap->username) |
... | @@ -538,31 +628,32 @@ action_add (struct action_data *ap) | ... | @@ -538,31 +628,32 @@ action_add (struct action_data *ap) |
538 | return 1; | 628 | return 1; |
539 | } | 629 | } |
540 | 630 | ||
541 | if (open_io (ACT_ADD, ap, &db, NULL)) | 631 | db = open_db_file (ACT_ADD, ap, NULL); |
542 | return 1; | ||
543 | 632 | ||
544 | fill_pass (ap); | 633 | fill_pass (ap); |
545 | 634 | ||
546 | memset (&key, 0, sizeof key); | 635 | memset (&key, 0, sizeof key); |
547 | memset (&contents, 0, sizeof contents); | 636 | memset (&contents, 0, sizeof contents); |
548 | MU_DATUM_PTR (key) = ap->username; | 637 | key.mu_dptr = ap->username; |
549 | MU_DATUM_SIZE (key) = strlen (ap->username); | 638 | key.mu_dsize = strlen (ap->username); |
550 | MU_DATUM_PTR (contents) = ap->passwd; | 639 | contents.mu_dptr = ap->passwd; |
551 | MU_DATUM_SIZE (contents) = strlen (ap->passwd); | 640 | contents.mu_dsize = strlen (ap->passwd); |
552 | 641 | ||
553 | rc = mu_dbm_insert (db, key, contents, 1); | 642 | rc = mu_dbm_store (db, &key, &contents, 1); |
554 | if (rc) | 643 | if (rc) |
555 | mu_error (_("cannot store datum")); | 644 | mu_error (_("cannot store datum: %s"), |
645 | rc == MU_ERR_FAILURE ? | ||
646 | mu_dbm_strerror (db) : mu_strerror (rc)); | ||
556 | 647 | ||
557 | mu_dbm_close (db); | 648 | mu_dbm_destroy (&db); |
558 | return rc; | 649 | return rc; |
559 | } | 650 | } |
560 | 651 | ||
561 | int | 652 | int |
562 | action_delete (struct action_data *ap) | 653 | action_delete (struct action_data *ap) |
563 | { | 654 | { |
564 | DBM_FILE db; | 655 | mu_dbm_file_t db; |
565 | DBM_DATUM key; | 656 | struct mu_dbm_datum key; |
566 | int rc; | 657 | int rc; |
567 | 658 | ||
568 | if (!ap->username) | 659 | if (!ap->username) |
... | @@ -571,56 +662,64 @@ action_delete (struct action_data *ap) | ... | @@ -571,56 +662,64 @@ action_delete (struct action_data *ap) |
571 | return 1; | 662 | return 1; |
572 | } | 663 | } |
573 | 664 | ||
574 | if (open_io (ACT_DELETE, ap, &db, NULL)) | 665 | db = open_db_file (ACT_DELETE, ap, NULL); |
575 | return 1; | 666 | |
576 | 667 | memset (&key, 0, sizeof key); | |
577 | MU_DATUM_PTR (key) = ap->username; | 668 | key.mu_dptr = ap->username; |
578 | MU_DATUM_SIZE (key) = strlen (ap->username); | 669 | key.mu_dsize = strlen (ap->username); |
579 | 670 | ||
580 | rc = mu_dbm_delete (db, key); | 671 | rc = mu_dbm_delete (db, &key); |
581 | if (rc) | 672 | if (rc) |
582 | mu_error (_("cannot remove record for %s"), ap->username); | 673 | mu_error (_("cannot remove record for %s: %s"), |
674 | ap->username, | ||
675 | rc == MU_ERR_FAILURE ? | ||
676 | mu_dbm_strerror (db) : mu_strerror (rc)); | ||
583 | 677 | ||
584 | mu_dbm_close (db); | 678 | mu_dbm_destroy (&db); |
585 | return rc; | 679 | return rc; |
586 | } | 680 | } |
587 | 681 | ||
588 | int | 682 | int |
589 | action_chpass (struct action_data *ap) | 683 | action_chpass (struct action_data *ap) |
590 | { | 684 | { |
591 | DBM_FILE db; | 685 | mu_dbm_file_t db; |
592 | DBM_DATUM key; | 686 | struct mu_dbm_datum key, contents; |
593 | DBM_DATUM contents; | ||
594 | int rc; | 687 | int rc; |
595 | int not_owner; | 688 | int my_file; |
596 | 689 | ||
597 | if (open_io (ACT_CHPASS, ap, &db, ¬_owner)) | 690 | db = open_db_file (ACT_CHPASS, ap, &my_file); |
598 | return 1; | ||
599 | 691 | ||
600 | if (!ap->username) | 692 | if (!ap->username) |
601 | { | 693 | { |
602 | mu_error (_("missing username")); | 694 | struct passwd *pw = getpwuid (getuid ()); |
603 | return 1; | 695 | ap->username = pw->pw_name; |
696 | printf ("Changing password for %s\n", ap->username); | ||
604 | } | 697 | } |
605 | 698 | ||
606 | memset (&key, 0, sizeof key); | 699 | memset (&key, 0, sizeof key); |
607 | memset (&contents, 0, sizeof contents); | 700 | memset (&contents, 0, sizeof contents); |
608 | 701 | ||
609 | MU_DATUM_PTR (key) = ap->username; | 702 | key.mu_dptr = ap->username; |
610 | MU_DATUM_SIZE (key) = strlen (ap->username); | 703 | key.mu_dsize = strlen (ap->username); |
611 | if (mu_dbm_fetch (db, key, &contents)) | 704 | rc = mu_dbm_fetch (db, &key, &contents); |
705 | if (rc == MU_ERR_NOENT) | ||
612 | { | 706 | { |
613 | mu_error (_("no such user: %s"), ap->username); | 707 | mu_error (_("no such user: %s"), ap->username); |
614 | return 1; | 708 | return 1; |
615 | } | 709 | } |
616 | 710 | else if (rc) | |
617 | if (not_owner) | 711 | { |
712 | mu_error (_("database fetch error: %s"), mu_dbm_strerror (db)); | ||
713 | exit (EX_UNAVAILABLE); | ||
714 | } | ||
715 | |||
716 | if (!my_file) | ||
618 | { | 717 | { |
619 | char *oldpass, *p; | 718 | char *oldpass, *p; |
620 | 719 | ||
621 | oldpass = xmalloc (MU_DATUM_SIZE (contents) + 1); | 720 | oldpass = xmalloc (contents.mu_dsize + 1); |
622 | memcpy (oldpass, MU_DATUM_PTR (contents), MU_DATUM_SIZE (contents)); | 721 | memcpy (oldpass, contents.mu_dptr, contents.mu_dsize); |
623 | oldpass[MU_DATUM_SIZE (contents)] = 0; | 722 | oldpass[contents.mu_dsize] = 0; |
624 | p = getpass (_("Old Password:")); | 723 | p = getpass (_("Old Password:")); |
625 | if (!p) | 724 | if (!p) |
626 | return 1; | 725 | return 1; |
... | @@ -634,32 +733,49 @@ action_chpass (struct action_data *ap) | ... | @@ -634,32 +733,49 @@ action_chpass (struct action_data *ap) |
634 | fill_pass (ap); | 733 | fill_pass (ap); |
635 | 734 | ||
636 | mu_dbm_datum_free (&contents); | 735 | mu_dbm_datum_free (&contents); |
637 | MU_DATUM_PTR (contents) = ap->passwd; | 736 | contents.mu_dptr = ap->passwd; |
638 | MU_DATUM_SIZE (contents) = strlen (ap->passwd); | 737 | contents.mu_dsize = strlen (ap->passwd); |
639 | rc = mu_dbm_insert (db, key, contents, 1); | 738 | rc = mu_dbm_store (db, &key, &contents, 1); |
640 | if (rc) | 739 | if (rc) |
641 | mu_error (_("cannot replace datum")); | 740 | mu_error (_("cannot replace datum: %s"), |
741 | rc == MU_ERR_FAILURE ? | ||
742 | mu_dbm_strerror (db) : mu_strerror (rc)); | ||
642 | 743 | ||
643 | mu_dbm_close (db); | 744 | mu_dbm_destroy (&db); |
644 | return rc; | 745 | return rc; |
645 | } | 746 | } |
646 | 747 | ||
647 | void | 748 | void |
648 | popauth_version (FILE *stream, struct argp_state *state) | 749 | popauth_version (FILE *stream, struct argp_state *state) |
649 | { | 750 | { |
650 | #if defined(WITH_GDBM) | 751 | mu_iterator_t itr; |
651 | # define FORMAT "GDBM" | 752 | int rc; |
652 | #elif defined(WITH_BDB) | 753 | |
653 | # define FORMAT "Berkeley DB" | ||
654 | #elif defined(WITH_NDBM) | ||
655 | # define FORMAT "NDBM" | ||
656 | #elif defined(WITH_OLD_DBM) | ||
657 | # define FORMAT "Old DBM" | ||
658 | #elif defined(WITH_TOKYOCABINET) | ||
659 | # define FORMAT "Tokyo Cabinet" | ||
660 | #endif | ||
661 | mu_program_version_hook (stream, state); | 754 | mu_program_version_hook (stream, state); |
662 | fprintf (stream, _("Database format: %s\n"), FORMAT); | 755 | fprintf (stream, _("Database formats: ")); |
663 | fprintf (stream, _("Database location: %s\n"), APOP_PASSFILE); | 756 | |
757 | rc = mu_dbm_impl_iterator (&itr); | ||
758 | if (rc) | ||
759 | { | ||
760 | fprintf (stream, "%s\n", _("unknown")); | ||
761 | mu_error ("%s", mu_strerror (rc)); | ||
762 | } | ||
763 | else | ||
764 | { | ||
765 | int i; | ||
766 | for (mu_iterator_first (itr), i = 0; !mu_iterator_is_done (itr); | ||
767 | mu_iterator_next (itr), i++) | ||
768 | { | ||
769 | struct mu_dbm_impl *impl; | ||
770 | |||
771 | mu_iterator_current (itr, (void**)&impl); | ||
772 | if (i) | ||
773 | fprintf (stream, ", "); | ||
774 | fprintf (stream, "%s", impl->_dbm_name); | ||
775 | } | ||
776 | fputc ('\n', stream); | ||
777 | mu_iterator_destroy (&itr); | ||
778 | } | ||
779 | fprintf (stream, _("Default database location: %s\n"), APOP_PASSFILE); | ||
664 | exit (EX_OK); | 780 | exit (EX_OK); |
665 | } | 781 | } | ... | ... |
-
Please register or sign in to post a comment