158f0484fSRodney W. Grimes /*- 258f0484fSRodney W. Grimes * Copyright (c) 1993 358f0484fSRodney W. Grimes * The Regents of the University of California. All rights reserved. 458f0484fSRodney W. Grimes * 558f0484fSRodney W. Grimes * This code is derived from software contributed to Berkeley by 658f0484fSRodney W. Grimes * Paul Borman at Krystal Technologies. 758f0484fSRodney W. Grimes * 858f0484fSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 958f0484fSRodney W. Grimes * modification, are permitted provided that the following conditions 1058f0484fSRodney W. Grimes * are met: 1158f0484fSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 1258f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 1358f0484fSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 1458f0484fSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 1558f0484fSRodney W. Grimes * documentation and/or other materials provided with the distribution. 1658f0484fSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 1758f0484fSRodney W. Grimes * must display the following acknowledgement: 1858f0484fSRodney W. Grimes * This product includes software developed by the University of 1958f0484fSRodney W. Grimes * California, Berkeley and its contributors. 2058f0484fSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 2158f0484fSRodney W. Grimes * may be used to endorse or promote products derived from this software 2258f0484fSRodney W. Grimes * without specific prior written permission. 2358f0484fSRodney W. Grimes * 2458f0484fSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2558f0484fSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2658f0484fSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2758f0484fSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2858f0484fSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2958f0484fSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3058f0484fSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3158f0484fSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3258f0484fSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3358f0484fSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3458f0484fSRodney W. Grimes * SUCH DAMAGE. 3558f0484fSRodney W. Grimes */ 3658f0484fSRodney W. Grimes 3758f0484fSRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint) 3858f0484fSRodney W. Grimes static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93"; 3958f0484fSRodney W. Grimes #endif /* LIBC_SCCS and not lint */ 40333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 41333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 4258f0484fSRodney W. Grimes 43d201fe46SDaniel Eischen #include "namespace.h" 44fd8e4ebcSMike Barcroft #include <arpa/inet.h> 4576692b80SAndrey A. Chernov #include <errno.h> 46a0998ce6STim J. Robbins #include <runetype.h> 4758f0484fSRodney W. Grimes #include <stdio.h> 48350a3d3eSAndrey A. Chernov #include <string.h> 4958f0484fSRodney W. Grimes #include <stdlib.h> 50350a3d3eSAndrey A. Chernov #include <sys/types.h> 51350a3d3eSAndrey A. Chernov #include <sys/stat.h> 52d201fe46SDaniel Eischen #include "un-namespace.h" 5358f0484fSRodney W. Grimes 54228f8c4fSRuslan Ermilov #include "runefile.h" 55228f8c4fSRuslan Ermilov 563fb3a430SRuslan Ermilov _RuneLocale *_Read_RuneMagi(FILE *); 573fb3a430SRuslan Ermilov 58350a3d3eSAndrey A. Chernov _RuneLocale * 593fb3a430SRuslan Ermilov _Read_RuneMagi(FILE *fp) 60350a3d3eSAndrey A. Chernov { 613fb3a430SRuslan Ermilov char *fdata, *data; 62350a3d3eSAndrey A. Chernov void *lastp; 633fb3a430SRuslan Ermilov _FileRuneLocale *frl; 64350a3d3eSAndrey A. Chernov _RuneLocale *rl; 653fb3a430SRuslan Ermilov _FileRuneEntry *frr; 66350a3d3eSAndrey A. Chernov _RuneEntry *rr; 67350a3d3eSAndrey A. Chernov struct stat sb; 6876692b80SAndrey A. Chernov int x, saverr; 693fb3a430SRuslan Ermilov void *variable; 703fb3a430SRuslan Ermilov _FileRuneEntry *runetype_ext_ranges; 713fb3a430SRuslan Ermilov _FileRuneEntry *maplower_ext_ranges; 723fb3a430SRuslan Ermilov _FileRuneEntry *mapupper_ext_ranges; 733fb3a430SRuslan Ermilov int runetype_ext_len = 0; 74350a3d3eSAndrey A. Chernov 75d201fe46SDaniel Eischen if (_fstat(fileno(fp), &sb) < 0) 7676692b80SAndrey A. Chernov return (NULL); 77350a3d3eSAndrey A. Chernov 783fb3a430SRuslan Ermilov if ((size_t)sb.st_size < sizeof(_FileRuneLocale)) { 7976692b80SAndrey A. Chernov errno = EFTYPE; 8076692b80SAndrey A. Chernov return (NULL); 8176692b80SAndrey A. Chernov } 82350a3d3eSAndrey A. Chernov 833fb3a430SRuslan Ermilov if ((fdata = malloc(sb.st_size)) == NULL) 8476692b80SAndrey A. Chernov return (NULL); 85350a3d3eSAndrey A. Chernov 8676692b80SAndrey A. Chernov errno = 0; 87350a3d3eSAndrey A. Chernov rewind(fp); /* Someone might have read the magic number once already */ 8876692b80SAndrey A. Chernov if (errno) { 8976692b80SAndrey A. Chernov saverr = errno; 903fb3a430SRuslan Ermilov free(fdata); 9176692b80SAndrey A. Chernov errno = saverr; 9276692b80SAndrey A. Chernov return (NULL); 9376692b80SAndrey A. Chernov } 94350a3d3eSAndrey A. Chernov 953fb3a430SRuslan Ermilov if (fread(fdata, sb.st_size, 1, fp) != 1) { 9676692b80SAndrey A. Chernov saverr = errno; 973fb3a430SRuslan Ermilov free(fdata); 9876692b80SAndrey A. Chernov errno = saverr; 9976692b80SAndrey A. Chernov return (NULL); 100350a3d3eSAndrey A. Chernov } 101350a3d3eSAndrey A. Chernov 1023fb3a430SRuslan Ermilov frl = (_FileRuneLocale *)fdata; 1033fb3a430SRuslan Ermilov lastp = fdata + sb.st_size; 104350a3d3eSAndrey A. Chernov 1053fb3a430SRuslan Ermilov variable = frl + 1; 106350a3d3eSAndrey A. Chernov 1073fb3a430SRuslan Ermilov if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof(frl->magic))) { 1083fb3a430SRuslan Ermilov free(fdata); 10976692b80SAndrey A. Chernov errno = EFTYPE; 11076692b80SAndrey A. Chernov return (NULL); 111350a3d3eSAndrey A. Chernov } 112350a3d3eSAndrey A. Chernov 1133fb3a430SRuslan Ermilov frl->variable_len = ntohl(frl->variable_len); 1143fb3a430SRuslan Ermilov frl->runetype_ext_nranges = ntohl(frl->runetype_ext_nranges); 1153fb3a430SRuslan Ermilov frl->maplower_ext_nranges = ntohl(frl->maplower_ext_nranges); 1163fb3a430SRuslan Ermilov frl->mapupper_ext_nranges = ntohl(frl->mapupper_ext_nranges); 117350a3d3eSAndrey A. Chernov 118350a3d3eSAndrey A. Chernov for (x = 0; x < _CACHED_RUNES; ++x) { 1193fb3a430SRuslan Ermilov frl->runetype[x] = ntohl(frl->runetype[x]); 1203fb3a430SRuslan Ermilov frl->maplower[x] = ntohl(frl->maplower[x]); 1213fb3a430SRuslan Ermilov frl->mapupper[x] = ntohl(frl->mapupper[x]); 122350a3d3eSAndrey A. Chernov } 123350a3d3eSAndrey A. Chernov 1243fb3a430SRuslan Ermilov runetype_ext_ranges = (_FileRuneEntry *)variable; 1253fb3a430SRuslan Ermilov variable = runetype_ext_ranges + frl->runetype_ext_nranges; 1263fb3a430SRuslan Ermilov if (variable > lastp) { 1273fb3a430SRuslan Ermilov free(fdata); 12876692b80SAndrey A. Chernov errno = EFTYPE; 12976692b80SAndrey A. Chernov return (NULL); 130350a3d3eSAndrey A. Chernov } 131350a3d3eSAndrey A. Chernov 1323fb3a430SRuslan Ermilov maplower_ext_ranges = (_FileRuneEntry *)variable; 1333fb3a430SRuslan Ermilov variable = maplower_ext_ranges + frl->maplower_ext_nranges; 1343fb3a430SRuslan Ermilov if (variable > lastp) { 1353fb3a430SRuslan Ermilov free(fdata); 13676692b80SAndrey A. Chernov errno = EFTYPE; 13776692b80SAndrey A. Chernov return (NULL); 138350a3d3eSAndrey A. Chernov } 139350a3d3eSAndrey A. Chernov 1403fb3a430SRuslan Ermilov mapupper_ext_ranges = (_FileRuneEntry *)variable; 1413fb3a430SRuslan Ermilov variable = mapupper_ext_ranges + frl->mapupper_ext_nranges; 1423fb3a430SRuslan Ermilov if (variable > lastp) { 1433fb3a430SRuslan Ermilov free(fdata); 14476692b80SAndrey A. Chernov errno = EFTYPE; 14576692b80SAndrey A. Chernov return (NULL); 146350a3d3eSAndrey A. Chernov } 147350a3d3eSAndrey A. Chernov 1483fb3a430SRuslan Ermilov frr = runetype_ext_ranges; 1493fb3a430SRuslan Ermilov for (x = 0; x < frl->runetype_ext_nranges; ++x) { 1503fb3a430SRuslan Ermilov uint32_t *types; 151350a3d3eSAndrey A. Chernov 1523fb3a430SRuslan Ermilov frr[x].min = ntohl(frr[x].min); 1533fb3a430SRuslan Ermilov frr[x].max = ntohl(frr[x].max); 1543fb3a430SRuslan Ermilov frr[x].map = ntohl(frr[x].map); 1553fb3a430SRuslan Ermilov if (frr[x].map == 0) { 1563fb3a430SRuslan Ermilov int len = frr[x].max - frr[x].min + 1; 1573fb3a430SRuslan Ermilov types = variable; 1583fb3a430SRuslan Ermilov variable = types + len; 1593fb3a430SRuslan Ermilov runetype_ext_len += len; 1603fb3a430SRuslan Ermilov if (variable > lastp) { 1613fb3a430SRuslan Ermilov free(fdata); 16276692b80SAndrey A. Chernov errno = EFTYPE; 16376692b80SAndrey A. Chernov return (NULL); 164350a3d3eSAndrey A. Chernov } 165350a3d3eSAndrey A. Chernov while (len-- > 0) 1663fb3a430SRuslan Ermilov types[len] = ntohl(types[len]); 1673fb3a430SRuslan Ermilov } 168350a3d3eSAndrey A. Chernov } 169350a3d3eSAndrey A. Chernov 1703fb3a430SRuslan Ermilov frr = maplower_ext_ranges; 1713fb3a430SRuslan Ermilov for (x = 0; x < frl->maplower_ext_nranges; ++x) { 1723fb3a430SRuslan Ermilov frr[x].min = ntohl(frr[x].min); 1733fb3a430SRuslan Ermilov frr[x].max = ntohl(frr[x].max); 1743fb3a430SRuslan Ermilov frr[x].map = ntohl(frr[x].map); 175350a3d3eSAndrey A. Chernov } 176350a3d3eSAndrey A. Chernov 1773fb3a430SRuslan Ermilov frr = mapupper_ext_ranges; 1783fb3a430SRuslan Ermilov for (x = 0; x < frl->mapupper_ext_nranges; ++x) { 1793fb3a430SRuslan Ermilov frr[x].min = ntohl(frr[x].min); 1803fb3a430SRuslan Ermilov frr[x].max = ntohl(frr[x].max); 1813fb3a430SRuslan Ermilov frr[x].map = ntohl(frr[x].map); 182350a3d3eSAndrey A. Chernov } 1833fb3a430SRuslan Ermilov if ((char *)variable + frl->variable_len > (char *)lastp) { 1843fb3a430SRuslan Ermilov free(fdata); 18576692b80SAndrey A. Chernov errno = EFTYPE; 18676692b80SAndrey A. Chernov return (NULL); 187350a3d3eSAndrey A. Chernov } 188350a3d3eSAndrey A. Chernov 189350a3d3eSAndrey A. Chernov /* 1903fb3a430SRuslan Ermilov * Convert from disk format to host format. 1913fb3a430SRuslan Ermilov */ 1923fb3a430SRuslan Ermilov data = malloc(sizeof(_RuneLocale) + 1933fb3a430SRuslan Ermilov (frl->runetype_ext_nranges + frl->maplower_ext_nranges + 1943fb3a430SRuslan Ermilov frl->mapupper_ext_nranges) * sizeof(_RuneEntry) + 1953fb3a430SRuslan Ermilov runetype_ext_len * sizeof(*rr->__types) + 1963fb3a430SRuslan Ermilov frl->variable_len); 1973fb3a430SRuslan Ermilov if (data == NULL) { 1983fb3a430SRuslan Ermilov saverr = errno; 1993fb3a430SRuslan Ermilov free(fdata); 2003fb3a430SRuslan Ermilov errno = saverr; 2013fb3a430SRuslan Ermilov return (NULL); 2023fb3a430SRuslan Ermilov } 2033fb3a430SRuslan Ermilov 2043fb3a430SRuslan Ermilov rl = (_RuneLocale *)data; 2053fb3a430SRuslan Ermilov rl->__variable = rl + 1; 2063fb3a430SRuslan Ermilov 2073fb3a430SRuslan Ermilov memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic)); 2083fb3a430SRuslan Ermilov memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding)); 2093fb3a430SRuslan Ermilov rl->__invalid_rune = 0; 2103fb3a430SRuslan Ermilov 2113fb3a430SRuslan Ermilov rl->__variable_len = frl->variable_len; 2123fb3a430SRuslan Ermilov rl->__runetype_ext.__nranges = frl->runetype_ext_nranges; 2133fb3a430SRuslan Ermilov rl->__maplower_ext.__nranges = frl->maplower_ext_nranges; 2143fb3a430SRuslan Ermilov rl->__mapupper_ext.__nranges = frl->mapupper_ext_nranges; 2153fb3a430SRuslan Ermilov 2163fb3a430SRuslan Ermilov for (x = 0; x < _CACHED_RUNES; ++x) { 2173fb3a430SRuslan Ermilov rl->__runetype[x] = frl->runetype[x]; 2183fb3a430SRuslan Ermilov rl->__maplower[x] = frl->maplower[x]; 2193fb3a430SRuslan Ermilov rl->__mapupper[x] = frl->mapupper[x]; 2203fb3a430SRuslan Ermilov } 2213fb3a430SRuslan Ermilov 2223fb3a430SRuslan Ermilov rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable; 2233fb3a430SRuslan Ermilov rl->__variable = rl->__runetype_ext.__ranges + 2243fb3a430SRuslan Ermilov rl->__runetype_ext.__nranges; 2253fb3a430SRuslan Ermilov 2263fb3a430SRuslan Ermilov rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable; 2273fb3a430SRuslan Ermilov rl->__variable = rl->__maplower_ext.__ranges + 2283fb3a430SRuslan Ermilov rl->__maplower_ext.__nranges; 2293fb3a430SRuslan Ermilov 2303fb3a430SRuslan Ermilov rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable; 2313fb3a430SRuslan Ermilov rl->__variable = rl->__mapupper_ext.__ranges + 2323fb3a430SRuslan Ermilov rl->__mapupper_ext.__nranges; 2333fb3a430SRuslan Ermilov 2343fb3a430SRuslan Ermilov variable = mapupper_ext_ranges + frl->mapupper_ext_nranges; 2353fb3a430SRuslan Ermilov frr = runetype_ext_ranges; 2363fb3a430SRuslan Ermilov rr = rl->__runetype_ext.__ranges; 2373fb3a430SRuslan Ermilov for (x = 0; x < rl->__runetype_ext.__nranges; ++x) { 2383fb3a430SRuslan Ermilov uint32_t *types; 2393fb3a430SRuslan Ermilov 2403fb3a430SRuslan Ermilov rr[x].__min = frr[x].min; 2413fb3a430SRuslan Ermilov rr[x].__max = frr[x].max; 2423fb3a430SRuslan Ermilov rr[x].__map = frr[x].map; 2433fb3a430SRuslan Ermilov if (rr[x].__map == 0) { 2443fb3a430SRuslan Ermilov int len = rr[x].__max - rr[x].__min + 1; 2453fb3a430SRuslan Ermilov types = variable; 2463fb3a430SRuslan Ermilov variable = types + len; 2473fb3a430SRuslan Ermilov rr[x].__types = rl->__variable; 2483fb3a430SRuslan Ermilov rl->__variable = rr[x].__types + len; 2493fb3a430SRuslan Ermilov while (len-- > 0) 2503fb3a430SRuslan Ermilov rr[x].__types[len] = types[len]; 2513fb3a430SRuslan Ermilov } else 2523fb3a430SRuslan Ermilov rr[x].__types = NULL; 2533fb3a430SRuslan Ermilov } 2543fb3a430SRuslan Ermilov 2553fb3a430SRuslan Ermilov frr = maplower_ext_ranges; 2563fb3a430SRuslan Ermilov rr = rl->__maplower_ext.__ranges; 2573fb3a430SRuslan Ermilov for (x = 0; x < rl->__maplower_ext.__nranges; ++x) { 2583fb3a430SRuslan Ermilov rr[x].__min = frr[x].min; 2593fb3a430SRuslan Ermilov rr[x].__max = frr[x].max; 2603fb3a430SRuslan Ermilov rr[x].__map = frr[x].map; 2613fb3a430SRuslan Ermilov } 2623fb3a430SRuslan Ermilov 2633fb3a430SRuslan Ermilov frr = mapupper_ext_ranges; 2643fb3a430SRuslan Ermilov rr = rl->__mapupper_ext.__ranges; 2653fb3a430SRuslan Ermilov for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) { 2663fb3a430SRuslan Ermilov rr[x].__min = frr[x].min; 2673fb3a430SRuslan Ermilov rr[x].__max = frr[x].max; 2683fb3a430SRuslan Ermilov rr[x].__map = frr[x].map; 2693fb3a430SRuslan Ermilov } 2703fb3a430SRuslan Ermilov 2713fb3a430SRuslan Ermilov memcpy(rl->__variable, variable, rl->__variable_len); 2723fb3a430SRuslan Ermilov free(fdata); 2733fb3a430SRuslan Ermilov 2743fb3a430SRuslan Ermilov /* 275350a3d3eSAndrey A. Chernov * Go out and zero pointers that should be zero. 276350a3d3eSAndrey A. Chernov */ 277ddc1ededSTim J. Robbins if (!rl->__variable_len) 2783fb3a430SRuslan Ermilov rl->__variable = NULL; 279350a3d3eSAndrey A. Chernov 280ddc1ededSTim J. Robbins if (!rl->__runetype_ext.__nranges) 2813fb3a430SRuslan Ermilov rl->__runetype_ext.__ranges = NULL; 282350a3d3eSAndrey A. Chernov 283ddc1ededSTim J. Robbins if (!rl->__maplower_ext.__nranges) 2843fb3a430SRuslan Ermilov rl->__maplower_ext.__ranges = NULL; 285350a3d3eSAndrey A. Chernov 286ddc1ededSTim J. Robbins if (!rl->__mapupper_ext.__nranges) 2873fb3a430SRuslan Ermilov rl->__mapupper_ext.__ranges = NULL; 288350a3d3eSAndrey A. Chernov 289350a3d3eSAndrey A. Chernov return (rl); 290350a3d3eSAndrey A. Chernov } 291