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