-/*
- * $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.
#include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#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"
#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
#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. */
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 */
}
* 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;
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)
{
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;
return NULL;
}
db->magic = CNID_DB_MAGIC;
-
+
strcpy(path, dir);
if (path[len - 1] != '/') {
strcat(path, "/");
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)) {
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;
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;
}
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))
goto fail_appinit;
}
}
-
+
/* XXX: in the future, we might check for version number here. */
#if 0
memcpy(&version, data.data, sizeof(version));
}
#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);