#include <netatalk/endian.h>
#include <atalk/cnid.h>
+#include <atalk/cnid_private.h>
#define STANDALONE 1
#include <stdlib.h>
#define TDB_ERROR_DEV 2
#define TDB_ERROR_INODE 4
-#define TDB_DB_MAGIC 0x434E4944U /* CNID */
-#define TDB_DATA_MAGIC 0x434E4945U /* CNIE */
-
-#define TDB_DEVINO_LEN 8
-#define TDB_DID_LEN 4
-#define TDB_HEADER_LEN (TDB_DEVINO_LEN + TDB_DID_LEN)
-
-#define TDB_START 17
-
-#define TDBFLAG_ROOTINFO_RO (1 << 0)
-#define TDBFLAG_DB_RO (1 << 1)
-
-/* the key is in the form of a did/name pair. in this case,
- * we use 0/RootInfo. */
-#define ROOTINFO_KEY "\0\0\0\0RootInfo"
-#define ROOTINFO_KEYLEN 12
-
struct _cnid_tdb_private {
dev_t st_dev;
int st_set;
extern cnid_t cnid_tdb_nextid (struct _cnid_db *);
/* construct db_cnid data. NOTE: this is not re-entrant. */
-static inline char *make_tdb_data(const struct stat *st,
- const cnid_t did,
- const char *name, const size_t len)
-{
- static char start[TDB_HEADER_LEN + MAXPATHLEN + 1];
- char *buf = start;
- u_int32_t i;
-
- if (len > MAXPATHLEN)
- return NULL;
-
- i = htonl(st->st_dev);
- buf = memcpy(buf, &i, sizeof(i));
- i = htonl(st->st_ino);
- buf = memcpy(buf + sizeof(i), &i, sizeof(i));
- /* did is already in network byte order */
- buf = memcpy(buf + sizeof(i), &did, sizeof(did));
- buf = memcpy(buf + sizeof(did), name, len);
- *(buf + len) = '\0';
- buf += len + 1;
-
- return start;
-}
+extern unsigned char *make_tdb_data(u_int32_t flags, const struct stat *st, const cnid_t did, const char *name, const size_t len);
#endif /* include/atalk/cnid_tdb.h */
/*
- * $Id: cnid_tdb_add.c,v 1.3 2005-05-03 14:55:15 didg Exp $
+ * $Id: cnid_tdb_add.c,v 1.4 2009-11-20 17:37:14 didg Exp $
*
* Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
* All Rights Reserved. See COPYRIGHT.
#include <unistd.h>
#include <atalk/logger.h>
-/* add an entry to the CNID databases. we do this as a transaction
- * to prevent messiness. */
+static void make_devino_data(unsigned char *buf, dev_t dev, ino_t ino)
+{
+ buf[CNID_DEV_LEN - 1] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 2] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 3] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 4] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 5] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 6] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 7] = dev; dev >>= 8;
+ buf[CNID_DEV_LEN - 8] = dev;
+
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 1] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 2] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 3] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 4] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 5] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 6] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 7] = ino; ino >>= 8;
+ buf[CNID_DEV_LEN + CNID_INO_LEN - 8] = ino;
+}
+
+unsigned char *make_tdb_data(u_int32_t flags, const struct stat *st,const cnid_t did,
+ const char *name, const size_t len)
+{
+ static unsigned char start[CNID_HEADER_LEN + MAXPATHLEN + 1];
+ unsigned char *buf = start +CNID_LEN;
+ u_int32_t i;
+
+ if (len > MAXPATHLEN)
+ return NULL;
+
+ make_devino_data(buf, !(flags & CNID_FLAG_NODEV)?st->st_dev:0, st->st_ino);
+ buf += CNID_DEVINO_LEN;
+ i = S_ISDIR(st->st_mode)?1:0;
+ i = htonl(i);
+ memcpy(buf, &i, sizeof(i));
+ buf += sizeof(i);
+
+ /* did is already in network byte order */
+ memcpy(buf, &did, sizeof(did));
+ buf += sizeof(did);
+
+ memcpy(buf, name, len);
+ *(buf + len) = '\0';
+
+ return start;
+}
+
+/* add an entry to the CNID databases. we do this as a transaction
+ * to prevent messiness.
+ * key: cnid
+ * data:
+ */
static int add_cnid (struct _cnid_tdb_private *db, TDB_DATA *key, TDB_DATA *data) {
TDB_DATA altkey, altdata;
}
/* dev/ino database */
- altkey.dptr = data->dptr;
- altkey.dsize = TDB_DEVINO_LEN;
+ altkey.dptr = data->dptr +CNID_DEVINO_OFS;
+ altkey.dsize = CNID_DEVINO_LEN;
altdata.dptr = key->dptr;
altdata.dsize = key->dsize;
if (tdb_store(db->tdb_devino, altkey, altdata, TDB_REPLACE)) {
}
/* did/name database */
- altkey.dptr = (char *) data->dptr + TDB_DEVINO_LEN;
- altkey.dsize = data->dsize - TDB_DEVINO_LEN;
+ altkey.dptr = (char *) data->dptr +CNID_DID_OFS;
+ altkey.dsize = data->dsize -CNID_DID_OFS;
if (tdb_store(db->tdb_didname, altkey, altdata, TDB_REPLACE)) {
goto abort;
}
hint = htonl(id);
}
else {
- hint = htonl(TDB_START);
+ hint = htonl(CNID_START);
}
memset(&data, 0, sizeof(data));
/* Do a lookup. */
id = cnid_tdb_lookup(cdb, st, did, name, len);
/* ... Return id if it is valid, or if Rootinfo is read-only. */
- if (id || (priv->flags & TDBFLAG_DB_RO)) {
+ if (id || (priv->flags & CNIDFLAG_DB_RO)) {
return id;
}
key.dptr = (char *)&hint;
key.dsize = sizeof(cnid_t);
- if ((data.dptr = make_tdb_data(lstp, did, name, len)) == NULL) {
+ if ((data.dptr = make_tdb_data(cdb->flags, lstp, did, name, len)) == NULL) {
LOG(log_error, logtype_default, "tdb_add: Path name is too long");
errno = CNID_ERR_PATH;
return CNID_INVALID;
}
- data.dsize = TDB_HEADER_LEN + len + 1;
+ data.dsize = CNID_HEADER_LEN + len + 1;
hint = get_cnid(priv);
if (hint == 0) {
errno = CNID_ERR_DB;
return CNID_INVALID;
}
+ memcpy(data.dptr, &hint, sizeof(hint));
/* Now we need to add the CNID data to the databases. */
rc = add_cnid(priv, &key, &data);
/*
- * $Id: cnid_tdb_delete.c,v 1.2 2005-04-28 20:50:02 bfernhomberg Exp $
+ * $Id: cnid_tdb_delete.c,v 1.3 2009-11-20 17:37:14 didg Exp $
*
* Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
* All Rights Reserved. See COPYRIGHT.
tdb_delete(db->tdb_cnid, key);
- key.dptr = data.dptr;
- key.dsize = TDB_DEVINO_LEN;
+ key.dptr = data.dptr +CNID_DEVINO_OFS;
+ key.dsize = CNID_DEVINO_LEN;
tdb_delete(db->tdb_devino, key);
- key.dptr = (char *)data.dptr + TDB_DEVINO_LEN;
- key.dsize = data.dsize - TDB_DEVINO_LEN;
+ key.dptr = (char *)data.dptr +CNID_DID_OFS;
+ key.dsize = data.dsize -CNID_DID_OFS;;
tdb_delete(db->tdb_didname, key);
free(data.dptr);
/*
- * $Id: cnid_tdb_get.c,v 1.3 2005-05-03 14:55:15 didg Exp $
+ * $Id: cnid_tdb_get.c,v 1.4 2009-11-20 17:37:14 didg Exp $
*/
#ifdef HAVE_CONFIG_H
/* Return CNID for a given did/name. */
cnid_t cnid_tdb_get(struct _cnid_db *cdb, const cnid_t did, char *name, const size_t len)
{
- char start[TDB_DID_LEN + MAXPATHLEN + 1], *buf;
+ char start[CNID_DID_LEN + MAXPATHLEN + 1], *buf;
struct _cnid_tdb_private *db;
TDB_DATA key, data;
cnid_t id;
memcpy(buf, name, len);
*(buf + len) = '\0'; /* Make it a C-string. */
key.dptr = start;
- key.dsize = TDB_DID_LEN + len + 1;
+ key.dsize = CNID_DID_LEN + len + 1;
data = tdb_fetch(db->tdb_didname, key);
if (!data.dptr)
return 0;
/*
- * $Id: cnid_tdb_lookup.c,v 1.3 2005-05-03 14:55:15 didg Exp $
+ * $Id: cnid_tdb_lookup.c,v 1.4 2009-11-20 17:37:14 didg Exp $
*/
#ifdef HAVE_CONFIG_H
return 0;
}
- if ((buf = make_tdb_data(st, did, name, len)) == NULL) {
+ if ((buf = make_tdb_data(cdb->flags, st, did, name, len)) == NULL) {
LOG(log_error, logtype_default, "tdb_lookup: Pathname is too long");
return 0;
}
/* 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.dptr = buf;
- key.dsize = TDB_DEVINO_LEN;
+ key.dptr = buf +CNID_DEVINO_OFS;
+ key.dsize = CNID_DEVINO_LEN;
devdata = tdb_fetch(db->tdb_devino, key);
if (!devdata.dptr) {
devino = 0;
}
/* did/name now */
- key.dptr = buf + TDB_DEVINO_LEN;
- key.dsize = TDB_DID_LEN + len + 1;
+ key.dptr = buf + +CNID_DID_OFS;
+ key.dsize = CNID_DID_LEN + len + 1;
diddata = tdb_fetch(db->tdb_didname, key);
if (!diddata.dptr) {
didname = 0;
/*
- * $Id: cnid_tdb_open.c,v 1.3 2009-11-18 13:26:50 didg Exp $
+ * $Id: cnid_tdb_open.c,v 1.4 2009-11-20 17:37:14 didg Exp $
*
* Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
* All Rights Reserved. See COPYRIGHT.
#define DBDEVINO "devino.tdb"
#define DBDIDNAME "didname.tdb" /* did/full name mapping */
-#define DBVERSION_KEY "\0\0\0\0\0"
-#define DBVERSION_KEYLEN 5
+#define DBVERSION_KEY "\0\0\0\0Version"
+#define DBVERSION_KEYLEN (sizeof(DBVERSION_KEY))
#define DBVERSION1 0x00000001U
#define DBVERSION DBVERSION1
/*
- * $Id: cnid_tdb_resolve.c,v 1.2 2005-04-28 20:50:02 bfernhomberg Exp $
+ * $Id: cnid_tdb_resolve.c,v 1.3 2009-11-20 17:37:14 didg Exp $
*/
#ifdef HAVE_CONFIG_H
if (data.dptr)
{
if (data.dsize < len && data.dsize > sizeof(cnid_t)) {
- memcpy(id, (char *)data.dptr + TDB_DEVINO_LEN, sizeof(cnid_t));
- strcpy(buffer, (char *)data.dptr + TDB_HEADER_LEN);
+ memcpy(id, (char *)data.dptr + +CNID_DID_OFS, sizeof(cnid_t));
+ strcpy(buffer, (char *)data.dptr + CNID_NAME_OFS);
free(data.dptr);
return buffer;
}
/*
- * $Id: cnid_tdb_update.c,v 1.3 2005-05-03 14:55:15 didg Exp $
+ * $Id: cnid_tdb_update.c,v 1.4 2009-11-20 17:37:14 didg Exp $
*/
#ifdef HAVE_CONFIG_H
struct _cnid_tdb_private *db;
TDB_DATA key, data, altdata;
- if (!cdb || !(db = cdb->_private) || !id || !st || !name || (db->flags & TDBFLAG_DB_RO)) {
+ if (!cdb || !(db = cdb->_private) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO)) {
return -1;
}
key.dsize = sizeof(id);
memset(&data, 0, sizeof(data));
data = tdb_fetch(db->tdb_cnid, key);
- if (!data.dptr)
+ if (!data.dptr) {
return 0;
-
- key.dptr = data.dptr;
- key.dsize = TDB_DEVINO_LEN;
+ }
+ key.dptr = data.dptr +CNID_DEVINO_OFS;
+ key.dsize = CNID_DEVINO_LEN;
tdb_delete(db->tdb_devino, key);
- key.dptr = (char *)data.dptr + TDB_DEVINO_LEN;
- key.dsize = data.dsize - TDB_DEVINO_LEN;
+ key.dptr = (char *)data.dptr +CNID_DID_OFS;
+ key.dsize = data.dsize - CNID_DID_OFS;
tdb_delete(db->tdb_didname, key);
free(data.dptr);
/* Make a new entry. */
- data.dptr = make_tdb_data(st, did, name, len);
- data.dsize = TDB_HEADER_LEN + len + 1;
+ data.dptr = make_tdb_data(cdb->flags, st, did, name, len);
+ data.dsize = CNID_HEADER_LEN + len + 1;
/* Update the old CNID with the new info. */
key.dptr = (char *) &id;
}
/* Put in a new dev/ino mapping. */
- key.dptr = data.dptr;
- key.dsize = TDB_DEVINO_LEN;
+ key.dptr = data.dptr +CNID_DEVINO_OFS;
+ key.dsize = CNID_DEVINO_LEN;
altdata.dptr = (char *) &id;
altdata.dsize = sizeof(id);
if (tdb_store(db->tdb_devino, key, altdata, TDB_REPLACE)) {
goto update_err;
}
/* put in a new did/name mapping. */
- key.dptr = (char *) data.dptr + TDB_DEVINO_LEN;
- key.dsize = data.dsize - TDB_DEVINO_LEN;
+ key.dptr = (char *) data.dptr +CNID_DID_OFS;
+ key.dsize = data.dsize -CNID_DID_OFS;
+
if (tdb_store(db->tdb_didname, key, altdata, TDB_REPLACE)) {
goto update_err;
}
return 0;
update_err:
- LOG(log_error, logtype_default, "cnid_update: Unable to update CNID %u",
- ntohl(id));
+ LOG(log_error, logtype_default, "cnid_update: Unable to update CNID %u", ntohl(id));
return -1;
}