nls.c revision 302408
129088Smarkm/*
229088Smarkm * Copyright (c) 2000-2001, Boris Popov
329088Smarkm * All rights reserved.
429088Smarkm *
529088Smarkm * Redistribution and use in source and binary forms, with or without
629088Smarkm * modification, are permitted provided that the following conditions
729088Smarkm * are met:
829088Smarkm * 1. Redistributions of source code must retain the above copyright
929088Smarkm *    notice, this list of conditions and the following disclaimer.
1029088Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1129088Smarkm *    notice, this list of conditions and the following disclaimer in the
1229088Smarkm *    documentation and/or other materials provided with the distribution.
1329088Smarkm * 3. All advertising materials mentioning features or use of this software
1429088Smarkm *    must display the following acknowledgement:
1529088Smarkm *    This product includes software developed by Boris Popov.
1629088Smarkm * 4. Neither the name of the author nor the names of any co-contributors
1729088Smarkm *    may be used to endorse or promote products derived from this software
1829088Smarkm *    without specific prior written permission.
1929088Smarkm *
2029088Smarkm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2129088Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2229088Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2329088Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2429088Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2529088Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2629088Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2729088Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2829088Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2929088Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3029088Smarkm * SUCH DAMAGE.
3129088Smarkm *
3229088Smarkm * $Id: nls.c,v 1.10 2002/07/22 08:33:59 bp Exp $
3329088Smarkm */
3429088Smarkm
3529181Smarkm#include <sys/cdefs.h>
3629088Smarkm__FBSDID("$FreeBSD: stable/11/contrib/smbfs/lib/smb/nls.c 281550 2015-04-15 09:09:20Z tijl $");
3729088Smarkm
3829088Smarkm#include <sys/types.h>
3929088Smarkm#include <sys/sysctl.h>
4029088Smarkm#include <ctype.h>
4129088Smarkm#include <errno.h>
4229088Smarkm#include <stdio.h>
4329088Smarkm#include <string.h>
4429088Smarkm#include <stdlib.h>
4529088Smarkm#include <locale.h>
4629088Smarkm#include <err.h>
4729088Smarkm#include <netsmb/smb_lib.h>
4829088Smarkm
4929088Smarkm#ifdef HAVE_ICONV
5029088Smarkm#include <iconv.h>
5129088Smarkm#endif
5229088Smarkm
5329088Smarkmu_char nls_lower[256];
5429088Smarkmu_char nls_upper[256];
5529088Smarkm
5629088Smarkm#ifdef HAVE_ICONV
5729088Smarkmstatic iconv_t nls_toext, nls_toloc;
5829088Smarkm#endif
5929088Smarkm
6029088Smarkmint
6129181Smarkmnls_setlocale(const char *name)
6229088Smarkm{
6329088Smarkm	int i;
6429088Smarkm
6529088Smarkm	if (setlocale(LC_CTYPE, name) == NULL) {
6629088Smarkm		warnx("can't set locale '%s'\n", name);
6729088Smarkm		return EINVAL;
6829088Smarkm	}
6929088Smarkm	for (i = 0; i < 256; i++) {
7029088Smarkm		nls_lower[i] = tolower(i);
7129088Smarkm		nls_upper[i] = toupper(i);
7229088Smarkm	}
7329088Smarkm	return 0;
7429088Smarkm}
7529088Smarkm
7629088Smarkmint
7729088Smarkmnls_setrecode(const char *local, const char *external)
7829088Smarkm{
7929088Smarkm#ifdef HAVE_ICONV
8029088Smarkm	iconv_t icd;
8129088Smarkm
8229088Smarkm	if (nls_toext)
8329181Smarkm		iconv_close(nls_toext);
8429181Smarkm	if (nls_toloc)
8529181Smarkm		iconv_close(nls_toloc);
8629181Smarkm	nls_toext = nls_toloc = (iconv_t)0;
8729181Smarkm	icd = iconv_open(external, local);
8829181Smarkm	if (icd == (iconv_t)-1)
8929181Smarkm		return errno;
9029181Smarkm	nls_toext = icd;
9129181Smarkm	icd = iconv_open(local, external);
9229181Smarkm	if (icd == (iconv_t)-1) {
9329181Smarkm		iconv_close(nls_toext);
9429181Smarkm		nls_toext = (iconv_t)0;
9529088Smarkm		return errno;
9629088Smarkm	}
9729088Smarkm	nls_toloc = icd;
9829088Smarkm	return 0;
9929088Smarkm#else
10029088Smarkm	return ENOENT;
10129088Smarkm#endif
10229088Smarkm}
10329088Smarkm
10429088Smarkmchar *
10529088Smarkmnls_str_toloc(char *dst, char *src)
10629088Smarkm{
10749887Snsayer#ifdef HAVE_ICONV
10849887Snsayer	char *p = dst;
10949887Snsayer	size_t inlen, outlen;
11049887Snsayer
11149887Snsayer	if (nls_toloc == (iconv_t)0)
11249887Snsayer		return strcpy(dst, src);
11349887Snsayer	inlen = outlen = strlen(src);
11449887Snsayer	iconv(nls_toloc, NULL, NULL, &p, &outlen);
11549887Snsayer	while (iconv(nls_toloc, &src, &inlen, &p, &outlen) == -1) {
11649887Snsayer		*p++ = *src++;
11749887Snsayer		inlen--;
11829088Smarkm		outlen--;
11929088Smarkm	}
12029088Smarkm	*p = 0;
12129088Smarkm	return dst;
12229088Smarkm#else
12329088Smarkm	return strcpy(dst, src);
12429088Smarkm#endif
12529088Smarkm}
12629088Smarkm
12729088Smarkmchar *
12829088Smarkmnls_str_toext(char *dst, char *src)
12929088Smarkm{
13029088Smarkm#ifdef HAVE_ICONV
13129088Smarkm	char *p = dst;
13229088Smarkm	size_t inlen, outlen;
13329088Smarkm
13429088Smarkm	if (nls_toext == (iconv_t)0)
13529088Smarkm		return strcpy(dst, src);
13629088Smarkm	inlen = outlen = strlen(src);
13729088Smarkm	iconv(nls_toext, NULL, NULL, &p, &outlen);
13829088Smarkm	while (iconv(nls_toext, &src, &inlen, &p, &outlen) == -1) {
13929088Smarkm		*p++ = *src++;
14029088Smarkm		inlen--;
14129088Smarkm		outlen--;
14229088Smarkm	}
14329088Smarkm	*p = 0;
14429088Smarkm	return dst;
14529088Smarkm#else
14629088Smarkm	return strcpy(dst, src);
14729088Smarkm#endif
14829088Smarkm}
14929088Smarkm
15029088Smarkmvoid *
15129088Smarkmnls_mem_toloc(void *dst, void *src, int size)
15229088Smarkm{
15329088Smarkm#ifdef HAVE_ICONV
15429088Smarkm	char *p = dst;
15529088Smarkm	char *s = src;
15629088Smarkm	size_t inlen, outlen;
15729088Smarkm
15829088Smarkm	if (size == 0)
15929088Smarkm		return NULL;
16029088Smarkm
16129088Smarkm	if (nls_toloc == (iconv_t)0)
16229088Smarkm		return memcpy(dst, src, size);
16329088Smarkm	inlen = outlen = size;
16429088Smarkm	iconv(nls_toloc, NULL, NULL, &p, &outlen);
16529088Smarkm	while (iconv(nls_toloc, &s, &inlen, &p, &outlen) == -1) {
16629088Smarkm		*p++ = *s++;
16729088Smarkm		inlen--;
16829088Smarkm		outlen--;
16929088Smarkm	}
17029088Smarkm	return dst;
17129088Smarkm#else
17229088Smarkm	return memcpy(dst, src, size);
17329088Smarkm#endif
17429088Smarkm}
17529088Smarkm
17629088Smarkmvoid *
17729088Smarkmnls_mem_toext(void *dst, void *src, int size)
17829088Smarkm{
17929088Smarkm#ifdef HAVE_ICONV
18029088Smarkm	char *p = dst;
18129088Smarkm	char *s = src;
18229088Smarkm	size_t inlen, outlen;
18329088Smarkm
18429088Smarkm	if (size == 0)
18529088Smarkm		return NULL;
18629088Smarkm
18729088Smarkm	if (nls_toext == (iconv_t)0)
18829088Smarkm		return memcpy(dst, src, size);
18929088Smarkm
19029088Smarkm	inlen = outlen = size;
19129088Smarkm	iconv(nls_toext, NULL, NULL, &p, &outlen);
19229088Smarkm	while (iconv(nls_toext, &s, &inlen, &p, &outlen) == -1) {
19329088Smarkm		*p++ = *s++;
19429088Smarkm		inlen--;
19529088Smarkm		outlen--;
19629088Smarkm	}
19729181Smarkm	return dst;
19829181Smarkm#else
19929088Smarkm	return memcpy(dst, src, size);
20029088Smarkm#endif
20129088Smarkm}
20229088Smarkm
20329088Smarkmchar *
20429088Smarkmnls_str_upper(char *dst, const char *src)
20529088Smarkm{
20629088Smarkm	char *p = dst;
20729088Smarkm
20829088Smarkm	while (*src)
20929088Smarkm		*dst++ = toupper(*src++);
21029088Smarkm	*dst = 0;
21129088Smarkm	return p;
21229088Smarkm}
21329088Smarkm
21429088Smarkmchar *
21529088Smarkmnls_str_lower(char *dst, const char *src)
21629088Smarkm{
21729088Smarkm	char *p = dst;
21829088Smarkm
21929088Smarkm	while (*src)
22029088Smarkm		*dst++ = tolower(*src++);
22129088Smarkm	*dst = 0;
22229088Smarkm	return p;
22329088Smarkm}
22429088Smarkm