1f1b9d127SSheldon Hearn /* 2f1b9d127SSheldon Hearn * Copyright (c) 2000-2001, Boris Popov 3f1b9d127SSheldon Hearn * All rights reserved. 4f1b9d127SSheldon Hearn * 5f1b9d127SSheldon Hearn * Redistribution and use in source and binary forms, with or without 6f1b9d127SSheldon Hearn * modification, are permitted provided that the following conditions 7f1b9d127SSheldon Hearn * are met: 8f1b9d127SSheldon Hearn * 1. Redistributions of source code must retain the above copyright 9f1b9d127SSheldon Hearn * notice, this list of conditions and the following disclaimer. 10f1b9d127SSheldon Hearn * 2. Redistributions in binary form must reproduce the above copyright 11f1b9d127SSheldon Hearn * notice, this list of conditions and the following disclaimer in the 12f1b9d127SSheldon Hearn * documentation and/or other materials provided with the distribution. 13f1b9d127SSheldon Hearn * 3. All advertising materials mentioning features or use of this software 14f1b9d127SSheldon Hearn * must display the following acknowledgement: 15f1b9d127SSheldon Hearn * This product includes software developed by Boris Popov. 16f1b9d127SSheldon Hearn * 4. Neither the name of the author nor the names of any co-contributors 17f1b9d127SSheldon Hearn * may be used to endorse or promote products derived from this software 18f1b9d127SSheldon Hearn * without specific prior written permission. 19f1b9d127SSheldon Hearn * 20f1b9d127SSheldon Hearn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21f1b9d127SSheldon Hearn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22f1b9d127SSheldon Hearn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23f1b9d127SSheldon Hearn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24f1b9d127SSheldon Hearn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25f1b9d127SSheldon Hearn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26f1b9d127SSheldon Hearn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27f1b9d127SSheldon Hearn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28f1b9d127SSheldon Hearn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29f1b9d127SSheldon Hearn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30f1b9d127SSheldon Hearn * SUCH DAMAGE. 31f1b9d127SSheldon Hearn * 32b4bd78b0SBoris Popov * $Id: nls.c,v 1.10 2002/07/22 08:33:59 bp Exp $ 33f1b9d127SSheldon Hearn */ 34f1b9d127SSheldon Hearn 35caef65b8SDavid E. O'Brien #include <sys/cdefs.h> 36caef65b8SDavid E. O'Brien __FBSDID("$FreeBSD$"); 37caef65b8SDavid E. O'Brien 38f1b9d127SSheldon Hearn #include <sys/types.h> 39f1b9d127SSheldon Hearn #include <sys/sysctl.h> 40f1b9d127SSheldon Hearn #include <ctype.h> 41f1b9d127SSheldon Hearn #include <errno.h> 42f1b9d127SSheldon Hearn #include <stdio.h> 43caef65b8SDavid E. O'Brien #include <string.h> 44f1b9d127SSheldon Hearn #include <stdlib.h> 45f1b9d127SSheldon Hearn #include <locale.h> 46f1b9d127SSheldon Hearn #include <err.h> 47f1b9d127SSheldon Hearn #include <netsmb/smb_lib.h> 48f1b9d127SSheldon Hearn 49*ce102ac2SGleb Smirnoff #ifdef HAVE_ICONV 50*ce102ac2SGleb Smirnoff #include <iconv.h> 51*ce102ac2SGleb Smirnoff #endif 52*ce102ac2SGleb Smirnoff 53f1b9d127SSheldon Hearn u_char nls_lower[256]; 54f1b9d127SSheldon Hearn u_char nls_upper[256]; 55f1b9d127SSheldon Hearn 56*ce102ac2SGleb Smirnoff #ifdef HAVE_ICONV 57f1b9d127SSheldon Hearn static iconv_t nls_toext, nls_toloc; 58*ce102ac2SGleb Smirnoff #endif 59f1b9d127SSheldon Hearn 60f1b9d127SSheldon Hearn int 61f1b9d127SSheldon Hearn nls_setlocale(const char *name) 62f1b9d127SSheldon Hearn { 63f1b9d127SSheldon Hearn int i; 64f1b9d127SSheldon Hearn 65f1b9d127SSheldon Hearn if (setlocale(LC_CTYPE, name) == NULL) { 66f1b9d127SSheldon Hearn warnx("can't set locale '%s'\n", name); 67f1b9d127SSheldon Hearn return EINVAL; 68f1b9d127SSheldon Hearn } 69f1b9d127SSheldon Hearn for (i = 0; i < 256; i++) { 70f1b9d127SSheldon Hearn nls_lower[i] = tolower(i); 71f1b9d127SSheldon Hearn nls_upper[i] = toupper(i); 72f1b9d127SSheldon Hearn } 73f1b9d127SSheldon Hearn return 0; 74f1b9d127SSheldon Hearn } 75f1b9d127SSheldon Hearn 76f1b9d127SSheldon Hearn int 77f1b9d127SSheldon Hearn nls_setrecode(const char *local, const char *external) 78f1b9d127SSheldon Hearn { 79*ce102ac2SGleb Smirnoff #ifdef HAVE_ICONV 80f1b9d127SSheldon Hearn iconv_t icd; 81f1b9d127SSheldon Hearn 82f1b9d127SSheldon Hearn if (nls_toext) 8309601309SGleb Smirnoff iconv_close(nls_toext); 84f1b9d127SSheldon Hearn if (nls_toloc) 8509601309SGleb Smirnoff iconv_close(nls_toloc); 86f1b9d127SSheldon Hearn nls_toext = nls_toloc = (iconv_t)0; 8709601309SGleb Smirnoff icd = iconv_open(external, local); 88f1b9d127SSheldon Hearn if (icd == (iconv_t)-1) 89f1b9d127SSheldon Hearn return errno; 90f1b9d127SSheldon Hearn nls_toext = icd; 9109601309SGleb Smirnoff icd = iconv_open(local, external); 92f1b9d127SSheldon Hearn if (icd == (iconv_t)-1) { 9309601309SGleb Smirnoff iconv_close(nls_toext); 94f1b9d127SSheldon Hearn nls_toext = (iconv_t)0; 95f1b9d127SSheldon Hearn return errno; 96f1b9d127SSheldon Hearn } 97f1b9d127SSheldon Hearn nls_toloc = icd; 98f1b9d127SSheldon Hearn return 0; 99*ce102ac2SGleb Smirnoff #else 100*ce102ac2SGleb Smirnoff return ENOENT; 101df3342d6SSheldon Hearn #endif 102f1b9d127SSheldon Hearn } 103f1b9d127SSheldon Hearn 104f1b9d127SSheldon Hearn char * 105f1b9d127SSheldon Hearn nls_str_toloc(char *dst, const char *src) 106f1b9d127SSheldon Hearn { 107*ce102ac2SGleb Smirnoff #ifdef HAVE_ICONV 108f1b9d127SSheldon Hearn char *p = dst; 109caef65b8SDavid E. O'Brien size_t inlen, outlen; 110f1b9d127SSheldon Hearn 111f1b9d127SSheldon Hearn if (nls_toloc == (iconv_t)0) 112f1b9d127SSheldon Hearn return strcpy(dst, src); 113f1b9d127SSheldon Hearn inlen = outlen = strlen(src); 11409601309SGleb Smirnoff iconv(nls_toloc, NULL, NULL, &p, &outlen); 11509601309SGleb Smirnoff while (iconv(nls_toloc, &src, &inlen, &p, &outlen) == -1) { 116b4bd78b0SBoris Popov *p++ = *src++; 117b4bd78b0SBoris Popov inlen--; 118b4bd78b0SBoris Popov outlen--; 119b4bd78b0SBoris Popov } 120f1b9d127SSheldon Hearn *p = 0; 121f1b9d127SSheldon Hearn return dst; 122*ce102ac2SGleb Smirnoff #else 123*ce102ac2SGleb Smirnoff return strcpy(dst, src); 124*ce102ac2SGleb Smirnoff #endif 125f1b9d127SSheldon Hearn } 126f1b9d127SSheldon Hearn 127f1b9d127SSheldon Hearn char * 128f1b9d127SSheldon Hearn nls_str_toext(char *dst, const char *src) 129f1b9d127SSheldon Hearn { 130*ce102ac2SGleb Smirnoff #ifdef HAVE_ICONV 131f1b9d127SSheldon Hearn char *p = dst; 132caef65b8SDavid E. O'Brien size_t inlen, outlen; 133f1b9d127SSheldon Hearn 134f1b9d127SSheldon Hearn if (nls_toext == (iconv_t)0) 135f1b9d127SSheldon Hearn return strcpy(dst, src); 136f1b9d127SSheldon Hearn inlen = outlen = strlen(src); 13709601309SGleb Smirnoff iconv(nls_toext, NULL, NULL, &p, &outlen); 13809601309SGleb Smirnoff while (iconv(nls_toext, &src, &inlen, &p, &outlen) == -1) { 139b4bd78b0SBoris Popov *p++ = *src++; 140b4bd78b0SBoris Popov inlen--; 141b4bd78b0SBoris Popov outlen--; 142b4bd78b0SBoris Popov } 143f1b9d127SSheldon Hearn *p = 0; 144f1b9d127SSheldon Hearn return dst; 145*ce102ac2SGleb Smirnoff #else 146*ce102ac2SGleb Smirnoff return strcpy(dst, src); 147*ce102ac2SGleb Smirnoff #endif 148f1b9d127SSheldon Hearn } 149f1b9d127SSheldon Hearn 150f1b9d127SSheldon Hearn void * 151f1b9d127SSheldon Hearn nls_mem_toloc(void *dst, const void *src, int size) 152f1b9d127SSheldon Hearn { 153*ce102ac2SGleb Smirnoff #ifdef HAVE_ICONV 154f1b9d127SSheldon Hearn char *p = dst; 155f1b9d127SSheldon Hearn const char *s = src; 156caef65b8SDavid E. O'Brien size_t inlen, outlen; 157f1b9d127SSheldon Hearn 158f1b9d127SSheldon Hearn if (size == 0) 159f1b9d127SSheldon Hearn return NULL; 160f1b9d127SSheldon Hearn 161f1b9d127SSheldon Hearn if (nls_toloc == (iconv_t)0) 162f1b9d127SSheldon Hearn return memcpy(dst, src, size); 163f1b9d127SSheldon Hearn inlen = outlen = size; 16409601309SGleb Smirnoff iconv(nls_toloc, NULL, NULL, &p, &outlen); 16509601309SGleb Smirnoff while (iconv(nls_toloc, &s, &inlen, &p, &outlen) == -1) { 166b4bd78b0SBoris Popov *p++ = *s++; 167b4bd78b0SBoris Popov inlen--; 168b4bd78b0SBoris Popov outlen--; 169b4bd78b0SBoris Popov } 170f1b9d127SSheldon Hearn return dst; 171*ce102ac2SGleb Smirnoff #else 172*ce102ac2SGleb Smirnoff return memcpy(dst, src, size); 173*ce102ac2SGleb Smirnoff #endif 174f1b9d127SSheldon Hearn } 175f1b9d127SSheldon Hearn 176f1b9d127SSheldon Hearn void * 177f1b9d127SSheldon Hearn nls_mem_toext(void *dst, const void *src, int size) 178f1b9d127SSheldon Hearn { 179*ce102ac2SGleb Smirnoff #ifdef HAVE_ICONV 180f1b9d127SSheldon Hearn char *p = dst; 181f1b9d127SSheldon Hearn const char *s = src; 182caef65b8SDavid E. O'Brien size_t inlen, outlen; 183f1b9d127SSheldon Hearn 184f1b9d127SSheldon Hearn if (size == 0) 185f1b9d127SSheldon Hearn return NULL; 186f1b9d127SSheldon Hearn 18709601309SGleb Smirnoff if (nls_toext == (iconv_t)0) 188f1b9d127SSheldon Hearn return memcpy(dst, src, size); 189f1b9d127SSheldon Hearn 190f1b9d127SSheldon Hearn inlen = outlen = size; 19109601309SGleb Smirnoff iconv(nls_toext, NULL, NULL, &p, &outlen); 19209601309SGleb Smirnoff while (iconv(nls_toext, &s, &inlen, &p, &outlen) == -1) { 193b4bd78b0SBoris Popov *p++ = *s++; 194b4bd78b0SBoris Popov inlen--; 195b4bd78b0SBoris Popov outlen--; 196b4bd78b0SBoris Popov } 197f1b9d127SSheldon Hearn return dst; 198*ce102ac2SGleb Smirnoff #else 199*ce102ac2SGleb Smirnoff return memcpy(dst, src, size); 200*ce102ac2SGleb Smirnoff #endif 201f1b9d127SSheldon Hearn } 202f1b9d127SSheldon Hearn 203f1b9d127SSheldon Hearn char * 204f1b9d127SSheldon Hearn nls_str_upper(char *dst, const char *src) 205f1b9d127SSheldon Hearn { 206f1b9d127SSheldon Hearn char *p = dst; 207f1b9d127SSheldon Hearn 208f1b9d127SSheldon Hearn while (*src) 209f1b9d127SSheldon Hearn *dst++ = toupper(*src++); 210f1b9d127SSheldon Hearn *dst = 0; 211f1b9d127SSheldon Hearn return p; 212f1b9d127SSheldon Hearn } 213f1b9d127SSheldon Hearn 214f1b9d127SSheldon Hearn char * 215f1b9d127SSheldon Hearn nls_str_lower(char *dst, const char *src) 216f1b9d127SSheldon Hearn { 217f1b9d127SSheldon Hearn char *p = dst; 218f1b9d127SSheldon Hearn 219f1b9d127SSheldon Hearn while (*src) 220f1b9d127SSheldon Hearn *dst++ = tolower(*src++); 221f1b9d127SSheldon Hearn *dst = 0; 222f1b9d127SSheldon Hearn return p; 223f1b9d127SSheldon Hearn } 224