]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/tdb/cnid_tdb_update.c
Remove bdb env on exit
[netatalk.git] / libatalk / cnid / tdb / cnid_tdb_update.c
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
14 int 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;
107 update_err:
108     LOG(log_error, logtype_default, "cnid_update: Unable to update CNID %u", ntohl(id));
109     return -1;
110
111 }
112
113 #endif