110015Speter/*-
212496Speter * Copyright (c) 1993
310015Speter *	The Regents of the University of California.  All rights reserved.
434832Speter *
510015Speter * This code is derived from software contributed to Berkeley by
656505Speter * Paul Borman at Krystal Technologies.
710015Speter *
810015Speter * Redistribution and use in source and binary forms, with or without
910015Speter * modification, are permitted provided that the following conditions
1010015Speter * are met:
1110015Speter * 1. Redistributions of source code must retain the above copyright
1210015Speter *    notice, this list of conditions and the following disclaimer.
1310015Speter * 2. Redistributions in binary form must reproduce the above copyright
1410015Speter *    notice, this list of conditions and the following disclaimer in the
1510015Speter *    documentation and/or other materials provided with the distribution.
1610015Speter * 4. Neither the name of the University nor the names of its contributors
1710015Speter *    may be used to endorse or promote products derived from this software
1810015Speter *    without specific prior written permission.
1910015Speter *
2010015Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2110015Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2210015Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2310015Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2410015Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2510015Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2610015Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2710015Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2810015Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2910015Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3010015Speter * SUCH DAMAGE.
3110015Speter */
3210015Speter
3310015Speter#if defined(LIBC_SCCS) && !defined(lint)
3410015Speterstatic char sccsid[] = "@(#)rune.c	8.1 (Berkeley) 6/4/93";
35119419Sobrien#endif /* LIBC_SCCS and not lint */
36119419Sobrien#include <sys/cdefs.h>
37119419Sobrien__FBSDID("$FreeBSD$");
3810015Speter
3934832Speter#include "namespace.h"
4034832Speter#include <arpa/inet.h>
4156505Speter#include <errno.h>
4210015Speter#include <runetype.h>
4310015Speter#include <stdio.h>
4431778Seivind#include <string.h>
4532929Seivind#include <stdlib.h>
46111899Sdas#include <sys/types.h>
4731778Seivind#include <sys/stat.h>
4810015Speter#include "un-namespace.h"
4910015Speter
5024207Sbde#include "runefile.h"
5124207Sbde
5224207Sbde_RuneLocale *_Read_RuneMagi(FILE *);
5310015Speter
5410015Speter_RuneLocale *
5524131Sbde_Read_RuneMagi(FILE *fp)
5610015Speter{
5710015Speter	char *fdata, *data;
5815683Speter	void *lastp;
5956498Speter	_FileRuneLocale *frl;
6056498Speter	_RuneLocale *rl;
6156498Speter	_FileRuneEntry *frr;
6256498Speter	_RuneEntry *rr;
6310015Speter	struct stat sb;
6410015Speter	int x, saverr;
6512659Sbde	void *variable;
6612662Sdg	_FileRuneEntry *runetype_ext_ranges;
6712659Sbde	_FileRuneEntry *maplower_ext_ranges;
6813353Speter	_FileRuneEntry *mapupper_ext_ranges;
6910015Speter	int runetype_ext_len = 0;
7056498Speter
7156505Speter	if (_fstat(fileno(fp), &sb) < 0)
7256498Speter		return (NULL);
7356498Speter
7410015Speter	if ((size_t)sb.st_size < sizeof(_FileRuneLocale)) {
7510015Speter		errno = EFTYPE;
7634832Speter		return (NULL);
7734832Speter	}
7810015Speter
7934832Speter	if ((fdata = malloc(sb.st_size)) == NULL)
8034832Speter		return (NULL);
8133395Speter
8234832Speter	errno = 0;
8310015Speter	rewind(fp); /* Someone might have read the magic number once already */
8410015Speter	if (errno) {
8517547Speter		saverr = errno;
8617547Speter		free(fdata);
8717547Speter		errno = saverr;
8812496Speter		return (NULL);
8934832Speter	}
9034832Speter
9115639Speter	if (fread(fdata, sb.st_size, 1, fp) != 1) {
9210015Speter		saverr = errno;
9310015Speter		free(fdata);
9410015Speter		errno = saverr;
9556498Speter		return (NULL);
9656498Speter	}
9756498Speter
9883366Sjulian	frl = (_FileRuneLocale *)fdata;
9956498Speter	lastp = fdata + sb.st_size;
10056498Speter
10125047Sbde	variable = frl + 1;
10256498Speter
10356498Speter	if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof(frl->magic))) {
10456498Speter		free(fdata);
10510015Speter		errno = EFTYPE;
10656505Speter		return (NULL);
10756505Speter	}
10856505Speter
10956505Speter	frl->variable_len = ntohl(frl->variable_len);
11056498Speter	frl->runetype_ext_nranges = ntohl(frl->runetype_ext_nranges);
11110015Speter	frl->maplower_ext_nranges = ntohl(frl->maplower_ext_nranges);
11256498Speter	frl->mapupper_ext_nranges = ntohl(frl->mapupper_ext_nranges);
11356498Speter
11410708Speter	for (x = 0; x < _CACHED_RUNES; ++x) {
11512675Sjulian		frl->runetype[x] = ntohl(frl->runetype[x]);
11612675Sjulian		frl->maplower[x] = ntohl(frl->maplower[x]);
11712675Sjulian		frl->mapupper[x] = ntohl(frl->mapupper[x]);
11812675Sjulian	}
11912675Sjulian
12047625Sphk	runetype_ext_ranges = (_FileRuneEntry *)variable;
121126080Sphk	variable = runetype_ext_ranges + frl->runetype_ext_nranges;
122111815Sphk	if (variable > lastp) {
123111815Sphk		free(fdata);
124111815Sphk		errno = EFTYPE;
125111815Sphk		return (NULL);
126111815Sphk	}
127126080Sphk
12838485Sbde	maplower_ext_ranges = (_FileRuneEntry *)variable;
12912675Sjulian	variable = maplower_ext_ranges + frl->maplower_ext_nranges;
13010962Speter	if (variable > lastp) {
13110962Speter		free(fdata);
13210962Speter		errno = EFTYPE;
13310015Speter		return (NULL);
13434832Speter	}
135100743Speter
13634832Speter	mapupper_ext_ranges = (_FileRuneEntry *)variable;
13756498Speter	variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
13810044Speter	if (variable > lastp) {
13956505Speter		free(fdata);
14056498Speter		errno = EFTYPE;
14112174Speter		return (NULL);
14210015Speter	}
14310015Speter
14410015Speter	frr = runetype_ext_ranges;
14550442Speter	for (x = 0; x < frl->runetype_ext_nranges; ++x) {
14650442Speter		uint32_t *types;
14750442Speter
14850442Speter		frr[x].min = ntohl(frr[x].min);
14950442Speter		frr[x].max = ntohl(frr[x].max);
15050442Speter		frr[x].map = ntohl(frr[x].map);
15150442Speter		if (frr[x].map == 0) {
15250442Speter			int len = frr[x].max - frr[x].min + 1;
15350442Speter			types = variable;
15450442Speter			variable = types + len;
15550442Speter			runetype_ext_len += len;
15650442Speter			if (variable > lastp) {
15750442Speter				free(fdata);
15850442Speter				errno = EFTYPE;
15950442Speter				return (NULL);
16010015Speter			}
16110015Speter			while (len-- > 0)
16210015Speter				types[len] = ntohl(types[len]);
16310015Speter		}
16410015Speter	}
16510015Speter
16610015Speter	frr = maplower_ext_ranges;
16750442Speter	for (x = 0; x < frl->maplower_ext_nranges; ++x) {
16850442Speter		frr[x].min = ntohl(frr[x].min);
16950442Speter		frr[x].max = ntohl(frr[x].max);
17050442Speter		frr[x].map = ntohl(frr[x].map);
17150442Speter	}
17250442Speter
17350442Speter	frr = mapupper_ext_ranges;
17450442Speter	for (x = 0; x < frl->mapupper_ext_nranges; ++x) {
17550442Speter		frr[x].min = ntohl(frr[x].min);
17650442Speter		frr[x].max = ntohl(frr[x].max);
17750442Speter		frr[x].map = ntohl(frr[x].map);
17850442Speter	}
17950442Speter	if ((char *)variable + frl->variable_len > (char *)lastp) {
18050442Speter		free(fdata);
18150442Speter		errno = EFTYPE;
18210015Speter		return (NULL);
18310015Speter	}
18410015Speter
18510015Speter	/*
18615683Speter	 * Convert from disk format to host format.
18756498Speter	 */
18815639Speter	data = malloc(sizeof(_RuneLocale) +
18916403Speter	    (frl->runetype_ext_nranges + frl->maplower_ext_nranges +
19017547Speter	    frl->mapupper_ext_nranges) * sizeof(_RuneEntry) +
19150442Speter	    runetype_ext_len * sizeof(*rr->__types) +
19210015Speter	    frl->variable_len);
19356498Speter	if (data == NULL) {
19410015Speter		saverr = errno;
19510015Speter		free(fdata);
19610015Speter		errno = saverr;
19710015Speter		return (NULL);
19810015Speter	}
19910015Speter
20010015Speter	rl = (_RuneLocale *)data;
20110015Speter	rl->__variable = rl + 1;
20210015Speter
20334832Speter	memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic));
20410015Speter	memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding));
20510015Speter	rl->__invalid_rune = 0;
20633395Speter
20733395Speter	rl->__variable_len = frl->variable_len;
20833395Speter	rl->__runetype_ext.__nranges = frl->runetype_ext_nranges;
20910015Speter	rl->__maplower_ext.__nranges = frl->maplower_ext_nranges;
21010015Speter	rl->__mapupper_ext.__nranges = frl->mapupper_ext_nranges;
21156498Speter
21256498Speter	for (x = 0; x < _CACHED_RUNES; ++x) {
21356498Speter		rl->__runetype[x] = frl->runetype[x];
21456498Speter		rl->__maplower[x] = frl->maplower[x];
21556498Speter		rl->__mapupper[x] = frl->mapupper[x];
21656498Speter	}
21756498Speter
21856498Speter	rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
21956498Speter	rl->__variable = rl->__runetype_ext.__ranges +
22056498Speter	    rl->__runetype_ext.__nranges;
22156498Speter
22256498Speter	rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable;
22356498Speter	rl->__variable = rl->__maplower_ext.__ranges +
22456498Speter	    rl->__maplower_ext.__nranges;
22556498Speter
22656498Speter	rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable;
22756498Speter	rl->__variable = rl->__mapupper_ext.__ranges +
22856498Speter	    rl->__mapupper_ext.__nranges;
22956498Speter
23056498Speter	variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
23156498Speter	frr = runetype_ext_ranges;
23256498Speter	rr = rl->__runetype_ext.__ranges;
23356498Speter	for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
23456498Speter		uint32_t *types;
23534832Speter
23610015Speter		rr[x].__min = frr[x].min;
23710015Speter		rr[x].__max = frr[x].max;
23856505Speter		rr[x].__map = frr[x].map;
23956498Speter		if (rr[x].__map == 0) {
24010015Speter			int len = rr[x].__max - rr[x].__min + 1;
24156498Speter			types = variable;
24256498Speter			variable = types + len;
24310015Speter			rr[x].__types = rl->__variable;
24410015Speter			rl->__variable = rr[x].__types + len;
24510015Speter			while (len-- > 0)
24610015Speter				rr[x].__types[len] = types[len];
24710015Speter		} else
24810015Speter			rr[x].__types = NULL;
24910015Speter	}
25012174Speter
25110015Speter	frr = maplower_ext_ranges;
25256498Speter	rr = rl->__maplower_ext.__ranges;
25356498Speter	for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
25410015Speter		rr[x].__min = frr[x].min;
25556505Speter		rr[x].__max = frr[x].max;
25656505Speter		rr[x].__map = frr[x].map;
25756505Speter	}
25856505Speter
25956498Speter	frr = mapupper_ext_ranges;
26010015Speter	rr = rl->__mapupper_ext.__ranges;
26156498Speter	for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
26256498Speter		rr[x].__min = frr[x].min;
26356498Speter		rr[x].__max = frr[x].max;
26456498Speter		rr[x].__map = frr[x].map;
26556498Speter	}
26656498Speter
26756498Speter	memcpy(rl->__variable, variable, rl->__variable_len);
26856498Speter	free(fdata);
26956498Speter
27033395Speter	/*
27133395Speter	 * Go out and zero pointers that should be zero.
27233395Speter	 */
27310015Speter	if (!rl->__variable_len)
27410015Speter		rl->__variable = NULL;
27510015Speter
27610015Speter	if (!rl->__runetype_ext.__nranges)
27734832Speter		rl->__runetype_ext.__ranges = NULL;
27834832Speter
27934832Speter	if (!rl->__maplower_ext.__nranges)
28034832Speter		rl->__maplower_ext.__ranges = NULL;
28156498Speter
28234832Speter	if (!rl->__mapupper_ext.__nranges)
28334832Speter		rl->__mapupper_ext.__ranges = NULL;
28434832Speter
28534832Speter	return (rl);
28634832Speter}
28734832Speter