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"
53 _RuneLocale
*_Read_RuneMagi(const char *);
56 _Read_RuneMagi(const char *fname
)
67 _FileRuneEntry
*runetype_ext_ranges
;
68 _FileRuneEntry
*maplower_ext_ranges
;
69 _FileRuneEntry
*mapupper_ext_ranges
;
70 int runetype_ext_len
= 0;
73 if ((fd
= _open(fname
, O_RDONLY
)) < 0) {
78 if (_fstat(fd
, &sb
) < 0) {
84 if ((size_t)sb
.st_size
< sizeof (_FileRuneLocale
)) {
91 fdata
= mmap(NULL
, sb
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
98 frl
= (_FileRuneLocale
*)(void *)fdata
;
99 lastp
= fdata
+ sb
.st_size
;
103 if (memcmp(frl
->magic
, _FILE_RUNE_MAGIC_1
, sizeof (frl
->magic
))) {
107 runetype_ext_ranges
= (_FileRuneEntry
*)variable
;
108 variable
= runetype_ext_ranges
+ frl
->runetype_ext_nranges
;
109 if (variable
> lastp
) {
113 maplower_ext_ranges
= (_FileRuneEntry
*)variable
;
114 variable
= maplower_ext_ranges
+ frl
->maplower_ext_nranges
;
115 if (variable
> lastp
) {
119 mapupper_ext_ranges
= (_FileRuneEntry
*)variable
;
120 variable
= mapupper_ext_ranges
+ frl
->mapupper_ext_nranges
;
121 if (variable
> lastp
) {
125 frr
= runetype_ext_ranges
;
126 for (x
= 0; x
< frl
->runetype_ext_nranges
; ++x
) {
129 if (frr
[x
].map
== 0) {
130 int len
= frr
[x
].max
- frr
[x
].min
+ 1;
132 variable
= types
+ len
;
133 runetype_ext_len
+= len
;
134 if (variable
> lastp
) {
140 if ((char *)variable
+ frl
->variable_len
> (char *)lastp
) {
145 * Convert from disk format to host format.
147 data
= malloc(sizeof(_RuneLocale
) +
148 (frl
->runetype_ext_nranges
+ frl
->maplower_ext_nranges
+
149 frl
->mapupper_ext_nranges
) * sizeof(_RuneEntry
) +
150 runetype_ext_len
* sizeof(*rr
->__types
) +
154 (void) munmap(fdata
, sb
.st_size
);
159 rl
= (_RuneLocale
*)(void *)data
;
160 rl
->__variable
= rl
+ 1;
162 (void) memcpy(rl
->__magic
, _RUNE_MAGIC_1
, sizeof (rl
->__magic
));
163 (void) memcpy(rl
->__encoding
, frl
->encoding
, sizeof (rl
->__encoding
));
165 rl
->__variable_len
= frl
->variable_len
;
166 rl
->__runetype_ext
.__nranges
= frl
->runetype_ext_nranges
;
167 rl
->__maplower_ext
.__nranges
= frl
->maplower_ext_nranges
;
168 rl
->__mapupper_ext
.__nranges
= frl
->mapupper_ext_nranges
;
170 for (x
= 0; x
< _CACHED_RUNES
; ++x
) {
171 rl
->__runetype
[x
] = frl
->runetype
[x
];
172 rl
->__maplower
[x
] = frl
->maplower
[x
];
173 rl
->__mapupper
[x
] = frl
->mapupper
[x
];
176 rl
->__runetype_ext
.__ranges
= (_RuneEntry
*)rl
->__variable
;
177 rl
->__variable
= rl
->__runetype_ext
.__ranges
+
178 rl
->__runetype_ext
.__nranges
;
180 rl
->__maplower_ext
.__ranges
= (_RuneEntry
*)rl
->__variable
;
181 rl
->__variable
= rl
->__maplower_ext
.__ranges
+
182 rl
->__maplower_ext
.__nranges
;
184 rl
->__mapupper_ext
.__ranges
= (_RuneEntry
*)rl
->__variable
;
185 rl
->__variable
= rl
->__mapupper_ext
.__ranges
+
186 rl
->__mapupper_ext
.__nranges
;
188 variable
= mapupper_ext_ranges
+ frl
->mapupper_ext_nranges
;
189 frr
= runetype_ext_ranges
;
190 rr
= rl
->__runetype_ext
.__ranges
;
191 for (x
= 0; x
< rl
->__runetype_ext
.__nranges
; ++x
) {
194 rr
[x
].__min
= frr
[x
].min
;
195 rr
[x
].__max
= frr
[x
].max
;
196 rr
[x
].__map
= frr
[x
].map
;
197 if (rr
[x
].__map
== 0) {
198 int len
= rr
[x
].__max
- rr
[x
].__min
+ 1;
200 variable
= types
+ len
;
201 rr
[x
].__types
= rl
->__variable
;
202 rl
->__variable
= rr
[x
].__types
+ len
;
204 rr
[x
].__types
[len
] = types
[len
];
206 rr
[x
].__types
= NULL
;
209 frr
= maplower_ext_ranges
;
210 rr
= rl
->__maplower_ext
.__ranges
;
211 for (x
= 0; x
< rl
->__maplower_ext
.__nranges
; ++x
) {
212 rr
[x
].__min
= frr
[x
].min
;
213 rr
[x
].__max
= frr
[x
].max
;
214 rr
[x
].__map
= frr
[x
].map
;
217 frr
= mapupper_ext_ranges
;
218 rr
= rl
->__mapupper_ext
.__ranges
;
219 for (x
= 0; x
< rl
->__mapupper_ext
.__nranges
; ++x
) {
220 rr
[x
].__min
= frr
[x
].min
;
221 rr
[x
].__max
= frr
[x
].max
;
222 rr
[x
].__map
= frr
[x
].map
;
225 (void) memcpy(rl
->__variable
, variable
, rl
->__variable_len
);
226 (void) munmap(fdata
, sb
.st_size
);
229 * Go out and zero pointers that should be zero.
231 if (!rl
->__variable_len
)
232 rl
->__variable
= NULL
;
234 if (!rl
->__runetype_ext
.__nranges
)
235 rl
->__runetype_ext
.__ranges
= NULL
;
237 if (!rl
->__maplower_ext
.__nranges
)
238 rl
->__maplower_ext
.__ranges
= NULL
;
240 if (!rl
->__mapupper_ext
.__nranges
)
241 rl
->__mapupper_ext
.__ranges
= NULL
;
246 (void) munmap(fdata
, sb
.st_size
);