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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 411 open_fr_720() 412 { 413 return ((void *)KICONV_TBLID_720); 414 } 415 416 static void * 417 open_fr_737() 418 { 419 return ((void *)KICONV_TBLID_737); 420 } 421 422 static void * 423 open_fr_852() 424 { 425 return ((void *)KICONV_TBLID_852); 426 } 427 428 static void * 429 open_fr_857() 430 { 431 return ((void *)KICONV_TBLID_857); 432 } 433 434 static void * 435 open_fr_862() 436 { 437 return ((void *)KICONV_TBLID_862); 438 } 439 440 static void * 441 open_fr_866() 442 { 443 return ((void *)KICONV_TBLID_866); 444 } 445 446 static void * 447 open_fr_1250() 448 { 449 return ((void *)KICONV_TBLID_1250); 450 } 451 452 static void * 453 open_fr_1251() 454 { 455 return ((void *)KICONV_TBLID_1251); 456 } 457 458 static void * 459 open_fr_1253() 460 { 461 return ((void *)KICONV_TBLID_1253); 462 } 463 464 static void * 465 open_fr_1254() 466 { 467 return ((void *)KICONV_TBLID_1254); 468 } 469 470 static void * 471 open_fr_1255() 472 { 473 return ((void *)KICONV_TBLID_1255); 474 } 475 476 static void * 477 open_fr_1256() 478 { 479 return ((void *)KICONV_TBLID_1256); 480 } 481 482 static void * 483 open_fr_1257() 484 { 485 return ((void *)KICONV_TBLID_1257); 486 } 487 488 static void * 489 open_fr_88592() 490 { 491 return ((void *)KICONV_TBLID_8859_2); 492 } 493 494 static void * 495 open_fr_88593() 496 { 497 return ((void *)KICONV_TBLID_8859_3); 498 } 499 500 static void * 501 open_fr_88594() 502 { 503 return ((void *)KICONV_TBLID_8859_4); 504 } 505 506 static void * 507 open_fr_88595() 508 { 509 return ((void *)KICONV_TBLID_8859_5); 510 } 511 512 static void * 513 open_fr_88596() 514 { 515 return ((void *)KICONV_TBLID_8859_6); 516 } 517 518 static void * 519 open_fr_88597() 520 { 521 return ((void *)KICONV_TBLID_8859_7); 522 } 523 524 static void * 525 open_fr_88598() 526 { 527 return ((void *)KICONV_TBLID_8859_8); 528 } 529 530 static void * 531 open_fr_88599() 532 { 533 return ((void *)KICONV_TBLID_8859_9); 534 } 535 536 static void * 537 open_fr_885910() 538 { 539 return ((void *)KICONV_TBLID_8859_10); 540 } 541 542 static void * 543 open_fr_885911() 544 { 545 return ((void *)KICONV_TBLID_8859_11); 546 } 547 548 static void * 549 open_fr_885913() 550 { 551 return ((void *)KICONV_TBLID_8859_13); 552 } 553 554 static void * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 1790 _info(struct modinfo *modinfop) 1791 { 1792 return (mod_info(&linkage, modinfop)); 1793 } 1794 1795 int 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