From 9753ac7c67d4871ea344993538b08c3850ad12e7 Mon Sep 17 00:00:00 2001 From: franklahm Date: Tue, 28 Apr 2009 13:01:24 +0000 Subject: [PATCH] New utility to maintain dbd databases: dbd. Also replaces cnid_index. Still incomplete. --- bin/cnid/Makefile.am | 10 - bin/cnid/cnid_index.c | 592 --------------------------------------- configure.in | 4 +- etc/afpd/volume.c | 3 +- etc/cnid_dbd/Makefile.am | 11 +- etc/cnid_dbd/dbd.c | 322 +++++++++++++++++++++ etc/cnid_dbd/dbif.c | 180 +++++++++++- etc/cnid_dbd/dbif.h | 32 ++- etc/cnid_dbd/main.c | 12 +- etc/cnid_dbd/pack.c | 4 +- etc/cnid_dbd/pack.h | 44 +-- include/atalk/util.h | 6 +- include/atalk/volinfo.h | 27 +- libatalk/util/volinfo.c | 10 +- 14 files changed, 570 insertions(+), 687 deletions(-) delete mode 100644 bin/cnid/cnid_index.c create mode 100644 etc/cnid_dbd/dbd.c diff --git a/bin/cnid/Makefile.am b/bin/cnid/Makefile.am index 96a5f909..16b5bfac 100644 --- a/bin/cnid/Makefile.am +++ b/bin/cnid/Makefile.am @@ -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 index 34129690..00000000 --- a/bin/cnid/cnid_index.c +++ /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 -#endif /* HAVE_UNISTD_H */ -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_TYPES_H -#include -#endif /* HAVE_SYS_TYPES_H */ -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif /* HAVE_SYS_STAT_H */ -#include -#include - -#include -#include -#include - -#define LOCKFILENAME "lock" -static int exit_sig = 0; - -/* Copy and past from etc/cnid_dbd/dbif.c */ -#include - -#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; -} diff --git a/configure.in b/configure.in index c644a1c6..4425151a 100644 --- a/configure.in +++ b/configure.in @@ -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... diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index 324b88b9..6d779917 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -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 #include #include +#include #include #ifdef CNID_DB #include diff --git a/etc/cnid_dbd/Makefile.am b/etc/cnid_dbd/Makefile.am index 20051a6e..fbde4afb 100644 --- a/etc/cnid_dbd/Makefile.am +++ b/etc/cnid_dbd/Makefile.am @@ -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 index 00000000..47af6fe6 --- /dev/null +++ b/etc/cnid_dbd/dbd.c @@ -0,0 +1,322 @@ +/* + $Id: dbd.c,v 1.1 2009-04-28 13:01:24 franklahm Exp $ + + Copyright (c) 2009 Frank Lahm + + 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#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] \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; +} diff --git a/etc/cnid_dbd/dbif.c b/etc/cnid_dbd/dbif.c index 1920838a..36131442 100644 --- a/etc/cnid_dbd/dbif.c +++ b/etc/cnid_dbd/dbif.c @@ -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 #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; +} diff --git a/etc/cnid_dbd/dbif.h b/etc/cnid_dbd/dbif.h index 0939ceb9..0953f72f 100644 --- a/etc/cnid_dbd/dbif.h +++ b/etc/cnid_dbd/dbif.h @@ -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. */ @@ -18,21 +19,22 @@ #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 diff --git a/etc/cnid_dbd/main.c b/etc/cnid_dbd/main.c index d1dde1bb..4a3f42c8 100644 --- a/etc/cnid_dbd/main.c +++ b/etc/cnid_dbd/main.c @@ -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 @@ -51,11 +51,15 @@ #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"); diff --git a/etc/cnid_dbd/pack.c b/etc/cnid_dbd/pack.c index b1fd85ae..02a73075 100644 --- a/etc/cnid_dbd/pack.c +++ b/etc/cnid_dbd/pack.c @@ -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; diff --git a/etc/cnid_dbd/pack.h b/etc/cnid_dbd/pack.h index c7f255b5..63f18ad4 100644 --- a/etc/cnid_dbd/pack.h +++ b/etc/cnid_dbd/pack.h @@ -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 #include -#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 */ diff --git a/include/atalk/util.h b/include/atalk/util.h index aa580bfc..bb5bed2b 100644 --- a/include/atalk/util.h +++ b/include/atalk/util.h @@ -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 diff --git a/include/atalk/volinfo.h b/include/atalk/volinfo.h index 6a290059..2a3e2e14 100644 --- a/include/atalk/volinfo.h +++ b/include/atalk/volinfo.h @@ -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 + /* 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) @@ -44,5 +45,27 @@ #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 diff --git a/libatalk/util/volinfo.c b/libatalk/util/volinfo.c index 68b7c71b..262c240b 100644 --- a/libatalk/util/volinfo.c +++ b/libatalk/util/volinfo.c @@ -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; } -- 2.39.2