1 /* $NetBSD: iconv.c,v 1.12 2009/08/05 15:17:02 joerg Exp $ */ 2 3 /*- 4 * Copyright (c)2003 Citrus Project, 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 #if defined(LIBC_SCCS) && !defined(lint) 31 __RCSID("$NetBSD: iconv.c,v 1.12 2009/08/05 15:17:02 joerg Exp $"); 32 #endif /* LIBC_SCCS and not lint */ 33 34 #include "namespace.h" 35 #include <assert.h> 36 #include <errno.h> 37 #include <paths.h> 38 #include <sys/queue.h> 39 40 #include <iconv.h> 41 42 #ifdef __weak_alias 43 __weak_alias(iconv, _iconv) 44 __weak_alias(iconv_open, _iconv_open) 45 __weak_alias(iconv_close, _iconv_close) 46 #endif 47 48 #ifdef HAVE_CITRUS 49 #include <sys/types.h> 50 #include "citrus_types.h" 51 #include "citrus_module.h" 52 #include "citrus_esdb.h" 53 #include "citrus_hash.h" 54 #include "citrus_iconv.h" 55 56 #define ISBADF(_h_) (!(_h_) || (_h_) == (iconv_t)-1) 57 58 59 iconv_t 60 iconv_open(const char *out, const char *in) 61 { 62 int ret; 63 struct _citrus_iconv *handle; 64 65 ret = _citrus_iconv_open(&handle, _PATH_ICONV, in, out); 66 if (ret) { 67 errno = ret == ENOENT? EINVAL : ret; 68 return ((iconv_t)-1); 69 } 70 71 return ((iconv_t)(void *)handle); 72 } 73 74 int 75 iconv_close(iconv_t handle) 76 { 77 if (ISBADF(handle)) { 78 errno = EBADF; 79 return (-1); 80 } 81 82 _citrus_iconv_close((struct _citrus_iconv *)(void *)handle); 83 84 return (0); 85 } 86 87 size_t 88 iconv(iconv_t handle, const char **in, size_t *szin, char **out, size_t *szout) 89 { 90 int err; 91 size_t ret; 92 93 if (ISBADF(handle)) { 94 errno = EBADF; 95 return ((size_t)-1); 96 } 97 98 err = _citrus_iconv_convert( 99 (struct _citrus_iconv *)(void *)handle, in, szin, out, szout, 100 0, &ret); 101 if (err) { 102 errno = err; 103 ret = (size_t)-1; 104 } 105 106 return (ret); 107 } 108 109 size_t 110 __iconv(iconv_t handle, const char **in, size_t *szin, char **out, 111 size_t *szout, u_int32_t flags, size_t *invalids) 112 { 113 int err; 114 size_t ret; 115 116 if (ISBADF(handle)) { 117 errno = EBADF; 118 return ((size_t)-1); 119 } 120 121 err = _citrus_iconv_convert( 122 (struct _citrus_iconv *)(void *)handle, in, szin, out, szout, 123 flags, &ret); 124 if (invalids) 125 *invalids = ret; 126 if (err) { 127 errno = err; 128 ret = (size_t)-1; 129 } 130 131 return (ret); 132 } 133 134 int 135 __iconv_get_list(char ***rlist, size_t *rsz) 136 { 137 int ret; 138 139 ret = _citrus_esdb_get_list(rlist, rsz); 140 if (ret) { 141 errno = ret; 142 return -1; 143 } 144 145 return 0; 146 } 147 148 void 149 __iconv_free_list(char **list, size_t sz) 150 { 151 _citrus_esdb_free_list(list, sz); 152 } 153 154 #else 155 iconv_t 156 /*ARGSUSED*/ 157 iconv_open(const char *in, const char *out) 158 { 159 errno = EINVAL; 160 return ((iconv_t)-1); 161 } 162 int 163 /*ARGSUSED*/ 164 iconv_close(iconv_t handle) 165 { 166 errno = EBADF; 167 return (-1); 168 } 169 size_t 170 /*ARGSUSED*/ 171 iconv(iconv_t handle, const char **in, size_t *szin, char **out, size_t *szout) 172 { 173 errno = EBADF; 174 return ((size_t)-1); 175 } 176 int 177 /*ARGSUSED*/ 178 __iconv_get_list(char ***rlist, size_t *rsz) 179 { 180 errno = EINVAL; 181 return -1; 182 } 183 void 184 /*ARGSUSED*/ 185 __iconv_free_list(char **list, size_t sz) 186 { 187 } 188 #endif 189