• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.0/etc/cnid_dbd/
1/*
2 * Copyright (C) Joerg Lenneis 2003
3 * Copyright (C) Frank Lahm 2010
4 * All Rights Reserved.  See COPYING.
5 */
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif /* HAVE_CONFIG_H */
10
11#include <netatalk/endian.h>
12
13#include <string.h>
14#include <inttypes.h>
15#include <sys/param.h>
16#include <sys/cdefs.h>
17#include <db.h>
18
19#include <atalk/unicode.h>
20#include <atalk/volinfo.h>
21#include <atalk/logger.h>
22#include <atalk/cnid_dbd_private.h>
23#include "pack.h"
24
25/* in main.c for `cnid_dbd` or cmd_dbd.c for `dbd` */
26extern struct volinfo volinfo;
27
28/* --------------- */
29/*
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.
32 */
33static void pack_devino(unsigned char *buf, dev_t dev, ino_t ino)
34{
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;
43
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;
52}
53
54/* --------------- */
55int didname(DB *dbp _U_, const DBT *pkey _U_, const DBT *pdata, DBT *skey)
56{
57int len;
58
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
63       out already. */
64    len = strlen((char *)skey->data + CNID_DID_LEN);
65    skey->size = CNID_DID_LEN + len + 1;
66    return (0);
67}
68
69/* --------------- */
70int devino(DB *dbp _U_, const DBT *pkey _U_,  const DBT *pdata, DBT *skey)
71{
72    memset(skey, 0, sizeof(DBT));
73    skey->data = (char *)pdata->data + CNID_DEVINO_OFS;
74    skey->size = CNID_DEVINO_LEN;
75    return (0);
76}
77
78/* --------------- */
79int idxname(DB *dbp _U_, const DBT *pkey _U_,  const DBT *pdata, DBT *skey)
80{
81    static char buffer[MAXPATHLEN +2];
82    uint16_t flags = CONV_TOLOWER;
83    memset(skey, 0, sizeof(DBT));
84
85    if (convert_charset(volinfo.v_volcharset,
86                        volinfo.v_volcharset,
87                        volinfo.v_maccharset,
88                        (char *)pdata->data + CNID_NAME_OFS,
89                        strlen((char *)pdata->data + CNID_NAME_OFS),
90                        buffer,
91                        MAXPATHLEN,
92                        &flags) == (size_t)-1) {
93        LOG(log_error, logtype_cnid, "idxname: conversion error");
94    }
95
96    skey->data = buffer;
97    skey->size = strlen(skey->data);
98    return (0);
99}
100
101/* The equivalent to make_cnid_data in the cnid library. Non re-entrant. We
102   differ from make_cnid_data in that we never return NULL, rqst->name cannot
103   ever cause start[] to overflow because name length is checked in libatalk. */
104
105unsigned char *pack_cnid_data(struct cnid_dbd_rqst *rqst)
106{
107    static unsigned char start[CNID_HEADER_LEN + MAXPATHLEN + 1];
108    unsigned char *buf = start +CNID_LEN;
109    u_int32_t i;
110
111    pack_devino(buf, rqst->dev, rqst->ino);
112    buf += CNID_DEVINO_LEN;
113
114    i = htonl(rqst->type);
115    memcpy(buf, &i, sizeof(i));
116    buf += sizeof(i);
117
118    /* did is already in network byte order */
119    buf = memcpy(buf, &rqst->did, sizeof(rqst->did));
120    buf += sizeof(rqst->did);
121    buf = memcpy(buf, rqst->name, rqst->namelen);
122    *(buf + rqst->namelen) = '\0';
123
124    return start;
125}
126
127