1*77a1ad5fSkamil /* $NetBSD: iconv.c,v 1.14 2019/10/24 18:17:59 kamil Exp $ */
2ff5c3e68Stshiozak
3ff5c3e68Stshiozak /*-
4ff5c3e68Stshiozak * Copyright (c)2003 Citrus Project,
5ff5c3e68Stshiozak * All rights reserved.
6ff5c3e68Stshiozak *
7ff5c3e68Stshiozak * Redistribution and use in source and binary forms, with or without
8ff5c3e68Stshiozak * modification, are permitted provided that the following conditions
9ff5c3e68Stshiozak * are met:
10ff5c3e68Stshiozak * 1. Redistributions of source code must retain the above copyright
11ff5c3e68Stshiozak * notice, this list of conditions and the following disclaimer.
12ff5c3e68Stshiozak * 2. Redistributions in binary form must reproduce the above copyright
13ff5c3e68Stshiozak * notice, this list of conditions and the following disclaimer in the
14ff5c3e68Stshiozak * documentation and/or other materials provided with the distribution.
15ff5c3e68Stshiozak *
16ff5c3e68Stshiozak * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17ff5c3e68Stshiozak * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18ff5c3e68Stshiozak * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ff5c3e68Stshiozak * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20ff5c3e68Stshiozak * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21ff5c3e68Stshiozak * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22ff5c3e68Stshiozak * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23ff5c3e68Stshiozak * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24ff5c3e68Stshiozak * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25ff5c3e68Stshiozak * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26ff5c3e68Stshiozak * SUCH DAMAGE.
27ff5c3e68Stshiozak */
28ff5c3e68Stshiozak
29ff5c3e68Stshiozak #include <sys/cdefs.h>
30ff5c3e68Stshiozak #if defined(LIBC_SCCS) && !defined(lint)
31*77a1ad5fSkamil __RCSID("$NetBSD: iconv.c,v 1.14 2019/10/24 18:17:59 kamil Exp $");
32ff5c3e68Stshiozak #endif /* LIBC_SCCS and not lint */
33ff5c3e68Stshiozak
34ff5c3e68Stshiozak #include "namespace.h"
35ff5c3e68Stshiozak #include <assert.h>
36ff5c3e68Stshiozak #include <errno.h>
37ff5c3e68Stshiozak #include <paths.h>
3858db2e99Stshiozak #include <sys/queue.h>
39ff5c3e68Stshiozak
40ff5c3e68Stshiozak #include <iconv.h>
41ff5c3e68Stshiozak
4296b41760Schristos #ifdef __weak_alias
__weak_alias(iconv,_iconv)4396b41760Schristos __weak_alias(iconv, _iconv)
4496b41760Schristos __weak_alias(iconv_open, _iconv_open)
4596b41760Schristos __weak_alias(iconv_close, _iconv_close)
4696b41760Schristos #endif
4796b41760Schristos
48ff5c3e68Stshiozak #include <sys/types.h>
4952ed7b03Stnozaki #include "citrus_types.h"
5052ed7b03Stnozaki #include "citrus_module.h"
5152ed7b03Stnozaki #include "citrus_esdb.h"
5252ed7b03Stnozaki #include "citrus_hash.h"
5352ed7b03Stnozaki #include "citrus_iconv.h"
54ff5c3e68Stshiozak
55ff5c3e68Stshiozak #define ISBADF(_h_) (!(_h_) || (_h_) == (iconv_t)-1)
56ff5c3e68Stshiozak
57466a3e5dSjoerg
58ff5c3e68Stshiozak iconv_t
5996b41760Schristos iconv_open(const char *out, const char *in)
60ff5c3e68Stshiozak {
61ff5c3e68Stshiozak int ret;
62ff5c3e68Stshiozak struct _citrus_iconv *handle;
63ff5c3e68Stshiozak
64466a3e5dSjoerg ret = _citrus_iconv_open(&handle, _PATH_ICONV, in, out);
65ff5c3e68Stshiozak if (ret) {
667204e681Stshiozak errno = ret == ENOENT? EINVAL : ret;
67ff5c3e68Stshiozak return ((iconv_t)-1);
68ff5c3e68Stshiozak }
69ff5c3e68Stshiozak
7058db2e99Stshiozak return ((iconv_t)(void *)handle);
71ff5c3e68Stshiozak }
72ff5c3e68Stshiozak
73ff5c3e68Stshiozak int
iconv_close(iconv_t handle)7496b41760Schristos iconv_close(iconv_t handle)
75ff5c3e68Stshiozak {
76ff5c3e68Stshiozak if (ISBADF(handle)) {
77ff5c3e68Stshiozak errno = EBADF;
78ff5c3e68Stshiozak return (-1);
79ff5c3e68Stshiozak }
80ff5c3e68Stshiozak
8158db2e99Stshiozak _citrus_iconv_close((struct _citrus_iconv *)(void *)handle);
82ff5c3e68Stshiozak
83ff5c3e68Stshiozak return (0);
84ff5c3e68Stshiozak }
85ff5c3e68Stshiozak
86ff5c3e68Stshiozak size_t
iconv(iconv_t handle,char ** in,size_t * szin,char ** out,size_t * szout)87*77a1ad5fSkamil iconv(iconv_t handle, char **in, size_t *szin, char **out, size_t *szout)
88ff5c3e68Stshiozak {
89ff5c3e68Stshiozak int err;
90ff5c3e68Stshiozak size_t ret;
91ff5c3e68Stshiozak
92ff5c3e68Stshiozak if (ISBADF(handle)) {
93ff5c3e68Stshiozak errno = EBADF;
94ff5c3e68Stshiozak return ((size_t)-1);
95ff5c3e68Stshiozak }
96ff5c3e68Stshiozak
97ff5c3e68Stshiozak err = _citrus_iconv_convert(
98*77a1ad5fSkamil (struct _citrus_iconv *)(void *)handle,
99*77a1ad5fSkamil (const char **)(void *)in, szin, out, szout, 0, &ret);
100ff5c3e68Stshiozak if (err) {
101ff5c3e68Stshiozak errno = err;
102ff5c3e68Stshiozak ret = (size_t)-1;
103ff5c3e68Stshiozak }
104ff5c3e68Stshiozak
105ff5c3e68Stshiozak return (ret);
106ff5c3e68Stshiozak }
107ff5c3e68Stshiozak
108ff5c3e68Stshiozak size_t
__iconv(iconv_t handle,char ** in,size_t * szin,char ** out,size_t * szout,u_int32_t flags,size_t * invalids)109*77a1ad5fSkamil __iconv(iconv_t handle, char **in, size_t *szin, char **out,
110ff5c3e68Stshiozak size_t *szout, u_int32_t flags, size_t *invalids)
111ff5c3e68Stshiozak {
112ff5c3e68Stshiozak int err;
113ff5c3e68Stshiozak size_t ret;
114ff5c3e68Stshiozak
115ff5c3e68Stshiozak if (ISBADF(handle)) {
116ff5c3e68Stshiozak errno = EBADF;
117ff5c3e68Stshiozak return ((size_t)-1);
118ff5c3e68Stshiozak }
119ff5c3e68Stshiozak
120ff5c3e68Stshiozak err = _citrus_iconv_convert(
121*77a1ad5fSkamil (struct _citrus_iconv *)(void *)handle,
122*77a1ad5fSkamil (const char **)(void *)in, szin, out, szout, flags, &ret);
123ff5c3e68Stshiozak if (invalids)
124ff5c3e68Stshiozak *invalids = ret;
125ff5c3e68Stshiozak if (err) {
126ff5c3e68Stshiozak errno = err;
127ff5c3e68Stshiozak ret = (size_t)-1;
128ff5c3e68Stshiozak }
129ff5c3e68Stshiozak
130ff5c3e68Stshiozak return (ret);
131ff5c3e68Stshiozak }
132ff5c3e68Stshiozak
133ff5c3e68Stshiozak int
__iconv_get_list(char *** rlist,size_t * rsz)134ff5c3e68Stshiozak __iconv_get_list(char ***rlist, size_t *rsz)
135ff5c3e68Stshiozak {
136ff5c3e68Stshiozak int ret;
137ff5c3e68Stshiozak
138ff5c3e68Stshiozak ret = _citrus_esdb_get_list(rlist, rsz);
139ff5c3e68Stshiozak if (ret) {
140ff5c3e68Stshiozak errno = ret;
141ff5c3e68Stshiozak return -1;
142ff5c3e68Stshiozak }
143ff5c3e68Stshiozak
144ff5c3e68Stshiozak return 0;
145ff5c3e68Stshiozak }
146ff5c3e68Stshiozak
147ff5c3e68Stshiozak void
__iconv_free_list(char ** list,size_t sz)148ff5c3e68Stshiozak __iconv_free_list(char **list, size_t sz)
149ff5c3e68Stshiozak {
150ff5c3e68Stshiozak _citrus_esdb_free_list(list, sz);
151ff5c3e68Stshiozak }
152