]> arthur.barton.de Git - netatalk.git/commitdiff
New utility to maintain dbd databases: dbd. Also replaces cnid_index. Still incomplete.
authorfranklahm <franklahm>
Tue, 28 Apr 2009 13:01:24 +0000 (13:01 +0000)
committerfranklahm <franklahm>
Tue, 28 Apr 2009 13:01:24 +0000 (13:01 +0000)
14 files changed:
bin/cnid/Makefile.am
bin/cnid/cnid_index.c [deleted file]
configure.in
etc/afpd/volume.c
etc/cnid_dbd/Makefile.am
etc/cnid_dbd/dbd.c [new file with mode: 0644]
etc/cnid_dbd/dbif.c
etc/cnid_dbd/dbif.h
etc/cnid_dbd/main.c
etc/cnid_dbd/pack.c
etc/cnid_dbd/pack.h
include/atalk/util.h
include/atalk/volinfo.h
libatalk/util/volinfo.c

index 96a5f909bd8c2d995c2f1da937ebd609a3e80aac..16b5bfac38f2fd879f52cfb621a1eaccaa4f19dd 100644 (file)
@@ -1,19 +1,9 @@
 # Makefile.am for bin/cnid/
 
 EXTRA_DIST = cnid_maint.in cnid2_create.in
-INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/sys
 
 if USE_BDB
 bin_SCRIPTS = cnid_maint cnid2_create
-bin_PROGRAMS = cnid_index
 else
 #bin_SCRIPTS = 
 endif
-
-cnid_index_SOURCES = cnid_index.c 
-
-cnid_index_LDADD = $(top_builddir)/libatalk/libatalk.la
-
-LIBS = @LIBS@ @BDB_LIBS@
-
-AM_CFLAGS = @CFLAGS@ @BDB_CFLAGS@ 
diff --git a/bin/cnid/cnid_index.c b/bin/cnid/cnid_index.c
deleted file mode 100644 (file)
index 3412969..0000000
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * $Id: cnid_index.c,v 1.5 2008-08-07 07:39:14 didg Exp $
- *
- * All Rights Reserved.  See COPYING.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif /* HAVE_CONFIG_H */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif /* HAVE_FCNTL_H */
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-#include <string.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif /* HAVE_SYS_TYPES_H */
-#include <sys/param.h>
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif /* HAVE_SYS_STAT_H */
-#include <time.h>
-#include <sys/file.h>
-
-#include <netatalk/endian.h>
-#include <atalk/cnid_dbd_private.h>
-#include <atalk/logger.h>
-
-#define LOCKFILENAME  "lock"
-static int exit_sig = 0;
-
-/* Copy and past from etc/cnid_dbd/dbif.c */
-#include <db.h>
-
-#define DB_ERRLOGFILE "db_errlog"
-
-static DB_ENV *db_env = NULL;
-static DB_TXN *db_txn = NULL;
-static FILE   *db_errlog = NULL;
-
-#ifdef CNID_BACKEND_DBD_TXN
-#define DBOPTIONS    (DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN)
-#else
-#define DBOPTIONS    (DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL | DB_PRIVATE) 
-#endif
-
-#define DBIF_DB_CNT 3
-
-#define DBIF_IDX_CNID      0
-#define DBIF_IDX_DEVINO    1
-#define DBIF_IDX_DIDNAME   2
-
-static struct db_table {
-     char            *name;
-     DB              *db;
-     u_int32_t       general_flags;
-     DBTYPE          type;
-} db_table[] =
-{
-     { "cnid2.db",       NULL,      0, DB_BTREE},
-     { "devino.db",      NULL,      0, DB_BTREE},
-     { "didname.db",     NULL,      0, DB_BTREE},
-};
-
-static char *old_dbfiles[] = {"cnid.db", NULL};
-
-/* --------------- */
-int didname(dbp, pkey, pdata, skey)
-DB *dbp _U_;
-const DBT *pkey _U_, *pdata;
-DBT *skey;
-{
-int len;
-    memset(skey, 0, sizeof(DBT));
-    skey->data = (char *)pdata->data + CNID_DID_OFS;
-    /* FIXME: At least DB 4.0.14 and 4.1.25 pass in the correct length of
-       pdata.size. strlen is therefore not needed. Also, skey should be zeroed
-       out already. */
-    len = strlen((char *)skey->data + CNID_DID_LEN);
-    skey->size = CNID_DID_LEN + len + 1;
-    return (0);
-}
-/* --------------- */
-int devino(dbp, pkey, pdata, skey)
-DB *dbp _U_;
-const DBT *pkey _U_, *pdata;
-DBT *skey;
-{
-    memset(skey, 0, sizeof(DBT));
-    skey->data = (char *)pdata->data + CNID_DEVINO_OFS;
-    skey->size = CNID_DEVINO_LEN;
-    return (0);
-}
-
-/* --------------- */
-static int  db_compat_associate (DB *p, DB *s,
-                   int (*callback)(DB *, const DBT *,const DBT *, DBT *),
-                   u_int32_t flags)
-{
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-    return p->associate(p, db_txn, s, callback, flags);
-#else
-#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 0)
-    return p->associate(p,       s, callback, flags);
-#else
-    return 0;
-#endif
-#endif
-}
-
-/* --------------- */
-static int db_compat_open(DB *db, char *file, char *name, DBTYPE type, int mode)
-{
-    int ret;
-
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
-    ret = db->open(db, db_txn, file, name, type, DB_CREATE, mode); 
-#else
-    ret = db->open(db,       file, name, type, DB_CREATE, mode); 
-#endif
-
-    if (ret) {
-        LOG(log_error, logtype_cnid, "error opening database %s: %s", name, db_strerror(ret));
-        return -1;
-    } else {
-        return 0;
-    }
-}
-
-/* --------------- */
-static int dbif_open(int do_truncate)
-{
-    int ret;
-    int i;
-    u_int32_t count;
-
-    for (i = 0; i != DBIF_DB_CNT; i++) {
-        if ((ret = db_create(&(db_table[i].db), db_env, 0))) {
-            LOG(log_error, logtype_cnid, "error creating handle for database %s: %s", 
-                db_table[i].name, db_strerror(ret));
-            return -1;
-        }
-
-        if (db_table[i].general_flags) { 
-            if ((ret = db_table[i].db->set_flags(db_table[i].db, db_table[i].general_flags))) {
-                LOG(log_error, logtype_cnid, "error setting flags for database %s: %s", 
-                    db_table[i].name, db_strerror(ret));
-                return -1;
-            }
-        }
-
-        if (db_compat_open(db_table[i].db, db_table[0].name, db_table[i].name, db_table[i].type, 0664) < 0)
-            return -1;
-        if (db_errlog != NULL)
-            db_table[i].db->set_errfile(db_table[i].db, db_errlog);
-
-        if (do_truncate && i > 0) {
-           if ((ret = db_table[i].db->truncate(db_table[i].db, db_txn, &count, 0))) {
-                LOG(log_error, logtype_cnid, "error truncating database %s: %s", 
-                    db_table[i].name, db_strerror(ret));
-                return -1;
-            }
-        }
-    }
-
-    /* TODO: Implement CNID DB versioning info on new databases. */
-    /* TODO: Make transaction support a runtime option. */
-    /* Associate the secondary with the primary. */
-    if ((ret = db_compat_associate(db_table[0].db, db_table[DBIF_IDX_DIDNAME].db, didname, (do_truncate)?DB_CREATE:0)) != 0) {
-        LOG(log_error, logtype_cnid, "Failed to associate didname database: %s",db_strerror(ret));
-        return -1;
-    }
-    if ((ret = db_compat_associate(db_table[0].db, db_table[DBIF_IDX_DEVINO].db, devino, (do_truncate)?DB_CREATE:0)) != 0) {
-        LOG(log_error, logtype_cnid, "Failed to associate devino database: %s",db_strerror(ret));
-       return -1;
-    }
-
-    return 0;
-}
-
-/* ------------------------ */
-static int dbif_closedb(void)
-{
-    int i;
-    int ret;
-    int err = 0;
-
-    for (i = DBIF_DB_CNT -1; i >= 0; i--) {
-        if (db_table[i].db != NULL && (ret = db_table[i].db->close(db_table[i].db, 0))) {
-            LOG(log_error, logtype_cnid, "error closing database %s: %s", db_table[i].name, db_strerror(ret));
-            err++;
-        }
-    }
-    if (err)
-        return -1;
-    return 0;
-}
-
-/* ------------------------ */
-static int dbif_close(void)
-{
-    int ret;
-    int err = 0;
-    
-    if (dbif_closedb()) 
-       err++;
-     
-    if (db_env != NULL && (ret = db_env->close(db_env, 0))) { 
-        LOG(log_error, logtype_cnid, "error closing DB environment: %s", db_strerror(ret));
-        err++;
-    }
-    if (db_errlog != NULL && fclose(db_errlog) == EOF) {
-        LOG(log_error, logtype_cnid, "error closing DB logfile: %s", strerror(errno));
-        err++;
-    }
-    if (err)
-        return -1;
-    return 0;
-}
-/* --------------- */
-static int upgrade_required(void)
-{
-    int i;
-    int found = 0;
-    struct stat st;
-    
-    for (i = 0; old_dbfiles[i] != NULL; i++) {
-       if ( !(stat(old_dbfiles[i], &st) < 0) ) {
-           found++;
-           continue;
-       }
-       if (errno != ENOENT) {
-           LOG(log_error, logtype_cnid, "cnid_open: Checking %s gave %s", old_dbfiles[i], strerror(errno));
-           found++;
-       }
-    }
-    return found;
-}
-
-/* -------------------------- */
-static int dbif_sync(void)
-{
-    int i;
-    int ret;
-    int err = 0;
-     
-    for (i = 0; i != /* DBIF_DB_CNT*/ 1; i++) {
-        if ((ret = db_table[i].db->sync(db_table[i].db, 0))) {
-            LOG(log_error, logtype_cnid, "error syncing database %s: %s", db_table[i].name, db_strerror(ret));
-            err++;
-        }
-    }
-    if (err)
-        return -1;
-    else
-        return 0;
-}
-
-/* -------------------------- */
-static int dbif_count(const int dbi, u_int32_t *count) 
-{
-    int ret;
-    DB_BTREE_STAT *sp;
-    DB *db = db_table[dbi].db;
-
-#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3)
-    ret = db->stat(db, db_txn, &sp, 0);
-#else
-    ret = db->stat(db, &sp, 0);
-#endif
-
-    if (ret) {
-        LOG(log_error, logtype_cnid, "error getting stat infotmation on database: %s", db_strerror(errno));
-        return -1;
-    }
-
-    *count = sp->bt_ndata;
-    free(sp);
-
-    return 0;
-}
-
-/* -------------------------- */
-static int dbd_check(char *dbdir)
-{
-    u_int32_t c_didname = 0, c_devino = 0, c_cnid = 0;
-
-    LOG(log_debug, logtype_cnid, "CNID database at `%s' is being checked (quick)", dbdir);
-
-    if (dbif_count(DBIF_IDX_CNID, &c_cnid)) 
-        return -1;
-
-    if (dbif_count(DBIF_IDX_DEVINO, &c_devino))
-        return -1;
-
-    /* bailout after the first error */
-    if ( c_cnid != c_devino) {
-        LOG(log_error, logtype_cnid, "CNID database at `%s' corrupted (%u/%u)", dbdir, c_cnid, c_devino);
-        return 1;
-    }
-
-    if (dbif_count(DBIF_IDX_DIDNAME, &c_didname)) 
-        return -1;
-
-    if ( c_cnid != c_didname) {
-        LOG(log_error, logtype_cnid, "CNID database at `%s' corrupted (%u/%u)", dbdir, c_cnid, c_didname);
-        return 1;
-    }
-
-    LOG(log_debug, logtype_cnid, "CNID database at `%s' seems ok, %u entries.", dbdir, c_cnid);
-    return 0;  
-}
-
-/* --------------- */
-/*
- *  We assume our current directory is already the BDB homedir. Otherwise
- *  opening the databases will not work as expected. If we use transactions,
- *  dbif_env_init(), dbif_close() and dbif_stamp() are the only interface
- *  functions that can be called without a valid transaction handle in db_txn.
- */
-static int dbif_env_init(void)
-{
-    int ret;
-#ifdef CNID_BACKEND_DBD_TXN
-    char **logfiles = NULL;
-    char **file;
-#endif
-
-    /* Refuse to do anything if this is an old version of the CNID database */
-    if (upgrade_required()) {
-       LOG(log_error, logtype_cnid, "Found version 1 of the CNID database. Please upgrade to version 2");
-       return -1;
-    }
-
-    if ((db_errlog = fopen(DB_ERRLOGFILE, "a")) == NULL)
-        LOG(log_warning, logtype_cnid, "error creating/opening DB errlogfile: %s", strerror(errno));
-
-#ifdef CNID_BACKEND_DBD_TXN
-    if ((ret = db_env_create(&db_env, 0))) {
-        LOG(log_error, logtype_cnid, "error creating DB environment: %s", 
-            db_strerror(ret));
-        db_env = NULL;
-        return -1;
-    }    
-    if (db_errlog != NULL)
-        db_env->set_errfile(db_env, db_errlog); 
-    db_env->set_verbose(db_env, DB_VERB_RECOVERY, 1);
-    if ((ret = db_env->open(db_env, ".", DBOPTIONS | DB_PRIVATE | DB_RECOVER, 0))) {
-        LOG(log_error, logtype_cnid, "error opening DB environment: %s", 
-            db_strerror(ret));
-        db_env->close(db_env, 0);
-        db_env = NULL;
-        return -1;
-    }
-
-    if (db_errlog != NULL)
-        fflush(db_errlog);
-
-    if ((ret = db_env->close(db_env, 0))) {
-        LOG(log_error, logtype_cnid, "error closing DB environment after recovery: %s", 
-            db_strerror(ret));
-        db_env = NULL;
-        return -1;
-    }
-#endif
-    if ((ret = db_env_create(&db_env, 0))) {
-        LOG(log_error, logtype_cnid, "error creating DB environment after recovery: %s",
-            db_strerror(ret));
-        db_env = NULL;
-        return -1;
-    }
-    if (db_errlog != NULL)
-        db_env->set_errfile(db_env, db_errlog);
-    if ((ret = db_env->open(db_env, ".", DBOPTIONS , 0))) {
-        LOG(log_error, logtype_cnid, "error opening DB environment after recovery: %s",
-            db_strerror(ret));
-        db_env->close(db_env, 0);
-        db_env = NULL;
-        return -1;      
-    }
-
-#ifdef CNID_BACKEND_DBD_TXN
-    if (db_env->log_archive(db_env, &logfiles, 0)) {
-       LOG(log_error, logtype_cnid, "error getting list of stale logfiles: %s",
-            db_strerror(ret));
-        db_env->close(db_env, 0);
-        db_env = NULL;
-        return -1;
-    }
-    if (logfiles != NULL) {
-       for (file = logfiles; *file != NULL; file++) {
-           if (unlink(*file) < 0)
-               LOG(log_warning, logtype_cnid, "Error removing stale logfile %s: %s", *file, strerror(errno));
-       }
-       free(logfiles);
-    }
-#endif
-    return 0;
-}
-
-
-static void sig_exit(int signo)
-{
-    exit_sig = signo;
-    return;
-}
-
-static void block_sigs_onoff(int block)
-{
-    sigset_t set;
-    
-    sigemptyset(&set);
-    sigaddset(&set, SIGINT);
-    sigaddset(&set, SIGTERM);
-    if (block)
-        sigprocmask(SIG_BLOCK, &set, NULL);
-    else
-        sigprocmask(SIG_UNBLOCK, &set, NULL);
-    return;
-}
-
-/* ------------------------ */
-int get_lock(void)
-{
-    int lockfd;
-    struct flock lock;
-
-    if ((lockfd = open(LOCKFILENAME, O_RDWR | O_CREAT, 0644)) < 0) {
-       LOG(log_error, logtype_cnid, "main: error opening lockfile: %s", strerror(errno));
-       exit(1);
-    }
-    
-    lock.l_start  = 0;
-    lock.l_whence = SEEK_SET;
-    lock.l_len    = 0;
-    lock.l_type   = F_WRLCK;
-
-    if (fcntl(lockfd, F_SETLK, &lock) < 0) {
-       if (errno == EACCES || errno == EAGAIN) {
-           exit(0);
-       } else {
-           LOG(log_error, logtype_cnid, "main: fcntl F_WRLCK lockfile: %s", strerror(errno));
-           exit(1);
-       }
-    }
-    
-    return lockfd;
-}
-
-/* ----------------------- */
-void set_signal(void)
-{
-    struct sigaction sv;
-
-    sv.sa_handler = sig_exit;
-    sv.sa_flags = 0;
-    sigemptyset(&sv.sa_mask);
-    sigaddset(&sv.sa_mask, SIGINT);
-    sigaddset(&sv.sa_mask, SIGTERM);
-    if (sigaction(SIGINT, &sv, NULL) < 0 || sigaction(SIGTERM, &sv, NULL) < 0) {
-        LOG(log_error, logtype_cnid, "main: sigaction: %s", strerror(errno));
-        exit(1);
-    }
-    sv.sa_handler = SIG_IGN;
-    sigemptyset(&sv.sa_mask);
-    if (sigaction(SIGPIPE, &sv, NULL) < 0) {
-        LOG(log_error, logtype_cnid, "main: sigaction: %s", strerror(errno));
-        exit(1);
-    }
-}
-
-/* ----------------------- */
-void free_lock(int lockfd)
-{
-    struct flock lock;
-
-    lock.l_start  = 0;
-    lock.l_whence = SEEK_SET;
-    lock.l_len    = 0;
-    lock.l_type = F_UNLCK;
-    fcntl(lockfd, F_SETLK, &lock);
-    close(lockfd);
-}
-
-/* ------------------------ */
-int main(int argc, char *argv[])
-{
-#ifdef CNID_BACKEND_DBD_TXN
-
-    fprintf(stderr, "%s doesn't work with db transaction enabled\n", argv[0]);
-    exit (1);
-    
-#else
-    int err = 0;
-    int ret;
-    int lockfd;
-    char *dir;
-       
-    set_processname("cnid_index");
-    syslog_setup(log_debug, logtype_default, logoption_ndelay | logoption_pid, logfacility_daemon);
-    
-    if (argc  != 2) {
-        LOG(log_error, logtype_cnid, "main: not enough arguments");
-        exit(1);
-    }
-
-    dir = argv[1];
-
-    if (chdir(dir) < 0) {
-        LOG(log_error, logtype_cnid, "chdir to %s failed: %s", dir, strerror(errno));
-        exit(1);
-    }
-    
-    /* Before we do anything else, check if there is an instance of cnid_dbd
-       running already and silently exit if yes. */
-    lockfd = get_lock();
-    
-    LOG(log_info, logtype_cnid, "Startup, DB dir %s", dir);
-    
-    set_signal();
-    
-    /* SIGINT and SIGTERM are always off, unless we get a return code of 0 from
-       comm_rcv (no requests for one second, see above in loop()). That means we
-       only shut down after one second of inactivity. */
-    block_sigs_onoff(1);
-
-    if (dbif_env_init() < 0)
-        exit(2); /* FIXME: same exit code as failure for dbif_open() */  
-    
-#ifdef CNID_BACKEND_DBD_TXN
-    if (dbif_txn_begin() < 0)
-       exit(6);
-#endif
-    
-    if (dbif_open(0) < 0) {
-#ifdef CNID_BACKEND_DBD_TXN
-       dbif_txn_abort();
-#endif
-        dbif_close();
-        exit(2);
-    }
-
-#ifndef CNID_BACKEND_DBD_TXN
-    if ((ret = dbd_check(dir))) {
-        if (ret < 0) {
-            dbif_close();
-            exit(2);
-        }
-        dbif_closedb();
-       LOG(log_info, logtype_cnid, "main: re-opening, secondaries will be rebuilt. This may take some time");
-        if (dbif_open(1) < 0) {
-           LOG(log_info, logtype_cnid, "main: re-opening databases failed");
-            dbif_close();
-            exit(2);
-        }
-       LOG(log_info, logtype_cnid, "main: rebuilt done");
-    }
-#endif
-
-#ifdef CNID_BACKEND_DBD_TXN
-    if (dbif_txn_commit() < 0)
-       exit(6);
-#endif
-
-#ifndef CNID_BACKEND_DBD_TXN
-    /* FIXME: Do we really need to sync before closing the DB? Just closing it
-       should be enough. */
-    if (dbif_sync() < 0)
-        err++;
-#endif
-
-    if (dbif_close() < 0)
-        err++;
-        
-    free_lock(lockfd);
-    
-    if (err)
-        exit(4);
-#endif
-    return 0;
-}
index c644a1c6af3b2211071ca31cfddc0def21eb029b..4425151ae2617a9bae74f1d1b8b659ba44b062cb 100644 (file)
@@ -1,4 +1,4 @@
-dnl $Id: configure.in,v 1.216 2009-04-22 08:06:01 franklahm Exp $
+dnl $Id: configure.in,v 1.217 2009-04-28 13:01:24 franklahm Exp $
 dnl configure.in for netatalk
 
 AC_INIT(etc/afpd/main.c)
@@ -22,6 +22,8 @@ AC_PROG_PERL
 AC_PROG_GREP
 AC_PROG_PS
 
+AM_PROG_CC_C_O
+
 dnl *********************************************************************
 dnl FIXME! FIXME! These should be selectable properly, and should produce
 dnl the proper flags and defines...
index 324b88b9bdc9c252ff67fbf791ebefa59ae4f76a..6d7799176b8e61b2b39f16a5a7b02a2f51ebc98a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: volume.c,v 1.85 2009-04-27 07:58:25 franklahm Exp $
+ * $Id: volume.c,v 1.86 2009-04-28 13:01:24 franklahm Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -43,6 +43,7 @@ char *strchr (), *strrchr ();
 #include <atalk/adouble.h>
 #include <atalk/afp.h>
 #include <atalk/util.h>
+#include <atalk/volinfo.h>
 #include <atalk/logger.h>
 #ifdef CNID_DB
 #include <atalk/cnid.h>
index 20051a6e3404e23dc81ef2dfd4b9c6d7676e8e5d..fbde4afbe738e00e0e5989b25a46c08996a9fe08 100644 (file)
@@ -2,6 +2,7 @@
 
 if BUILD_DBD_DAEMON
 sbin_PROGRAMS = cnid_dbd cnid_metad
+bin_PROGRAMS = dbd
 else
 sbin_PROGRAMS =
 endif
@@ -10,17 +11,17 @@ cnid_dbd_SOURCES = dbif.c pack.c comm.c db_param.c main.c \
                    dbd_add.c dbd_get.c dbd_resolve.c dbd_lookup.c \
                    dbd_update.c dbd_delete.c dbd_getstamp.c \
                    dbd_rebuild_add.c dbd_dbcheck.c
-
 cnid_dbd_LDADD = $(top_builddir)/libatalk/libatalk.la @BDB_LIBS@
 
 cnid_metad_SOURCES = cnid_metad.c usockfd.c db_param.c
-
 cnid_metad_LDADD = $(top_builddir)/libatalk/libatalk.la
 
+dbd_SOURCES = dbd.c dbif.c pack.c
+dbd_CFLAGS = $(AM_CFLAGS)
+dbd_LDADD = $(top_builddir)/libatalk/libatalk.la @BDB_LIBS@
+
 noinst_HEADERS = dbif.h pack.h db_param.h dbd.h usockfd.h comm.h
 
 EXTRA_DIST = README
 
-
-AM_CFLAGS = @CFLAGS@ @BDB_CFLAGS@ \
-         -D_PATH_CNID_DBD=\"$(sbindir)/cnid_dbd\"
+AM_CFLAGS = @BDB_CFLAGS@ -D_PATH_CNID_DBD=\"$(sbindir)/cnid_dbd\"
diff --git a/etc/cnid_dbd/dbd.c b/etc/cnid_dbd/dbd.c
new file mode 100644 (file)
index 0000000..47af6fe
--- /dev/null
@@ -0,0 +1,322 @@
+/* 
+   $Id: dbd.c,v 1.1 2009-04-28 13:01:24 franklahm Exp $
+
+   Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+
+#include <atalk/logger.h>
+#include <atalk/cnid_dbd_private.h>
+#include <atalk/volinfo.h>
+#include "dbif.h"
+#include "db_param.h"
+
+#define LOCKFILENAME  "lock"
+#define DBOPTIONS (DB_CREATE | DB_INIT_LOCK | DB_INIT_MPOOL | DB_INIT_TXN)
+
+enum logtype {LOGSTD, LOGDEBUG};
+
+static volatile sig_atomic_t alarmed;
+static int verbose; /* Logging flag */
+static int exclusive;  /* How to open the bdb database */
+static struct volinfo volinfo;
+static struct db_param db_param = {
+    NULL,                       /* Volume dirpath */
+    1,                          /* bdb logfile autoremove */
+    16384,                      /* bdb cachesize */
+    -1,                         /* not used ... */
+    -1,
+    "",
+    -1,
+    -1,
+    -1
+};
+
+/* 
+   Provide some logging
+ */
+static void dblog(enum logtype lt, char *fmt, ...)
+{
+    int len;
+    static char logbuffer[1024];
+    va_list args;
+
+    if ( (lt == LOGSTD) || (verbose == 1)) {
+        va_start(args, fmt);
+        len = vsnprintf(logbuffer, 1023, fmt, args);
+        va_end(args);
+        logbuffer[1023] = 0;
+
+        printf("%s\n", logbuffer);
+    }
+}
+
+/* 
+   SIGNAL handling:
+   ignore everything except SIGTERM which we catch and which causes
+   a clean exit.
+ */
+
+static void sig_handler(int signo)
+{
+    alarmed = 1;
+    return;
+}
+
+void set_signal(void)
+{
+    struct sigaction sv;
+
+    sv.sa_handler = sig_handler;
+    sv.sa_flags = SA_RESTART;
+    sigemptyset(&sv.sa_mask);
+    sigaddset(&sv.sa_mask, SIGTERM);
+    if (sigaction(SIGTERM, &sv, NULL) < 0) {
+        dblog( LOGSTD, "error in sigaction(SIGTERM): %s", strerror(errno));
+        exit(EXIT_FAILURE);
+    }        
+
+    sv.sa_handler = SIG_IGN;
+    memset(&sv, 0, sizeof(struct sigaction));
+    sigemptyset(&sv.sa_mask);
+
+    if (sigaction(SIGINT, &sv, NULL) < 0) {
+        dblog( LOGSTD, "error in sigaction(SIGINT): %s", strerror(errno));
+        exit(EXIT_FAILURE);
+    }        
+    if (sigaction(SIGABRT, &sv, NULL) < 0) {
+        dblog( LOGSTD, "error in sigaction(SIGABRT): %s", strerror(errno));
+        exit(EXIT_FAILURE);
+    }        
+    if (sigaction(SIGHUP, &sv, NULL) < 0) {
+        dblog( LOGSTD, "error in sigaction(SIGHUP): %s", strerror(errno));
+        exit(EXIT_FAILURE);
+    }        
+    if (sigaction(SIGQUIT, &sv, NULL) < 0) {
+        dblog( LOGSTD, "error in sigaction(SIGQUIT): %s", strerror(errno));
+        exit(EXIT_FAILURE);
+    }        
+}
+
+#if 0
+static void block_sigs_onoff(int block)
+{
+    sigset_t set;
+    
+    sigemptyset(&set);
+    sigaddset(&set, SIGINT);
+    sigaddset(&set, SIGTERM);
+    if (block)
+        sigprocmask(SIG_BLOCK, &set, NULL);
+    else
+        sigprocmask(SIG_UNBLOCK, &set, NULL);
+    return;
+}
+#endif
+
+int get_lock(void)
+{
+    int lockfd;
+    struct flock lock;
+
+    if ((lockfd = open(LOCKFILENAME, O_RDWR | O_CREAT, 0644)) < 0) {
+        dblog( LOGSTD, "Error opening lockfile: %s", strerror(errno));
+        exit(EXIT_FAILURE);
+    }
+    
+    lock.l_start  = 0;
+    lock.l_whence = SEEK_SET;
+    lock.l_len    = 0;
+    lock.l_type   = F_WRLCK;
+
+    if (fcntl(lockfd, F_SETLK, &lock) < 0) {
+        if (errno == EACCES || errno == EAGAIN) {
+            if (exclusive) {
+                dblog( LOGDEBUG, "Database is in use and exlusive was requested", strerror(errno));        
+                exit(EXIT_FAILURE);
+            };
+        } else {
+            dblog( LOGSTD, "Error getting fcntl F_WRLCK on lockfile: %s", strerror(errno));
+            exit(EXIT_FAILURE);
+       }
+    }
+    
+    return lockfd;
+}
+
+void free_lock(int lockfd)
+{
+    struct flock lock;
+
+    lock.l_start  = 0;
+    lock.l_whence = SEEK_SET;
+    lock.l_len    = 0;
+    lock.l_type = F_UNLCK;
+    fcntl(lockfd, F_SETLK, &lock);
+    close(lockfd);
+}
+
+static void usage ()
+{
+    printf("Usage: dbd [-e|-v|-x] -d [-i] | -s | -r [-f] <path to netatalk volume>\n"
+           "dbd can dump, scan, reindex and rebuild Netatalk dbd CNID databases.\n"
+           "dbd must run with appropiate permissions i.e. as root.\n\n"
+           "Main commands are:\n"
+           "   -d dump\n"
+           "      Dump CNID database\n"
+           "      Option: -i dump indexes too\n"
+           "   -s scan\n"
+           "      Compare database with volume\n"
+           "   -r rebuild\n"
+           "      Rebuild CNID database\n"
+           "      Option: -f wipe database and rebuild from IDs stored in AppleDouble files\n\n"
+           "General options:\n"
+           "   -e only work on inactive volumes and lock them (exclusive)\n"
+           "   -x rebuild indexes\n"
+           "   -v verbose\n"
+           "\n"
+           "28-04-2009: -s and -r and not yet implemented\n"
+        );
+}
+
+int main(int argc, char **argv)
+{
+    int c, ret, lockfd;
+    int dump=0, scan=0, rebuild=0, rebuildindexes=0, dumpindexes=0, force=0;
+    char *volpath;
+
+    if (geteuid() != 0) {
+        usage();
+        exit(EXIT_FAILURE);
+    }
+
+    while ((c = getopt(argc, argv, ":dsrvxif")) != -1) {
+        switch(c) {
+        case 'd':
+            dump = 1;
+            break;
+        case 'i':
+            dumpindexes = 1;
+            break;
+        case 's':
+            scan = 1;
+            break;
+        case 'r':
+            rebuild = 1;
+            break;
+        case 'v':
+            verbose = 1;
+            break;
+        case 'e':
+            exclusive = 1;
+            break;
+        case 'x':
+            rebuildindexes = 1;
+            break;
+        case 'f':
+            force = 1;
+            break;
+        case ':':
+        case '?':
+            usage();
+            exit(EXIT_FAILURE);
+            break;
+        }
+    }
+
+    if ((dump + scan + rebuild) != 1) {
+        usage();
+        exit(EXIT_FAILURE);
+    }
+
+    if ( (optind + 1) != argc ) {
+        usage();
+        exit(EXIT_FAILURE);
+    }
+    volpath = argv[optind];
+
+    /* Put "/.AppleDB" at end of volpath */
+    if ( (strlen(volpath) + strlen("/.AppleDB")) > (PATH_MAX -1) ) {
+        dblog( LOGSTD, "Volume pathname too long");
+        exit(EXIT_FAILURE);        
+    }
+    char dbpath[PATH_MAX];
+    strncpy(dbpath, volpath, PATH_MAX - 1);
+    strcat(dbpath, "/.AppleDB");
+
+    if ( -1 == (ret = loadvolinfo(volpath, &volinfo)) ) {
+        dblog( LOGSTD, "Unkown volume options!");
+        exit(EXIT_FAILURE);
+    }
+    
+    if (chdir(dbpath) < 0) {
+        dblog( LOGSTD, "chdir to %s failed: %s", dbpath, strerror(errno));
+        exit(EXIT_FAILURE);
+    }
+    
+    /* 
+       Before we do anything else, check if there is an instance of cnid_dbd
+       running already and silently exit if yes.
+    */
+    lockfd = get_lock();
+    
+    /* Ignore everything except SIGTERM */
+    set_signal();
+
+    /* Setup logging. Should be portable among *NIXes */
+    if (!verbose)
+        setuplog("default log_info /dev/tty");
+    else
+        setuplog("default log_debug /dev/tty");
+
+    /* 
+       Lets start with the BerkeleyDB stuff
+    */
+    if (dbif_env_init(&db_param, DBOPTIONS) < 0) {
+        dblog( LOGSTD, "error opening database!");
+        exit(EXIT_FAILURE);
+    }
+
+    dblog( LOGDEBUG, "Finished opening BerkeleyDB databases including recovery.");
+
+    if (dbif_open(&db_param, rebuildindexes) < 0) {
+        dbif_close();
+        exit(EXIT_FAILURE);
+    }
+
+    if (dump) {
+        if (dbif_dump(dumpindexes) < 0) {
+            dblog( LOGSTD, "Error dumping database");
+        }
+    }
+
+    if (dbif_close() < 0)
+        exit(EXIT_FAILURE);
+
+    free_lock(lockfd);
+
+    return 0;
+}
index 1920838a8ceea1cc1bc464d7129760a0e7c8d0e6..36131442945e78ed248b2c1375e14d006c0d829b 100644 (file)
@@ -1,7 +1,8 @@
 /*
- * $Id: dbif.c,v 1.6 2009-04-21 10:18:44 franklahm Exp $
+ * $Id: dbif.c,v 1.7 2009-04-28 13:01:24 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
+ * Copyright (C) Frank Lahm 2009
  * All Rights Reserved.  See COPYING.
  */
 
@@ -24,6 +25,7 @@
 #include <db.h>
 #include "db_param.h"
 #include "dbif.h"
+#include "pack.h"
 
 #define DB_ERRLOGFILE "db_errlog"
 
@@ -31,12 +33,6 @@ static DB_ENV *db_env = NULL;
 static DB_TXN *db_txn = NULL;
 static FILE   *db_errlog = NULL;
 
-/* 
-   Note: DB_INIT_LOCK is here so we can run the db_* utilities while netatalk is running.
-   It's a likey performance hit, but it might we worth it.
- */
-#define DBOPTIONS    (DB_CREATE | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN)
-
 static struct db_table {
     char            *name;
     DB              *db;
@@ -51,9 +47,6 @@ static struct db_table {
 
 static char *old_dbfiles[] = {"cnid.db", NULL};
 
-extern int didname(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
-extern int devino(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
-
 /* --------------- */
 static int  db_compat_associate (DB *p, DB *s,
                                  int (*callback)(DB *, const DBT *,const DBT *, DBT *),
@@ -121,7 +114,7 @@ int dbif_stamp(void *buffer, int size)
  *  We assume our current directory is already the BDB homedir. Otherwise
  *  opening the databases will not work as expected.
  */
-int dbif_env_init(struct db_param *dbp)
+int dbif_env_init(struct db_param *dbp, uint32_t dbenv_oflags)
 {
     int ret;
     char **logfiles = NULL;
@@ -151,7 +144,7 @@ int dbif_env_init(struct db_param *dbp)
     db_env->set_verbose(db_env, DB_VERB_RECOVERY, 1);
 
     /* Open the database for recovery using DB_PRIVATE option which is faster */
-    if ((ret = db_env->open(db_env, ".", DBOPTIONS | DB_PRIVATE | DB_RECOVER, 0))) {
+    if ((ret = db_env->open(db_env, ".", dbenv_oflags | DB_PRIVATE | DB_RECOVER, 0))) {
         LOG(log_error, logtype_cnid, "error opening DB environment: %s",
             db_strerror(ret));
         db_env->close(db_env, 0);
@@ -188,7 +181,7 @@ int dbif_env_init(struct db_param *dbp)
         db_env->set_errfile(db_env, db_errlog);
         db_env->set_msgfile(db_env, db_errlog);
     }
-    if ((ret = db_env->open(db_env, ".", DBOPTIONS , 0))) {
+    if ((ret = db_env->open(db_env, ".", dbenv_oflags, 0))) {
         LOG(log_error, logtype_cnid, "error opening DB environment after recovery: %s",
             db_strerror(ret));
         db_env->close(db_env, 0);
@@ -270,6 +263,7 @@ int dbif_open(struct db_param *dbp _U_, int do_truncate)
             db_table[i].db->set_errfile(db_table[i].db, db_errlog);
 
         if (do_truncate && i > 0) {
+            LOG(log_info, logtype_cnid, "Truncating CNID index.");
             if ((ret = db_table[i].db->truncate(db_table[i].db, NULL, &count, 0))) {
                 LOG(log_error, logtype_cnid, "error truncating database %s: %s",
                     db_table[i].name, db_strerror(ret));
@@ -281,15 +275,19 @@ int dbif_open(struct db_param *dbp _U_, int do_truncate)
     /* TODO: Implement CNID DB versioning info on new databases. */
 
     /* Associate the secondary with the primary. */
+    LOG(log_debug, logtype_cnid, "Associating DBIF_IDX_DIDNAME index. Possibly reindexing...");
     if ((ret = db_compat_associate(db_table[0].db, db_table[DBIF_IDX_DIDNAME].db, didname, (do_truncate)?DB_CREATE:0)) != 0) {
         LOG(log_error, logtype_cnid, "Failed to associate didname database: %s",db_strerror(ret));
         return -1;
     }
+    LOG(log_debug, logtype_cnid, "... done.");
 
+    LOG(log_debug, logtype_cnid, "Associating DBIF_IDX_DEVINO index. Possibly reindexing...");
     if ((ret = db_compat_associate(db_table[0].db, db_table[DBIF_IDX_DEVINO].db, devino, (do_truncate)?DB_CREATE:0)) != 0) {
         LOG(log_error, logtype_cnid, "Failed to associate devino database: %s",db_strerror(ret));
         return -1;
     }
+    LOG(log_debug, logtype_cnid, "... done.");
 
     return 0;
 }
@@ -504,4 +502,160 @@ int dbif_count(const int dbi, u_int32_t *count)
     return 0;
 }
 
+int dbif_dump(int dumpindexes)
+{
+    int rc;
+    uint32_t max = 0, count = 0, cnid, type, did;
+    uint64_t dev, ino;
+    DBC *cur;
+    DBT key = { 0 }, data = { 0 };
+    DB *db = db_table[DBIF_IDX_CNID].db;
+    char *typestring[2] = {"f", "d"};
+
+    printf("CNID database:\n");
+
+    rc = db->cursor(db, NULL, &cur, 0);
+    if (rc) {
+        LOG(log_error, logtype_cnid, "Couldn't create cursor: %s", db_strerror(errno));
+        return -1;
+    }
+
+    cur->c_get(cur, &key, &data, DB_FIRST);
+    while (rc == 0) {
+        /* Parse and print data */
+        memcpy(&cnid, key.data, 4);
+        cnid = ntohl(cnid);
+        if (cnid > max)
+            max = cnid;
+
+        /* Rootinfo node ? */
+        if (cnid == 0) {
+        } else {
+            /* dev */
+            memcpy(&dev, data.data + CNID_DEV_OFS, 8);
+            dev = ntoh64(dev);
+            /* ino */
+            memcpy(&ino, data.data + CNID_INO_OFS, 8);
+            ino = ntoh64(ino);
+            /* type */
+            memcpy(&type, data.data + CNID_TYPE_OFS, 4);
+            type = ntohl(type);
+            /* did */
+            memcpy(&did, data.data + CNID_DID_OFS, 4);
+            did = ntohl(did);
+
+            count++;
+            printf("id: %10u, did: %10u, type: %s, dev: 0x%llx, ino: 0x%016llx, name: %s\n", 
+                   cnid, did, typestring[type],
+                   (long long unsigned int)dev, (long long unsigned int)ino, 
+                   (char *)data.data + CNID_NAME_OFS);
+
+        }
+
+        rc = cur->c_get(cur, &key, &data, DB_NEXT);
+    }
+
+    if (rc != DB_NOTFOUND) {
+        LOG(log_error, logtype_cnid, "Error iterating over btree: %s", db_strerror(errno));
+        return -1;
+    }
+
+    rc = cur->c_close(cur);
+    if (rc) {
+        LOG(log_error, logtype_cnid, "Couldn't close cursor: %s", db_strerror(errno));
+        return -1;
+    }
+    printf("%u CNIDs in database. Max CNID: %u.\n", count, max);
+
+    /* Dump indexes too ? */
+    if (dumpindexes) {
+        /* DBIF_IDX_DEVINO */
+        printf("\ndev/inode index:\n");
+        count = 0;
+        db = db_table[DBIF_IDX_DEVINO].db;
+        rc = db->cursor(db, NULL, &cur, 0);
+        if (rc) {
+            LOG(log_error, logtype_cnid, "Couldn't create cursor: %s", db_strerror(errno));
+            return -1;
+        }
+        
+        cur->c_get(cur, &key, &data, DB_FIRST);
+        while (rc == 0) {
+            /* Parse and print data */
+
+            /* cnid */
+            memcpy(&cnid, data.data, CNID_LEN);
+            cnid = ntohl(cnid);
+            if (cnid == 0) {
+                /* Rootinfo node */
+            } else {
+                /* dev */
+                memcpy(&dev, key.data, CNID_DEV_LEN);
+                dev = ntoh64(dev);
+                /* ino */
+                memcpy(&ino, key.data + CNID_DEV_LEN, CNID_INO_LEN);
+                ino = ntoh64(ino);
+                
+                printf("id: %10u <== dev: 0x%llx, ino: 0x%016llx\n", 
+                       cnid, (unsigned long long int)dev, (unsigned long long int)ino);
+                count++;
+            }
+            rc = cur->c_get(cur, &key, &data, DB_NEXT);
+        }
+        if (rc != DB_NOTFOUND) {
+            LOG(log_error, logtype_cnid, "Error iterating over btree: %s", db_strerror(errno));
+            return -1;
+        }
+        
+        rc = cur->c_close(cur);
+        if (rc) {
+            LOG(log_error, logtype_cnid, "Couldn't close cursor: %s", db_strerror(errno));
+            return -1;
+        }
+        printf("%u items\n", count);
+
+        /* Now dump DBIF_IDX_DIDNAME */
+        printf("\ndid/name index:\n");
+        count = 0;
+        db = db_table[DBIF_IDX_DIDNAME].db;
+        rc = db->cursor(db, NULL, &cur, 0);
+        if (rc) {
+            LOG(log_error, logtype_cnid, "Couldn't create cursor: %s", db_strerror(errno));
+            return -1;
+        }
+        
+        cur->c_get(cur, &key, &data, DB_FIRST);
+        while (rc == 0) {
+            /* Parse and print data */
+
+            /* cnid */
+            memcpy(&cnid, data.data, CNID_LEN);
+            cnid = ntohl(cnid);
+            if (cnid == 0) {
+                /* Rootinfo node */
+            } else {
+                /* did */
+                memcpy(&did, key.data, CNID_LEN);
+                did = ntohl(did);
+
+                printf("id: %10u <== did: %10u, name: %s\n", cnid, did, (char *)key.data + CNID_LEN);
+                count++;
+            }
+            rc = cur->c_get(cur, &key, &data, DB_NEXT);
+        }
+        if (rc != DB_NOTFOUND) {
+            LOG(log_error, logtype_cnid, "Error iterating over btree: %s", db_strerror(errno));
+            return -1;
+        }
+        
+        rc = cur->c_close(cur);
+        if (rc) {
+            LOG(log_error, logtype_cnid, "Couldn't close cursor: %s", db_strerror(errno));
+            return -1;
+        }
+        printf("%u items\n", count);
+    }
+
+    return 0;
+}
 
index 0939ceb971486a10967ed0b9d56dbd839c98a1ad..0953f72f81730d50fe50894a24f7f2db40c2eb6f 100644 (file)
@@ -1,7 +1,8 @@
 /*
- * $Id: dbif.h,v 1.3 2009-04-21 08:55:44 franklahm Exp $
+ * $Id: dbif.h,v 1.4 2009-04-28 13:01:24 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
+ * Copyright (C) Frank Lahm 2009
  * All Rights Reserved.  See COPYING.
  */
 
 #define DBIF_IDX_DEVINO    1
 #define DBIF_IDX_DIDNAME   2
 
-extern int        dbif_stamp  __P((void *, int));
-extern int        dbif_env_init  __P((struct db_param *));
-extern int        dbif_open  __P((struct db_param *, int));
-extern int        dbif_close __P((void));
-extern int        dbif_closedb __P((void));
-extern int        dbif_get __P((const int, DBT *, DBT *, u_int32_t));
-extern int        dbif_pget __P((const int, DBT *, DBT *, DBT *, u_int32_t));
-extern int        dbif_put __P((const int, DBT *, DBT *, u_int32_t));
-extern int        dbif_del __P((const int, DBT *, u_int32_t));
+extern int dbif_stamp(void *, int);
+extern int dbif_env_init(struct db_param *, uint32_t);
+extern int dbif_open(struct db_param *, int);
+extern int dbif_close(void);
+extern int dbif_closedb(void);
+extern int dbif_get(const int, DBT *, DBT *, u_int32_t);
+extern int dbif_pget(const int, DBT *, DBT *, DBT *, u_int32_t);
+extern int dbif_put(const int, DBT *, DBT *, u_int32_t);
+extern int dbif_del(const int, DBT *, u_int32_t);
 
-extern int        dbif_count __P((const int, u_int32_t *));
+extern int dbif_count(const int, u_int32_t *);
 
-extern int        dbif_txn_begin  __P((void));
-extern int        dbif_txn_commit  __P((void));
-extern int        dbif_txn_abort  __P((void));
-extern int        dbif_txn_checkpoint  __P((u_int32_t, u_int32_t, u_int32_t));
+extern int dbif_txn_begin(void);
+extern int dbif_txn_commit(void);
+extern int dbif_txn_abort(void);
+extern int dbif_txn_checkpoint(u_int32_t, u_int32_t, u_int32_t);
 
+extern int dbif_dump(int dumpindexes);
 #endif
index d1dde1bbf640bcd0ebd3c1f647c8df71dddb7c18..4a3f42c80e32f535baca7e232b03deb488a85baa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: main.c,v 1.4 2009-04-21 08:55:44 franklahm Exp $
+ * $Id: main.c,v 1.5 2009-04-28 13:01:24 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * Copyright (c) Frank Lahm 2009
 #include "dbd.h"
 #include "comm.h"
 
-
 #define LOCKFILENAME  "lock"
 
-static int exit_sig = 0;
+/* 
+   Note: DB_INIT_LOCK is here so we can run the db_* utilities while netatalk is running.
+   It's a likey performance hit, but it might we worth it.
+ */
+#define DBOPTIONS (DB_CREATE | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN)
 
+static int exit_sig = 0;
 
 static void sig_exit(int signo)
 {
@@ -345,7 +349,7 @@ int main(int argc, char *argv[])
         exit(1);
     LOG(log_maxdebug, logtype_cnid, "Finished parsing db_param config file");
 
-    if (dbif_env_init(dbp) < 0)
+    if (dbif_env_init(dbp, DBOPTIONS) < 0)
         exit(2); /* FIXME: same exit code as failure for dbif_open() */
     LOG(log_debug, logtype_cnid, "Finished initializing BerkeleyDB environment");
 
index b1fd85ae0f512eba91651501f4fdac92b4e1fd37..02a73075f953d295f763b629d43f99794566f060 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: pack.c,v 1.3 2005-05-03 14:55:11 didg Exp $
+ * $Id: pack.c,v 1.4 2009-04-28 13:01:24 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYING.
@@ -130,7 +130,7 @@ char *stringify_devino(dev_t dev, ino_t ino)
     char *end;
     int   ci;
 
-    pack_devino(buf, dev, ino);
+    pack_devino((unsigned char *)buf, dev, ino);
     
     middle = buf + CNID_DEV_LEN;
     end = buf + CNID_DEV_LEN + CNID_INO_LEN;
index c7f255b59c33e3a84eebe20354d7c36e08faace5..63f18ad47cc3a668d967b14c8861006f25e14d11 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: pack.h,v 1.3 2005-05-03 14:55:11 didg Exp $
+ * $Id: pack.h,v 1.4 2009-04-28 13:01:24 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * All Rights Reserved.  See COPYING.
@@ -8,40 +8,24 @@
 #ifndef CNID_DBD_PACK_H
 #define CNID_DBD_PACK_H 1
 
-
+#include <db.h>
 #include <atalk/cnid_dbd_private.h>
 
-#define CNID_OFS                 0
-#define CNID_LEN                 4
-#define CNID_DEV_OFS             CNID_LEN
-#define CNID_DEV_LEN             8
-  
-#define CNID_INO_OFS             (CNID_DEV_OFS + CNID_DEV_LEN)
-#define CNID_INO_LEN             8
-   
-#define CNID_DEVINO_OFS          CNID_LEN
-#define CNID_DEVINO_LEN          (CNID_DEV_LEN +CNID_INO_LEN)
-    
-#define CNID_TYPE_OFS            (CNID_DEVINO_OFS +CNID_DEVINO_LEN)
-#define CNID_TYPE_LEN            4
-     
-#define CNID_DID_OFS             (CNID_TYPE_OFS +CNID_TYPE_LEN)
-#define CNID_DID_LEN             CNID_LEN
-      
-#define CNID_NAME_OFS            (CNID_DID_OFS + CNID_DID_LEN)
-#define CNID_HEADER_LEN          (CNID_NAME_OFS)
-
-#if 0
-#define CNID_DBD_DEVINO_LEN          8
-#define CNID_DBD_DID_LEN             4
-#define CNID_DBD_HEADER_LEN          (CNID_DBD_DEVINO_LEN + CNID_DBD_DID_LEN)
-#endif
+#define ntoh64(x)       (((uint64_t)(x) << 56) | \
+                        (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \
+                        (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \
+                        (((uint64_t)(x) << 8)  & 0xff00000000ULL) | \
+                        (((uint64_t)(x) >> 8)  & 0xff000000ULL) | \
+                        (((uint64_t)(x) >> 24) & 0xff0000ULL) | \
+                        (((uint64_t)(x) >> 40) & 0xff00ULL) | \
+                        ((uint64_t)(x)  >> 56))
 
-extern unsigned char *pack_cnid_data  __P((struct cnid_dbd_rqst *));
+extern unsigned char *pack_cnid_data(struct cnid_dbd_rqst *);
+extern int didname(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
+extern int devino(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey);
 
 #ifdef DEBUG
-extern char      *stringify_devino  __P((dev_t dev, ino_t ino));
+extern char *stringify_devino(dev_t dev, ino_t ino);
 #endif
 
 #endif /* CNID_DBD_PACK_H */
index aa580bfc23ba474ec71da2ac03d7adcb0e144c86..bb5bed2b4e6540e1aa425e992f20f3263e02b86f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: util.h,v 1.8 2005-04-28 20:49:51 bfernhomberg Exp $
+ * $Id: util.h,v 1.9 2009-04-28 13:01:24 franklahm Exp $
  */
 
 #ifndef _ATALK_UTIL_H
@@ -81,9 +81,8 @@ extern void *mod_symbol  __P((void *, const char *));
 #define mod_close(a)     dlclose(a)
 #endif /* ! HAVE_DLFCN_H */
 
-
+#if 0
 /* volinfo for shell utilities */
-
 #define VOLINFOFILE ".volinfo"
 
 struct volinfo {
@@ -105,5 +104,6 @@ struct volinfo {
 
 extern int loadvolinfo __P((char *path, struct volinfo *vol));
 extern int vol_load_charsets __P(( struct volinfo *vol));
+#endif /* 0 */
 
 #endif
index 6a290059e6f287b20eed72f49ad98fc4c2b8e1ee..2a3e2e1410b2e360a03a29b4501033289945d90c 100644 (file)
@@ -1,10 +1,12 @@
 /*
- * $Id: volinfo.h,v 1.3 2009-04-27 07:58:26 franklahm Exp $
+ * $Id: volinfo.h,v 1.4 2009-04-28 13:01:24 franklahm Exp $
  */
 
 #ifndef _ATALK_VOLINFO_H
 #define _ATALK_VOLINFO_H 1
 
+#include <atalk/unicode.h>
+
 /* FIXME: following duplicated from etc/afpd/volume.h  */
 
 /* flags that alter volume behaviour. */
@@ -33,7 +35,6 @@
 #define AFPVOL_EXT_ATTRS (1 << 23)   /* Volume supports Extended Attributes */
 #define AFPVOL_ACLS      (1 << 25)   /* Volume supports ACLS */
 
-
 /* handle casefolding */
 #define AFPVOL_MTOUUPPER       (1 << 0)
 #define AFPVOL_MTOULOWER       (1 << 1)
 #define AFPVOL_UUPPERMLOWER    (AFPVOL_MTOUUPPER | AFPVOL_UTOMLOWER)
 #define AFPVOL_ULOWERMUPPER    (AFPVOL_MTOULOWER | AFPVOL_UTOMUPPER)
 
+/* volinfo for shell utilities */
+#define VOLINFOFILE ".volinfo"
+
+struct volinfo {
+    char                *v_name;
+    char                *v_path;
+    int                 v_flags;
+    int                 v_casefold;
+    char                *v_cnidscheme;
+    char                *v_dbpath;
+    char                *v_volcodepage;
+    charset_t           v_volcharset;
+    char                *v_maccodepage;
+    charset_t           v_maccharset;
+    int                 v_adouble;  /* default adouble format */
+    char                *(*ad_path)(const char *, int);
+    char                *v_dbd_host;
+    int                 v_dbd_port;
+};
+
+extern int loadvolinfo(char *path, struct volinfo *vol);
+extern int vol_load_charsets(struct volinfo *vol);
 
 #endif
index 68b7c71b0c3bd9c66275483079e14a50cee4f775..262c240b8eaa826fcfe082448554684951f38869 100644 (file)
@@ -118,9 +118,6 @@ static char* find_in_path( char *path, char *subdir, size_t maxlen)
     pos = strrchr(path, '/');
 
     while ( stat(path, &st) != 0) {
-#ifdef DEBUG
-        fprintf(stderr, "searching in path %s\n", path);
-#endif
         path[pos-path]=0;
         if ((pos = strrchr(path, '/'))) {
             path[pos-path]=0;
@@ -133,9 +130,7 @@ static char* find_in_path( char *path, char *subdir, size_t maxlen)
 
     path[pos-path] = '/';
     path[pos-path+1] = 0;
-#ifdef DEBUG
-    fprintf(stderr, "%s path %s\n", subdir, path);
-#endif
+
     return path;
 }
 
@@ -319,9 +314,6 @@ static int parseline ( char *buf, struct volinfo *vol)
        return (-1);
         break;
     }
-#ifdef DEBUG
-    printf ("volume information: %s, %s", buf, value);
-#endif
         
     return 0;
 }