xref: /freebsd/lib/libc/locale/rune.c (revision d201fe46)
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.
35d201fe46SDaniel Eischen  *
36d201fe46SDaniel Eischen  * $FreeBSD$
3758f0484fSRodney W. Grimes  */
3858f0484fSRodney W. Grimes 
3958f0484fSRodney W. Grimes #if defined(LIBC_SCCS) && !defined(lint)
4058f0484fSRodney W. Grimes static char sccsid[] = "@(#)rune.c	8.1 (Berkeley) 6/4/93";
4158f0484fSRodney W. Grimes #endif /* LIBC_SCCS and not lint */
4258f0484fSRodney W. Grimes 
43d201fe46SDaniel Eischen #include "namespace.h"
4458f0484fSRodney W. Grimes #include <rune.h>
4558f0484fSRodney W. Grimes #include <stdio.h>
46350a3d3eSAndrey A. Chernov #include <string.h>
4758f0484fSRodney W. Grimes #include <stdlib.h>
48350a3d3eSAndrey A. Chernov #include <sys/types.h>
49350a3d3eSAndrey A. Chernov #include <sys/stat.h>
50d201fe46SDaniel Eischen #include "un-namespace.h"
5158f0484fSRodney W. Grimes 
52350a3d3eSAndrey A. Chernov _RuneLocale *
53350a3d3eSAndrey A. Chernov _Read_RuneMagi(fp)
54350a3d3eSAndrey A. Chernov 	FILE *fp;
55350a3d3eSAndrey A. Chernov {
56350a3d3eSAndrey A. Chernov 	char *data;
57350a3d3eSAndrey A. Chernov 	void *lastp;
58350a3d3eSAndrey A. Chernov 	_RuneLocale *rl;
59350a3d3eSAndrey A. Chernov 	_RuneEntry *rr;
60350a3d3eSAndrey A. Chernov 	struct stat sb;
61350a3d3eSAndrey A. Chernov 	int x;
62350a3d3eSAndrey A. Chernov 
63d201fe46SDaniel Eischen 	if (_fstat(fileno(fp), &sb) < 0)
64350a3d3eSAndrey A. Chernov 		return(0);
65350a3d3eSAndrey A. Chernov 
66350a3d3eSAndrey A. Chernov 	if (sb.st_size < sizeof(_RuneLocale))
67350a3d3eSAndrey A. Chernov 		return(0);
68350a3d3eSAndrey A. Chernov 
69350a3d3eSAndrey A. Chernov 	if ((data = malloc(sb.st_size)) == NULL)
70350a3d3eSAndrey A. Chernov 		return(0);
71350a3d3eSAndrey A. Chernov 
72350a3d3eSAndrey A. Chernov 	rewind(fp); /* Someone might have read the magic number once already */
73350a3d3eSAndrey A. Chernov 
74350a3d3eSAndrey A. Chernov 	if (fread(data, sb.st_size, 1, fp) != 1) {
75350a3d3eSAndrey A. Chernov 		free(data);
76350a3d3eSAndrey A. Chernov 		return(0);
77350a3d3eSAndrey A. Chernov 	}
78350a3d3eSAndrey A. Chernov 
79350a3d3eSAndrey A. Chernov 	rl = (_RuneLocale *)data;
80350a3d3eSAndrey A. Chernov 	lastp = data + sb.st_size;
81350a3d3eSAndrey A. Chernov 
82350a3d3eSAndrey A. Chernov 	rl->variable = rl + 1;
83350a3d3eSAndrey A. Chernov 
84350a3d3eSAndrey A. Chernov 	if (memcmp(rl->magic, _RUNE_MAGIC_1, sizeof(rl->magic))) {
85350a3d3eSAndrey A. Chernov 		free(data);
86350a3d3eSAndrey A. Chernov 		return(0);
87350a3d3eSAndrey A. Chernov 	}
88350a3d3eSAndrey A. Chernov 
89350a3d3eSAndrey A. Chernov 	rl->invalid_rune = ntohl(rl->invalid_rune);
90350a3d3eSAndrey A. Chernov 	rl->variable_len = ntohl(rl->variable_len);
91350a3d3eSAndrey A. Chernov 	rl->runetype_ext.nranges = ntohl(rl->runetype_ext.nranges);
92350a3d3eSAndrey A. Chernov 	rl->maplower_ext.nranges = ntohl(rl->maplower_ext.nranges);
93350a3d3eSAndrey A. Chernov 	rl->mapupper_ext.nranges = ntohl(rl->mapupper_ext.nranges);
94350a3d3eSAndrey A. Chernov 
95350a3d3eSAndrey A. Chernov 	for (x = 0; x < _CACHED_RUNES; ++x) {
96350a3d3eSAndrey A. Chernov 		rl->runetype[x] = ntohl(rl->runetype[x]);
97350a3d3eSAndrey A. Chernov 		rl->maplower[x] = ntohl(rl->maplower[x]);
98350a3d3eSAndrey A. Chernov 		rl->mapupper[x] = ntohl(rl->mapupper[x]);
99350a3d3eSAndrey A. Chernov 	}
100350a3d3eSAndrey A. Chernov 
101350a3d3eSAndrey A. Chernov 	rl->runetype_ext.ranges = (_RuneEntry *)rl->variable;
102350a3d3eSAndrey A. Chernov 	rl->variable = rl->runetype_ext.ranges + rl->runetype_ext.nranges;
103350a3d3eSAndrey A. Chernov 	if (rl->variable > lastp) {
104350a3d3eSAndrey A. Chernov 		free(data);
105350a3d3eSAndrey A. Chernov 		return(0);
106350a3d3eSAndrey A. Chernov 	}
107350a3d3eSAndrey A. Chernov 
108350a3d3eSAndrey A. Chernov 	rl->maplower_ext.ranges = (_RuneEntry *)rl->variable;
109350a3d3eSAndrey A. Chernov 	rl->variable = rl->maplower_ext.ranges + rl->maplower_ext.nranges;
110350a3d3eSAndrey A. Chernov 	if (rl->variable > lastp) {
111350a3d3eSAndrey A. Chernov 		free(data);
112350a3d3eSAndrey A. Chernov 		return(0);
113350a3d3eSAndrey A. Chernov 	}
114350a3d3eSAndrey A. Chernov 
115350a3d3eSAndrey A. Chernov 	rl->mapupper_ext.ranges = (_RuneEntry *)rl->variable;
116350a3d3eSAndrey A. Chernov 	rl->variable = rl->mapupper_ext.ranges + rl->mapupper_ext.nranges;
117350a3d3eSAndrey A. Chernov 	if (rl->variable > lastp) {
118350a3d3eSAndrey A. Chernov 		free(data);
119350a3d3eSAndrey A. Chernov 		return(0);
120350a3d3eSAndrey A. Chernov 	}
121350a3d3eSAndrey A. Chernov 
122350a3d3eSAndrey A. Chernov 	for (x = 0; x < rl->runetype_ext.nranges; ++x) {
123350a3d3eSAndrey A. Chernov 		rr = rl->runetype_ext.ranges;
124350a3d3eSAndrey A. Chernov 
125350a3d3eSAndrey A. Chernov 		rr[x].min = ntohl(rr[x].min);
126350a3d3eSAndrey A. Chernov 		rr[x].max = ntohl(rr[x].max);
127350a3d3eSAndrey A. Chernov 		if ((rr[x].map = ntohl(rr[x].map)) == 0) {
128350a3d3eSAndrey A. Chernov 			int len = rr[x].max - rr[x].min + 1;
129350a3d3eSAndrey A. Chernov 			rr[x].types = rl->variable;
130350a3d3eSAndrey A. Chernov 			rl->variable = rr[x].types + len;
131350a3d3eSAndrey A. Chernov 			if (rl->variable > lastp) {
132350a3d3eSAndrey A. Chernov 				free(data);
133350a3d3eSAndrey A. Chernov 				return(0);
134350a3d3eSAndrey A. Chernov 			}
135350a3d3eSAndrey A. Chernov 			while (len-- > 0)
136350a3d3eSAndrey A. Chernov 				rr[x].types[len] = ntohl(rr[x].types[len]);
137350a3d3eSAndrey A. Chernov 		} else
138350a3d3eSAndrey A. Chernov 			rr[x].types = 0;
139350a3d3eSAndrey A. Chernov 	}
140350a3d3eSAndrey A. Chernov 
141350a3d3eSAndrey A. Chernov 	for (x = 0; x < rl->maplower_ext.nranges; ++x) {
142350a3d3eSAndrey A. Chernov 		rr = rl->maplower_ext.ranges;
143350a3d3eSAndrey A. Chernov 
144350a3d3eSAndrey A. Chernov 		rr[x].min = ntohl(rr[x].min);
145350a3d3eSAndrey A. Chernov 		rr[x].max = ntohl(rr[x].max);
146350a3d3eSAndrey A. Chernov 		rr[x].map = ntohl(rr[x].map);
147350a3d3eSAndrey A. Chernov 	}
148350a3d3eSAndrey A. Chernov 
149350a3d3eSAndrey A. Chernov 	for (x = 0; x < rl->mapupper_ext.nranges; ++x) {
150350a3d3eSAndrey A. Chernov 		rr = rl->mapupper_ext.ranges;
151350a3d3eSAndrey A. Chernov 
152350a3d3eSAndrey A. Chernov 		rr[x].min = ntohl(rr[x].min);
153350a3d3eSAndrey A. Chernov 		rr[x].max = ntohl(rr[x].max);
154350a3d3eSAndrey A. Chernov 		rr[x].map = ntohl(rr[x].map);
155350a3d3eSAndrey A. Chernov 	}
156350a3d3eSAndrey A. Chernov 	if (((char *)rl->variable) + rl->variable_len > (char *)lastp) {
157350a3d3eSAndrey A. Chernov 		free(data);
158350a3d3eSAndrey A. Chernov 		return(0);
159350a3d3eSAndrey A. Chernov 	}
160350a3d3eSAndrey A. Chernov 
161350a3d3eSAndrey A. Chernov 	/*
162350a3d3eSAndrey A. Chernov 	 * Go out and zero pointers that should be zero.
163350a3d3eSAndrey A. Chernov 	 */
164350a3d3eSAndrey A. Chernov 	if (!rl->variable_len)
165350a3d3eSAndrey A. Chernov 		rl->variable = 0;
166350a3d3eSAndrey A. Chernov 
167350a3d3eSAndrey A. Chernov 	if (!rl->runetype_ext.nranges)
168350a3d3eSAndrey A. Chernov 		rl->runetype_ext.ranges = 0;
169350a3d3eSAndrey A. Chernov 
170350a3d3eSAndrey A. Chernov 	if (!rl->maplower_ext.nranges)
171350a3d3eSAndrey A. Chernov 		rl->maplower_ext.ranges = 0;
172350a3d3eSAndrey A. Chernov 
173350a3d3eSAndrey A. Chernov 	if (!rl->mapupper_ext.nranges)
174350a3d3eSAndrey A. Chernov 		rl->mapupper_ext.ranges = 0;
175350a3d3eSAndrey A. Chernov 
176350a3d3eSAndrey A. Chernov 	return(rl);
177350a3d3eSAndrey A. Chernov }
178