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