]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/tdb/cnid_tdb_update.c
6d23b109f528ab71aad7de553339d534fd85431e
[netatalk.git] / libatalk / cnid / tdb / cnid_tdb_update.c
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
10 int 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;
102 update_err:
103     LOG(log_error, logtype_default, "cnid_update: Unable to update CNID %u", ntohl(id));
104     return -1;
105
106 }
107
108 #endif