]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/hash/cnid_hash_open.c
- merge branch-netatalk-afp-3x-dev, HEAD was tagged before
[netatalk.git] / libatalk / cnid / hash / cnid_hash_open.c
1 /*
2  * $Id: cnid_hash_open.c,v 1.2 2005-04-28 20:50:01 bfernhomberg 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_HASH
13 #include <sys/param.h>   
14
15 #include "cnid_hash.h"
16 #include <atalk/logger.h>
17 #include <stdlib.h>
18 #define DBHOME       ".AppleDB" 
19 #define DBNAME       "private_tdb.%sX"
20 #define DBHOMELEN    9
21 #define DBLEN        24 
22
23 static struct _cnid_db *cnid_hash_new(const char *volpath)
24 {
25     struct _cnid_db *cdb;
26     struct _cnid_hash_private *priv;
27
28     if ((cdb = (struct _cnid_db *) calloc(1, sizeof(struct _cnid_db))) == NULL)
29         return NULL;
30
31     if ((cdb->volpath = strdup(volpath)) == NULL) {
32         free(cdb);
33         return NULL;
34     }
35
36     if ((cdb->_private = calloc(1, sizeof(struct _cnid_hash_private))) == NULL) {
37         free(cdb->volpath);
38         free(cdb);
39         return NULL;
40     }
41
42     /* Set up private state */
43     priv = (struct _cnid_hash_private *) (cdb->_private);
44
45     /* Set up standard fields */
46     cdb->flags = CNID_FLAG_PERSISTENT;
47
48     cdb->cnid_add = cnid_hash_add;
49     cdb->cnid_delete = cnid_hash_delete;
50     cdb->cnid_get = cnid_hash_get;
51     cdb->cnid_lookup = cnid_hash_lookup;
52     cdb->cnid_nextid = NULL;    /*cnid_hash_nextid;*/
53     cdb->cnid_resolve = cnid_hash_resolve;
54     cdb->cnid_update = cnid_hash_update;
55     cdb->cnid_close = cnid_hash_close;
56     
57     return cdb;
58 }
59
60 /* ---------------------------- */
61 struct _cnid_db *cnid_hash_open(const char *dir, mode_t mask)
62 {
63     struct stat               st;
64     struct _cnid_db           *cdb;
65     struct _cnid_hash_private *db;
66     size_t                    len;
67     char                      path[MAXPATHLEN + 1];
68     
69     if (!dir) {
70         return NULL;
71     }
72
73     if ((len = strlen(dir)) > (MAXPATHLEN - DBLEN - 1)) {
74         LOG(log_error, logtype_default, "cnid_open: Pathname too large: %s", dir);
75         return NULL;
76     }
77     
78     if ((cdb = cnid_hash_new(dir)) == NULL) {
79         LOG(log_error, logtype_default, "cnid_open: Unable to allocate memory for hash");
80         return NULL;
81     }
82     strcpy(path, dir);
83     if (path[len - 1] != '/') {
84         strcat(path, "/");
85         len++;
86     }
87  
88     strcpy(path + len, DBHOME);
89     if ((stat(path, &st) < 0) && (ad_mkdir(path, 0777 & ~mask) < 0)) {
90         LOG(log_error, logtype_default, "cnid_open: DBHOME mkdir failed for %s", path);
91         goto fail;
92     }
93     strcat(path, "/");
94  
95     path[len + DBHOMELEN] = '\0';
96     strcat(path, DBNAME);
97     db = (struct _cnid_hash_private *)cdb->_private;
98     db->tdb = tdb_open(path, 0, TDB_CLEAR_IF_FIRST | TDB_INTERNAL, O_RDWR | O_CREAT | O_TRUNC, 0600);
99     if (!db->tdb) {
100         LOG(log_error, logtype_default, "cnid_open: unable to open tdb", path);
101         goto fail;
102     }
103
104     return cdb;
105
106 fail:
107     free(cdb->_private);
108     free(cdb->volpath);
109     free(cdb);
110     
111     return NULL;
112 }
113
114 struct _cnid_module cnid_hash_module = {
115     "hash",
116     {NULL, NULL},
117     cnid_hash_open,
118 };
119
120
121 #endif /* CNID_BACKEND_HASH */