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