]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - lib/libncp/ncpl_nls.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / lib / libncp / ncpl_nls.c
1 /*
2  * Copyright (c) 1999-2002, 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. Neither the name of the author nor the names of any co-contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 /*
34  * Languages support. Currently is very primitive.
35  */
36 #include <sys/types.h>
37 #include <ctype.h>
38 #include <errno.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <locale.h>
42
43 #include <netncp/ncp_lib.h>
44 #include <netncp/ncp_cfg.h>
45 #include <netncp/ncp_nls.h>
46
47 #ifndef NCP_NLS_DEFAULT
48 #define NCP_NLS_DEFAULT NCP_NLS_AS_IS
49 #endif
50
51 /*
52  * TODO: Make all tables dynamically loadable.
53  */
54 #ifdef NCP_NLS_KOI2CP866
55 /* Russian tables from easy-cyrillic:
56  * Copyright (C) 1993-1994 by Andrey A. Chernov, Moscow, Russia
57  */
58 static u_int8_t alt2koi8[] = {
59         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
60         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
61         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
62         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
63         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
64         0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
65         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
66         0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
67         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
68         0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
69         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
70         0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
71         0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
72         0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
73         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
74         0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
75         0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
76         0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
77         0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
78         0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
79         0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
80         0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
81         0x90, 0x91, 0x92, 0x81, 0x87, 0xb2, 0xb4, 0xa7,
82         0xa6, 0xb5, 0xa1, 0xa8, 0xae, 0xad, 0xac, 0x83,
83         0x84, 0x89, 0x88, 0x86, 0x80, 0x8a, 0xaf, 0xb0,
84         0xab, 0xa5, 0xbb, 0xb8, 0xb1, 0xa0, 0xbe, 0xb9,
85         0xba, 0xb6, 0xb7, 0xaa, 0xa9, 0xa2, 0xa4, 0xbd,
86         0xbc, 0x85, 0x82, 0x8d, 0x8c, 0x8e, 0x8f, 0x8b,
87         0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
88         0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
89         0xb3, 0xa3, 0x99, 0x98, 0x93, 0x9b, 0x9f, 0x97,
90         0x9c, 0x95, 0x9e, 0x96, 0xbf, 0x9d, 0x94, 0x9a
91 };
92
93 static u_int8_t koi82alt[] = {
94         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
95         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
96         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
97         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
98         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
99         0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
100         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
101         0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
102         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
103         0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
104         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
105         0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
106         0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
107         0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
108         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
109         0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
110         0xc4, 0xb3, 0xda, 0xbf, 0xc0, 0xd9, 0xc3, 0xb4, /* 0x80 */
111         0xc2, 0xc1, 0xc5, 0xdf, 0xdc, 0xdb, 0xdd, 0xde,
112         0xb0, 0xb1, 0xb2, 0xf4, 0xfe, 0xf9, 0xfb, 0xf7,
113         0xf3, 0xf2, 0xff, 0xf5, 0xf8, 0xfd, 0xfa, 0xf6,
114         0xcd, 0xba, 0xd5, 0xf1, 0xd6, 0xc9, 0xb8, 0xb7,
115         0xbb, 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6,
116         0xc7, 0xcc, 0xb5, 0xf0, 0xb6, 0xb9, 0xd1, 0xd2,
117         0xcb, 0xcf, 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0xfc,
118         0xee, 0xa0, 0xa1, 0xe6, 0xa4, 0xa5, 0xe4, 0xa3,
119         0xe5, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
120         0xaf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0xa6, 0xa2,
121         0xec, 0xeb, 0xa7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
122         0x9e, 0x80, 0x81, 0x96, 0x84, 0x85, 0x94, 0x83,
123         0x95, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
124         0x8f, 0x9f, 0x90, 0x91, 0x92, 0x93, 0x86, 0x82, /* 0xf0 */ 
125         0x9c, 0x9b, 0x87, 0x98, 0x9d, 0x99, 0x97, 0x9a
126 };
127
128 #endif
129
130 /*
131  * Characters mapping for codepages used in Sweden.
132  */
133 static u_int8_t se_nw2unix[] = {
134         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
135         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
136         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
137         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
138         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
139         0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
140         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
141         0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
142         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
143         0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
144         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
145         0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
146         0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
147         0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
148         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
149         0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
150         0xe1, 0xe2, 0xf7, 0xe7, 0xE4, 0xc4, 0xE5, 0xfa, /* 0x80 */
151         0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xC4, 0xC5,
152         0xf2, 0xf3, 0xf4, 0xf5, 0xF6, 0xe8, 0xe3, 0xfe, /* 0x90 */
153         0xfb, 0xD6, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
154         0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0xA0 */
155         0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
156         0x90, 0x91, 0x92, 0x81, 0x87, 0xb2, 0xb4, 0xa7, /* 0xB0 */
157         0xa6, 0xb5, 0xa1, 0xa8, 0xae, 0xad, 0xac, 0x83,
158         0x84, 0x89, 0x88, 0x86, 0x80, 0x8a, 0xaf, 0xb0, /* 0xC0 */
159         0xab, 0xa5, 0xbb, 0xb8, 0xb1, 0xa0, 0xbe, 0xb9,
160         0xba, 0xb6, 0xb7, 0xaa, 0xa9, 0xa2, 0xa4, 0xbd, /* 0xD0 */
161         0xbc, 0x85, 0x82, 0x8d, 0x8c, 0x8e, 0x8f, 0x8b,
162         0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0xE0 */
163         0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
164         0xb3, 0xa3, 0x99, 0x98, 0x93, 0x9b, 0x9f, 0x97, /* 0xF0 */
165         0x9c, 0x95, 0x9e, 0x96, 0xbf, 0x9d, 0x94, 0x9a
166 };
167
168 static u_int8_t se_unix2nw[] = {
169         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
170         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
171         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
172         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
173         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
174         0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
175         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
176         0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x5f,
177         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
178         0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
179         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
180         0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
181         0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
182         0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
183         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
184         0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
185         0xc4, 0xb3, 0xda, 0xbf, 0xc0, 0xd9, 0xc3, 0xb4, /* 0x80 */
186         0xc2, 0xc1, 0xc5, 0xdf, 0xdc, 0xdb, 0xdd, 0xde,
187         0xb0, 0xb1, 0xb2, 0xf4, 0xfe, 0xf9, 0xfb, 0xf7, /* 0x90 */
188         0xf3, 0xf2, 0xff, 0xf5, 0xf8, 0xfd, 0xfa, 0xf6,
189         0xcd, 0xba, 0xd5, 0xf1, 0xd6, 0xc9, 0xb8, 0xb7, /* 0xA0 */
190         0xbb, 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6,
191         0xc7, 0xcc, 0xb5, 0xf0, 0xb6, 0xb9, 0xd1, 0xd2, /* 0xB0 */
192         0xcb, 0xcf, 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0xfc,
193         0xee, 0xa0, 0xa1, 0xe6, 0x8E, 0x8F, 0xe4, 0xa3, /* 0xC0 */
194         0xe5, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
195         0xaf, 0xef, 0xe0, 0xe1, 0xe2, 0xe3, 0x99, 0xa2, /* 0xD0 */
196         0xec, 0xeb, 0xa7, 0xe8, 0xed, 0xe9, 0xe7, 0xea,
197         0x9e, 0x80, 0x81, 0x96, 0x84, 0x86, 0x94, 0x83, /* 0xE0 */
198         0x95, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
199         0x8f, 0x9f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x82, /* 0xf0 */ 
200         0x9c, 0x9b, 0x87, 0x98, 0x9d, 0x99, 0x97, 0x9a
201 };
202
203 /*
204  * Characters mapping for codepages used in Germany.
205  */
206 static u_int8_t de_nw2unix[] = {
207         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
208         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
209         0x5f, 0x5f, 0x5f, 0x5f, 0xb6, 0xa7, 0x5f, 0x5f, /* 0x10 */
210         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
211         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
212         0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
213         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
214         0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
215         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
216         0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
217         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
218         0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
219         0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
220         0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
221         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
222         0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
223         0xc7, 0xfc, 0xe9, 0xe2, 0xe4, 0xe0, 0xe5, 0xe7, /* 0x80 */
224         0xea, 0xeb, 0xe8, 0xef, 0xee, 0xec, 0xc4, 0xc5,
225         0xc9, 0xe6, 0xc6, 0xf4, 0xf6, 0xf2, 0xfb, 0xf9, /* 0x90 */
226         0xff, 0xd6, 0xdc, 0xa2, 0xa3, 0xa5, 0x5f, 0x5f,
227         0xe1, 0xed, 0xf3, 0xfa, 0xf1, 0xd1, 0xaa, 0xba, /* 0xA0 */
228         0xbf, 0x5f, 0xac, 0xbd, 0xbc, 0xa1, 0xab, 0xbb,
229         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0xB0 */
230         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
231         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0xC0 */
232         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
233         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0xD0 */
234         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
235         0x5f, 0xdf, 0x5f, 0x5f, 0x5f, 0x5f, 0xb5, 0x5f, /* 0xE0 */
236         0x5f, 0x5f, 0x5f, 0xf0, 0x5f, 0xf8, 0x5f, 0x5f,
237         0x5f, 0xb1, 0x5f, 0x5f, 0x5f, 0x5f, 0xf7, 0x5f, /* 0xF0 */
238         0xb0, 0x5f, 0xb7, 0x5f, 0x5f, 0xb2, 0x5f, 0xa0
239 };
240
241 static u_int8_t de_unix2nw[] = {
242         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x00 */
243         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
244         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x10 */
245         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
246         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 */
247         0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
248         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30 */
249         0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
250         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40 */
251         0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
252         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50 */
253         0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
254         0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60 */
255         0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
256         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70 */
257         0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
258         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x80 */
259         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
260         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, /* 0x90 */
261         0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
262         0xff, 0xad, 0x9b, 0x9c, 0x5f, 0x9d, 0x5f, 0x15, /* 0xA0 */
263         0x5f, 0x5f, 0xa6, 0xae, 0xaa, 0x5f, 0x5f, 0x5f,
264         0xf8, 0xf1, 0xfd, 0x5f, 0x5f, 0xe6, 0x14, 0xfa, /* 0xB0 */
265         0x5f, 0x5f, 0xa7, 0xaf, 0xac, 0xab, 0x5f, 0xa8,
266         0x5f, 0x5f, 0x5f, 0x5f, 0x8e, 0x8f, 0x92, 0x80, /* 0xC0 */
267         0x5f, 0x90, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
268         0x5f, 0xa5, 0x5f, 0x5f, 0x5f, 0x5f, 0x99, 0x5f, /* 0xD0 */
269         0x5f, 0x5f, 0x5f, 0x5f, 0x9a, 0x5f, 0x5f, 0xe1,
270         0x85, 0xa0, 0x83, 0x5f, 0x84, 0x86, 0x91, 0x87, /* 0xE0 */
271         0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b,
272         0xeb, 0xa4, 0x95, 0xa2, 0x93, 0x5f, 0x94, 0xf6, /* 0xF0 */
273         0xed, 0x97, 0xa3, 0x96, 0x81, 0x5f, 0x5f, 0x98
274 };
275
276
277 static u_int8_t def2lower[256];
278 static u_int8_t def2upper[256];
279
280 /*
281  * List of available charsets
282  */
283 struct ncp_nlsdesc {
284         int     scheme;
285         char    *name;
286         struct ncp_nlstables nls;
287 };
288
289 static struct ncp_nlsdesc ncp_nlslist[] = {
290         {NCP_NLS_AS_IS, NCP_NLS_AS_IS_NAME, 
291             {def2lower, def2upper, NULL, NULL, 0}
292         },
293 #ifdef NCP_NLS_KOI2CP866
294         {NCP_NLS_KOI_866, NCP_NLS_KOI_866_NAME, 
295             {def2lower, def2upper, alt2koi8, koi82alt, 0}
296         },
297 #endif
298         {NCP_NLS_SE, NCP_NLS_SE_NAME, 
299             {def2lower, def2upper, se_nw2unix, se_unix2nw, 0}
300         },
301         {NCP_NLS_DE, NCP_NLS_DE_NAME,
302             {def2lower, def2upper, de_nw2unix, de_unix2nw, 0}
303         },
304         {0}
305 };
306
307 struct ncp_nlstables ncp_nls;
308
309 int
310 ncp_nls_setlocale(char *name) {
311         int i;
312
313         ncp_nls.to_lower = def2lower;
314         ncp_nls.to_upper = def2upper;
315         if (setlocale(LC_CTYPE, name) == NULL) {
316                 fprintf(stderr, "Can't set locale '%s'\n", name);
317                 return EINVAL;
318         }
319         for (i = 0; i < 256; i++) {
320                 ncp_nls.to_lower[i] = tolower(i);
321                 ncp_nls.to_upper[i] = toupper(i);
322         }
323         return 0;
324 }
325
326 int
327 ncp_nls_setrecode(int scheme) {
328         struct ncp_nlsdesc *nd;
329
330         if (scheme == 0) {
331 #if NCP_NLS_DEFAULT
332                 scheme = NCP_NLS_DEFAULT;
333 #else
334                 scheme = NCP_NLS_AS_IS;
335 #endif
336         }
337         for (nd = ncp_nlslist; nd->name; nd++) {
338                 if (nd->scheme != scheme) continue;
339                 ncp_nls.u2n = nd->nls.u2n;
340                 ncp_nls.n2u = nd->nls.n2u;
341                 return ncp_nls_setlocale("");
342         }
343         fprintf(stderr, "Character conversion scheme %d was not compiled in\n", scheme);
344         return EINVAL;
345 }
346
347 int
348 ncp_nls_setrecodebyname(char *name) {
349         struct ncp_nlsdesc *nd;
350
351         for (nd = ncp_nlslist; nd->name; nd++) {
352                 if (strcmp(nd->name, name) != 0) continue;
353                 ncp_nls.u2n = nd->nls.u2n;
354                 ncp_nls.n2u = nd->nls.n2u;
355                 return 0;
356         }
357         fprintf(stderr, "Character conversion scheme %s was not compiled in\n", name);
358         return EINVAL;
359 }
360
361 char *
362 ncp_nls_str_n2u(char *dst, const char *src) {
363         char *p;
364
365         if (ncp_nls.n2u == NULL) {
366                 return strcpy(dst, src);
367         }
368         p = dst;
369         while (*src)
370                 *p++ = ncp_nls.n2u[(u_char)*(src++)];
371         *p = 0;
372         return dst;
373 }
374
375 char *
376 ncp_nls_str_u2n(char *dst, const char *src) {
377         char *p;
378
379         if (ncp_nls.u2n == NULL) {
380                 return strcpy(dst, src);
381         }
382         p = dst;
383         while (*src)
384                 *p++ = ncp_nls.u2n[(u_char)*(src++)];
385         *p = 0;
386         return dst;
387 }
388
389 char *
390 ncp_nls_mem_n2u(char *dst, const char *src, int size) {
391         char *p;
392
393         if (size == 0) return NULL;
394         if (ncp_nls.n2u == NULL) {
395                 return memcpy(dst, src, size);
396         }
397         for(p = dst; size; size--, p++)
398                 *p = ncp_nls.n2u[(u_char)*(src++)];
399         return dst;
400 }
401
402 char *
403 ncp_nls_mem_u2n(char *dst, const char *src, int size) {
404         char *p;
405
406         if (size == 0) return NULL;
407         if (ncp_nls.u2n == NULL) {
408                 return strcpy(dst, src);
409         }
410         for(p = dst; size; size--, p++)
411                 *p = ncp_nls.u2n[(u_char)*(src++)];
412         return dst;
413 }
414
415 char *
416 ncp_str_upper(char *s) {
417         char *p = s;
418         while (*s) {
419                 *s = toupper(*s);
420                 s++;
421         }
422         return p;
423 }