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 0x2500, 0x2502, 0x250c, 0x2510,
0059 0x2514, 0x2518, 0x251c, 0x2524,
0060 0x252c, 0x2534, 0x253c, 0x2580,
0061 0x2584, 0x2588, 0x258c, 0x2590,
0062
0063 0x2591, 0x2592, 0x2593, 0x2320,
0064 0x25a0, 0x2219, 0x221a, 0x2248,
0065 0x2264, 0x2265, 0x00a0, 0x2321,
0066 0x00b0, 0x00b2, 0x00b7, 0x00f7,
0067
0068 0x2550, 0x2551, 0x2552, 0x0451,
0069 0x2553, 0x2554, 0x2555, 0x2556,
0070 0x2557, 0x2558, 0x2559, 0x255a,
0071 0x255b, 0x255c, 0x255d, 0x255e,
0072
0073 0x255f, 0x2560, 0x2561, 0x0401,
0074 0x2562, 0x2563, 0x2564, 0x2565,
0075 0x2566, 0x2567, 0x2568, 0x2569,
0076 0x256a, 0x256b, 0x256c, 0x00a9,
0077
0078 0x044e, 0x0430, 0x0431, 0x0446,
0079 0x0434, 0x0435, 0x0444, 0x0433,
0080 0x0445, 0x0438, 0x0439, 0x043a,
0081 0x043b, 0x043c, 0x043d, 0x043e,
0082
0083 0x043f, 0x044f, 0x0440, 0x0441,
0084 0x0442, 0x0443, 0x0436, 0x0432,
0085 0x044c, 0x044b, 0x0437, 0x0448,
0086 0x044d, 0x0449, 0x0447, 0x044a,
0087
0088 0x042e, 0x0410, 0x0411, 0x0426,
0089 0x0414, 0x0415, 0x0424, 0x0413,
0090 0x0425, 0x0418, 0x0419, 0x041a,
0091 0x041b, 0x041c, 0x041d, 0x041e,
0092
0093 0x041f, 0x042f, 0x0420, 0x0421,
0094 0x0422, 0x0423, 0x0416, 0x0412,
0095 0x042c, 0x042b, 0x0417, 0x0428,
0096 0x042d, 0x0429, 0x0427, 0x042a,
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0121 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0122 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0123 0x9c, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x9e,
0124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x9f,
0132 };
0133
0134 static const unsigned char page04[256] = {
0135 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0137 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
0138 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
0139 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
0140 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
0141 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
0142 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
0143 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
0144 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
0145 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0146 };
0147
0148 static const unsigned char page22[256] = {
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, 0x95, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
0153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0158 0x97, 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, 0x98, 0x99, 0x00, 0x00,
0162 };
0163
0164 static const unsigned char page23[256] = {
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 0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0170 };
0171
0172 static const unsigned char page25[256] = {
0173 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,
0174 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00,
0175 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00,
0176 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00,
0177 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00,
0178 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
0179 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00,
0180 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00,
0181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0183 0xa0, 0xa1, 0xa2, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
0184 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0,
0185 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
0186 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, 0x00, 0x00,
0187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0189
0190 0x8b, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,
0191 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
0192 0x8f, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00,
0193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0194 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0195 };
0196
0197 static const unsigned char *const page_uni2charset[256] = {
0198 page00, NULL, NULL, NULL, page04, NULL, NULL, NULL,
0199 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0200 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0201 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0202 NULL, NULL, page22, page23, NULL, page25, NULL, NULL,
0203 };
0204
0205 static const unsigned char charset2lower[256] = {
0206 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0207 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0208 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0209 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0210 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0211 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0212 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0213 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0214 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0215 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0216 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0217 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0218 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0219 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0220 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0221 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0222
0223 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0224 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0225 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0226 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0227 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0228 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0229 0xb0, 0xb1, 0xb2, 0xa3, 0xb4, 0xb5, 0xb6, 0xb7,
0230 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0231 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0232 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0233 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0234 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0235 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0236 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0237 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0238 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0239 };
0240
0241 static const unsigned char charset2upper[256] = {
0242 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0243 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0244 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0245 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0246 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0247 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0248 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0249 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0250 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0251 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0252 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0253 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0254 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0255 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0256 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0257 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0258
0259 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0260 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0261 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0262 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0263 0xa0, 0xa1, 0xa2, 0xb3, 0xa4, 0xa5, 0xa6, 0xa7,
0264 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0265 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0266 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0267 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0268 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0269 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0270 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0271 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0272 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0273 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0274 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0275 };
0276
0277 static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
0278 {
0279 const unsigned char *uni2charset;
0280 unsigned char cl = uni & 0x00ff;
0281 unsigned char ch = (uni & 0xff00) >> 8;
0282
0283 if (boundlen <= 0)
0284 return -ENAMETOOLONG;
0285
0286 uni2charset = page_uni2charset[ch];
0287 if (uni2charset && uni2charset[cl])
0288 out[0] = uni2charset[cl];
0289 else
0290 return -EINVAL;
0291 return 1;
0292 }
0293
0294 static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
0295 {
0296 *uni = charset2uni[*rawstring];
0297 if (*uni == 0x0000)
0298 return -EINVAL;
0299 return 1;
0300 }
0301
0302 static struct nls_table table = {
0303 .charset = "koi8-r",
0304 .uni2char = uni2char,
0305 .char2uni = char2uni,
0306 .charset2lower = charset2lower,
0307 .charset2upper = charset2upper,
0308 };
0309
0310 static int __init init_nls_koi8_r(void)
0311 {
0312 return register_nls(&table);
0313 }
0314
0315 static void __exit exit_nls_koi8_r(void)
0316 {
0317 unregister_nls(&table);
0318 }
0319
0320 module_init(init_nls_koi8_r)
0321 module_exit(exit_nls_koi8_r)
0322
0323 MODULE_LICENSE("Dual BSD/GPL");