2 * Copyright (c) 1999-2002, Boris Popov
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
32 * $FreeBSD: src/lib/libncp/ncpl_nls.c,v 1.2.2.1 2002/04/30 08:18:24 bp Exp $
36 * Languages support. Currently is very primitive.
38 #include <sys/types.h>
45 #include <netncp/ncp_lib.h>
46 #include <netncp/ncp_cfg.h>
47 #include <netncp/ncp_nls.h>
49 #ifndef NCP_NLS_DEFAULT
50 #define NCP_NLS_DEFAULT NCP_NLS_AS_IS
54 * TODO: Make all tables dynamically loadable.
56 #ifdef NCP_NLS_KOI2CP866
57 /* Russian tables from easy-cyrillic:
58 * Copyright (C) 1993-1994 by Andrey A. Chernov, Moscow, Russia
60 static u_int8_t alt2koi8[] = {
61 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
62 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
63 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
64 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
65 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
66 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
67 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
68 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
69 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
70 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
71 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
72 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
73 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
74 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
75 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
76 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
77 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
78 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
79 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
80 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
81 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
82 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
83 0x90, 0x91, 0x92, 0x81, 0x87, 0xb2, 0xb4, 0xa7,
84 0xa6, 0xb5, 0xa1, 0xa8, 0xae, 0xad, 0xac, 0x83,
85 0x84, 0x89, 0x88, 0x86, 0x80, 0x8a, 0xaf, 0xb0,
86 0xab, 0xa5, 0xbb, 0xb8, 0xb1, 0xa0, 0xbe, 0xb9,
87 0xba, 0xb6, 0xb7, 0xaa, 0xa9, 0xa2, 0xa4, 0xbd,
88 0xbc, 0x85, 0x82, 0x8d, 0x8c, 0x8e, 0x8f, 0x8b,
89 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
90 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
91 0xb3, 0xa3, 0x99, 0x98, 0x93, 0x9b, 0x9f, 0x97,
92 0x9c, 0x95, 0x9e, 0x96, 0xbf, 0x9d, 0x94, 0x9a
95 static u_int8_t koi82alt[] = {
96 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
97 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
98 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
99 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
100 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
101 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
102 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
103 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
104 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
105 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
106 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
107 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
108 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
109 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
110 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
111 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
112 0xc4, 0xb3, 0xda, 0xbf, 0xc0, 0xd9, 0xc3, 0xb4, /* 0x80 */
113 0xc2, 0xc1, 0xc5, 0xdf, 0xdc, 0xdb, 0xdd, 0xde,
114 0xb0, 0xb1, 0xb2, 0xf4, 0xfe, 0xf9, 0xfb, 0xf7,
115 0xf3, 0xf2, 0xff, 0xf5, 0xf8, 0xfd, 0xfa, 0xf6,
116 0xcd, 0xba, 0xd5, 0xf1, 0xd6, 0xc9, 0xb8, 0xb7,
117 0xbb, 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6,
118 0xc7, 0xcc, 0xb5, 0xf0, 0xb6, 0xb9, 0xd1, 0xd2,
119 0xcb, 0xcf, 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0xfc,
120 0xee, 0xa0, 0xa1, 0xe6, 0xa4, 0xa5, 0xe4, 0xa3,
121 0xe5, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
122 0xaf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0xa6, 0xa2,
123 0xec, 0xeb, 0xa7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
124 0x9e, 0x80, 0x81, 0x96, 0x84, 0x85, 0x94, 0x83,
125 0x95, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
126 0x8f, 0x9f, 0x90, 0x91, 0x92, 0x93, 0x86, 0x82, /* 0xf0 */
127 0x9c, 0x9b, 0x87, 0x98, 0x9d, 0x99, 0x97, 0x9a
133 * Characters mapping for codepages used in Sweden.
135 static u_int8_t se_nw2unix[] = {
136 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
137 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
138 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
139 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
140 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
141 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
142 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
143 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
144 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
145 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
146 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
147 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
148 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
149 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
150 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
151 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
152 0xe1, 0xe2, 0xf7, 0xe7, 0xE4, 0xc4, 0xE5, 0xfa, /* 0x80 */
153 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xC4, 0xC5,
154 0xf2, 0xf3, 0xf4, 0xf5, 0xF6, 0xe8, 0xe3, 0xfe, /* 0x90 */
155 0xfb, 0xD6, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
156 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0xA0 */
157 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
158 0x90, 0x91, 0x92, 0x81, 0x87, 0xb2, 0xb4, 0xa7, /* 0xB0 */
159 0xa6, 0xb5, 0xa1, 0xa8, 0xae, 0xad, 0xac, 0x83,
160 0x84, 0x89, 0x88, 0x86, 0x80, 0x8a, 0xaf, 0xb0, /* 0xC0 */
161 0xab, 0xa5, 0xbb, 0xb8, 0xb1, 0xa0, 0xbe, 0xb9,
162 0xba, 0xb6, 0xb7, 0xaa, 0xa9, 0xa2, 0xa4, 0xbd, /* 0xD0 */
163 0xbc, 0x85, 0x82, 0x8d, 0x8c, 0x8e, 0x8f, 0x8b,
164 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0xE0 */
165 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
166 0xb3, 0xa3, 0x99, 0x98, 0x93, 0x9b, 0x9f, 0x97, /* 0xF0 */
167 0x9c, 0x95, 0x9e, 0x96, 0xbf, 0x9d, 0x94, 0x9a
170 static u_int8_t se_unix2nw[] = {
171 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
172 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
173 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
174 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
175 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
176 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
177 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
178 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
179 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
180 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
181 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
182 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
183 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
184 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
185 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
186 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
187 0xc4, 0xb3, 0xda, 0xbf, 0xc0, 0xd9, 0xc3, 0xb4, /* 0x80 */
188 0xc2, 0xc1, 0xc5, 0xdf, 0xdc, 0xdb, 0xdd, 0xde,
189 0xb0, 0xb1, 0xb2, 0xf4, 0xfe, 0xf9, 0xfb, 0xf7, /* 0x90 */
190 0xf3, 0xf2, 0xff, 0xf5, 0xf8, 0xfd, 0xfa, 0xf6,
191 0xcd, 0xba, 0xd5, 0xf1, 0xd6, 0xc9, 0xb8, 0xb7, /* 0xA0 */
192 0xbb, 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6,
193 0xc7, 0xcc, 0xb5, 0xf0, 0xb6, 0xb9, 0xd1, 0xd2, /* 0xB0 */
194 0xcb, 0xcf, 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0xfc,
195 0xee, 0xa0, 0xa1, 0xe6, 0x8E, 0x8F, 0xe4, 0xa3, /* 0xC0 */
196 0xe5, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
197 0xaf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0x99, 0xa2, /* 0xD0 */
198 0xec, 0xeb, 0xa7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
199 0x9e, 0x80, 0x81, 0x96, 0x84, 0x86, 0x94, 0x83, /* 0xE0 */
200 0x95, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
201 0x8f, 0x9f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x82, /* 0xf0 */
202 0x9c, 0x9b, 0x87, 0x98, 0x9d, 0x99, 0x97, 0x9a
206 static u_int8_t def2lower[256];
207 static u_int8_t def2upper[256];
210 * List of available charsets
215 struct ncp_nlstables nls;
218 static struct ncp_nlsdesc ncp_nlslist[] = {
219 {NCP_NLS_AS_IS, NCP_NLS_AS_IS_NAME,
220 {def2lower, def2upper, NULL, NULL, 0}
222 #ifdef NCP_NLS_KOI2CP866
223 {NCP_NLS_KOI_866, NCP_NLS_KOI_866_NAME,
224 {def2lower, def2upper, alt2koi8, koi82alt, 0}
227 {NCP_NLS_SE, NCP_NLS_SE_NAME,
228 {def2lower, def2upper, se_nw2unix, se_unix2nw, 0}
233 struct ncp_nlstables ncp_nls;
236 ncp_nls_setlocale(char *name) {
239 ncp_nls.to_lower = def2lower;
240 ncp_nls.to_upper = def2upper;
241 if (setlocale(LC_CTYPE, name) == NULL) {
242 fprintf(stderr, "Can't set locale '%s'\n", name);
245 for (i = 0; i < 256; i++) {
246 ncp_nls.to_lower[i] = tolower(i);
247 ncp_nls.to_upper[i] = toupper(i);
253 ncp_nls_setrecode(int scheme) {
254 struct ncp_nlsdesc *nd;
258 scheme = NCP_NLS_DEFAULT;
260 scheme = NCP_NLS_AS_IS;
263 for (nd = ncp_nlslist; nd->name; nd++) {
264 if (nd->scheme != scheme) continue;
265 ncp_nls.u2n = nd->nls.u2n;
266 ncp_nls.n2u = nd->nls.n2u;
267 return ncp_nls_setlocale("");
269 fprintf(stderr, "Character conversion scheme %d was not compiled in\n", scheme);
274 ncp_nls_setrecodebyname(char *name) {
275 struct ncp_nlsdesc *nd;
277 for (nd = ncp_nlslist; nd->name; nd++) {
278 if (strcmp(nd->name, name) != 0) continue;
279 ncp_nls.u2n = nd->nls.u2n;
280 ncp_nls.n2u = nd->nls.n2u;
283 fprintf(stderr, "Character conversion scheme %s was not compiled in\n", name);
288 ncp_nls_str_n2u(char *dst, const char *src) {
291 if (ncp_nls.n2u == NULL) {
292 return strcpy(dst, src);
296 *p++ = ncp_nls.n2u[(u_char)*(src++)];
302 ncp_nls_str_u2n(char *dst, const char *src) {
305 if (ncp_nls.u2n == NULL) {
306 return strcpy(dst, src);
310 *p++ = ncp_nls.u2n[(u_char)*(src++)];
316 ncp_nls_mem_n2u(char *dst, const char *src, int size) {
319 if (size == 0) return NULL;
320 if (ncp_nls.n2u == NULL) {
321 return memcpy(dst, src, size);
323 for(p = dst; size; size--, p++)
324 *p = ncp_nls.n2u[(u_char)*(src++)];
329 ncp_nls_mem_u2n(char *dst, const char *src, int size) {
332 if (size == 0) return NULL;
333 if (ncp_nls.u2n == NULL) {
334 return strcpy(dst, src);
336 for(p = dst; size; size--, p++)
337 *p = ncp_nls.u2n[(u_char)*(src++)];
342 ncp_str_upper(char *s) {