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, 0x0104, 0x0138, 0x0156,
69 0x00a4, 0x0128, 0x013b, 0x00a7,
70 0x00a8, 0x0160, 0x0112, 0x0122,
71 0x0166, 0x00ad, 0x017d, 0x00af,
72
73 0x00b0, 0x0105, 0x02db, 0x0157,
74 0x00b4, 0x0129, 0x013c, 0x02c7,
75 0x00b8, 0x0161, 0x0113, 0x0123,
76 0x0167, 0x014a, 0x017e, 0x014b,
77
78 0x0100, 0x00c1, 0x00c2, 0x00c3,
79 0x00c4, 0x00c5, 0x00c6, 0x012e,
80 0x010c, 0x00c9, 0x0118, 0x00cb,
81 0x0116, 0x00cd, 0x00ce, 0x012a,
82
83 0x0110, 0x0145, 0x014c, 0x0136,
84 0x00d4, 0x00d5, 0x00d6, 0x00d7,
85 0x00d8, 0x0172, 0x00da, 0x00db,
86 0x00dc, 0x0168, 0x016a, 0x00df,
87
88 0x0101, 0x00e1, 0x00e2, 0x00e3,
89 0x00e4, 0x00e5, 0x00e6, 0x012f,
90 0x010d, 0x00e9, 0x0119, 0x00eb,
91 0x0117, 0x00ed, 0x00ee, 0x012b,
92
93 0x0111, 0x0146, 0x014d, 0x0137,
94 0x00f4, 0x00f5, 0x00f6, 0x00f7,
95 0x00f8, 0x0173, 0x00fa, 0x00fb,
96 0x00fc, 0x0169, 0x016b, 0x02d9,
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, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0xa7,
122 0xa8, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0xaf,
123 0xb0, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00,
124 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0x00,
126 0x00, 0xc9, 0x00, 0xcb, 0x00, 0xcd, 0xce, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0xd4, 0xd5, 0xd6, 0xd7,
128 0xd8, 0x00, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf,
129 0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0x00,
130 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0xee, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0xf4, 0xf5, 0xf6, 0xf7,
132 0xf8, 0x00, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0x00,
133};
134
135static const unsigned char page01[256] = {
136 0xc0, 0xe0, 0x00, 0x00, 0xa1, 0xb1, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00,
138 0xd0, 0xf0, 0xaa, 0xba, 0x00, 0x00, 0xcc, 0xec,
139 0xca, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0xab, 0xbb, 0x00, 0x00, 0x00, 0x00,
141 0xa5, 0xb5, 0xcf, 0xef, 0x00, 0x00, 0xc7, 0xe7,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf3,
143 0xa2, 0x00, 0x00, 0xa6, 0xb6, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf1, 0x00,
145 0x00, 0x00, 0xbd, 0xbf, 0xd2, 0xf2, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0xb3,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0xa9, 0xb9, 0x00, 0x00, 0x00, 0x00, 0xac, 0xbc,
149 0xdd, 0xfd, 0xde, 0xfe, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0xd9, 0xf9, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0xbe, 0x00,
152};
153
154static const unsigned char page02[256] = {
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00,
184};
185
186static const unsigned char *const page_uni2charset[256] = {
187 page00, page01, page02, NULL, NULL, NULL, NULL, NULL,
188};
189
190static const unsigned char charset2lower[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, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
200 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
201 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
202 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
203 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
204 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
205 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
206 0x78, 0x79, 0x7a, 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, 0xb1, 0xa2, 0xb3, 0xa4, 0xb5, 0xb6, 0xa7,
213 0xa8, 0xb9, 0xba, 0xbb, 0xbc, 0xad, 0xbe, 0xaf,
214 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
215 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbf, 0xbe, 0xbf,
216 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
217 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
218 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7,
219 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf,
220 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
221 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
222 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
223 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
224};
225
226static const unsigned char charset2upper[256] = {
227 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
228 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
229 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
230 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
231 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
232 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
233 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
234 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
235 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
236 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
237 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
238 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
239 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
240 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
241 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
242 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
243
244 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
245 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
246 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
247 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
248 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
249 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
250 0xb0, 0xa1, 0xb2, 0xa3, 0xb4, 0xa5, 0xa6, 0xb7,
251 0xb8, 0xa9, 0xaa, 0xab, 0xac, 0xbd, 0xae, 0xbd,
252 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
253 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
254 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
255 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
256 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
257 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
258 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xf7,
259 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xff,
260};
261
262static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
263{
264 const unsigned char *uni2charset;
265 unsigned char cl = uni & 0x00ff;
266 unsigned char ch = (uni & 0xff00) >> 8;
267
268 if (boundlen <= 0)
269 return -ENAMETOOLONG;
270
271 uni2charset = page_uni2charset[ch];
272 if (uni2charset && uni2charset[cl])
273 out[0] = uni2charset[cl];
274 else
275 return -EINVAL;
276 return 1;
277}
278
279static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
280{
281 *uni = charset2uni[*rawstring];
282 if (*uni == 0x0000)
283 return -EINVAL;
284 return 1;
285}
286
287static struct nls_table table = {
288 .charset = "iso8859-4",
289 .uni2char = uni2char,
290 .char2uni = char2uni,
291 .charset2lower = charset2lower,
292 .charset2upper = charset2upper,
293};
294
295static int __init init_nls_iso8859_4(void)
296{
297 return register_nls(&table);
298}
299
300static void __exit exit_nls_iso8859_4(void)
301{
302 unregister_nls(&table);
303}
304
305module_init(init_nls_iso8859_4)
306module_exit(exit_nls_iso8859_4)
307
308MODULE_LICENSE("Dual BSD/GPL");
309