0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/kernel.h>
0012 #include <linux/string.h>
0013 #include <linux/nls.h>
0014 #include <linux/errno.h>
0015
0016 static const wchar_t charset2uni[256] = {
0017
0018 0x0000, 0x0001, 0x0002, 0x0003,
0019 0x0004, 0x0005, 0x0006, 0x0007,
0020 0x0008, 0x0009, 0x000a, 0x000b,
0021 0x000c, 0x000d, 0x000e, 0x000f,
0022
0023 0x0010, 0x0011, 0x0012, 0x0013,
0024 0x0014, 0x0015, 0x0016, 0x0017,
0025 0x0018, 0x0019, 0x001a, 0x001b,
0026 0x001c, 0x001d, 0x001e, 0x001f,
0027
0028 0x0020, 0x0021, 0x0022, 0x0023,
0029 0x0024, 0x0025, 0x0026, 0x0027,
0030 0x0028, 0x0029, 0x002a, 0x002b,
0031 0x002c, 0x002d, 0x002e, 0x002f,
0032
0033 0x0030, 0x0031, 0x0032, 0x0033,
0034 0x0034, 0x0035, 0x0036, 0x0037,
0035 0x0038, 0x0039, 0x003a, 0x003b,
0036 0x003c, 0x003d, 0x003e, 0x003f,
0037
0038 0x0040, 0x0041, 0x0042, 0x0043,
0039 0x0044, 0x0045, 0x0046, 0x0047,
0040 0x0048, 0x0049, 0x004a, 0x004b,
0041 0x004c, 0x004d, 0x004e, 0x004f,
0042
0043 0x0050, 0x0051, 0x0052, 0x0053,
0044 0x0054, 0x0055, 0x0056, 0x0057,
0045 0x0058, 0x0059, 0x005a, 0x005b,
0046 0x005c, 0x005d, 0x005e, 0x005f,
0047
0048 0x0060, 0x0061, 0x0062, 0x0063,
0049 0x0064, 0x0065, 0x0066, 0x0067,
0050 0x0068, 0x0069, 0x006a, 0x006b,
0051 0x006c, 0x006d, 0x006e, 0x006f,
0052
0053 0x0070, 0x0071, 0x0072, 0x0073,
0054 0x0074, 0x0075, 0x0076, 0x0077,
0055 0x0078, 0x0079, 0x007a, 0x007b,
0056 0x007c, 0x007d, 0x007e, 0x007f,
0057
0058 0x0080, 0x0081, 0x0082, 0x0083,
0059 0x0084, 0x0085, 0x0086, 0x0087,
0060 0x0088, 0x0089, 0x008a, 0x008b,
0061 0x008c, 0x008d, 0x008e, 0x008f,
0062
0063 0x0090, 0x0091, 0x0092, 0x0093,
0064 0x0094, 0x0095, 0x0096, 0x0097,
0065 0x0098, 0x0099, 0x009a, 0x009b,
0066 0x009c, 0x009d, 0x009e, 0x009f,
0067
0068 0x00a0, 0x02bd, 0x02bc, 0x00a3,
0069 0x0000, 0x0000, 0x00a6, 0x00a7,
0070 0x00a8, 0x00a9, 0x0000, 0x00ab,
0071 0x00ac, 0x00ad, 0x0000, 0x2015,
0072
0073 0x00b0, 0x00b1, 0x00b2, 0x00b3,
0074 0x0384, 0x0385, 0x0386, 0x00b7,
0075 0x0388, 0x0389, 0x038a, 0x00bb,
0076 0x038c, 0x00bd, 0x038e, 0x038f,
0077
0078 0x0390, 0x0391, 0x0392, 0x0393,
0079 0x0394, 0x0395, 0x0396, 0x0397,
0080 0x0398, 0x0399, 0x039a, 0x039b,
0081 0x039c, 0x039d, 0x039e, 0x039f,
0082
0083 0x03a0, 0x03a1, 0x0000, 0x03a3,
0084 0x03a4, 0x03a5, 0x03a6, 0x03a7,
0085 0x03a8, 0x03a9, 0x03aa, 0x03ab,
0086 0x03ac, 0x03ad, 0x03ae, 0x03af,
0087
0088 0x03b0, 0x03b1, 0x03b2, 0x03b3,
0089 0x03b4, 0x03b5, 0x03b6, 0x03b7,
0090 0x03b8, 0x03b9, 0x03ba, 0x03bb,
0091 0x03bc, 0x03bd, 0x03be, 0x03bf,
0092
0093 0x03c0, 0x03c1, 0x03c2, 0x03c3,
0094 0x03c4, 0x03c5, 0x03c6, 0x03c7,
0095 0x03c8, 0x03c9, 0x03ca, 0x03cb,
0096 0x03cc, 0x03cd, 0x03ce, 0x0000,
0097 };
0098
0099 static const unsigned char page00[256] = {
0100 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0101 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0102 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0103 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0104 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0105 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0106 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0107 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0108 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0109 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0110 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0111 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0112 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0113 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0114 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0115 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0116
0117 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0118 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0119 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0120 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0121 0xa0, 0x00, 0x00, 0xa3, 0x00, 0x00, 0xa6, 0xa7,
0122 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0x00, 0x00,
0123 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0x00, 0x00, 0xb7,
0124 0x00, 0x00, 0x00, 0xbb, 0x00, 0xbd, 0x00, 0x00,
0125 };
0126
0127 static const unsigned char page02[256] = {
0128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0144
0145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0152 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa1, 0x00, 0x00,
0153 };
0154
0155 static const unsigned char page03[256] = {
0156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0172
0173 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb5, 0xb6, 0x00,
0174 0xb8, 0xb9, 0xba, 0x00, 0xbc, 0x00, 0xbe, 0xbf,
0175 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0176 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0177 0xd0, 0xd1, 0x00, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0178 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0179 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0180 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0181 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0182 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00,
0183 };
0184
0185 static const unsigned char page20[256] = {
0186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0188 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00,
0189 };
0190
0191 static const unsigned char *const page_uni2charset[256] = {
0192 page00, NULL, page02, page03, NULL, NULL, NULL, NULL,
0193 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0194 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0195 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0196 page20, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0197 };
0198
0199 static const unsigned char charset2lower[256] = {
0200 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0201 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0202 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0203 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0204 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0205 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0206 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0207 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0208 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0209 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0210 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0211 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0212 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0213 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0214 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0215 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0216
0217 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0218 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0219 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0220 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0221 0xa0, 0xa1, 0xa2, 0xa3, 0x00, 0x00, 0xa6, 0xa7,
0222 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0x00, 0xaf,
0223 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xdc, 0xb7,
0224 0xdd, 0xde, 0xdf, 0xbb, 0xfc, 0xbd, 0xfd, 0xfe,
0225 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0226 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0227 0xf0, 0xf1, 0x00, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0228 0xf8, 0xf9, 0xfa, 0xfb, 0xdc, 0xdd, 0xde, 0xdf,
0229 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0230 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0231 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0232 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00,
0233 };
0234
0235 static const unsigned char charset2upper[256] = {
0236 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0237 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0238 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0239 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0240 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0241 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0242 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0243 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0244 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0245 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0246 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0247 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0248 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0249 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0250 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0251 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0252
0253 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0254 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0255 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0256 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0257 0xa0, 0xa1, 0xa2, 0xa3, 0x00, 0x00, 0xa6, 0xa7,
0258 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0x00, 0xaf,
0259 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0260 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0261 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0262 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0263 0xd0, 0xd1, 0x00, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0264 0xd8, 0xd9, 0xda, 0xdb, 0xb6, 0xb8, 0xb9, 0xba,
0265 0xe0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0266 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0267 0xd0, 0xd1, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0268 0xd8, 0xd9, 0xda, 0xdb, 0xbc, 0xbe, 0xbf, 0x00,
0269 };
0270
0271 static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
0272 {
0273 const unsigned char *uni2charset;
0274 unsigned char cl = uni & 0x00ff;
0275 unsigned char ch = (uni & 0xff00) >> 8;
0276
0277 if (boundlen <= 0)
0278 return -ENAMETOOLONG;
0279
0280 uni2charset = page_uni2charset[ch];
0281 if (uni2charset && uni2charset[cl])
0282 out[0] = uni2charset[cl];
0283 else
0284 return -EINVAL;
0285 return 1;
0286 }
0287
0288 static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
0289 {
0290 *uni = charset2uni[*rawstring];
0291 if (*uni == 0x0000)
0292 return -EINVAL;
0293 return 1;
0294 }
0295
0296 static struct nls_table table = {
0297 .charset = "iso8859-7",
0298 .uni2char = uni2char,
0299 .char2uni = char2uni,
0300 .charset2lower = charset2lower,
0301 .charset2upper = charset2upper,
0302 };
0303
0304 static int __init init_nls_iso8859_7(void)
0305 {
0306 return register_nls(&table);
0307 }
0308
0309 static void __exit exit_nls_iso8859_7(void)
0310 {
0311 unregister_nls(&table);
0312 }
0313
0314 module_init(init_nls_iso8859_7)
0315 module_exit(exit_nls_iso8859_7)
0316
0317 MODULE_LICENSE("Dual BSD/GPL");