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 */
16 int iconv_open_stub(const char *, const char *, void **);
17 int iconv_close_stub(void *);
18 int 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 
23 int
iconv_open_stub(const char * to,const char * from,void ** handle)24 iconv_open_stub(const char *to, const char *from,
25     void **handle)
26 {
27 	return 0;
28 }
29 
30 int
iconv_close_stub(void * handle)31 iconv_close_stub(void *handle)
32 {
33 	return 0;
34 }
35 
36 int
iconv_conv_stub(void * handle,const char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)37 iconv_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 
58 char *
iconv_convstr(void * handle,char * dst,const char * src,size_t l)59 iconv_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 
81 void *
iconv_convmem(void * handle,void * dst,const void * src,int size)82 iconv_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 
105 int
iconv_lookupcp(const char ** cpp,const char * s)106 iconv_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