]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/cdb/cnid_cdb_private.h
Tru64 Changes, from Burkhard Schmidt.
[netatalk.git] / libatalk / cnid / cdb / cnid_cdb_private.h
1 /*
2  * $Id: cnid_cdb_private.h,v 1.1.4.6 2004-02-07 19:46:09 didg Exp $
3  */
4
5 #ifndef LIBATALK_CDB_PRIVATE_H
6 #define LIBATALK_CDB_PRIVATE_H 1
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif /* HAVE_CONFIG_H */
11
12 #include <netatalk/endian.h>
13
14 #ifdef HAVE_UNISTD_H
15 #include <unistd.h>
16 #endif /* HAVE_UNISTD_H */
17 #include <stdlib.h>
18 #include <string.h>
19 #include <errno.h>
20 #ifdef HAVE_FCNTL_H
21 #include <fcntl.h>
22 #endif /* HAVE_FCNTL_H */
23 #include <sys/param.h>
24 #include <sys/stat.h>
25 #ifdef HAVE_SYS_TIME_H
26 #include <sys/time.h>
27 #endif /* HAVE_SYS_TIME_H */
28 #include <sys/cdefs.h>
29 #include <db.h>
30
31 #include <atalk/logger.h>
32 #include <atalk/adouble.h>
33 #include <atalk/cnid.h>
34 #include <atalk/util.h>
35 #include "cnid_cdb.h"
36
37 #define CNID_DB_MAGIC   0x434E4944U  /* CNID */
38 #define CNID_DATA_MAGIC 0x434E4945U  /* CNIE */
39
40 /* record structure 
41    cnid                4
42    dev                 8
43    inode               8
44    type/last cnid      4 Not used    
45    did                 4
46    name                strlen(name) +1
47
48 primary key 
49 cnid
50 secondary keys
51 dev/inode
52 did/name   
53
54 */
55
56 typedef struct cnid_record { /* helper for debug don't use */
57   unsigned int  cnid;
58   dev_t    dev;
59   ino_t    inode;
60   unsigned int  type;
61   unsigned int  did;
62   char          name[50];
63 } cnid_record;
64
65 #define CNID_OFS                 0
66 #define CNID_LEN                 4
67
68 #define CNID_DEV_OFS             CNID_LEN
69 #define CNID_DEV_LEN             8
70
71 #define CNID_INO_OFS             (CNID_DEV_OFS + CNID_DEV_LEN)
72 #define CNID_INO_LEN             8
73
74 #define CNID_DEVINO_OFS          CNID_LEN
75 #define CNID_DEVINO_LEN          (CNID_DEV_LEN +CNID_INO_LEN)
76
77 #define CNID_TYPE_OFS            (CNID_DEVINO_OFS +CNID_DEVINO_LEN)
78 #define CNID_TYPE_LEN            4
79
80 #define CNID_DID_OFS             (CNID_TYPE_OFS +CNID_TYPE_LEN)
81 #define CNID_DID_LEN             CNID_LEN
82
83 #define CNID_NAME_OFS            (CNID_DID_OFS + CNID_DID_LEN)
84 #define CNID_HEADER_LEN          (CNID_NAME_OFS)
85
86 #define CNID_START               17
87
88 #define CNIDFLAG_ROOTINFO_RO     (1 << 0)
89 #define CNIDFLAG_DB_RO           (1 << 1)
90
91 /* the key is cnid 0 
92  * we use 0/RootInfo. */
93 #define ROOTINFO_KEY    "\0\0\0\0"
94 #define ROOTINFO_KEYLEN 4
95
96 /*                         cnid   - dev        - inode     - type  - did  - name */
97 #define ROOTINFO_DATA    "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0RootInfo"
98 #define ROOTINFO_DATALEN (3*4 +2*8  +9)
99
100
101 typedef struct CNID_private {
102     u_int32_t magic;
103     DB *db_cnid;
104     DB *db_didname;
105     DB *db_devino;
106     DB_ENV *dbenv;
107     int lockfd, flags;
108     char lock_file[MAXPATHLEN + 1];
109 } CNID_private;
110
111 /* on-disk data format (in network byte order where appropriate) --
112  * db_cnid:      (key: cnid)
113  * name          size (in bytes)
114  * dev           4
115  * ino           4
116  * did           4
117  * unix name     strlen(name) + 1 
118  *
119  * db_didname:   (key: did/unix name)
120  * -- this also caches the bits of .AppleDouble used by FPGetFilDirParam
121  *    so that we don't have to open the header file.
122  *    NOTE: FPCatSearch has to search through all of the directories as
123  *          this stuff doesn't get entered until needed.
124  *          if the entire volume is in the database, though, we can use
125  *          cursor operations to make this faster.
126  *
127  *    version number is stored with did/name key of 0/0
128  *
129  * cnid          4
130  * modfiller     4 (dates only use 4 bytes right now, but we leave space 
131  * moddate       4  for 8. moddate is also used to keep this info 
132  * createfiller  4  up-to-date.)
133  * createdate    4
134  * backfiller    4
135  * backupdate    4
136  * accfiller     4 (unused)
137  * accdate       4 (unused)
138  * AFP info      4 (stores a couple permission bits as well)
139  * finder info   32
140  * prodos info   8
141  * rforkfiller   4
142  * rforklen      4
143  * macname       32 (nul-terminated)
144  * shortname     12 (nul-terminated)
145  * longname      longnamelen (nul-terminated)
146  * ---------------
147  *             132 bytes + longnamelen
148  * 
149  * db_devino:    (key: dev/ino) 
150  * -- this is only used for consistency checks and isn't 1-1
151  * cnid          4 
152  *
153  * these correspond to the different path types. longname is for the
154  * 255 unicode character names (path type == ?), macname is for the
155  * 32-character names (path type == 2), and shortname is for the
156  * 8+3-character names (path type == 1).
157  *
158  * db_longname: (key: did/longname)
159  * name          namelen = strlen(name) + 1
160  *
161  * db_macname:   (key: did/macname)
162  * name          namelen = strlen(name) + 1
163  *
164  * db_shortname: (key: did/shortname)
165  * name namelen = strlen(name) + 1 
166  */
167
168 #ifndef __inline__
169 #define __inline__
170 #endif /* __inline__ */
171
172 /* construct db_cnid data. NOTE: this is not re-entrant.  */
173 #ifndef ATACC
174 static void make_devino_data(unsigned char *buf, dev_t dev, ino_t ino)
175 {
176     buf[CNID_DEV_LEN - 1] = dev; dev >>= 8;
177     buf[CNID_DEV_LEN - 2] = dev; dev >>= 8;
178     buf[CNID_DEV_LEN - 3] = dev; dev >>= 8;
179     buf[CNID_DEV_LEN - 4] = dev; dev >>= 8;
180     buf[CNID_DEV_LEN - 5] = dev; dev >>= 8;
181     buf[CNID_DEV_LEN - 6] = dev; dev >>= 8;
182     buf[CNID_DEV_LEN - 7] = dev; dev >>= 8;
183     buf[CNID_DEV_LEN - 8] = dev;
184
185     buf[CNID_DEV_LEN + CNID_INO_LEN - 1] = ino; ino >>= 8;
186     buf[CNID_DEV_LEN + CNID_INO_LEN - 2] = ino; ino >>= 8;
187     buf[CNID_DEV_LEN + CNID_INO_LEN - 3] = ino; ino >>= 8;
188     buf[CNID_DEV_LEN + CNID_INO_LEN - 4] = ino; ino >>= 8;
189     buf[CNID_DEV_LEN + CNID_INO_LEN - 5] = ino; ino >>= 8;
190     buf[CNID_DEV_LEN + CNID_INO_LEN - 6] = ino; ino >>= 8;
191     buf[CNID_DEV_LEN + CNID_INO_LEN - 7] = ino; ino >>= 8;
192     buf[CNID_DEV_LEN + CNID_INO_LEN - 8] = ino;    
193 }
194
195 static __inline__ char *make_cnid_data(const struct stat *st,
196                                        const cnid_t did,
197                                        const char *name, const int len)
198 {
199     static char start[CNID_HEADER_LEN + MAXPATHLEN + 1];
200     char *buf = start  +CNID_LEN;
201     u_int32_t i;
202
203     if (len > MAXPATHLEN)
204         return NULL;
205
206     make_devino_data(buf, st->st_dev, st->st_ino);
207     buf += CNID_DEVINO_LEN;
208
209     i = S_ISDIR(st->st_mode)?1:0;
210     i = htonl(i);
211     memcpy(buf, &i, sizeof(i));
212     buf += sizeof(i);
213     
214     /* did is already in network byte order */
215     memcpy(buf, &did, sizeof(did));
216     buf += sizeof(did);
217
218     memcpy(buf, name, len);
219     *(buf + len) = '\0';
220
221     return start;
222 }
223 #else
224 extern char *make_cnid_data __P((const struct stat *,const cnid_t ,
225                                        const char *, const int ));
226 #endif
227
228 #endif /* atalk/cnid/cnid_private.h */