]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/cnid/cdb/cnid_cdb_open.c
Merge master
[netatalk.git] / libatalk / cnid / cdb / cnid_cdb_open.c
index f645574d16d3f5f352a27f320622fac1881c9e0d..056420dad099f1123a6e514f98630055d285fa3a 100644 (file)
@@ -1,7 +1,4 @@
-
 /*
- * $Id: cnid_cdb_open.c,v 1.2 2005-04-28 20:49:59 bfernhomberg Exp $
- *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
  *
@@ -40,6 +37,8 @@
 #endif /* HAVE_CONFIG_H */
 
 #ifdef CNID_BACKEND_CDB
+
+#include <atalk/cnid_private.h>
 #include "cnid_cdb_private.h"
 
 #ifndef MIN
 #define DBHOMELEN    8
 #define DBLEN        10
 
-/* we version the did/name database so that we can change the format
- * if necessary. the key is in the form of a did/name pair. in this case,
- * we use 0/0. */
-#define DBVERSION_KEY    "\0\0\0\0\0"
-#define DBVERSION_KEYLEN 5
-#define DBVERSION1       0x00000001U
-#define DBVERSION        DBVERSION1
-
 #define DBOPTIONS    (DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL)
 
 #define MAXITER     0xFFFF      /* maximum number of simultaneously open CNID
 
 static char *old_dbfiles[] = {"cnid.db", NULL};
 
-/* -----------------------
- * bandaid for LanTest performance pb. for now not used, cf. ifdef 0 below
-*/
-static int my_yield(void)
-{
-    struct timeval t;
-    int ret;
-
-    t.tv_sec = 0;
-    t.tv_usec = 1000;
-    ret = select(0, NULL, NULL, NULL, &t);
-    return 0;
-}
-
 /* --------------- */
-static int didname(dbp, pkey, pdata, skey)
-DB *dbp _U_;
-const DBT *pkey _U_, *pdata;
-DBT *skey;
+static int didname(DB *dbp _U_, const DBT *pkey _U_, const DBT *pdata, DBT *skey)
 {
 int len;
  
@@ -100,10 +74,7 @@ int len;
 }
  
 /* --------------- */
-static int devino(dbp, pkey, pdata, skey)
-DB *dbp _U_;
-const DBT *pkey _U_, *pdata;
-DBT *skey;
+static int devino(DB *dbp _U_, const DBT *pkey _U_, const DBT *pdata, DBT *skey)
 {
     memset(skey, 0, sizeof(DBT));
     skey->data = (char *)pdata->data + CNID_DEVINO_OFS;
@@ -208,7 +179,7 @@ static int upgrade_required(char *dbdir)
 }
 
 /* --------------- */
-struct _cnid_db *cnid_cdb_open(const char *dir, mode_t mask)
+struct _cnid_db *cnid_cdb_open(struct cnid_open_args *args)
 {
     struct stat st;
     char path[MAXPATHLEN + 1];
@@ -218,18 +189,18 @@ struct _cnid_db *cnid_cdb_open(const char *dir, mode_t mask)
     static int first = 0;
     int rc;
 
-    if (!dir || *dir == 0) {
+    if (!args->dir || *args->dir == 0) {
         return NULL;
     }
 
     /* this checks .AppleDB.
        We need space for dir + '/' + DBHOMELEN + '/' + DBLEN */
-    if ((len = strlen(dir)) > (MAXPATHLEN - DBHOMELEN - DBLEN - 2)) {
-        LOG(log_error, logtype_default, "cnid_open: Pathname too large: %s", dir);
+    if ((len = strlen(args->dir)) > (MAXPATHLEN - DBHOMELEN - DBLEN - 2)) {
+        LOG(log_error, logtype_default, "cnid_open: Pathname too large: %s", args->dir);
         return NULL;
     }
 
-    if ((cdb = cnid_cdb_new(dir)) == NULL) {
+    if ((cdb = cnid_cdb_new(args->dir)) == NULL) {
         LOG(log_error, logtype_default, "cnid_open: Unable to allocate memory for database");
         return NULL;
     }
@@ -242,14 +213,14 @@ struct _cnid_db *cnid_cdb_open(const char *dir, mode_t mask)
     cdb->_private = (void *) db;
     db->magic = CNID_DB_MAGIC;
 
-    strcpy(path, dir);
+    strcpy(path, args->dir);
     if (path[len - 1] != '/') {
         strcat(path, "/");
         len++;
     }
 
     strcpy(path + len, DBHOME);
-    if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777 & ~mask) < 0)) {
+    if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777 & ~args->mask) < 0)) {
         LOG(log_error, logtype_default, "cnid_open: DBHOME mkdir failed for %s", path);
         goto fail_adouble;
     }
@@ -276,7 +247,7 @@ struct _cnid_db *cnid_cdb_open(const char *dir, mode_t mask)
     }
 
     /* Open the database environment. */
-    if ((rc = db->dbenv->open(db->dbenv, path, DBOPTIONS, 0666 & ~mask)) != 0) {
+    if ((rc = db->dbenv->open(db->dbenv, path, DBOPTIONS, 0666 & ~args->mask)) != 0) {
        LOG(log_error, logtype_default, "cnid_open: dbenv->open (rw) of %s failed: %s", path, db_strerror(rc));
        /* FIXME: This should probably go. Even if it worked, any use for a read-only DB? Didier? */
         if (rc == DB_RUNRECOVERY) {
@@ -289,10 +260,10 @@ struct _cnid_db *cnid_cdb_open(const char *dir, mode_t mask)
         /* We can't get a full transactional environment, so multi-access
          * is out of the question.  Let's assume a read-only environment,
          * and try to at least get a shared memory pool. */
-        if ((rc = db->dbenv->open(db->dbenv, path, DB_INIT_MPOOL, 0666 & ~mask)) != 0) {
+        if ((rc = db->dbenv->open(db->dbenv, path, DB_INIT_MPOOL, 0666 & ~args->mask)) != 0) {
             /* Nope, not a MPOOL, either.  Last-ditch effort: we'll try to
              * open the environment with no flags. */
-            if ((rc = db->dbenv->open(db->dbenv, path, 0, 0666 & ~mask)) != 0) {
+            if ((rc = db->dbenv->open(db->dbenv, path, 0, 0666 & ~args->mask)) != 0) {
                 LOG(log_error, logtype_default, "cnid_open: dbenv->open of %s failed: %s", path, db_strerror(rc));
                 goto fail_lock;
             }
@@ -311,7 +282,7 @@ struct _cnid_db *cnid_cdb_open(const char *dir, mode_t mask)
         goto fail_appinit;
     }
 
-    if ((rc = my_open(db->db_cnid, DBCNID, DBCNID, DB_BTREE, open_flag, 0666 & ~mask)) != 0) {
+    if ((rc = my_open(db->db_cnid, DBCNID, DBCNID, DB_BTREE, open_flag, 0666 & ~args->mask)) != 0) {
         LOG(log_error, logtype_default, "cnid_open: Failed to open dev/ino database: %s",
             db_strerror(rc));
         goto fail_appinit;
@@ -326,7 +297,7 @@ struct _cnid_db *cnid_cdb_open(const char *dir, mode_t mask)
         goto fail_appinit;
     }
 
-    if ((rc = my_open(db->db_didname, DBCNID, DBDIDNAME, DB_BTREE, open_flag, 0666 & ~mask))) {
+    if ((rc = my_open(db->db_didname, DBCNID, DBDIDNAME, DB_BTREE, open_flag, 0666 & ~args->mask))) {
         LOG(log_error, logtype_default, "cnid_open: Failed to open did/name database: %s",
             db_strerror(rc));
         goto fail_appinit;
@@ -341,7 +312,7 @@ struct _cnid_db *cnid_cdb_open(const char *dir, mode_t mask)
         goto fail_appinit;
     }
 
-    if ((rc = my_open(db->db_devino, DBCNID, DBDEVINO, DB_BTREE, open_flag, 0666 & ~mask)) != 0) {
+    if ((rc = my_open(db->db_devino, DBCNID, DBDEVINO, DB_BTREE, open_flag, 0666 & ~args->mask)) != 0) {
         LOG(log_error, logtype_default, "cnid_open: Failed to open devino database: %s",
             db_strerror(rc));
         goto fail_appinit;
@@ -361,44 +332,28 @@ struct _cnid_db *cnid_cdb_open(const char *dir, mode_t mask)
         goto fail_appinit;
     }
  
-#if 0
-    DBT key, pkey, data;
     /* ---------------------- */
-    /* Check for version.  This way we can update the database if we need
-     * to change the format in any way. */
-    memset(&key, 0, sizeof(key));
-    memset(&pkey, 0, sizeof(DBT));
-    memset(&data, 0, sizeof(data));
-    key.data = DBVERSION_KEY;
-    key.size = DBVERSION_KEYLEN;
+    /* Check for version. "cdb" only supports CNID_VERSION_0, cf cnid_private.h */
 
-    if ((rc = db->db_didname->pget(db->db_didname, NULL, &key, &pkey, &data, 0)) != 0) {
-        int ret;
-        {
-            u_int32_t version = htonl(DBVERSION);
+    DBT key, data;
+    uint32_t version;
 
-            data.data = &version;
-            data.size = sizeof(version);
-        }
-        if ((ret = db->db_didname->put(db->db_cnid, NULL, &key, &data,
-                                       DB_NOOVERWRITE))) {
-            LOG(log_error, logtype_default, "cnid_open: Error putting new version: %s",
-                db_strerror(ret));
-            db->db_didname->close(db->db_didname, 0);
+    memset(&key, 0, sizeof(key));
+    memset(&data, 0, sizeof(data));
+    key.data = ROOTINFO_KEY;
+    key.size = ROOTINFO_KEYLEN;
+
+    if ((rc = db->db_cnid->get(db->db_cnid, NULL, &key, &data, 0)) == 0) {
+        /* If not found, ignore it */
+        memcpy(&version, data.data + CNID_DID_OFS, sizeof(version));
+        version = ntohl(version);
+        LOG(log_debug, logtype_default, "CNID db version %u", version);
+        if (version != CNID_VERSION_0) {
+            LOG(log_error, logtype_default, "Unsupported CNID db version %u, use CNID backend \"dbd\"", version);
             goto fail_appinit;
         }
     }
-#endif
-
-    /* TODO In the future we might check for version number here. */
-#if 0
-    memcpy(&version, data.data, sizeof(version));
-    if (version != ntohl(DBVERSION)) {
-        /* Do stuff here. */
-    }
-#endif /* 0 */
 
-    db_env_set_func_yield(my_yield);
     return cdb;
 
   fail_appinit: