]> arthur.barton.de Git - netatalk.git/blob - etc/cnid_dbd/pack.c
New MySQL CNID backend
[netatalk.git] / etc / cnid_dbd / pack.c
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 <arpa/inet.h>
12
13 #include <string.h>
14 #include <inttypes.h>
15 #include <sys/param.h>
16 #include <db.h>
17
18 #include <atalk/unicode.h>
19 #include <atalk/logger.h>
20 #include <atalk/cnid_bdb_private.h>
21 #include <atalk/volume.h>
22 #include "pack.h"
23
24 static const struct vol *volume;
25
26 /* --------------- */
27 /*
28  *  This implementation is portable, but could probably be faster by using htonl
29  *  where appropriate. Also, this again doubles code from the cdb backend.
30  */
31 static void pack_devino(unsigned char *buf, dev_t dev, ino_t ino)
32 {
33     buf[CNID_DEV_LEN - 1] = dev; dev >>= 8;
34     buf[CNID_DEV_LEN - 2] = dev; dev >>= 8;
35     buf[CNID_DEV_LEN - 3] = dev; dev >>= 8;
36     buf[CNID_DEV_LEN - 4] = dev; dev >>= 8;
37     buf[CNID_DEV_LEN - 5] = dev; dev >>= 8;
38     buf[CNID_DEV_LEN - 6] = dev; dev >>= 8;
39     buf[CNID_DEV_LEN - 7] = dev; dev >>= 8;
40     buf[CNID_DEV_LEN - 8] = dev;
41
42     buf[CNID_DEV_LEN + CNID_INO_LEN - 1] = ino; ino >>= 8;
43     buf[CNID_DEV_LEN + CNID_INO_LEN - 2] = ino; ino >>= 8;
44     buf[CNID_DEV_LEN + CNID_INO_LEN - 3] = ino; ino >>= 8;
45     buf[CNID_DEV_LEN + CNID_INO_LEN - 4] = ino; ino >>= 8;
46     buf[CNID_DEV_LEN + CNID_INO_LEN - 5] = ino; ino >>= 8;
47     buf[CNID_DEV_LEN + CNID_INO_LEN - 6] = ino; ino >>= 8;
48     buf[CNID_DEV_LEN + CNID_INO_LEN - 7] = ino; ino >>= 8;
49     buf[CNID_DEV_LEN + CNID_INO_LEN - 8] = ino;    
50 }
51
52 /* --------------- */
53 int didname(DB *dbp _U_, const DBT *pkey _U_, const DBT *pdata, DBT *skey)
54 {
55 int len;
56  
57     memset(skey, 0, sizeof(DBT));
58     skey->data = (char *)pdata->data + CNID_DID_OFS;
59     /* FIXME: At least DB 4.0.14 and 4.1.25 pass in the correct length of
60        pdata.size. strlen is therefore not needed. Also, skey should be zeroed
61        out already. */
62     len = strlen((char *)skey->data + CNID_DID_LEN);
63     skey->size = CNID_DID_LEN + len + 1;
64     return (0);
65 }
66  
67 /* --------------- */
68 int devino(DB *dbp _U_, const DBT *pkey _U_,  const DBT *pdata, DBT *skey)
69 {
70     memset(skey, 0, sizeof(DBT));
71     skey->data = (char *)pdata->data + CNID_DEVINO_OFS;
72     skey->size = CNID_DEVINO_LEN;
73     return (0);
74 }
75
76 /* --------------- */
77 int idxname(DB *dbp _U_, const DBT *pkey _U_,  const DBT *pdata, DBT *skey)
78 {
79     static char buffer[MAXPATHLEN +2];
80     uint16_t flags = CONV_TOLOWER;
81     memset(skey, 0, sizeof(DBT));
82
83     if (convert_charset(volume->v_volcharset,
84                         volume->v_volcharset,
85                         volume->v_maccharset,
86                         (char *)pdata->data + CNID_NAME_OFS,
87                         strlen((char *)pdata->data + CNID_NAME_OFS),
88                         buffer,
89                         MAXPATHLEN,
90                         &flags) == (size_t)-1) {
91         LOG(log_error, logtype_cnid, "idxname: conversion error");
92     }
93
94     skey->data = buffer;
95     skey->size = strlen(skey->data);
96     return (0);
97 }
98
99 void pack_setvol(const struct vol *vol)
100 {
101     volume = vol;
102 }
103
104 /* The equivalent to make_cnid_data in the cnid library. Non re-entrant. We
105    differ from make_cnid_data in that we never return NULL, rqst->name cannot
106    ever cause start[] to overflow because name length is checked in libatalk. */
107
108 unsigned char *pack_cnid_data(struct cnid_dbd_rqst *rqst)
109 {
110     static unsigned char start[CNID_HEADER_LEN + MAXPATHLEN + 1];
111     unsigned char *buf = start +CNID_LEN;
112     u_int32_t i;
113
114     pack_devino(buf, rqst->dev, rqst->ino);
115     buf += CNID_DEVINO_LEN;
116
117     i = htonl(rqst->type);
118     memcpy(buf, &i, sizeof(i));
119     buf += sizeof(i);
120
121     /* did is already in network byte order */
122     buf = memcpy(buf, &rqst->did, sizeof(rqst->did));
123     buf += sizeof(rqst->did);
124     buf = memcpy(buf, rqst->name, rqst->namelen);
125     *(buf + rqst->namelen) = '\0';
126
127     return start;
128 }
129