rune.c revision 146261
1168404Spjd/*- 2168404Spjd * Copyright (c) 1993 3168404Spjd * The Regents of the University of California. All rights reserved. 4168404Spjd * 5168404Spjd * This code is derived from software contributed to Berkeley by 6168404Spjd * Paul Borman at Krystal Technologies. 7168404Spjd * 8168404Spjd * Redistribution and use in source and binary forms, with or without 9168404Spjd * modification, are permitted provided that the following conditions 10168404Spjd * are met: 11168404Spjd * 1. Redistributions of source code must retain the above copyright 12168404Spjd * notice, this list of conditions and the following disclaimer. 13168404Spjd * 2. Redistributions in binary form must reproduce the above copyright 14168404Spjd * notice, this list of conditions and the following disclaimer in the 15168404Spjd * documentation and/or other materials provided with the distribution. 16168404Spjd * 3. All advertising materials mentioning features or use of this software 17168404Spjd * must display the following acknowledgement: 18168404Spjd * This product includes software developed by the University of 19168404Spjd * California, Berkeley and its contributors. 20168404Spjd * 4. Neither the name of the University nor the names of its contributors 21168404Spjd * may be used to endorse or promote products derived from this software 22219089Spjd * without specific prior written permission. 23240415Smm * 24168404Spjd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25168404Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26169195Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27226732Smm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28169195Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29168404Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30168404Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31168404Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32168404Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33168404Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34168404Spjd * SUCH DAMAGE. 35168404Spjd */ 36168404Spjd 37185029Spjd#if defined(LIBC_SCCS) && !defined(lint) 38185029Spjdstatic char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93"; 39168404Spjd#endif /* LIBC_SCCS and not lint */ 40168404Spjd#include <sys/cdefs.h> 41168404Spjd__FBSDID("$FreeBSD: head/lib/libc/locale/rune.c 146261 2005-05-16 09:32:41Z ru $"); 42168404Spjd 43168404Spjd#include "namespace.h" 44168404Spjd#include <arpa/inet.h> 45168404Spjd#include <errno.h> 46168404Spjd#include <runetype.h> 47168404Spjd#include <stdio.h> 48168404Spjd#include <string.h> 49168404Spjd#include <stdlib.h> 50185029Spjd#include <sys/types.h> 51219089Spjd#include <sys/stat.h> 52168404Spjd#include "un-namespace.h" 53185029Spjd 54168404Spjd#include "runefile.h" 55168404Spjd 56168404Spjd_RuneLocale *_Read_RuneMagi(FILE *); 57168404Spjd 58168404Spjd_RuneLocale * 59168404Spjd_Read_RuneMagi(FILE *fp) 60168404Spjd{ 61219089Spjd char *fdata, *data; 62219089Spjd void *lastp; 63219089Spjd _FileRuneLocale *frl; 64168404Spjd _RuneLocale *rl; 65168404Spjd _FileRuneEntry *frr; 66185029Spjd _RuneEntry *rr; 67219089Spjd struct stat sb; 68185029Spjd int x, saverr; 69173268Slulf void *variable; 70173268Slulf _FileRuneEntry *runetype_ext_ranges; 71173268Slulf _FileRuneEntry *maplower_ext_ranges; 72173268Slulf _FileRuneEntry *mapupper_ext_ranges; 73168404Spjd int runetype_ext_len = 0; 74185029Spjd 75185029Spjd if (_fstat(fileno(fp), &sb) < 0) 76185029Spjd return (NULL); 77185029Spjd 78185029Spjd if ((size_t)sb.st_size < sizeof(_FileRuneLocale)) { 79185029Spjd errno = EFTYPE; 80185029Spjd return (NULL); 81185029Spjd } 82185029Spjd 83185029Spjd if ((fdata = malloc(sb.st_size)) == NULL) 84185029Spjd return (NULL); 85185029Spjd 86185029Spjd errno = 0; 87185029Spjd rewind(fp); /* Someone might have read the magic number once already */ 88168404Spjd if (errno) { 89168404Spjd saverr = errno; 90168404Spjd free(fdata); 91168404Spjd errno = saverr; 92168404Spjd return (NULL); 93210470Smm } 94210470Smm 95210470Smm if (fread(fdata, sb.st_size, 1, fp) != 1) { 96210470Smm saverr = errno; 97210470Smm free(fdata); 98210470Smm errno = saverr; 99185029Spjd return (NULL); 100168404Spjd } 101168404Spjd 102168404Spjd frl = (_FileRuneLocale *)fdata; 103185029Spjd lastp = fdata + sb.st_size; 104168404Spjd 105185029Spjd variable = frl + 1; 106185029Spjd 107185029Spjd if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof(frl->magic))) { 108185029Spjd free(fdata); 109185029Spjd errno = EFTYPE; 110168404Spjd return (NULL); 111168404Spjd } 112168404Spjd 113168404Spjd frl->variable_len = ntohl(frl->variable_len); 114209962Smm frl->runetype_ext_nranges = ntohl(frl->runetype_ext_nranges); 115168404Spjd frl->maplower_ext_nranges = ntohl(frl->maplower_ext_nranges); 116168404Spjd frl->mapupper_ext_nranges = ntohl(frl->mapupper_ext_nranges); 117168404Spjd 118168404Spjd for (x = 0; x < _CACHED_RUNES; ++x) { 119168404Spjd frl->runetype[x] = ntohl(frl->runetype[x]); 120168404Spjd frl->maplower[x] = ntohl(frl->maplower[x]); 121168404Spjd frl->mapupper[x] = ntohl(frl->mapupper[x]); 122219089Spjd } 123168404Spjd 124185029Spjd runetype_ext_ranges = (_FileRuneEntry *)variable; 125168404Spjd variable = runetype_ext_ranges + frl->runetype_ext_nranges; 126168404Spjd if (variable > lastp) { 127169196Spjd free(fdata); 128185029Spjd errno = EFTYPE; 129168404Spjd return (NULL); 130168404Spjd } 131185029Spjd 132185029Spjd maplower_ext_ranges = (_FileRuneEntry *)variable; 133185029Spjd variable = maplower_ext_ranges + frl->maplower_ext_nranges; 134199156Spjd if (variable > lastp) { 135199156Spjd free(fdata); 136199156Spjd errno = EFTYPE; 137199156Spjd return (NULL); 138199156Spjd } 139199156Spjd 140199156Spjd mapupper_ext_ranges = (_FileRuneEntry *)variable; 141199156Spjd variable = mapupper_ext_ranges + frl->mapupper_ext_nranges; 142199156Spjd if (variable > lastp) { 143219089Spjd free(fdata); 144199156Spjd errno = EFTYPE; 145199156Spjd return (NULL); 146199156Spjd } 147185029Spjd 148185029Spjd frr = runetype_ext_ranges; 149185029Spjd for (x = 0; x < frl->runetype_ext_nranges; ++x) { 150168404Spjd uint32_t *types; 151168404Spjd 152168404Spjd frr[x].min = ntohl(frr[x].min); 153168404Spjd frr[x].max = ntohl(frr[x].max); 154168404Spjd frr[x].map = ntohl(frr[x].map); 155168404Spjd if (frr[x].map == 0) { 156168404Spjd int len = frr[x].max - frr[x].min + 1; 157168404Spjd types = variable; 158168404Spjd variable = types + len; 159185029Spjd runetype_ext_len += len; 160211932Smm if (variable > lastp) { 161219089Spjd free(fdata); 162168404Spjd errno = EFTYPE; 163168404Spjd return (NULL); 164168404Spjd } 165168404Spjd while (len-- > 0) 166168404Spjd types[len] = ntohl(types[len]); 167185029Spjd } 168168404Spjd } 169168404Spjd 170168404Spjd frr = maplower_ext_ranges; 171185029Spjd for (x = 0; x < frl->maplower_ext_nranges; ++x) { 172185029Spjd frr[x].min = ntohl(frr[x].min); 173185029Spjd frr[x].max = ntohl(frr[x].max); 174185029Spjd frr[x].map = ntohl(frr[x].map); 175168404Spjd } 176168404Spjd 177168404Spjd frr = mapupper_ext_ranges; 178168404Spjd for (x = 0; x < frl->mapupper_ext_nranges; ++x) { 179185029Spjd frr[x].min = ntohl(frr[x].min); 180168404Spjd frr[x].max = ntohl(frr[x].max); 181168404Spjd frr[x].map = ntohl(frr[x].map); 182185029Spjd } 183211932Smm if ((char *)variable + frl->variable_len > (char *)lastp) { 184168404Spjd free(fdata); 185168404Spjd errno = EFTYPE; 186185029Spjd return (NULL); 187185029Spjd } 188185029Spjd 189210470Smm /* 190185029Spjd * Convert from disk format to host format. 191210470Smm */ 192185029Spjd data = malloc(sizeof(_RuneLocale) + 193185029Spjd (frl->runetype_ext_nranges + frl->maplower_ext_nranges + 194185029Spjd frl->mapupper_ext_nranges) * sizeof(_RuneEntry) + 195185029Spjd runetype_ext_len * sizeof(*rr->__types) + 196185029Spjd frl->variable_len); 197185029Spjd if (data == NULL) { 198219089Spjd saverr = errno; 199185029Spjd free(fdata); 200185029Spjd errno = saverr; 201185029Spjd return (NULL); 202185029Spjd } 203185029Spjd 204185029Spjd rl = (_RuneLocale *)data; 205185029Spjd rl->__variable = rl + 1; 206185029Spjd 207185029Spjd memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic)); 208185029Spjd memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding)); 209185029Spjd rl->__invalid_rune = 0; 210185029Spjd 211185029Spjd rl->__variable_len = frl->variable_len; 212185029Spjd rl->__runetype_ext.__nranges = frl->runetype_ext_nranges; 213185029Spjd rl->__maplower_ext.__nranges = frl->maplower_ext_nranges; 214185029Spjd rl->__mapupper_ext.__nranges = frl->mapupper_ext_nranges; 215185029Spjd 216185029Spjd for (x = 0; x < _CACHED_RUNES; ++x) { 217185029Spjd rl->__runetype[x] = frl->runetype[x]; 218185029Spjd rl->__maplower[x] = frl->maplower[x]; 219185029Spjd rl->__mapupper[x] = frl->mapupper[x]; 220185029Spjd } 221185029Spjd 222185029Spjd rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable; 223185029Spjd rl->__variable = rl->__runetype_ext.__ranges + 224185029Spjd rl->__runetype_ext.__nranges; 225219089Spjd 226219089Spjd rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable; 227219089Spjd rl->__variable = rl->__maplower_ext.__ranges + 228219089Spjd rl->__maplower_ext.__nranges; 229219089Spjd 230219089Spjd rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable; 231219089Spjd rl->__variable = rl->__mapupper_ext.__ranges + 232219089Spjd rl->__mapupper_ext.__nranges; 233219089Spjd 234185029Spjd variable = mapupper_ext_ranges + frl->mapupper_ext_nranges; 235211932Smm frr = runetype_ext_ranges; 236211932Smm rr = rl->__runetype_ext.__ranges; 237211932Smm for (x = 0; x < rl->__runetype_ext.__nranges; ++x) { 238211932Smm uint32_t *types; 239211932Smm 240211932Smm rr[x].__min = frr[x].min; 241211932Smm rr[x].__max = frr[x].max; 242211932Smm rr[x].__map = frr[x].map; 243211932Smm if (rr[x].__map == 0) { 244219089Spjd int len = rr[x].__max - rr[x].__min + 1; 245185029Spjd types = variable; 246185029Spjd variable = types + len; 247185029Spjd rr[x].__types = rl->__variable; 248185029Spjd rl->__variable = rr[x].__types + len; 249185029Spjd while (len-- > 0) 250185029Spjd rr[x].__types[len] = types[len]; 251185029Spjd } else 252219089Spjd rr[x].__types = NULL; 253185029Spjd } 254219089Spjd 255219089Spjd frr = maplower_ext_ranges; 256219089Spjd rr = rl->__maplower_ext.__ranges; 257219089Spjd for (x = 0; x < rl->__maplower_ext.__nranges; ++x) { 258219089Spjd rr[x].__min = frr[x].min; 259219089Spjd rr[x].__max = frr[x].max; 260185029Spjd rr[x].__map = frr[x].map; 261185029Spjd } 262185029Spjd 263185029Spjd frr = mapupper_ext_ranges; 264185029Spjd rr = rl->__mapupper_ext.__ranges; 265185029Spjd for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) { 266185029Spjd rr[x].__min = frr[x].min; 267185029Spjd rr[x].__max = frr[x].max; 268185029Spjd rr[x].__map = frr[x].map; 269185029Spjd } 270185029Spjd 271185029Spjd memcpy(rl->__variable, variable, rl->__variable_len); 272185029Spjd free(fdata); 273185029Spjd 274185029Spjd /* 275185029Spjd * Go out and zero pointers that should be zero. 276185029Spjd */ 277185029Spjd if (!rl->__variable_len) 278185029Spjd rl->__variable = NULL; 279185029Spjd 280185029Spjd if (!rl->__runetype_ext.__nranges) 281185029Spjd rl->__runetype_ext.__ranges = NULL; 282185029Spjd 283185029Spjd if (!rl->__maplower_ext.__nranges) 284185029Spjd rl->__maplower_ext.__ranges = NULL; 285210470Smm 286210470Smm if (!rl->__mapupper_ext.__nranges) 287210470Smm rl->__mapupper_ext.__ranges = NULL; 288210470Smm 289185029Spjd return (rl); 290210470Smm} 291210470Smm