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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 409 open_fr_720() 410 { 411 return ((void *)KICONV_TBLID_720); 412 } 413 414 static void * 415 open_fr_737() 416 { 417 return ((void *)KICONV_TBLID_737); 418 } 419 420 static void * 421 open_fr_852() 422 { 423 return ((void *)KICONV_TBLID_852); 424 } 425 426 static void * 427 open_fr_857() 428 { 429 return ((void *)KICONV_TBLID_857); 430 } 431 432 static void * 433 open_fr_862() 434 { 435 return ((void *)KICONV_TBLID_862); 436 } 437 438 static void * 439 open_fr_866() 440 { 441 return ((void *)KICONV_TBLID_866); 442 } 443 444 static void * 445 open_fr_1250() 446 { 447 return ((void *)KICONV_TBLID_1250); 448 } 449 450 static void * 451 open_fr_1251() 452 { 453 return ((void *)KICONV_TBLID_1251); 454 } 455 456 static void * 457 open_fr_1253() 458 { 459 return ((void *)KICONV_TBLID_1253); 460 } 461 462 static void * 463 open_fr_1254() 464 { 465 return ((void *)KICONV_TBLID_1254); 466 } 467 468 static void * 469 open_fr_1255() 470 { 471 return ((void *)KICONV_TBLID_1255); 472 } 473 474 static void * 475 open_fr_1256() 476 { 477 return ((void *)KICONV_TBLID_1256); 478 } 479 480 static void * 481 open_fr_1257() 482 { 483 return ((void *)KICONV_TBLID_1257); 484 } 485 486 static void * 487 open_fr_88592() 488 { 489 return ((void *)KICONV_TBLID_8859_2); 490 } 491 492 static void * 493 open_fr_88593() 494 { 495 return ((void *)KICONV_TBLID_8859_3); 496 } 497 498 static void * 499 open_fr_88594() 500 { 501 return ((void *)KICONV_TBLID_8859_4); 502 } 503 504 static void * 505 open_fr_88595() 506 { 507 return ((void *)KICONV_TBLID_8859_5); 508 } 509 510 static void * 511 open_fr_88596() 512 { 513 return ((void *)KICONV_TBLID_8859_6); 514 } 515 516 static void * 517 open_fr_88597() 518 { 519 return ((void *)KICONV_TBLID_8859_7); 520 } 521 522 static void * 523 open_fr_88598() 524 { 525 return ((void *)KICONV_TBLID_8859_8); 526 } 527 528 static void * 529 open_fr_88599() 530 { 531 return ((void *)KICONV_TBLID_8859_9); 532 } 533 534 static void * 535 open_fr_885910() 536 { 537 return ((void *)KICONV_TBLID_8859_10); 538 } 539 540 static void * 541 open_fr_885911() 542 { 543 return ((void *)KICONV_TBLID_8859_11); 544 } 545 546 static void * 547 open_fr_885913() 548 { 549 return ((void *)KICONV_TBLID_8859_13); 550 } 551 552 static void * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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, NULL } 1772 }; 1773 1774 int 1775 _init() 1776 { 1777 int err; 1778 1779 err = mod_install(&linkage); 1780 if (err) 1781 cmn_err(CE_WARN, "kiconv_emea: failed to load kernel module"); 1782 1783 return (err); 1784 } 1785 1786 int 1787 _info(struct modinfo *modinfop) 1788 { 1789 return (mod_info(&linkage, modinfop)); 1790 } 1791 1792 int 1793 _fini() 1794 { 1795 int err; 1796 1797 /* 1798 * If this module is being used, then, we cannot remove the module. 1799 * The following checking will catch pretty much all usual cases. 1800 * 1801 * Any remaining will be catached by the kiconv_unregister_module() 1802 * during mod_remove() at below. 1803 */ 1804 if (kiconv_module_ref_count(KICONV_MODULE_ID_EMEA)) 1805 return (EBUSY); 1806 1807 err = mod_remove(&linkage); 1808 if (err) 1809 cmn_err(CE_WARN, "kiconv_emea: failed to remove kernel module"); 1810 1811 return (err); 1812 }