]> arthur.barton.de Git - netatalk.git/blob - etc/cnid_dbd/dbd_update.c
491a04d9ac640bc29534c4137b8707bfe3af01db
[netatalk.git] / etc / cnid_dbd / dbd_update.c
1 /*
2  * $Id: dbd_update.c,v 1.6 2009-05-28 10:22:07 franklahm Exp $
3  *
4  * Copyright (C) Joerg Lenneis 2003
5  * All Rights Reserved.  See COPYING.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif /* HAVE_CONFIG_H */
11
12 #include <string.h>
13 #include <errno.h>
14 #include <atalk/logger.h>
15 #include <netatalk/endian.h>
16 #include <atalk/cnid_dbd_private.h>
17
18
19 #include "pack.h"
20 #include "dbif.h"
21 #include "dbd.h"
22
23
24 /* cnid_update: takes the given cnid and updates the metadata. */
25
26 /* FIXME: This calls pack_cnid_data(rqst) three times without modifying rqst */
27 /* FIXME: (Only tested with DB 4.1.25):
28
29       dbif_pget on the secondary index followed by dbif_del with the CNID on the
30       main cnid db could be replaced by a single dbif_del on the secondary index. That 
31       deletes the secondary, the corresponding entry from the main cnid db as well as the 
32       other secondary index.
33 */   
34    
35 int dbd_update(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
36 {
37     DBT key,pkey, data;
38     int rc;
39     unsigned char *buf;                            
40     int notfound = 0;
41     char getbuf[CNID_HEADER_LEN + MAXPATHLEN +1];
42     cnid_t tmpcnid;
43
44     memset(&key, 0, sizeof(key));
45     memset(&pkey, 0, sizeof(pkey));
46     memset(&data, 0, sizeof(data));
47
48     rply->namelen = 0;
49
50     buf = pack_cnid_data(rqst);
51     key.data = buf +CNID_DEVINO_OFS;
52     key.size = CNID_DEVINO_LEN;
53
54     data.data = getbuf;
55     data.size = CNID_HEADER_LEN + MAXPATHLEN + 1;
56     if ((rc = dbif_pget(dbd, DBIF_IDX_DEVINO, &key, &pkey, &data, 0)) < 0 ) {
57         goto err_db;
58     }
59     else if  (rc > 0) {
60         memcpy(&tmpcnid, pkey.data, sizeof(cnid_t));
61         LOG(log_debug, logtype_cnid, "dbd_update: Deleting %u corresponding to dev/ino 0x%llx/0x%llx from cnid2.db",
62             ntohl(tmpcnid), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
63
64         if ((rc = dbif_del(dbd, DBIF_CNID, &pkey, 0)) < 0 ) {
65             goto err_db;
66         }
67         else if (!rc) {
68             LOG(log_error, logtype_cnid, "dbd_update: delete DEVINO %u %s", ntohl(rqst->cnid), db_strerror(errno));
69         }
70     }
71     if (!rc) {
72        notfound = 1;
73     }
74
75     buf = pack_cnid_data(rqst);
76     key.data = buf + CNID_DID_OFS;
77     key.size = CNID_DID_LEN + rqst->namelen +1;
78     memset(&pkey, 0, sizeof(pkey));
79
80     if ((rc = dbif_pget(dbd, DBIF_IDX_DIDNAME, &key, &pkey, &data, 0)) < 0) {
81         goto err_db;
82     }
83     else if  (rc > 0) {
84
85         memcpy(&tmpcnid, pkey.data, sizeof(cnid_t));
86         
87         LOG(log_debug, logtype_cnid, "dbd_update: Deleting %u corresponding to did %u name %s from cnid2.db",
88             ntohl(tmpcnid), ntohl(rqst->did), rqst->name);
89     
90         if ((rc = dbif_del(dbd, DBIF_CNID, &pkey, 0)) < 0) {
91             goto err_db;
92         }
93         else if (!rc) {
94                 LOG(log_error, logtype_cnid, "dbd_update: delete DIDNAME %u %s", ntohl(rqst->cnid), db_strerror(errno));
95         }
96     }
97     if (!rc) {
98        notfound |= 2;
99     }
100
101     memset(&key, 0, sizeof(key));
102     key.data = (cnid_t *) &rqst->cnid;
103     key.size = sizeof(rqst->cnid);
104
105     memset(&data, 0, sizeof(data));
106     /* Make a new entry. */
107     data.data = pack_cnid_data(rqst);
108     memcpy(data.data, &rqst->cnid, sizeof(rqst->cnid));
109     data.size = CNID_HEADER_LEN + rqst->namelen + 1;
110
111     if (dbif_put(dbd, DBIF_CNID, &key, &data, 0) < 0)
112         goto err_db;
113
114     LOG(log_info, logtype_cnid, "dbd_update: Updated cnid2.db with dev/ino 0x%llx/0x%llx did %u name %s cnid %u",
115         (unsigned long long)rqst->dev, (unsigned long long)rqst->ino, ntohl(rqst->did), rqst->name, ntohl(rqst->cnid));
116
117     rply->result = CNID_DBD_RES_OK;
118     return 1;
119
120 err_db:
121     LOG(log_error, logtype_cnid, "dbd_update: Unable to update CNID %u dev/ino 0x%llx/0x%llx, DID %ul: %s",
122         ntohl(rqst->cnid), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino, rqst->did, rqst->name);
123
124     rply->result = CNID_DBD_RES_ERR_DB;
125     return -1;
126 }