1/* $NetBSD: iconv.c,v 1.14 2014/11/15 18:49:04 nakayama Exp $ */
2
3/* Public domain */
4
5#include <sys/cdefs.h>
6__KERNEL_RCSID(0, "$NetBSD: iconv.c,v 1.14 2014/11/15 18:49:04 nakayama Exp $");
7
8#include <sys/param.h>
9#include <sys/kernel.h>
10#include <sys/systm.h>
11#include <sys/errno.h>
12
13#include <netsmb/iconv.h>
14
15/* stubs for iconv functions */
16int iconv_open_stub(const char *, const char *, void **);
17int iconv_close_stub(void *);
18int iconv_conv_stub(void *, const char **, size_t *, char **, size_t *);
19__weak_alias(iconv_open, iconv_open_stub);
20__weak_alias(iconv_close, iconv_close_stub);
21__weak_alias(iconv_conv, iconv_conv_stub);
22
23int
24iconv_open_stub(const char *to, const char *from,
25 void **handle)
26{
27 return 0;
28}
29
30int
31iconv_close_stub(void *handle)
32{
33 return 0;
34}
35
36int
37iconv_conv_stub(void *handle, const char **inbuf,
38 size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
39{
40 if (inbuf == NULL)
41 return(0); /* initial shift state */
42
43 if (*inbytesleft > *outbytesleft)
44 return(E2BIG);
45
46 (void)memcpy(*outbuf, *inbuf, *inbytesleft);
47
48 *outbytesleft -= *inbytesleft;
49
50 *inbuf += *inbytesleft;
51 *outbuf += *inbytesleft;
52
53 *inbytesleft = 0;
54
55 return 0;
56}
57
58char *
59iconv_convstr(void *handle, char *dst, const char *src, size_t l)
60{
61 char *p = dst;
62 size_t inlen, outlen;
63 int error;
64
65 if (handle == NULL) {
66 strlcpy(dst, src, l);
67 return dst;
68 }
69 inlen = strlen(src);
70 outlen = l - 1;
71 error = iconv_conv(handle, NULL, NULL, &p, &outlen);
72 if (error)
73 return NULL;
74 error = iconv_conv(handle, &src, &inlen, &p, &outlen);
75 if (error)
76 return NULL;
77 *p = 0;
78 return dst;
79}
80
81void *
82iconv_convmem(void *handle, void *dst, const void *src, int size)
83{
84 const char *s = src;
85 char *d = dst;
86 size_t inlen, outlen;
87 int error;
88
89 if (size == 0)
90 return dst;
91 if (handle == NULL) {
92 memcpy(dst, src, size);
93 return dst;
94 }
95 inlen = outlen = size;
96 error = iconv_conv(handle, NULL, NULL, &d, &outlen);
97 if (error)
98 return NULL;
99 error = iconv_conv(handle, &s, &inlen, &d, &outlen);
100 if (error)
101 return NULL;
102 return dst;
103}
104
105int
106iconv_lookupcp(const char **cpp, const char *s)
107{
108 for (; *cpp; cpp++)
109 if (strcmp(*cpp, s) == 0)
110 return 0;
111 return ENOENT;
112}
113