]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/cnid_delete.c
a4b0f3477c41ff462062f62784c57c5ee8c7f13e
[netatalk.git] / libatalk / cnid / cnid_delete.c
1 /*
2  * $Id: cnid_delete.c,v 1.9.2.2 2001-12-03 15:53:39 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, 0))) {
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 */