2 * $Id: cnid_tdb_lookup.c,v 1.6 2009-11-21 11:12:49 didg Exp $
9 #ifdef CNID_BACKEND_TDB
12 #include <atalk/logger.h>
14 cnid_t cnid_tdb_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t did, char *name, const size_t len)
17 struct _cnid_tdb_private *db;
18 TDB_DATA key, devdata, diddata, cniddata;
19 int devino = 1, didname = 1;
20 char dev[CNID_DEV_LEN];
21 char ino[CNID_INO_LEN];
22 u_int32_t type_devino = (unsigned)-1;
23 u_int32_t type_didname = (unsigned)-1;
26 cnid_t id_devino = 0, id_didname = 0,id = 0;
28 if (!cdb || !(db = cdb->_private) || !st || !name) {
32 if ((buf = make_tdb_data(cdb->flags, st, did, name, len)) == NULL) {
33 LOG(log_error, logtype_default, "tdb_lookup: Pathname is too long");
36 memcpy(&type, buf +CNID_TYPE_OFS, sizeof(type));
39 memset(&key, 0, sizeof(key));
40 memset(&devdata, 0, sizeof(devdata));
41 memset(&diddata, 0, sizeof(diddata));
42 memset(&cniddata, 0, sizeof(cniddata));
44 /* Look for a CNID. We have two options: dev/ino or did/name. If we
45 * only get a match in one of them, that means a file has moved. */
46 memcpy(dev, buf + CNID_DEV_OFS, CNID_DEV_LEN);
47 memcpy(ino, buf + CNID_INO_OFS, CNID_INO_LEN);
49 key.dptr = buf +CNID_DEVINO_OFS;
50 key.dsize = CNID_DEVINO_LEN;
51 cniddata = tdb_fetch(db->tdb_devino, key);
57 key.dptr = cniddata.dptr;
58 key.dsize = sizeof(id);
60 devdata = tdb_fetch(db->tdb_cnid, key);
63 memcpy(&id_devino, devdata.dptr, sizeof(cnid_t));
64 memcpy(&type_devino, (char *)devdata.dptr +CNID_TYPE_OFS, sizeof(type_devino));
65 type_devino = ntohl(type_devino);
73 key.dptr = buf + CNID_DID_OFS;
74 key.dsize = CNID_DID_LEN + len + 1;
75 cniddata = tdb_fetch(db->tdb_didname, key);
81 key.dptr = cniddata.dptr;
82 key.dsize = sizeof(id);
84 diddata = tdb_fetch(db->tdb_cnid, key);
87 memcpy(&id_didname, diddata.dptr, sizeof(cnid_t));
88 memcpy(&type_didname, (char *)diddata.dptr +CNID_TYPE_OFS, sizeof(type_didname));
89 type_didname = ntohl(type_didname);
95 /* Set id. Honor did/name over dev/ino as dev/ino isn't necessarily
97 if (!devino && !didname) {
103 if (devino && didname && id_devino == id_didname && type_devino == type) {
112 /* we have a did:name
113 * if it's the same dev or not the same type
116 if (!memcmp(dev, (char *)diddata.dptr + CNID_DEV_OFS, CNID_DEV_LEN) ||
117 type_didname != type) {
118 if (cnid_tdb_delete(cdb, id) < 0) {
131 if (type_devino != type) {
132 /* same dev:inode but not same type one is a folder the other
133 * is a file,it's an inode reused, delete the record
135 if (cnid_tdb_delete(cdb, id) < 0) {
151 /* Fix up the database. */
152 cnid_tdb_update(cdb, id, st, did, name, len);