rune.c revision 11695
1/*-
2 * Copyright (c) 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Paul Borman at Krystal Technologies.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by the University of
19 *	California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if defined(LIBC_SCCS) && !defined(lint)
38static char sccsid[] = "@(#)rune.c	8.1 (Berkeley) 6/4/93";
39#endif /* LIBC_SCCS and not lint */
40
41#include <rune.h>
42#include <stdio.h>
43#include <string.h>
44#include <stdlib.h>
45#include <sys/types.h>
46#include <sys/stat.h>
47
48void
49setinvalidrune(ir)
50	rune_t ir;
51{
52	_INVALID_RUNE = ir;
53}
54
55_RuneLocale *
56_Read_RuneMagi(fp)
57	FILE *fp;
58{
59	char *data;
60	void *lastp;
61	_RuneLocale *rl;
62	_RuneEntry *rr;
63	struct stat sb;
64	int x;
65
66	if (fstat(fileno(fp), &sb) < 0)
67		return(0);
68
69	if (sb.st_size < sizeof(_RuneLocale))
70		return(0);
71
72	if ((data = malloc(sb.st_size)) == NULL)
73		return(0);
74
75	rewind(fp); /* Someone might have read the magic number once already */
76
77	if (fread(data, sb.st_size, 1, fp) != 1) {
78		free(data);
79		return(0);
80	}
81
82	rl = (_RuneLocale *)data;
83	lastp = data + sb.st_size;
84
85	rl->variable = rl + 1;
86
87	if (memcmp(rl->magic, _RUNE_MAGIC_1, sizeof(rl->magic))) {
88		free(data);
89		return(0);
90	}
91
92	rl->invalid_rune = ntohl(rl->invalid_rune);
93	rl->variable_len = ntohl(rl->variable_len);
94	rl->runetype_ext.nranges = ntohl(rl->runetype_ext.nranges);
95	rl->maplower_ext.nranges = ntohl(rl->maplower_ext.nranges);
96	rl->mapupper_ext.nranges = ntohl(rl->mapupper_ext.nranges);
97
98	for (x = 0; x < _CACHED_RUNES; ++x) {
99		rl->runetype[x] = ntohl(rl->runetype[x]);
100		rl->maplower[x] = ntohl(rl->maplower[x]);
101		rl->mapupper[x] = ntohl(rl->mapupper[x]);
102	}
103
104	rl->runetype_ext.ranges = (_RuneEntry *)rl->variable;
105	rl->variable = rl->runetype_ext.ranges + rl->runetype_ext.nranges;
106	if (rl->variable > lastp) {
107		free(data);
108		return(0);
109	}
110
111	rl->maplower_ext.ranges = (_RuneEntry *)rl->variable;
112	rl->variable = rl->maplower_ext.ranges + rl->maplower_ext.nranges;
113	if (rl->variable > lastp) {
114		free(data);
115		return(0);
116	}
117
118	rl->mapupper_ext.ranges = (_RuneEntry *)rl->variable;
119	rl->variable = rl->mapupper_ext.ranges + rl->mapupper_ext.nranges;
120	if (rl->variable > lastp) {
121		free(data);
122		return(0);
123	}
124
125	for (x = 0; x < rl->runetype_ext.nranges; ++x) {
126		rr = rl->runetype_ext.ranges;
127
128		rr[x].min = ntohl(rr[x].min);
129		rr[x].max = ntohl(rr[x].max);
130		if ((rr[x].map = ntohl(rr[x].map)) == 0) {
131			int len = rr[x].max - rr[x].min + 1;
132			rr[x].types = rl->variable;
133			rl->variable = rr[x].types + len;
134			if (rl->variable > lastp) {
135				free(data);
136				return(0);
137			}
138			while (len-- > 0)
139				rr[x].types[len] = ntohl(rr[x].types[len]);
140		} else
141			rr[x].types = 0;
142	}
143
144	for (x = 0; x < rl->maplower_ext.nranges; ++x) {
145		rr = rl->maplower_ext.ranges;
146
147		rr[x].min = ntohl(rr[x].min);
148		rr[x].max = ntohl(rr[x].max);
149		rr[x].map = ntohl(rr[x].map);
150	}
151
152	for (x = 0; x < rl->mapupper_ext.nranges; ++x) {
153		rr = rl->mapupper_ext.ranges;
154
155		rr[x].min = ntohl(rr[x].min);
156		rr[x].max = ntohl(rr[x].max);
157		rr[x].map = ntohl(rr[x].map);
158	}
159	if (((char *)rl->variable) + rl->variable_len > (char *)lastp) {
160		free(data);
161		return(0);
162	}
163
164	/*
165	 * Go out and zero pointers that should be zero.
166	 */
167	if (!rl->variable_len)
168		rl->variable = 0;
169
170	if (!rl->runetype_ext.nranges)
171		rl->runetype_ext.ranges = 0;
172
173	if (!rl->maplower_ext.nranges)
174		rl->maplower_ext.ranges = 0;
175
176	if (!rl->mapupper_ext.nranges)
177		rl->mapupper_ext.ranges = 0;
178
179	return(rl);
180}
181