9 #include <netatalk/endian.h>
10 #include <atalk/adouble.h>
11 #include <atalk/cnid.h>
13 #include "cnid_private.h"
16 /* cnid_update: takes the given cnid and updates the metadata. to
17 handle the did/name data, there are a bunch of functions to get
18 and set the various fields. */
19 int cnid_update(void *CNID, cnid_t id, const struct stat *st,
20 const cnid_t did, const char *name, const int len,
21 const char *info, const int infolen)
24 DBT key, data, altdata;
28 if (!(db = CNID) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO))
31 memset(&key, 0, sizeof(key));
32 memset(&data, 0, sizeof(data));
33 memset(&altdata, 0, sizeof(altdata));
34 txnp = db->dbenv.tx_info;
36 /* begin a transaction */
38 if (errno = txn_begin(txnp, NULL, &tid)) {
42 /* get the old info */
44 key.size = sizeof(id);
45 if (errno = db->db_cnid->get(db->db_cnid, tid, &key, &data, 0)) {
52 /* delete the old dev/ino mapping */
54 key.size = CNID_DEVINO_LEN;
55 if (errno = db->db_devino->del(db->db_devino, tid, &key, 0)) {
56 if (errno == EAGAIN) {
61 /* silently fail on a non-existent entry */
62 if (errno != DB_NOTFOUND) {
68 /* delete the old did/name mapping */
69 key.data = data.data + CNID_DEVINO_LEN;
70 key.size = data.size - CNID_DEVINO_LEN;
71 if (errno = db->db_didname->del(db->db_didname, tid, &key, 0)) {
72 if (errno == EAGAIN) {
77 /* silently fail on a non-existent entry */
78 if (errno != DB_NOTFOUND) {
84 /* delete the old aliases if necessary */
87 /* make a new entry */
88 data.data = make_cnid_data(st, did, name, len);
89 data.size = CNID_HEADER_LEN + len + 1;
91 /* put a new dev/ino mapping in */
93 key.size = CNID_DEVINO_LEN;
95 altdata.size = sizeof(id);
96 if (errno = db->db_devino->put(db->db_devino, tid, &key, &altdata, 0)) {
98 if (errno == EAGAIN) {
104 /* put a new did/name mapping in */
105 key.data = data.data + CNID_DEVINO_LEN;
106 key.size = data.size - CNID_DEVINO_LEN;
107 if (errno = db->db_didname->put(db->db_didname, tid, &key, &altdata, 0)) {
109 if (errno == EAGAIN) {
115 /* update the old CNID with the new info */
117 key.size = sizeof(id);
118 if (errno = db->db_cnid->put(db->db_cnid, tid, &key, &data, 0)) {
120 if (errno == EAGAIN) {
126 /* end transaction */
127 return txn_commit(tid);
130 syslog(LOG_ERR, "cnid_update: can't update CNID(%x)", id);