]> arthur.barton.de Git - netatalk.git/blob - etc/cnid_dbd/pack.c
13b7e736b64742995b984428dcb8456d1a4ba147
[netatalk.git] / etc / cnid_dbd / pack.c
1 /*
2  * $Id: pack.c,v 1.2 2005-04-28 20:49:48 bfernhomberg Exp $
3  *
4  * Copyright (C) Joerg Lenneis 2003
5  * All Rights Reserved.  See COPYING.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif /* HAVE_CONFIG_H */
11
12 #include <netatalk/endian.h>
13
14 #include <string.h>
15 #ifdef HAVE_SYS_TYPES_H
16 #include <sys/types.h>
17 #endif /* HAVE_SYS_TYPES_H */
18 #include <sys/param.h>
19 #include <sys/cdefs.h>
20 #include <db.h>
21
22 #include <atalk/cnid_dbd_private.h>
23 #include "pack.h"
24
25 #ifdef DEBUG
26 /*
27  *  Auxiliary stuff for stringify_devino. See comments below.
28  */
29 static char hexchars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
30 #endif
31
32 /* --------------- */
33 /*
34  *  This implementation is portable, but could probably be faster by using htonl
35  *  where appropriate. Also, this again doubles code from the cdb backend.
36  */
37 static void pack_devino(unsigned char *buf, dev_t dev, ino_t ino)
38 {
39     buf[CNID_DEV_LEN - 1] = dev; dev >>= 8;
40     buf[CNID_DEV_LEN - 2] = dev; dev >>= 8;
41     buf[CNID_DEV_LEN - 3] = dev; dev >>= 8;
42     buf[CNID_DEV_LEN - 4] = dev; dev >>= 8;
43     buf[CNID_DEV_LEN - 5] = dev; dev >>= 8;
44     buf[CNID_DEV_LEN - 6] = dev; dev >>= 8;
45     buf[CNID_DEV_LEN - 7] = dev; dev >>= 8;
46     buf[CNID_DEV_LEN - 8] = dev;
47
48     buf[CNID_DEV_LEN + CNID_INO_LEN - 1] = ino; ino >>= 8;
49     buf[CNID_DEV_LEN + CNID_INO_LEN - 2] = ino; ino >>= 8;
50     buf[CNID_DEV_LEN + CNID_INO_LEN - 3] = ino; ino >>= 8;
51     buf[CNID_DEV_LEN + CNID_INO_LEN - 4] = ino; ino >>= 8;
52     buf[CNID_DEV_LEN + CNID_INO_LEN - 5] = ino; ino >>= 8;
53     buf[CNID_DEV_LEN + CNID_INO_LEN - 6] = ino; ino >>= 8;
54     buf[CNID_DEV_LEN + CNID_INO_LEN - 7] = ino; ino >>= 8;
55     buf[CNID_DEV_LEN + CNID_INO_LEN - 8] = ino;    
56 }
57
58 /* --------------- */
59 int didname(dbp, pkey, pdata, skey)
60 DB *dbp _U_;
61 const DBT *pkey _U_, *pdata;
62 DBT *skey;
63 {
64 int len;
65  
66     memset(skey, 0, sizeof(DBT));
67     skey->data = (char *)pdata->data + CNID_DID_OFS;
68     /* FIXME: At least DB 4.0.14 and 4.1.25 pass in the correct length of
69        pdata.size. strlen is therefore not needed. Also, skey should be zeroed
70        out already. */
71     len = strlen((char *)skey->data + CNID_DID_LEN);
72     skey->size = CNID_DID_LEN + len + 1;
73     return (0);
74 }
75  
76 /* --------------- */
77 int devino(dbp, pkey, pdata, skey)
78 DB *dbp _U_;
79 const DBT *pkey _U_, *pdata;
80 DBT *skey;
81 {
82     memset(skey, 0, sizeof(DBT));
83     skey->data = (char *)pdata->data + CNID_DEVINO_OFS;
84     skey->size = CNID_DEVINO_LEN;
85     return (0);
86 }
87
88 /* The equivalent to make_cnid_data in the cnid library. Non re-entrant. We
89    differ from make_cnid_data in that we never return NULL, rqst->name cannot
90    ever cause start[] to overflow because name length is checked in libatalk. */
91
92 char *pack_cnid_data(struct cnid_dbd_rqst *rqst)
93 {
94     static char start[CNID_HEADER_LEN + MAXPATHLEN + 1];
95     char *buf = start +CNID_LEN;
96     u_int32_t i;
97
98     pack_devino(buf, rqst->dev, rqst->ino);
99     buf += CNID_DEVINO_LEN;
100
101     i = htonl(rqst->type);
102     memcpy(buf, &i, sizeof(i));
103     buf += sizeof(i);
104
105     /* did is already in network byte order */
106     buf = memcpy(buf, &rqst->did, sizeof(rqst->did));
107     buf += sizeof(rqst->did);
108     buf = memcpy(buf, rqst->name, rqst->namelen);
109     *(buf + rqst->namelen) = '\0';
110
111     return start;
112 }
113
114 #ifdef DEBUG
115
116 /*
117  *  Whack 4 or 8 byte dev/ino numbers into something printable for DEBUG
118  *  logging. This function must not be used more that once per printf() style
119  *  invocation. This (or something improved) should probably migrate to
120  *  libatalk logging. Checking for printf() %ll support would be an alternative.
121  */
122
123 char *stringify_devino(dev_t dev, ino_t ino)
124 {
125     static char rbuf[CNID_DEV_LEN * 2 + 1 + CNID_INO_LEN * 2 + 1] = {0};
126     char buf[CNID_DEV_LEN + CNID_INO_LEN];
127     char *c1;
128     char *c2;
129     char *middle;
130     char *end;
131     int   ci;
132
133     pack_devino(buf, dev, ino);
134     
135     middle = buf + CNID_DEV_LEN;
136     end = buf + CNID_DEV_LEN + CNID_INO_LEN;
137     c1  = buf;
138     c2  = rbuf;  
139     
140     while (c1 < end) {
141         if (c1 == middle) {
142             *c2 = '/';
143             c2++;
144         }    
145         ci = *c1;
146         c2[0] = hexchars[(ci & 0xf0) >> 4];
147         c2[1] = hexchars[ci & 0x0f];
148         c1++;
149         c2 += 2;
150     }
151     return rbuf;
152 }
153 #endif