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
34 * @(#)rune.c 8.1 (Berkeley) 6/4/93
38 #include "namespace.h"
44 #include <sys/types.h>
49 #include "un-namespace.h"
54 _Read_RuneMagi(const char *fname
)
65 _FileRuneEntry
*runetype_ext_ranges
;
66 _FileRuneEntry
*maplower_ext_ranges
;
67 _FileRuneEntry
*mapupper_ext_ranges
;
68 int runetype_ext_len
= 0;
71 if ((fd
= _open(fname
, O_RDONLY
)) < 0) {
76 if (_fstat(fd
, &sb
) < 0) {
82 if ((size_t)sb
.st_size
< sizeof (_FileRuneLocale
)) {
89 fdata
= mmap(NULL
, sb
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
96 frl
= (_FileRuneLocale
*)(void *)fdata
;
97 lastp
= fdata
+ sb
.st_size
;
101 if (memcmp(frl
->magic
, _FILE_RUNE_MAGIC_1
, sizeof (frl
->magic
))) {
105 runetype_ext_ranges
= (_FileRuneEntry
*)variable
;
106 variable
= runetype_ext_ranges
+ frl
->runetype_ext_nranges
;
107 if (variable
> lastp
) {
111 maplower_ext_ranges
= (_FileRuneEntry
*)variable
;
112 variable
= maplower_ext_ranges
+ frl
->maplower_ext_nranges
;
113 if (variable
> lastp
) {
117 mapupper_ext_ranges
= (_FileRuneEntry
*)variable
;
118 variable
= mapupper_ext_ranges
+ frl
->mapupper_ext_nranges
;
119 if (variable
> lastp
) {
123 frr
= runetype_ext_ranges
;
124 for (x
= 0; x
< frl
->runetype_ext_nranges
; ++x
) {
127 if (frr
[x
].map
== 0) {
128 int len
= frr
[x
].max
- frr
[x
].min
+ 1;
130 variable
= types
+ len
;
131 runetype_ext_len
+= len
;
132 if (variable
> lastp
) {
138 if ((char *)variable
+ frl
->variable_len
> (char *)lastp
) {
143 * Convert from disk format to host format.
145 data
= malloc(sizeof(_RuneLocale
) +
146 (frl
->runetype_ext_nranges
+ frl
->maplower_ext_nranges
+
147 frl
->mapupper_ext_nranges
) * sizeof(_RuneEntry
) +
148 runetype_ext_len
* sizeof(*rr
->__types
) +
152 (void) munmap(fdata
, sb
.st_size
);
157 rl
= (_RuneLocale
*)(void *)data
;
158 rl
->__variable
= rl
+ 1;
160 (void) memcpy(rl
->__magic
, _RUNE_MAGIC_1
, sizeof (rl
->__magic
));
161 (void) memcpy(rl
->__encoding
, frl
->encoding
, sizeof (rl
->__encoding
));
163 rl
->__variable_len
= frl
->variable_len
;
164 rl
->__runetype_ext
.__nranges
= frl
->runetype_ext_nranges
;
165 rl
->__maplower_ext
.__nranges
= frl
->maplower_ext_nranges
;
166 rl
->__mapupper_ext
.__nranges
= frl
->mapupper_ext_nranges
;
168 for (x
= 0; x
< _CACHED_RUNES
; ++x
) {
169 rl
->__runetype
[x
] = frl
->runetype
[x
];
170 rl
->__maplower
[x
] = frl
->maplower
[x
];
171 rl
->__mapupper
[x
] = frl
->mapupper
[x
];
174 rl
->__runetype_ext
.__ranges
= (_RuneEntry
*)rl
->__variable
;
175 rl
->__variable
= rl
->__runetype_ext
.__ranges
+
176 rl
->__runetype_ext
.__nranges
;
178 rl
->__maplower_ext
.__ranges
= (_RuneEntry
*)rl
->__variable
;
179 rl
->__variable
= rl
->__maplower_ext
.__ranges
+
180 rl
->__maplower_ext
.__nranges
;
182 rl
->__mapupper_ext
.__ranges
= (_RuneEntry
*)rl
->__variable
;
183 rl
->__variable
= rl
->__mapupper_ext
.__ranges
+
184 rl
->__mapupper_ext
.__nranges
;
186 variable
= mapupper_ext_ranges
+ frl
->mapupper_ext_nranges
;
187 frr
= runetype_ext_ranges
;
188 rr
= rl
->__runetype_ext
.__ranges
;
189 for (x
= 0; x
< rl
->__runetype_ext
.__nranges
; ++x
) {
192 rr
[x
].__min
= frr
[x
].min
;
193 rr
[x
].__max
= frr
[x
].max
;
194 rr
[x
].__map
= frr
[x
].map
;
195 if (rr
[x
].__map
== 0) {
196 int len
= rr
[x
].__max
- rr
[x
].__min
+ 1;
198 variable
= types
+ len
;
199 rr
[x
].__types
= rl
->__variable
;
200 rl
->__variable
= rr
[x
].__types
+ len
;
202 rr
[x
].__types
[len
] = types
[len
];
204 rr
[x
].__types
= NULL
;
207 frr
= maplower_ext_ranges
;
208 rr
= rl
->__maplower_ext
.__ranges
;
209 for (x
= 0; x
< rl
->__maplower_ext
.__nranges
; ++x
) {
210 rr
[x
].__min
= frr
[x
].min
;
211 rr
[x
].__max
= frr
[x
].max
;
212 rr
[x
].__map
= frr
[x
].map
;
215 frr
= mapupper_ext_ranges
;
216 rr
= rl
->__mapupper_ext
.__ranges
;
217 for (x
= 0; x
< rl
->__mapupper_ext
.__nranges
; ++x
) {
218 rr
[x
].__min
= frr
[x
].min
;
219 rr
[x
].__max
= frr
[x
].max
;
220 rr
[x
].__map
= frr
[x
].map
;
223 (void) memcpy(rl
->__variable
, variable
, rl
->__variable_len
);
224 (void) munmap(fdata
, sb
.st_size
);
227 * Go out and zero pointers that should be zero.
229 if (!rl
->__variable_len
)
230 rl
->__variable
= NULL
;
232 if (!rl
->__runetype_ext
.__nranges
)
233 rl
->__runetype_ext
.__ranges
= NULL
;
235 if (!rl
->__maplower_ext
.__nranges
)
236 rl
->__maplower_ext
.__ranges
= NULL
;
238 if (!rl
->__mapupper_ext
.__nranges
)
239 rl
->__mapupper_ext
.__ranges
= NULL
;
244 (void) munmap(fdata
, sb
.st_size
);