]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/cnid_delete.c
Add a static variable to track the exclusive lock. Seems Macs like to open
[netatalk.git] / libatalk / cnid / cnid_delete.c
1 /*
2  * $Id: cnid_delete.c,v 1.9 2001-10-22 03:40:19 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 <syslog.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 int cnid_delete(void *CNID, const cnid_t id) {
28         CNID_private *db;
29         DBT key, data;
30         DB_TXN *tid;
31         int rc;
32
33         if (!(db = CNID) || !id || (db->flags & CNIDFLAG_DB_RO)) {
34                 return -1;
35         }
36
37         memset(&key, 0, sizeof(key));
38         memset(&data, 0, sizeof(data));
39
40 retry:
41         if ((rc = txn_begin(db->dbenv, NULL, &tid, 0)) != 0) {
42                 syslog(LOG_ERR, "cnid_delete: Failed to begin transaction: %s",
43                        db_strerror(rc));
44                 return rc;
45         }
46
47         /* Get from ain CNID database. */
48         key.data = (cnid_t *)&id;
49         key.size = sizeof(id);
50         if ((rc = db->db_cnid->get(db->db_cnid, tid, &key, &data, DB_RMW))) {
51                 int ret;
52                 if ((ret = txn_abort(tid)) != 0) {
53                         syslog(LOG_ERR, "cnid_delete: txn_abort: %s", db_strerror(ret));
54                         return ret;
55                 }
56                 switch (rc) {
57                         case DB_LOCK_DEADLOCK:
58                                 goto retry;
59                         case DB_NOTFOUND:
60                                 syslog(LOG_INFO, "cnid_delete: CNID %u not in database", 
61                                        ntohl(id));
62                                 return 0;
63                         default:
64                                 syslog(LOG_ERR, "cnid_delete: Unable to delete entry: %s",
65                                        db_strerror(rc));
66                                 return rc;
67                 }
68         }
69
70         /* Now delete from dev/ino database. */
71         key.data = data.data;
72         key.size = CNID_DEVINO_LEN;
73         if ((rc = db->db_devino->del(db->db_devino, tid, &key, 0))) {
74                 switch (rc) {
75                         case DB_LOCK_DEADLOCK:
76                                 if ((rc = txn_abort(tid)) != 0) {
77                                         syslog(LOG_ERR, "cnid_delete: txn_abort: %s",
78                                                db_strerror(rc));
79                                         return rc;
80                                 }
81                                 goto retry;
82                         case DB_NOTFOUND:
83                                 /* Quietly fall through if the entry isn't found. */
84                                 break;
85                         default:
86                                 if ((rc = txn_abort(tid)) != 0) {
87                                         syslog(LOG_ERR, "cnid_delete: txn_abort: %s",
88                                                db_strerror(rc));
89                                         return rc;
90                                 }
91                                 goto abort_err;
92                 }
93         }
94
95         /* Get data from the did/name database.
96          * TODO Also handle did/macname, did/shortname, and did/longname. */
97         
98         key.data = (char *)data.data + CNID_DEVINO_LEN;
99         key.size = data.size - CNID_DEVINO_LEN;
100         if ((rc = db->db_didname->del(db->db_didname, tid, &key, 0))) {
101                 switch (rc) {
102                         case DB_LOCK_DEADLOCK:
103                                 if ((rc = txn_abort(tid)) != 0) {
104                                         syslog(LOG_ERR, "cnid_delete: txn_abort: %s",
105                                                db_strerror(rc));
106                                         return rc;
107                                 }
108                                 goto retry;
109                         case DB_NOTFOUND:
110                                 break;
111                         default:
112                                 if ((rc = txn_abort(tid)) != 0) {
113                                         syslog(LOG_ERR, "cnid_delete: txn_abort: %s",
114                                                db_strerror(rc));
115                                         return rc;
116                                 }
117                                 goto abort_err;
118                 }
119         }
120
121         /* Now delete from the main CNID database. */
122         key.data = (cnid_t *)&id;
123         key.size = sizeof(id);
124         if ((rc = db->db_cnid->del(db->db_cnid, tid, &key, 0))) {
125                 int ret;
126                 if ((ret = txn_abort(tid)) != 0) {
127                         syslog(LOG_ERR, "cnid_delete: txn_abort: %s", db_strerror(ret));
128                         return ret;
129                 }
130                 switch (rc) {
131                         case DB_LOCK_DEADLOCK:
132                                 goto retry;
133                         default:
134                                 goto abort_err;
135                 }
136         }
137
138 #ifdef DEBUG
139         syslog(LOG_INFO, "cnid_delete: Deleting CNID %u", ntohl(id));
140 #endif
141         if ((rc = txn_commit(tid, 0)) != 0) {
142                 syslog(LOG_ERR, "cnid_delete: Failed to commit transaction: %s",
143                        db_strerror(rc));
144                 return rc;
145         }
146         return 0;
147
148 abort_err:
149         syslog(LOG_ERR, "cnid_delete: Unable to delete CNID %u: %s",
150                ntohl(id), db_strerror(rc));
151         return rc;
152 }
153 #endif /*CNID_DB */