-
/*
- * $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.
*
#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 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;
}
/* --------------- */
-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;
}
/* --------------- */
-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];
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;
}
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;
}
}
/* 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) {
/* 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;
}
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;
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;
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;
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;