]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/nls/makecode.c
apply parts of the netbsd build patch by Patrick Welche <prlw1@newn.cam.ac.uk>, mostl...
[netatalk.git] / etc / afpd / nls / makecode.c
1 /*
2  * $Id: makecode.c,v 1.8 2003-06-06 20:18:39 srittau Exp $
3  *
4  * quick-and-dirty way of creating code pages
5  */
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif /* HAVE_CONFIG_H */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <errno.h>
15
16 #include <netatalk/endian.h>
17 #include "codepage.h"
18
19 /* passthrough map */
20 static const unsigned char identity_map[] = {
21     0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
22     0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
23     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
24     0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
25     0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
26     0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
27     0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
28     0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
29     0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
30     0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
31     0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
32     0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
33     0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
34     0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
35     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
36     0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
37 };
38
39 /* map of cp10000 (mac roman) to iso-latin-1 */
40 static const unsigned char mac_to_isolatin1_map[] = {
41     0xC4, 0xC5, 0xC7, 0xC9, 0xD1, 0xD6, 0xDC, 0xE1,
42     0xE0, 0xE2, 0xE4, 0xE3, 0xE5, 0xE7, 0xE9, 0xE8,
43     0xEA, 0xEB, 0xED, 0xEC, 0xEE, 0xEF, 0xF1, 0xF3,
44     0xF2, 0xF4, 0xF6, 0xF5, 0xFA, 0xF9, 0xFB, 0xFC,
45     0x00, 0xB0, 0xA2, 0xA3, 0xA7, 0xB7, 0xB6, 0xDF,
46     0xAE, 0xA9, 0x00, 0xB4, 0xA8, 0x00, 0xC6, 0xD8,
47     0x00, 0xB1, 0x00, 0x00, 0xA5, 0xB5, 0xF0, 0x00,
48     0x00, 0x00, 0x00, 0xAA, 0xBA, 0x00, 0xE6, 0xF8,
49     0xBF, 0xA1, 0xAC, 0x00, 0x00, 0x00, 0x00, 0xAB,
50     0xBB, 0x00, 0xA0, 0xC0, 0xC3, 0xD5, 0x00, 0x00,
51     0xAD, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF7, 0x00,
52     0xFF, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x00, 0x00,
53     0x00, 0x00, 0xB8, 0x00, 0x00, 0xC2, 0xCA, 0xC1,
54     0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0xD3, 0xD4,
55     0x00, 0xD2, 0xDA, 0xDB, 0xD9
56     /*, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57       0x00, 0x00, 0x00, 0x00, 0x00 */
58 };
59
60 /* map of cp10000 (mac roman) to iso-latin-1 adapted */
61 static const unsigned char mac_to_isolatin1_adapted_map[] = {
62     0xC4, 0xC5, 0xC7, 0xC9, 0xD1, 0xD6, 0xDC, 0xE1,
63     0xE0, 0xE2, 0xE4, 0xE3, 0xE5, 0xE7, 0xE9, 0xE8,
64     0xEA, 0xEB, 0xED, 0xEC, 0xEE, 0xEF, 0xF1, 0xF3,
65     0xF2, 0xF4, 0xF6, 0xF5, 0xFA, 0xF9, 0xFB, 0xFC,
66     0x00, 0xB0, 0xA2, 0xA3, 0xA7, 0xB7, 0xB6, 0xDF,
67     0xAE, 0xA9, 0xFE, 0xB4, 0xA8, 0x00, 0xC6, 0xD8,
68     0x00, 0xB1, 0x00, 0x00, 0xA5, 0xB5, 0xF0, 0x00,
69     0x00, 0x00, 0x00, 0xAA, 0xBA, 0x00, 0xE6, 0xF8,
70     0xBF, 0xA1, 0xAC, 0x00, 0xFD, 0x00, 0x00, 0xAB,
71     0xBB, 0x00, 0xA0, 0xC0, 0xC3, 0xD5, 0x00, 0x00,
72     0xAD, 0xAF, 0xB2, 0xB3, 0xDD, 0xDE, 0xF7, 0xB0,
73     0xFF, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x00, 0x00,
74     0x00, 0x00, 0xB8, 0x00, 0x00, 0xC2, 0xCA, 0xC1,
75     0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0xD3, 0xD4,
76     0x00, 0xD2, 0xDA, 0xDB, 0xD9
77     /*, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78       0x00, 0x00, 0x00, 0x00, 0x00 */
79 };
80
81 /* Map of CP10000 (Mac Roman) to MSDOS CP 437 */
82 static const unsigned char mac_to_cp437_map[] = {
83     0x8e, 0x8f, 0x80, 0x90, 0xa5, 0x99, 0x9a, 0xa0,
84     0x85, 0x83, 0x84, 0xe0, 0x86, 0x87, 0x82, 0x8a,
85     0x88, 0x89, 0xa1, 0x8d, 0x8c, 0x8b, 0xa4, 0xa2,
86     0x95, 0x93, 0x94, 0xe5, 0xa3, 0x97, 0x96, 0x81,
87     0xc5, 0xf8, 0x9b, 0x9c, 0xb6, 0xf9, 0xb8, 0xe1,
88     0xc9, 0xe9, 0xcb, 0xd9, 0xc0, 0xd8, 0x92, 0xe8,
89     0xec, 0xf1, 0xf3, 0xf2, 0x9d, 0xe6, 0xeb, 0xe4,
90     0xef, 0xe3, 0xf4, 0xa6, 0xa7, 0xea, 0x91, 0xed,
91     0xa8, 0xad, 0xaa, 0xfb, 0x9f, 0xf7, 0xdd, 0xae,
92     0xaf, 0xb0, 0xff, 0xd6, 0xd2, 0xb1, 0xb2, 0xb7,
93     0xb4, 0xc4, 0xb5, 0xb9, 0xba, 0xbb, 0xf6, 0xbc,
94     0x98, 0xbd, 0xf5, 0xfe, 0xbe, 0xbf, 0xc1, 0xc2,
95     0xce, 0xfa, 0xc3, 0xc6, 0xc7, 0xc8, 0xee, 0xca,
96     0xcc, 0xcd, 0xb3, 0xd7, 0xcf, 0xd0, 0xd1, 0xd3,
97     0xdb, 0xda, 0xa9, 0xab, 0xac, 0xd4, 0xd5, 0xdc,
98     0xde, 0xdf, 0xfc, 0xfd, 0xe7, 0xe2, 0xf0, 0x9e
99 };
100
101 /* Map of CP10000 (Mac Roman) to MSDOS CP 850 */
102 static const unsigned char mac_to_cp850_map[] = {
103     0x8e, 0x8f, 0x80, 0x90, 0xa5, 0x99, 0x9a, 0xa0,
104     0x85, 0x83, 0x84, 0xc6, 0x86, 0x87, 0x82, 0x8a,
105     0x88, 0x89, 0xa1, 0x8d, 0x8c, 0x8b, 0xa4, 0xa2,
106     0x95, 0x93, 0x94, 0xe4, 0xa3, 0x97, 0x96, 0x81,
107     0xc5, 0xf8, 0xbd, 0x9c, 0xf5, 0xb0, 0xf4, 0xe1,
108     0xa9, 0xb8, 0xb1, 0xef, 0xf9, 0xca, 0x92, 0x9d,
109     0xb2, 0xf1, 0xb3, 0xb4, 0xbe, 0xe6, 0xd0, 0xba,
110     0xbb, 0xcb, 0xdd, 0xa6, 0xa7, 0xbc, 0x91, 0x9b,
111     0xa8, 0xad, 0xaa, 0xd9, 0x9f, 0xf2, 0xfe, 0xae,
112     0xaf, 0xdc, 0xff, 0xb7, 0xc7, 0xe5, 0xc0, 0xc1,
113     0xc2, 0xc4, 0xc3, 0x9e, 0xab, 0xac, 0xf6, 0xbf,
114     0x98, 0xed, 0xc8, 0xcf, 0xc9, 0xcc, 0xcd, 0xce,
115     0xd1, 0xfa, 0xd5, 0xda, 0xdb, 0xb6, 0xd2, 0xb5,
116     0xd3, 0xd4, 0xd6, 0xd7, 0xd8, 0xde, 0xe0, 0xe2,
117     0xf0, 0xe3, 0xe9, 0xea, 0xeb, 0xfb, 0xdf, 0xe7,
118     0xee, 0xe8, 0xec, 0xf3, 0xf7, 0xfc, 0xfd, 0xb9
119 };
120
121
122
123 /* Map of CP10000 (Mac Roman) to koi8-r */
124 static const unsigned char mac_to_koi8_r_map[] = {
125     225, 226, 247, 231, 228, 229, 246, 250,
126     233, 234, 235, 236, 237, 238, 239, 240,
127     242, 243, 244, 245, 230, 232, 227, 254,
128     251, 253, 255, 249, 248, 252, 224, 241,
129     160, 161, 162, 163, 164, 165, 166, 167,
130     168, 191, 170, 171, 172, 173, 174, 175,
131     176, 177, 178, 179, 180, 181, 182, 183,
132     184, 185, 186, 187, 188, 189, 190, 191,
133     192, 193, 194, 195, 196, 197, 198, 199,
134     200, 201, 202, 203, 204, 205, 206, 207,
135     208, 209, 210, 211, 212, 213, 214, 215,
136     216, 217, 218, 219, 220, 179, 163, 209,
137     193, 194, 215, 199, 196, 197, 214, 218,
138     201, 202, 203, 204, 205, 206, 207, 208,
139     210, 211, 212, 213, 198, 200, 195, 222,
140     219, 221, 223, 217, 216, 220, 192, 255
141 };
142
143 struct mac_code {
144     char *m_name;
145     const unsigned char *m_map;
146     u_int16_t m_len;
147     const char *m_id;
148 };
149
150 static struct mac_code names[] = {
151     {"maccode.identity", identity_map, sizeof(identity_map), "identity"},
152     {"maccode.437", mac_to_cp437_map, sizeof(mac_to_cp437_map), "cp437"},
153     {"maccode.850", mac_to_cp850_map, sizeof(mac_to_cp850_map), "cp850"},
154     {"maccode.iso8859-1", mac_to_isolatin1_map, sizeof(mac_to_isolatin1_map), "iso8859-1"},
155     {"maccode.iso8859-1.adapted", mac_to_isolatin1_adapted_map, sizeof(mac_to_isolatin1_adapted_map), "iso8859-1-adapted"},
156     {"maccode.koi8-r",mac_to_koi8_r_map,sizeof(mac_to_koi8_r_map),"koi8-r"},
157     {NULL, NULL, 0, NULL}
158 };
159
160 int main(int argc, char **argv)
161 {
162     unsigned char buf[CODEPAGE_FILE_HEADER_SIZE];
163     u_int16_t id;
164     int i, j;
165     FILE *fp;
166
167     if (argc != 2) {
168         fprintf(stderr, "Usage: %s MACCODE\n", argv[0]);
169         return 1;
170     }
171
172     for (i = 0; names[i].m_name; i++) {
173         if (!strcmp(names[i].m_name, argv[1]))
174             break;
175     }
176
177     if (!names[i].m_name) {
178         fprintf(stderr, "unknown codepage\n");
179         return 1;
180     }
181
182
183     if ((fp = fopen(names[i].m_name, "w")) == NULL) {
184         fprintf(stderr, "can't open %s: %s\n",
185                 names[i].m_name, strerror(errno));
186         return 1;
187     }
188
189     memset(buf, 0, CODEPAGE_FILE_HEADER_SIZE);
190
191     id = htons(CODEPAGE_FILE_ID); /* file id */
192     memcpy(buf, &id, sizeof(id));
193     *(buf + 2) = CODEPAGE_FILE_VERSION; /* version */
194     if ((j = strlen(names[i].m_id)) & 1) /* pad to even boundary */
195         j++;
196     *(buf + 3) = j; /* length of name */
197
198     *(buf + 4) = 1; /* default quantum. this should be modified to
199                      * deal with multibyte characters */
200
201     /* rules */
202     *(buf + 5) = CODEPAGE_RULE_MTOU | CODEPAGE_RULE_UTOM;
203
204     /* offset to data */
205     id = htons(CODEPAGE_FILE_HEADER_SIZE + j);
206     memcpy(buf + 6, &id, sizeof(id));
207
208     /* size of data */
209     id = htons(names[i].m_len);
210     memcpy(buf + 8, &id, sizeof(id));
211
212     /* write it out */
213     fwrite(buf, CODEPAGE_FILE_HEADER_SIZE, 1, fp);
214
215     /* we either keep or drop the null byte to keep the name on an
216      * even boundary */
217     fwrite(names[i].m_id, j, 1, fp);
218
219     /* we typically only map characters > 0x7F */
220     for (j = 0; j < names[i].m_len; j++) {
221         buf[0] = CODEPAGE_RULE_MTOU | CODEPAGE_RULE_UTOM;
222         buf[1] = j + 0x80;
223         buf[2] = names[i].m_map[j];
224         fwrite(buf, 3, 1, fp);
225     }
226     fclose(fp);
227
228     return 0;
229 }