]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/last/cnid_last.c
Fix typo
[netatalk.git] / libatalk / cnid / last / cnid_last.c
1
2 /*
3  * $Id: cnid_last.c,v 1.5 2010-03-31 09:47:32 franklahm Exp $
4  *
5  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
6  * All Rights Reserved. See COPYRIGHT.
7  *
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif /* HAVE_CONFIG_H */
13
14 #ifdef CNID_BACKEND_LAST
15 #include <stdlib.h>
16 #include "cnid_last.h"
17 #include <atalk/util.h>
18 #include <atalk/logger.h>
19
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include <arpa/inet.h>
24
25 /* ------------------------ */
26 cnid_t cnid_last_add(struct _cnid_db *cdb, const struct stat *st,
27                      cnid_t did _U_, const char *name _U_, size_t len _U_, cnid_t hint _U_)
28 {
29
30     /* FIXME: it relies on fact, that this is never called twice for the same file/dir. */
31     /* Propably we should look through DID tree. */
32
33     /*
34      * First thing:  DID and FNUMs are
35      * in the same space for purposes of enumerate (and several
36      * other wierd places).  While we consider this Apple's bug,
37      * this is the work-around:  In order to maintain constant and
38      * unique DIDs and FNUMs, we monotonically generate the DIDs
39      * during the session, and derive the FNUMs from the filesystem.
40      * Since the DIDs are small, we insure that the FNUMs are fairly
41      * large by setting thier high bits to the device number.
42      *
43      * AFS already does something very similar to this for the
44      * inode number, so we don't repeat the procedure.
45      *
46      * new algorithm:
47      * due to complaints over did's being non-persistent,
48      * here's the current hack to provide semi-persistent
49      * did's:
50      *      1) we reserve the first bit for file ids.
51      *      2) the next 7 bits are for the device.
52      *      3) the remaining 24 bits are for the inode.
53      *
54      * both the inode and device information are actually hashes
55      * that are then truncated to the requisite bit length.
56      *
57      * it should be okay to use lstat to deal with symlinks.
58      */
59
60     struct _cnid_last_private *priv;
61
62     if (!cdb || !(cdb->_private))
63         return CNID_INVALID;
64
65     priv = (struct _cnid_last_private *) (cdb->_private);
66
67     if (S_ISDIR(st->st_mode))
68         return htonl(priv->last_did++);
69     else
70         return htonl((st->st_dev << 16) | (st->st_ino & 0x0000ffff));
71 }
72
73
74
75 void cnid_last_close(struct _cnid_db *cdb)
76 {
77     free(cdb->volpath);
78     free(cdb->_private);
79     free(cdb);
80 }
81
82
83
84 int cnid_last_delete(struct _cnid_db *cdb _U_, const cnid_t id _U_)
85 {
86     return CNID_INVALID;
87 }
88
89
90 /* Return CNID for a given did/name. */
91 cnid_t cnid_last_get(struct _cnid_db *cdb _U_, cnid_t did _U_, const char *name _U_, size_t len _U_)
92 {
93     /* FIXME: it relies on fact, that this is never called twice for the same file/dir. */
94     /* Propably we should look through DID tree. */
95     return CNID_INVALID;
96 }
97
98
99 /* */
100 cnid_t cnid_last_lookup(struct _cnid_db *cdb _U_, const struct stat *st _U_, cnid_t did _U_, 
101                         const char *name _U_, size_t len _U_)
102 {
103     /* FIXME: this function doesn't work in [last] scheme ! */
104     /* Should be never called or CNID should be somewhat refactored again. */
105     return CNID_INVALID;
106 }
107
108
109 static struct _cnid_db *cnid_last_new(const char *volpath)
110 {
111     struct _cnid_db *cdb;
112     struct _cnid_last_private *priv;
113
114     if ((cdb = (struct _cnid_db *) calloc(1, sizeof(struct _cnid_db))) == NULL)
115         return NULL;
116
117     if ((cdb->volpath = strdup(volpath)) == NULL) {
118         free(cdb);
119         return NULL;
120     }
121
122     if ((cdb->_private = calloc(1, sizeof(struct _cnid_last_private))) == NULL) {
123         free(cdb->volpath);
124         free(cdb);
125         return NULL;
126     }
127
128     /* Set up private state */
129     priv = (struct _cnid_last_private *) (cdb->_private);
130     priv->last_did = 17;
131
132     /* Set up standard fields */
133     cdb->flags = 0;
134     cdb->cnid_add = cnid_last_add;
135     cdb->cnid_delete = cnid_last_delete;
136     cdb->cnid_get = cnid_last_get;
137     cdb->cnid_lookup = cnid_last_lookup;
138     cdb->cnid_nextid = NULL;    /* cnid_last_nextid; */
139     cdb->cnid_resolve = cnid_last_resolve;
140     cdb->cnid_update = cnid_last_update;
141     cdb->cnid_close = cnid_last_close;
142     
143     return cdb;
144 }
145
146 struct _cnid_db *cnid_last_open(struct cnid_open_args *args)
147 {
148     struct _cnid_db *cdb;
149
150     if (!args->dir) {
151         return NULL;
152     }
153
154     if ((cdb = cnid_last_new(args->dir)) == NULL) {
155         LOG(log_error, logtype_default, "cnid_open: Unable to allocate memory for database");
156         return NULL;
157     }
158
159     return cdb;
160 }
161
162 struct _cnid_module cnid_last_module = {
163     "last",
164     {NULL, NULL},
165     cnid_last_open,
166     0
167 };
168
169 /* Return the did/name pair corresponding to a CNID. */
170 char *cnid_last_resolve(struct _cnid_db *cdb _U_, cnid_t * id _U_, void *buffer _U_, size_t len _U_)
171 {
172     /* FIXME: frankly, it does not work. As get, add and other functions. */
173     return NULL;
174 }
175
176
177 int cnid_last_update(struct _cnid_db *cdb _U_, cnid_t id _U_, const struct stat *st _U_,
178                      cnid_t did  _U_, const char *name  _U_, size_t len _U_)
179 {
180     return 0;
181 }
182
183
184 #endif /* CNID_BACKEND_LAST */