2 * $Id: cnid_tdb_open.c,v 1.4 2009-11-20 17:37:14 didg Exp $
4 * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
5 * All Rights Reserved. See COPYRIGHT.
12 #ifdef CNID_BACKEND_TDB
13 #include <sys/param.h>
16 #include <atalk/logger.h>
18 #define DBHOME ".AppleDB"
19 #define DBNAME "private_tdb.%sX"
20 #define DBHOMELEN 9 /* strlen(DBHOME) +1 for / */
22 #define DBCNID "cnid.tdb"
23 #define DBDEVINO "devino.tdb"
24 #define DBDIDNAME "didname.tdb" /* did/full name mapping */
26 #define DBVERSION_KEY "\0\0\0\0Version"
27 #define DBVERSION_KEYLEN (sizeof(DBVERSION_KEY))
28 #define DBVERSION1 0x00000001U
29 #define DBVERSION DBVERSION1
31 static struct _cnid_db *cnid_tdb_new(const char *volpath)
34 struct _cnid_tdb_private *priv;
36 if ((cdb = (struct _cnid_db *) calloc(1, sizeof(struct _cnid_db))) == NULL)
39 if ((cdb->volpath = strdup(volpath)) == NULL) {
44 if ((cdb->_private = calloc(1, sizeof(struct _cnid_tdb_private))) == NULL) {
50 /* Set up private state */
51 priv = (struct _cnid_tdb_private *) (cdb->_private);
53 /* Set up standard fields */
54 cdb->flags = CNID_FLAG_PERSISTENT;
56 cdb->cnid_add = cnid_tdb_add;
57 cdb->cnid_delete = cnid_tdb_delete;
58 cdb->cnid_get = cnid_tdb_get;
59 cdb->cnid_lookup = cnid_tdb_lookup;
60 cdb->cnid_nextid = NULL; /*cnid_tdb_nextid;*/
61 cdb->cnid_resolve = cnid_tdb_resolve;
62 cdb->cnid_update = cnid_tdb_update;
63 cdb->cnid_close = cnid_tdb_close;
68 /* ---------------------------- */
69 struct _cnid_db *cnid_tdb_open(const char *dir, mode_t mask)
73 struct _cnid_tdb_private *db;
75 char path[MAXPATHLEN + 1];
82 if ((len = strlen(dir)) > (MAXPATHLEN - DBLEN - 1)) {
83 LOG(log_error, logtype_default, "tdb_open: Pathname too large: %s", dir);
87 if ((cdb = cnid_tdb_new(dir)) == NULL) {
88 LOG(log_error, logtype_default, "tdb_open: Unable to allocate memory for tdb");
92 if (path[len - 1] != '/') {
97 strcpy(path + len, DBHOME);
98 if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777 & ~mask) < 0)) {
99 LOG(log_error, logtype_default, "tdb_open: DBHOME mkdir failed for %s", path);
104 db = (struct _cnid_tdb_private *)cdb->_private;
106 path[len + DBHOMELEN] = '\0';
107 strcat(path, DBCNID);
108 db->tdb_cnid = tdb_open(path, 0, 0 , O_RDWR | O_CREAT, 0666 & ~mask);
110 LOG(log_error, logtype_default, "tdb_open: unable to open tdb", path);
115 path[len + DBHOMELEN] = '\0';
116 strcat(path, DBDIDNAME);
117 db->tdb_didname = tdb_open(path, 0, 0 , O_RDWR | O_CREAT, 0666 & ~mask);
119 LOG(log_error, logtype_default, "tdb_open: unable to open tdb", path);
122 /* Check for version. This way we can update the database if we need
123 * to change the format in any way. */
124 memset(&key, 0, sizeof(key));
125 memset(&data, 0, sizeof(data));
126 key.dptr = DBVERSION_KEY;
127 key.dsize = DBVERSION_KEYLEN;
129 data = tdb_fetch(db->tdb_didname, key);
131 u_int32_t version = htonl(DBVERSION);
133 data.dptr = (char *)&version;
134 data.dsize = sizeof(version);
135 if (tdb_store(db->tdb_didname, key, data, TDB_REPLACE)) {
136 LOG(log_error, logtype_default, "tdb_open: Error putting new version");
145 path[len + DBHOMELEN] = '\0';
146 strcat(path, DBDEVINO);
147 db->tdb_devino = tdb_open(path, 0, 0 , O_RDWR | O_CREAT, 0666 & ~mask);
148 if (!db->tdb_devino) {
149 LOG(log_error, logtype_default, "tdb_open: unable to open tdb", path);
163 struct _cnid_module cnid_tdb_module = {
167 CNID_FLAG_SETUID | CNID_FLAG_BLOCK