]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/cnid/tdb/cnid_tdb_add.c
update tdb to use the same format as dbd/cdb, still broken (exchangefile)
[netatalk.git] / libatalk / cnid / tdb / cnid_tdb_add.c
index fe5d36286d11675c38441c145a333b0a03bd10ab..5758300c2e528c6b8a513b086fb8a4fb4a43e1e9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $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;
 
@@ -35,8 +86,8 @@ static int add_cnid (struct _cnid_tdb_private *db, TDB_DATA *key, TDB_DATA *data
     }
 
     /* 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)) {
@@ -44,8 +95,8 @@ static int add_cnid (struct _cnid_tdb_private *db, TDB_DATA *key, TDB_DATA *data
     }
 
     /* 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;
     }
@@ -83,7 +134,7 @@ static cnid_t get_cnid(struct _cnid_tdb_private *db)
         hint = htonl(id);
     }
     else {
-        hint = htonl(TDB_START);
+        hint = htonl(CNID_START);
     }
     
     memset(&data, 0, sizeof(data));
@@ -118,7 +169,7 @@ cnid_t cnid_tdb_add(struct _cnid_db *cdb, const struct stat *st,
     /* 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;
     }
 
@@ -134,17 +185,18 @@ cnid_t cnid_tdb_add(struct _cnid_db *cdb, const struct stat *st,
 
     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);