~ubuntu-branches/ubuntu/precise/netatalk/precise

« back to all changes in this revision

Viewing changes to libatalk/cnid/cnid_update.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: cnid_update.c,v 1.20.2.1 2003/09/16 14:21:44 bfernhomberg Exp $
 
3
 */
 
4
 
 
5
#ifdef HAVE_CONFIG_H
 
6
#include "config.h"
 
7
#endif /* HAVE_CONFIG_H */
 
8
 
 
9
#ifdef CNID_DB
 
10
#include <stdio.h>
 
11
#include <string.h>
 
12
#include <sys/param.h>
 
13
#include <sys/stat.h>
 
14
#include <errno.h>
 
15
#include <atalk/logger.h>
 
16
 
 
17
#include <db.h>
 
18
#include <netatalk/endian.h>
 
19
#include <atalk/adouble.h>
 
20
#include <atalk/cnid.h>
 
21
 
 
22
#include "cnid_private.h"
 
23
 
 
24
#ifdef CNID_DB_CDB
 
25
#define tid    NULL
 
26
#endif /* CNID_DB_CDB */
 
27
 
 
28
/* cnid_update: takes the given cnid and updates the metadata.  To
 
29
 * handle the did/name data, there are a bunch of functions to get
 
30
 * and set the various fields. */
 
31
int cnid_update(void *CNID, const cnid_t id, const struct stat *st,
 
32
                const cnid_t did, const char *name, const int len
 
33
                /*, const char *info, const int infolen*/)
 
34
{
 
35
    CNID_private *db;
 
36
    DBT key, data, altdata;
 
37
#ifndef CNID_DB_CDB
 
38
    DB_TXN *tid;
 
39
#endif /* CNID_DB_CDB */
 
40
    int rc;
 
41
 
 
42
    if (!(db = CNID) || !id || !st || !name || (db->flags & CNIDFLAG_DB_RO)) {
 
43
        return -1;
 
44
    }
 
45
 
 
46
    memset(&key, 0, sizeof(key));
 
47
    memset(&altdata, 0, sizeof(altdata));
 
48
 
 
49
#ifndef CNID_DB_CDB
 
50
retry:
 
51
    if ((rc = txn_begin(db->dbenv, NULL, &tid, 0))) {
 
52
        LOG(log_error, logtype_default, "cnid_update: Failed to begin transaction: %s", db_strerror(rc));
 
53
        return rc;
 
54
    }
 
55
#endif /* CNID_DB_CDB */
 
56
 
 
57
    /* Get the old info. */
 
58
    key.data = (cnid_t *)&id;
 
59
    key.size = sizeof(id);
 
60
    memset(&data, 0, sizeof(data));
 
61
#ifdef CNID_DB_CDB
 
62
    if ((rc = db->db_cnid->get(db->db_cnid, NULL, &key, &data, 0))) {
 
63
#else  /* CNID_DB_CDB */
 
64
    if ((rc = db->db_cnid->get(db->db_cnid, tid, &key, &data, DB_RMW))) {
 
65
        txn_abort(tid);
 
66
#endif /* CNID_DB_CDB */
 
67
        switch (rc) {
 
68
#ifndef CNID_DB_CDB
 
69
        case DB_LOCK_DEADLOCK:
 
70
            goto retry;
 
71
#endif /* CNID_DB_CDB */
 
72
        case DB_NOTFOUND:
 
73
            /* Silently fail here.  We're allowed to do this since this CNID
 
74
             * might have been deleted out from under us, or someone has
 
75
             * called cnid_lookup then cnid_update (which is redundant). */
 
76
            return 0;
 
77
        default:
 
78
            goto update_err;
 
79
        }
 
80
    }
 
81
 
 
82
    /* Delete the old dev/ino mapping. */
 
83
    key.data = data.data;
 
84
    key.size = CNID_DEVINO_LEN;
 
85
    if ((rc = db->db_devino->del(db->db_devino, tid, &key, 0))) {
 
86
        switch (rc) {
 
87
#ifndef CNID_DB_CDB
 
88
        case DB_LOCK_DEADLOCK:
 
89
            txn_abort(tid);
 
90
            goto retry;
 
91
#endif /* CNID_DB_CDB */
 
92
        case DB_NOTFOUND:
 
93
            break;
 
94
        default:
 
95
#ifndef CNID_DB_CDB
 
96
            txn_abort(tid);
 
97
#endif /* CNID_DB_CDB */
 
98
            goto update_err;
 
99
        }
 
100
    }
 
101
 
 
102
    /* Delete the old did/name mapping. */
 
103
    key.data = (char *) data.data + CNID_DEVINO_LEN;
 
104
    key.size = data.size - CNID_DEVINO_LEN;
 
105
    if ((rc = db->db_didname->del(db->db_didname, tid, &key, 0))) {
 
106
        switch (rc) {
 
107
#ifndef CNID_DB_CDB
 
108
        case DB_LOCK_DEADLOCK:
 
109
            txn_abort(tid);
 
110
            goto retry;
 
111
#endif /* CNID_DB_CDB */
 
112
        case DB_NOTFOUND:
 
113
            break;
 
114
        default:
 
115
#ifndef CNID_DB_CDB
 
116
            txn_abort(tid);
 
117
#endif /* CNID_DB_CDB */
 
118
            goto update_err;
 
119
        }
 
120
    }
 
121
 
 
122
    /* Make a new entry. */
 
123
    data.data = make_cnid_data(st, did, name, len);
 
124
    data.size = CNID_HEADER_LEN + len + 1;
 
125
 
 
126
    /* Update the old CNID with the new info. */
 
127
    key.data = (cnid_t *) &id;
 
128
    key.size = sizeof(id);
 
129
    if ((rc = db->db_cnid->put(db->db_cnid, tid, &key, &data, 0))) {
 
130
#ifndef CNID_DB_CDB
 
131
        txn_abort(tid);
 
132
#endif /* CNID_DB_CDB */
 
133
        switch (rc) {
 
134
#ifndef CNID_DB_CDB
 
135
        case DB_LOCK_DEADLOCK:
 
136
            goto retry;
 
137
#endif /* CNID_DB_CDB */
 
138
        default:
 
139
            goto update_err;
 
140
        }
 
141
    }
 
142
 
 
143
    /* Put in a new dev/ino mapping. */
 
144
    key.data = data.data;
 
145
    key.size = CNID_DEVINO_LEN;
 
146
    altdata.data = (cnid_t *) &id;
 
147
    altdata.size = sizeof(id);
 
148
    if ((rc = db->db_devino->put(db->db_devino, tid, &key, &altdata, 0))) {
 
149
#ifndef CNID_DB_CDB
 
150
        txn_abort(tid);
 
151
#endif /* CNID_DB_CDB */
 
152
        switch (rc) {
 
153
#ifndef CNID_DB_CDB
 
154
        case DB_LOCK_DEADLOCK:
 
155
            goto retry;
 
156
#endif /* CNID_DB_CDB */
 
157
        default:
 
158
            goto update_err;
 
159
        }
 
160
    }
 
161
 
 
162
    /* put in a new did/name mapping. */
 
163
    key.data = (char *) data.data + CNID_DEVINO_LEN;
 
164
    key.size = data.size - CNID_DEVINO_LEN;
 
165
    if ((rc = db->db_didname->put(db->db_didname, tid, &key, &altdata, 0))) {
 
166
#ifndef CNID_DB_CDB
 
167
        txn_abort(tid);
 
168
#endif /* CNID_DB_CDB */
 
169
        switch (rc) {
 
170
#ifndef CNID_DB_CDB
 
171
        case DB_LOCK_DEADLOCK:
 
172
            goto retry;
 
173
#endif /* CNID_DB_CDB */
 
174
        default:
 
175
            goto update_err;
 
176
        }
 
177
    }
 
178
 
 
179
 
 
180
#ifdef CNID_DB_CDB
 
181
    return 0;
 
182
#else  /* CNID_DB_CDB */
 
183
    return txn_commit(tid, 0);
 
184
#endif /* CNID_DB_CDB */
 
185
 
 
186
update_err:
 
187
    LOG(log_error, logtype_default, "cnid_update: Unable to update CNID %u: %s",
 
188
        ntohl(id), db_strerror(rc));
 
189
    return -1;
 
190
}
 
191
#endif /* CNID_DB */