1
2
3
4
5
6
7
8
9
10
11#include <linux/module.h>
12#include <linux/string.h>
13#include <linux/nls.h>
14#include <linux/kernel.h>
15#include <linux/errno.h>
16#include <linux/kmod.h>
17#include <linux/spinlock.h>
18#include <asm/byteorder.h>
19
20static struct nls_table default_table;
21static struct nls_table *tables = &default_table;
22static DEFINE_SPINLOCK(nls_lock);
23
24
25
26
27
28struct utf8_table {
29 int cmask;
30 int cval;
31 int shift;
32 long lmask;
33 long lval;
34};
35
36static const struct utf8_table utf8_table[] =
37{
38 {0x80, 0x00, 0*6, 0x7F, 0, },
39 {0xE0, 0xC0, 1*6, 0x7FF, 0x80, },
40 {0xF0, 0xE0, 2*6, 0xFFFF, 0x800, },
41 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, },
42 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, },
43 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, },
44 {0, }
45};
46
47#define UNICODE_MAX 0x0010ffff
48#define PLANE_SIZE 0x00010000
49
50#define SURROGATE_MASK 0xfffff800
51#define SURROGATE_PAIR 0x0000d800
52#define SURROGATE_LOW 0x00000400
53#define SURROGATE_BITS 0x000003ff
54
55int utf8_to_utf32(const u8 *s, int inlen, unicode_t *pu)
56{
57 unsigned long l;
58 int c0, c, nc;
59 const struct utf8_table *t;
60
61 nc = 0;
62 c0 = *s;
63 l = c0;
64 for (t = utf8_table; t->cmask; t++) {
65 nc++;
66 if ((c0 & t->cmask) == t->cval) {
67 l &= t->lmask;
68 if (l < t->lval || l > UNICODE_MAX ||
69 (l & SURROGATE_MASK) == SURROGATE_PAIR)
70 return -1;
71 *pu = (unicode_t) l;
72 return nc;
73 }
74 if (inlen <= nc)
75 return -1;
76 s++;
77 c = (*s ^ 0x80) & 0xFF;
78 if (c & 0xC0)
79 return -1;
80 l = (l << 6) | c;
81 }
82 return -1;
83}
84EXPORT_SYMBOL(utf8_to_utf32);
85
86int utf32_to_utf8(unicode_t u, u8 *s, int maxout)
87{
88 unsigned long l;
89 int c, nc;
90 const struct utf8_table *t;
91
92 if (!s)
93 return 0;
94
95 l = u;
96 if (l > UNICODE_MAX || (l & SURROGATE_MASK) == SURROGATE_PAIR)
97 return -1;
98
99 nc = 0;
100 for (t = utf8_table; t->cmask && maxout; t++, maxout--) {
101 nc++;
102 if (l <= t->lmask) {
103 c = t->shift;
104 *s = (u8) (t->cval | (l >> c));
105 while (c > 0) {
106 c -= 6;
107 s++;
108 *s = (u8) (0x80 | ((l >> c) & 0x3F));
109 }
110 return nc;
111 }
112 }
113 return -1;
114}
115EXPORT_SYMBOL(utf32_to_utf8);
116
117static inline void put_utf16(wchar_t *s, unsigned c, enum utf16_endian endian)
118{
119 switch (endian) {
120 default:
121 *s = (wchar_t) c;
122 break;
123 case UTF16_LITTLE_ENDIAN:
124 *s = __cpu_to_le16(c);
125 break;
126 case UTF16_BIG_ENDIAN:
127 *s = __cpu_to_be16(c);
128 break;
129 }
130}
131
132int utf8s_to_utf16s(const u8 *s, int inlen, enum utf16_endian endian,
133 wchar_t *pwcs, int maxout)
134{
135 u16 *op;
136 int size;
137 unicode_t u;
138
139 op = pwcs;
140 while (inlen > 0 && maxout > 0 && *s) {
141 if (*s & 0x80) {
142 size = utf8_to_utf32(s, inlen, &u);
143 if (size < 0)
144 return -EINVAL;
145 s += size;
146 inlen -= size;
147
148 if (u >= PLANE_SIZE) {
149 if (maxout < 2)
150 break;
151 u -= PLANE_SIZE;
152 put_utf16(op++, SURROGATE_PAIR |
153 ((u >> 10) & SURROGATE_BITS),
154 endian);
155 put_utf16(op++, SURROGATE_PAIR |
156 SURROGATE_LOW |
157 (u & SURROGATE_BITS),
158 endian);
159 maxout -= 2;
160 } else {
161 put_utf16(op++, u, endian);
162 maxout--;
163 }
164 } else {
165 put_utf16(op++, *s++, endian);
166 inlen--;
167 maxout--;
168 }
169 }
170 return op - pwcs;
171}
172EXPORT_SYMBOL(utf8s_to_utf16s);
173
174static inline unsigned long get_utf16(unsigned c, enum utf16_endian endian)
175{
176 switch (endian) {
177 default:
178 return c;
179 case UTF16_LITTLE_ENDIAN:
180 return __le16_to_cpu(c);
181 case UTF16_BIG_ENDIAN:
182 return __be16_to_cpu(c);
183 }
184}
185
186int utf16s_to_utf8s(const wchar_t *pwcs, int inlen, enum utf16_endian endian,
187 u8 *s, int maxout)
188{
189 u8 *op;
190 int size;
191 unsigned long u, v;
192
193 op = s;
194 while (inlen > 0 && maxout > 0) {
195 u = get_utf16(*pwcs, endian);
196 if (!u)
197 break;
198 pwcs++;
199 inlen--;
200 if (u > 0x7f) {
201 if ((u & SURROGATE_MASK) == SURROGATE_PAIR) {
202 if (u & SURROGATE_LOW) {
203
204 continue;
205 }
206 if (inlen <= 0)
207 break;
208 v = get_utf16(*pwcs, endian);
209 if ((v & SURROGATE_MASK) != SURROGATE_PAIR ||
210 !(v & SURROGATE_LOW)) {
211
212 continue;
213 }
214 u = PLANE_SIZE + ((u & SURROGATE_BITS) << 10)
215 + (v & SURROGATE_BITS);
216 pwcs++;
217 inlen--;
218 }
219 size = utf32_to_utf8(u, op, maxout);
220 if (size == -1) {
221
222 } else {
223 op += size;
224 maxout -= size;
225 }
226 } else {
227 *op++ = (u8) u;
228 maxout--;
229 }
230 }
231 return op - s;
232}
233EXPORT_SYMBOL(utf16s_to_utf8s);
234
235int register_nls(struct nls_table * nls)
236{
237 struct nls_table ** tmp = &tables;
238
239 if (nls->next)
240 return -EBUSY;
241
242 spin_lock(&nls_lock);
243 while (*tmp) {
244 if (nls == *tmp) {
245 spin_unlock(&nls_lock);
246 return -EBUSY;
247 }
248 tmp = &(*tmp)->next;
249 }
250 nls->next = tables;
251 tables = nls;
252 spin_unlock(&nls_lock);
253 return 0;
254}
255
256int unregister_nls(struct nls_table * nls)
257{
258 struct nls_table ** tmp = &tables;
259
260 spin_lock(&nls_lock);
261 while (*tmp) {
262 if (nls == *tmp) {
263 *tmp = nls->next;
264 spin_unlock(&nls_lock);
265 return 0;
266 }
267 tmp = &(*tmp)->next;
268 }
269 spin_unlock(&nls_lock);
270 return -EINVAL;
271}
272
273static struct nls_table *find_nls(char *charset)
274{
275 struct nls_table *nls;
276 spin_lock(&nls_lock);
277 for (nls = tables; nls; nls = nls->next) {
278 if (!strcmp(nls->charset, charset))
279 break;
280 if (nls->alias && !strcmp(nls->alias, charset))
281 break;
282 }
283 if (nls && !try_module_get(nls->owner))
284 nls = NULL;
285 spin_unlock(&nls_lock);
286 return nls;
287}
288
289struct nls_table *load_nls(char *charset)
290{
291 return try_then_request_module(find_nls(charset), "nls_%s", charset);
292}
293
294void unload_nls(struct nls_table *nls)
295{
296 if (nls)
297 module_put(nls->owner);
298}
299
300static const wchar_t charset2uni[256] = {
301
302 0x0000, 0x0001, 0x0002, 0x0003,
303 0x0004, 0x0005, 0x0006, 0x0007,
304 0x0008, 0x0009, 0x000a, 0x000b,
305 0x000c, 0x000d, 0x000e, 0x000f,
306
307 0x0010, 0x0011, 0x0012, 0x0013,
308 0x0014, 0x0015, 0x0016, 0x0017,
309 0x0018, 0x0019, 0x001a, 0x001b,
310 0x001c, 0x001d, 0x001e, 0x001f,
311
312 0x0020, 0x0021, 0x0022, 0x0023,
313 0x0024, 0x0025, 0x0026, 0x0027,
314 0x0028, 0x0029, 0x002a, 0x002b,
315 0x002c, 0x002d, 0x002e, 0x002f,
316
317 0x0030, 0x0031, 0x0032, 0x0033,
318 0x0034, 0x0035, 0x0036, 0x0037,
319 0x0038, 0x0039, 0x003a, 0x003b,
320 0x003c, 0x003d, 0x003e, 0x003f,
321
322 0x0040, 0x0041, 0x0042, 0x0043,
323 0x0044, 0x0045, 0x0046, 0x0047,
324 0x0048, 0x0049, 0x004a, 0x004b,
325 0x004c, 0x004d, 0x004e, 0x004f,
326
327 0x0050, 0x0051, 0x0052, 0x0053,
328 0x0054, 0x0055, 0x0056, 0x0057,
329 0x0058, 0x0059, 0x005a, 0x005b,
330 0x005c, 0x005d, 0x005e, 0x005f,
331
332 0x0060, 0x0061, 0x0062, 0x0063,
333 0x0064, 0x0065, 0x0066, 0x0067,
334 0x0068, 0x0069, 0x006a, 0x006b,
335 0x006c, 0x006d, 0x006e, 0x006f,
336
337 0x0070, 0x0071, 0x0072, 0x0073,
338 0x0074, 0x0075, 0x0076, 0x0077,
339 0x0078, 0x0079, 0x007a, 0x007b,
340 0x007c, 0x007d, 0x007e, 0x007f,
341
342 0x0080, 0x0081, 0x0082, 0x0083,
343 0x0084, 0x0085, 0x0086, 0x0087,
344 0x0088, 0x0089, 0x008a, 0x008b,
345 0x008c, 0x008d, 0x008e, 0x008f,
346
347 0x0090, 0x0091, 0x0092, 0x0093,
348 0x0094, 0x0095, 0x0096, 0x0097,
349 0x0098, 0x0099, 0x009a, 0x009b,
350 0x009c, 0x009d, 0x009e, 0x009f,
351
352 0x00a0, 0x00a1, 0x00a2, 0x00a3,
353 0x00a4, 0x00a5, 0x00a6, 0x00a7,
354 0x00a8, 0x00a9, 0x00aa, 0x00ab,
355 0x00ac, 0x00ad, 0x00ae, 0x00af,
356
357 0x00b0, 0x00b1, 0x00b2, 0x00b3,
358 0x00b4, 0x00b5, 0x00b6, 0x00b7,
359 0x00b8, 0x00b9, 0x00ba, 0x00bb,
360 0x00bc, 0x00bd, 0x00be, 0x00bf,
361
362 0x00c0, 0x00c1, 0x00c2, 0x00c3,
363 0x00c4, 0x00c5, 0x00c6, 0x00c7,
364 0x00c8, 0x00c9, 0x00ca, 0x00cb,
365 0x00cc, 0x00cd, 0x00ce, 0x00cf,
366
367 0x00d0, 0x00d1, 0x00d2, 0x00d3,
368 0x00d4, 0x00d5, 0x00d6, 0x00d7,
369 0x00d8, 0x00d9, 0x00da, 0x00db,
370 0x00dc, 0x00dd, 0x00de, 0x00df,
371
372 0x00e0, 0x00e1, 0x00e2, 0x00e3,
373 0x00e4, 0x00e5, 0x00e6, 0x00e7,
374 0x00e8, 0x00e9, 0x00ea, 0x00eb,
375 0x00ec, 0x00ed, 0x00ee, 0x00ef,
376
377 0x00f0, 0x00f1, 0x00f2, 0x00f3,
378 0x00f4, 0x00f5, 0x00f6, 0x00f7,
379 0x00f8, 0x00f9, 0x00fa, 0x00fb,
380 0x00fc, 0x00fd, 0x00fe, 0x00ff,
381};
382
383static const unsigned char page00[256] = {
384 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
385 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
386 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
387 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
388 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
389 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
390 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
391 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
392 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
393 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
394 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
395 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
396 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
397 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
398 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
399 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
400
401 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
402 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
403 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
404 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
405 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
406 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
407 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
408 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
409 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
410 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
411 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
412 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
413 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
414 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
415 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
416 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
417};
418
419static const unsigned char *const page_uni2charset[256] = {
420 page00
421};
422
423static const unsigned char charset2lower[256] = {
424 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
425 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
426 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
427 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
428 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
429 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
430 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
431 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
432 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
433 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
434 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
435 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
436 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
437 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
438 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
439 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
440
441 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
442 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
443 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
444 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
445 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
446 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
447 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
448 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
449 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
450 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
451 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
452 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
453 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
454 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
455 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
456 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
457};
458
459static const unsigned char charset2upper[256] = {
460 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
461 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
462 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
463 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
464 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
465 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
466 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
467 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
468 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
469 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
470 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
471 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
472 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
473 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
474 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
475 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
476
477 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
478 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
479 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
480 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
481 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
482 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
483 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
484 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
485 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
486 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
487 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
488 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
489 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
490 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
491 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
492 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
493};
494
495
496static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
497{
498 const unsigned char *uni2charset;
499 unsigned char cl = uni & 0x00ff;
500 unsigned char ch = (uni & 0xff00) >> 8;
501
502 if (boundlen <= 0)
503 return -ENAMETOOLONG;
504
505 uni2charset = page_uni2charset[ch];
506 if (uni2charset && uni2charset[cl])
507 out[0] = uni2charset[cl];
508 else
509 return -EINVAL;
510 return 1;
511}
512
513static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
514{
515 *uni = charset2uni[*rawstring];
516 if (*uni == 0x0000)
517 return -EINVAL;
518 return 1;
519}
520
521static struct nls_table default_table = {
522 .charset = "default",
523 .uni2char = uni2char,
524 .char2uni = char2uni,
525 .charset2lower = charset2lower,
526 .charset2upper = charset2upper,
527};
528
529
530struct nls_table *load_nls_default(void)
531{
532 struct nls_table *default_nls;
533
534 default_nls = load_nls(CONFIG_NLS_DEFAULT);
535 if (default_nls != NULL)
536 return default_nls;
537 else
538 return &default_table;
539}
540
541EXPORT_SYMBOL(register_nls);
542EXPORT_SYMBOL(unregister_nls);
543EXPORT_SYMBOL(unload_nls);
544EXPORT_SYMBOL(load_nls);
545EXPORT_SYMBOL(load_nls_default);
546
547MODULE_LICENSE("Dual BSD/GPL");
548