0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/kernel.h>
0010 #include <linux/string.h>
0011 #include <linux/nls.h>
0012 #include <linux/errno.h>
0013
0014 static const wchar_t charset2uni[256] = {
0015
0016 0x0000, 0x0001, 0x0002, 0x0003,
0017 0x0004, 0x0005, 0x0006, 0x0007,
0018 0x0008, 0x0009, 0x000a, 0x000b,
0019 0x000c, 0x000d, 0x000e, 0x000f,
0020
0021 0x0010, 0x0011, 0x0012, 0x0013,
0022 0x0014, 0x0015, 0x0016, 0x0017,
0023 0x0018, 0x0019, 0x001a, 0x001b,
0024 0x001c, 0x001d, 0x001e, 0x001f,
0025
0026 0x0020, 0x0021, 0x0022, 0x0023,
0027 0x0024, 0x0025, 0x0026, 0x0027,
0028 0x0028, 0x0029, 0x002a, 0x002b,
0029 0x002c, 0x002d, 0x002e, 0x002f,
0030
0031 0x0030, 0x0031, 0x0032, 0x0033,
0032 0x0034, 0x0035, 0x0036, 0x0037,
0033 0x0038, 0x0039, 0x003a, 0x003b,
0034 0x003c, 0x003d, 0x003e, 0x003f,
0035
0036 0x0040, 0x0041, 0x0042, 0x0043,
0037 0x0044, 0x0045, 0x0046, 0x0047,
0038 0x0048, 0x0049, 0x004a, 0x004b,
0039 0x004c, 0x004d, 0x004e, 0x004f,
0040
0041 0x0050, 0x0051, 0x0052, 0x0053,
0042 0x0054, 0x0055, 0x0056, 0x0057,
0043 0x0058, 0x0059, 0x005a, 0x005b,
0044 0x005c, 0x005d, 0x005e, 0x005f,
0045
0046 0x0060, 0x0061, 0x0062, 0x0063,
0047 0x0064, 0x0065, 0x0066, 0x0067,
0048 0x0068, 0x0069, 0x006a, 0x006b,
0049 0x006c, 0x006d, 0x006e, 0x006f,
0050
0051 0x0070, 0x0071, 0x0072, 0x0073,
0052 0x0074, 0x0075, 0x0076, 0x0077,
0053 0x0078, 0x0079, 0x007a, 0x007b,
0054 0x007c, 0x007d, 0x007e, 0x007f,
0055
0056 0x2500, 0x2502, 0x250c, 0x2510,
0057 0x2514, 0x2518, 0x251c, 0x2524,
0058 0x252c, 0x2534, 0x253c, 0x2580,
0059 0x2584, 0x2588, 0x258c, 0x2590,
0060
0061 0x2591, 0x2592, 0x2593, 0x2320,
0062 0x25a0, 0x2219, 0x221a, 0x2248,
0063 0x2264, 0x2265, 0x00a0, 0x2321,
0064 0x00b0, 0x00b2, 0x00b7, 0x00f7,
0065
0066 0x2550, 0x2551, 0x2552, 0x0451,
0067 0x0454, 0x2554, 0x0456, 0x0457,
0068 0x2557, 0x2558, 0x2559, 0x255a,
0069 0x255b, 0x0491, 0x255d, 0x255e,
0070
0071 0x255f, 0x2560, 0x2561, 0x0401,
0072 0x0404, 0x2563, 0x0406, 0x0407,
0073 0x2566, 0x2567, 0x2568, 0x2569,
0074 0x256a, 0x0490, 0x256c, 0x00a9,
0075
0076 0x044e, 0x0430, 0x0431, 0x0446,
0077 0x0434, 0x0435, 0x0444, 0x0433,
0078 0x0445, 0x0438, 0x0439, 0x043a,
0079 0x043b, 0x043c, 0x043d, 0x043e,
0080
0081 0x043f, 0x044f, 0x0440, 0x0441,
0082 0x0442, 0x0443, 0x0436, 0x0432,
0083 0x044c, 0x044b, 0x0437, 0x0448,
0084 0x044d, 0x0449, 0x0447, 0x044a,
0085
0086 0x042e, 0x0410, 0x0411, 0x0426,
0087 0x0414, 0x0415, 0x0424, 0x0413,
0088 0x0425, 0x0418, 0x0419, 0x041a,
0089 0x041b, 0x041c, 0x041d, 0x041e,
0090
0091 0x041f, 0x042f, 0x0420, 0x0421,
0092 0x0422, 0x0423, 0x0416, 0x0412,
0093 0x042c, 0x042b, 0x0417, 0x0428,
0094 0x042d, 0x0429, 0x0427, 0x042a,
0095 };
0096
0097 static const unsigned char page00[256] = {
0098 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0099 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0100 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0101 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0102 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0103 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0104 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0105 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0106 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0107 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0108 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0109 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0110 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0111 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0112 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0113 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0114
0115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0119 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0120 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0121 0x9c, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x9e,
0122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x9f,
0130 };
0131
0132 static const unsigned char page04[256] = {
0133 0x00, 0xb3, 0x00, 0x00, 0xb4, 0x00, 0xb6, 0xb7,
0134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0135 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa,
0136 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
0137 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe,
0138 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1,
0139 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda,
0140 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
0141 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde,
0142 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1,
0143 0x00, 0xa3, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7,
0144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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
0150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0152 0xbd, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0153 };
0154
0155 static const unsigned char page22[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, 0x95, 0x96, 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 0x97, 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, 0x98, 0x99, 0x00, 0x00,
0169 };
0170
0171 static const unsigned char page23[256] = {
0172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0176 0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0177 };
0178
0179 static const unsigned char page25[256] = {
0180 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,
0181 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00,
0182 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00,
0183 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00,
0184 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00,
0185 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
0186 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00,
0187 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00,
0188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0190 0xa0, 0xa1, 0xa2, 0x00, 0xa5, 0x00, 0x00, 0xa8,
0191 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, 0xb0,
0192 0xb1, 0xb2, 0x00, 0xb5, 0x00, 0x00, 0xb8, 0xb9,
0193 0xba, 0xbb, 0xbc, 0x00, 0xbe, 0x00, 0x00, 0x00,
0194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0196
0197 0x8b, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,
0198 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00,
0199 0x8f, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00,
0200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0201 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0202 };
0203
0204 static const unsigned char *const page_uni2charset[256] = {
0205 page00, NULL, NULL, NULL, page04, NULL, NULL, NULL,
0206 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0207 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0208 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0209 NULL, NULL, page22, page23, NULL, page25, NULL, NULL,
0210 };
0211
0212 static const unsigned char charset2lower[256] = {
0213 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0214 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0215 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0216 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0217 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0218 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0219 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0220 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0221 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0222 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0223 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0224 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0225 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0226 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0227 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0228 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0229
0230 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0231 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0232 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0233 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0234 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0235 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0236 0xb0, 0xb1, 0xb2, 0xa3, 0xa4, 0xb5, 0xa6, 0xa7,
0237 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xad, 0xbe, 0xbf,
0238 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0239 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0240 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0241 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0242 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0243 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0244 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0245 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0246 };
0247
0248 static const unsigned char charset2upper[256] = {
0249 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0250 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0251 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0252 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0253 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0254 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0255 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0256 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0257 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0258 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0259 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0260 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0261 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0262 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0263 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0264 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0265
0266 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0267 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0268 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0269 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0270 0xa0, 0xa1, 0xa2, 0xb3, 0xb4, 0xa5, 0xb6, 0xb7,
0271 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xbd, 0xae, 0xaf,
0272 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0273 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0274 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0275 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0276 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0277 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0278 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0279 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0280 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0281 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0282 };
0283
0284 static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
0285 {
0286 const unsigned char *uni2charset;
0287 unsigned char cl = uni & 0x00ff;
0288 unsigned char ch = (uni & 0xff00) >> 8;
0289
0290 if (boundlen <= 0)
0291 return -ENAMETOOLONG;
0292
0293 uni2charset = page_uni2charset[ch];
0294 if (uni2charset && uni2charset[cl])
0295 out[0] = uni2charset[cl];
0296 else
0297 return -EINVAL;
0298 return 1;
0299 }
0300
0301 static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
0302 {
0303 *uni = charset2uni[*rawstring];
0304 if (*uni == 0x0000)
0305 return -EINVAL;
0306 return 1;
0307 }
0308
0309 static struct nls_table table = {
0310 .charset = "koi8-u",
0311 .uni2char = uni2char,
0312 .char2uni = char2uni,
0313 .charset2lower = charset2lower,
0314 .charset2upper = charset2upper,
0315 };
0316
0317 static int __init init_nls_koi8_u(void)
0318 {
0319 return register_nls(&table);
0320 }
0321
0322 static void __exit exit_nls_koi8_u(void)
0323 {
0324 unregister_nls(&table);
0325 }
0326
0327 module_init(init_nls_koi8_u)
0328 module_exit(exit_nls_koi8_u)
0329
0330 MODULE_LICENSE("Dual BSD/GPL");