4 * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
5 * All Rights Reserved. See COPYRIGHT.
11 #endif /* HAVE_CONFIG_H */
13 #ifdef CNID_BACKEND_LAST
15 #include "cnid_last.h"
16 #include <atalk/util.h>
17 #include <atalk/logger.h>
19 #include <sys/types.h>
22 #include <arpa/inet.h>
24 /* ------------------------ */
25 cnid_t cnid_last_add(struct _cnid_db *cdb, const struct stat *st,
26 cnid_t did _U_, const char *name _U_, size_t len _U_, cnid_t hint _U_)
29 /* FIXME: it relies on fact, that this is never called twice for the same file/dir. */
30 /* Propably we should look through DID tree. */
33 * First thing: DID and FNUMs are
34 * in the same space for purposes of enumerate (and several
35 * other wierd places). While we consider this Apple's bug,
36 * this is the work-around: In order to maintain constant and
37 * unique DIDs and FNUMs, we monotonically generate the DIDs
38 * during the session, and derive the FNUMs from the filesystem.
39 * Since the DIDs are small, we insure that the FNUMs are fairly
40 * large by setting thier high bits to the device number.
42 * AFS already does something very similar to this for the
43 * inode number, so we don't repeat the procedure.
46 * due to complaints over did's being non-persistent,
47 * here's the current hack to provide semi-persistent
49 * 1) we reserve the first bit for file ids.
50 * 2) the next 7 bits are for the device.
51 * 3) the remaining 24 bits are for the inode.
53 * both the inode and device information are actually hashes
54 * that are then truncated to the requisite bit length.
56 * it should be okay to use lstat to deal with symlinks.
59 struct _cnid_last_private *priv;
61 if (!cdb || !(cdb->cnid_db_private))
64 priv = (struct _cnid_last_private *) (cdb->cnid_db_private);
66 if (S_ISDIR(st->st_mode))
67 return htonl(priv->last_did++);
69 return htonl((st->st_dev << 16) | (st->st_ino & 0x0000ffff));
74 void cnid_last_close(struct _cnid_db *cdb)
76 free(cdb->cnid_db_private);
82 int cnid_last_delete(struct _cnid_db *cdb _U_, const cnid_t id _U_)
88 /* Return CNID for a given did/name. */
89 cnid_t cnid_last_get(struct _cnid_db *cdb _U_, cnid_t did _U_, const char *name _U_, size_t len _U_)
91 /* FIXME: it relies on fact, that this is never called twice for the same file/dir. */
92 /* Propably we should look through DID tree. */
98 cnid_t cnid_last_lookup(struct _cnid_db *cdb _U_, const struct stat *st _U_, cnid_t did _U_,
99 const char *name _U_, size_t len _U_)
101 /* FIXME: this function doesn't work in [last] scheme ! */
102 /* Should be never called or CNID should be somewhat refactored again. */
107 static struct _cnid_db *cnid_last_new(struct vol *vol)
109 struct _cnid_db *cdb;
110 struct _cnid_last_private *priv;
112 if ((cdb = (struct _cnid_db *) calloc(1, sizeof(struct _cnid_db))) == NULL)
115 if ((cdb->cnid_db_private = calloc(1, sizeof(struct _cnid_last_private))) == NULL) {
120 /* Set up private state */
121 priv = (struct _cnid_last_private *) (cdb->cnid_db_private);
124 /* Set up standard fields */
125 cdb->cnid_db_flags = 0;
126 cdb->cnid_add = cnid_last_add;
127 cdb->cnid_delete = cnid_last_delete;
128 cdb->cnid_get = cnid_last_get;
129 cdb->cnid_lookup = cnid_last_lookup;
130 cdb->cnid_nextid = NULL; /* cnid_last_nextid; */
131 cdb->cnid_resolve = cnid_last_resolve;
132 cdb->cnid_update = cnid_last_update;
133 cdb->cnid_close = cnid_last_close;
134 cdb->cnid_wipe = NULL;
139 struct _cnid_db *cnid_last_open(struct cnid_open_args *args)
141 struct _cnid_db *cdb;
143 if ((cdb = cnid_last_new(args->cnid_args_vol)) == NULL) {
144 LOG(log_error, logtype_default, "cnid_open: Unable to allocate memory for database");
151 struct _cnid_module cnid_last_module = {
158 /* Return the did/name pair corresponding to a CNID. */
159 char *cnid_last_resolve(struct _cnid_db *cdb _U_, cnid_t * id _U_, void *buffer _U_, size_t len _U_)
161 /* FIXME: frankly, it does not work. As get, add and other functions. */
166 int cnid_last_update(struct _cnid_db *cdb _U_, cnid_t id _U_, const struct stat *st _U_,
167 cnid_t did _U_, const char *name _U_, size_t len _U_)
173 #endif /* CNID_BACKEND_LAST */