]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/db3/cnid_db3_delete.c
use log_debug rather than log_info for LOG inside ifdef DEBUG
[netatalk.git] / libatalk / cnid / db3 / cnid_db3_delete.c
1 /*
2  * $Id: cnid_db3_delete.c,v 1.3 2009-10-29 13:17:29 didg Exp $
3  *
4  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
5  * All Rights Reserved. See COPYRIGHT.
6  *
7  * cnid_delete: delete a CNID from the database 
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif /* HAVE_CONFIG_H */
13
14 #ifdef CNID_BACKEND_DB3
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <atalk/logger.h>
20
21 #ifdef HAVE_DB4_DB_H
22 #include <db4/db.h>
23 #else
24 #include <db.h>
25 #endif
26 #include <netatalk/endian.h>
27 #include <atalk/adouble.h>
28 #include "cnid_db3.h"
29
30 #include "cnid_db3_private.h"
31
32 int cnid_db3_delete(struct _cnid_db *cdb, const cnid_t id) {
33     CNID_private *db;
34     DBT key, data;
35     DB_TXN *tid;
36     int rc, found = 0;
37
38     if (!cdb || !(db = cdb->_private) || !id || (db->flags & CNIDFLAG_DB_RO)) {
39         return -1;
40     }
41
42     memset(&key, 0, sizeof(key));
43     memset(&data, 0, sizeof(data));
44
45     /* Get from ain CNID database. */
46     key.data = (cnid_t *)&id;
47     key.size = sizeof(id);
48     while (!found) {
49         rc = db->db_cnid->get(db->db_cnid, NULL, &key, &data, 0);
50         switch (rc) {
51         case 0:
52             found = 1;
53             break;
54         case DB_LOCK_DEADLOCK:
55             break;
56         case DB_NOTFOUND:
57 #ifdef DEBUG
58             LOG(log_debug, logtype_default, "cnid_delete: CNID %u not in database",
59                 ntohl(id));
60 #endif
61             return 0;
62         default:
63             LOG(log_error, logtype_default, "cnid_delete: Unable to delete entry: %s",
64                 db_strerror(rc));
65             return rc;
66         }
67     }
68
69 retry:
70     if ((rc = db3_txn_begin(db->dbenv, NULL, &tid, 0)) != 0) {
71         LOG(log_error, logtype_default, "cnid_delete: Failed to begin transaction: %s",
72             db_strerror(rc));
73         return rc;
74     }
75
76     /* Now delete from the main CNID database. */
77     key.data = (cnid_t *)&id;
78     key.size = sizeof(id);
79     if ((rc = db->db_cnid->del(db->db_cnid, tid, &key, 0))) {
80         int ret;
81         if ((ret = db3_txn_abort(tid)) != 0) {
82             LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s", db_strerror(ret));
83             return ret;
84         }
85         switch (rc) {
86         case DB_LOCK_DEADLOCK:
87             goto retry;
88         default:
89             goto abort_err;
90         }
91     }
92
93     /* Now delete from dev/ino database. */
94     key.data = data.data;
95     key.size = CNID_DEVINO_LEN;
96     if ((rc = db->db_devino->del(db->db_devino, tid, &key, 0))) {
97         switch (rc) {
98         case DB_LOCK_DEADLOCK:
99             if ((rc = db3_txn_abort(tid)) != 0) {
100                 LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s",
101                     db_strerror(rc));
102                 return rc;
103             }
104             goto retry;
105         case DB_NOTFOUND:
106             /* Quietly fall through if the entry isn't found. */
107             break;
108         default:
109             if ((rc = db3_txn_abort(tid)) != 0) {
110                 LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s",
111                     db_strerror(rc));
112                 return rc;
113             }
114             goto abort_err;
115         }
116     }
117
118     /* Get data from the did/name database.
119      * TODO Also handle did/macname, did/shortname, and did/longname. */
120     key.data = (char *)data.data + CNID_DEVINO_LEN;
121     key.size = data.size - CNID_DEVINO_LEN;
122     if ((rc = db->db_didname->del(db->db_didname, tid, &key, 0))) {
123         switch (rc) {
124         case DB_LOCK_DEADLOCK:
125             if ((rc = db3_txn_abort(tid)) != 0) {
126                 LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s",
127                     db_strerror(rc));
128                 return rc;
129             }
130             goto retry;
131         case DB_NOTFOUND:
132             break;
133         default:
134             if ((rc = db3_txn_abort(tid)) != 0) {
135                 LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s",
136                     db_strerror(rc));
137                 return rc;
138             }
139             goto abort_err;
140         }
141     }
142
143 #ifdef DEBUG
144     LOG(log_debug, logtype_default, "cnid_delete: Deleting CNID %u", ntohl(id));
145 #endif
146     if ((rc = db3_txn_commit(tid, 0)) != 0) {
147         LOG(log_error, logtype_default, "cnid_delete: Failed to commit transaction: %s",
148             db_strerror(rc));
149         return rc;
150     }
151     return 0;
152
153 abort_err:
154     LOG(log_error, logtype_default, "cnid_delete: Unable to delete CNID %u: %s",
155         ntohl(id), db_strerror(rc));
156     return rc;
157 }
158
159 #endif /* CNID_BACKEND_DB3 */