kiconv_emea.c revision 5206:34f0b41fc3c5
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 */ 97extern const int8_t u8_number_of_bytes[]; 98extern const uint8_t u8_valid_min_2nd_byte[]; 99extern 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 */ 106static void * 107open_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 118static void * 119open_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 130static void * 131open_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 142static void * 143open_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 154static void * 155open_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 166static void * 167open_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 178static void * 179open_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 190static void * 191open_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 202static void * 203open_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 214static void * 215open_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 226static void * 227open_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 238static void * 239open_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 250static void * 251open_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 262static void * 263open_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 274static void * 275open_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 286static void * 287open_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 298static void * 299open_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 310static void * 311open_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 322static void * 323open_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 334static void * 335open_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 346static void * 347open_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 358static void * 359open_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 370static void * 371open_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 382static void * 383open_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 394static void * 395open_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 */ 410static void * 411open_fr_720() 412{ 413 return ((void *)KICONV_TBLID_720); 414} 415 416static void * 417open_fr_737() 418{ 419 return ((void *)KICONV_TBLID_737); 420} 421 422static void * 423open_fr_852() 424{ 425 return ((void *)KICONV_TBLID_852); 426} 427 428static void * 429open_fr_857() 430{ 431 return ((void *)KICONV_TBLID_857); 432} 433 434static void * 435open_fr_862() 436{ 437 return ((void *)KICONV_TBLID_862); 438} 439 440static void * 441open_fr_866() 442{ 443 return ((void *)KICONV_TBLID_866); 444} 445 446static void * 447open_fr_1250() 448{ 449 return ((void *)KICONV_TBLID_1250); 450} 451 452static void * 453open_fr_1251() 454{ 455 return ((void *)KICONV_TBLID_1251); 456} 457 458static void * 459open_fr_1253() 460{ 461 return ((void *)KICONV_TBLID_1253); 462} 463 464static void * 465open_fr_1254() 466{ 467 return ((void *)KICONV_TBLID_1254); 468} 469 470static void * 471open_fr_1255() 472{ 473 return ((void *)KICONV_TBLID_1255); 474} 475 476static void * 477open_fr_1256() 478{ 479 return ((void *)KICONV_TBLID_1256); 480} 481 482static void * 483open_fr_1257() 484{ 485 return ((void *)KICONV_TBLID_1257); 486} 487 488static void * 489open_fr_88592() 490{ 491 return ((void *)KICONV_TBLID_8859_2); 492} 493 494static void * 495open_fr_88593() 496{ 497 return ((void *)KICONV_TBLID_8859_3); 498} 499 500static void * 501open_fr_88594() 502{ 503 return ((void *)KICONV_TBLID_8859_4); 504} 505 506static void * 507open_fr_88595() 508{ 509 return ((void *)KICONV_TBLID_8859_5); 510} 511 512static void * 513open_fr_88596() 514{ 515 return ((void *)KICONV_TBLID_8859_6); 516} 517 518static void * 519open_fr_88597() 520{ 521 return ((void *)KICONV_TBLID_8859_7); 522} 523 524static void * 525open_fr_88598() 526{ 527 return ((void *)KICONV_TBLID_8859_8); 528} 529 530static void * 531open_fr_88599() 532{ 533 return ((void *)KICONV_TBLID_8859_9); 534} 535 536static void * 537open_fr_885910() 538{ 539 return ((void *)KICONV_TBLID_8859_10); 540} 541 542static void * 543open_fr_885911() 544{ 545 return ((void *)KICONV_TBLID_8859_11); 546} 547 548static void * 549open_fr_885913() 550{ 551 return ((void *)KICONV_TBLID_8859_13); 552} 553 554static void * 555open_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 */ 564static int 565close_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 */ 579static int 580close_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 */ 599static size_t 600kiconv_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 779TO_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 */ 792static size_t 793kiconv_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 */ 892static size_t 893kiconvstr_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 { 1033STR_TO_SB_REPLACE_INVALID: 1034 *ob++ = KICONV_ASCII_REPLACEMENT_CHAR; 1035 ret_val++; 1036 } 1037 } 1038 1039STR_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 */ 1050static size_t 1051kiconvstr_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 1058static size_t 1059kiconvstr_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 1066static size_t 1067kiconvstr_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 1074static size_t 1075kiconvstr_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 1082static size_t 1083kiconvstr_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 1090static size_t 1091kiconvstr_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 1098static size_t 1099kiconvstr_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 1106static size_t 1107kiconvstr_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 1114static size_t 1115kiconvstr_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 1122static size_t 1123kiconvstr_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 1130static size_t 1131kiconvstr_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 1138static size_t 1139kiconvstr_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 1146static size_t 1147kiconvstr_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 1154static size_t 1155kiconvstr_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 1162static size_t 1163kiconvstr_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 1170static size_t 1171kiconvstr_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 1178static size_t 1179kiconvstr_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 1186static size_t 1187kiconvstr_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 1194static size_t 1195kiconvstr_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 1202static size_t 1203kiconvstr_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 1210static size_t 1211kiconvstr_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 1218static size_t 1219kiconvstr_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 1226static size_t 1227kiconvstr_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 1234static size_t 1235kiconvstr_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 1242static size_t 1243kiconvstr_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 */ 1254static size_t 1255kiconvstr_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 */ 1344static size_t 1345kiconvstr_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 1352static size_t 1353kiconvstr_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 1360static size_t 1361kiconvstr_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 1368static size_t 1369kiconvstr_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 1376static size_t 1377kiconvstr_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 1384static size_t 1385kiconvstr_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 1392static size_t 1393kiconvstr_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 1400static size_t 1401kiconvstr_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 1408static size_t 1409kiconvstr_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 1416static size_t 1417kiconvstr_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 1424static size_t 1425kiconvstr_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 1432static size_t 1433kiconvstr_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 1440static size_t 1441kiconvstr_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 1448static size_t 1449kiconvstr_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 1456static size_t 1457kiconvstr_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 1464static size_t 1465kiconvstr_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 1472static size_t 1473kiconvstr_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 1480static size_t 1481kiconvstr_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 1488static size_t 1489kiconvstr_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 1496static size_t 1497kiconvstr_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 1504static size_t 1505kiconvstr_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 1512static size_t 1513kiconvstr_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 1520static size_t 1521kiconvstr_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 1528static size_t 1529kiconvstr_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 1536static size_t 1537kiconvstr_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 1552static 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 1755static 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 1765static struct modlkiconv kiconv_emea = { 1766 &mod_kiconvops, 1767 "kiconv module for EMEA", 1768 &kiconv_emea_modinfo 1769}; 1770 1771static struct modlinkage linkage = { 1772 MODREV_1, 1773 (void *)&kiconv_emea, 1774 NULL 1775}; 1776 1777int 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 1789int 1790_info(struct modinfo *modinfop) 1791{ 1792 return (mod_info(&linkage, modinfop)); 1793} 1794 1795int 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