]> arthur.barton.de Git - netatalk.git/blob - etc/cnid_dbd/cmd_dbd_lookup.c
Comment out all mappings. They're unmaintained, possibly wrong and do not fit for...
[netatalk.git] / etc / cnid_dbd / cmd_dbd_lookup.c
1 /*
2  * $Id: cmd_dbd_lookup.c,v 1.1 2009-05-14 13:46:08 franklahm Exp $
3  *
4  * Copyright (C) Frank Lahm 2009
5  * All Rights Reserved.  See COPYING.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif /* HAVE_CONFIG_H */
11
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <sys/param.h>
16 #include <errno.h>
17 #include <netatalk/endian.h>
18 #include <atalk/logger.h>
19 #include <atalk/cnid_dbd_private.h>
20
21 #include "pack.h"
22 #include "dbif.h"
23 #include "dbd.h"
24 #include "cmd_dbd.h"
25
26 /* Pull these in from dbd_add.c */
27 extern int add_cnid(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply);
28 extern int get_cnid(DBD *dbd, struct cnid_dbd_rply *rply);
29
30 /*
31  *  This returns the CNID corresponding to a particular file and logs any inconsitencies.
32  *  If roflags == 1 we only scan, if roflag == 0, we modify, but we do _not_ *add* as does
33  *  dbd_lookup.
34  */
35
36 int cmd_dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, int roflag)
37 {
38     unsigned char *buf;
39     DBT key, devdata, diddata;
40     uint64_t dev = 0;
41     int devino = 1, didname = 1; 
42     int rc;
43     cnid_t id_devino, id_didname;
44     u_int32_t type_devino  = (unsigned)-1;
45     u_int32_t type_didname = (unsigned)-1;
46     int update = 0;
47     
48     memset(&key, 0, sizeof(key));
49     memset(&diddata, 0, sizeof(diddata));
50     memset(&devdata, 0, sizeof(devdata));
51
52     rply->namelen = 0; 
53     rply->cnid = 0;
54     
55     buf = pack_cnid_data(rqst); 
56
57     /* Look for a CNID.  We have two options: dev/ino or did/name.  If we
58        only get a match in one of them, that means a file has moved. */
59     key.data = buf + CNID_DEVINO_OFS;
60     key.size = CNID_DEVINO_LEN;
61
62     if ((rc = dbif_get(dbd, DBIF_IDX_DEVINO, &key, &devdata, 0))  < 0) {
63         dbd_log( LOGSTD, "dbd_search: Unable to get CNID %u, name %s",
64                 ntohl(rqst->did), rqst->name);
65         rply->result = CNID_DBD_RES_ERR_DB;
66         return -1;
67     }
68     if (rc == 0) {
69         devino = 0;
70     }
71     else {
72         memcpy(&id_devino, devdata.data, sizeof(rply->cnid));
73         memcpy(&type_devino, (char *)devdata.data +CNID_TYPE_OFS, sizeof(type_devino));
74         type_devino = ntohl(type_devino);
75     }
76
77     key.data = buf + CNID_DID_OFS;
78     key.size = CNID_DID_LEN + rqst->namelen + 1;
79
80     if ((rc = dbif_get(dbd, DBIF_IDX_DIDNAME, &key, &diddata, 0))  < 0) {
81         dbd_log( LOGSTD, "dbd_search: Unable to get CNID %u, name %s",
82                 ntohl(rqst->did), rqst->name);
83         rply->result = CNID_DBD_RES_ERR_DB;
84         return -1;
85     }
86     if (rc == 0) {
87         didname = 0;
88     }
89     else {
90         memcpy(&id_didname, diddata.data, sizeof(rply->cnid));
91         memcpy(&type_didname, (char *)diddata.data +CNID_TYPE_OFS, sizeof(type_didname));
92         type_didname = ntohl(type_didname);
93     }
94     
95     if (!devino && !didname) {  
96         /* not found */
97         dbd_log( LOGDEBUG, "name: '%s/%s', did: %u, dev/ino: 0x%llx/0x%llx is not in the CNID database", 
98                  cwdbuf, rqst->name, ntohl(rqst->did), (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
99         rply->result = CNID_DBD_RES_NOTFOUND;
100         return 1;
101     }
102
103     if (devino && didname && id_devino == id_didname && type_devino == rqst->type) {
104         /* the same */
105         rply->cnid = id_didname;
106         rply->result = CNID_DBD_RES_OK;
107         return 1;
108     }
109
110     if (didname) {
111         dbd_log( LOGSTD, "CNID resolve problem: changed dev/ino for '%s/%s'", cwdbuf, rqst->name);
112         rqst->cnid = id_didname;
113         /* we have a did/name.
114            If it's the same dev or not the same type, e.g. a remove followed by a new file
115            with the same name */
116         if (!memcmp(&dev, (char *)diddata.data + CNID_DEV_OFS, CNID_DEV_LEN) ||
117                    type_didname != rqst->type) {
118             if (! roflag)
119                 if (dbd_delete(dbd, rqst, rply) < 0)
120                     return -1;
121         }
122         else {
123             update = 1;
124         }
125     }
126
127     if (devino) {
128         dbd_log( LOGSTD, "CNID resolve problem: server side rename oder reused inode for '%s/%s'", cwdbuf, rqst->name);
129         rqst->cnid = id_devino;
130         if (type_devino != rqst->type) {
131             /* same dev/inode but not same type: it's an inode reused, delete the record */
132             if (! roflag)
133                 if (dbd_delete(dbd, rqst, rply) < 0)
134                     return -1;
135         }
136         else {
137             update = 1;
138         }
139     }
140     if (!update || roflag) {
141         rply->result = CNID_DBD_RES_NOTFOUND;
142         return 1;
143     }
144     /* Fix up the database. assume it was a file move and rename */
145     rc = dbd_update(dbd, rqst, rply);
146     if (rc >0) {
147         rply->cnid = rqst->cnid;
148     }
149
150     dbd_log( LOGSTD, "CNID database needed update: dev/ino: 0x%llx/0x%llx, did: %u, name: '%s/%s' --> CNID: %u", 
151              (unsigned long long)rqst->dev, (unsigned long long)rqst->ino,
152              ntohl(rqst->did), cwdbuf, rqst->name, ntohl(rply->cnid));
153
154     return rc;
155 }
156
157 /* 
158    This is taken from dbd_add.c
159 */
160 int cmd_dbd_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply)
161 {
162     if (get_cnid(dbd, rply) < 0) {
163         if (rply->result == CNID_DBD_RES_ERR_MAX) {
164             dbd_log( LOGSTD, "FATAL: CNID database has reached its limit.");
165             /* This will cause an abort/rollback if transactions are used */
166             return 0;
167         } else {
168             dbd_log( LOGSTD, "Failed to compute CNID for %s, error reading/updating Rootkey", rqst->name);
169             return -1;
170         }
171     }
172     
173     if (add_cnid(dbd, rqst, rply) < 0) {
174         if (rply->result == CNID_DBD_RES_ERR_DUPLCNID) {
175             dbd_log( LOGSTD, "Cannot add CNID %u. Corrupt/invalid Rootkey?.", ntohl(rply->cnid));
176             /* abort/rollback, see above */
177             return 0;
178         } else {
179             dbd_log( LOGSTD, "Failed to add CNID for %s to database", rqst->name);
180             return -1;
181         }
182     }
183     dbd_log( LOGDEBUG, "Add to CNID database: did: %u, cnid: %u, name: '%s', dev/ino: 0x%llx/0x%llx",
184              ntohl(rqst->did), ntohl(rply->cnid), rqst->name,
185              (unsigned long long)rqst->dev, (unsigned long long)rqst->ino);
186
187     rply->result = CNID_DBD_RES_OK;
188     return 1;
189 }