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