1#ifdef HAVE_CONFIG_H 2#include "config.h" 3#endif 4 5#ifdef CNID_BACKEND_TDB 6 7#include "cnid_tdb.h" 8#include <atalk/logger.h> 9 10int cnid_tdb_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st, 11 cnid_t did, const char *name, size_t len) 12{ 13 struct _cnid_tdb_private *db; 14 TDB_DATA key, data, altdata; 15 16 if (!cdb || !(db = cdb->_private) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO)) { 17 return -1; 18 } 19 20 memset(&key, 0, sizeof(key)); 21 memset(&altdata, 0, sizeof(altdata)); 22 23 24 /* Get the old info. search by dev/ino */ 25 data.dptr = make_tdb_data(cdb->flags, st, did, name, len); 26 data.dsize = CNID_HEADER_LEN + len + 1; 27 key.dptr = data.dptr +CNID_DEVINO_OFS; 28 key.dsize = CNID_DEVINO_LEN; 29 altdata = tdb_fetch(db->tdb_devino, key); 30 if (altdata.dptr) { 31 tdb_delete(db->tdb_devino, key); 32 33 key.dptr = altdata.dptr; 34 key.dsize = sizeof(id); 35 36 data = tdb_fetch(db->tdb_cnid, key); 37 tdb_delete(db->tdb_cnid, key); 38 free(altdata.dptr); 39 40 if (data.dptr) { 41 key.dptr = (unsigned char *)data.dptr +CNID_DID_OFS; 42 key.dsize = data.dsize - CNID_DID_OFS; 43 tdb_delete(db->tdb_didname, key); 44 45 free(data.dptr); 46 } 47 } 48 49 /* search by did/name */ 50 data.dptr = make_tdb_data(cdb->flags, st, did, name, len); 51 data.dsize = CNID_HEADER_LEN + len + 1; 52 key.dptr = (unsigned char *)data.dptr +CNID_DID_OFS; 53 key.dsize = data.dsize - CNID_DID_OFS; 54 altdata = tdb_fetch(db->tdb_didname, key); 55 if (altdata.dptr) { 56 tdb_delete(db->tdb_didname, key); 57 58 key.dptr = altdata.dptr; 59 key.dsize = sizeof(id); 60 data = tdb_fetch(db->tdb_cnid, key); 61 tdb_delete(db->tdb_cnid, key); 62 free(altdata.dptr); 63 64 if (data.dptr) { 65 key.dptr = data.dptr +CNID_DEVINO_OFS; 66 key.dsize = CNID_DEVINO_LEN; 67 tdb_delete(db->tdb_devino, key); 68 free(data.dptr); 69 } 70 } 71 72 73 /* Make a new entry. */ 74 data.dptr = make_tdb_data(cdb->flags, st, did, name, len); 75 data.dsize = CNID_HEADER_LEN + len + 1; 76 memcpy(data.dptr, &id, sizeof(id)); 77 78 /* Update the old CNID with the new info. */ 79 key.dptr = (unsigned char *) &id; 80 key.dsize = sizeof(id); 81 if (tdb_store(db->tdb_cnid, key, data, TDB_REPLACE)) { 82 goto update_err; 83 } 84 85 /* Put in a new dev/ino mapping. */ 86 key.dptr = data.dptr +CNID_DEVINO_OFS; 87 key.dsize = CNID_DEVINO_LEN; 88 altdata.dptr = (unsigned char *) &id; 89 altdata.dsize = sizeof(id); 90 if (tdb_store(db->tdb_devino, key, altdata, TDB_REPLACE)) { 91 goto update_err; 92 } 93 /* put in a new did/name mapping. */ 94 key.dptr = (unsigned char *) data.dptr +CNID_DID_OFS; 95 key.dsize = data.dsize -CNID_DID_OFS; 96 97 if (tdb_store(db->tdb_didname, key, altdata, TDB_REPLACE)) { 98 goto update_err; 99 } 100 101 return 0; 102update_err: 103 LOG(log_error, logtype_default, "cnid_update: Unable to update CNID %u", ntohl(id)); 104 return -1; 105 106} 107 108#endif 109