]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/last/cnid_last.c
Support for using $u username variable in AFP volume definitions
[netatalk.git] / libatalk / cnid / last / cnid_last.c
1
2 /*
3  *
4  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
5  * All Rights Reserved. See COPYRIGHT.
6  *
7  */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif /* HAVE_CONFIG_H */
12
13 #ifdef CNID_BACKEND_LAST
14 #include <stdlib.h>
15 #include "cnid_last.h"
16 #include <atalk/util.h>
17 #include <atalk/logger.h>
18
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include <arpa/inet.h>
23
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_)
27 {
28
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. */
31
32     /*
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.
41      *
42      * AFS already does something very similar to this for the
43      * inode number, so we don't repeat the procedure.
44      *
45      * new algorithm:
46      * due to complaints over did's being non-persistent,
47      * here's the current hack to provide semi-persistent
48      * did's:
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.
52      *
53      * both the inode and device information are actually hashes
54      * that are then truncated to the requisite bit length.
55      *
56      * it should be okay to use lstat to deal with symlinks.
57      */
58
59     struct _cnid_last_private *priv;
60
61     if (!cdb || !(cdb->cnid_db_private))
62         return CNID_INVALID;
63
64     priv = (struct _cnid_last_private *) (cdb->cnid_db_private);
65
66     if (S_ISDIR(st->st_mode))
67         return htonl(priv->last_did++);
68     else
69         return htonl((st->st_dev << 16) | (st->st_ino & 0x0000ffff));
70 }
71
72
73
74 void cnid_last_close(struct _cnid_db *cdb)
75 {
76     free(cdb->cnid_db_private);
77     free(cdb);
78 }
79
80
81
82 int cnid_last_delete(struct _cnid_db *cdb _U_, const cnid_t id _U_)
83 {
84     return CNID_INVALID;
85 }
86
87
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_)
90 {
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. */
93     return CNID_INVALID;
94 }
95
96
97 /* */
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_)
100 {
101     /* FIXME: this function doesn't work in [last] scheme ! */
102     /* Should be never called or CNID should be somewhat refactored again. */
103     return CNID_INVALID;
104 }
105
106
107 static struct _cnid_db *cnid_last_new(struct vol *vol)
108 {
109     struct _cnid_db *cdb;
110     struct _cnid_last_private *priv;
111
112     if ((cdb = (struct _cnid_db *) calloc(1, sizeof(struct _cnid_db))) == NULL)
113         return NULL;
114
115     if ((cdb->cnid_db_private = calloc(1, sizeof(struct _cnid_last_private))) == NULL) {
116         free(cdb);
117         return NULL;
118     }
119
120     /* Set up private state */
121     priv = (struct _cnid_last_private *) (cdb->cnid_db_private);
122     priv->last_did = 17;
123
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;
135
136     return cdb;
137 }
138
139 struct _cnid_db *cnid_last_open(struct cnid_open_args *args)
140 {
141     struct _cnid_db *cdb;
142
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");
145         return NULL;
146     }
147
148     return cdb;
149 }
150
151 struct _cnid_module cnid_last_module = {
152     "last",
153     {NULL, NULL},
154     cnid_last_open,
155     0
156 };
157
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_)
160 {
161     /* FIXME: frankly, it does not work. As get, add and other functions. */
162     return NULL;
163 }
164
165
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_)
168 {
169     return 0;
170 }
171
172
173 #endif /* CNID_BACKEND_LAST */