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