]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/cnid_delete.c
increase number of cnid_dbd slots to 512
[netatalk.git] / libatalk / cnid / cnid_delete.c
1 /*
2  * $Id: cnid_delete.c,v 1.14 2002-08-30 03:12:52 jmarcus 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_DB
15 #include <stdio.h>
16 #include <string.h>
17 #include <errno.h>
18 #include <atalk/logger.h>
19
20 #include <db.h>
21 #include <netatalk/endian.h>
22 #include <atalk/adouble.h>
23 #include <atalk/cnid.h>
24
25 #include "cnid_private.h"
26
27 #ifdef CNID_DB_CDB
28     #define tid    NULL
29 #endif /* CNID_DB_CDB */
30
31 int cnid_delete(void *CNID, const cnid_t id) {
32     CNID_private *db;
33     DBT key, data;
34 #ifndef CNID_DB_CDB
35     DB_TXN *tid;
36 #endif /* CNID_DB_CDB */
37     int rc, found = 0;
38
39     if (!(db = CNID) || !id || (db->flags & CNIDFLAG_DB_RO)) {
40         return -1;
41     }
42
43     memset(&key, 0, sizeof(key));
44     memset(&data, 0, sizeof(data));
45
46     /* Get from ain CNID database. */
47     key.data = (cnid_t *)&id;
48     key.size = sizeof(id);
49     while (!found) {
50         rc = db->db_cnid->get(db->db_cnid, NULL, &key, &data, 0);
51         switch (rc) {
52         case 0:
53             found = 1;
54             break;
55 #ifndef CNID_DB_CDB
56         case DB_LOCK_DEADLOCK:
57             break;
58 #endif /* CNID_DB_CDB */
59         case DB_NOTFOUND:
60 #ifdef DEBUG
61             LOG(log_info, logtype_default, "cnid_delete: CNID %u not in database",
62                 ntohl(id));
63 #endif
64             return 0;
65         default:
66             LOG(log_error, logtype_default, "cnid_delete: Unable to delete entry: %s",
67                 db_strerror(rc));
68             return rc;
69         }
70     }
71
72 #ifndef CNID_DB_CDB
73 retry:
74     if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) {
75         LOG(log_error, logtype_default, "cnid_delete: Failed to begin transaction: %s",
76             db_strerror(rc));
77         return rc;
78     }
79 #endif /* CNID_DB_CDB */
80
81     /* Now delete from the main CNID database. */
82     key.data = (cnid_t *)&id;
83     key.size = sizeof(id);
84     if ((rc = db->db_cnid->del(db->db_cnid, tid, &key, 0))) {
85 #ifndef CNID_DB_CDB
86         int ret;
87         if ((ret = txn_abort(tid)) != 0) {
88             LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s", db_strerror(ret));
89             return ret;
90         }
91         switch (rc) {
92         case DB_LOCK_DEADLOCK:
93             goto retry;
94         default:
95 #endif /* CNID_DB_CDB */
96             goto abort_err;
97 #ifndef CNID_DB_CDB
98         }
99 #endif /* CNID_DB_CDB */
100     }
101
102     /* Now delete from dev/ino database. */
103     key.data = data.data;
104     key.size = CNID_DEVINO_LEN;
105     if ((rc = db->db_devino->del(db->db_devino, tid, &key, 0))) {
106         switch (rc) {
107 #ifndef CNID_DB_CDB
108         case DB_LOCK_DEADLOCK:
109             if ((rc = 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 retry;
115 #endif /* CNID_DB_CDB */
116         case DB_NOTFOUND:
117             /* Quietly fall through if the entry isn't found. */
118             break;
119         default:
120 #ifndef CNID_DB_CDB
121             if ((rc = txn_abort(tid)) != 0) {
122                 LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s",
123                     db_strerror(rc));
124                 return rc;
125             }
126 #endif /* CNID_DB_CDB */
127             goto abort_err;
128         }
129     }
130
131     /* Get data from the did/name database.
132      * TODO Also handle did/macname, did/shortname, and did/longname. */
133     key.data = (char *)data.data + CNID_DEVINO_LEN;
134     key.size = data.size - CNID_DEVINO_LEN;
135     if ((rc = db->db_didname->del(db->db_didname, tid, &key, 0))) {
136         switch (rc) {
137 #ifndef CNID_DB_CDB
138         case DB_LOCK_DEADLOCK:
139             if ((rc = txn_abort(tid)) != 0) {
140                 LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s",
141                     db_strerror(rc));
142                 return rc;
143             }
144             goto retry;
145 #endif /* CNID_DB_CDB */
146         case DB_NOTFOUND:
147             break;
148         default:
149 #ifndef CNID_DB_CDB
150             if ((rc = txn_abort(tid)) != 0) {
151                 LOG(log_error, logtype_default, "cnid_delete: txn_abort: %s",
152                     db_strerror(rc));
153                 return rc;
154             }
155 #endif /* CNID_DB_CDB */
156             goto abort_err;
157         }
158     }
159
160 #ifdef DEBUG
161     LOG(log_info, logtype_default, "cnid_delete: Deleting CNID %u", ntohl(id));
162 #endif
163 #ifndef CNID_DB_CDB
164     if ((rc = txn_commit(tid, 0)) != 0) {
165         LOG(log_error, logtype_default, "cnid_delete: Failed to commit transaction: %s",
166             db_strerror(rc));
167         return rc;
168     }
169 #endif /* CNID_DB_CDB */
170     return 0;
171
172 abort_err:
173     LOG(log_error, logtype_default, "cnid_delete: Unable to delete CNID %u: %s",
174         ntohl(id), db_strerror(rc));
175     return rc;
176 }
177 #endif /*CNID_DB */