2 * $Id: pack.c,v 1.1.4.9.2.1 2005-09-27 10:40:41 didg Exp $
4 * Copyright (C) Joerg Lenneis 2003
5 * All Rights Reserved. See COPYING.
10 #endif /* HAVE_CONFIG_H */
12 #include <netatalk/endian.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>
22 #include <atalk/cnid_dbd_private.h>
27 * Auxiliary stuff for stringify_devino. See comments below.
29 static char hexchars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
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.
37 static void pack_devino(unsigned char *buf, dev_t dev, ino_t ino)
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;
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;
59 int didname(dbp, pkey, pdata, skey)
61 const DBT *pkey _U_, *pdata;
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
71 len = strlen((char *)skey->data + CNID_DID_LEN);
72 skey->size = CNID_DID_LEN + len + 1;
77 int devino(dbp, pkey, pdata, skey)
79 const DBT *pkey _U_, *pdata;
82 memset(skey, 0, sizeof(DBT));
83 skey->data = (char *)pdata->data + CNID_DEVINO_OFS;
84 skey->size = CNID_DEVINO_LEN;
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. */
92 unsigned char *pack_cnid_data(struct cnid_dbd_rqst *rqst)
94 static unsigned char start[CNID_HEADER_LEN + MAXPATHLEN + 1];
95 unsigned char *buf = start +CNID_LEN;
98 pack_devino(buf, rqst->dev, rqst->ino);
99 buf += CNID_DEVINO_LEN;
101 i = htonl(rqst->type);
102 memcpy(buf, &i, sizeof(i));
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';
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.
123 char *stringify_devino(dev_t dev, ino_t ino)
125 static char rbuf[CNID_DEV_LEN * 2 + 1 + CNID_INO_LEN * 2 + 1] = {0};
126 char buf[CNID_DEV_LEN + CNID_INO_LEN];
133 pack_devino(buf, dev, ino);
135 middle = buf + CNID_DEV_LEN;
136 end = buf + CNID_DEV_LEN + CNID_INO_LEN;
146 c2[0] = hexchars[(ci & 0xf0) >> 4];
147 c2[1] = hexchars[ci & 0x0f];