2 * Copyright (C) Joerg Lenneis 2003
3 * Copyright (C) Frank Lahm 2010
4 * All Rights Reserved. See COPYING.
9 #endif /* HAVE_CONFIG_H */
11 #include <netatalk/endian.h>
15 #include <sys/param.h>
16 #include <sys/cdefs.h>
19 #include <atalk/unicode.h>
20 #include <atalk/volinfo.h>
21 #include <atalk/logger.h>
22 #include <atalk/cnid_dbd_private.h>
26 extern struct volinfo volinfo;
30 * This implementation is portable, but could probably be faster by using htonl
31 * where appropriate. Also, this again doubles code from the cdb backend.
33 static void pack_devino(unsigned char *buf, dev_t dev, ino_t ino)
35 buf[CNID_DEV_LEN - 1] = dev; dev >>= 8;
36 buf[CNID_DEV_LEN - 2] = dev; dev >>= 8;
37 buf[CNID_DEV_LEN - 3] = dev; dev >>= 8;
38 buf[CNID_DEV_LEN - 4] = dev; dev >>= 8;
39 buf[CNID_DEV_LEN - 5] = dev; dev >>= 8;
40 buf[CNID_DEV_LEN - 6] = dev; dev >>= 8;
41 buf[CNID_DEV_LEN - 7] = dev; dev >>= 8;
42 buf[CNID_DEV_LEN - 8] = dev;
44 buf[CNID_DEV_LEN + CNID_INO_LEN - 1] = ino; ino >>= 8;
45 buf[CNID_DEV_LEN + CNID_INO_LEN - 2] = ino; ino >>= 8;
46 buf[CNID_DEV_LEN + CNID_INO_LEN - 3] = ino; ino >>= 8;
47 buf[CNID_DEV_LEN + CNID_INO_LEN - 4] = ino; ino >>= 8;
48 buf[CNID_DEV_LEN + CNID_INO_LEN - 5] = ino; ino >>= 8;
49 buf[CNID_DEV_LEN + CNID_INO_LEN - 6] = ino; ino >>= 8;
50 buf[CNID_DEV_LEN + CNID_INO_LEN - 7] = ino; ino >>= 8;
51 buf[CNID_DEV_LEN + CNID_INO_LEN - 8] = ino;
55 int didname(DB *dbp _U_, const DBT *pkey _U_, const DBT *pdata, DBT *skey)
59 memset(skey, 0, sizeof(DBT));
60 skey->data = (char *)pdata->data + CNID_DID_OFS;
61 /* FIXME: At least DB 4.0.14 and 4.1.25 pass in the correct length of
62 pdata.size. strlen is therefore not needed. Also, skey should be zeroed
64 len = strlen((char *)skey->data + CNID_DID_LEN);
65 skey->size = CNID_DID_LEN + len + 1;
70 int devino(DB *dbp _U_, const DBT *pkey _U_, const DBT *pdata, DBT *skey)
72 memset(skey, 0, sizeof(DBT));
73 skey->data = (char *)pdata->data + CNID_DEVINO_OFS;
74 skey->size = CNID_DEVINO_LEN;
79 int idxname(DB *dbp _U_, const DBT *pkey _U_, const DBT *pdata, DBT *skey)
81 char buffer[MAXPATHLEN +2];
82 uint16_t flags = CONV_TOLOWER;
83 memset(skey, 0, sizeof(DBT));
84 skey->data = (char *)pdata->data + CNID_NAME_OFS;
86 if (convert_charset(volinfo.v_volcharset,
89 (char *)pdata->data + CNID_NAME_OFS,
90 strlen((char *)pdata->data + CNID_NAME_OFS),
93 &flags) == (size_t)-1) {
94 LOG(log_error, logtype_cnid, "idxname: conversion error");
98 skey->size = strlen(skey->data);
102 /* The equivalent to make_cnid_data in the cnid library. Non re-entrant. We
103 differ from make_cnid_data in that we never return NULL, rqst->name cannot
104 ever cause start[] to overflow because name length is checked in libatalk. */
106 unsigned char *pack_cnid_data(struct cnid_dbd_rqst *rqst)
108 static unsigned char start[CNID_HEADER_LEN + MAXPATHLEN + 1];
109 unsigned char *buf = start +CNID_LEN;
112 pack_devino(buf, rqst->dev, rqst->ino);
113 buf += CNID_DEVINO_LEN;
115 i = htonl(rqst->type);
116 memcpy(buf, &i, sizeof(i));
119 /* did is already in network byte order */
120 buf = memcpy(buf, &rqst->did, sizeof(rqst->did));
121 buf += sizeof(rqst->did);
122 buf = memcpy(buf, rqst->name, rqst->namelen);
123 *(buf + rqst->namelen) = '\0';