#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysmacros.h>
#include <sys/systm.h>
#include <sys/debug.h>
#include <sys/kmem.h>
#include <sys/cmn_err.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/ksynch.h>
#include <sys/modctl.h>
#include <sys/byteorder.h>
#include <sys/errno.h>
#include <sys/kiconv.h>
#include <sys/kiconv_emea1.h>
#include <sys/kiconv_emea2.h>
#define KICONV_TBLID_720 (0xFFU)
#define KICONV_TBLID_RANGE1_START KICONV_TBLID_720
#define KICONV_TBLID_RANGE1_END KICONV_TBLID_720
#define KICONV_TBLID_737 (0)
#define KICONV_TBLID_852 (1)
#define KICONV_TBLID_857 (2)
#define KICONV_TBLID_862 (3)
#define KICONV_TBLID_866 (4)
#define KICONV_TBLID_1250 (5)
#define KICONV_TBLID_1251 (6)
#define KICONV_TBLID_1253 (7)
#define KICONV_TBLID_1254 (8)
#define KICONV_TBLID_1255 (9)
#define KICONV_TBLID_1256 (10)
#define KICONV_TBLID_1257 (11)
#define KICONV_TBLID_8859_2 (12)
#define KICONV_TBLID_8859_3 (13)
#define KICONV_TBLID_8859_4 (14)
#define KICONV_TBLID_8859_5 (15)
#define KICONV_TBLID_8859_6 (16)
#define KICONV_TBLID_8859_7 (17)
#define KICONV_TBLID_8859_8 (18)
#define KICONV_TBLID_8859_9 (19)
#define KICONV_TBLID_8859_10 (20)
#define KICONV_TBLID_8859_11 (21)
#define KICONV_TBLID_8859_13 (22)
#define KICONV_TBLID_KOI8_R (23)
#define KICONV_MAX_MAPPING_TBLID KICONV_TBLID_KOI8_R
extern const int8_t u8_number_of_bytes[];
extern const uint8_t u8_valid_min_2nd_byte[];
extern const uint8_t u8_valid_max_2nd_byte[];
static void *
open_to_720()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_720;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_737()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_737;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_852()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_852;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_857()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_857;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_862()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_862;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_866()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_866;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_1250()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_1250;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_1251()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_1251;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_1253()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_1253;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_1254()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_1254;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_1255()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_1255;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_1256()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_1256;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_1257()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_1257;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_88592()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_8859_2;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_88593()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_8859_3;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_88594()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_8859_4;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_88595()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_8859_5;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_88596()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_8859_6;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_88597()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_8859_7;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_88598()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_8859_8;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_88599()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_8859_9;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_885910()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_8859_10;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_885911()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_8859_11;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_885913()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_8859_13;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_to_koi8r()
{
kiconv_state_t s;
s = (kiconv_state_t)kmem_alloc(sizeof (kiconv_state_data_t), KM_SLEEP);
s->id = KICONV_TBLID_KOI8_R;
s->bom_processed = 0;
return ((void *)s);
}
static void *
open_fr_720()
{
return ((void *)KICONV_TBLID_720);
}
static void *
open_fr_737()
{
return ((void *)KICONV_TBLID_737);
}
static void *
open_fr_852()
{
return ((void *)KICONV_TBLID_852);
}
static void *
open_fr_857()
{
return ((void *)KICONV_TBLID_857);
}
static void *
open_fr_862()
{
return ((void *)KICONV_TBLID_862);
}
static void *
open_fr_866()
{
return ((void *)KICONV_TBLID_866);
}
static void *
open_fr_1250()
{
return ((void *)KICONV_TBLID_1250);
}
static void *
open_fr_1251()
{
return ((void *)KICONV_TBLID_1251);
}
static void *
open_fr_1253()
{
return ((void *)KICONV_TBLID_1253);
}
static void *
open_fr_1254()
{
return ((void *)KICONV_TBLID_1254);
}
static void *
open_fr_1255()
{
return ((void *)KICONV_TBLID_1255);
}
static void *
open_fr_1256()
{
return ((void *)KICONV_TBLID_1256);
}
static void *
open_fr_1257()
{
return ((void *)KICONV_TBLID_1257);
}
static void *
open_fr_88592()
{
return ((void *)KICONV_TBLID_8859_2);
}
static void *
open_fr_88593()
{
return ((void *)KICONV_TBLID_8859_3);
}
static void *
open_fr_88594()
{
return ((void *)KICONV_TBLID_8859_4);
}
static void *
open_fr_88595()
{
return ((void *)KICONV_TBLID_8859_5);
}
static void *
open_fr_88596()
{
return ((void *)KICONV_TBLID_8859_6);
}
static void *
open_fr_88597()
{
return ((void *)KICONV_TBLID_8859_7);
}
static void *
open_fr_88598()
{
return ((void *)KICONV_TBLID_8859_8);
}
static void *
open_fr_88599()
{
return ((void *)KICONV_TBLID_8859_9);
}
static void *
open_fr_885910()
{
return ((void *)KICONV_TBLID_8859_10);
}
static void *
open_fr_885911()
{
return ((void *)KICONV_TBLID_8859_11);
}
static void *
open_fr_885913()
{
return ((void *)KICONV_TBLID_8859_13);
}
static void *
open_fr_koi8r()
{
return ((void *)KICONV_TBLID_KOI8_R);
}
static int
close_to_sb(void *s)
{
if (! s || s == (void *)-1)
return (EBADF);
kmem_free(s, sizeof (kiconv_state_data_t));
return (0);
}
static int
close_fr_sb(void *s)
{
if ((ulong_t)s > KICONV_MAX_MAPPING_TBLID &&
((ulong_t)s < KICONV_TBLID_RANGE1_START ||
(ulong_t)s > KICONV_TBLID_RANGE1_END))
return (EBADF);
return (0);
}
static size_t
kiconv_to_sb(void *kcd, char **inbuf, size_t *inbytesleft, char **outbuf,
size_t *outbytesleft, int *errno)
{
kiconv_to_sb_tbl_comp_t *tbl;
size_t id;
size_t ret_val;
uchar_t *ib;
uchar_t *oldib;
uchar_t *ob;
uchar_t *ibtail;
uchar_t *obtail;
uint32_t u8;
size_t i;
size_t l;
size_t h;
size_t init_h;
int8_t sz;
boolean_t second;
if (! kcd || kcd == (void *)-1) {
*errno = EBADF;
return ((size_t)-1);
}
id = ((kiconv_state_t)kcd)->id;
if (id > KICONV_MAX_MAPPING_TBLID &&
(id < KICONV_TBLID_RANGE1_START || id > KICONV_TBLID_RANGE1_END)) {
*errno = EBADF;
return ((size_t)-1);
}
if (! inbuf || ! (*inbuf)) {
((kiconv_state_t)kcd)->bom_processed = 0;
return ((size_t)0);
}
ret_val = 0;
ib = (uchar_t *)*inbuf;
ob = (uchar_t *)*outbuf;
ibtail = ib + *inbytesleft;
obtail = ob + *outbytesleft;
if (id == KICONV_TBLID_720) {
tbl = (kiconv_to_sb_tbl_comp_t *)u8_to_cp720_tbl;
init_h = sizeof (u8_to_cp720_tbl);
} else {
tbl = (kiconv_to_sb_tbl_comp_t *)to_sb_tbl[id];
init_h = sizeof (to_sb_tbl[id]);
}
init_h = init_h / sizeof (kiconv_to_sb_tbl_comp_t) - 1;
if (((kiconv_state_t)kcd)->bom_processed == 0 && (ibtail - ib) >= 3 &&
*ib == 0xef && *(ib + 1) == 0xbb && *(ib + 2) == 0xbf)
ib += 3;
((kiconv_state_t)kcd)->bom_processed = 1;
while (ib < ibtail) {
sz = u8_number_of_bytes[*ib];
if (sz <= 0) {
*errno = EILSEQ;
ret_val = (size_t)-1;
break;
}
if (ob >= obtail) {
*errno = E2BIG;
ret_val = (size_t)-1;
break;
}
if (sz == 1) {
*ob++ = *ib++;
continue;
}
if ((ibtail - ib) < sz) {
*errno = EINVAL;
ret_val = (size_t)-1;
break;
}
oldib = ib;
u8 = *ib++;
second = B_TRUE;
for (i = 1; i < sz; i++) {
if (second) {
if (*ib < u8_valid_min_2nd_byte[u8] ||
*ib > u8_valid_max_2nd_byte[u8]) {
*errno = EILSEQ;
ret_val = (size_t)-1;
ib = oldib;
goto TO_SB_ILLEGAL_CHAR_ERR;
}
second = B_FALSE;
} else if (*ib < 0x80 || *ib > 0xbf) {
*errno = EILSEQ;
ret_val = (size_t)-1;
ib = oldib;
goto TO_SB_ILLEGAL_CHAR_ERR;
}
u8 = (u8 << 8) | ((uint32_t)*ib);
ib++;
}
i = l = 0;
h = init_h;
while (l <= h) {
i = (l + h) / 2;
if (tbl[i].u8 == u8)
break;
else if (tbl[i].u8 < u8)
l = i + 1;
else
h = i - 1;
}
if (tbl[i].u8 == u8) {
*ob++ = tbl[i].sb;
} else {
*ob++ = KICONV_ASCII_REPLACEMENT_CHAR;
ret_val++;
}
}
TO_SB_ILLEGAL_CHAR_ERR:
*inbuf = (char *)ib;
*inbytesleft = ibtail - ib;
*outbuf = (char *)ob;
*outbytesleft = obtail - ob;
return (ret_val);
}
static size_t
kiconv_fr_sb(void *kcd, char **inbuf, size_t *inbytesleft, char **outbuf,
size_t *outbytesleft, int *errno)
{
kiconv_to_utf8_tbl_comp_t *tbl;
size_t ret_val;
uchar_t *ib;
uchar_t *ob;
uchar_t *ibtail;
uchar_t *obtail;
size_t i;
size_t k;
int8_t sz;
if ((ulong_t)kcd > KICONV_MAX_MAPPING_TBLID &&
((ulong_t)kcd < KICONV_TBLID_RANGE1_START ||
(ulong_t)kcd > KICONV_TBLID_RANGE1_END)) {
*errno = EBADF;
return ((size_t)-1);
}
if (! inbuf || ! (*inbuf))
return ((size_t)0);
ret_val = 0;
ib = (uchar_t *)*inbuf;
ob = (uchar_t *)*outbuf;
ibtail = ib + *inbytesleft;
obtail = ob + *outbytesleft;
tbl = ((ulong_t)kcd == KICONV_TBLID_720) ?
(kiconv_to_utf8_tbl_comp_t *)cp720_to_u8_tbl :
(kiconv_to_utf8_tbl_comp_t *)to_u8_tbl[(ulong_t)kcd];
while (ib < ibtail) {
if (*ib < 0x80) {
if (ob >= obtail) {
*errno = E2BIG;
ret_val = (size_t)-1;
break;
}
*ob++ = *ib++;
continue;
}
k = *ib - 0x80;
sz = u8_number_of_bytes[tbl[k].u8[0]];
if (sz <= 0) {
*errno = EILSEQ;
ret_val = (size_t)-1;
break;
}
if ((obtail - ob) < sz) {
*errno = E2BIG;
ret_val = (size_t)-1;
break;
}
for (i = 0; i < sz; i++)
*ob++ = tbl[k].u8[i];
ib++;
}
*inbuf = (char *)ib;
*inbytesleft = ibtail - ib;
*outbuf = (char *)ob;
*outbytesleft = obtail - ob;
return (ret_val);
}
static size_t
kiconvstr_to_sb(size_t id, uchar_t *ib, size_t *inlen, uchar_t *ob,
size_t *outlen, int flag, int *errno)
{
kiconv_to_sb_tbl_comp_t *tbl;
size_t ret_val;
uchar_t *oldib;
uchar_t *ibtail;
uchar_t *obtail;
uint32_t u8;
size_t i;
size_t l;
size_t h;
size_t init_h;
int8_t sz;
boolean_t second;
boolean_t do_not_ignore_null;
if (id > KICONV_MAX_MAPPING_TBLID &&
(id < KICONV_TBLID_RANGE1_START || id > KICONV_TBLID_RANGE1_END)) {
*errno = EBADF;
return ((size_t)-1);
}
ret_val = 0;
ibtail = ib + *inlen;
obtail = ob + *outlen;
do_not_ignore_null = ((flag & KICONV_IGNORE_NULL) == 0);
if (id == KICONV_TBLID_720) {
tbl = (kiconv_to_sb_tbl_comp_t *)u8_to_cp720_tbl;
init_h = sizeof (u8_to_cp720_tbl);
} else {
tbl = (kiconv_to_sb_tbl_comp_t *)to_sb_tbl[id];
init_h = sizeof (to_sb_tbl[id]);
}
init_h = init_h / sizeof (kiconv_to_sb_tbl_comp_t) - 1;
if ((ibtail - ib) >= 3 && *ib == 0xef && *(ib + 1) == 0xbb &&
*(ib + 2) == 0xbf)
ib += 3;
while (ib < ibtail) {
sz = u8_number_of_bytes[*ib];
if (sz <= 0) {
if (flag & KICONV_REPLACE_INVALID) {
if (ob >= obtail) {
*errno = E2BIG;
ret_val = (size_t)-1;
break;
}
ib++;
goto STR_TO_SB_REPLACE_INVALID;
}
*errno = EILSEQ;
ret_val = (size_t)-1;
break;
}
if (*ib == '\0' && do_not_ignore_null)
break;
if (ob >= obtail) {
*errno = E2BIG;
ret_val = (size_t)-1;
break;
}
if (sz == 1) {
*ob++ = *ib++;
continue;
}
if ((ibtail - ib) < sz) {
if (flag & KICONV_REPLACE_INVALID) {
ib = ibtail;
goto STR_TO_SB_REPLACE_INVALID;
}
*errno = EINVAL;
ret_val = (size_t)-1;
break;
}
oldib = ib;
u8 = *ib++;
second = B_TRUE;
for (i = 1; i < sz; i++) {
if (second) {
if (*ib < u8_valid_min_2nd_byte[u8] ||
*ib > u8_valid_max_2nd_byte[u8]) {
if (flag & KICONV_REPLACE_INVALID) {
ib = oldib + sz;
goto STR_TO_SB_REPLACE_INVALID;
}
*errno = EILSEQ;
ret_val = (size_t)-1;
ib = oldib;
goto STR_TO_SB_ILLEGAL_CHAR_ERR;
}
second = B_FALSE;
} else if (*ib < 0x80 || *ib > 0xbf) {
if (flag & KICONV_REPLACE_INVALID) {
ib = oldib + sz;
goto STR_TO_SB_REPLACE_INVALID;
}
*errno = EILSEQ;
ret_val = (size_t)-1;
ib = oldib;
goto STR_TO_SB_ILLEGAL_CHAR_ERR;
}
u8 = (u8 << 8) | ((uint32_t)*ib);
ib++;
}
i = l = 0;
h = init_h;
while (l <= h) {
i = (l + h) / 2;
if (tbl[i].u8 == u8)
break;
else if (tbl[i].u8 < u8)
l = i + 1;
else
h = i - 1;
}
if (tbl[i].u8 == u8) {
*ob++ = tbl[i].sb;
} else {
STR_TO_SB_REPLACE_INVALID:
*ob++ = KICONV_ASCII_REPLACEMENT_CHAR;
ret_val++;
}
}
STR_TO_SB_ILLEGAL_CHAR_ERR:
*inlen = ibtail - ib;
*outlen = obtail - ob;
return (ret_val);
}
static size_t
kiconvstr_to_720(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_720, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_737(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_737, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_852(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_852, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_857(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_857, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_862(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_862, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_866(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_866, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_1250(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_1250, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_1251(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_1251, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_1253(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_1253, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_1254(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_1254, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_1255(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_1255, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_1256(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_1256, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_1257(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_1257, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_88592(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_8859_2, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_88593(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_8859_3, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_88594(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_8859_4, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_88595(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_8859_5, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_88596(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_8859_6, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_88597(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_8859_7, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_88598(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_8859_8, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_88599(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_8859_9, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_885910(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_8859_10, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_885911(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_8859_11, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_885913(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_8859_13, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_to_koi8r(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_to_sb(KICONV_TBLID_KOI8_R, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_sb(size_t id, uchar_t *ib, size_t *inlen, uchar_t *ob,
size_t *outlen, int flag, int *errno)
{
kiconv_to_utf8_tbl_comp_t *tbl;
size_t ret_val;
uchar_t *ibtail;
uchar_t *obtail;
size_t i;
size_t k;
int8_t sz;
boolean_t do_not_ignore_null;
if (id > KICONV_MAX_MAPPING_TBLID &&
(id < KICONV_TBLID_RANGE1_START || id > KICONV_TBLID_RANGE1_END)) {
*errno = EBADF;
return ((size_t)-1);
}
ret_val = 0;
ibtail = ib + *inlen;
obtail = ob + *outlen;
do_not_ignore_null = ((flag & KICONV_IGNORE_NULL) == 0);
tbl = (id == KICONV_TBLID_720) ?
(kiconv_to_utf8_tbl_comp_t *)cp720_to_u8_tbl :
(kiconv_to_utf8_tbl_comp_t *)to_u8_tbl[id];
while (ib < ibtail) {
if (*ib == '\0' && do_not_ignore_null)
break;
if (*ib < 0x80) {
if (ob >= obtail) {
*errno = E2BIG;
ret_val = (size_t)-1;
break;
}
*ob++ = *ib++;
continue;
}
k = *ib - 0x80;
sz = u8_number_of_bytes[tbl[k].u8[0]];
if (sz <= 0) {
if (flag & KICONV_REPLACE_INVALID) {
if ((obtail - ob) < 3) {
*errno = E2BIG;
ret_val = (size_t)-1;
break;
}
*ob++ = 0xef;
*ob++ = 0xbf;
*ob++ = 0xbd;
ret_val++;
ib++;
continue;
}
*errno = EILSEQ;
ret_val = (size_t)-1;
break;
}
if ((obtail - ob) < sz) {
*errno = E2BIG;
ret_val = (size_t)-1;
break;
}
for (i = 0; i < sz; i++)
*ob++ = tbl[k].u8[i];
ib++;
}
*inlen = ibtail - ib;
*outlen = obtail - ob;
return (ret_val);
}
static size_t
kiconvstr_fr_720(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_720, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_737(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_737, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_852(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_852, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_857(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_857, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_862(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_862, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_866(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_866, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_1250(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_1250, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_1251(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_1251, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_1253(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_1253, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_1254(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_1254, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_1255(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_1255, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_1256(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_1256, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_1257(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_1257, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_88592(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_8859_2, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_88593(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_8859_3, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_88594(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_8859_4, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_88595(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_8859_5, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_88596(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_8859_6, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_88597(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_8859_7, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_88598(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_8859_8, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_88599(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_8859_9, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_885910(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_8859_10, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_885911(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_8859_11, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_885913(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_8859_13, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
static size_t
kiconvstr_fr_koi8r(char *inarray, size_t *inlen, char *outarray,
size_t *outlen, int flag, int *errno)
{
return (kiconvstr_fr_sb(KICONV_TBLID_KOI8_R, (uchar_t *)inarray,
inlen, (uchar_t *)outarray, outlen, flag, errno));
}
#define KICONV_MAX_EMEA_OPS 50
static kiconv_ops_t kiconv_emea_ops[KICONV_MAX_EMEA_OPS] = {
{
"utf8", "cp1250",
open_fr_1250, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1250
},
{
"cp1250", "utf8",
open_to_1250, kiconv_to_sb, close_to_sb, kiconvstr_to_1250
},
{
"utf8", "iso88592",
open_fr_88592, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88592
},
{
"iso88592", "utf8",
open_to_88592, kiconv_to_sb, close_to_sb, kiconvstr_to_88592
},
{
"utf8", "cp852",
open_fr_852, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_852
},
{
"cp852", "utf8",
open_to_852, kiconv_to_sb, close_to_sb, kiconvstr_to_852
},
{
"utf8", "cp1251",
open_fr_1251, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1251
},
{
"cp1251", "utf8",
open_to_1251, kiconv_to_sb, close_to_sb, kiconvstr_to_1251
},
{
"utf8", "iso88595",
open_fr_88595, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88595
},
{
"iso88595", "utf8",
open_to_88595, kiconv_to_sb, close_to_sb, kiconvstr_to_88595
},
{
"utf8", "koi8r",
open_fr_koi8r, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_koi8r
},
{
"koi8r", "utf8",
open_to_koi8r, kiconv_to_sb, close_to_sb, kiconvstr_to_koi8r
},
{
"utf8", "cp866",
open_fr_866, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_866
},
{
"cp866", "utf8",
open_to_866, kiconv_to_sb, close_to_sb, kiconvstr_to_866
},
{
"utf8", "cp1253",
open_fr_1253, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1253
},
{
"cp1253", "utf8",
open_to_1253, kiconv_to_sb, close_to_sb, kiconvstr_to_1253
},
{
"utf8", "iso88597",
open_fr_88597, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88597
},
{
"iso88597", "utf8",
open_to_88597, kiconv_to_sb, close_to_sb, kiconvstr_to_88597
},
{
"utf8", "cp737",
open_fr_737, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_737
},
{
"cp737", "utf8",
open_to_737, kiconv_to_sb, close_to_sb, kiconvstr_to_737
},
{
"utf8", "cp1254",
open_fr_1254, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1254
},
{
"cp1254", "utf8",
open_to_1254, kiconv_to_sb, close_to_sb, kiconvstr_to_1254
},
{
"utf8", "iso88599",
open_fr_88599, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88599
},
{
"iso88599", "utf8",
open_to_88599, kiconv_to_sb, close_to_sb, kiconvstr_to_88599
},
{
"utf8", "cp857",
open_fr_857, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_857
},
{
"cp857", "utf8",
open_to_857, kiconv_to_sb, close_to_sb, kiconvstr_to_857
},
{
"utf8", "cp1256",
open_fr_1256, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1256
},
{
"cp1256", "utf8",
open_to_1256, kiconv_to_sb, close_to_sb, kiconvstr_to_1256
},
{
"utf8", "iso88596",
open_fr_88596, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88596
},
{
"iso88596", "utf8",
open_to_88596, kiconv_to_sb, close_to_sb, kiconvstr_to_88596
},
{
"utf8", "cp720",
open_fr_720, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_720
},
{
"cp720", "utf8",
open_to_720, kiconv_to_sb, close_to_sb, kiconvstr_to_720
},
{
"utf8", "cp1255",
open_fr_1255, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1255
},
{
"cp1255", "utf8",
open_to_1255, kiconv_to_sb, close_to_sb, kiconvstr_to_1255
},
{
"utf8", "iso88598",
open_fr_88598, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88598
},
{
"iso88598", "utf8",
open_to_88598, kiconv_to_sb, close_to_sb, kiconvstr_to_88598
},
{
"utf8", "cp862",
open_fr_862, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_862
},
{
"cp862", "utf8",
open_to_862, kiconv_to_sb, close_to_sb, kiconvstr_to_862
},
{
"utf8", "cp1257",
open_fr_1257, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_1257
},
{
"cp1257", "utf8",
open_to_1257, kiconv_to_sb, close_to_sb, kiconvstr_to_1257
},
{
"utf8", "iso885913",
open_fr_885913, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_885913
},
{
"iso885913", "utf8",
open_to_885913, kiconv_to_sb, close_to_sb, kiconvstr_to_885913
},
{
"utf8", "iso885910",
open_fr_885910, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_885910
},
{
"iso885910", "utf8",
open_to_885910, kiconv_to_sb, close_to_sb, kiconvstr_to_885910
},
{
"utf8", "iso885911",
open_fr_885911, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_885911
},
{
"iso885911", "utf8",
open_to_885911, kiconv_to_sb, close_to_sb, kiconvstr_to_885911
},
{
"utf8", "iso88593",
open_fr_88593, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88593
},
{
"iso88593", "utf8",
open_to_88593, kiconv_to_sb, close_to_sb, kiconvstr_to_88593
},
{
"utf8", "iso88594",
open_fr_88594, kiconv_fr_sb, close_fr_sb, kiconvstr_fr_88594
},
{
"iso88594", "utf8",
open_to_88594, kiconv_to_sb, close_to_sb, kiconvstr_to_88594
},
};
static kiconv_module_info_t kiconv_emea_modinfo = {
"kiconv_emea",
KICONV_MAX_EMEA_OPS,
kiconv_emea_ops,
0,
NULL,
NULL,
0
};
static struct modlkiconv kiconv_emea = {
&mod_kiconvops,
"kiconv module for EMEA",
&kiconv_emea_modinfo
};
static struct modlinkage linkage = {
MODREV_1,
(void *)&kiconv_emea,
NULL
};
int
_init()
{
int err;
err = mod_install(&linkage);
if (err)
cmn_err(CE_WARN, "kiconv_emea: failed to load kernel module");
return (err);
}
int
_info(struct modinfo *modinfop)
{
return (mod_info(&linkage, modinfop));
}
int
_fini()
{
int err;
if (kiconv_module_ref_count(KICONV_MODULE_ID_EMEA))
return (EBUSY);
err = mod_remove(&linkage);
if (err)
cmn_err(CE_WARN, "kiconv_emea: failed to remove kernel module");
return (err);
}