]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/cnid/cnid_open.c
CNID/DID patch from Uwe Hees (moderately tested)
[netatalk.git] / libatalk / cnid / cnid_open.c
index 796c5495dd95cdb07a2c69004529a4f7bb342078..0f26c118bd5ca68cabe32a85f9bd81bbbe5ff8e4 100644 (file)
@@ -1,5 +1,5 @@
-/* 
- * $Id: cnid_open.c,v 1.2 2001-06-29 14:14:46 rufustfirefly Exp $
+/*
+ * $Id: cnid_open.c,v 1.3 2001-08-14 14:00:10 rufustfirefly Exp $
  *
  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
  * All Rights Reserved. See COPYRIGHT.
@@ -37,6 +37,7 @@
 #include "config.h"
 #endif /* HAVE_CONFIG_H */
 
+#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #ifdef HAVE_UNISTD_H
@@ -61,9 +62,6 @@
 #define MIN(a, b)  ((a) < (b) ? (a) : (b))
 #endif /* ! MIN */
 
-#define ROOTINFO     "RootInfo"
-#define ROOTINFO_LEN 8
-
 #define DBHOME       ".AppleDB"
 #define DBCNID       "cnid.db"
 #define DBDEVINO     "devino.db"
@@ -71,7 +69,7 @@
 #define DBSHORTNAME  "shortname.db" /* did/8+3 mapping */
 #define DBMACNAME    "macname.db"   /* did/31 mapping */
 #define DBLONGNAME   "longname.db"  /* did/unicode mapping */
-#define DBLOCKFILE   "/cnid.lock"
+#define DBLOCKFILE   "cnid.lock"
 
 #define DBHOMELEN    8
 #define DBLEN        10
@@ -87,7 +85,7 @@
 #define DBOPTIONS    (DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | \
 DB_INIT_LOG | DB_INIT_TXN | DB_TXN_NOSYNC | DB_RECOVER)
 
-#define MAXITER     0xFFFF /* maximum number of simultaneously open CNID 
+#define MAXITER     0xFFFF /* maximum number of simultaneously open CNID
                            * databases. */
 
 /* the first compare that's always done. */
@@ -116,6 +114,7 @@ static int compare_unix(const DBT *a, const DBT *b)
   for (len = MIN(a->size, b->size); len-- > 4; sa++, sb++)
     if (ret = (*sa - *sb))
       return ret; /* sort by lexical ordering */
+
   return a->size - b->size; /* sort by length */
 }
 
@@ -123,11 +122,11 @@ static int compare_unix(const DBT *a, const DBT *b)
  * did/macname, and did/shortname. i think did/longname needs a
  * unicode table to work. also, we can't use strdiacasecmp as that
  * returns a match if a < b. */
-static int compare_mac(const DBT *a, const DBT *b) 
+static int compare_mac(const DBT *a, const DBT *b)
 {
   u_int8_t *sa, *sb;
   int len, ret;
-  
+
   /* sort by did */
   if (ret = compare_did(a, b))
     return ret;
@@ -136,13 +135,17 @@ static int compare_mac(const DBT *a, const DBT *b)
   sb = b->data + 4;
   for (len = MIN(a->size, b->size); len-- > 4; sa++, sb++)
     if (ret = (_diacasemap[*sa] - _diacasemap[*sb]))
-      return ret; /* sort by lexical ordering */
+         return ret; /* sort by lexical ordering */
+
   return a->size - b->size; /* sort by length */
 }
 
 
 /* for unicode names -- right now it's the same as compare_mac. */
-#define compare_unicode(a, b) compare_mac((a), (b))
+static int compare_unicode(const DBT *a, const DBT *b)
+{
+       return compare_mac(a,b);
+}
 
 void *cnid_open(const char *dir)
 {
@@ -150,14 +153,13 @@ void *cnid_open(const char *dir)
   struct flock lock;
   char path[MAXPATHLEN + 1];
   CNID_private *db;
-  DB_INFO dbi;
   DBT key, data;
   int open_flag, len;
 
   if (!dir)
     return NULL;
 
-  /* this checks both RootInfo and .AppleDB */
+  /* this checks .AppleDB */
   if ((len = strlen(dir)) > (MAXPATHLEN - DBLEN - 1)) {
     syslog(LOG_ERR, "cnid_open: path too large");
     return NULL;
@@ -168,7 +170,7 @@ void *cnid_open(const char *dir)
     return NULL;
   }
   db->magic = CNID_DB_MAGIC;
-    
+
   strcpy(path, dir);
   if (path[len - 1] != '/') {
     strcat(path, "/");
@@ -178,48 +180,6 @@ void *cnid_open(const char *dir)
   lock.l_type = F_WRLCK;
   lock.l_whence = SEEK_SET;
 
-  /* we create and initialize RootInfo if it doesn't exist. */
-  strcat(path, ROOTINFO);
-  if (ad_open(path, ADFLAGS_HF, O_RDWR, 0666, &db->rootinfo) < 0) {
-    cnid_t id;
-
-    /* see if we can open it read-only. if it's read-only, we can't
-     * add CNIDs. */
-    memset(&db->rootinfo, 0, sizeof(db->rootinfo));
-    if (ad_open(path, ADFLAGS_HF, O_RDONLY, 0666, &db->rootinfo) == 0) {
-      db->flags = CNIDFLAG_ROOTINFO_RO;
-      syslog(LOG_INFO, "cnid_open: read-only RootInfo");
-      goto mkdir_appledb;
-    }
-
-    /* create the file */
-    memset(&db->rootinfo, 0, sizeof(db->rootinfo));
-    if (ad_open(path, ADFLAGS_HF, O_CREAT | O_RDWR, 0666, 
-               &db->rootinfo) < 0) {
-      syslog(LOG_ERR, "cnid_open: ad_open(RootInfo)");
-      goto fail_db;
-    }
-
-    /* lock the RootInfo file. this and cnid_add are the only places
-     * that should fiddle with RootInfo. */
-    lock.l_start = ad_getentryoff(&db->rootinfo, ADEID_DID);
-    lock.l_len = ad_getentrylen(&db->rootinfo, ADEID_DID);
-    if (fcntl(ad_hfileno(&db->rootinfo), F_SETLKW,  &lock) < 0) {
-      syslog(LOG_ERR, "cnid_open: can't establish lock: %m");
-      goto fail_adouble;
-    }
-    
-    /* store the beginning CNID */
-    id = htonl(CNID_START);
-    memcpy(ad_entry(&db->rootinfo, ADEID_DID), &id, sizeof(id));
-    ad_flush(&db->rootinfo, ADFLAGS_HF);
-
-    /* unlock it */
-    lock.l_type = F_UNLCK;
-    fcntl(ad_hfileno(&db->rootinfo), F_SETLK, &lock);
-    lock.l_type = F_WRLCK;
-  }
-
 mkdir_appledb:
   strcpy(path + len, DBHOME);
   if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777) < 0)) {
@@ -242,24 +202,27 @@ mkdir_appledb:
        close(db->lockfd);
        db->lockfd = -1;
        break;
-      }      
+      }
     }
-  } 
+  }
 
   path[len + DBHOMELEN] = '\0';
   open_flag = DB_CREATE;
   /* try a full-blown transactional environment */
-  if (db_appinit(path, NULL, &db->dbenv, DBOPTIONS)) {
+  if (db_env_create(&db->dbenv, 0)) {
+    syslog(LOG_ERR, "cnid_open: db_env_create failed");
+    goto fail_lock;
+  }
+
+  if (db->dbenv->open(db->dbenv, path, DBOPTIONS, 0666)) {
 
     /* try with a shared memory pool */
-    memset(&db->dbenv, 0, sizeof(db->dbenv));
-    if (db_appinit(path, NULL, &db->dbenv, DB_INIT_MPOOL)) {
+       if (db->dbenv->open(db->dbenv, path, DB_INIT_MPOOL, 0666)) {
 
       /* try without any options. */
-      memset(&db->dbenv, 0, sizeof(db->dbenv));
-      if (db_appinit(path, NULL, &db->dbenv, 0)) {
-       syslog(LOG_ERR, "cnid_open: db_appinit failed");
-       goto fail_lock;
+      if (db->dbenv->open(db->dbenv, path, 0, 0666)) {
+               syslog(LOG_ERR, "cnid_open: db_env_open failed");
+               goto fail_lock;
       }
     }
     db->flags |= CNIDFLAG_DB_RO;
@@ -267,12 +230,12 @@ mkdir_appledb:
     syslog(LOG_INFO, "cnid_open: read-only CNID database");
   }
 
-  memset(&dbi, 0, sizeof(dbi));
-
   /* did/name reverse mapping. we use a btree for this one. */
-  dbi.bt_compare = compare_unix;
-  if (db_open(DBDIDNAME, DB_BTREE, open_flag, 0666, &db->dbenv, &dbi,
-             &db->db_didname)) {
+  if (db_create(&db->db_didname, db->dbenv, 0))
+       goto fail_appinit;
+
+  db->db_didname->set_bt_compare(db->db_didname, compare_unix);
+  if (db->db_didname->open(db->db_didname, DBDIDNAME, NULL, DB_BTREE, open_flag, 0666)) {
     goto fail_appinit;
   }
 
@@ -281,17 +244,19 @@ mkdir_appledb:
   memset(&key, 0, sizeof(key));
   memset(&data, 0, sizeof(data));
   key.data = DBVERSION_KEY;
-  key.len = DBVERSION_KEY_LEN;
+  key.size = DBVERSION_KEYLEN;
   while (errno = db->db_didname->get(db->db_didname, NULL, &key, &data, 0)) {
     switch (errno) {
     case EAGAIN:
       continue;
-    
+
     case DB_NOTFOUND:
+       {
       u_int32_t version = htonl(DBVERSION);
 
       data.data = &version;
-      data.len = sizeof(version);
+      data.size = sizeof(version);
+       }
 dbversion_retry:
       if (db->db_didname->put(db->db_didname, NULL, &key, &data,
                              DB_NOOVERWRITE))
@@ -304,7 +269,7 @@ dbversion_retry:
       goto fail_appinit;
     }
   }
-  
+
   /* XXX: in the future, we might check for version number here. */
 #if 0
   memcpy(&version, data.data, sizeof(version));
@@ -313,65 +278,82 @@ dbversion_retry:
   }
 #endif /* 0 */
 
+#ifdef EXTENDED_DB
   /* did/macname mapping. btree this one. */
-  dbi.bt_compare = compare_mac;
-  if (db_open(DBMACNAME, DB_BTREE, open_flag, 0666, &db->dbenv, &dbi,
-             &db->db_macname)) {
+  if (db_create(&db->db_macname, db->dbenv, 0))
+    goto fail_appinit;
+
+  db->db_macname->set_bt_compare(db->db_macname, compare_mac);
+  if (db->db_macname->open(db->db_macname, DBMACNAME, NULL, DB_BTREE, open_flag, 0666)) {
     db->db_didname->close(db->db_didname, 0);
     goto fail_appinit;
   }
 
   /* did/shortname mapping */
-  if (db_open(DBSHORTNAME, DB_BTREE, open_flag, 0666, &db->dbenv, &dbi,
-             &db->db_shortname)) {
+  if (db_create(&db->db_shortname, db->dbenv, 0))
+    goto fail_appinit;
+
+  db->db_shortname->set_bt_compare(db->db_shortname, compare_mac);
+  if (db->db_shortname->open(db->db_shortname, DBSHORTNAME, NULL, DB_BTREE, open_flag, 0666)) {
     db->db_didname->close(db->db_didname, 0);
     db->db_macname->close(db->db_macname, 0);
     goto fail_appinit;
   }
 
   /* did/longname mapping */
-  dbi.bt_compare = compare_unicode;
-  if (db_open(DBLONGNAME, DB_BTREE, open_flag, 0666, &db->dbenv, &dbi,
-             &db->db_longname)) {
+  if (db_create(&db->db_longname, db->dbenv, 0))
+    goto fail_appinit;
+
+  db->db_longname->set_bt_compare(db->db_longname, compare_unicode);
+  if (db->db_longname->open(db->db_longname, DBLONGNAME, NULL, DB_BTREE, open_flag, 0666)) {
     db->db_didname->close(db->db_didname, 0);
     db->db_macname->close(db->db_macname, 0);
     db->db_shortname->close(db->db_shortname, 0);
     goto fail_appinit;
   }
+#endif /* EXTENDED_DB */
 
   /* dev/ino reverse mapping. we hash this one. */
-  dbi.bt_compare = NULL;
-  if (db_open(DBDEVINO, DB_HASH, open_flag, 0666, &db->dbenv, &dbi,
-             &db->db_devino)) {
+  if (db_create(&db->db_devino, db->dbenv, 0))
+    goto fail_appinit;
+
+  if (db->db_devino->open(db->db_devino, DBDEVINO, NULL, DB_HASH, open_flag, 0666)) {
     db->db_didname->close(db->db_didname, 0);
+#ifdef EXTENDED_DB
     db->db_macname->close(db->db_macname, 0);
     db->db_shortname->close(db->db_shortname, 0);
     db->db_longname->close(db->db_longname, 0);
+#endif /* EXTENDED_DB */
     goto fail_appinit;
   }
 
   /* main cnid database. we hash this one as well. */
-  if (db_open(DBCNID, DB_HASH, open_flag, 0666, &db->dbenv, &dbi,
-             &db->db_cnid)) {
+  if (db_create(&db->db_cnid, db->dbenv, 0))
+    goto fail_appinit;
+
+  if (db->db_cnid->open(db->db_cnid, DBCNID, NULL, DB_HASH, open_flag, 0666)) {
     db->db_didname->close(db->db_didname, 0);
+#ifdef EXTENDED_DB
     db->db_macname->close(db->db_macname, 0);
     db->db_shortname->close(db->db_shortname, 0);
     db->db_longname->close(db->db_longname, 0);
+#endif /* EXTENDED_DB */
     db->db_devino->close(db->db_devino, 0);
     goto fail_appinit;
   }
+
   return db;
-  
+
 fail_appinit:
   syslog(LOG_ERR, "cnid_open: db_open failed");
-  db_appexit(&db->dbenv);
+  db->dbenv->close(db->dbenv, 0);
+  /* db->dbenv->remove(db->dbenv, db->dbenv->db_home, 0); */
 
 fail_lock:
   if (db->lockfd > -1)
     close(db->lockfd);
 
 fail_adouble:
-  ad_close(&db->rootinfo, ADFLAGS_HF);
 
 fail_db:
   free(db);