~ubuntu-branches/ubuntu/precise/netatalk/precise

« back to all changes in this revision

Viewing changes to etc/afpd/codepage.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: codepage.c,v 1.8 2002/03/24 01:23:40 sibaz Exp $
 
3
 *
 
4
 * Copyright (c) 2000 Adrian Sun
 
5
 * All Rights Reserved. See COPYRIGHT.
 
6
 *
 
7
 * codepage support (based initially on some code from
 
8
 * julian@whistle.com)
 
9
 *
 
10
 * the strategy:
 
11
 * for single-byte maps, the codepage support devolves to a lookup
 
12
 * table for all possible 8-bit values. for double-byte maps, 
 
13
 * the first byte is used as a hash index followed by a linked list of
 
14
 * values.
 
15
 *
 
16
 * the badumap specifies illegal characters. these are 8-bit values
 
17
 * with an associated rule field. here are the rules:
 
18
 *   
 
19
 * illegal values: 0 is the only illegal value. no translation will
 
20
 * occur in those cases.  
 
21
 */
 
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
#include "config.h"
 
25
#endif /* HAVE_CONFIG_H */
 
26
 
 
27
#include <stdio.h>
 
28
#include <stdlib.h>
 
29
#include <string.h>
 
30
#include <sys/types.h>
 
31
#include <sys/stat.h>
 
32
#ifdef HAVE_FCNTL_H
 
33
#include <fcntl.h>
 
34
#endif /* HAVE_FCNTL_H */
 
35
#ifdef HAVE_UNISTD_H
 
36
#include <unistd.h>
 
37
#endif /* HAVE_UNISTD_H */
 
38
#include <atalk/logger.h>
 
39
 
 
40
#include <netatalk/endian.h>
 
41
 
 
42
#include "globals.h"
 
43
#include "volume.h"
 
44
#include "codepage.h"
 
45
 
 
46
#define MAPSIZE 256
 
47
 
 
48
/* deal with linked lists */
 
49
#define CP_INIT(a) (a)->next = (a)->prev = (a)
 
50
#define CP_ADD(a, b) do { \
 
51
  (b)->next = (a)->next; \
 
52
  (b)->prev = (a); \
 
53
  (a)->next = (b); \
 
54
} while (0)
 
55
#define CP_REMOVE(a) do {  \
 
56
  (a)->prev->next = (a)->next; \
 
57
  (a)->next->prev = (a)->prev; \
 
58
} while (0)
 
59
 
 
60
/* search for stuff */
 
61
#if 0
 
62
static __inline__ unsigned char *codepage_find(struct codepage *page,
 
63
        unsigned char *from)
 
64
{
 
65
}
 
66
#endif
 
67
 
 
68
static int add_code(struct codepage *page, unsigned char *from,
 
69
                    unsigned char *to)
 
70
{
 
71
#if 0
 
72
    union codepage_val *ptr;
 
73
#endif /* 0 */
 
74
 
 
75
    if (page->quantum < 1) /* no quantum given. don't do anything */
 
76
        return 1;
 
77
 
 
78
    if (page->quantum == 1) {
 
79
        page->map[*from].value = *to;
 
80
        return 0;
 
81
    }
 
82
 
 
83
#if 0
 
84
    if (ptr = codepage_find(page->map, from)) {
 
85
 
 
86
    } else {
 
87
        unsigned char *space;
 
88
        ptr = map[*from].hash;
 
89
 
 
90
        space = (unsigned char *) malloc(sizeof(unsigned char)*quantum);
 
91
        if (!ptr->from) {
 
92
        } else {
 
93
        }
 
94
 
 
95
        map[*from].hash
 
96
    }
 
97
#endif /* 0 */
 
98
    return 0;
 
99
}
 
100
 
 
101
static struct codepage *init_codepage(const int quantum)
 
102
{
 
103
    struct codepage *cp;
 
104
 
 
105
    cp = (struct codepage *) malloc(sizeof(struct codepage));
 
106
    if (!cp)
 
107
        return NULL;
 
108
 
 
109
    if ((cp->map = (union codepage_val *)
 
110
                   calloc(MAPSIZE, sizeof(union codepage_val))) == NULL) {
 
111
        free(cp);
 
112
        return NULL;
 
113
    }
 
114
 
 
115
    cp->quantum = quantum;
 
116
    return cp;
 
117
}
 
118
 
 
119
 
 
120
static void free_codepage(struct codepage *cp)
 
121
{
 
122
    int i;
 
123
 
 
124
    if (!cp)
 
125
        return;
 
126
 
 
127
    if (cp->map) {
 
128
        if (cp->quantum > 1) {
 
129
            /* deal with any linked lists that may exist */
 
130
            for (i = 0; i < MAPSIZE; i++) {
 
131
                struct codepage_hash *ptr, *h;
 
132
 
 
133
                h = &cp->map[i].hash; /* we don't free this one */
 
134
                while ((ptr = h->prev) != h) {
 
135
                    CP_REMOVE(ptr);
 
136
                    free(ptr);
 
137
                }
 
138
            }
 
139
        }
 
140
        free(cp->map);
 
141
    }
 
142
    free(cp);
 
143
}
 
144
 
 
145
 
 
146
 
 
147
/* this is used by both codepages and generic mapping utilities. we
 
148
 * allocate enough space to map all 8-bit characters if necessary.
 
149
 * for double-byte mappings, we just use the table as a hash lookup.
 
150
 * if we don't match, we don't convert.
 
151
 */
 
152
int codepage_init(struct vol *vol, const int rules,
 
153
                  const int quantum)
 
154
{
 
155
    if ((rules & CODEPAGE_RULE_UTOM) && !vol->v_utompage) {
 
156
        vol->v_utompage = init_codepage(quantum);
 
157
        if (!vol->v_utompage)
 
158
            goto err_utompage;
 
159
    }
 
160
 
 
161
    if ((rules & CODEPAGE_RULE_MTOU) && !vol->v_mtoupage) {
 
162
        vol->v_mtoupage = init_codepage(quantum);
 
163
        if (!vol->v_mtoupage) {
 
164
            goto err_mtoupage;
 
165
        }
 
166
    }
 
167
 
 
168
    if ((rules & CODEPAGE_RULE_BADU)  && !vol->v_badumap) {
 
169
        vol->v_badumap = init_codepage(quantum);
 
170
        if (!vol->v_badumap)
 
171
            goto err_mtoupage;
 
172
    }
 
173
    return 0;
 
174
 
 
175
err_mtoupage:
 
176
    free_codepage(vol->v_mtoupage);
 
177
    vol->v_mtoupage = NULL;
 
178
 
 
179
err_utompage:
 
180
    free_codepage(vol->v_utompage);
 
181
    vol->v_utompage = NULL;
 
182
    return -1;
 
183
}
 
184
 
 
185
void codepage_free(struct vol *vol)
 
186
{
 
187
    if (vol->v_utompage) {
 
188
        free_codepage(vol->v_utompage);
 
189
        vol->v_utompage = NULL;
 
190
    }
 
191
 
 
192
    if (vol->v_mtoupage) {
 
193
        free_codepage(vol->v_mtoupage);
 
194
        vol->v_mtoupage = NULL;
 
195
    }
 
196
 
 
197
    if (vol->v_badumap) {
 
198
        free_codepage(vol->v_badumap);
 
199
        vol->v_badumap = NULL;
 
200
    }
 
201
}
 
202
 
 
203
 
 
204
int codepage_read(struct vol *vol, const char *path)
 
205
{
 
206
    unsigned char buf[CODEPAGE_FILE_HEADER_SIZE], *cur;
 
207
    u_int16_t id;
 
208
    int fd, i, quantum, rules;
 
209
 
 
210
    if ((fd = open(path, O_RDONLY)) < 0) {
 
211
        LOG(log_error, logtype_afpd, "%s: failed to open codepage", path);
 
212
        return -1;
 
213
    }
 
214
 
 
215
    /* Read the codepage file header. */
 
216
    if(read(fd, buf, sizeof(buf)) != sizeof(buf)) {
 
217
        LOG(log_error, logtype_afpd, "%s: failed to read codepage header", path);
 
218
        goto codepage_fail;
 
219
    }
 
220
 
 
221
    /* Check the file id */
 
222
    cur = buf;
 
223
    memcpy(&id, cur, sizeof(id));
 
224
    cur += sizeof(id);
 
225
    id = ntohs(id);
 
226
    if (id != CODEPAGE_FILE_ID) {
 
227
        LOG(log_error, logtype_afpd, "%s: not a codepage", path);
 
228
        goto codepage_fail;
 
229
    }
 
230
 
 
231
    /* check the version number */
 
232
    if (*cur++ != CODEPAGE_FILE_VERSION) {
 
233
        LOG(log_error, logtype_afpd, "%s: codepage version not supported", path);
 
234
        goto codepage_fail;
 
235
    }
 
236
 
 
237
    /* ignore namelen */
 
238
    cur++;
 
239
 
 
240
    /* find out the data quantum size. default to 1 if nothing's given. */
 
241
    quantum = *cur ? *cur : 1;
 
242
    cur++;
 
243
 
 
244
    /* rules used in this file. */
 
245
    rules = *cur++;
 
246
 
 
247
    if (codepage_init(vol, rules, quantum) < 0) {
 
248
        LOG(log_error, logtype_afpd, "%s: Unable to allocate memory", path);
 
249
        goto codepage_fail;
 
250
    }
 
251
 
 
252
    /* offset to data */
 
253
 
 
254
    /* skip to the start of the data */
 
255
    memcpy(&id, cur , sizeof(id));
 
256
    id = ntohs(id);
 
257
    lseek(fd, id, SEEK_SET);
 
258
 
 
259
    /* mtoupage is the the equivalent of samba's unix2dos. utompage is
 
260
     * the equivalent of dos2unix. it's a little confusing due to a
 
261
     * desire to match up with mtoupath and utompath. 
 
262
     * NOTE: we allow codepages to specify 7-bit mappings if they want. 
 
263
     */
 
264
    i = 1 + 2*quantum;
 
265
    while (read(fd, buf, i) == i) {
 
266
        if (*buf & CODEPAGE_RULE_MTOU) {
 
267
            if (add_code(vol->v_mtoupage, buf + 1, buf + 1 + quantum) < 0) {
 
268
                LOG(log_error, logtype_afpd, "unable to allocate memory for mtoupage");
 
269
                break;
 
270
            }
 
271
        }
 
272
 
 
273
        if (*buf & CODEPAGE_RULE_UTOM) {
 
274
            if (add_code(vol->v_utompage, buf + 1 + quantum, buf + 1) < 0) {
 
275
                LOG(log_error, logtype_afpd, "unable to allocate memory for utompage");
 
276
                break;
 
277
            }
 
278
        }
 
279
 
 
280
        /* we only look at the first character here. if we need to
 
281
         * do so, we can always use the quantum to expand the 
 
282
         * available flags. */
 
283
        if (*buf & CODEPAGE_RULE_BADU)
 
284
            vol->v_badumap->map[*(buf + 1)].value = *(buf + 1 + quantum);
 
285
    }
 
286
    close(fd);
 
287
    return 0;
 
288
 
 
289
codepage_fail:
 
290
    close(fd);
 
291
    return -1;
 
292
}