/*
- * $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);