繁体中文: mount -t vfat /dev/hda1 /mnt/1 -o codepage=950,iocharset=cp936
有趣的是,由于GBK包含了全部的GB2312/Big5/JIS的内码,所以使用936的Codepage也可以显示Big5的文件名.
制作codepage950支持的是台湾的 先生, 主页为
制作GBK的cp936支持的是TurboLinux的中文研发小组的 和
#!/bin/sh
cat $1 | awk '{if(index($1,"#")==0)print $0}' | awk 'BEGIN{FS="0x"}{print $2 $3}' |
awk '{if(length($1)==length($2))print $1,$2}'
1 #!/usr/bin/perl
2
3 @code = (
4 "00", "01", "02", "03", "04", "05", "06", "07",
5 "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
6 "10", "11", "12", "13", "14", "15", "16", "17",
7 "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
8 "20", "21", "22", "23", "24", "25", "26", "27",
9 "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
10 "30", "31", "32", "33", "34", "35", "36", "37",
11 "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
12 "40", "41", "42", "43", "44", "45", "46", "47",
13 "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
14 "50", "51", "52", "53", "54", "55", "56", "57",
15 "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
16 "60", "61", "62", "63", "64", "65", "66", "67",
17 "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
18 "70", "71", "72", "73", "74", "75", "76", "77",
19 "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
20 "80", "81", "82", "83", "84", "85", "86", "87",
21 "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
22 "90", "91", "92", "93", "94", "95", "96", "97",
23 "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
24 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
25 "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
26 "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7",
27 "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
28 "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7",
29 "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
30 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
31 "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
32 "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7",
33 "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
34 "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
35 "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF");
36
37 while (<STDIN>){
38 ($unicode, $big5) = split;
39 ($high, $low) = $unicode =~ /(..)(..)/;
40 $table2{$high}{$low} = $big5;
41 ($high, $low) = $big5 =~ /(..)(..)/;
42 $table{$high}{$low} = $unicode;
43 }
44
45 print <<EOF;
46 /*
47 * linux/fs/nls_cp874.c
48 *
49 * Charset cp874 translation tables.
50 * Generated automatically from the Unicode and charset
51 * tables from the Unicode Organization (www.unicode.org).
52 * The Unicode to charset table has only exact mappings.
53 */
54
55 #include
56 #include
57 #include
58 #include
59
60 /* A1 - F9*/
61 static struct nls_unicode charset2uni[(0xF9-0xA1+1)*(0x100-0x60)] = {
62 EOF
63
64 for ($high=0xA1; $high <= 0xF9; $high++){
65 for ($low=0x40; $low <= 0x7F; $low++){
66 $unicode = $table2{$code[$high]}{$code[$low]};
67 $unicode = "0000" if (!(defined $unicode));
68 print "\n\t" if ($low%4 == 0);
69 print "/* $code[$high]$code[$low]*/\n\t" if ($low%0x10 == 0);
70 ($uhigh, $ulow) = $unicode =~ /(..)(..)/;
71 printf("{0x%2s, 0x%2s}, ", $ulow, $uhigh);
72 }
73 for ($low=0xA0; $low <= 0xFF; $low++){
74 $unicode = $table2{$code[$high]}{$code[$low]};
75 $unicode = "0000" if (!(defined $unicode));
76 print "\n\t" if ($low%4 == 0);
77 print "/* $code[$high]$code[$low]*/\n\t" if ($low%0x10 == 0);
78 ($uhigh, $ulow) = $unicode =~ /(..)(..)/;
79 printf("{0x%2s, 0x%2s}, ", $ulow, $uhigh);
80 }
81 }
82
83 print "\n};\n\n";
84 for ($high=1; $high <= 255;$high++){
85 if (defined $table{$code[$high]}){
86 print "static unsigned char page$code[$high]\[512\] = {\n\t";
87 for ($low=0; $low<=255;$low++){
88 $big5 = $table{$code[$high]}{$code[$low]};
89 $big5 = "3F3F" if (!(defined $big5));
90 if ($low > 0 && $low%4 == 0){
91 printf("/* 0x%02X-0x%02X */\n\t", $low-4, $low-1);
92 }
93 print "\n\t" if ($low == 0x80);
94 ($bhigh, $blow) = $big5 =~ /(..)(..)/;
95 printf("0x%2s, 0x%2s, ", $bhigh, $blow);
96 }
97 print "/* 0xFC-0xFF */\n};\n\n";
98 }
99 }
100
101 print "static unsigned char *page_uni2charset[256] = {";
102 for ($high=0; $high<=255;$high++){
103 print "\n\t" if ($high%8 == 0);
104 if ($high>0 && defined $table{$code[$high]}){
105 print "page$code[$high], ";
106 }
107 else{
108 print "NULL, ";
109 }
110 }
111 print <<EOF;
112
113 };
114
115 static unsigned char charset2upper[256] = {
116 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
117 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
118 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
119 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
120 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
121 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
122 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
123 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
124 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
125 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
126 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
127 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
128 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
131 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
132 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */
133 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */
134 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */
135 0x98, 0x99, 0x9a, 0x00, 0x9c, 0x00, 0x00, 0x00, /* 0x98-0x9f */
136 0x00, 0x00, 0x00, 0x00, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
137 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
138 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
139 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */
140 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
141 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */
142 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0x00, 0x00, /* 0xd0-0xd7 */
143 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, /* 0xe8-0xef */
146 0xf0, 0xf1, 0x00, 0x00, 0x00, 0xf5, 0x00, 0xf7, /* 0xf0-0xf7 */
147 0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, /* 0xf8-0xff */
148 };
149
150
151 static void inc_use_count(void)
152 {
153 MOD_INC_USE_COUNT;
154 }
155
156 static void dec_use_count(void)
157 {
158 MOD_DEC_USE_COUNT;
159 }
160
161 static struct nls_table table = {
162 "cp950",
163 page_uni2charset,
164 charset2uni,
165 inc_use_count,
166 dec_use_count,
167 NULL
168 };
169
170 int init_nls_cp950(void)
171 {
172 return register_nls();
173 }
174
175 #ifdef MODULE
176 int init_module(void)
177 {
178 return init_nls_cp950();
179 }
180
181
182 void cleanup_module(void)
183 {
184 unregister_nls();
185 return;
186 }
187 #endif
188
189 /*
190 * Overrides for Emacs so that we follow Linus's tabbing style.
191 * Emacs will notice this stuff at the end of the file and automatically
192 * adjust the settings for this buffer only. This must remain at the end
193 * of the file.
194 *
195 ---------------------------------------------------------------------------
196 * Local variables:
197 * c-indent-level: 8
198 * c-brace-imaginary-offset: 0
199 * c-brace-offset: -8
200 * c-argdecl-indent: 8
201 * c-label-offset: -8
202 * c-continued-statement-offset: 8
203 * c-continued-brace-offset: 0
204 * End:
205 */
206 EOF
207
208 5.4 uni2gbk.pl
209
210 #!/usr/bin/perl
211
212 @code = (
213 "00", "01", "02", "03", "04", "05", "06", "07",
214 "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
215 "10", "11", "12", "13", "14", "15", "16", "17",
216 "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
217 "20", "21", "22", "23", "24", "25", "26", "27",
218 "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
219 "30", "31", "32", "33", "34", "35", "36", "37",
220 "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
221 "40", "41", "42", "43", "44", "45", "46", "47",
222 "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
223 "50", "51", "52", "53", "54", "55", "56", "57",
224 "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
225 "60", "61", "62", "63", "64", "65", "66", "67",
226 "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
227 "70", "71", "72", "73", "74", "75", "76", "77",
228 "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
229 "80", "81", "82", "83", "84", "85", "86", "87",
230 "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
231 "90", "91", "92", "93", "94", "95", "96", "97",
232 "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
233 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
234 "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
235 "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7",
236 "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
237 "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7",
238 "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
239 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
240 "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
241 "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7",
242 "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
243 "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
244 "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF");
245
246 while (){
247 ($unicode, $big5) = split;
248 ($high, $low) = $unicode =~ /(..)(..)/;
249 $table2{$high}{$low} = $big5;
250 ($high, $low) = $big5 =~ /(..)(..)/;
251 $table{$high}{$low} = $unicode;
252 }
253
254 print <255 /*
256 * linux/fs/nls_cp936.c
257 *
258 * Charset cp936 translation tables.
259 * Generated automatically from the Unicode and charset
260 * tables from the Unicode Organization (www.unicode.org).
261 * The Unicode to charset table has only exact mappings.
262 */
263
264 #include
265 #include
266 #include
267 #include
268
269 /* 81 - FE*/
270 static struct nls_unicode charset2uni[(0xFE-0x81+1)*(0x100-0x40)] = {
271 EOF
272
273 for ($high=0x81; $high <= 0xFE; $high++){
274 for ($low=0x40; $low <= 0x7F; $low++){
275 $unicode = $table2{$code[$high]}{$code[$low]};
276 $unicode = "0000" if (!(defined $unicode));
277 print "\n\t" if ($low%4 == 0);
278 print "/* $code[$high]$code[$low]*/\n\t" if ($low%0x10 == 0);
279 ($uhigh, $ulow) = $unicode =~ /(..)(..)/;
280 printf("{0x%2s, 0x%2s}, ", $ulow, $uhigh);
281 }
282 for ($low=0x80; $low <= 0xFF; $low++){
283 $unicode = $table2{$code[$high]}{$code[$low]};
284 $unicode = "0000" if (!(defined $unicode));
285 print "\n\t" if ($low%4 == 0);
286 print "/* $code[$high]$code[$low]*/\n\t" if ($low%0x10 == 0);
287 ($uhigh, $ulow) = $unicode =~ /(..)(..)/;
288 printf("{0x%2s, 0x%2s}, ", $ulow, $uhigh);
289 }
290 }
291
292 print "\n};\n\n";
293 for ($high=1; $high <= 255;$high++){
294 if (defined $table{$code[$high]}){
295 print "static unsigned char page$code[$high]\[512\] = {\n\t";
296 for ($low=0; $low<=255;$low++){
297 $big5 = $table{$code[$high]}{$code[$low]};
298 $big5 = "3F3F" if (!(defined $big5));
299 if ($low > 0 && $low%4 == 0){
300 printf("/* 0x%02X-0x%02X */\n\t", $low-4, $low-1);
301 }
302 print "\n\t" if ($low == 0x80);
303 ($bhigh, $blow) = $big5 =~ /(..)(..)/;
304 printf("0x%2s, 0x%2s, ", $bhigh, $blow);
305 }
306 print "/* 0xFC-0xFF */\n};\n\n";
307 }
308 }
309
310 print "static unsigned char *page_uni2charset[256] = {";
311 for ($high=0; $high<=255;$high++){
312 print "\n\t" if ($high%8 == 0);
313 if ($high>0 && defined $table{$code[$high]}){
314 print "page$code[$high], ";
315 }
316 else{
317 print "NULL, ";
318 }
319 }
320 print <321
322 };
323
324 static unsigned char charset2upper[256] = {
325 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
326 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
327 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
328 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
329 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
330 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
331 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
332 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
333 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
334 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
335 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
336 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
337 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
340 0x00, 0x00, 0x00, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
341 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */
342 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */
343 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */
344 0x98, 0x99, 0x9a, 0x00, 0x9c, 0x00, 0x00, 0x00, /* 0x98-0x9f */
345 0x00, 0x00, 0x00, 0x00, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
346 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
347 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
348 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */
349 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
350 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */
351 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0x00, 0x00, /* 0xd0-0xd7 */
352 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, /* 0xe8-0xef */
355 0xf0, 0xf1, 0x00, 0x00, 0x00, 0xf5, 0x00, 0xf7, /* 0xf0-0xf7 */
356 0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, /* 0xf8-0xff */
357 };
358
359
360 static void inc_use_count(void)
361 {
362 MOD_INC_USE_COUNT;
363 }
364
365 static void dec_use_count(void)
366 {
367 MOD_DEC_USE_COUNT;
368 }
369
370 static struct nls_table table = {
371 "cp936",
372 page_uni2charset,
373 charset2uni,
374 inc_use_count,
375 dec_use_count,
376 NULL
377 };
378
379 int init_nls_cp936(void)
380 {
381 return register_nls();
382 }
383
384 #ifdef MODULE
385 int init_module(void)
386 {
387 return init_nls_cp936();
388 }
389
390
391 void cleanup_module(void)
392 {
393 unregister_nls();
394 return;
395 }
396 #endif
397
398 /*
399 * Overrides for Emacs so that we follow Linus's tabbing style.
400 * Emacs will notice this stuff at the end of the file and automatically
401 * adjust the settings for this buffer only. This must remain at the end
402 * of the file.
403 *
404 ---------------------------------------------------------------------------
405 * Local variables:
406 * c-indent-level: 8
407 * c-brace-imaginary-offset: 0
408 * c-brace-offset: -8
409 * c-argdecl-indent: 8
410 * c-label-offset: -8
411 * c-continued-statement-offset: 8
412 * c-continued-brace-offset: 0
413 * End:
414 */
415 EOF
416
417 5.5 转换CODEPAGE的工具
418
419 /*
420 * CPI.C: A program to examine MSDOS codepage files (*.cpi)
421 * and extract specific codepages.
422 * Compiles under Linux & DOS (using BC++ 3.1).
423 *
424 * Compile: gcc -o cpi cpi.c
425 * Call: codepage file.cpi [-a|-l|nnn]
426 *
427 * Author: Ahmed M. Naas (ahmed@oea.xs4all.nl)
428 * Many changes: aeb@cwi.nl [changed until it would handle all
429 * *.cpi files people have sent me; I have no documentation,
430 * so all this is experimental]
431 * Remains to do: DRDOS fonts.
432 *
433 * Copyright: Public domain.
434 */
435
436 #include
437 #include
438 #include
439 #include
440
441 int handle_codepage(int);
442 void handle_fontfile(void);
443
444 #define PACKED __attribute__ ((packed))
445 /* Use this (instead of the above) to compile under MSDOS */
446 /*#define PACKED */
447
448 struct {
449 unsigned char id[8] PACKED;
450 unsigned char res[8] PACKED;
451 unsigned short num_pointers PACKED;
452 unsigned char p_type PACKED;
453 unsigned long offset PACKED;
454 } FontFileHeader;
455
456 struct {
457 unsigned short num_codepages PACKED;
458 } FontInfoHeader;
459
460 struct {
461 unsigned short size PACKED;
462 unsigned long off_nexthdr PACKED;
463 unsigned short device_type PACKED; /* screen=1; printer=2 */
464 unsigned char device_name[8] PACKED;
465 unsigned short codepage PACKED;
466 unsigned char res[6] PACKED;
467 unsigned long off_font PACKED;
468 } CPEntryHeader;
469
470 struct {
471 unsigned short reserved PACKED;
472 unsigned short num_fonts PACKED;
473 unsigned short size PACKED;
474 } CPInfoHeader;
475
476 struct {
477 unsigned char height PACKED;
478 unsigned char width PACKED;
479 unsigned short reserved PACKED;
480 unsigned short num_chard PACKED;
481 } ScreenFontHeader;
482
483 struct {
484 unsigned short p1 PACKED;
485 unsigned short p2 PACKED;
486 } PrinterFontHeader;
487
488 FILE *in, *out;
489 void usage(void);
490
491 int opta, optc, optl, optL, optx;
492 extern int optind;
493 extern char *optarg;
494
495 unsigned short codepage;
496
497 int main (int argc, char *argv[])
498 {
499 if (argc < 2)
500 usage();
501
502 if ((in = fopen(argv[1], "r")) == NULL) {
503 printf("\nUnable to open file %s.\n", argv[1]);
504 exit(0);
505 }
506
507 opta = optc = optl = optL = optx = 0;
508 optind = 2;
509 if (argc == 2)
510 optl = 1;
511 else
512 while(1) {
513 switch(getopt(argc, argv, "alLc")) {
514 case 'a':
515 opta = 1;
516 continue;
517 case 'c':
518 optc = 1;
519 continue;
520 case 'L':
521 optL = 1;
522 continue;
523 case 'l':
524 optl = 1;
525 continue;
526 case '?':
527 default:
528 usage();
529 case -1:
530 break;
531 }
532 break;
533 }
534 if (optind != argc) {
535 if (optind != argc-1 || opta)
536 usage();
537 codepage = atoi(argv[optind]);
538 optx = 1;
539 }
540
541 if (optc)
542 handle_codepage(0);
543 else
544 handle_fontfile();
545
546 if (optx) {
547 printf("no page %d found\n", codepage);
548 exit(1);
549 }
550
551 fclose(in);
552 return (0);
553 }
554
555 void
556 handle_fontfile(){
557 int i, j;
558
559 j = fread(, 1, sizeof(FontFileHeader), in);
560 if (j != sizeof(FontFileHeader)) {
561 printf("error reading FontFileHeader - got %d chars\n", j);
562 exit (1);
563 }
564 if (!strcmp(FontFileHeader.id + 1, "DRFONT ")) {
565 printf("this program cannot handle DRDOS font files\n");
566 exit(1);
567 }
568 if (optL)
569 printf("FontFileHeader: id=%8.8s res=%8.8s num=%d typ=%c offset=%ld\n\n",
570 FontFileHeader.id, FontFileHeader.res,
571 FontFileHeader.num_pointers,
572 FontFileHeader.p_type,
573 FontFileHeader.offset);
574
575 j = fread(, 1, sizeof(FontInfoHeader), in);
576 if (j != sizeof(FontInfoHeader)) {
577 printf("error reading FontInfoHeader - got %d chars\n", j);
578 exit (1);
579 }
580 if (optL)
581 printf("FontInfoHeader: num_codepages=%d\n\n",
582 FontInfoHeader.num_codepages);
583
584 for (i = FontInfoHeader.num_codepages; i; i--)
585 if (handle_codepage(i-1))
586 break;
587 }
588
589 int
590 handle_codepage(int more_to_come) {
591 int j;
592 char outfile[20];
593 unsigned char *fonts;
594 long inpos, nexthdr;
595
596 j = fread(, 1, sizeof(CPEntryHeader), in);
597 if (j != sizeof(CPEntryHeader)) {
598 printf("error reading CPEntryHeader - got %d chars\n", j);
599 exit(1);
600 }
601 if (optL) {
602 int t = CPEntryHeader.device_type;
603 printf("CPEntryHeader: size=%d dev=%d [%s] name=%8.8s \
604 codepage=%d\n\t\tres=%6.6s nxt=%ld off_font=%ld\n\n",
605 CPEntryHeader.size,
606 t, (t==1) ? "screen" : (t==2) ? "printer" : "?",
607 CPEntryHeader.device_name,
608 CPEntryHeader.codepage,
609 CPEntryHeader.res,
610 CPEntryHeader.off_nexthdr, CPEntryHeader.off_font);
611 } else if (optl) {
612 printf("\nCodepage = %d\n", CPEntryHeader.codepage);
613 printf("Device = %.8s\n", CPEntryHeader.device_name);
614 }
615 #if 0
616 if (CPEntryHeader.size != sizeof(CPEntryHeader)) {
617 /* seen 26 and 28, so that the difference below is -2 or 0 */
618 if (optl)
619 printf("Skipping %d bytes of garbage\n",
620 CPEntryHeader.size - sizeof(CPEntryHeader));
621 fseek(in, CPEntryHeader.size - sizeof(CPEntryHeader),
622 SEEK_CUR);
623 }
624 #endif
625 if (!opta && (!optx || CPEntryHeader.codepage != codepage) && !optc)
626 goto next;
627
628 inpos = ftell(in);
629 if (inpos != CPEntryHeader.off_font && !optc) {
630 if (optL)
631 printf("pos=%ld font at %ld\n", inpos, CPEntryHeader.off_font);
632 fseek(in, CPEntryHeader.off_font, SEEK_SET);
633 }
634
635 j = fread(, 1, sizeof(CPInfoHeader), in);
636 if (j != sizeof(CPInfoHeader)) {
637 printf("error reading CPInfoHeader - got %d chars\n", j);
638 exit(1);
639 }
640 if (optl) {
641 printf("Number of Fonts = %d\n", CPInfoHeader.num_fonts);
642 printf("Size of Bitmap = %d\n", CPInfoHeader.size);
643 }
644 if (CPInfoHeader.num_fonts == 0)
645 goto next;
646 if (optc)
647 return 0;
648
649 sprintf(outfile, "%d.cp", CPEntryHeader.codepage);
650 if ((out = fopen(outfile, "w")) == NULL) {
651 printf("\nUnable to open file %s.\n", outfile);
652 exit(1);
653 } else printf("\nWriting %s\n", outfile);
654
655 fonts = (unsigned char *) malloc(CPInfoHeader.size);
656
657 fread(fonts, CPInfoHeader.size, 1, in);
658 fwrite(, sizeof(CPEntryHeader), 1, out);
659 fwrite(, sizeof(CPInfoHeader), 1, out);
660 j = fwrite(fonts, 1, CPInfoHeader.size, out);
661 if (j != CPInfoHeader.size) {
662 printf("error writing %s - wrote %d chars\n", outfile, j);
663 exit(1);
664 }
665 fclose(out);
666 free(fonts);
667 if (optx) exit(0);
668 next:
669 /*
670 * It seems that if entry headers and fonts are interspersed,
671 * then nexthdr will point past the font, regardless of
672 * whether more entries follow.
673 * Otherwise, first all entry headers are given, and then
674 * all fonts; in this case nexthdr will be 0 in the last entry.
675 */
676 nexthdr = CPEntryHeader.off_nexthdr;
677 if (nexthdr == 0 || nexthdr == -1) {
678 if (more_to_come) {
679 printf("mode codepages expected, but nexthdr=%ld\n",
680 nexthdr);
681 exit(1);
682 } else
683 return 1;
684 }
685
686 inpos = ftell(in);
687 if (inpos != CPEntryHeader.off_nexthdr) {
688 if (optL)
689 printf("pos=%ld nexthdr at %ld\n", inpos, nexthdr);
690 if (opta && !more_to_come) {
691 printf("no more code pages, but nexthdr != 0\n");
692 return 1;
693 }
694
695 fseek(in, CPEntryHeader.off_nexthdr, SEEK_SET);
696 }
697
698 return 0;
699 }
700
701 void usage(void)
702 {
703 printf("\nUsage: cpi code_page_file [-c] [-L] [-l] [-a|nnn]\n");
704 printf(" -c: input file is a single codepage\n");
705 printf(" -L: print header info (you don't want to see this)\n");
706 printf(" -l or no option: list all codepages contained in the file\n");
707 printf(" -a: extract all codepages from the file\n");
708 printf(" nnn (3 digits): extract codepage nnn from the file\n");
709 printf("Example: cpi ega.cpi 850 \n");
710 printf(" will create a file 850.cp containing the requested codepage.\n\n");
711 exit(1);
712 }