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