]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libncp/ncpl_nls.c
This commit was generated by cvs2svn to compensate for changes in r74713,
[FreeBSD/FreeBSD.git] / lib / libncp / ncpl_nls.c
1 /*
2  * Copyright (c) 1999, 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  * $FreeBSD$
33  */
34
35 /*
36  * Languages support. Currently is very primitive.
37  */
38 #include <sys/types.h>
39 #include <ctype.h>
40 #include <errno.h>
41 #include <stdio.h>
42 #include <strings.h>
43 #include <locale.h>
44
45 #include <netncp/ncp_lib.h>
46 #include <netncp/ncp_cfg.h>
47 #include <netncp/ncp_nls.h>
48
49 #ifndef NCP_NLS_DEFAULT
50 #define NCP_NLS_DEFAULT NCP_NLS_AS_IS
51 #endif
52
53 /*
54  * TODO: Make all tables dynamically loadable.
55  */
56 #ifdef NCP_NLS_KOI2CP866
57 /* Russian tables from easy-cyrillic:
58  * Copyright (C) 1993-1994 by Andrey A. Chernov, Moscow, Russia
59  */
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
93 };
94
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
128 };
129
130 #endif
131
132 static u_int8_t def2lower[256];
133 static u_int8_t def2upper[256];
134
135 /*
136  * List of available charsets
137  */
138 struct ncp_nlsdesc {
139         int     scheme;
140         char    *name;
141         struct ncp_nlstables nls;
142 };
143
144 static struct ncp_nlsdesc ncp_nlslist[] = {
145         {NCP_NLS_AS_IS, NCP_NLS_AS_IS_NAME, 
146             {def2lower, def2upper, NULL, NULL, 0}
147         },
148 #ifdef NCP_NLS_KOI2CP866
149         {NCP_NLS_KOI_866, NCP_NLS_KOI_866_NAME, 
150             {def2lower, def2upper, alt2koi8, koi82alt, 0}
151         },
152 #endif
153         {NULL, 0}
154 };
155
156 struct ncp_nlstables ncp_nls;
157
158 int
159 ncp_nls_setlocale(char *name) {
160         int i;
161
162         ncp_nls.to_lower = def2lower;
163         ncp_nls.to_upper = def2upper;
164         if (setlocale(LC_CTYPE, name) == NULL) {
165                 fprintf(stderr, "Can't set locale '%s'\n", name);
166                 return EINVAL;
167         }
168         for (i = 0; i < 256; i++) {
169                 ncp_nls.to_lower[i] = tolower(i);
170                 ncp_nls.to_upper[i] = toupper(i);
171         }
172         return 0;
173 }
174
175 int
176 ncp_nls_setrecode(int scheme) {
177         struct ncp_nlsdesc *nd;
178
179         if (scheme == 0) {
180 #if NCP_NLS_DEFAULT
181                 scheme = NCP_NLS_DEFAULT;
182 #else
183                 scheme = NCP_NLS_AS_IS;
184 #endif
185         }
186         for (nd = ncp_nlslist; nd->name; nd++) {
187                 if (nd->scheme != scheme) continue;
188                 ncp_nls.u2n = nd->nls.u2n;
189                 ncp_nls.n2u = nd->nls.n2u;
190                 return ncp_nls_setlocale("");
191         }
192         fprintf(stderr, "Character conversion scheme %d was not compiled in\n", scheme);
193         return EINVAL;
194 }
195
196 int
197 ncp_nls_setrecodebyname(char *name) {
198         struct ncp_nlsdesc *nd;
199
200         for (nd = ncp_nlslist; nd->name; nd++) {
201                 if (strcmp(nd->name, name) != 0) continue;
202                 ncp_nls.u2n = nd->nls.u2n;
203                 ncp_nls.n2u = nd->nls.n2u;
204                 return 0;
205         }
206         fprintf(stderr, "Character conversion scheme %s was not compiled in\n", name);
207         return EINVAL;
208 }
209
210 char *
211 ncp_nls_str_n2u(char *dst, const char *src) {
212         char *p;
213
214         if (ncp_nls.n2u == NULL) {
215                 return strcpy(dst, src);
216         }
217         p = dst;
218         while (*src)
219                 *p++ = ncp_nls.n2u[(u_char)*(src++)];
220         *p = 0;
221         return dst;
222 }
223
224 char *
225 ncp_nls_str_u2n(char *dst, const char *src) {
226         char *p;
227
228         if (ncp_nls.u2n == NULL) {
229                 return strcpy(dst, src);
230         }
231         p = dst;
232         while (*src)
233                 *p++ = ncp_nls.u2n[(u_char)*(src++)];
234         *p = 0;
235         return dst;
236 }
237
238 char *
239 ncp_nls_mem_n2u(char *dst, const char *src, int size) {
240         char *p;
241
242         if (size == 0) return NULL;
243         if (ncp_nls.n2u == NULL) {
244                 return memcpy(dst, src, size);
245         }
246         for(p = dst; size; size--, p++)
247                 *p = ncp_nls.n2u[(u_char)*(src++)];
248         return dst;
249 }
250
251 char *
252 ncp_nls_mem_u2n(char *dst, const char *src, int size) {
253         char *p;
254
255         if (size == 0) return NULL;
256         if (ncp_nls.u2n == NULL) {
257                 return strcpy(dst, src);
258         }
259         for(p = dst; size; size--, p++)
260                 *p = ncp_nls.u2n[(u_char)*(src++)];
261         return dst;
262 }
263
264 char *
265 ncp_str_upper(char *s) {
266         char *p = s;
267         while (*s) {
268                 *s = toupper(*s);
269                 s++;
270         }
271         return p;
272 }