--- sys/sys/iconv.h.orig Tue Aug 15 22:29:40 2006 +++ sys/sys/iconv.h Sat Aug 19 02:13:41 2006 @@ -94,10 +94,12 @@ #define KICONV_VENDOR_MICSFT 1 /* Microsoft Vendor Code for quirk */ +int kiconv_add(const char *, const char *, const char *, const void *, int); int kiconv_add_xlat_table(const char *, const char *, const u_char *); int kiconv_add_xlat16_cspair(const char *, const char *, int); int kiconv_add_xlat16_cspairs(const char *, const char *); int kiconv_add_xlat16_table(const char *, const char *, const void *, int); +int kiconv_lookup_aliases(const char *tocode, const char *fromcode); int kiconv_lookupconv(const char *drvname); int kiconv_lookupcs(const char *tocode, const char *fromcode); const char *kiconv_quirkcs(const char *, int); @@ -132,6 +134,11 @@ struct iconv_cspair *cp_base; TAILQ_ENTRY(iconv_cspair) cp_link; }; + +/* for the alias converter to look at other instances */ +#define KICONV_DRV_COM_FIELDS \ + KOBJ_FIELDS; \ + struct iconv_cspair * d_csp #define KICONV_CONVERTER(name,size) \ static struct iconv_converter_class iconv_ ## name ## _class = { \ --- sys/libkern/iconv_xlat.c.orig Sat Sep 27 05:26:24 2003 +++ sys/libkern/iconv_xlat.c Wed Aug 16 23:27:17 2006 @@ -53,9 +53,8 @@ * XLAT converter instance */ struct iconv_xlat { - KOBJ_FIELDS; - u_char * d_table; - struct iconv_cspair * d_csp; + KICONV_DRV_COM_FIELDS; + u_char * d_table; }; static int --- sys/libkern/iconv_xlat16.c.orig Tue Aug 15 22:24:30 2006 +++ sys/libkern/iconv_xlat16.c Fri Aug 18 22:44:09 2006 @@ -50,11 +50,10 @@ * XLAT16 converter instance */ struct iconv_xlat16 { - KOBJ_FIELDS; - uint32_t * d_table[0x200]; - void * f_ctp; - void * t_ctp; - struct iconv_cspair * d_csp; + KICONV_DRV_COM_FIELDS; + uint32_t * d_table[0x200]; + void * f_ctp; + void * t_ctp; }; static int --- sys/libkern/iconv_ucs.c.orig Tue Aug 15 22:29:40 2006 +++ sys/libkern/iconv_ucs.c Fri Aug 18 22:45:04 2006 @@ -76,9 +76,8 @@ * UCS converter instance */ struct iconv_ucs { - KOBJ_FIELDS; + KICONV_DRV_COM_FIELDS; int convtype; - struct iconv_cspair * d_csp; struct iconv_cspair * d_cspf; void * f_ctp; void * t_ctp; --- /dev/null Fri Aug 18 22:44:02 2006 +++ sys/libkern/iconv_alias.c Fri Aug 18 21:45:47 2006 @@ -0,0 +1,106 @@ +/*- + * Copyright (c) 2006 Ryuichiro Imura + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include "iconv_converter_if.h" + +/* + * alias converter + */ + +#ifdef MODULE_DEPEND +MODULE_DEPEND(iconv_alias, libiconv, 2, 2, 2); +#endif + +struct iconv_alias { + KICONV_DRV_COM_FIELDS; +}; + +static int +iconv_alias_open(struct iconv_converter_class *dcp, + struct iconv_cspair *csp, struct iconv_cspair *cspf, void **dpp) +{ + void *dp; + const char *cp, *from, *to; + struct iconv_alias *dp_base; + + cp = from = (const char *)csp->cp_data; + if (from == '\0' || strlen(from) >= ICONV_CSNMAXLEN) + goto bad; + to = from + strlen(from) + 1; + if (to == '\0' || strlen(to) >= ICONV_CSNMAXLEN) + goto bad; + + iconv_open(to, from, &dp); + if (dp) { + dp_base = (struct iconv_alias *)dp; + csp->cp_base = dp_base->d_csp; + *dpp = dp; + return 0; + } + +bad: + *dpp = NULL; + return -1; +} + +static int +iconv_alias_close(void *data) +{ + return 0; +} + +static int +iconv_alias_conv(void *d2p, const char **inbuf, + size_t *inbytesleft, char **outbuf, size_t *outbytesleft, + int convchar, int casetype) +{ + return -1; +} + +static const char * +iconv_alias_name(struct iconv_converter_class *dcp) +{ + return ("alias"); +} + +static kobj_method_t iconv_alias_methods[] = { + KOBJMETHOD(iconv_converter_open, iconv_alias_open), + KOBJMETHOD(iconv_converter_close, iconv_alias_close), + KOBJMETHOD(iconv_converter_conv, iconv_alias_conv), + KOBJMETHOD(iconv_converter_name, iconv_alias_name), + { NULL, NULL } +}; + +KICONV_CONVERTER(alias, sizeof(struct iconv_alias)); --- sys/conf/files.orig Tue Aug 15 22:29:40 2006 +++ sys/conf/files Fri Aug 18 22:49:43 2006 @@ -1380,6 +1380,7 @@ libkern/fnmatch.c standard libkern/gets.c standard libkern/iconv.c optional libiconv +libkern/iconv_alias.c optional libiconv libkern/iconv_converter_if.m optional libiconv libkern/iconv_ucs.c optional libiconv libkern/iconv_xlat.c optional libiconv --- sys/modules/libiconv/Makefile.orig Tue Aug 15 22:29:40 2006 +++ sys/modules/libiconv/Makefile Fri Aug 18 00:35:11 2006 @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/../../libkern ${.CURDIR}/../../sys KMOD= libiconv -SRCS= iconv.c iconv_ucs.c iconv_xlat.c iconv_xlat16.c +SRCS= iconv.c iconv_alias.c iconv_ucs.c iconv_xlat.c iconv_xlat16.c SRCS+= iconv.h SRCS+= iconv_converter_if.c iconv_converter_if.h MFILES= libkern/iconv_converter_if.m --- lib/libkiconv/Makefile.orig Tue Aug 15 22:24:46 2006 +++ lib/libkiconv/Makefile Thu Aug 17 23:48:54 2006 @@ -2,7 +2,7 @@ LIB= kiconv SHLIBDIR?= /lib -SRCS= sysctl.c xlat16_iconv.c xlat16_sysctl.c +SRCS= alias.c sysctl.c xlat16_iconv.c xlat16_sysctl.c SRCS+= quirks.c SHLIB_MAJOR= 2 --- /dev/null Sat Aug 19 02:06:15 2006 +++ lib/libkiconv/alias.c Sat Aug 19 01:57:32 2006 @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2006 Ryuichiro Imura + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include + +#include +#include +#include + +#include "alias.h" + +int +kiconv_add_aliases(const char *to, const char *from, const char *aliasto, + const char *aliasfrom) +{ + size_t len; + int ret; + char data[ICONV_CSNMAXLEN * 2], *dp; + + len = (strlen(aliasfrom) + 1) + (strlen(aliasto) + 1); + dp = stpcpy(data, aliasfrom); + dp++; + strcpy(dp, aliasto); + + ret = kiconv_add("alias", to, from, (const void *)data, len); + return (ret); +} + +int +kiconv_aliascmp(const char *str1, const char *str2) +{ + int i; + const char *c1, *c2; + + for (i = 0, c1 = str1, c2 = str2; i < ICONV_CSNMAXLEN;) { + if (*c1 == '\0' && *c2 == '\0' && i > 0) { + return (0); + } else if (*c1 == '\0' || *c2 == '\0') { + return (ENOENT); + } + if (*c1 == '-' || *c1 == '_') { + i++; + c1++; + continue; + } + if (*c2 == '-' || *c2 == '_') { + c2++; + continue; + } + if (toupper(*c1) == toupper(*c2)) { + i++; + c1++; + c2++; + continue; + } + return (ENOENT); + } + return (ENOENT); +} --- /dev/null Sat Aug 19 02:06:15 2006 +++ lib/libkiconv/alias.h Sat Aug 19 01:58:10 2006 @@ -0,0 +1,30 @@ +/*- + * Copyright (c) 2006 Ryuichiro Imura + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +int kiconv_add_aliases(const char *, const char *, const char *, const char *); +int kiconv_aliascmp(const char *, const char *); --- lib/libkiconv/sysctl.c.orig Tue Aug 15 22:24:46 2006 +++ lib/libkiconv/sysctl.c Sat Aug 19 02:04:17 2006 @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005 Ryuichiro Imura + * Copyright (c) 2005, 2006 Ryuichiro Imura * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,6 +35,8 @@ #include #include +#include "alias.h" + int kiconv_lookupconv(const char *drvname) { @@ -87,6 +89,39 @@ return (0); } } + } + return (ENOENT); +} + +int +kiconv_lookup_aliases(const char *tocode, const char *fromcode) +{ + size_t i, size; + struct iconv_cspair_info *csi, *csip; + int error, j; + const char *kp, *lp; + + if (sysctlbyname("kern.iconv.cslist", NULL, &size, NULL, 0) == -1) + return (errno); + if (size > 0) { + csi = malloc(size); + if (csi == NULL) + return (ENOMEM); + if (sysctlbyname("kern.iconv.cslist", csi, &size, NULL, 0) == -1) { + error = errno; + free(csi); + return (error); + } + for (i = 0, csip = csi; i < (size/sizeof(*csi)); i++, csip++) { + if (kiconv_aliascmp(csip->cs_to, tocode) == 0 && + kiconv_aliascmp(csip->cs_from, fromcode) == 0) { + error = kiconv_add_aliases(tocode, fromcode, + csip->cs_to, csip->cs_from); + free(csi); + return (error); + } + } + free(csi); } return (ENOENT); } --- lib/libkiconv/xlat16_iconv.c.orig Tue Aug 15 22:30:13 2006 +++ lib/libkiconv/xlat16_iconv.c Fri Aug 18 01:47:06 2006 @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2005 Ryuichiro Imura + * Copyright (c) 2003, 2005, 2006 Ryuichiro Imura * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,6 +89,15 @@ if (kiconv_lookupcs(tocode, fromcode) == 0) return (0); + + if (kiconv_lookupconv("alias") == 0) { + if (flag & KICONV_WCTYPE) + error = kiconv_lookup_aliases(fromcode, fromcode); + else + error = kiconv_lookup_aliases(tocode, fromcode); + if (error == 0) + return (0); + } if (flag & KICONV_WCTYPE) xt = kiconv_xlat16_open(fromcode, fromcode, flag); --- lib/libkiconv/xlat16_sysctl.c.orig Fri Sep 9 00:46:38 2005 +++ lib/libkiconv/xlat16_sysctl.c Thu Aug 17 23:58:36 2006 @@ -32,13 +32,6 @@ * $FreeBSD: src/lib/libkiconv/xlat16_sysctl.c,v 1.1.10.1 2005/09/08 15:46:38 imura Exp $ */ -/* - * kiconv(3) requires shared linked, and reduce module size - * when statically linked. - */ - -#ifdef PIC - #include #include #include @@ -48,16 +41,19 @@ #include int -kiconv_add_xlat16_table(const char *to, const char *from, const void *data, int datalen) +kiconv_add(const char *drv, const char *to, const char *from, const void *data, + int datalen) { struct iconv_add_in din; struct iconv_add_out dout; size_t olen; + if (strlen(drv) >= ICONV_CNVNMAXLEN) + return (EINVAL); if (strlen(from) >= ICONV_CSNMAXLEN || strlen(to) >= ICONV_CSNMAXLEN) return (EINVAL); din.ia_version = ICONV_ADD_VER; - strcpy(din.ia_converter, "xlat16"); + strcpy(din.ia_converter, drv); strcpy(din.ia_from, from); strcpy(din.ia_to, to); din.ia_data = data; @@ -68,9 +64,23 @@ return (0); } -#else /* statically linked */ +/* + * kiconv(3) requires shared linked, and reduce module size + * when statically linked. + */ -#include +#ifdef PIC + +int +kiconv_add_xlat16_table(const char *to, const char *from, const void *data, int datalen) +{ + int ret; + + ret = kiconv_add("xlat16", to, from, data, datalen); + return (ret); + } + +#else /* statically linked */ int kiconv_add_xlat16_table(const char *to, const char *from, const void *data, int datalen)