187866Ssheldonh/* 287866Ssheldonh * Copyright (c) 2000-2001, Boris Popov 387866Ssheldonh * All rights reserved. 487866Ssheldonh * 587866Ssheldonh * Redistribution and use in source and binary forms, with or without 687866Ssheldonh * modification, are permitted provided that the following conditions 787866Ssheldonh * are met: 887866Ssheldonh * 1. Redistributions of source code must retain the above copyright 987866Ssheldonh * notice, this list of conditions and the following disclaimer. 1087866Ssheldonh * 2. Redistributions in binary form must reproduce the above copyright 1187866Ssheldonh * notice, this list of conditions and the following disclaimer in the 1287866Ssheldonh * documentation and/or other materials provided with the distribution. 1387866Ssheldonh * 3. All advertising materials mentioning features or use of this software 1487866Ssheldonh * must display the following acknowledgement: 1587866Ssheldonh * This product includes software developed by Boris Popov. 1687866Ssheldonh * 4. Neither the name of the author nor the names of any co-contributors 1787866Ssheldonh * may be used to endorse or promote products derived from this software 1887866Ssheldonh * without specific prior written permission. 1987866Ssheldonh * 2087866Ssheldonh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2187866Ssheldonh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2287866Ssheldonh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2387866Ssheldonh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2487866Ssheldonh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2587866Ssheldonh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2687866Ssheldonh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2787866Ssheldonh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2887866Ssheldonh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2987866Ssheldonh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3087866Ssheldonh * SUCH DAMAGE. 3187866Ssheldonh * 32100490Sbp * $Id: nls.c,v 1.10 2002/07/22 08:33:59 bp Exp $ 3387866Ssheldonh */ 3487866Ssheldonh 35136699Sobrien#include <sys/cdefs.h> 36136699Sobrien__FBSDID("$FreeBSD$"); 37136699Sobrien 3887866Ssheldonh#include <sys/types.h> 3987866Ssheldonh#include <sys/sysctl.h> 4087866Ssheldonh#include <ctype.h> 4187866Ssheldonh#include <errno.h> 4287866Ssheldonh#include <stdio.h> 43136699Sobrien#include <string.h> 4487866Ssheldonh#include <stdlib.h> 4587866Ssheldonh#include <locale.h> 4687866Ssheldonh#include <err.h> 4787866Ssheldonh#include <netsmb/smb_lib.h> 4887866Ssheldonh 49258125Sglebius#ifdef HAVE_ICONV 50258125Sglebius#include <iconv.h> 51258125Sglebius#endif 5287866Ssheldonh 5387866Ssheldonhu_char nls_lower[256]; 5487866Ssheldonhu_char nls_upper[256]; 5587866Ssheldonh 56258125Sglebius#ifdef HAVE_ICONV 5787866Ssheldonhstatic iconv_t nls_toext, nls_toloc; 58258125Sglebius#endif 5987866Ssheldonh 6087866Ssheldonhint 6187866Ssheldonhnls_setlocale(const char *name) 6287866Ssheldonh{ 6387866Ssheldonh int i; 6487866Ssheldonh 6587866Ssheldonh if (setlocale(LC_CTYPE, name) == NULL) { 6687866Ssheldonh warnx("can't set locale '%s'\n", name); 6787866Ssheldonh return EINVAL; 6887866Ssheldonh } 6987866Ssheldonh for (i = 0; i < 256; i++) { 7087866Ssheldonh nls_lower[i] = tolower(i); 7187866Ssheldonh nls_upper[i] = toupper(i); 7287866Ssheldonh } 7387866Ssheldonh return 0; 7487866Ssheldonh} 7587866Ssheldonh 7687866Ssheldonhint 7787866Ssheldonhnls_setrecode(const char *local, const char *external) 7887866Ssheldonh{ 79258125Sglebius#ifdef HAVE_ICONV 8087866Ssheldonh iconv_t icd; 8187866Ssheldonh 8287866Ssheldonh if (nls_toext) 83258125Sglebius iconv_close(nls_toext); 8487866Ssheldonh if (nls_toloc) 85258125Sglebius iconv_close(nls_toloc); 8687866Ssheldonh nls_toext = nls_toloc = (iconv_t)0; 87258125Sglebius icd = iconv_open(external, local); 8887866Ssheldonh if (icd == (iconv_t)-1) 8987866Ssheldonh return errno; 9087866Ssheldonh nls_toext = icd; 91258125Sglebius icd = iconv_open(local, external); 9287866Ssheldonh if (icd == (iconv_t)-1) { 93258125Sglebius iconv_close(nls_toext); 9487866Ssheldonh nls_toext = (iconv_t)0; 9587866Ssheldonh return errno; 9687866Ssheldonh } 9787866Ssheldonh nls_toloc = icd; 9887866Ssheldonh return 0; 99258125Sglebius#else 100258125Sglebius return ENOENT; 10188282Ssheldonh#endif 10287866Ssheldonh} 10387866Ssheldonh 10487866Ssheldonhchar * 105282275Stijlnls_str_toloc(char *dst, char *src) 10687866Ssheldonh{ 107258125Sglebius#ifdef HAVE_ICONV 10887866Ssheldonh char *p = dst; 109136699Sobrien size_t inlen, outlen; 11087866Ssheldonh 11187866Ssheldonh if (nls_toloc == (iconv_t)0) 11287866Ssheldonh return strcpy(dst, src); 11387866Ssheldonh inlen = outlen = strlen(src); 114258125Sglebius iconv(nls_toloc, NULL, NULL, &p, &outlen); 115258125Sglebius while (iconv(nls_toloc, &src, &inlen, &p, &outlen) == -1) { 116100490Sbp *p++ = *src++; 117100490Sbp inlen--; 118100490Sbp outlen--; 119100490Sbp } 12087866Ssheldonh *p = 0; 12187866Ssheldonh return dst; 122258125Sglebius#else 123258125Sglebius return strcpy(dst, src); 124258125Sglebius#endif 12587866Ssheldonh} 12687866Ssheldonh 12787866Ssheldonhchar * 128282275Stijlnls_str_toext(char *dst, char *src) 12987866Ssheldonh{ 130258125Sglebius#ifdef HAVE_ICONV 13187866Ssheldonh char *p = dst; 132136699Sobrien size_t inlen, outlen; 13387866Ssheldonh 13487866Ssheldonh if (nls_toext == (iconv_t)0) 13587866Ssheldonh return strcpy(dst, src); 13687866Ssheldonh inlen = outlen = strlen(src); 137258125Sglebius iconv(nls_toext, NULL, NULL, &p, &outlen); 138258125Sglebius while (iconv(nls_toext, &src, &inlen, &p, &outlen) == -1) { 139100490Sbp *p++ = *src++; 140100490Sbp inlen--; 141100490Sbp outlen--; 142100490Sbp } 14387866Ssheldonh *p = 0; 14487866Ssheldonh return dst; 145258125Sglebius#else 146258125Sglebius return strcpy(dst, src); 147258125Sglebius#endif 14887866Ssheldonh} 14987866Ssheldonh 15087866Ssheldonhvoid * 151282275Stijlnls_mem_toloc(void *dst, void *src, int size) 15287866Ssheldonh{ 153258125Sglebius#ifdef HAVE_ICONV 15487866Ssheldonh char *p = dst; 155282275Stijl char *s = src; 156136699Sobrien size_t inlen, outlen; 15787866Ssheldonh 15887866Ssheldonh if (size == 0) 15987866Ssheldonh return NULL; 16087866Ssheldonh 16187866Ssheldonh if (nls_toloc == (iconv_t)0) 16287866Ssheldonh return memcpy(dst, src, size); 16387866Ssheldonh inlen = outlen = size; 164258125Sglebius iconv(nls_toloc, NULL, NULL, &p, &outlen); 165258125Sglebius while (iconv(nls_toloc, &s, &inlen, &p, &outlen) == -1) { 166100490Sbp *p++ = *s++; 167100490Sbp inlen--; 168100490Sbp outlen--; 169100490Sbp } 17087866Ssheldonh return dst; 171258125Sglebius#else 172258125Sglebius return memcpy(dst, src, size); 173258125Sglebius#endif 17487866Ssheldonh} 17587866Ssheldonh 17687866Ssheldonhvoid * 177282275Stijlnls_mem_toext(void *dst, void *src, int size) 17887866Ssheldonh{ 179258125Sglebius#ifdef HAVE_ICONV 18087866Ssheldonh char *p = dst; 181282275Stijl char *s = src; 182136699Sobrien size_t inlen, outlen; 18387866Ssheldonh 18487866Ssheldonh if (size == 0) 18587866Ssheldonh return NULL; 18687866Ssheldonh 187258125Sglebius if (nls_toext == (iconv_t)0) 18887866Ssheldonh return memcpy(dst, src, size); 18987866Ssheldonh 19087866Ssheldonh inlen = outlen = size; 191258125Sglebius iconv(nls_toext, NULL, NULL, &p, &outlen); 192258125Sglebius while (iconv(nls_toext, &s, &inlen, &p, &outlen) == -1) { 193100490Sbp *p++ = *s++; 194100490Sbp inlen--; 195100490Sbp outlen--; 196100490Sbp } 19787866Ssheldonh return dst; 198258125Sglebius#else 199258125Sglebius return memcpy(dst, src, size); 200258125Sglebius#endif 20187866Ssheldonh} 20287866Ssheldonh 20387866Ssheldonhchar * 20487866Ssheldonhnls_str_upper(char *dst, const char *src) 20587866Ssheldonh{ 20687866Ssheldonh char *p = dst; 20787866Ssheldonh 20887866Ssheldonh while (*src) 20987866Ssheldonh *dst++ = toupper(*src++); 21087866Ssheldonh *dst = 0; 21187866Ssheldonh return p; 21287866Ssheldonh} 21387866Ssheldonh 21487866Ssheldonhchar * 21587866Ssheldonhnls_str_lower(char *dst, const char *src) 21687866Ssheldonh{ 21787866Ssheldonh char *p = dst; 21887866Ssheldonh 21987866Ssheldonh while (*src) 22087866Ssheldonh *dst++ = tolower(*src++); 22187866Ssheldonh *dst = 0; 22287866Ssheldonh return p; 22387866Ssheldonh} 224