1 /*
2  * mimeenc.c - translate our internal character set codes to and
3  * from MIME standard character-set names.
4  *
5  */
6 
7 #include <ctype.h>
8 #include "charset.h"
9 #include "internal.h"
10 
11 static const struct {
12     const char *name;
13     int charset;
14 } mimeencs[] = {
15     /*
16      * These names are taken from
17      *
18      *   http://www.iana.org/assignments/character-sets
19      *
20      * Where multiple encoding names map to the same encoding id
21      * (such as the variety of aliases for ISO-8859-1), the first
22      * is considered canonical and will be returned when
23      * translating the id to a string.
24      */
25     { "ISO-8859-1", CS_ISO8859_1 },
26     { "iso-ir-100", CS_ISO8859_1 },
27     { "ISO_8859-1", CS_ISO8859_1 },
28     { "ISO_8859-1:1987", CS_ISO8859_1 },
29     { "latin1", CS_ISO8859_1 },
30     { "l1", CS_ISO8859_1 },
31     { "IBM819", CS_ISO8859_1 },
32     { "CP819", CS_ISO8859_1 },
33     { "csISOLatin1", CS_ISO8859_1 },
34 
35     { "ISO-8859-2", CS_ISO8859_2 },
36     { "ISO_8859-2:1987", CS_ISO8859_2 },
37     { "iso-ir-101", CS_ISO8859_2 },
38     { "ISO_8859-2", CS_ISO8859_2 },
39     { "latin2", CS_ISO8859_2 },
40     { "l2", CS_ISO8859_2 },
41     { "csISOLatin2", CS_ISO8859_2 },
42 
43     { "ISO-8859-3", CS_ISO8859_3 },
44     { "ISO_8859-3:1988", CS_ISO8859_3 },
45     { "iso-ir-109", CS_ISO8859_3 },
46     { "ISO_8859-3", CS_ISO8859_3 },
47     { "latin3", CS_ISO8859_3 },
48     { "l3", CS_ISO8859_3 },
49     { "csISOLatin3", CS_ISO8859_3 },
50 
51     { "ISO-8859-4", CS_ISO8859_4 },
52     { "ISO_8859-4:1988", CS_ISO8859_4 },
53     { "iso-ir-110", CS_ISO8859_4 },
54     { "ISO_8859-4", CS_ISO8859_4 },
55     { "latin4", CS_ISO8859_4 },
56     { "l4", CS_ISO8859_4 },
57     { "csISOLatin4", CS_ISO8859_4 },
58 
59     { "ISO-8859-5", CS_ISO8859_5 },
60     { "ISO_8859-5:1988", CS_ISO8859_5 },
61     { "iso-ir-144", CS_ISO8859_5 },
62     { "ISO_8859-5", CS_ISO8859_5 },
63     { "cyrillic", CS_ISO8859_5 },
64     { "csISOLatinCyrillic", CS_ISO8859_5 },
65 
66     { "ISO-8859-6", CS_ISO8859_6 },
67     { "ISO_8859-6:1987", CS_ISO8859_6 },
68     { "iso-ir-127", CS_ISO8859_6 },
69     { "ISO_8859-6", CS_ISO8859_6 },
70     { "ECMA-114", CS_ISO8859_6 },
71     { "ASMO-708", CS_ISO8859_6 },
72     { "arabic", CS_ISO8859_6 },
73     { "csISOLatinArabic", CS_ISO8859_6 },
74 
75     { "ISO-8859-7", CS_ISO8859_7 },
76     { "ISO_8859-7:1987", CS_ISO8859_7 },
77     { "iso-ir-126", CS_ISO8859_7 },
78     { "ISO_8859-7", CS_ISO8859_7 },
79     { "ELOT_928", CS_ISO8859_7 },
80     { "ECMA-118", CS_ISO8859_7 },
81     { "greek", CS_ISO8859_7 },
82     { "greek8", CS_ISO8859_7 },
83     { "csISOLatinGreek", CS_ISO8859_7 },
84 
85     { "ISO-8859-8", CS_ISO8859_8 },
86     { "ISO_8859-8:1988", CS_ISO8859_8 },
87     { "iso-ir-138", CS_ISO8859_8 },
88     { "ISO_8859-8", CS_ISO8859_8 },
89     { "hebrew", CS_ISO8859_8 },
90     { "csISOLatinHebrew", CS_ISO8859_8 },
91 
92     { "ISO-8859-9", CS_ISO8859_9 },
93     { "ISO_8859-9:1989", CS_ISO8859_9 },
94     { "iso-ir-148", CS_ISO8859_9 },
95     { "ISO_8859-9", CS_ISO8859_9 },
96     { "latin5", CS_ISO8859_9 },
97     { "l5", CS_ISO8859_9 },
98     { "csISOLatin5", CS_ISO8859_9 },
99 
100     { "ISO-8859-10", CS_ISO8859_10 },
101     { "iso-ir-157", CS_ISO8859_10 },
102     { "l6", CS_ISO8859_10 },
103     { "ISO_8859-10:1992", CS_ISO8859_10 },
104     { "csISOLatin6", CS_ISO8859_10 },
105     { "latin6", CS_ISO8859_10 },
106 
107     { "ISO-8859-13", CS_ISO8859_13 },
108 
109     { "ISO-8859-14", CS_ISO8859_14 },
110     { "iso-ir-199", CS_ISO8859_14 },
111     { "ISO_8859-14:1998", CS_ISO8859_14 },
112     { "ISO_8859-14", CS_ISO8859_14 },
113     { "latin8", CS_ISO8859_14 },
114     { "iso-celtic", CS_ISO8859_14 },
115     { "l8", CS_ISO8859_14 },
116 
117     { "ISO-8859-15", CS_ISO8859_15 },
118     { "ISO_8859-15", CS_ISO8859_15 },
119     { "Latin-9", CS_ISO8859_15 },
120 
121     { "ISO-8859-16", CS_ISO8859_16 },
122     { "iso-ir-226", CS_ISO8859_16 },
123     { "ISO_8859-16", CS_ISO8859_16 },
124     { "ISO_8859-16:2001", CS_ISO8859_16 },
125     { "latin10", CS_ISO8859_16 },
126     { "l10", CS_ISO8859_16 },
127 
128     { "IBM437", CS_CP437 },
129     { "cp437", CS_CP437 },
130     { "437", CS_CP437 },
131     { "csPC8CodePage437", CS_CP437 },
132 
133     { "IBM850", CS_CP850 },
134     { "cp850", CS_CP850 },
135     { "850", CS_CP850 },
136     { "csPC850Multilingual", CS_CP850 },
137 
138     { "IBM852", CS_CP852 },
139     { "cp852", CS_CP852 },
140     { "852", CS_CP852 },
141     { "csIBM852", CS_CP852 },
142 
143     { "IBM866", CS_CP866 },
144     { "cp866", CS_CP866 },
145     { "866", CS_CP866 },
146     { "csIBM866", CS_CP866 },
147 
148     { "windows-1250", CS_CP1250 },
149 
150     { "windows-1251", CS_CP1251 },
151 
152     { "windows-1252", CS_CP1252 },
153 
154     { "windows-1253", CS_CP1253 },
155 
156     { "windows-1254", CS_CP1254 },
157 
158     { "windows-1255", CS_CP1255 },
159 
160     { "windows-1256", CS_CP1256 },
161 
162     { "windows-1257", CS_CP1257 },
163 
164     { "windows-1258", CS_CP1258 },
165 
166     { "KOI8-R", CS_KOI8_R },
167     { "csKOI8R", CS_KOI8_R },
168 
169     { "KOI8-U", CS_KOI8_U },
170 
171     { "macintosh", CS_MAC_ROMAN_OLD },
172     { "mac", CS_MAC_ROMAN_OLD },
173     { "csMacintosh", CS_MAC_ROMAN_OLD },
174 
175     { "VISCII", CS_VISCII },
176     { "csVISCII", CS_VISCII },
177 
178     { "hp-roman8", CS_HP_ROMAN8 },
179     { "roman8", CS_HP_ROMAN8 },
180     { "r8", CS_HP_ROMAN8 },
181     { "csHPRoman8", CS_HP_ROMAN8 },
182 
183     { "DEC-MCS", CS_DEC_MCS },
184     { "dec", CS_DEC_MCS },
185     { "csDECMCS", CS_DEC_MCS },
186 
187     { "UTF-8", CS_UTF8 },
188 };
189 
charset_to_mimeenc(int charset)190 const char *charset_to_mimeenc(int charset)
191 {
192     int i;
193 
194     for (i = 0; i < (int)lenof(mimeencs); i++)
195         if (charset == mimeencs[i].charset)
196             return mimeencs[i].name;
197 
198     return NULL;                       /* not found */
199 }
200 
charset_from_mimeenc(const char * name)201 int charset_from_mimeenc(const char *name)
202 {
203     int i;
204 
205     for (i = 0; i < (int)lenof(mimeencs); i++) {
206         const char *p, *q;
207         p = name;
208         q = mimeencs[i].name;
209         while (*p || *q) {
210                 if (tolower((unsigned char)*p) != tolower((unsigned char)*q))
211                 break;
212             p++; q++;
213         }
214         if (!*p && !*q)
215             return mimeencs[i].charset;
216     }
217 
218     return CS_NONE;                    /* not found */
219 }
220