1*d14d7d31Sis /*
2*d14d7d31Sis  * CDDL HEADER START
3*d14d7d31Sis  *
4*d14d7d31Sis  * The contents of this file are subject to the terms of the
5*d14d7d31Sis  * Common Development and Distribution License (the "License").
6*d14d7d31Sis  * You may not use this file except in compliance with the License.
7*d14d7d31Sis  *
8*d14d7d31Sis  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*d14d7d31Sis  * or http://www.opensolaris.org/os/licensing.
10*d14d7d31Sis  * See the License for the specific language governing permissions
11*d14d7d31Sis  * and limitations under the License.
12*d14d7d31Sis  *
13*d14d7d31Sis  * When distributing Covered Code, include this CDDL HEADER in each
14*d14d7d31Sis  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*d14d7d31Sis  * If applicable, add the following below this CDDL HEADER, with the
16*d14d7d31Sis  * fields enclosed by brackets "[]" replaced with your own identifying
17*d14d7d31Sis  * information: Portions Copyright [yyyy] [name of copyright owner]
18*d14d7d31Sis  *
19*d14d7d31Sis  * CDDL HEADER END
20*d14d7d31Sis  */
21*d14d7d31Sis /*
22*d14d7d31Sis  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*d14d7d31Sis  * Use is subject to license terms.
24*d14d7d31Sis  */
25*d14d7d31Sis 
26*d14d7d31Sis /*
27*d14d7d31Sis  * Kernel iconv code conversion module (kiconv_emea) for Europe, Middle East,
28*d14d7d31Sis  * and South East Asia (PSARC/2007/173).
29*d14d7d31Sis  */
30*d14d7d31Sis 
31*d14d7d31Sis #include <sys/types.h>
32*d14d7d31Sis #include <sys/param.h>
33*d14d7d31Sis #include <sys/sysmacros.h>
34*d14d7d31Sis #include <sys/systm.h>
35*d14d7d31Sis #include <sys/debug.h>
36*d14d7d31Sis #include <sys/kmem.h>
37*d14d7d31Sis #include <sys/cmn_err.h>
38*d14d7d31Sis #include <sys/ddi.h>
39*d14d7d31Sis #include <sys/sunddi.h>
40*d14d7d31Sis #include <sys/ksynch.h>
41*d14d7d31Sis #include <sys/modctl.h>
42*d14d7d31Sis #include <sys/byteorder.h>
43*d14d7d31Sis #include <sys/errno.h>
44*d14d7d31Sis #include <sys/kiconv.h>
45*d14d7d31Sis #include <sys/kiconv_emea1.h>
46*d14d7d31Sis #include <sys/kiconv_emea2.h>
47*d14d7d31Sis 
48*d14d7d31Sis 
49*d14d7d31Sis /*
50*d14d7d31Sis  * The following macros indicate ids to the correct code conversion mapping
51*d14d7d31Sis  * data tables to use. The actual tables are coming from <sys/kiconv_emea1.h>
52*d14d7d31Sis  * and <sys/kiconv_emea2.h>. If you update the header files, then, you might
53*d14d7d31Sis  * also need to update the table ids at below.
54*d14d7d31Sis  *
55*d14d7d31Sis  * The table for KICONV_TBLID_720 is a special case and should come from
56*d14d7d31Sis  * a separate header file than others at <sys/kiconv_emea1.h> hence it has
57*d14d7d31Sis  * an id that is rather unusual distinguishing itself from others. (And,
58*d14d7d31Sis  * the ids much be of uint8_t.)
59*d14d7d31Sis  */
60*d14d7d31Sis #define	KICONV_TBLID_720		(0xFFU)
61*d14d7d31Sis #define	KICONV_TBLID_RANGE1_START	KICONV_TBLID_720
62*d14d7d31Sis #define	KICONV_TBLID_RANGE1_END		KICONV_TBLID_720
63*d14d7d31Sis 
64*d14d7d31Sis #define	KICONV_TBLID_737		(0)
65*d14d7d31Sis #define	KICONV_TBLID_852		(1)
66*d14d7d31Sis #define	KICONV_TBLID_857		(2)
67*d14d7d31Sis #define	KICONV_TBLID_862		(3)
68*d14d7d31Sis #define	KICONV_TBLID_866		(4)
69*d14d7d31Sis #define	KICONV_TBLID_1250		(5)
70*d14d7d31Sis #define	KICONV_TBLID_1251		(6)
71*d14d7d31Sis #define	KICONV_TBLID_1253		(7)
72*d14d7d31Sis #define	KICONV_TBLID_1254		(8)
73*d14d7d31Sis #define	KICONV_TBLID_1255		(9)
74*d14d7d31Sis #define	KICONV_TBLID_1256		(10)
75*d14d7d31Sis #define	KICONV_TBLID_1257		(11)
76*d14d7d31Sis #define	KICONV_TBLID_8859_2		(12)
77*d14d7d31Sis #define	KICONV_TBLID_8859_3		(13)
78*d14d7d31Sis #define	KICONV_TBLID_8859_4		(14)
79*d14d7d31Sis #define	KICONV_TBLID_8859_5		(15)
80*d14d7d31Sis #define	KICONV_TBLID_8859_6		(16)
81*d14d7d31Sis #define	KICONV_TBLID_8859_7		(17)
82*d14d7d31Sis #define	KICONV_TBLID_8859_8		(18)
83*d14d7d31Sis #define	KICONV_TBLID_8859_9		(19)
84*d14d7d31Sis #define	KICONV_TBLID_8859_10		(20)
85*d14d7d31Sis #define	KICONV_TBLID_8859_11		(21)
86*d14d7d31Sis #define	KICONV_TBLID_8859_13		(22)
87*d14d7d31Sis #define	KICONV_TBLID_KOI8_R		(23)
88*d14d7d31Sis 
89*d14d7d31Sis #define	KICONV_MAX_MAPPING_TBLID	KICONV_TBLID_KOI8_R
90*d14d7d31Sis 
91*d14d7d31Sis /*
92*d14d7d31Sis  * The following tables are coming from u8_textprep.c. We use them to
93*d14d7d31Sis  * check on validity of UTF-8 characters and their bytes.
94*d14d7d31Sis  */
95*d14d7d31Sis extern const int8_t u8_number_of_bytes[];
96*d14d7d31Sis extern const uint8_t u8_valid_min_2nd_byte[];
97*d14d7d31Sis extern const uint8_t u8_valid_max_2nd_byte[];
98*d14d7d31Sis 
99*d14d7d31Sis 
100*d14d7d31Sis /*
101*d14d7d31Sis  * The following 25 open_to_xxxx() functions are kiconv_open functions for
102*d14d7d31Sis  * the conversions from UTF-8 to xxxx single byte codesets.
103*d14d7d31Sis  */
104*d14d7d31Sis static void *
open_to_720()105*d14d7d31Sis open_to_720()
106*d14d7d31Sis {
107*d14d7d31Sis 	kiconv_state_t s;
108*d14d7d31Sis 
109*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
110*d14d7d31Sis 	s->id = KICONV_TBLID_720;
111*d14d7d31Sis 	s->bom_processed = 0;
112*d14d7d31Sis 
113*d14d7d31Sis 	return ((void *)s);
114*d14d7d31Sis }
115*d14d7d31Sis 
116*d14d7d31Sis static void *
open_to_737()117*d14d7d31Sis open_to_737()
118*d14d7d31Sis {
119*d14d7d31Sis 	kiconv_state_t s;
120*d14d7d31Sis 
121*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
122*d14d7d31Sis 	s->id = KICONV_TBLID_737;
123*d14d7d31Sis 	s->bom_processed = 0;
124*d14d7d31Sis 
125*d14d7d31Sis 	return ((void *)s);
126*d14d7d31Sis }
127*d14d7d31Sis 
128*d14d7d31Sis static void *
open_to_852()129*d14d7d31Sis open_to_852()
130*d14d7d31Sis {
131*d14d7d31Sis 	kiconv_state_t s;
132*d14d7d31Sis 
133*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
134*d14d7d31Sis 	s->id = KICONV_TBLID_852;
135*d14d7d31Sis 	s->bom_processed = 0;
136*d14d7d31Sis 
137*d14d7d31Sis 	return ((void *)s);
138*d14d7d31Sis }
139*d14d7d31Sis 
140*d14d7d31Sis static void *
open_to_857()141*d14d7d31Sis open_to_857()
142*d14d7d31Sis {
143*d14d7d31Sis 	kiconv_state_t s;
144*d14d7d31Sis 
145*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
146*d14d7d31Sis 	s->id = KICONV_TBLID_857;
147*d14d7d31Sis 	s->bom_processed = 0;
148*d14d7d31Sis 
149*d14d7d31Sis 	return ((void *)s);
150*d14d7d31Sis }
151*d14d7d31Sis 
152*d14d7d31Sis static void *
open_to_862()153*d14d7d31Sis open_to_862()
154*d14d7d31Sis {
155*d14d7d31Sis 	kiconv_state_t s;
156*d14d7d31Sis 
157*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
158*d14d7d31Sis 	s->id = KICONV_TBLID_862;
159*d14d7d31Sis 	s->bom_processed = 0;
160*d14d7d31Sis 
161*d14d7d31Sis 	return ((void *)s);
162*d14d7d31Sis }
163*d14d7d31Sis 
164*d14d7d31Sis static void *
open_to_866()165*d14d7d31Sis open_to_866()
166*d14d7d31Sis {
167*d14d7d31Sis 	kiconv_state_t s;
168*d14d7d31Sis 
169*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
170*d14d7d31Sis 	s->id = KICONV_TBLID_866;
171*d14d7d31Sis 	s->bom_processed = 0;
172*d14d7d31Sis 
173*d14d7d31Sis 	return ((void *)s);
174*d14d7d31Sis }
175*d14d7d31Sis 
176*d14d7d31Sis static void *
open_to_1250()177*d14d7d31Sis open_to_1250()
178*d14d7d31Sis {
179*d14d7d31Sis 	kiconv_state_t s;
180*d14d7d31Sis 
181*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
182*d14d7d31Sis 	s->id = KICONV_TBLID_1250;
183*d14d7d31Sis 	s->bom_processed = 0;
184*d14d7d31Sis 
185*d14d7d31Sis 	return ((void *)s);
186*d14d7d31Sis }
187*d14d7d31Sis 
188*d14d7d31Sis static void *
open_to_1251()189*d14d7d31Sis open_to_1251()
190*d14d7d31Sis {
191*d14d7d31Sis 	kiconv_state_t s;
192*d14d7d31Sis 
193*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
194*d14d7d31Sis 	s->id = KICONV_TBLID_1251;
195*d14d7d31Sis 	s->bom_processed = 0;
196*d14d7d31Sis 
197*d14d7d31Sis 	return ((void *)s);
198*d14d7d31Sis }
199*d14d7d31Sis 
200*d14d7d31Sis static void *
open_to_1253()201*d14d7d31Sis open_to_1253()
202*d14d7d31Sis {
203*d14d7d31Sis 	kiconv_state_t s;
204*d14d7d31Sis 
205*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
206*d14d7d31Sis 	s->id = KICONV_TBLID_1253;
207*d14d7d31Sis 	s->bom_processed = 0;
208*d14d7d31Sis 
209*d14d7d31Sis 	return ((void *)s);
210*d14d7d31Sis }
211*d14d7d31Sis 
212*d14d7d31Sis static void *
open_to_1254()213*d14d7d31Sis open_to_1254()
214*d14d7d31Sis {
215*d14d7d31Sis 	kiconv_state_t s;
216*d14d7d31Sis 
217*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
218*d14d7d31Sis 	s->id = KICONV_TBLID_1254;
219*d14d7d31Sis 	s->bom_processed = 0;
220*d14d7d31Sis 
221*d14d7d31Sis 	return ((void *)s);
222*d14d7d31Sis }
223*d14d7d31Sis 
224*d14d7d31Sis static void *
open_to_1255()225*d14d7d31Sis open_to_1255()
226*d14d7d31Sis {
227*d14d7d31Sis 	kiconv_state_t s;
228*d14d7d31Sis 
229*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
230*d14d7d31Sis 	s->id = KICONV_TBLID_1255;
231*d14d7d31Sis 	s->bom_processed = 0;
232*d14d7d31Sis 
233*d14d7d31Sis 	return ((void *)s);
234*d14d7d31Sis }
235*d14d7d31Sis 
236*d14d7d31Sis static void *
open_to_1256()237*d14d7d31Sis open_to_1256()
238*d14d7d31Sis {
239*d14d7d31Sis 	kiconv_state_t s;
240*d14d7d31Sis 
241*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
242*d14d7d31Sis 	s->id = KICONV_TBLID_1256;
243*d14d7d31Sis 	s->bom_processed = 0;
244*d14d7d31Sis 
245*d14d7d31Sis 	return ((void *)s);
246*d14d7d31Sis }
247*d14d7d31Sis 
248*d14d7d31Sis static void *
open_to_1257()249*d14d7d31Sis open_to_1257()
250*d14d7d31Sis {
251*d14d7d31Sis 	kiconv_state_t s;
252*d14d7d31Sis 
253*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
254*d14d7d31Sis 	s->id = KICONV_TBLID_1257;
255*d14d7d31Sis 	s->bom_processed = 0;
256*d14d7d31Sis 
257*d14d7d31Sis 	return ((void *)s);
258*d14d7d31Sis }
259*d14d7d31Sis 
260*d14d7d31Sis static void *
open_to_88592()261*d14d7d31Sis open_to_88592()
262*d14d7d31Sis {
263*d14d7d31Sis 	kiconv_state_t s;
264*d14d7d31Sis 
265*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
266*d14d7d31Sis 	s->id = KICONV_TBLID_8859_2;
267*d14d7d31Sis 	s->bom_processed = 0;
268*d14d7d31Sis 
269*d14d7d31Sis 	return ((void *)s);
270*d14d7d31Sis }
271*d14d7d31Sis 
272*d14d7d31Sis static void *
open_to_88593()273*d14d7d31Sis open_to_88593()
274*d14d7d31Sis {
275*d14d7d31Sis 	kiconv_state_t s;
276*d14d7d31Sis 
277*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
278*d14d7d31Sis 	s->id = KICONV_TBLID_8859_3;
279*d14d7d31Sis 	s->bom_processed = 0;
280*d14d7d31Sis 
281*d14d7d31Sis 	return ((void *)s);
282*d14d7d31Sis }
283*d14d7d31Sis 
284*d14d7d31Sis static void *
open_to_88594()285*d14d7d31Sis open_to_88594()
286*d14d7d31Sis {
287*d14d7d31Sis 	kiconv_state_t s;
288*d14d7d31Sis 
289*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
290*d14d7d31Sis 	s->id = KICONV_TBLID_8859_4;
291*d14d7d31Sis 	s->bom_processed = 0;
292*d14d7d31Sis 
293*d14d7d31Sis 	return ((void *)s);
294*d14d7d31Sis }
295*d14d7d31Sis 
296*d14d7d31Sis static void *
open_to_88595()297*d14d7d31Sis open_to_88595()
298*d14d7d31Sis {
299*d14d7d31Sis 	kiconv_state_t s;
300*d14d7d31Sis 
301*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
302*d14d7d31Sis 	s->id = KICONV_TBLID_8859_5;
303*d14d7d31Sis 	s->bom_processed = 0;
304*d14d7d31Sis 
305*d14d7d31Sis 	return ((void *)s);
306*d14d7d31Sis }
307*d14d7d31Sis 
308*d14d7d31Sis static void *
open_to_88596()309*d14d7d31Sis open_to_88596()
310*d14d7d31Sis {
311*d14d7d31Sis 	kiconv_state_t s;
312*d14d7d31Sis 
313*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
314*d14d7d31Sis 	s->id = KICONV_TBLID_8859_6;
315*d14d7d31Sis 	s->bom_processed = 0;
316*d14d7d31Sis 
317*d14d7d31Sis 	return ((void *)s);
318*d14d7d31Sis }
319*d14d7d31Sis 
320*d14d7d31Sis static void *
open_to_88597()321*d14d7d31Sis open_to_88597()
322*d14d7d31Sis {
323*d14d7d31Sis 	kiconv_state_t s;
324*d14d7d31Sis 
325*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
326*d14d7d31Sis 	s->id = KICONV_TBLID_8859_7;
327*d14d7d31Sis 	s->bom_processed = 0;
328*d14d7d31Sis 
329*d14d7d31Sis 	return ((void *)s);
330*d14d7d31Sis }
331*d14d7d31Sis 
332*d14d7d31Sis static void *
open_to_88598()333*d14d7d31Sis open_to_88598()
334*d14d7d31Sis {
335*d14d7d31Sis 	kiconv_state_t s;
336*d14d7d31Sis 
337*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
338*d14d7d31Sis 	s->id = KICONV_TBLID_8859_8;
339*d14d7d31Sis 	s->bom_processed = 0;
340*d14d7d31Sis 
341*d14d7d31Sis 	return ((void *)s);
342*d14d7d31Sis }
343*d14d7d31Sis 
344*d14d7d31Sis static void *
open_to_88599()345*d14d7d31Sis open_to_88599()
346*d14d7d31Sis {
347*d14d7d31Sis 	kiconv_state_t s;
348*d14d7d31Sis 
349*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
350*d14d7d31Sis 	s->id = KICONV_TBLID_8859_9;
351*d14d7d31Sis 	s->bom_processed = 0;
352*d14d7d31Sis 
353*d14d7d31Sis 	return ((void *)s);
354*d14d7d31Sis }
355*d14d7d31Sis 
356*d14d7d31Sis static void *
open_to_885910()357*d14d7d31Sis open_to_885910()
358*d14d7d31Sis {
359*d14d7d31Sis 	kiconv_state_t s;
360*d14d7d31Sis 
361*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
362*d14d7d31Sis 	s->id = KICONV_TBLID_8859_10;
363*d14d7d31Sis 	s->bom_processed = 0;
364*d14d7d31Sis 
365*d14d7d31Sis 	return ((void *)s);
366*d14d7d31Sis }
367*d14d7d31Sis 
368*d14d7d31Sis static void *
open_to_885911()369*d14d7d31Sis open_to_885911()
370*d14d7d31Sis {
371*d14d7d31Sis 	kiconv_state_t s;
372*d14d7d31Sis 
373*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
374*d14d7d31Sis 	s->id = KICONV_TBLID_8859_11;
375*d14d7d31Sis 	s->bom_processed = 0;
376*d14d7d31Sis 
377*d14d7d31Sis 	return ((void *)s);
378*d14d7d31Sis }
379*d14d7d31Sis 
380*d14d7d31Sis static void *
open_to_885913()381*d14d7d31Sis open_to_885913()
382*d14d7d31Sis {
383*d14d7d31Sis 	kiconv_state_t s;
384*d14d7d31Sis 
385*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
386*d14d7d31Sis 	s->id = KICONV_TBLID_8859_13;
387*d14d7d31Sis 	s->bom_processed = 0;
388*d14d7d31Sis 
389*d14d7d31Sis 	return ((void *)s);
390*d14d7d31Sis }
391*d14d7d31Sis 
392*d14d7d31Sis static void *
open_to_koi8r()393*d14d7d31Sis open_to_koi8r()
394*d14d7d31Sis {
395*d14d7d31Sis 	kiconv_state_t s;
396*d14d7d31Sis 
397*d14d7d31Sis 	s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
398*d14d7d31Sis 	s->id = KICONV_TBLID_KOI8_R;
399*d14d7d31Sis 	s->bom_processed = 0;
400*d14d7d31Sis 
401*d14d7d31Sis 	return ((void *)s);
402*d14d7d31Sis }
403*d14d7d31Sis 
404*d14d7d31Sis /*
405*d14d7d31Sis  * The following 25 open_fr_xxxx() functions are kiconv_open functions for
406*d14d7d31Sis  * the conversions from xxxx single byte codeset to UTF-8.
407*d14d7d31Sis  */
408*d14d7d31Sis static void *
open_fr_720()409*d14d7d31Sis open_fr_720()
410*d14d7d31Sis {
411*d14d7d31Sis 	return ((void *)KICONV_TBLID_720);
412*d14d7d31Sis }
413*d14d7d31Sis 
414*d14d7d31Sis static void *
open_fr_737()415*d14d7d31Sis open_fr_737()
416*d14d7d31Sis {
417*d14d7d31Sis 	return ((void *)KICONV_TBLID_737);
418*d14d7d31Sis }
419*d14d7d31Sis 
420*d14d7d31Sis static void *
open_fr_852()421*d14d7d31Sis open_fr_852()
422*d14d7d31Sis {
423*d14d7d31Sis 	return ((void *)KICONV_TBLID_852);
424*d14d7d31Sis }
425*d14d7d31Sis 
426*d14d7d31Sis static void *
open_fr_857()427*d14d7d31Sis open_fr_857()
428*d14d7d31Sis {
429*d14d7d31Sis 	return ((void *)KICONV_TBLID_857);
430*d14d7d31Sis }
431*d14d7d31Sis 
432*d14d7d31Sis static void *
open_fr_862()433*d14d7d31Sis open_fr_862()
434*d14d7d31Sis {
435*d14d7d31Sis 	return ((void *)KICONV_TBLID_862);
436*d14d7d31Sis }
437*d14d7d31Sis 
438*d14d7d31Sis static void *
open_fr_866()439*d14d7d31Sis open_fr_866()
440*d14d7d31Sis {
441*d14d7d31Sis 	return ((void *)KICONV_TBLID_866);
442*d14d7d31Sis }
443*d14d7d31Sis 
444*d14d7d31Sis static void *
open_fr_1250()445*d14d7d31Sis open_fr_1250()
446*d14d7d31Sis {
447*d14d7d31Sis 	return ((void *)KICONV_TBLID_1250);
448*d14d7d31Sis }
449*d14d7d31Sis 
450*d14d7d31Sis static void *
open_fr_1251()451*d14d7d31Sis open_fr_1251()
452*d14d7d31Sis {
453*d14d7d31Sis 	return ((void *)KICONV_TBLID_1251);
454*d14d7d31Sis }
455*d14d7d31Sis 
456*d14d7d31Sis static void *
open_fr_1253()457*d14d7d31Sis open_fr_1253()
458*d14d7d31Sis {
459*d14d7d31Sis 	return ((void *)KICONV_TBLID_1253);
460*d14d7d31Sis }
461*d14d7d31Sis 
462*d14d7d31Sis static void *
open_fr_1254()463*d14d7d31Sis open_fr_1254()
464*d14d7d31Sis {
465*d14d7d31Sis 	return ((void *)KICONV_TBLID_1254);
466*d14d7d31Sis }
467*d14d7d31Sis 
468*d14d7d31Sis static void *
open_fr_1255()469*d14d7d31Sis open_fr_1255()
470*d14d7d31Sis {
471*d14d7d31Sis 	return ((void *)KICONV_TBLID_1255);
472*d14d7d31Sis }
473*d14d7d31Sis 
474*d14d7d31Sis static void *
open_fr_1256()475*d14d7d31Sis open_fr_1256()
476*d14d7d31Sis {
477*d14d7d31Sis 	return ((void *)KICONV_TBLID_1256);
478*d14d7d31Sis }
479*d14d7d31Sis 
480*d14d7d31Sis static void *
open_fr_1257()481*d14d7d31Sis open_fr_1257()
482*d14d7d31Sis {
483*d14d7d31Sis 	return ((void *)KICONV_TBLID_1257);
484*d14d7d31Sis }
485*d14d7d31Sis 
486*d14d7d31Sis static void *
open_fr_88592()487*d14d7d31Sis open_fr_88592()
488*d14d7d31Sis {
489*d14d7d31Sis 	return ((void *)KICONV_TBLID_8859_2);
490*d14d7d31Sis }
491*d14d7d31Sis 
492*d14d7d31Sis static void *
open_fr_88593()493*d14d7d31Sis open_fr_88593()
494*d14d7d31Sis {
495*d14d7d31Sis 	return ((void *)KICONV_TBLID_8859_3);
496*d14d7d31Sis }
497*d14d7d31Sis 
498*d14d7d31Sis static void *
open_fr_88594()499*d14d7d31Sis open_fr_88594()
500*d14d7d31Sis {
501*d14d7d31Sis 	return ((void *)KICONV_TBLID_8859_4);
502*d14d7d31Sis }
503*d14d7d31Sis 
504*d14d7d31Sis static void *
open_fr_88595()505*d14d7d31Sis open_fr_88595()
506*d14d7d31Sis {
507*d14d7d31Sis 	return ((void *)KICONV_TBLID_8859_5);
508*d14d7d31Sis }
509*d14d7d31Sis 
510*d14d7d31Sis static void *
open_fr_88596()511*d14d7d31Sis open_fr_88596()
512*d14d7d31Sis {
513*d14d7d31Sis 	return ((void *)KICONV_TBLID_8859_6);
514*d14d7d31Sis }
515*d14d7d31Sis 
516*d14d7d31Sis static void *
open_fr_88597()517*d14d7d31Sis open_fr_88597()
518*d14d7d31Sis {
519*d14d7d31Sis 	return ((void *)KICONV_TBLID_8859_7);
520*d14d7d31Sis }
521*d14d7d31Sis 
522*d14d7d31Sis static void *
open_fr_88598()523*d14d7d31Sis open_fr_88598()
524*d14d7d31Sis {
525*d14d7d31Sis 	return ((void *)KICONV_TBLID_8859_8);
526*d14d7d31Sis }
527*d14d7d31Sis 
528*d14d7d31Sis static void *
open_fr_88599()529*d14d7d31Sis open_fr_88599()
530*d14d7d31Sis {
531*d14d7d31Sis 	return ((void *)KICONV_TBLID_8859_9);
532*d14d7d31Sis }
533*d14d7d31Sis 
534*d14d7d31Sis static void *
open_fr_885910()535*d14d7d31Sis open_fr_885910()
536*d14d7d31Sis {
537*d14d7d31Sis 	return ((void *)KICONV_TBLID_8859_10);
538*d14d7d31Sis }
539*d14d7d31Sis 
540*d14d7d31Sis static void *
open_fr_885911()541*d14d7d31Sis open_fr_885911()
542*d14d7d31Sis {
543*d14d7d31Sis 	return ((void *)KICONV_TBLID_8859_11);
544*d14d7d31Sis }
545*d14d7d31Sis 
546*d14d7d31Sis static void *
open_fr_885913()547*d14d7d31Sis open_fr_885913()
548*d14d7d31Sis {
549*d14d7d31Sis 	return ((void *)KICONV_TBLID_8859_13);
550*d14d7d31Sis }
551*d14d7d31Sis 
552*d14d7d31Sis static void *
open_fr_koi8r()553*d14d7d31Sis open_fr_koi8r()
554*d14d7d31Sis {
555*d14d7d31Sis 	return ((void *)KICONV_TBLID_KOI8_R);
556*d14d7d31Sis }
557*d14d7d31Sis 
558*d14d7d31Sis /*
559*d14d7d31Sis  * The following is the common kiconv_close function for the conversions from
560*d14d7d31Sis  * UTF-8 to single byte codesets.
561*d14d7d31Sis  */
562*d14d7d31Sis static int
close_to_sb(void * s)563*d14d7d31Sis close_to_sb(void *s)
564*d14d7d31Sis {
565*d14d7d31Sis 	if (! s || s == (void *)-1)
566*d14d7d31Sis 		return (EBADF);
567*d14d7d31Sis 
568*d14d7d31Sis 	kmem_free(s, sizeof (kiconv_state_data_t));
569*d14d7d31Sis 
570*d14d7d31Sis 	return (0);
571*d14d7d31Sis }
572*d14d7d31Sis 
573*d14d7d31Sis /*
574*d14d7d31Sis  * The following is the common kiconv_close function for the conversions from
575*d14d7d31Sis  * single byte codesets to UTF-8.
576*d14d7d31Sis  */
577*d14d7d31Sis static int
close_fr_sb(void * s)578*d14d7d31Sis close_fr_sb(void *s)
579*d14d7d31Sis {
580*d14d7d31Sis 	if ((ulong_t)s > KICONV_MAX_MAPPING_TBLID &&
581*d14d7d31Sis 	    ((ulong_t)s < KICONV_TBLID_RANGE1_START ||
582*d14d7d31Sis 	    (ulong_t)s > KICONV_TBLID_RANGE1_END))
583*d14d7d31Sis 		return (EBADF);
584*d14d7d31Sis 
585*d14d7d31Sis 	return (0);
586*d14d7d31Sis }
587*d14d7d31Sis 
588*d14d7d31Sis /*
589*d14d7d31Sis  * The following is the common kiconv function for the conversions from
590*d14d7d31Sis  * UTF-8 to single byte codesets. (This may look a lot similar to
591*d14d7d31Sis  * kiconvstr_to_sb() but they do have different features to cover and
592*d14d7d31Sis  * it's not really worth to try to merge them into a single function since
593*d14d7d31Sis  * you'll have to add performance penalty for both per each character
594*d14d7d31Sis  * conversion as you will have to figure out if this is kiconv_to_sb() or
595*d14d7d31Sis  * kiconvstr_to_sb().)
596*d14d7d31Sis  */
597*d14d7d31Sis static size_t
kiconv_to_sb(void * kcd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft,int * errno)598*d14d7d31Sis kiconv_to_sb(void *kcd, char **inbuf, size_t *inbytesleft, char **outbuf,
599*d14d7d31Sis 	size_t *outbytesleft, int *errno)
600*d14d7d31Sis {
601*d14d7d31Sis 	kiconv_to_sb_tbl_comp_t *tbl;
602*d14d7d31Sis 	size_t id;
603*d14d7d31Sis 	size_t ret_val;
604*d14d7d31Sis 	uchar_t *ib;
605*d14d7d31Sis 	uchar_t *oldib;
606*d14d7d31Sis 	uchar_t *ob;
607*d14d7d31Sis 	uchar_t *ibtail;
608*d14d7d31Sis 	uchar_t *obtail;
609*d14d7d31Sis 	uint32_t u8;
610*d14d7d31Sis 	size_t i;
611*d14d7d31Sis 	size_t l;
612*d14d7d31Sis 	size_t h;
613*d14d7d31Sis 	size_t init_h;
614*d14d7d31Sis 	int8_t sz;
615*d14d7d31Sis 	boolean_t second;
616*d14d7d31Sis 
617*d14d7d31Sis 	/* Check on the kiconv code conversion descriptor. */
618*d14d7d31Sis 	if (! kcd || kcd == (void *)-1) {
619*d14d7d31Sis 		*errno = EBADF;
620*d14d7d31Sis 		return ((size_t)-1);
621*d14d7d31Sis 	}
622*d14d7d31Sis 
623*d14d7d31Sis 	/* Get the table id and check on it. */
624*d14d7d31Sis 	id = ((kiconv_state_t)kcd)->id;
625*d14d7d31Sis 	if (id > KICONV_MAX_MAPPING_TBLID &&
626*d14d7d31Sis 	    (id < KICONV_TBLID_RANGE1_START || id > KICONV_TBLID_RANGE1_END)) {
627*d14d7d31Sis 		*errno = EBADF;
628*d14d7d31Sis 		return ((size_t)-1);
629*d14d7d31Sis 	}
630*d14d7d31Sis 
631*d14d7d31Sis 	/* If this is a state reset request, process and return. */
632*d14d7d31Sis 	if (! inbuf || ! (*inbuf)) {
633*d14d7d31Sis 		((kiconv_state_t)kcd)->bom_processed = 0;
634*d14d7d31Sis 		return ((size_t)0);
635*d14d7d31Sis 	}
636*d14d7d31Sis 
637*d14d7d31Sis 	ret_val = 0;
638*d14d7d31Sis 	ib = (uchar_t *)*inbuf;
639*d14d7d31Sis 	ob = (uchar_t *)*outbuf;
640*d14d7d31Sis 	ibtail = ib + *inbytesleft;
641*d14d7d31Sis 	obtail = ob + *outbytesleft;
642*d14d7d31Sis 
643*d14d7d31Sis 	/*
644*d14d7d31Sis 	 * Get the table we want to use and also calculate the "init_h"
645*d14d7d31Sis 	 * which is the initial high index for the binary search that we will
646*d14d7d31Sis 	 * use. While the table sizes are all the same at the moment, to be
647*d14d7d31Sis 	 * ready for future cases where tables could be in different sizes,
648*d14d7d31Sis 	 * we separately calculate the init_h at here.
649*d14d7d31Sis 	 */
650*d14d7d31Sis 	if (id == KICONV_TBLID_720) {
651*d14d7d31Sis 		tbl = (kiconv_to_sb_tbl_comp_t *)u8_to_cp720_tbl;
652*d14d7d31Sis 		init_h = sizeof (u8_to_cp720_tbl);
653*d14d7d31Sis 	} else {
654*d14d7d31Sis 		tbl = (kiconv_to_sb_tbl_comp_t *)to_sb_tbl[id];
655*d14d7d31Sis 		init_h = sizeof (to_sb_tbl[id]);
656*d14d7d31Sis 	}
657*d14d7d31Sis 	init_h = init_h / sizeof (kiconv_to_sb_tbl_comp_t) - 1;
658*d14d7d31Sis 
659*d14d7d31Sis 	/*
660*d14d7d31Sis 	 * If we haven't checked on the UTF-8 signature BOM character in
661*d14d7d31Sis 	 * the beginning of the conversion data stream, we check it and if
662*d14d7d31Sis 	 * find one, we skip it since we have no use for it.
663*d14d7d31Sis 	 */
664*d14d7d31Sis 	if (((kiconv_state_t)kcd)->bom_processed == 0 && (ibtail - ib) >= 3 &&
665*d14d7d31Sis 	    *ib == 0xef && *(ib + 1) == 0xbb && *(ib + 2) == 0xbf)
666*d14d7d31Sis 			ib += 3;
667*d14d7d31Sis 	((kiconv_state_t)kcd)->bom_processed = 1;
668*d14d7d31Sis 
669*d14d7d31Sis 	while (ib < ibtail) {
670*d14d7d31Sis 		sz = u8_number_of_bytes[*ib];
671*d14d7d31Sis 		if (sz <= 0) {
672*d14d7d31Sis 			*errno = EILSEQ;
673*d14d7d31Sis 			ret_val = (size_t)-1;
674*d14d7d31Sis 			break;
675*d14d7d31Sis 		}
676*d14d7d31Sis 
677*d14d7d31Sis 		/*
678*d14d7d31Sis 		 * If there is no room to write at the output buffer,
679*d14d7d31Sis 		 * we issue E2BIG and let the caller knows about it.
680*d14d7d31Sis 		 */
681*d14d7d31Sis 		if (ob >= obtail) {
682*d14d7d31Sis 			*errno = E2BIG;
683*d14d7d31Sis 			ret_val = (size_t)-1;
684*d14d7d31Sis 			break;
685*d14d7d31Sis 		}
686*d14d7d31Sis 
687*d14d7d31Sis 		/*
688*d14d7d31Sis 		 * If it is a 7-bit ASCII character, we don't need to
689*d14d7d31Sis 		 * process further and we just copy the character over.
690*d14d7d31Sis 		 *
691*d14d7d31Sis 		 * If not, we collect the character bytes up to four bytes,
692*d14d7d31Sis 		 * validate the bytes, and binary search for the corresponding
693*d14d7d31Sis 		 * single byte codeset character byte. If we find it from
694*d14d7d31Sis 		 * the mapping table, we put that into the output buffer;
695*d14d7d31Sis 		 * otherwise, we put a replacement character instead as
696*d14d7d31Sis 		 * a non-identical conversion.
697*d14d7d31Sis 		 */
698*d14d7d31Sis 		if (sz == 1) {
699*d14d7d31Sis 			*ob++ = *ib++;
700*d14d7d31Sis 			continue;
701*d14d7d31Sis 		}
702*d14d7d31Sis 
703*d14d7d31Sis 		/*
704*d14d7d31Sis 		 * Issue EINVAL if the last character at the input buffer
705*d14d7d31Sis 		 * is an incomplete character missing a byte or more.
706*d14d7d31Sis 		 */
707*d14d7d31Sis 		if ((ibtail - ib) < sz) {
708*d14d7d31Sis 			*errno = EINVAL;
709*d14d7d31Sis 			ret_val = (size_t)-1;
710*d14d7d31Sis 			break;
711*d14d7d31Sis 		}
712*d14d7d31Sis 
713*d14d7d31Sis 		/*
714*d14d7d31Sis 		 * We collect UTF-8 character bytes and at the same time,
715*d14d7d31Sis 		 * check on if the bytes are valid bytes or not. This follows
716*d14d7d31Sis 		 * the latest UTF-8 byte representation.
717*d14d7d31Sis 		 */
718*d14d7d31Sis 		oldib = ib;
719*d14d7d31Sis 		u8 = *ib++;
720*d14d7d31Sis 		second = B_TRUE;
721*d14d7d31Sis 		for (i = 1; i < sz; i++) {
722*d14d7d31Sis 			if (second) {
723*d14d7d31Sis 				if (*ib < u8_valid_min_2nd_byte[u8] ||
724*d14d7d31Sis 				    *ib > u8_valid_max_2nd_byte[u8]) {
725*d14d7d31Sis 					*errno = EILSEQ;
726*d14d7d31Sis 					ret_val = (size_t)-1;
727*d14d7d31Sis 					ib = oldib;
728*d14d7d31Sis 					goto TO_SB_ILLEGAL_CHAR_ERR;
729*d14d7d31Sis 				}
730*d14d7d31Sis 				second = B_FALSE;
731*d14d7d31Sis 			} else if (*ib < 0x80 || *ib > 0xbf) {
732*d14d7d31Sis 				*errno = EILSEQ;
733*d14d7d31Sis 				ret_val = (size_t)-1;
734*d14d7d31Sis 				ib = oldib;
735*d14d7d31Sis 				goto TO_SB_ILLEGAL_CHAR_ERR;
736*d14d7d31Sis 			}
737*d14d7d31Sis 			u8 = (u8 << 8) | ((uint32_t)*ib);
738*d14d7d31Sis 			ib++;
739*d14d7d31Sis 		}
740*d14d7d31Sis 
741*d14d7d31Sis 		i = l = 0;
742*d14d7d31Sis 		h = init_h;
743*d14d7d31Sis 		while (l <= h) {
744*d14d7d31Sis 			i = (l + h) / 2;
745*d14d7d31Sis 			if (tbl[i].u8 == u8)
746*d14d7d31Sis 				break;
747*d14d7d31Sis 			else if (tbl[i].u8 < u8)
748*d14d7d31Sis 				l = i + 1;
749*d14d7d31Sis 			else
750*d14d7d31Sis 				h = i - 1;
751*d14d7d31Sis 		}
752*d14d7d31Sis 
753*d14d7d31Sis 		if (tbl[i].u8 == u8) {
754*d14d7d31Sis 			*ob++ = tbl[i].sb;
755*d14d7d31Sis 		} else {
756*d14d7d31Sis 			/*
757*d14d7d31Sis 			 * What this means is that we encountered
758*d14d7d31Sis 			 * a non-identical conversion. In other words,
759*d14d7d31Sis 			 * input buffer contains a valid character in
760*d14d7d31Sis 			 * the fromcode but the tocode doesn't have
761*d14d7d31Sis 			 * any character that can be mapped to.
762*d14d7d31Sis 			 *
763*d14d7d31Sis 			 * In this case, we insert an ASCII replacement
764*d14d7d31Sis 			 * character instead at the output buffer and
765*d14d7d31Sis 			 * count such non-identical conversions by
766*d14d7d31Sis 			 * increasing the ret_val.
767*d14d7d31Sis 			 *
768*d14d7d31Sis 			 * If the return value of the function is bigger
769*d14d7d31Sis 			 * than zero, that means we had such non-identical
770*d14d7d31Sis 			 * conversion(s).
771*d14d7d31Sis 			 */
772*d14d7d31Sis 			*ob++ = KICONV_ASCII_REPLACEMENT_CHAR;
773*d14d7d31Sis 			ret_val++;
774*d14d7d31Sis 		}
775*d14d7d31Sis 	}
776*d14d7d31Sis 
777*d14d7d31Sis TO_SB_ILLEGAL_CHAR_ERR:
778*d14d7d31Sis 	*inbuf = (char *)ib;
779*d14d7d31Sis 	*inbytesleft = ibtail - ib;
780*d14d7d31Sis 	*outbuf = (char *)ob;
781*d14d7d31Sis 	*outbytesleft = obtail - ob;
782*d14d7d31Sis 
783*d14d7d31Sis 	return (ret_val);
784*d14d7d31Sis }
785*d14d7d31Sis 
786*d14d7d31Sis /*
787*d14d7d31Sis  * The following is the common kiconv function for the conversions from
788*d14d7d31Sis  * single byte codesets to UTf-8.
789*d14d7d31Sis  */
790*d14d7d31Sis static size_t
kiconv_fr_sb(void * kcd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft,int * errno)791*d14d7d31Sis kiconv_fr_sb(void *kcd, char **inbuf, size_t *inbytesleft, char **outbuf,
792*d14d7d31Sis 	size_t *outbytesleft, int *errno)
793*d14d7d31Sis {
794*d14d7d31Sis 	kiconv_to_utf8_tbl_comp_t *tbl;
795*d14d7d31Sis 	size_t ret_val;
796*d14d7d31Sis 	uchar_t *ib;
797*d14d7d31Sis 	uchar_t *ob;
798*d14d7d31Sis 	uchar_t *ibtail;
799*d14d7d31Sis 	uchar_t *obtail;
800*d14d7d31Sis 	size_t i;
801*d14d7d31Sis 	size_t k;
802*d14d7d31Sis 	int8_t sz;
803*d14d7d31Sis 
804*d14d7d31Sis 	/* Validate the kiconv code conversion descriptor. */
805*d14d7d31Sis 	if ((ulong_t)kcd > KICONV_MAX_MAPPING_TBLID &&
806*d14d7d31Sis 	    ((ulong_t)kcd < KICONV_TBLID_RANGE1_START ||
807*d14d7d31Sis 	    (ulong_t)kcd > KICONV_TBLID_RANGE1_END)) {
808*d14d7d31Sis 		*errno = EBADF;
809*d14d7d31Sis 		return ((size_t)-1);
810*d14d7d31Sis 	}
811*d14d7d31Sis 
812*d14d7d31Sis 	/*
813*d14d7d31Sis 	 * If this is a state reset request, there is nothing to do and so
814*d14d7d31Sis 	 * we just return.
815*d14d7d31Sis 	 */
816*d14d7d31Sis 	if (! inbuf || ! (*inbuf))
817*d14d7d31Sis 		return ((size_t)0);
818*d14d7d31Sis 
819*d14d7d31Sis 	ret_val = 0;
820*d14d7d31Sis 	ib = (uchar_t *)*inbuf;
821*d14d7d31Sis 	ob = (uchar_t *)*outbuf;
822*d14d7d31Sis 	ibtail = ib + *inbytesleft;
823*d14d7d31Sis 	obtail = ob + *outbytesleft;
824*d14d7d31Sis 
825*d14d7d31Sis 	tbl = ((ulong_t)kcd == KICONV_TBLID_720) ?
826*d14d7d31Sis 	    (kiconv_to_utf8_tbl_comp_t *)cp720_to_u8_tbl :
827*d14d7d31Sis 	    (kiconv_to_utf8_tbl_comp_t *)to_u8_tbl[(ulong_t)kcd];
828*d14d7d31Sis 
829*d14d7d31Sis 	while (ib < ibtail) {
830*d14d7d31Sis 		/*
831*d14d7d31Sis 		 * If this is a 7-bit ASCII character, we just copy over and
832*d14d7d31Sis 		 * that's all we need to do for this character.
833*d14d7d31Sis 		 */
834*d14d7d31Sis 		if (*ib < 0x80) {
835*d14d7d31Sis 			if (ob >= obtail) {
836*d14d7d31Sis 				*errno = E2BIG;
837*d14d7d31Sis 				ret_val = (size_t)-1;
838*d14d7d31Sis 				break;
839*d14d7d31Sis 			}
840*d14d7d31Sis 
841*d14d7d31Sis 			*ob++ = *ib++;
842*d14d7d31Sis 			continue;
843*d14d7d31Sis 		}
844*d14d7d31Sis 
845*d14d7d31Sis 		/*
846*d14d7d31Sis 		 * Otherwise, we get the corresponding UTF-8 character bytes
847*d14d7d31Sis 		 * from the mapping table and copy them over.
848*d14d7d31Sis 		 *
849*d14d7d31Sis 		 * We don't need to worry about if the UTF-8 character bytes
850*d14d7d31Sis 		 * at the mapping tables are valid or not since they are good.
851*d14d7d31Sis 		 */
852*d14d7d31Sis 		k = *ib - 0x80;
853*d14d7d31Sis 		sz = u8_number_of_bytes[tbl[k].u8[0]];
854*d14d7d31Sis 
855*d14d7d31Sis 		/*
856*d14d7d31Sis 		 * If (sz <= 0), that means the character in the input buffer
857*d14d7d31Sis 		 * is an illegal character possibly unassigned or non-character
858*d14d7d31Sis 		 * at the fromcode single byte codeset.
859*d14d7d31Sis 		 */
860*d14d7d31Sis 		if (sz <= 0) {
861*d14d7d31Sis 			*errno = EILSEQ;
862*d14d7d31Sis 			ret_val = (size_t)-1;
863*d14d7d31Sis 			break;
864*d14d7d31Sis 		}
865*d14d7d31Sis 
866*d14d7d31Sis 		if ((obtail - ob) < sz) {
867*d14d7d31Sis 			*errno = E2BIG;
868*d14d7d31Sis 			ret_val = (size_t)-1;
869*d14d7d31Sis 			break;
870*d14d7d31Sis 		}
871*d14d7d31Sis 
872*d14d7d31Sis 		for (i = 0; i < sz; i++)
873*d14d7d31Sis 			*ob++ = tbl[k].u8[i];
874*d14d7d31Sis 
875*d14d7d31Sis 		ib++;
876*d14d7d31Sis 	}
877*d14d7d31Sis 
878*d14d7d31Sis 	*inbuf = (char *)ib;
879*d14d7d31Sis 	*inbytesleft = ibtail - ib;
880*d14d7d31Sis 	*outbuf = (char *)ob;
881*d14d7d31Sis 	*outbytesleft = obtail - ob;
882*d14d7d31Sis 
883*d14d7d31Sis 	return (ret_val);
884*d14d7d31Sis }
885*d14d7d31Sis 
886*d14d7d31Sis /*
887*d14d7d31Sis  * The following is the common kiconvstr function for the conversions from
888*d14d7d31Sis  * UTF-8 to single byte codeset.
889*d14d7d31Sis  */
890*d14d7d31Sis static size_t
kiconvstr_to_sb(size_t id,uchar_t * ib,size_t * inlen,uchar_t * ob,size_t * outlen,int flag,int * errno)891*d14d7d31Sis kiconvstr_to_sb(size_t id, uchar_t *ib, size_t *inlen, uchar_t *ob,
892*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
893*d14d7d31Sis {
894*d14d7d31Sis 	kiconv_to_sb_tbl_comp_t *tbl;
895*d14d7d31Sis 	size_t ret_val;
896*d14d7d31Sis 	uchar_t *oldib;
897*d14d7d31Sis 	uchar_t *ibtail;
898*d14d7d31Sis 	uchar_t *obtail;
899*d14d7d31Sis 	uint32_t u8;
900*d14d7d31Sis 	size_t i;
901*d14d7d31Sis 	size_t l;
902*d14d7d31Sis 	size_t h;
903*d14d7d31Sis 	size_t init_h;
904*d14d7d31Sis 	int8_t sz;
905*d14d7d31Sis 	boolean_t second;
906*d14d7d31Sis 	boolean_t do_not_ignore_null;
907*d14d7d31Sis 
908*d14d7d31Sis 	/* Let's double check on the table id. */
909*d14d7d31Sis 	if (id > KICONV_MAX_MAPPING_TBLID &&
910*d14d7d31Sis 	    (id < KICONV_TBLID_RANGE1_START || id > KICONV_TBLID_RANGE1_END)) {
911*d14d7d31Sis 		*errno = EBADF;
912*d14d7d31Sis 		return ((size_t)-1);
913*d14d7d31Sis 	}
914*d14d7d31Sis 
915*d14d7d31Sis 	ret_val = 0;
916*d14d7d31Sis 	ibtail = ib + *inlen;
917*d14d7d31Sis 	obtail = ob + *outlen;
918*d14d7d31Sis 	do_not_ignore_null = ((flag & KICONV_IGNORE_NULL) == 0);
919*d14d7d31Sis 
920*d14d7d31Sis 	if (id == KICONV_TBLID_720) {
921*d14d7d31Sis 		tbl = (kiconv_to_sb_tbl_comp_t *)u8_to_cp720_tbl;
922*d14d7d31Sis 		init_h = sizeof (u8_to_cp720_tbl);
923*d14d7d31Sis 	} else {
924*d14d7d31Sis 		tbl = (kiconv_to_sb_tbl_comp_t *)to_sb_tbl[id];
925*d14d7d31Sis 		init_h = sizeof (to_sb_tbl[id]);
926*d14d7d31Sis 	}
927*d14d7d31Sis 	init_h = init_h / sizeof (kiconv_to_sb_tbl_comp_t) - 1;
928*d14d7d31Sis 
929*d14d7d31Sis 	/* Skip any UTF-8 signature BOM character in the beginning. */
930*d14d7d31Sis 	if ((ibtail - ib) >= 3 && *ib == 0xef && *(ib + 1) == 0xbb &&
931*d14d7d31Sis 	    *(ib + 2) == 0xbf)
932*d14d7d31Sis 			ib += 3;
933*d14d7d31Sis 
934*d14d7d31Sis 	/*
935*d14d7d31Sis 	 * Basically this is pretty much the same as kiconv_to_sb() except
936*d14d7d31Sis 	 * that we are now accepting two flag values and doing the processing
937*d14d7d31Sis 	 * accordingly.
938*d14d7d31Sis 	 */
939*d14d7d31Sis 	while (ib < ibtail) {
940*d14d7d31Sis 		sz = u8_number_of_bytes[*ib];
941*d14d7d31Sis 		if (sz <= 0) {
942*d14d7d31Sis 			if (flag & KICONV_REPLACE_INVALID) {
943*d14d7d31Sis 				if (ob >= obtail) {
944*d14d7d31Sis 					*errno = E2BIG;
945*d14d7d31Sis 					ret_val = (size_t)-1;
946*d14d7d31Sis 					break;
947*d14d7d31Sis 				}
948*d14d7d31Sis 
949*d14d7d31Sis 				ib++;
950*d14d7d31Sis 				goto STR_TO_SB_REPLACE_INVALID;
951*d14d7d31Sis 			}
952*d14d7d31Sis 
953*d14d7d31Sis 			*errno = EILSEQ;
954*d14d7d31Sis 			ret_val = (size_t)-1;
955*d14d7d31Sis 			break;
956*d14d7d31Sis 		}
957*d14d7d31Sis 
958*d14d7d31Sis 		if (*ib == '\0' && do_not_ignore_null)
959*d14d7d31Sis 			break;
960*d14d7d31Sis 
961*d14d7d31Sis 		if (ob >= obtail) {
962*d14d7d31Sis 			*errno = E2BIG;
963*d14d7d31Sis 			ret_val = (size_t)-1;
964*d14d7d31Sis 			break;
965*d14d7d31Sis 		}
966*d14d7d31Sis 
967*d14d7d31Sis 		if (sz == 1) {
968*d14d7d31Sis 			*ob++ = *ib++;
969*d14d7d31Sis 			continue;
970*d14d7d31Sis 		}
971*d14d7d31Sis 
972*d14d7d31Sis 		if ((ibtail - ib) < sz) {
973*d14d7d31Sis 			if (flag & KICONV_REPLACE_INVALID) {
974*d14d7d31Sis 				ib = ibtail;
975*d14d7d31Sis 				goto STR_TO_SB_REPLACE_INVALID;
976*d14d7d31Sis 			}
977*d14d7d31Sis 
978*d14d7d31Sis 			*errno = EINVAL;
979*d14d7d31Sis 			ret_val = (size_t)-1;
980*d14d7d31Sis 			break;
981*d14d7d31Sis 		}
982*d14d7d31Sis 
983*d14d7d31Sis 		oldib = ib;
984*d14d7d31Sis 		u8 = *ib++;
985*d14d7d31Sis 		second = B_TRUE;
986*d14d7d31Sis 		for (i = 1; i < sz; i++) {
987*d14d7d31Sis 			if (second) {
988*d14d7d31Sis 				if (*ib < u8_valid_min_2nd_byte[u8] ||
989*d14d7d31Sis 				    *ib > u8_valid_max_2nd_byte[u8]) {
990*d14d7d31Sis 					if (flag & KICONV_REPLACE_INVALID) {
991*d14d7d31Sis 						ib = oldib + sz;
992*d14d7d31Sis 						goto STR_TO_SB_REPLACE_INVALID;
993*d14d7d31Sis 					}
994*d14d7d31Sis 
995*d14d7d31Sis 					*errno = EILSEQ;
996*d14d7d31Sis 					ret_val = (size_t)-1;
997*d14d7d31Sis 					ib = oldib;
998*d14d7d31Sis 					goto STR_TO_SB_ILLEGAL_CHAR_ERR;
999*d14d7d31Sis 				}
1000*d14d7d31Sis 				second = B_FALSE;
1001*d14d7d31Sis 			} else if (*ib < 0x80 || *ib > 0xbf) {
1002*d14d7d31Sis 				if (flag & KICONV_REPLACE_INVALID) {
1003*d14d7d31Sis 					ib = oldib + sz;
1004*d14d7d31Sis 					goto STR_TO_SB_REPLACE_INVALID;
1005*d14d7d31Sis 				}
1006*d14d7d31Sis 
1007*d14d7d31Sis 				*errno = EILSEQ;
1008*d14d7d31Sis 				ret_val = (size_t)-1;
1009*d14d7d31Sis 				ib = oldib;
1010*d14d7d31Sis 				goto STR_TO_SB_ILLEGAL_CHAR_ERR;
1011*d14d7d31Sis 			}
1012*d14d7d31Sis 			u8 = (u8 << 8) | ((uint32_t)*ib);
1013*d14d7d31Sis 			ib++;
1014*d14d7d31Sis 		}
1015*d14d7d31Sis 
1016*d14d7d31Sis 		i = l = 0;
1017*d14d7d31Sis 		h = init_h;
1018*d14d7d31Sis 		while (l <= h) {
1019*d14d7d31Sis 			i = (l + h) / 2;
1020*d14d7d31Sis 			if (tbl[i].u8 == u8)
1021*d14d7d31Sis 				break;
1022*d14d7d31Sis 			else if (tbl[i].u8 < u8)
1023*d14d7d31Sis 				l = i + 1;
1024*d14d7d31Sis 			else
1025*d14d7d31Sis 				h = i - 1;
1026*d14d7d31Sis 		}
1027*d14d7d31Sis 
1028*d14d7d31Sis 		if (tbl[i].u8 == u8) {
1029*d14d7d31Sis 			*ob++ = tbl[i].sb;
1030*d14d7d31Sis 		} else {
1031*d14d7d31Sis STR_TO_SB_REPLACE_INVALID:
1032*d14d7d31Sis 			*ob++ = KICONV_ASCII_REPLACEMENT_CHAR;
1033*d14d7d31Sis 			ret_val++;
1034*d14d7d31Sis 		}
1035*d14d7d31Sis 	}
1036*d14d7d31Sis 
1037*d14d7d31Sis STR_TO_SB_ILLEGAL_CHAR_ERR:
1038*d14d7d31Sis 	*inlen = ibtail - ib;
1039*d14d7d31Sis 	*outlen = obtail - ob;
1040*d14d7d31Sis 
1041*d14d7d31Sis 	return (ret_val);
1042*d14d7d31Sis }
1043*d14d7d31Sis 
1044*d14d7d31Sis /*
1045*d14d7d31Sis  * The following 25 functions are the real entry points that will be
1046*d14d7d31Sis  * given to the kiconv framework at the genunix.
1047*d14d7d31Sis  */
1048*d14d7d31Sis static size_t
kiconvstr_to_720(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1049*d14d7d31Sis kiconvstr_to_720(char *inarray, size_t *inlen, char *outarray,
1050*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1051*d14d7d31Sis {
1052*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_720, (uchar_t *)inarray,
1053*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1054*d14d7d31Sis }
1055*d14d7d31Sis 
1056*d14d7d31Sis static size_t
kiconvstr_to_737(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1057*d14d7d31Sis kiconvstr_to_737(char *inarray, size_t *inlen, char *outarray,
1058*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1059*d14d7d31Sis {
1060*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_737, (uchar_t *)inarray,
1061*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1062*d14d7d31Sis }
1063*d14d7d31Sis 
1064*d14d7d31Sis static size_t
kiconvstr_to_852(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1065*d14d7d31Sis kiconvstr_to_852(char *inarray, size_t *inlen, char *outarray,
1066*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1067*d14d7d31Sis {
1068*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_852, (uchar_t *)inarray,
1069*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1070*d14d7d31Sis }
1071*d14d7d31Sis 
1072*d14d7d31Sis static size_t
kiconvstr_to_857(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1073*d14d7d31Sis kiconvstr_to_857(char *inarray, size_t *inlen, char *outarray,
1074*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1075*d14d7d31Sis {
1076*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_857, (uchar_t *)inarray,
1077*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1078*d14d7d31Sis }
1079*d14d7d31Sis 
1080*d14d7d31Sis static size_t
kiconvstr_to_862(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1081*d14d7d31Sis kiconvstr_to_862(char *inarray, size_t *inlen, char *outarray,
1082*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1083*d14d7d31Sis {
1084*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_862, (uchar_t *)inarray,
1085*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1086*d14d7d31Sis }
1087*d14d7d31Sis 
1088*d14d7d31Sis static size_t
kiconvstr_to_866(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1089*d14d7d31Sis kiconvstr_to_866(char *inarray, size_t *inlen, char *outarray,
1090*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1091*d14d7d31Sis {
1092*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_866, (uchar_t *)inarray,
1093*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1094*d14d7d31Sis }
1095*d14d7d31Sis 
1096*d14d7d31Sis static size_t
kiconvstr_to_1250(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1097*d14d7d31Sis kiconvstr_to_1250(char *inarray, size_t *inlen, char *outarray,
1098*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1099*d14d7d31Sis {
1100*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_1250, (uchar_t *)inarray,
1101*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1102*d14d7d31Sis }
1103*d14d7d31Sis 
1104*d14d7d31Sis static size_t
kiconvstr_to_1251(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1105*d14d7d31Sis kiconvstr_to_1251(char *inarray, size_t *inlen, char *outarray,
1106*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1107*d14d7d31Sis {
1108*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_1251, (uchar_t *)inarray,
1109*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1110*d14d7d31Sis }
1111*d14d7d31Sis 
1112*d14d7d31Sis static size_t
kiconvstr_to_1253(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1113*d14d7d31Sis kiconvstr_to_1253(char *inarray, size_t *inlen, char *outarray,
1114*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1115*d14d7d31Sis {
1116*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_1253, (uchar_t *)inarray,
1117*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1118*d14d7d31Sis }
1119*d14d7d31Sis 
1120*d14d7d31Sis static size_t
kiconvstr_to_1254(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1121*d14d7d31Sis kiconvstr_to_1254(char *inarray, size_t *inlen, char *outarray,
1122*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1123*d14d7d31Sis {
1124*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_1254, (uchar_t *)inarray,
1125*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1126*d14d7d31Sis }
1127*d14d7d31Sis 
1128*d14d7d31Sis static size_t
kiconvstr_to_1255(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1129*d14d7d31Sis kiconvstr_to_1255(char *inarray, size_t *inlen, char *outarray,
1130*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1131*d14d7d31Sis {
1132*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_1255, (uchar_t *)inarray,
1133*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1134*d14d7d31Sis }
1135*d14d7d31Sis 
1136*d14d7d31Sis static size_t
kiconvstr_to_1256(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1137*d14d7d31Sis kiconvstr_to_1256(char *inarray, size_t *inlen, char *outarray,
1138*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1139*d14d7d31Sis {
1140*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_1256, (uchar_t *)inarray,
1141*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1142*d14d7d31Sis }
1143*d14d7d31Sis 
1144*d14d7d31Sis static size_t
kiconvstr_to_1257(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1145*d14d7d31Sis kiconvstr_to_1257(char *inarray, size_t *inlen, char *outarray,
1146*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1147*d14d7d31Sis {
1148*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_1257, (uchar_t *)inarray,
1149*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1150*d14d7d31Sis }
1151*d14d7d31Sis 
1152*d14d7d31Sis static size_t
kiconvstr_to_88592(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1153*d14d7d31Sis kiconvstr_to_88592(char *inarray, size_t *inlen, char *outarray,
1154*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1155*d14d7d31Sis {
1156*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_8859_2, (uchar_t *)inarray,
1157*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1158*d14d7d31Sis }
1159*d14d7d31Sis 
1160*d14d7d31Sis static size_t
kiconvstr_to_88593(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1161*d14d7d31Sis kiconvstr_to_88593(char *inarray, size_t *inlen, char *outarray,
1162*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1163*d14d7d31Sis {
1164*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_8859_3, (uchar_t *)inarray,
1165*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1166*d14d7d31Sis }
1167*d14d7d31Sis 
1168*d14d7d31Sis static size_t
kiconvstr_to_88594(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1169*d14d7d31Sis kiconvstr_to_88594(char *inarray, size_t *inlen, char *outarray,
1170*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1171*d14d7d31Sis {
1172*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_8859_4, (uchar_t *)inarray,
1173*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1174*d14d7d31Sis }
1175*d14d7d31Sis 
1176*d14d7d31Sis static size_t
kiconvstr_to_88595(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1177*d14d7d31Sis kiconvstr_to_88595(char *inarray, size_t *inlen, char *outarray,
1178*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1179*d14d7d31Sis {
1180*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_8859_5, (uchar_t *)inarray,
1181*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1182*d14d7d31Sis }
1183*d14d7d31Sis 
1184*d14d7d31Sis static size_t
kiconvstr_to_88596(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1185*d14d7d31Sis kiconvstr_to_88596(char *inarray, size_t *inlen, char *outarray,
1186*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1187*d14d7d31Sis {
1188*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_8859_6, (uchar_t *)inarray,
1189*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1190*d14d7d31Sis }
1191*d14d7d31Sis 
1192*d14d7d31Sis static size_t
kiconvstr_to_88597(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1193*d14d7d31Sis kiconvstr_to_88597(char *inarray, size_t *inlen, char *outarray,
1194*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1195*d14d7d31Sis {
1196*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_8859_7, (uchar_t *)inarray,
1197*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1198*d14d7d31Sis }
1199*d14d7d31Sis 
1200*d14d7d31Sis static size_t
kiconvstr_to_88598(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1201*d14d7d31Sis kiconvstr_to_88598(char *inarray, size_t *inlen, char *outarray,
1202*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1203*d14d7d31Sis {
1204*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_8859_8, (uchar_t *)inarray,
1205*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1206*d14d7d31Sis }
1207*d14d7d31Sis 
1208*d14d7d31Sis static size_t
kiconvstr_to_88599(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1209*d14d7d31Sis kiconvstr_to_88599(char *inarray, size_t *inlen, char *outarray,
1210*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1211*d14d7d31Sis {
1212*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_8859_9, (uchar_t *)inarray,
1213*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1214*d14d7d31Sis }
1215*d14d7d31Sis 
1216*d14d7d31Sis static size_t
kiconvstr_to_885910(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1217*d14d7d31Sis kiconvstr_to_885910(char *inarray, size_t *inlen, char *outarray,
1218*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1219*d14d7d31Sis {
1220*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_8859_10, (uchar_t *)inarray,
1221*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1222*d14d7d31Sis }
1223*d14d7d31Sis 
1224*d14d7d31Sis static size_t
kiconvstr_to_885911(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1225*d14d7d31Sis kiconvstr_to_885911(char *inarray, size_t *inlen, char *outarray,
1226*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1227*d14d7d31Sis {
1228*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_8859_11, (uchar_t *)inarray,
1229*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1230*d14d7d31Sis }
1231*d14d7d31Sis 
1232*d14d7d31Sis static size_t
kiconvstr_to_885913(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1233*d14d7d31Sis kiconvstr_to_885913(char *inarray, size_t *inlen, char *outarray,
1234*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1235*d14d7d31Sis {
1236*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_8859_13, (uchar_t *)inarray,
1237*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1238*d14d7d31Sis }
1239*d14d7d31Sis 
1240*d14d7d31Sis static size_t
kiconvstr_to_koi8r(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1241*d14d7d31Sis kiconvstr_to_koi8r(char *inarray, size_t *inlen, char *outarray,
1242*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1243*d14d7d31Sis {
1244*d14d7d31Sis 	return (kiconvstr_to_sb(KICONV_TBLID_KOI8_R, (uchar_t *)inarray,
1245*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1246*d14d7d31Sis }
1247*d14d7d31Sis 
1248*d14d7d31Sis /*
1249*d14d7d31Sis  * The following is the common kiconvstr function for the conversions from
1250*d14d7d31Sis  * single byte codeset to UTF-8.
1251*d14d7d31Sis  */
1252*d14d7d31Sis static size_t
kiconvstr_fr_sb(size_t id,uchar_t * ib,size_t * inlen,uchar_t * ob,size_t * outlen,int flag,int * errno)1253*d14d7d31Sis kiconvstr_fr_sb(size_t id, uchar_t *ib, size_t *inlen, uchar_t *ob,
1254*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1255*d14d7d31Sis {
1256*d14d7d31Sis 	kiconv_to_utf8_tbl_comp_t *tbl;
1257*d14d7d31Sis 	size_t ret_val;
1258*d14d7d31Sis 	uchar_t *ibtail;
1259*d14d7d31Sis 	uchar_t *obtail;
1260*d14d7d31Sis 	size_t i;
1261*d14d7d31Sis 	size_t k;
1262*d14d7d31Sis 	int8_t sz;
1263*d14d7d31Sis 	boolean_t do_not_ignore_null;
1264*d14d7d31Sis 
1265*d14d7d31Sis 	if (id > KICONV_MAX_MAPPING_TBLID &&
1266*d14d7d31Sis 	    (id < KICONV_TBLID_RANGE1_START || id > KICONV_TBLID_RANGE1_END)) {
1267*d14d7d31Sis 		*errno = EBADF;
1268*d14d7d31Sis 		return ((size_t)-1);
1269*d14d7d31Sis 	}
1270*d14d7d31Sis 
1271*d14d7d31Sis 	ret_val = 0;
1272*d14d7d31Sis 	ibtail = ib + *inlen;
1273*d14d7d31Sis 	obtail = ob + *outlen;
1274*d14d7d31Sis 	do_not_ignore_null = ((flag & KICONV_IGNORE_NULL) == 0);
1275*d14d7d31Sis 
1276*d14d7d31Sis 	tbl = (id == KICONV_TBLID_720) ?
1277*d14d7d31Sis 	    (kiconv_to_utf8_tbl_comp_t *)cp720_to_u8_tbl :
1278*d14d7d31Sis 	    (kiconv_to_utf8_tbl_comp_t *)to_u8_tbl[id];
1279*d14d7d31Sis 
1280*d14d7d31Sis 	while (ib < ibtail) {
1281*d14d7d31Sis 		if (*ib == '\0' && do_not_ignore_null)
1282*d14d7d31Sis 			break;
1283*d14d7d31Sis 
1284*d14d7d31Sis 		if (*ib < 0x80) {
1285*d14d7d31Sis 			if (ob >= obtail) {
1286*d14d7d31Sis 				*errno = E2BIG;
1287*d14d7d31Sis 				ret_val = (size_t)-1;
1288*d14d7d31Sis 				break;
1289*d14d7d31Sis 			}
1290*d14d7d31Sis 			*ob++ = *ib++;
1291*d14d7d31Sis 			continue;
1292*d14d7d31Sis 		}
1293*d14d7d31Sis 
1294*d14d7d31Sis 		k = *ib - 0x80;
1295*d14d7d31Sis 		sz = u8_number_of_bytes[tbl[k].u8[0]];
1296*d14d7d31Sis 
1297*d14d7d31Sis 		if (sz <= 0) {
1298*d14d7d31Sis 			if (flag & KICONV_REPLACE_INVALID) {
1299*d14d7d31Sis 				if ((obtail - ob) < 3) {
1300*d14d7d31Sis 					*errno = E2BIG;
1301*d14d7d31Sis 					ret_val = (size_t)-1;
1302*d14d7d31Sis 					break;
1303*d14d7d31Sis 				}
1304*d14d7d31Sis 
1305*d14d7d31Sis 				/* Save KICONV_UTF8_REPLACEMENT_CHAR. */
1306*d14d7d31Sis 				*ob++ = 0xef;
1307*d14d7d31Sis 				*ob++ = 0xbf;
1308*d14d7d31Sis 				*ob++ = 0xbd;
1309*d14d7d31Sis 				ret_val++;
1310*d14d7d31Sis 				ib++;
1311*d14d7d31Sis 
1312*d14d7d31Sis 				continue;
1313*d14d7d31Sis 			}
1314*d14d7d31Sis 
1315*d14d7d31Sis 			*errno = EILSEQ;
1316*d14d7d31Sis 			ret_val = (size_t)-1;
1317*d14d7d31Sis 			break;
1318*d14d7d31Sis 		}
1319*d14d7d31Sis 
1320*d14d7d31Sis 		if ((obtail - ob) < sz) {
1321*d14d7d31Sis 			*errno = E2BIG;
1322*d14d7d31Sis 			ret_val = (size_t)-1;
1323*d14d7d31Sis 			break;
1324*d14d7d31Sis 		}
1325*d14d7d31Sis 
1326*d14d7d31Sis 		for (i = 0; i < sz; i++)
1327*d14d7d31Sis 			*ob++ = tbl[k].u8[i];
1328*d14d7d31Sis 
1329*d14d7d31Sis 		ib++;
1330*d14d7d31Sis 	}
1331*d14d7d31Sis 
1332*d14d7d31Sis 	*inlen = ibtail - ib;
1333*d14d7d31Sis 	*outlen = obtail - ob;
1334*d14d7d31Sis 
1335*d14d7d31Sis 	return (ret_val);
1336*d14d7d31Sis }
1337*d14d7d31Sis 
1338*d14d7d31Sis /*
1339*d14d7d31Sis  * The following 25 functions are the real entry points that will be
1340*d14d7d31Sis  * given to kiconv framework at the genunix.
1341*d14d7d31Sis  */
1342*d14d7d31Sis static size_t
kiconvstr_fr_720(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1343*d14d7d31Sis kiconvstr_fr_720(char *inarray, size_t *inlen, char *outarray,
1344*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1345*d14d7d31Sis {
1346*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_720, (uchar_t *)inarray,
1347*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1348*d14d7d31Sis }
1349*d14d7d31Sis 
1350*d14d7d31Sis static size_t
kiconvstr_fr_737(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1351*d14d7d31Sis kiconvstr_fr_737(char *inarray, size_t *inlen, char *outarray,
1352*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1353*d14d7d31Sis {
1354*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_737, (uchar_t *)inarray,
1355*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1356*d14d7d31Sis }
1357*d14d7d31Sis 
1358*d14d7d31Sis static size_t
kiconvstr_fr_852(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1359*d14d7d31Sis kiconvstr_fr_852(char *inarray, size_t *inlen, char *outarray,
1360*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1361*d14d7d31Sis {
1362*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_852, (uchar_t *)inarray,
1363*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1364*d14d7d31Sis }
1365*d14d7d31Sis 
1366*d14d7d31Sis static size_t
kiconvstr_fr_857(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1367*d14d7d31Sis kiconvstr_fr_857(char *inarray, size_t *inlen, char *outarray,
1368*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1369*d14d7d31Sis {
1370*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_857, (uchar_t *)inarray,
1371*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1372*d14d7d31Sis }
1373*d14d7d31Sis 
1374*d14d7d31Sis static size_t
kiconvstr_fr_862(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1375*d14d7d31Sis kiconvstr_fr_862(char *inarray, size_t *inlen, char *outarray,
1376*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1377*d14d7d31Sis {
1378*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_862, (uchar_t *)inarray,
1379*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1380*d14d7d31Sis }
1381*d14d7d31Sis 
1382*d14d7d31Sis static size_t
kiconvstr_fr_866(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1383*d14d7d31Sis kiconvstr_fr_866(char *inarray, size_t *inlen, char *outarray,
1384*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1385*d14d7d31Sis {
1386*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_866, (uchar_t *)inarray,
1387*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1388*d14d7d31Sis }
1389*d14d7d31Sis 
1390*d14d7d31Sis static size_t
kiconvstr_fr_1250(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1391*d14d7d31Sis kiconvstr_fr_1250(char *inarray, size_t *inlen, char *outarray,
1392*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1393*d14d7d31Sis {
1394*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_1250, (uchar_t *)inarray,
1395*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1396*d14d7d31Sis }
1397*d14d7d31Sis 
1398*d14d7d31Sis static size_t
kiconvstr_fr_1251(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1399*d14d7d31Sis kiconvstr_fr_1251(char *inarray, size_t *inlen, char *outarray,
1400*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1401*d14d7d31Sis {
1402*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_1251, (uchar_t *)inarray,
1403*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1404*d14d7d31Sis }
1405*d14d7d31Sis 
1406*d14d7d31Sis static size_t
kiconvstr_fr_1253(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1407*d14d7d31Sis kiconvstr_fr_1253(char *inarray, size_t *inlen, char *outarray,
1408*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1409*d14d7d31Sis {
1410*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_1253, (uchar_t *)inarray,
1411*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1412*d14d7d31Sis }
1413*d14d7d31Sis 
1414*d14d7d31Sis static size_t
kiconvstr_fr_1254(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1415*d14d7d31Sis kiconvstr_fr_1254(char *inarray, size_t *inlen, char *outarray,
1416*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1417*d14d7d31Sis {
1418*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_1254, (uchar_t *)inarray,
1419*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1420*d14d7d31Sis }
1421*d14d7d31Sis 
1422*d14d7d31Sis static size_t
kiconvstr_fr_1255(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1423*d14d7d31Sis kiconvstr_fr_1255(char *inarray, size_t *inlen, char *outarray,
1424*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1425*d14d7d31Sis {
1426*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_1255, (uchar_t *)inarray,
1427*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1428*d14d7d31Sis }
1429*d14d7d31Sis 
1430*d14d7d31Sis static size_t
kiconvstr_fr_1256(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1431*d14d7d31Sis kiconvstr_fr_1256(char *inarray, size_t *inlen, char *outarray,
1432*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1433*d14d7d31Sis {
1434*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_1256, (uchar_t *)inarray,
1435*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1436*d14d7d31Sis }
1437*d14d7d31Sis 
1438*d14d7d31Sis static size_t
kiconvstr_fr_1257(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1439*d14d7d31Sis kiconvstr_fr_1257(char *inarray, size_t *inlen, char *outarray,
1440*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1441*d14d7d31Sis {
1442*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_1257, (uchar_t *)inarray,
1443*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1444*d14d7d31Sis }
1445*d14d7d31Sis 
1446*d14d7d31Sis static size_t
kiconvstr_fr_88592(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1447*d14d7d31Sis kiconvstr_fr_88592(char *inarray, size_t *inlen, char *outarray,
1448*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1449*d14d7d31Sis {
1450*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_8859_2, (uchar_t *)inarray,
1451*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1452*d14d7d31Sis }
1453*d14d7d31Sis 
1454*d14d7d31Sis static size_t
kiconvstr_fr_88593(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1455*d14d7d31Sis kiconvstr_fr_88593(char *inarray, size_t *inlen, char *outarray,
1456*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1457*d14d7d31Sis {
1458*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_8859_3, (uchar_t *)inarray,
1459*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1460*d14d7d31Sis }
1461*d14d7d31Sis 
1462*d14d7d31Sis static size_t
kiconvstr_fr_88594(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1463*d14d7d31Sis kiconvstr_fr_88594(char *inarray, size_t *inlen, char *outarray,
1464*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1465*d14d7d31Sis {
1466*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_8859_4, (uchar_t *)inarray,
1467*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1468*d14d7d31Sis }
1469*d14d7d31Sis 
1470*d14d7d31Sis static size_t
kiconvstr_fr_88595(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1471*d14d7d31Sis kiconvstr_fr_88595(char *inarray, size_t *inlen, char *outarray,
1472*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1473*d14d7d31Sis {
1474*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_8859_5, (uchar_t *)inarray,
1475*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1476*d14d7d31Sis }
1477*d14d7d31Sis 
1478*d14d7d31Sis static size_t
kiconvstr_fr_88596(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1479*d14d7d31Sis kiconvstr_fr_88596(char *inarray, size_t *inlen, char *outarray,
1480*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1481*d14d7d31Sis {
1482*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_8859_6, (uchar_t *)inarray,
1483*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1484*d14d7d31Sis }
1485*d14d7d31Sis 
1486*d14d7d31Sis static size_t
kiconvstr_fr_88597(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1487*d14d7d31Sis kiconvstr_fr_88597(char *inarray, size_t *inlen, char *outarray,
1488*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1489*d14d7d31Sis {
1490*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_8859_7, (uchar_t *)inarray,
1491*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1492*d14d7d31Sis }
1493*d14d7d31Sis 
1494*d14d7d31Sis static size_t
kiconvstr_fr_88598(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1495*d14d7d31Sis kiconvstr_fr_88598(char *inarray, size_t *inlen, char *outarray,
1496*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1497*d14d7d31Sis {
1498*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_8859_8, (uchar_t *)inarray,
1499*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1500*d14d7d31Sis }
1501*d14d7d31Sis 
1502*d14d7d31Sis static size_t
kiconvstr_fr_88599(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1503*d14d7d31Sis kiconvstr_fr_88599(char *inarray, size_t *inlen, char *outarray,
1504*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1505*d14d7d31Sis {
1506*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_8859_9, (uchar_t *)inarray,
1507*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1508*d14d7d31Sis }
1509*d14d7d31Sis 
1510*d14d7d31Sis static size_t
kiconvstr_fr_885910(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1511*d14d7d31Sis kiconvstr_fr_885910(char *inarray, size_t *inlen, char *outarray,
1512*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1513*d14d7d31Sis {
1514*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_8859_10, (uchar_t *)inarray,
1515*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1516*d14d7d31Sis }
1517*d14d7d31Sis 
1518*d14d7d31Sis static size_t
kiconvstr_fr_885911(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1519*d14d7d31Sis kiconvstr_fr_885911(char *inarray, size_t *inlen, char *outarray,
1520*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1521*d14d7d31Sis {
1522*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_8859_11, (uchar_t *)inarray,
1523*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1524*d14d7d31Sis }
1525*d14d7d31Sis 
1526*d14d7d31Sis static size_t
kiconvstr_fr_885913(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1527*d14d7d31Sis kiconvstr_fr_885913(char *inarray, size_t *inlen, char *outarray,
1528*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1529*d14d7d31Sis {
1530*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_8859_13, (uchar_t *)inarray,
1531*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1532*d14d7d31Sis }
1533*d14d7d31Sis 
1534*d14d7d31Sis static size_t
kiconvstr_fr_koi8r(char * inarray,size_t * inlen,char * outarray,size_t * outlen,int flag,int * errno)1535*d14d7d31Sis kiconvstr_fr_koi8r(char *inarray, size_t *inlen, char *outarray,
1536*d14d7d31Sis 	size_t *outlen, int flag, int *errno)
1537*d14d7d31Sis {
1538*d14d7d31Sis 	return (kiconvstr_fr_sb(KICONV_TBLID_KOI8_R, (uchar_t *)inarray,
1539*d14d7d31Sis 	    inlen, (uchar_t *)outarray, outlen, flag, errno));
1540*d14d7d31Sis }
1541*d14d7d31Sis 
1542*d14d7d31Sis 
1543*d14d7d31Sis /*
1544*d14d7d31Sis  * The following are the supported code conversions that will be passed to
1545*d14d7d31Sis  * and registered from this module. The tocode and fromcode names are
1546*d14d7d31Sis  * normalized.
1547*d14d7d31Sis  */
1548*d14d7d31Sis #define	KICONV_MAX_EMEA_OPS		50
1549*d14d7d31Sis 
1550*d14d7d31Sis static kiconv_ops_t kiconv_emea_ops[KICONV_MAX_EMEA_OPS] = {
1551*d14d7d31Sis 	{
1552*d14d7d31Sis 		"utf8", "cp1250",
1553*d14d7d31Sis 		open_fr_1250, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1250
1554*d14d7d31Sis 	},
1555*d14d7d31Sis 	{
1556*d14d7d31Sis 		"cp1250", "utf8",
1557*d14d7d31Sis 		open_to_1250, kiconv_to_sb, close_to_sb, kiconvstr_to_1250
1558*d14d7d31Sis 	},
1559*d14d7d31Sis 	{
1560*d14d7d31Sis 		"utf8", "iso88592",
1561*d14d7d31Sis 		open_fr_88592, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88592
1562*d14d7d31Sis 	},
1563*d14d7d31Sis 	{
1564*d14d7d31Sis 		"iso88592", "utf8",
1565*d14d7d31Sis 		open_to_88592, kiconv_to_sb, close_to_sb, kiconvstr_to_88592
1566*d14d7d31Sis 	},
1567*d14d7d31Sis 	{
1568*d14d7d31Sis 		"utf8", "cp852",
1569*d14d7d31Sis 		open_fr_852, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_852
1570*d14d7d31Sis 	},
1571*d14d7d31Sis 	{
1572*d14d7d31Sis 		"cp852", "utf8",
1573*d14d7d31Sis 		open_to_852, kiconv_to_sb, close_to_sb, kiconvstr_to_852
1574*d14d7d31Sis 	},
1575*d14d7d31Sis 	{
1576*d14d7d31Sis 		"utf8", "cp1251",
1577*d14d7d31Sis 		open_fr_1251, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1251
1578*d14d7d31Sis 	},
1579*d14d7d31Sis 	{
1580*d14d7d31Sis 		"cp1251", "utf8",
1581*d14d7d31Sis 		open_to_1251, kiconv_to_sb, close_to_sb, kiconvstr_to_1251
1582*d14d7d31Sis 	},
1583*d14d7d31Sis 	{
1584*d14d7d31Sis 		"utf8", "iso88595",
1585*d14d7d31Sis 		open_fr_88595, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88595
1586*d14d7d31Sis 	},
1587*d14d7d31Sis 	{
1588*d14d7d31Sis 		"iso88595", "utf8",
1589*d14d7d31Sis 		open_to_88595, kiconv_to_sb, close_to_sb, kiconvstr_to_88595
1590*d14d7d31Sis 	},
1591*d14d7d31Sis 	{
1592*d14d7d31Sis 		"utf8", "koi8r",
1593*d14d7d31Sis 		open_fr_koi8r, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_koi8r
1594*d14d7d31Sis 	},
1595*d14d7d31Sis 	{
1596*d14d7d31Sis 		"koi8r", "utf8",
1597*d14d7d31Sis 		open_to_koi8r, kiconv_to_sb, close_to_sb, kiconvstr_to_koi8r
1598*d14d7d31Sis 	},
1599*d14d7d31Sis 	{
1600*d14d7d31Sis 		"utf8", "cp866",
1601*d14d7d31Sis 		open_fr_866, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_866
1602*d14d7d31Sis 	},
1603*d14d7d31Sis 	{
1604*d14d7d31Sis 		"cp866", "utf8",
1605*d14d7d31Sis 		open_to_866, kiconv_to_sb, close_to_sb, kiconvstr_to_866
1606*d14d7d31Sis 	},
1607*d14d7d31Sis 	{
1608*d14d7d31Sis 		"utf8", "cp1253",
1609*d14d7d31Sis 		open_fr_1253, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1253
1610*d14d7d31Sis 	},
1611*d14d7d31Sis 	{
1612*d14d7d31Sis 		"cp1253", "utf8",
1613*d14d7d31Sis 		open_to_1253, kiconv_to_sb, close_to_sb, kiconvstr_to_1253
1614*d14d7d31Sis 	},
1615*d14d7d31Sis 	{
1616*d14d7d31Sis 		"utf8", "iso88597",
1617*d14d7d31Sis 		open_fr_88597, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88597
1618*d14d7d31Sis 	},
1619*d14d7d31Sis 	{
1620*d14d7d31Sis 		"iso88597", "utf8",
1621*d14d7d31Sis 		open_to_88597, kiconv_to_sb, close_to_sb, kiconvstr_to_88597
1622*d14d7d31Sis 	},
1623*d14d7d31Sis 	{
1624*d14d7d31Sis 		"utf8", "cp737",
1625*d14d7d31Sis 		open_fr_737, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_737
1626*d14d7d31Sis 	},
1627*d14d7d31Sis 	{
1628*d14d7d31Sis 		"cp737", "utf8",
1629*d14d7d31Sis 		open_to_737, kiconv_to_sb, close_to_sb, kiconvstr_to_737
1630*d14d7d31Sis 	},
1631*d14d7d31Sis 	{
1632*d14d7d31Sis 		"utf8", "cp1254",
1633*d14d7d31Sis 		open_fr_1254, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1254
1634*d14d7d31Sis 	},
1635*d14d7d31Sis 	{
1636*d14d7d31Sis 		"cp1254", "utf8",
1637*d14d7d31Sis 		open_to_1254, kiconv_to_sb, close_to_sb, kiconvstr_to_1254
1638*d14d7d31Sis 	},
1639*d14d7d31Sis 	{
1640*d14d7d31Sis 		"utf8", "iso88599",
1641*d14d7d31Sis 		open_fr_88599, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88599
1642*d14d7d31Sis 	},
1643*d14d7d31Sis 	{
1644*d14d7d31Sis 		"iso88599", "utf8",
1645*d14d7d31Sis 		open_to_88599, kiconv_to_sb, close_to_sb, kiconvstr_to_88599
1646*d14d7d31Sis 	},
1647*d14d7d31Sis 	{
1648*d14d7d31Sis 		"utf8", "cp857",
1649*d14d7d31Sis 		open_fr_857, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_857
1650*d14d7d31Sis 	},
1651*d14d7d31Sis 	{
1652*d14d7d31Sis 		"cp857", "utf8",
1653*d14d7d31Sis 		open_to_857, kiconv_to_sb, close_to_sb, kiconvstr_to_857
1654*d14d7d31Sis 	},
1655*d14d7d31Sis 	{
1656*d14d7d31Sis 		"utf8", "cp1256",
1657*d14d7d31Sis 		open_fr_1256, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1256
1658*d14d7d31Sis 	},
1659*d14d7d31Sis 	{
1660*d14d7d31Sis 		"cp1256", "utf8",
1661*d14d7d31Sis 		open_to_1256, kiconv_to_sb, close_to_sb, kiconvstr_to_1256
1662*d14d7d31Sis 	},
1663*d14d7d31Sis 	{
1664*d14d7d31Sis 		"utf8", "iso88596",
1665*d14d7d31Sis 		open_fr_88596, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88596
1666*d14d7d31Sis 	},
1667*d14d7d31Sis 	{
1668*d14d7d31Sis 		"iso88596", "utf8",
1669*d14d7d31Sis 		open_to_88596, kiconv_to_sb, close_to_sb, kiconvstr_to_88596
1670*d14d7d31Sis 	},
1671*d14d7d31Sis 	{
1672*d14d7d31Sis 		"utf8", "cp720",
1673*d14d7d31Sis 		open_fr_720, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_720
1674*d14d7d31Sis 	},
1675*d14d7d31Sis 	{
1676*d14d7d31Sis 		"cp720", "utf8",
1677*d14d7d31Sis 		open_to_720, kiconv_to_sb, close_to_sb, kiconvstr_to_720
1678*d14d7d31Sis 	},
1679*d14d7d31Sis 	{
1680*d14d7d31Sis 		"utf8", "cp1255",
1681*d14d7d31Sis 		open_fr_1255, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1255
1682*d14d7d31Sis 	},
1683*d14d7d31Sis 	{
1684*d14d7d31Sis 		"cp1255", "utf8",
1685*d14d7d31Sis 		open_to_1255, kiconv_to_sb, close_to_sb, kiconvstr_to_1255
1686*d14d7d31Sis 	},
1687*d14d7d31Sis 	{
1688*d14d7d31Sis 		"utf8", "iso88598",
1689*d14d7d31Sis 		open_fr_88598, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88598
1690*d14d7d31Sis 	},
1691*d14d7d31Sis 	{
1692*d14d7d31Sis 		"iso88598", "utf8",
1693*d14d7d31Sis 		open_to_88598, kiconv_to_sb, close_to_sb, kiconvstr_to_88598
1694*d14d7d31Sis 	},
1695*d14d7d31Sis 	{
1696*d14d7d31Sis 		"utf8", "cp862",
1697*d14d7d31Sis 		open_fr_862, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_862
1698*d14d7d31Sis 	},
1699*d14d7d31Sis 	{
1700*d14d7d31Sis 		"cp862", "utf8",
1701*d14d7d31Sis 		open_to_862, kiconv_to_sb, close_to_sb, kiconvstr_to_862
1702*d14d7d31Sis 	},
1703*d14d7d31Sis 	{
1704*d14d7d31Sis 		"utf8", "cp1257",
1705*d14d7d31Sis 		open_fr_1257, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1257
1706*d14d7d31Sis 	},
1707*d14d7d31Sis 	{
1708*d14d7d31Sis 		"cp1257", "utf8",
1709*d14d7d31Sis 		open_to_1257, kiconv_to_sb, close_to_sb, kiconvstr_to_1257
1710*d14d7d31Sis 	},
1711*d14d7d31Sis 	{
1712*d14d7d31Sis 		"utf8", "iso885913",
1713*d14d7d31Sis 		open_fr_885913, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_885913
1714*d14d7d31Sis 	},
1715*d14d7d31Sis 	{
1716*d14d7d31Sis 		"iso885913", "utf8",
1717*d14d7d31Sis 		open_to_885913, kiconv_to_sb, close_to_sb, kiconvstr_to_885913
1718*d14d7d31Sis 	},
1719*d14d7d31Sis 	{
1720*d14d7d31Sis 		"utf8", "iso885910",
1721*d14d7d31Sis 		open_fr_885910, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_885910
1722*d14d7d31Sis 	},
1723*d14d7d31Sis 	{
1724*d14d7d31Sis 		"iso885910", "utf8",
1725*d14d7d31Sis 		open_to_885910, kiconv_to_sb, close_to_sb, kiconvstr_to_885910
1726*d14d7d31Sis 	},
1727*d14d7d31Sis 	{
1728*d14d7d31Sis 		"utf8", "iso885911",
1729*d14d7d31Sis 		open_fr_885911, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_885911
1730*d14d7d31Sis 	},
1731*d14d7d31Sis 	{
1732*d14d7d31Sis 		"iso885911", "utf8",
1733*d14d7d31Sis 		open_to_885911, kiconv_to_sb, close_to_sb, kiconvstr_to_885911
1734*d14d7d31Sis 	},
1735*d14d7d31Sis 	{
1736*d14d7d31Sis 		"utf8", "iso88593",
1737*d14d7d31Sis 		open_fr_88593, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88593
1738*d14d7d31Sis 	},
1739*d14d7d31Sis 	{
1740*d14d7d31Sis 		"iso88593", "utf8",
1741*d14d7d31Sis 		open_to_88593, kiconv_to_sb, close_to_sb, kiconvstr_to_88593
1742*d14d7d31Sis 	},
1743*d14d7d31Sis 	{
1744*d14d7d31Sis 		"utf8", "iso88594",
1745*d14d7d31Sis 		open_fr_88594, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88594
1746*d14d7d31Sis 	},
1747*d14d7d31Sis 	{
1748*d14d7d31Sis 		"iso88594", "utf8",
1749*d14d7d31Sis 		open_to_88594, kiconv_to_sb, close_to_sb, kiconvstr_to_88594
1750*d14d7d31Sis 	},
1751*d14d7d31Sis };
1752*d14d7d31Sis 
1753*d14d7d31Sis static kiconv_module_info_t kiconv_emea_modinfo = {
1754*d14d7d31Sis 	"kiconv_emea",		/* Must be the same as in kiconv framework. */
1755*d14d7d31Sis 	KICONV_MAX_EMEA_OPS,	/* size_t kiconv_num_convs */
1756*d14d7d31Sis 	kiconv_emea_ops,	/* kiconv_ops_t *kiconv_ops_tbl */
1757*d14d7d31Sis 	0,			/* size_t kiconv_num_aliases */
1758*d14d7d31Sis 	NULL,			/* char **aliases */
1759*d14d7d31Sis 	NULL,			/* char **canonicals */
1760*d14d7d31Sis 	0			/* int nowait */
1761*d14d7d31Sis };
1762*d14d7d31Sis 
1763*d14d7d31Sis static struct modlkiconv kiconv_emea = {
1764*d14d7d31Sis 	&mod_kiconvops,
1765*d14d7d31Sis 	"kiconv module for EMEA",
1766*d14d7d31Sis 	&kiconv_emea_modinfo
1767*d14d7d31Sis };
1768*d14d7d31Sis 
1769*d14d7d31Sis static struct modlinkage linkage = {
1770*d14d7d31Sis 	MODREV_1,
1771*d14d7d31Sis 	(void *)&kiconv_emea,
1772*d14d7d31Sis 	NULL
1773*d14d7d31Sis };
1774*d14d7d31Sis 
1775*d14d7d31Sis int
_init()1776*d14d7d31Sis _init()
1777*d14d7d31Sis {
1778*d14d7d31Sis 	int err;
1779*d14d7d31Sis 
1780*d14d7d31Sis 	err = mod_install(&linkage);
1781*d14d7d31Sis 	if (err)
1782*d14d7d31Sis 		cmn_err(CE_WARN, "kiconv_emea: failed to load kernel module");
1783*d14d7d31Sis 
1784*d14d7d31Sis 	return (err);
1785*d14d7d31Sis }
1786*d14d7d31Sis 
1787*d14d7d31Sis int
_info(struct modinfo * modinfop)1788*d14d7d31Sis _info(struct modinfo *modinfop)
1789*d14d7d31Sis {
1790*d14d7d31Sis 	return (mod_info(&linkage, modinfop));
1791*d14d7d31Sis }
1792*d14d7d31Sis 
1793*d14d7d31Sis int
_fini()1794*d14d7d31Sis _fini()
1795*d14d7d31Sis {
1796*d14d7d31Sis 	int err;
1797*d14d7d31Sis 
1798*d14d7d31Sis 	/*
1799*d14d7d31Sis 	 * If this module is being used, then, we cannot remove the module.
1800*d14d7d31Sis 	 * The following checking will catch pretty much all usual cases.
1801*d14d7d31Sis 	 *
1802*d14d7d31Sis 	 * Any remaining will be catached by the kiconv_unregister_module()
1803*d14d7d31Sis 	 * during mod_remove() at below.
1804*d14d7d31Sis 	 */
1805*d14d7d31Sis 	if (kiconv_module_ref_count(KICONV_MODULE_ID_EMEA))
1806*d14d7d31Sis 		return (EBUSY);
1807*d14d7d31Sis 
1808*d14d7d31Sis 	err = mod_remove(&linkage);
1809*d14d7d31Sis 	if (err)
1810*d14d7d31Sis 		cmn_err(CE_WARN, "kiconv_emea: failed to remove kernel module");
1811*d14d7d31Sis 
1812*d14d7d31Sis 	return (err);
1813*d14d7d31Sis }
1814