Print this page
    
7127  remove -Wno-missing-braces from Makefile.uts
    
      
        | Split | Close | 
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/kiconv/kiconv_ko/kiconv_ko.c
          +++ new/usr/src/uts/common/kiconv/kiconv_ko/kiconv_ko.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  
    | ↓ open down ↓ | 16 lines elided | ↑ open up ↑ | 
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
  27      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  28      -
  29   27  #include <sys/types.h>
  30   28  #include <sys/param.h>
  31   29  #include <sys/sysmacros.h>
  32   30  #include <sys/systm.h>
  33   31  #include <sys/debug.h>
  34   32  #include <sys/kmem.h>
  35   33  #include <sys/sunddi.h>
  36   34  #include <sys/byteorder.h>
  37   35  #include <sys/errno.h>
  38   36  #include <sys/modctl.h>
  39   37  #include <sys/u8_textprep.h>
  40   38  #include <sys/kiconv.h>
  41   39  #include <sys/kiconv_cck_common.h>
  42   40  #include <sys/kiconv_ko.h>
  43   41  #include <sys/kiconv_uhc_utf8.h>
  44   42  #include <sys/kiconv_utf8_uhc.h>
  45   43  #include <sys/kiconv_euckr_utf8.h>
  46   44  #include <sys/kiconv_utf8_euckr.h>
  47   45  
  48   46  static int8_t utf8_to_euckr(uint32_t utf8, uchar_t **inbuf, uchar_t *ibtail,
  49   47          uchar_t *ob, uchar_t *obtail, size_t *ret_val);
  50   48  static int8_t utf8_to_uhc(uint32_t utf8, uchar_t **inbuf, uchar_t *ibtail,
  51   49          uchar_t *ob, uchar_t *obtail, size_t *ret_val);
  52   50  static int8_t ko_to_utf8(uint32_t ko_val, uchar_t *ob, uchar_t *obtail,
  53   51          size_t *ret_val, kiconv_table_array_t *table, size_t nitems);
  54   52  
  55   53  
  56   54  #define KICONV_KO_EUCKR         (0x01)
  57   55  #define KICONV_KO_UHC           (0x02)
  58   56  #define KICONV_KO_MAX_MAGIC_ID  (0x02)
  59   57  
  60   58  static void *
  61   59  open_fr_euckr()
  62   60  {
  63   61          return ((void *)KICONV_KO_EUCKR);
  64   62  }
  65   63  
  66   64  static void *
  67   65  open_fr_uhc()
  68   66  {
  69   67          return ((void *)KICONV_KO_UHC);
  70   68  }
  71   69  
  72   70  static int
  73   71  close_fr_ko(void *s)
  74   72  {
  75   73          if ((uintptr_t)s > KICONV_KO_MAX_MAGIC_ID)
  76   74                  return (EBADF);
  77   75  
  78   76          return (0);
  79   77  }
  80   78  
  81   79  /*
  82   80   * Encoding convertor from EUC-KR to UTF-8.
  83   81   */
  84   82  static size_t
  85   83  kiconv_fr_euckr(void *kcd, char **inbuf, size_t *inbufleft,
  86   84          char **outbuf, size_t *outbufleft, int *errno)
  87   85  {
  88   86          uchar_t         *ib;
  89   87          uchar_t         *ob;
  90   88          uchar_t         *ibtail;
  91   89          uchar_t         *obtail;
  92   90          size_t          ret_val;
  93   91          int8_t          sz;
  94   92          uint32_t        euckr_val;
  95   93  
  96   94          /* Check on the kiconv code conversion descriptor. */
  97   95          if (kcd == NULL || kcd == (void *)-1) {
  98   96                  *errno = EBADF;
  99   97                  return ((size_t)-1);
 100   98          }
 101   99  
 102  100          /* If this is a state reset request, process and return. */
 103  101          if (inbuf == NULL || *inbuf == NULL) {
 104  102                  return (0);
 105  103          }
 106  104  
 107  105          ret_val = 0;
 108  106          ib = (uchar_t *)*inbuf;
 109  107          ob = (uchar_t *)*outbuf;
 110  108          ibtail = ib + *inbufleft;
 111  109          obtail = ob + *outbufleft;
 112  110  
 113  111          while (ib < ibtail) {
 114  112                  if (KICONV_IS_ASCII(*ib)) {
 115  113                          if (ob >= obtail) {
 116  114                                  KICONV_SET_ERRNO_AND_BREAK(E2BIG);
 117  115                          }
 118  116  
 119  117                          *ob++ = *ib++;
 120  118                          continue;
 121  119                  }
 122  120  
 123  121                  /*
 124  122                   * Issue EILSEQ error if the first byte is not a
 125  123                   * valid EUC-KR leading byte.
 126  124                   */
 127  125                  if (! KICONV_KO_IS_EUCKR_BYTE(*ib)) {
 128  126                          KICONV_SET_ERRNO_AND_BREAK(EILSEQ);
 129  127                  }
 130  128  
 131  129                  /*
 132  130                   * Issue EINVAL error if input buffer has an incomplete
 133  131                   * character at the end of the buffer.
 134  132                   */
 135  133                  if (ibtail - ib < 2) {
 136  134                          KICONV_SET_ERRNO_AND_BREAK(EINVAL);
 137  135                  }
 138  136  
 139  137                  /*
 140  138                   * Issue EILSEQ error if the remaining byte is not
 141  139                   * a valid EUC-KR byte.
 142  140                   */
 143  141                  if (! KICONV_KO_IS_EUCKR_BYTE(*(ib + 1))) {
 144  142                          KICONV_SET_ERRNO_AND_BREAK(EILSEQ);
 145  143                  }
 146  144  
 147  145                  euckr_val = (uint32_t)(*ib) << 8 | *(ib + 1);
 148  146                  sz = ko_to_utf8(euckr_val, ob, obtail, &ret_val,
 149  147                      kiconv_euckr_utf8, KICONV_EUCKR_UTF8_MAX);
 150  148  
 151  149                  if (sz < 0) {
 152  150                          KICONV_SET_ERRNO_AND_BREAK(E2BIG);
 153  151                  }
 154  152  
 155  153                  ib += 2;
 156  154                  ob += sz;
 157  155          }
 158  156  
 159  157          *inbuf = (char *)ib;
 160  158          *inbufleft = ibtail - ib;
 161  159          *outbuf = (char *)ob;
 162  160          *outbufleft = obtail - ob;
 163  161  
 164  162          return (ret_val);
 165  163  }
 166  164  
 167  165  /*
 168  166   * String based encoding convertor from EUC-KR to UTF-8.
 169  167   */
 170  168  static size_t
 171  169  kiconvstr_fr_euckr(char *inarray, size_t *inlen, char *outarray,
 172  170          size_t *outlen, int flag, int *errno)
 173  171  {
 174  172          uchar_t         *ib;
 175  173          uchar_t         *ob;
 176  174          uchar_t         *ibtail;
 177  175          uchar_t         *obtail;
 178  176          uchar_t         *oldib;
 179  177          size_t          ret_val;
 180  178          int8_t          sz;
 181  179          uint32_t        euckr_val;
 182  180          boolean_t       do_not_ignore_null;
 183  181  
 184  182          ret_val = 0;
 185  183          ib = (uchar_t *)inarray;
 186  184          ob = (uchar_t *)outarray;
 187  185          ibtail = ib + *inlen;
 188  186          obtail = ob + *outlen;
 189  187          do_not_ignore_null = ((flag & KICONV_IGNORE_NULL) == 0);
 190  188  
 191  189          while (ib < ibtail) {
 192  190                  if (*ib == '\0' && do_not_ignore_null)
 193  191                          break;
 194  192  
 195  193                  if (KICONV_IS_ASCII(*ib)) {
 196  194                          if (ob >= obtail) {
 197  195                                  KICONV_SET_ERRNO_AND_BREAK(E2BIG);
 198  196                          }
 199  197  
 200  198                          *ob++ = *ib++;
 201  199                          continue;
 202  200                  }
 203  201  
 204  202                  oldib = ib;
 205  203  
 206  204                  if (! KICONV_KO_IS_EUCKR_BYTE(*ib)) {
 207  205                          KICONV_SET_ERRNO_WITH_FLAG(1, EILSEQ);
 208  206                  }
 209  207  
 210  208                  if (ibtail - ib < 2) {
 211  209                          KICONV_SET_ERRNO_WITH_FLAG(1, EINVAL);
 212  210                  }
 213  211  
 214  212                  if (! KICONV_KO_IS_EUCKR_BYTE(*(ib + 1))) {
 215  213                          KICONV_SET_ERRNO_WITH_FLAG(2, EILSEQ);
 216  214                  }
 217  215  
 218  216                  euckr_val = *ib++;
 219  217                  euckr_val = (euckr_val << 8) | *ib++;
 220  218                  sz = ko_to_utf8(euckr_val, ob, obtail, &ret_val,
 221  219                      kiconv_euckr_utf8, KICONV_EUCKR_UTF8_MAX);
 222  220  
 223  221                  if (sz < 0) {
 224  222                          ib = oldib;
 225  223                          KICONV_SET_ERRNO_AND_BREAK(E2BIG);
 226  224                  }
 227  225  
 228  226                  ob += sz;
 229  227                  continue;
 230  228  
 231  229  REPLACE_INVALID:
 232  230                  if (obtail - ob < KICONV_UTF8_REPLACEMENT_CHAR_LEN) {
 233  231                          ib = oldib;
 234  232                          KICONV_SET_ERRNO_AND_BREAK(E2BIG);
 235  233                  }
 236  234  
 237  235                  *ob++ = KICONV_UTF8_REPLACEMENT_CHAR1;
 238  236                  *ob++ = KICONV_UTF8_REPLACEMENT_CHAR2;
 239  237                  *ob++ = KICONV_UTF8_REPLACEMENT_CHAR3;
 240  238                  ret_val++;
 241  239          }
 242  240  
 243  241          *inlen = ibtail - ib;
 244  242          *outlen = obtail - ob;
 245  243  
 246  244          return (ret_val);
 247  245  }
 248  246  
 249  247  /*
 250  248   * Encoding convertor from Unified Hangul Code to UTF-8.
 251  249   */
 252  250  static size_t
 253  251  kiconv_fr_uhc(void *kcd, char **inbuf, size_t *inbufleft,
 254  252          char **outbuf, size_t *outbufleft, int *errno)
 255  253  {
 256  254          uchar_t         *ib;
 257  255          uchar_t         *ob;
 258  256          uchar_t         *ibtail;
 259  257          uchar_t         *obtail;
 260  258          size_t          ret_val;
 261  259          int8_t          sz;
 262  260          uint32_t        uhc_val;
 263  261  
 264  262          /* Check on the kiconv code conversion descriptor. */
 265  263          if (kcd == NULL || kcd == (void *)-1) {
 266  264                  *errno = EBADF;
 267  265                  return ((size_t)-1);
 268  266          }
 269  267  
 270  268          /* If this is a state reset request, process and return. */
 271  269          if (inbuf == NULL || *inbuf == NULL) {
 272  270                  return (0);
 273  271          }
 274  272  
 275  273          ret_val = 0;
 276  274          ib = (uchar_t *)*inbuf;
 277  275          ob = (uchar_t *)*outbuf;
 278  276          ibtail = ib + *inbufleft;
 279  277          obtail = ob + *outbufleft;
 280  278  
 281  279          while (ib < ibtail) {
 282  280                  if (KICONV_IS_ASCII(*ib)) {
 283  281                          if (ob >= obtail) {
 284  282                                  KICONV_SET_ERRNO_AND_BREAK(E2BIG);
 285  283                          }
 286  284  
 287  285                          *ob++ = *ib++;
 288  286                          continue;
 289  287                  }
 290  288  
 291  289                  /*
 292  290                   * Issue EILSEQ error if the first byte is not a
 293  291                   * valid UHC leading byte.
 294  292                   */
 295  293                  if (! KICONV_KO_IS_UHC_1st_BYTE(*ib)) {
 296  294                          KICONV_SET_ERRNO_AND_BREAK(EILSEQ);
 297  295                  }
 298  296  
 299  297                  /*
 300  298                   * Issue EINVAL error if input buffer has an incomplete
 301  299                   * character at the end of the buffer.
 302  300                   */
 303  301                  if (ibtail - ib < 2) {
 304  302                          KICONV_SET_ERRNO_AND_BREAK(EINVAL);
 305  303                  }
 306  304  
 307  305                  /*
 308  306                   * Issue EILSEQ error if the remaining byte is not
 309  307                   * a valid UHC byte.
 310  308                   */
 311  309                  if (! KICONV_KO_IS_UHC_2nd_BYTE(*(ib + 1))) {
 312  310                          KICONV_SET_ERRNO_AND_BREAK(EILSEQ);
 313  311                  }
 314  312  
 315  313                  uhc_val = (uint32_t)(*ib) << 8 | *(ib + 1);
 316  314                  sz = ko_to_utf8(uhc_val, ob, obtail, &ret_val,
 317  315                      kiconv_uhc_utf8, KICONV_UHC_UTF8_MAX);
 318  316  
 319  317                  if (sz < 0) {
 320  318                          KICONV_SET_ERRNO_AND_BREAK(E2BIG);
 321  319                  }
 322  320  
 323  321                  ib += 2;
 324  322                  ob += sz;
 325  323          }
 326  324  
 327  325          *inbuf = (char *)ib;
 328  326          *inbufleft = ibtail - ib;
 329  327          *outbuf = (char *)ob;
 330  328          *outbufleft = obtail - ob;
 331  329  
 332  330          return (ret_val);
 333  331  }
 334  332  
 335  333  /*
 336  334   * String based encoding convertor from Unified Hangul Code to UTF-8.
 337  335   */
 338  336  static size_t
 339  337  kiconvstr_fr_uhc(char *inarray, size_t *inlen, char *outarray,
 340  338          size_t *outlen, int flag, int *errno)
 341  339  {
 342  340          uchar_t         *ib;
 343  341          uchar_t         *ob;
 344  342          uchar_t         *ibtail;
 345  343          uchar_t         *obtail;
 346  344          uchar_t         *oldib;
 347  345          size_t          ret_val;
 348  346          int8_t          sz;
 349  347          uint32_t        uhc_val;
 350  348          boolean_t       do_not_ignore_null;
 351  349  
 352  350          ret_val = 0;
 353  351          ib = (uchar_t *)inarray;
 354  352          ob = (uchar_t *)outarray;
 355  353          ibtail = ib + *inlen;
 356  354          obtail = ob + *outlen;
 357  355          do_not_ignore_null = ((flag & KICONV_IGNORE_NULL) == 0);
 358  356  
 359  357          while (ib < ibtail) {
 360  358                  if (*ib == '\0' && do_not_ignore_null)
 361  359                          break;
 362  360  
 363  361                  if (KICONV_IS_ASCII(*ib)) {
 364  362                          if (ob >= obtail) {
 365  363                                  KICONV_SET_ERRNO_AND_BREAK(E2BIG);
 366  364                          }
 367  365  
 368  366                          *ob++ = *ib++;
 369  367                          continue;
 370  368                  }
 371  369  
 372  370                  oldib = ib;
 373  371  
 374  372                  if (! KICONV_KO_IS_UHC_1st_BYTE(*ib)) {
 375  373                          KICONV_SET_ERRNO_WITH_FLAG(1, EILSEQ);
 376  374                  }
 377  375  
 378  376                  if (ibtail - ib < 2) {
 379  377                          KICONV_SET_ERRNO_WITH_FLAG(1, EINVAL);
 380  378                  }
 381  379  
 382  380                  if (! KICONV_KO_IS_UHC_2nd_BYTE(*(ib + 1))) {
 383  381                          KICONV_SET_ERRNO_WITH_FLAG(2, EILSEQ);
 384  382                  }
 385  383  
 386  384                  uhc_val = *ib++;
 387  385                  uhc_val = (uhc_val << 8) | *ib++;
 388  386                  sz = ko_to_utf8(uhc_val, ob, obtail, &ret_val,
 389  387                      kiconv_uhc_utf8, KICONV_UHC_UTF8_MAX);
 390  388  
 391  389                  if (sz < 0) {
 392  390                          ib = oldib;
 393  391                          KICONV_SET_ERRNO_AND_BREAK(E2BIG);
 394  392                  }
 395  393  
 396  394                  ob += sz;
 397  395                  continue;
 398  396  
 399  397  REPLACE_INVALID:
 400  398                  if (obtail - ob < KICONV_UTF8_REPLACEMENT_CHAR_LEN) {
 401  399                          ib = oldib;
 402  400                          KICONV_SET_ERRNO_AND_BREAK(E2BIG);
 403  401                  }
 404  402  
 405  403                  *ob++ = KICONV_UTF8_REPLACEMENT_CHAR1;
 406  404                  *ob++ = KICONV_UTF8_REPLACEMENT_CHAR2;
 407  405                  *ob++ = KICONV_UTF8_REPLACEMENT_CHAR3;
 408  406                  ret_val++;
 409  407          }
 410  408  
 411  409          *inlen = ibtail - ib;
 412  410          *outlen = obtail - ob;
 413  411  
 414  412          return (ret_val);
 415  413  }
 416  414  
 417  415  /*
 418  416   * Encoding convertor from UTF-8 to EUC-KR.
 419  417   */
 420  418  static size_t
 421  419  kiconv_to_euckr(void *kcd, char **inbuf, size_t *inbytesleft,
 422  420          char **outbuf, size_t *outbytesleft, int *errno)
 423  421  {
 424  422          return (kiconv_utf8_to_cck(kcd, inbuf, inbytesleft, outbuf,
 425  423              outbytesleft, errno, utf8_to_euckr));
 426  424  }
 427  425  
 428  426  /*
 429  427   * Encoding convertor from UTF-8 to Unified Hangul Code.
 430  428   */
 431  429  static size_t
 432  430  kiconv_to_uhc(void *kcd, char **inbuf, size_t *inbytesleft,
 433  431          char **outbuf, size_t *outbytesleft, int *errno)
 434  432  {
 435  433          return (kiconv_utf8_to_cck(kcd, inbuf, inbytesleft, outbuf,
 436  434              outbytesleft, errno, utf8_to_uhc));
 437  435  }
 438  436  
 439  437  /*
 440  438   * String based encoding convertor from UTF-8 to EUC-KR.
 441  439   */
 442  440  static size_t
 443  441  kiconvstr_to_euckr(char *inarray, size_t *inlen, char *outarray,
 444  442          size_t *outlen, int flag, int *errno)
 445  443  {
 446  444          return kiconvstr_utf8_to_cck((uchar_t *)inarray, inlen,
 447  445              (uchar_t *)outarray, outlen, flag, errno, utf8_to_euckr);
 448  446  }
 449  447  
 450  448  /*
 451  449   * String based encoding convertor from UTF-8 to Unified Hangul Code.
 452  450   */
 453  451  static size_t
 454  452  kiconvstr_to_uhc(char *inarray, size_t *inlen, char *outarray,
 455  453          size_t *outlen, int flag, int *errno)
 456  454  {
 457  455          return kiconvstr_utf8_to_cck((uchar_t *)inarray, inlen,
 458  456              (uchar_t *)outarray, outlen, flag, errno, utf8_to_uhc);
 459  457  }
 460  458  
 461  459  /*
 462  460   * Convert an UTF-8 character to a character of ko encodings
 463  461   * (EUC-KR or UHC).
 464  462   */
 465  463  static int8_t
 466  464  utf8_to_ko(uint32_t utf8, uchar_t *ob, uchar_t *obtail, size_t *ret_val,
 467  465          kiconv_table_t *table, size_t nitems)
 468  466  {
 469  467          size_t  index;
 470  468          size_t  kocode;
 471  469          int8_t  kolen;
 472  470  
 473  471          if (KICONV_KO_IS_UDC_IN_UTF8(utf8)) {
 474  472                  /* User Definable Area handing. */
 475  473                  kocode = (((utf8 & 0xF0000) >> 4) | ((utf8 & 0x3F00) >> 2) |
 476  474                      (utf8 & 0x3F)) - KICONV_KO_UDA_UCS4_START;
 477  475                  if (kocode < KICONV_KO_UDA_RANGE) {
 478  476                          kocode = (KICONV_KO_UDA_EUC_SEG1 << 8) |
 479  477                              (kocode + KICONV_KO_UDA_OFFSET_START);
 480  478                  } else {
 481  479                          /* 0x43 = 0xA1 - 0x5E */
 482  480                          kocode = (KICONV_KO_UDA_EUC_SEG2 << 8) |
 483  481                              (kocode + 0x43);
 484  482                  }
 485  483  
 486  484                  index = 1;
 487  485          } else {
 488  486                  index = kiconv_binsearch(utf8, table, nitems);
 489  487                  kocode = table[index].value;
 490  488          }
 491  489  
 492  490          kolen = (kocode <= 0xFF) ? 1 : 2;
 493  491  
 494  492          if (obtail - ob < kolen) {
 495  493                  *ret_val = (size_t)-1;
 496  494                  return (-1);
 497  495          }
 498  496  
 499  497          if (index == 0)
 500  498                  (*ret_val)++;
 501  499  
 502  500          if (kolen > 1)
 503  501                  *ob++ = (uchar_t)(kocode >> 8);
 504  502          *ob = (uchar_t)(kocode & 0xFF);
 505  503  
 506  504          return (kolen);
 507  505  }
 508  506  
 509  507  /*
 510  508   * Convert an UTF-8 character to Unified Hangual Code.
 511  509   */
 512  510  /* ARGSUSED */
 513  511  static int8_t
 514  512  utf8_to_uhc(uint32_t utf8, uchar_t **inbuf, uchar_t *ibtail,
 515  513          uchar_t *ob, uchar_t *obtail, size_t *ret_val)
 516  514  {
 517  515          return (utf8_to_ko(utf8, ob, obtail, ret_val, kiconv_utf8_uhc,
 518  516              KICONV_UTF8_UHC_MAX));
 519  517  }
 520  518  
 521  519  /*
 522  520   * Convert an UTF-8 character to EUC-KR.
 523  521   */
 524  522  /* ARGSUSED */
 525  523  static int8_t
 526  524  utf8_to_euckr(uint32_t utf8, uchar_t **inbuf, uchar_t *ibtail,
 527  525          uchar_t *ob, uchar_t *obtail, size_t *ret_val)
 528  526  {
 529  527          return (utf8_to_ko(utf8, ob, obtail, ret_val, kiconv_utf8_euckr,
 530  528              KICONV_UTF8_EUCKR_MAX));
 531  529  }
 532  530  
 533  531  /*
 534  532   * Convert a single ko encoding (EUC-KR or UHC) character to UTF-8.
 535  533   */
 536  534  static int8_t
 537  535  ko_to_utf8(uint32_t ko_val, uchar_t *ob, uchar_t *obtail, size_t *ret_val,
 538  536          kiconv_table_array_t *table, size_t nitems)
 539  537  {
 540  538          size_t  index;
 541  539          int8_t  sz;
 542  540          uchar_t udc[3];
 543  541          uchar_t *u8;
 544  542  
 545  543          if (KICONV_KO_IS_UDC_IN_EUC(ko_val)) {
 546  544                  /* UDA(User Definable Area) handling. */
 547  545                  uint32_t u32;
 548  546  
 549  547                  u32 = (ko_val & 0xFF) + (((ko_val & 0xFF00) == 0xC900) ?
 550  548                      KICONV_KO_UDA_OFFSET_1 : KICONV_KO_UDA_OFFSET_2);
 551  549                  udc[0] = 0xEF;
 552  550                  udc[1] = (uchar_t)(0x80 | (u32 & 0x00000FC0) >> 6);
 553  551                  udc[2] = (uchar_t)(0x80 | (u32 & 0x0000003F));
 554  552                  u8 = udc;
 555  553                  index = 1;
 556  554          } else {
 557  555                  index = kiconv_binsearch(ko_val, table, nitems);
 558  556                  u8 = table[index].u8;
 559  557          }
 560  558  
 561  559          sz = u8_number_of_bytes[u8[0]];
 562  560  
 563  561          if (obtail - ob < sz) {
 564  562                  *ret_val = (size_t)-1;
 565  563                  return (-1);
 566  564          }
 567  565  
 568  566          if (index == 0)
 569  567                  (*ret_val)++;   /* Non-identical conversion */
 570  568  
 571  569          for (index = 0; index < sz; index++)
 572  570                  *ob++ = u8[index];
 573  571  
 574  572          return (sz);
 575  573  }
 576  574  
 577  575  static kiconv_ops_t kiconv_ko_ops_tbl[] = {
 578  576          {
 579  577                  "euc-kr", "utf-8", kiconv_open_to_cck, kiconv_to_euckr,
 580  578                  kiconv_close_to_cck, kiconvstr_to_euckr
 581  579          },
 582  580          {
 583  581                  "utf-8", "euc-kr", open_fr_euckr, kiconv_fr_euckr,
 584  582                  close_fr_ko, kiconvstr_fr_euckr
 585  583          },
 586  584          {
 587  585                  "unifiedhangul", "utf-8", kiconv_open_to_cck, kiconv_to_uhc,
 588  586                  kiconv_close_to_cck, kiconvstr_to_uhc
 589  587          },
 590  588          {
 591  589                  "utf-8", "unifiedhangul", open_fr_uhc, kiconv_fr_uhc,
 592  590                  close_fr_ko, kiconvstr_fr_uhc
 593  591          }
 594  592  };
 595  593  
 596  594  static kiconv_module_info_t kiconv_ko_info = {
 597  595          "kiconv_ko",            /* module name */
 598  596          sizeof (kiconv_ko_ops_tbl) / sizeof (kiconv_ko_ops_tbl[0]),
 599  597          kiconv_ko_ops_tbl,
 600  598          0,
 601  599          NULL,
 602  600          NULL,
 603  601          0
  
    | ↓ open down ↓ | 565 lines elided | ↑ open up ↑ | 
 604  602  };
 605  603  
 606  604  static struct modlkiconv modlkiconv_ko = {
 607  605          &mod_kiconvops,
 608  606          "kiconv korean module 1.0",
 609  607          &kiconv_ko_info
 610  608  };
 611  609  
 612  610  static struct modlinkage modlinkage = {
 613  611          MODREV_1,
 614      -        (void *)&modlkiconv_ko,
 615      -        NULL
      612 +        { (void *)&modlkiconv_ko, NULL }
 616  613  };
 617  614  
 618  615  int
 619  616  _init(void)
 620  617  {
 621  618          int err;
 622  619  
 623  620          err = mod_install(&modlinkage);
 624  621          if (err)
 625  622                  cmn_err(CE_WARN, "kiconv_ko: failed to load kernel module");
 626  623  
 627  624          return (err);
 628  625  }
 629  626  
 630  627  int
 631  628  _fini(void)
 632  629  {
 633  630          int err;
 634  631  
 635  632          /*
 636  633           * If this module is being used, then, we cannot remove the module.
 637  634           * The following checking will catch pretty much all usual cases.
 638  635           *
 639  636           * Any remaining will be catached by the kiconv_unregister_module()
 640  637           * during mod_remove() at below.
 641  638           */
 642  639          if (kiconv_module_ref_count(KICONV_MODULE_ID_KO))
 643  640                  return (EBUSY);
 644  641  
 645  642          err = mod_remove(&modlinkage);
 646  643          if (err)
 647  644                  cmn_err(CE_WARN, "kiconv_ko: failed to remove kernel module");
 648  645  
 649  646          return (err);
 650  647  }
 651  648  
 652  649  int
 653  650  _info(struct modinfo *modinfop)
 654  651  {
 655  652          return (mod_info(&modlinkage, modinfop));
 656  653  }
  
    | ↓ open down ↓ | 31 lines elided | ↑ open up ↑ | 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX