| 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 |
| 24 | iconv_open_stub(const char *to, const char *from, |
| 25 | void **handle) |
| 26 | { |
| 27 | return 0; |
| 28 | } |
| 29 | |
| 30 | int |
| 31 | iconv_close_stub(void *handle) |
| 32 | { |
| 33 | return 0; |
| 34 | } |
| 35 | |
| 36 | int |
| 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 * |
| 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 * |
| 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 |
| 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 | |