1
2
3
4
5
6
7
8
9
10#include <linux/module.h>
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/nls.h>
14#include <linux/errno.h>
15
16static const wchar_t charset2uni[256] = {
17
18 0x0000, 0x0001, 0x0002, 0x0003,
19 0x0004, 0x0005, 0x0006, 0x0007,
20 0x0008, 0x0009, 0x000a, 0x000b,
21 0x000c, 0x000d, 0x000e, 0x000f,
22
23 0x0010, 0x0011, 0x0012, 0x0013,
24 0x0014, 0x0015, 0x0016, 0x0017,
25 0x0018, 0x0019, 0x001a, 0x001b,
26 0x001c, 0x001d, 0x001e, 0x001f,
27
28 0x0020, 0x0021, 0x0022, 0x0023,
29 0x0024, 0x0025, 0x0026, 0x0027,
30 0x0028, 0x0029, 0x002a, 0x002b,
31 0x002c, 0x002d, 0x002e, 0x002f,
32
33 0x0030, 0x0031, 0x0032, 0x0033,
34 0x0034, 0x0035, 0x0036, 0x0037,
35 0x0038, 0x0039, 0x003a, 0x003b,
36 0x003c, 0x003d, 0x003e, 0x003f,
37
38 0x0040, 0x0041, 0x0042, 0x0043,
39 0x0044, 0x0045, 0x0046, 0x0047,
40 0x0048, 0x0049, 0x004a, 0x004b,
41 0x004c, 0x004d, 0x004e, 0x004f,
42
43 0x0050, 0x0051, 0x0052, 0x0053,
44 0x0054, 0x0055, 0x0056, 0x0057,
45 0x0058, 0x0059, 0x005a, 0x005b,
46 0x005c, 0x005d, 0x005e, 0x005f,
47
48 0x0060, 0x0061, 0x0062, 0x0063,
49 0x0064, 0x0065, 0x0066, 0x0067,
50 0x0068, 0x0069, 0x006a, 0x006b,
51 0x006c, 0x006d, 0x006e, 0x006f,
52
53 0x0070, 0x0071, 0x0072, 0x0073,
54 0x0074, 0x0075, 0x0076, 0x0077,
55 0x0078, 0x0079, 0x007a, 0x007b,
56 0x007c, 0x007d, 0x007e, 0x007f,
57
58 0x0080, 0x0081, 0x0082, 0x0083,
59 0x0084, 0x0085, 0x0086, 0x0087,
60 0x0088, 0x0089, 0x008a, 0x008b,
61 0x008c, 0x008d, 0x008e, 0x008f,
62
63 0x0090, 0x0091, 0x0092, 0x0093,
64 0x0094, 0x0095, 0x0096, 0x0097,
65 0x0098, 0x0099, 0x009a, 0x009b,
66 0x009c, 0x009d, 0x009e, 0x009f,
67
68 0x00a0, 0x00a1, 0x00a2, 0x00a3,
69 0x00a4, 0x00a5, 0x00a6, 0x00a7,
70 0x00a8, 0x00a9, 0x00aa, 0x00ab,
71 0x00ac, 0x00ad, 0x00ae, 0x00af,
72
73 0x00b0, 0x00b1, 0x00b2, 0x00b3,
74 0x00b4, 0x00b5, 0x00b6, 0x00b7,
75 0x00b8, 0x00b9, 0x00ba, 0x00bb,
76 0x00bc, 0x00bd, 0x00be, 0x00bf,
77
78 0x00c0, 0x00c1, 0x00c2, 0x00c3,
79 0x00c4, 0x00c5, 0x00c6, 0x00c7,
80 0x00c8, 0x00c9, 0x00ca, 0x00cb,
81 0x00cc, 0x00cd, 0x00ce, 0x00cf,
82
83 0x011e, 0x00d1, 0x00d2, 0x00d3,
84 0x00d4, 0x00d5, 0x00d6, 0x00d7,
85 0x00d8, 0x00d9, 0x00da, 0x00db,
86 0x00dc, 0x0130, 0x015e, 0x00df,
87
88 0x00e0, 0x00e1, 0x00e2, 0x00e3,
89 0x00e4, 0x00e5, 0x00e6, 0x00e7,
90 0x00e8, 0x00e9, 0x00ea, 0x00eb,
91 0x00ec, 0x00ed, 0x00ee, 0x00ef,
92
93 0x011f, 0x00f1, 0x00f2, 0x00f3,
94 0x00f4, 0x00f5, 0x00f6, 0x00f7,
95 0x00f8, 0x00f9, 0x00fa, 0x00fb,
96 0x00fc, 0x0131, 0x015f, 0x00ff,
97};
98
99static const unsigned char page00[256] = {
100 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
101 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
102 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
103 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
104 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
105 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
106 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
107 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
108 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
109 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
110 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
111 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
112 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
113 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
114 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
115 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
116
117 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
118 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
119 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
120 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
121 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
122 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
123 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
124 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
125 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
126 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
127 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
128 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf,
129 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
130 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
131 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
132 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0xff,
133};
134
135static const unsigned char page01[256] = {
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0xdd, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xfe,
148};
149
150static const unsigned char *const page_uni2charset[256] = {
151 page00, page01, NULL, NULL, NULL, NULL, NULL, NULL,
152};
153
154static const unsigned char charset2lower[256] = {
155 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
156 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
157 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
158 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
159 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
160 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
161 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
162 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
163 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
164 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
165 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
166 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
167 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
168 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
169 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
170 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
171
172 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
173 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
174 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
175 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
176 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
177 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
178 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
179 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
180 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
181 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
182 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7,
183 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x69, 0xfe, 0xdf,
184 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
185 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
186 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
187 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
188};
189
190static const unsigned char charset2upper[256] = {
191 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
192 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
193 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
194 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
195 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
196 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
197 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
198 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
199 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
200 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
201 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
202 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
203 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
204 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
205 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
206 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
207
208 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
209 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
210 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
211 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
212 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
213 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
214 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0x00, 0xb6, 0xb7,
215 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
216 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
217 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
218 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
219 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
220 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
221 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
222 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xf7,
223 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0x49, 0xde, 0x00,
224};
225
226static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
227{
228 const unsigned char *uni2charset;
229 unsigned char cl = uni & 0x00ff;
230 unsigned char ch = (uni & 0xff00) >> 8;
231
232 if (boundlen <= 0)
233 return -ENAMETOOLONG;
234
235 uni2charset = page_uni2charset[ch];
236 if (uni2charset && uni2charset[cl])
237 out[0] = uni2charset[cl];
238 else
239 return -EINVAL;
240 return 1;
241}
242
243static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
244{
245 *uni = charset2uni[*rawstring];
246 if (*uni == 0x0000)
247 return -EINVAL;
248 return 1;
249}
250
251static struct nls_table table = {
252 .charset = "iso8859-9",
253 .uni2char = uni2char,
254 .char2uni = char2uni,
255 .charset2lower = charset2lower,
256 .charset2upper = charset2upper,
257 .owner = THIS_MODULE,
258};
259
260static int __init init_nls_iso8859_9(void)
261{
262 return register_nls(&table);
263}
264
265static void __exit exit_nls_iso8859_9(void)
266{
267 unregister_nls(&table);
268}
269
270module_init(init_nls_iso8859_9)
271module_exit(exit_nls_iso8859_9)
272
273MODULE_LICENSE("Dual BSD/GPL");
274