/*
- * $Id: cnid_lookup.c,v 1.8 2001-10-18 02:30:45 jmarcus Exp $
+ * $Id: cnid_lookup.c,v 1.14.2.1 2003-02-08 03:16:53 jmarcus Exp $
*/
#ifdef HAVE_CONFIG_H
#include <string.h>
#include <sys/param.h>
#include <sys/stat.h>
-#include <syslog.h>
+#include <atalk/logger.h>
#include <errno.h>
#include <db.h>
#define LOGFILEMAX 100 /* kbytes */
#define CHECKTIMEMAX 30 /* minutes */
-/* this returns the cnid corresponding to a particular file. it will
- also fix up the various databases if there's a problem. */
-cnid_t cnid_lookup(void *CNID,
- const struct stat *st, const cnid_t did,
- const char *name, const int len)
+/* This returns the CNID corresponding to a particular file. It will
+ * also fix up the various databases if there's a problem. */
+cnid_t cnid_lookup(void *CNID, const struct stat *st, const cnid_t did,
+ const char *name, const int len)
{
- char *buf;
- CNID_private *db;
- DBT key, devdata, diddata;
- int devino = 1, didname = 1;
- cnid_t id = 0;
- int rc = 0;
-
- int debug = 0;
-
- if (!(db = CNID) || !st || !name)
- return 0;
-
- /* do a little checkpointing if necessary. i stuck it here as
- * cnid_lookup gets called when we do directory lookups. only do
- * this if we're using a read-write database. */
- if ((db->flags & CNIDFLAG_DB_RO) == 0) {
- rc = txn_checkpoint(db->dbenv, LOGFILEMAX, CHECKTIMEMAX, 0);
- while (rc == DB_INCOMPLETE)
- rc = txn_checkpoint(db->dbenv, 0, 0, 0);
- if (rc) {
- syslog(LOG_ERR, "cnid_lookup: txn_checkpoint failed with: %d", rc);
- return 0;
- }
- }
-
- if ((buf = make_cnid_data(st, did, name, len)) == NULL) {
- syslog(LOG_ERR, "cnid_lookup: path name too long");
- return 0;
- }
-
- memset(&key, 0, sizeof(key));
- memset(&devdata, 0, sizeof(devdata));
-
- /* look for a CNID. we have two options: dev/ino or did/name. if we
- only get a match on one of them, that means a file has moved. */
- key.data = buf; /* dev/ino is the first part of the buffer */
- key.size = CNID_DEVINO_LEN;
- while ((rc = db->db_devino->get(db->db_devino, NULL,
- &key, &devdata, 0))) {
- if (rc == DB_LOCK_DEADLOCK) {
- continue;
- }
-
- if (rc == DB_NOTFOUND) {
- devino = 0;
- break;
+ char *buf;
+ CNID_private *db;
+ DBT key, devdata, diddata;
+ int devino = 1, didname = 1;
+ cnid_t id = 0;
+ int rc;
+
+ if (!(db = CNID) || !st || !name) {
+ return 0;
}
- syslog(LOG_ERR, "cnid_lookup: can't get CNID(%u/%u) (%d)",
- st->st_dev, st->st_ino, rc);
- return 0;
- }
-
- /* did/name is right afterwards. */
- key.data = buf + CNID_DEVINO_LEN;
- key.size = CNID_DID_LEN + len + 1;
- memset(&diddata, 0, sizeof(diddata));
- while ((rc = db->db_didname->get(db->db_didname, NULL,
- &key, &diddata, 0))) {
- if (rc == DB_LOCK_DEADLOCK) {
- continue;
- }
-
- if (rc == DB_NOTFOUND) {
- didname = 0;
- break;
+#ifndef CNID_DB_CDB
+ /* Do a little checkpointing if necessary. I stuck it here as cnid_lookup
+ * gets called when we do directory lookups. Only do this if we're using
+ * a read-write database. */
+ if ((db->flags & CNIDFLAG_DB_RO) == 0) {
+#ifdef DEBUG
+ LOG(log_info, logtype_default, "cnid_lookup: Running database checkpoint");
+#endif
+#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
+ db->dbenv->txn_checkpoint(db->dbenv, LOGFILEMAX, CHECKTIMEMAX, 0)
+#else
+#if DB_VERSION_MAJOR >= 4
+ switch (rc = db->dbenv->txn_checkpoint(db->dbenv, LOGFILEMAX, CHECKTIMEMAX, 0)) {
+#else
+ switch (rc = txn_checkpoint(db->dbenv, LOGFILEMAX, CHECKTIMEMAX, 0)) {
+#endif /* DB_VERSION_MAJOR >= 4 */
+ case 0:
+ case DB_INCOMPLETE:
+ break;
+ default:
+ LOG(log_error, logtype_default, "cnid_lookup: txn_checkpoint: %s",
+ db_strerror(rc));
+ return 0;
+ }
+ }
+#endif /* DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1) */
+#endif /* CNID_DB_CDB */
+
+ if ((buf = make_cnid_data(st, did, name, len)) == NULL) {
+ LOG(log_error, logtype_default, "cnid_lookup: Pathname is too long");
+ return 0;
+ }
+
+ memset(&key, 0, sizeof(key));
+ memset(&devdata, 0, sizeof(devdata));
+ memset(&diddata, 0, sizeof(diddata));
+
+ /* Look for a CNID. We have two options: dev/ino or did/name. If we
+ * only get a match in one of them, that means a file has moved. */
+ key.data = buf;
+ key.size = CNID_DEVINO_LEN;
+ while ((rc = db->db_devino->get(db->db_devino, NULL, &key, &devdata, 0))) {
+#ifndef CNID_DB_CDB
+ if (rc == DB_LOCK_DEADLOCK) {
+ continue;
+ }
+#endif /* CNID_DB_CDB */
+
+ if (rc == DB_NOTFOUND) {
+ devino = 0;
+ break;
+ }
+
+ LOG(log_error, logtype_default, "cnid_lookup: Unable to get CNID dev %u, ino %u: %s",
+ st->st_dev, st->st_ino, db_strerror(rc));
+ return 0;
+ }
+
+ /* did/name now */
+ key.data = buf + CNID_DEVINO_LEN;
+ key.size = CNID_DID_LEN + len + 1;
+ while ((rc = db->db_didname->get(db->db_didname, NULL, &key, &diddata, 0))) {
+#ifndef CNID_DB_CDB
+ if (rc == DB_LOCK_DEADLOCK) {
+ continue;
+ }
+#endif /* CNID_DB_CDB */
+
+ if (rc == DB_NOTFOUND) {
+ didname = 0;
+ break;
+ }
+
+ LOG(log_error, logtype_default, "cnid_lookup: Unable to get CNID %u, name %s: %s",
+ ntohl(did), name, db_strerror(rc));
+ return 0;
+ }
+
+ /* Set id. Honor did/name over dev/ino as dev/ino isn't necessarily
+ * 1-1. */
+ if (didname) {
+ memcpy(&id, diddata.data, sizeof(id));
+ }
+ else if (devino) {
+ memcpy(&id, devdata.data, sizeof(id));
+ }
+
+ /* Either entries are in both databases or neither of them. */
+ if ((devino && didname) || !(devino || didname)) {
+#ifdef DEBUG
+ LOG(log_info, logtype_default, "cnid_lookup: Looked up did %u, name %s, as %u",
+ ntohl(did), name, ntohl(id));
+#endif
+ return id;
+ }
+
+ /* Fix up the database. */
+ cnid_update(db, id, st, did, name, len);
+#ifdef DEBUG
+ LOG(log_info, logtype_default, "cnid_lookup: Looked up did %u, name %s, as %u (needed update)", ntohl(did), name, ntohl(id));
+#endif
+ return id;
}
-
- syslog(LOG_ERR, "cnid_lookup: can't get CNID(%u:%s) (%d)",
- did, name, rc);
- return 0;
- }
-
- /* set id. honor did/name over dev/ino as dev/ino isn't necessarily
- * 1-1. */
- if (didname) {
- memcpy(&id, diddata.data, sizeof(id));
- } else if (devino) {
- memcpy(&id, devdata.data, sizeof(id));
- }
-
- /* either entries in both databases exist or neither of them do. */
- if ((devino && didname) || !(devino || didname)) {
- if (debug)
- syslog(LOG_ERR, "cnid_lookup: looked up did %u, name %s as %u", ntohl(did), name, ntohl(id));
- return id;
- }
- /* fix up the databases */
- cnid_update(db, id, st, did, name, len);
- if (debug)
- syslog(LOG_ERR, "cnid_lookup: looked up did %u, name %s as %u (needed update)", ntohl(did), name, ntohl(id));
- return id;
-}
#endif /* CNID_DB */
+
+