2 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
3 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Paul Borman at Krystal Technologies.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #if defined(LIBC_SCCS) && !defined(lint)
36 static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93";
37 #endif /* LIBC_SCCS and not lint */
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
41 #include "namespace.h"
42 #include <arpa/inet.h>
48 #include <sys/types.h>
53 #include "un-namespace.h"
59 _Read_RuneMagi(const char *fname)
70 _FileRuneEntry *runetype_ext_ranges;
71 _FileRuneEntry *maplower_ext_ranges;
72 _FileRuneEntry *mapupper_ext_ranges;
73 int runetype_ext_len = 0;
76 if ((fd = _open(fname, O_RDONLY)) < 0) {
81 if (_fstat(fd, &sb) < 0) {
87 if ((size_t)sb.st_size < sizeof (_FileRuneLocale)) {
94 fdata = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
101 frl = (_FileRuneLocale *)(void *)fdata;
102 lastp = fdata + sb.st_size;
106 if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof (frl->magic))) {
110 runetype_ext_ranges = (_FileRuneEntry *)variable;
111 variable = runetype_ext_ranges + BSWAP(frl->runetype_ext_nranges);
112 if (variable > lastp) {
116 maplower_ext_ranges = (_FileRuneEntry *)variable;
117 variable = maplower_ext_ranges + BSWAP(frl->maplower_ext_nranges);
118 if (variable > lastp) {
122 mapupper_ext_ranges = (_FileRuneEntry *)variable;
123 variable = mapupper_ext_ranges + BSWAP(frl->mapupper_ext_nranges);
124 if (variable > lastp) {
128 frr = runetype_ext_ranges;
129 for (x = 0; x < BSWAP(frl->runetype_ext_nranges); ++x) {
132 if (BSWAP(frr[x].map) == 0) {
133 int len = BSWAP(frr[x].max) - BSWAP(frr[x].min) + 1;
135 variable = types + len;
136 runetype_ext_len += len;
137 if (variable > lastp) {
143 if ((char *)variable + BSWAP(frl->variable_len) > (char *)lastp) {
148 * Convert from disk format to host format.
150 data = malloc(sizeof(_RuneLocale) +
151 (BSWAP(frl->runetype_ext_nranges) + BSWAP(frl->maplower_ext_nranges) +
152 BSWAP(frl->mapupper_ext_nranges)) * sizeof(_RuneEntry) +
153 runetype_ext_len * sizeof(*rr->__types) +
154 BSWAP(frl->variable_len));
157 munmap(fdata, sb.st_size);
162 rl = (_RuneLocale *)data;
163 rl->__variable = rl + 1;
165 memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic));
166 memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding));
168 rl->__variable_len = BSWAP(frl->variable_len);
169 rl->__runetype_ext.__nranges = BSWAP(frl->runetype_ext_nranges);
170 rl->__maplower_ext.__nranges = BSWAP(frl->maplower_ext_nranges);
171 rl->__mapupper_ext.__nranges = BSWAP(frl->mapupper_ext_nranges);
173 for (x = 0; x < _CACHED_RUNES; ++x) {
174 rl->__runetype[x] = BSWAP(frl->runetype[x]);
175 rl->__maplower[x] = BSWAP(frl->maplower[x]);
176 rl->__mapupper[x] = BSWAP(frl->mapupper[x]);
179 rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
180 rl->__variable = rl->__runetype_ext.__ranges +
181 rl->__runetype_ext.__nranges;
183 rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable;
184 rl->__variable = rl->__maplower_ext.__ranges +
185 rl->__maplower_ext.__nranges;
187 rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable;
188 rl->__variable = rl->__mapupper_ext.__ranges +
189 rl->__mapupper_ext.__nranges;
191 variable = mapupper_ext_ranges + BSWAP(frl->mapupper_ext_nranges);
192 frr = runetype_ext_ranges;
193 rr = rl->__runetype_ext.__ranges;
194 for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
197 rr[x].__min = BSWAP(frr[x].min);
198 rr[x].__max = BSWAP(frr[x].max);
199 rr[x].__map = BSWAP(frr[x].map);
200 if (rr[x].__map == 0) {
201 int len = rr[x].__max - rr[x].__min + 1;
203 variable = types + len;
204 rr[x].__types = rl->__variable;
205 rl->__variable = rr[x].__types + len;
207 rr[x].__types[len] = types[len];
209 rr[x].__types = NULL;
212 frr = maplower_ext_ranges;
213 rr = rl->__maplower_ext.__ranges;
214 for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
215 rr[x].__min = BSWAP(frr[x].min);
216 rr[x].__max = BSWAP(frr[x].max);
217 rr[x].__map = BSWAP(frr[x].map);
220 frr = mapupper_ext_ranges;
221 rr = rl->__mapupper_ext.__ranges;
222 for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
223 rr[x].__min = BSWAP(frr[x].min);
224 rr[x].__max = BSWAP(frr[x].max);
225 rr[x].__map = BSWAP(frr[x].map);
228 memcpy(rl->__variable, variable, rl->__variable_len);
229 munmap(fdata, sb.st_size);
232 * Go out and zero pointers that should be zero.
234 if (!rl->__variable_len)
235 rl->__variable = NULL;
237 if (!rl->__runetype_ext.__nranges)
238 rl->__runetype_ext.__ranges = NULL;
240 if (!rl->__maplower_ext.__nranges)
241 rl->__maplower_ext.__ranges = NULL;
243 if (!rl->__mapupper_ext.__nranges)
244 rl->__mapupper_ext.__ranges = NULL;
249 munmap(fdata, sb.st_size);