• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/netatalk-3.0.5/libatalk/cnid/tdb/
1/*
2 * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
3 * All Rights Reserved. See COPYRIGHT.
4 *
5 */
6#ifdef HAVE_CONFIG_H
7#include "config.h"
8#endif
9
10#ifdef CNID_BACKEND_TDB
11#include <sys/param.h>
12
13#include "cnid_tdb.h"
14#include <atalk/logger.h>
15#include <stdlib.h>
16#define DBHOME       ".AppleDB"
17#define DBHOMELEN    9                  /* strlen(DBHOME) +1 for / */
18#define DBLEN        12
19#define DBCNID       "cnid2.tdb"
20
21#define DBVERSION_KEY    "\0\0\0\0Version"
22#define DBVERSION_KEYLEN (sizeof(DBVERSION_KEY))
23#define DBVERSION2       0x00000002U
24#define DBVERSION        DBVERSION2
25
26static struct _cnid_db *cnid_tdb_new(const char *volpath)
27{
28    struct _cnid_db *cdb;
29    struct _cnid_tdb_private *priv;
30
31    if ((cdb = (struct _cnid_db *) calloc(1, sizeof(struct _cnid_db))) == NULL)
32        return NULL;
33
34    if ((cdb->volpath = strdup(volpath)) == NULL) {
35        free(cdb);
36        return NULL;
37    }
38
39    if ((cdb->_private = calloc(1, sizeof(struct _cnid_tdb_private))) == NULL) {
40        free(cdb->volpath);
41        free(cdb);
42        return NULL;
43    }
44
45    /* Set up private state */
46    priv = (struct _cnid_tdb_private *) (cdb->_private);
47
48    /* Set up standard fields */
49    cdb->flags = CNID_FLAG_PERSISTENT;
50
51    cdb->cnid_add = cnid_tdb_add;
52    cdb->cnid_delete = cnid_tdb_delete;
53    cdb->cnid_get = cnid_tdb_get;
54    cdb->cnid_lookup = cnid_tdb_lookup;
55    cdb->cnid_nextid = NULL;    /*cnid_tdb_nextid;*/
56    cdb->cnid_resolve = cnid_tdb_resolve;
57    cdb->cnid_update = cnid_tdb_update;
58    cdb->cnid_close = cnid_tdb_close;
59    cdb->cnid_wipe = NULL;
60
61    return cdb;
62}
63
64/* ---------------------------- */
65struct _cnid_db *cnid_tdb_open(struct cnid_open_args *args)
66{
67    struct stat               st;
68    struct _cnid_db           *cdb;
69    struct _cnid_tdb_private *db;
70    size_t                    len;
71    char                      path[MAXPATHLEN + 1];
72    TDB_DATA                  key, data;
73    int 		      hash_size = 131071;
74    int                       tdb_flags = 0;
75
76    if (!args->dir) {
77        /* note: dir and path are not used for in memory db */
78        return NULL;
79    }
80
81    if ((len = strlen(args->dir)) > (MAXPATHLEN - DBLEN - 1)) {
82        LOG(log_error, logtype_default, "tdb_open: Pathname too large: %s", args->dir);
83        return NULL;
84    }
85
86    if ((cdb = cnid_tdb_new(args->dir)) == NULL) {
87        LOG(log_error, logtype_default, "tdb_open: Unable to allocate memory for tdb");
88        return NULL;
89    }
90
91    strcpy(path, args->dir);
92    if (path[len - 1] != '/') {
93        strcat(path, "/");
94        len++;
95    }
96
97    strcpy(path + len, DBHOME);
98    if (!(args->flags & CNID_FLAG_MEMORY)) {
99        if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777 & ~args->mask) < 0)) {
100            LOG(log_error, logtype_default, "tdb_open: DBHOME mkdir failed for %s", path);
101            goto fail;
102        }
103    }
104    else {
105        hash_size = 0;
106        tdb_flags = TDB_INTERNAL;
107    }
108    strcat(path, "/");
109
110    db = (struct _cnid_tdb_private *)cdb->_private;
111
112    path[len + DBHOMELEN] = '\0';
113    strcat(path, DBCNID);
114
115    db->tdb_cnid = tdb_open(path, hash_size, tdb_flags , O_RDWR | O_CREAT, 0666 & ~args->mask);
116    if (!db->tdb_cnid) {
117        LOG(log_error, logtype_default, "tdb_open: unable to open tdb", path);
118        goto fail;
119    }
120    /* ------------- */
121    db->tdb_didname = db->tdb_cnid;
122    db->tdb_devino = db->tdb_cnid;
123
124    /* Check for version.  This way we can update the database if we need
125     * to change the format in any way. */
126    memset(&key, 0, sizeof(key));
127    memset(&data, 0, sizeof(data));
128    key.dptr = (unsigned char *)DBVERSION_KEY;
129    key.dsize = DBVERSION_KEYLEN;
130
131    data = tdb_fetch(db->tdb_didname, key);
132    if (!data.dptr) {
133        uint32_t version = htonl(DBVERSION);
134
135        data.dptr = (unsigned char *)&version;
136        data.dsize = sizeof(version);
137        if (tdb_store(db->tdb_didname, key, data, TDB_REPLACE)) {
138            LOG(log_error, logtype_default, "tdb_open: Error putting new version");
139            goto fail;
140        }
141    }
142    else {
143        free(data.dptr);
144    }
145
146    return cdb;
147
148fail:
149    free(cdb->_private);
150    free(cdb->volpath);
151    free(cdb);
152
153    return NULL;
154}
155
156struct _cnid_module cnid_tdb_module = {
157    "tdb",
158    {NULL, NULL},
159    cnid_tdb_open,
160    CNID_FLAG_SETUID | CNID_FLAG_BLOCK
161};
162
163
164#endif
165