1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is Mozilla Communicator client code, released
15  * March 31, 1998.
16  *
17  * The Initial Developer of the Original Code is
18  * Netscape Communications Corporation.
19  * Portions created by the Initial Developer are Copyright (C) 1998-1999
20  * the Initial Developer. All Rights Reserved.
21  *
22  * Contributor(s):
23  *
24  * Alternatively, the contents of this file may be used under the terms of
25  * either of the GNU General Public License Version 2 or later (the "GPL"),
26  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27  * in which case the provisions of the GPL or the LGPL are applicable instead
28  * of those above. If you wish to allow use of your version of this file only
29  * under the terms of either the GPL or the LGPL, and not to allow others to
30  * use your version of this file under the terms of the MPL, indicate your
31  * decision by deleting the provisions above and replace them with the notice
32  * and other provisions required by the GPL or the LGPL. If you do not delete
33  * the provisions above, a recipient may use your version of this file under
34  * the terms of any one of the MPL, the GPL or the LGPL.
35  *
36  * ***** END LICENSE BLOCK ***** */
37 /*
38  *  Copyright (c) 1995 Regents of the University of Michigan.
39  *  All rights reserved.
40  */
41 /*
42  *  charset.c
43  */
44 
45 #include "ldap-int.h"
46 
47 #ifdef STR_TRANSLATION
48 
ldap_set_string_translators(LDAP * ld,BERTranslateProc encode_proc,BERTranslateProc decode_proc)49 void ldap_set_string_translators(LDAP* ld, BERTranslateProc encode_proc,
50                                  BERTranslateProc decode_proc) {
51   if (ld == NULL) {
52     if (!nsldapi_initialized) {
53       nsldapi_initialize_defaults();
54     }
55     ld = &nsldapi_ld_defaults;
56   }
57 
58   if (NSLDAPI_VALID_LDAP_POINTER(ld)) {
59     ld->ld_lber_encode_translate_proc = encode_proc;
60     ld->ld_lber_decode_translate_proc = decode_proc;
61   }
62 }
63 
ldap_enable_translation(LDAP * ld,LDAPMessage * entry,int enable)64 void ldap_enable_translation(LDAP* ld, LDAPMessage* entry, int enable) {
65   char* optionsp;
66 
67   if (ld == NULL) {
68     if (!nsldapi_initialized) {
69       nsldapi_initialize_defaults();
70     }
71     ld = &nsldapi_ld_defaults;
72   }
73 
74   optionsp =
75       (entry == NULLMSG) ? &ld->ld_lberoptions : &entry->lm_ber->ber_options;
76 
77   if (enable) {
78     *optionsp |= LBER_OPT_TRANSLATE_STRINGS;
79   } else {
80     *optionsp &= ~LBER_OPT_TRANSLATE_STRINGS;
81   }
82 }
83 
ldap_translate_from_t61(LDAP * ld,char ** bufp,unsigned long * lenp,int free_input)84 int ldap_translate_from_t61(LDAP* ld, char** bufp, unsigned long* lenp,
85                             int free_input) {
86   if (ld->ld_lber_decode_translate_proc == NULL) {
87     return (LDAP_SUCCESS);
88   }
89 
90   return ((*ld->ld_lber_decode_translate_proc)(bufp, lenp, free_input));
91 }
92 
ldap_translate_to_t61(LDAP * ld,char ** bufp,unsigned long * lenp,int free_input)93 int ldap_translate_to_t61(LDAP* ld, char** bufp, unsigned long* lenp,
94                           int free_input) {
95   if (ld->ld_lber_encode_translate_proc == NULL) {
96     return (LDAP_SUCCESS);
97   }
98 
99   return ((*ld->ld_lber_encode_translate_proc)(bufp, lenp, free_input));
100 }
101 
102 /*
103  ** Character translation routine notes:
104  *
105  * On entry:  bufp points to a "string" to be converted (not necessarily
106  *  zero-terminated) and buflenp points to the length of the buffer.
107  *
108  * On exit:  bufp should point to a malloc'd result.  If free_input is
109  *  non-zero then the original bufp will be freed.  *buflenp should be
110  *  set to the new length.  Zero bytes in the input buffer must be left
111  *  as zero bytes.
112  *
113  * Return values: any ldap error code (LDAP_SUCCESS if all goes well).
114  */
115 
116 #  ifdef LDAP_CHARSET_8859
117 
118 #    if LDAP_CHARSET_8859 == 88591
119 #      define ISO_8859 1
120 #    elif LDAP_CHARSET_8859 == 88592
121 #      define ISO_8859 2
122 #    elif LDAP_CHARSET_8859 == 88593
123 #      define ISO_8859 3
124 #    elif LDAP_CHARSET_8859 == 88594
125 #      define ISO_8859 4
126 #    elif LDAP_CHARSET_8859 == 88595
127 #      define ISO_8859 5
128 #    elif LDAP_CHARSET_8859 == 88596
129 #      define ISO_8859 6
130 #    elif LDAP_CHARSET_8859 == 88597
131 #      define ISO_8859 7
132 #    elif LDAP_CHARSET_8859 == 88598
133 #      define ISO_8859 8
134 #    elif LDAP_CHARSET_8859 == 88599
135 #      define ISO_8859 9
136 #    elif LDAP_CHARSET_8859 == 885910
137 #      define ISO_8859 10
138 #    else
139 #      define ISO_8859 0
140 #    endif
141 
142 /*
143  * the following ISO_8859 to/afrom T.61 character set translation code is
144  * based on the code found in Enrique Silvestre Mora's iso-t61.c, found
145  * as part of this package:
146  *   ftp://pereiii.uji.es/pub/uji-ftp/unix/ldap/iso-t61.translation.tar.Z
147  * Enrique is now (10/95) at this address: enrique.silvestre@uv.es
148  *
149  * changes made by mcs@umich.edu 12 October 1995:
150  *   Change calling conventions of iso8859_t61() and t61_iso8859() to
151  *   match libldap conventions; rename to ldap_8859_to_t61() and
152  *   ldap_t61_to_8859().
153  *   Change conversion routines to deal with non-zero terminated strings.
154  *   ANSI-ize functions and include prototypes.
155  */
156 
157 /* iso-t61.c - ISO-T61 translation routines (version: 0.2.1, July-1994) */
158 /*
159  * Copyright (c) 1994 Enrique Silvestre Mora, Universitat Jaume I, Spain.
160  * All rights reserved.
161  *
162  * Redistribution and use in source and binary forms are permitted
163  * provided that this notice is preserved and that due credit is given
164  * to the Universitat Jaume I. The name of the University
165  * may not be used to endorse or promote products derived from this
166  * software without specific prior written permission. This software
167  * is provided ``as is'' without express or implied warranty.
168  */
169 
170 #    include <stdio.h>
171 #    include <stdlib.h>
172 #    include <string.h>
173 
174 /* Character set used: ISO 8859-1, ISO 8859-2, ISO 8859-3, ... */
175 /* #define  ISO_8859      1 */
176 
177 #    ifndef ISO_8859
178 #      define ISO_8859 0
179 #    endif
180 
181 typedef unsigned char Byte;
182 typedef struct {
183   Byte a, b;
184 } Couple;
185 
186 #    ifdef NEEDPROTOS
187 static Byte* c_to_hh(Byte* o, Byte c);
188 static Byte* c_to_cc(Byte* o, Couple* cc, Byte c);
189 static int hh_to_c(Byte* h);
190 static Byte* cc_to_t61(Byte* o, Byte* s);
191 #    else  /* NEEDPROTOS */
192 static Byte* c_to_hh();
193 static Byte* c_to_cc();
194 static int hh_to_c();
195 static Byte* cc_to_t61();
196 #    endif /* NEEDPROTOS */
197 
198 /*
199    Character chosen as base in diacritics alone: NO-BREAK SPACE.
200    (The standard say it must be a blank space, 0x20.)
201 */
202 #    define ALONE 0xA0
203 
204 static Couple diacritic[16] = {
205 #    if (ISO_8859 == 1) || (ISO_8859 == 9)
206     {0, 0},    {'`', 0},     {0xb4, 0},    {'^', 0},
207     {'~', 0},  {0xaf, 0},    {'(', ALONE}, {'.', ALONE},
208     {0xa8, 0}, {0, 0},       {'0', ALONE}, {0xb8, 0},
209     {0, 0},    {'"', ALONE}, {';', ALONE}, {'<', ALONE},
210 #    elif (ISO_8859 == 2)
211     {0, 0},    {'`', 0},  {0xb4, 0}, {'^', 0}, {'~', 0},     {'-', ALONE},
212     {0xa2, 0}, {0xff, 0}, {0xa8, 0}, {0, 0},   {'0', ALONE}, {0xb8, 0},
213     {0, 0},    {0xbd, 0}, {0xb2, 0}, {0xb7, 0}
214 #    elif (ISO_8859 == 3)
215     {0, 0},       {'`', 0},  {0xb4, 0}, {'^', 0},     {'~', 0},
216     {'-', ALONE}, {0xa2, 0}, {0xff, 0}, {0xa8, 0},    {0, 0},
217     {'0', ALONE}, {0xb8, 0}, {0, 0},    {'"', ALONE}, {';', ALONE},
218     {'<', ALONE}
219 #    elif (ISO_8859 == 4)
220     {0, 0},       {'`', 0},     {0xb4, 0}, {'^', 0}, {'~', 0},     {0xaf, 0},
221     {'(', ALONE}, {0xff, 0},    {0xa8, 0}, {0, 0},   {'0', ALONE}, {0xb8, 0},
222     {0, 0},       {'"', ALONE}, {0xb2, 0}, {0xb7, 0}
223 #    else
224     {0, 0},       {'`', 0},     {'\'', ALONE}, {'^', 0},     {'~', 0},
225     {'-', ALONE}, {'(', ALONE}, {'.', ALONE},  {':', ALONE}, {0, 0},
226     {'0', ALONE}, {',', ALONE}, {0, 0},        {'"', ALONE}, {';', ALONE},
227     {'<', ALONE}
228 #    endif
229 };
230 
231 /*
232    --- T.61 (T.51) letters with diacritics: conversion to ISO 8859-n -----
233        A,   C,   D,   E,   G,   H,   I,   J,   K,
234        L,   N,   O,   R,   S,   T,   U,   W,   Y,   Z.
235    -----------------------------------------------------------------------
236 */
237 static int letter_w_diacritic[16][38] = {
238 #    if (ISO_8859 == 1)
239     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
240     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
241     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
242     0,    0,    0xc0, 0,    0,    0xc8, 0,    0,    0xcc, 0,    0,    0,
243     0,    0xd2, 0,    0,    0,    0xd9, 0,    0,    0,    0xe0, 0,    0,
244     0xe8, 0,    0,    0xec, 0,    0,    0,    0,    0xf2, 0,    0,    0,
245     0xf9, 0,    0,    0,    0xc1, -1,   0,    0xc9, 0,    0,    0xcd, 0,
246     0,    -1,   -1,   0xd3, -1,   -1,   0,    0xda, 0,    0xdd, -1,   0xe1,
247     -1,   0,    0xe9, 0,    0,    0xed, 0,    0,    -1,   -1,   0xf3, -1,
248     -1,   0,    0xfa, 0,    0xfd, -1,   0xc2, -1,   0,    0xca, -1,   -1,
249     0xce, -1,   0,    0,    0,    0xd4, 0,    -1,   0,    0xdb, -1,   -1,
250     0,    0xe2, -1,   0,    0xea, -1,   -1,   0xee, -1,   0,    0,    0,
251     0xf4, 0,    -1,   0,    0xfb, -1,   -1,   0,    0xc3, 0,    0,    0,
252     0,    0,    -1,   0,    0,    0,    0xd1, 0xd5, 0,    0,    0,    -1,
253     0,    0,    0,    0xe3, 0,    0,    0,    0,    0,    -1,   0,    0,
254     0,    0xf1, 0xf5, 0,    0,    0,    -1,   0,    0,    0,    -1,   0,
255     0,    -1,   0,    0,    -1,   0,    0,    0,    0,    -1,   0,    0,
256     0,    -1,   0,    0,    0,    -1,   0,    0,    -1,   0,    0,    -1,
257     0,    0,    0,    0,    -1,   0,    0,    0,    -1,   0,    0,    0,
258     -1,   0,    0,    0,    -1,   0,    0,    0,    0,    0,    0,    0,
259     0,    0,    0,    -1,   0,    0,    0,    -1,   0,    0,    0,    -1,
260     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,
261     0,    0,    0,    -1,   0,    -1,   -1,   0,    -1,   0,    0,    0,
262     0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,    -1,   0,
263     -1,   -1,   0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
264     0,    0,    0,    -1,   0xc4, 0,    0,    0xcb, 0,    0,    0xcf, 0,
265     0,    0,    0,    0xd6, 0,    0,    0,    0xdc, 0,    -1,   0,    0xe4,
266     0,    0,    0xeb, 0,    0,    0xef, 0,    0,    0,    0,    0xf6, 0,
267     0,    0,    0xfc, 0,    0xff, 0,    0,    0,    0,    0,    0,    0,
268     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
269     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
270     0,    0,    0,    0,    0,    0,    0,    0,    0xc5, 0,    0,    0,
271     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    -1,
272     0,    0,    0,    0xe5, 0,    0,    0,    0,    0,    0,    0,    0,
273     0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,    0,    0xc7,
274     0,    0,    -1,   0,    0,    0,    -1,   -1,   -1,   0,    -1,   -1,
275     -1,   0,    0,    0,    0,    0,    0xe7, 0,    0,    -1,   0,    0,
276     0,    -1,   -1,   -1,   0,    -1,   -1,   -1,   0,    0,    0,    0,
277     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
278     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
279     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
280     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
281     0,    -1,   0,    0,    0,    -1,   0,    0,    0,    0,    0,    0,
282     0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,
283     -1,   0,    0,    0,    -1,   0,    0,    -1,   0,    0,    -1,   0,
284     0,    0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,    -1,
285     0,    0,    -1,   0,    0,    -1,   0,    0,    0,    0,    0,    0,
286     0,    0,    -1,   0,    0,    0,    0,    -1,   -1,   -1,   0,    0,
287     0,    0,    0,    -1,   -1,   0,    -1,   -1,   -1,   0,    0,    0,
288     -1,   0,    -1,   -1,   -1,   0,    0,    0,    0,    0,    -1,   -1,
289     0,    -1,   -1,   -1,   0,    0,    0,    -1
290 #    elif (ISO_8859 == 2)
291     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
292     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
293     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
294     0,    0,    -1,   0,    0,    -1,   0,    0,    -1,   0,    0,    0,
295     0,    -1,   0,    0,    0,    -1,   0,    0,    0,    -1,   0,    0,
296     -1,   0,    0,    -1,   0,    0,    0,    0,    -1,   0,    0,    0,
297     -1,   0,    0,    0,    0xc1, 0xc6, 0,    0xc9, 0,    0,    0xcd, 0,
298     0,    0xc5, 0xd1, 0xd3, 0xc0, 0xa6, 0,    0xda, 0,    0xdd, 0xac, 0xe1,
299     0xe6, 0,    0xe9, 0,    0,    0xed, 0,    0,    0xe5, 0xf1, 0xf3, 0xe0,
300     0xb6, 0,    0xfa, 0,    0xfd, 0xbc, 0xc2, -1,   0,    -1,   -1,   -1,
301     0xce, -1,   0,    0,    0,    0xd4, 0,    -1,   0,    -1,   -1,   -1,
302     0,    0xe2, -1,   0,    -1,   -1,   -1,   0xee, -1,   0,    0,    0,
303     0xf4, 0,    -1,   0,    -1,   -1,   -1,   0,    -1,   0,    0,    0,
304     0,    0,    -1,   0,    0,    0,    -1,   -1,   0,    0,    0,    -1,
305     0,    0,    0,    -1,   0,    0,    0,    0,    0,    -1,   0,    0,
306     0,    -1,   -1,   0,    0,    0,    -1,   0,    0,    0,    -1,   0,
307     0,    -1,   0,    0,    -1,   0,    0,    0,    0,    -1,   0,    0,
308     0,    -1,   0,    0,    0,    -1,   0,    0,    -1,   0,    0,    -1,
309     0,    0,    0,    0,    -1,   0,    0,    0,    -1,   0,    0,    0,
310     0xc3, 0,    0,    0,    -1,   0,    0,    0,    0,    0,    0,    0,
311     0,    0,    0,    -1,   0,    0,    0,    0xe3, 0,    0,    0,    -1,
312     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,
313     0,    0,    0,    -1,   0,    -1,   -1,   0,    -1,   0,    0,    0,
314     0,    0,    0,    0,    0,    0,    0,    0,    0xaf, 0,    -1,   0,
315     -1,   -1,   0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
316     0,    0,    0,    0xbf, 0xc4, 0,    0,    0xcb, 0,    0,    -1,   0,
317     0,    0,    0,    0xd6, 0,    0,    0,    0xdc, 0,    -1,   0,    0xe4,
318     0,    0,    0xeb, 0,    0,    -1,   0,    0,    0,    0,    0xf6, 0,
319     0,    0,    0xfc, 0,    -1,   0,    0,    0,    0,    0,    0,    0,
320     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
321     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
322     0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,
323     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0xd9,
324     0,    0,    0,    -1,   0,    0,    0,    0,    0,    0,    0,    0,
325     0,    0,    0,    0,    0,    0,    0xf9, 0,    0,    0,    0,    0xc7,
326     0,    0,    -1,   0,    0,    0,    -1,   -1,   -1,   0,    -1,   0xaa,
327     0xde, 0,    0,    0,    0,    0,    0xe7, 0,    0,    -1,   0,    0,
328     0,    -1,   -1,   -1,   0,    -1,   0xba, 0xfe, 0,    0,    0,    0,
329     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
330     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
331     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
332     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
333     0,    0xd5, 0,    0,    0,    0xdb, 0,    0,    0,    0,    0,    0,
334     0,    0,    0,    0,    0,    0,    0,    0,    0xf5, 0,    0,    0,
335     0xfb, 0,    0,    0,    0xa1, 0,    0,    0xca, 0,    0,    -1,   0,
336     0,    0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,    0xb1,
337     0,    0,    0xea, 0,    0,    -1,   0,    0,    0,    0,    0,    0,
338     0,    0,    -1,   0,    0,    0,    0,    0xc8, 0xcf, 0xcc, 0,    0,
339     0,    0,    0,    0xa5, 0xd2, 0,    0xd8, 0xa9, 0xab, 0,    0,    0,
340     0xae, 0,    0xe8, 0xef, 0xec, 0,    0,    0,    0,    0,    0xb5, 0xf2,
341     0,    0xf8, 0xb9, 0xbb, 0,    0,    0,    0xbe
342 #    elif (ISO_8859 == 3)
343     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
344     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
345     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
346     0,    0,    0xc0, 0,    0,    0xc8, 0,    0,    0xcc, 0,    0,    0,
347     0,    0xd2, 0,    0,    0,    0xd9, 0,    0,    0,    0xe0, 0,    0,
348     0xe8, 0,    0,    0xec, 0,    0,    0,    0,    0xf2, 0,    0,    0,
349     0xf9, 0,    0,    0,    0xc1, -1,   0,    0xc9, 0,    0,    0xcd, 0,
350     0,    -1,   -1,   0xd3, -1,   -1,   0,    0xda, 0,    -1,   -1,   0xe1,
351     -1,   0,    0xe9, 0,    0,    0xed, 0,    0,    -1,   -1,   0xf3, -1,
352     -1,   0,    0xfa, 0,    -1,   -1,   0xc2, 0xc6, 0,    0xca, 0xd8, 0xa6,
353     0xce, 0xac, 0,    0,    0,    0xd4, 0,    0xde, 0,    0xdb, -1,   -1,
354     0,    0xe2, 0xe6, 0,    0xea, 0xf8, 0xb6, 0xee, 0xbc, 0,    0,    0,
355     0xf4, 0,    0xfe, 0,    0xfb, -1,   -1,   0,    -1,   0,    0,    0,
356     0,    0,    -1,   0,    0,    0,    0xd1, -1,   0,    0,    0,    -1,
357     0,    0,    0,    -1,   0,    0,    0,    0,    0,    -1,   0,    0,
358     0,    0xf1, -1,   0,    0,    0,    -1,   0,    0,    0,    -1,   0,
359     0,    -1,   0,    0,    -1,   0,    0,    0,    0,    -1,   0,    0,
360     0,    -1,   0,    0,    0,    -1,   0,    0,    -1,   0,    0,    -1,
361     0,    0,    0,    0,    -1,   0,    0,    0,    -1,   0,    0,    0,
362     -1,   0,    0,    0,    0xab, 0,    0,    0,    0,    0,    0,    0,
363     0,    0,    0,    0xdd, 0,    0,    0,    -1,   0,    0,    0,    0xbb,
364     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0xfd, 0,
365     0,    0,    0,    0xc5, 0,    -1,   0xd5, 0,    0xa9, 0,    0,    0,
366     0,    0,    0,    0,    0,    0,    0,    0,    0xaf, 0,    0xe5, 0,
367     -1,   0xf5, 0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
368     0,    0,    0,    0xbf, 0xc4, 0,    0,    0xcb, 0,    0,    0xcf, 0,
369     0,    0,    0,    0xd6, 0,    0,    0,    0xdc, 0,    -1,   0,    0xe4,
370     0,    0,    0xeb, 0,    0,    0xef, 0,    0,    0,    0,    0xf6, 0,
371     0,    0,    0xfc, 0,    -1,   0,    0,    0,    0,    0,    0,    0,
372     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
373     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
374     0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,
375     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    -1,
376     0,    0,    0,    -1,   0,    0,    0,    0,    0,    0,    0,    0,
377     0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,    0,    0xc7,
378     0,    0,    -1,   0,    0,    0,    -1,   -1,   -1,   0,    -1,   0xaa,
379     -1,   0,    0,    0,    0,    0,    0xe7, 0,    0,    -1,   0,    0,
380     0,    -1,   -1,   -1,   0,    -1,   0xba, -1,   0,    0,    0,    0,
381     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
382     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
383     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
384     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
385     0,    -1,   0,    0,    0,    -1,   0,    0,    0,    0,    0,    0,
386     0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,
387     -1,   0,    0,    0,    -1,   0,    0,    -1,   0,    0,    -1,   0,
388     0,    0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,    -1,
389     0,    0,    -1,   0,    0,    -1,   0,    0,    0,    0,    0,    0,
390     0,    0,    -1,   0,    0,    0,    0,    -1,   -1,   -1,   0,    0,
391     0,    0,    0,    -1,   -1,   0,    -1,   -1,   -1,   0,    0,    0,
392     -1,   0,    -1,   -1,   -1,   0,    0,    0,    0,    0,    -1,   -1,
393     0,    -1,   -1,   -1,   0,    0,    0,    -1
394 #    elif (ISO_8859 == 4)
395     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
396     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
397     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
398     0,    0,    -1,   0,    0,    -1,   0,    0,    -1,   0,    0,    0,
399     0,    -1,   0,    0,    0,    -1,   0,    0,    0,    -1,   0,    0,
400     -1,   0,    0,    -1,   0,    0,    0,    0,    -1,   0,    0,    0,
401     -1,   0,    0,    0,    0xc1, -1,   0,    0xc9, 0,    0,    0xcd, 0,
402     0,    -1,   -1,   -1,   -1,   -1,   0,    0xda, 0,    -1,   -1,   0xe1,
403     -1,   0,    0xe9, 0,    0,    0xed, 0,    0,    -1,   -1,   -1,   -1,
404     -1,   0,    0xfa, 0,    -1,   -1,   0xc2, -1,   0,    -1,   -1,   -1,
405     0xce, -1,   0,    0,    0,    0xd4, 0,    -1,   0,    0xdb, -1,   -1,
406     0,    0xe2, -1,   0,    -1,   -1,   -1,   0xee, -1,   0,    0,    0,
407     0xf4, 0,    -1,   0,    0xfb, -1,   -1,   0,    0xc3, 0,    0,    0,
408     0,    0,    0xa5, 0,    0,    0,    -1,   0xd5, 0,    0,    0,    0xdd,
409     0,    0,    0,    0xe3, 0,    0,    0,    0,    0,    0xb5, 0,    0,
410     0,    -1,   0xf5, 0,    0,    0,    0xfd, 0,    0,    0,    0xc0, 0,
411     0,    0xaa, 0,    0,    0xcf, 0,    0,    0,    0,    0xd2, 0,    0,
412     0,    0xde, 0,    0,    0,    0xe0, 0,    0,    0xba, 0,    0,    0xef,
413     0,    0,    0,    0,    0xf2, 0,    0,    0,    0xfe, 0,    0,    0,
414     -1,   0,    0,    0,    -1,   0,    0,    0,    0,    0,    0,    0,
415     0,    0,    0,    -1,   0,    0,    0,    -1,   0,    0,    0,    -1,
416     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,
417     0,    0,    0,    -1,   0,    0xcc, -1,   0,    -1,   0,    0,    0,
418     0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,    -1,   0,
419     0xec, -1,   0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
420     0,    0,    0,    -1,   0xc4, 0,    0,    0xcb, 0,    0,    -1,   0,
421     0,    0,    0,    0xd6, 0,    0,    0,    0xdc, 0,    -1,   0,    0xe4,
422     0,    0,    0xeb, 0,    0,    -1,   0,    0,    0,    0,    0xf6, 0,
423     0,    0,    0xfc, 0,    -1,   0,    0,    0,    0,    0,    0,    0,
424     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
425     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
426     0,    0,    0,    0,    0,    0,    0,    0,    0xc5, 0,    0,    0,
427     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    -1,
428     0,    0,    0,    0xe5, 0,    0,    0,    0,    0,    0,    0,    0,
429     0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,    0,    -1,
430     0,    0,    0xab, 0,    0,    0,    0xd3, 0xa6, 0xd1, 0,    0xa3, -1,
431     -1,   0,    0,    0,    0,    0,    -1,   0,    0,    0xbb, 0,    0,
432     0,    0xf3, 0xb6, 0xf1, 0,    0xb3, -1,   -1,   0,    0,    0,    0,
433     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
434     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
435     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
436     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
437     0,    -1,   0,    0,    0,    -1,   0,    0,    0,    0,    0,    0,
438     0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,
439     -1,   0,    0,    0,    0xa1, 0,    0,    0xca, 0,    0,    0xc7, 0,
440     0,    0,    0,    0,    0,    0,    0,    0xd9, 0,    0,    0,    0xb1,
441     0,    0,    0xea, 0,    0,    0xe7, 0,    0,    0,    0,    0,    0,
442     0,    0,    0xf9, 0,    0,    0,    0,    0xc8, -1,   -1,   0,    0,
443     0,    0,    0,    -1,   -1,   0,    -1,   0xa9, -1,   0,    0,    0,
444     0xae, 0,    0xe8, -1,   -1,   0,    0,    0,    0,    0,    -1,   -1,
445     0,    -1,   0xb9, -1,   0,    0,    0,    0xbe
446 #    elif (ISO_8859 == 9)
447     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
448     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
449     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
450     0,    0,    0xc0, 0,    0,    0xc8, 0,    0,    0xcc, 0,    0,    0,
451     0,    0xd2, 0,    0,    0,    0xd9, 0,    0,    0,    0xe0, 0,    0,
452     0xe8, 0,    0,    -1,   0,    0,    0,    0,    0xf2, 0,    0,    0,
453     0xf9, 0,    0,    0,    0xc1, -1,   0,    0xc9, 0,    0,    0xcd, 0,
454     0,    -1,   -1,   0xd3, -1,   -1,   0,    0xda, 0,    -1,   -1,   0xe1,
455     -1,   0,    0xe9, 0,    0,    0xed, 0,    0,    -1,   -1,   0xf3, -1,
456     -1,   0,    0xfa, 0,    -1,   -1,   0xc2, -1,   0,    0xca, -1,   -1,
457     0xce, -1,   0,    0,    0,    0xd4, 0,    -1,   0,    0xdb, -1,   -1,
458     0,    0xe2, -1,   0,    -1,   -1,   -1,   0xee, -1,   0,    0,    0,
459     0xf4, 0,    -1,   0,    0xfb, -1,   -1,   0,    0xc3, 0,    0,    0,
460     0,    0,    -1,   0,    0,    0,    0xd1, 0xd5, 0,    0,    0,    -1,
461     0,    0,    0,    0xe3, 0,    0,    0,    0,    0,    -1,   0,    0,
462     0,    0xf1, 0xf5, 0,    0,    0,    -1,   0,    0,    0,    -1,   0,
463     0,    -1,   0,    0,    -1,   0,    0,    0,    0,    -1,   0,    0,
464     0,    -1,   0,    0,    0,    -1,   0,    0,    -1,   0,    0,    0xef,
465     0,    0,    0,    0,    -1,   0,    0,    0,    -1,   0,    0,    0,
466     -1,   0,    0,    0,    0xd0, 0,    0,    0,    0,    0,    0,    0,
467     0,    0,    0,    -1,   0,    0,    0,    -1,   0,    0,    0,    0xf0,
468     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,
469     0,    0,    0,    -1,   0,    -1,   -1,   0,    0xdd, 0,    0,    0,
470     0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,    -1,   0,
471     0xec, -1,   0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
472     0,    0,    0,    -1,   0xc4, 0,    0,    0xcb, 0,    0,    0xcf, 0,
473     0,    0,    0,    0xd6, 0,    0,    0,    0xdc, 0,    -1,   0,    0xe4,
474     0,    0,    0xeb, 0,    0,    -1,   0,    0,    0,    0,    0xf6, 0,
475     0,    0,    0xfc, 0,    0xff, 0,    0,    0,    0,    0,    0,    0,
476     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
477     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
478     0,    0,    0,    0,    0,    0,    0,    0,    0xc5, 0,    0,    0,
479     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    -1,
480     0,    0,    0,    0xe5, 0,    0,    0,    0,    0,    0,    0,    0,
481     0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,    0,    0xc7,
482     0,    0,    -1,   0,    0,    0,    -1,   -1,   -1,   0,    -1,   0xde,
483     -1,   0,    0,    0,    0,    0,    0xe7, 0,    0,    -1,   0,    0,
484     0,    -1,   -1,   -1,   0,    -1,   0xfe, -1,   0,    0,    0,    0,
485     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
486     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
487     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
488     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
489     0,    -1,   0,    0,    0,    -1,   0,    0,    0,    0,    0,    0,
490     0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,
491     -1,   0,    0,    0,    -1,   0,    0,    -1,   0,    0,    -1,   0,
492     0,    0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,    -1,
493     0,    0,    0xea, 0,    0,    -1,   0,    0,    0,    0,    0,    0,
494     0,    0,    -1,   0,    0,    0,    0,    -1,   -1,   -1,   0,    0,
495     0,    0,    0,    -1,   -1,   0,    -1,   -1,   -1,   0,    0,    0,
496     -1,   0,    -1,   -1,   -1,   0,    0,    0,    0,    0,    -1,   -1,
497     0,    -1,   -1,   -1,   0,    0,    0,    -1
498 #    elif (ISO_8859 == 10)
499     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
500     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
501     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
502     0,    0,    -1,   0,    0,    -1,   0,    0,    -1,   0,    0,    0,
503     0,    -1,   0,    0,    0,    -1,   0,    0,    0,    -1,   0,    0,
504     -1,   0,    0,    -1,   0,    0,    0,    0,    -1,   0,    0,    0,
505     -1,   0,    0,    0,    0xc1, -1,   0,    0xc9, 0,    0,    0xcd, 0,
506     0,    -1,   -1,   0xd3, -1,   -1,   0,    0xda, 0,    0xdd, -1,   0xe1,
507     -1,   0,    0xe9, 0,    0,    0xed, 0,    0,    -1,   -1,   0xf3, -1,
508     -1,   0,    0xfa, 0,    0xfd, -1,   0xc2, -1,   0,    -1,   -1,   -1,
509     0xce, -1,   0,    0,    0,    0xd4, 0,    -1,   0,    0xdb, -1,   -1,
510     0,    0xe2, -1,   0,    -1,   -1,   -1,   0xee, -1,   0,    0,    0,
511     0xf4, 0,    -1,   0,    0xfb, -1,   -1,   0,    0xc3, 0,    0,    0,
512     0,    0,    0xa5, 0,    0,    0,    -1,   0xd5, 0,    0,    0,    0xd7,
513     0,    0,    0,    0xe3, 0,    0,    0,    0,    0,    0xb5, 0,    0,
514     0,    -1,   0xf5, 0,    0,    0,    0xf7, 0,    0,    0,    0xc0, 0,
515     0,    0xa2, 0,    0,    0xa4, 0,    0,    0,    0,    0xd2, 0,    0,
516     0,    0xae, 0,    0,    0,    0xe0, 0,    0,    0xb2, 0,    0,    0xb4,
517     0,    0,    0,    0,    0xf2, 0,    0,    0,    0xbe, 0,    0,    0,
518     -1,   0,    0,    0,    -1,   0,    0,    0,    0,    0,    0,    0,
519     0,    0,    0,    -1,   0,    0,    0,    -1,   0,    0,    0,    -1,
520     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,
521     0,    0,    0,    -1,   0,    0xcc, -1,   0,    -1,   0,    0,    0,
522     0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,    -1,   0,
523     0xec, -1,   0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
524     0,    0,    0,    -1,   0xc4, 0,    0,    0xcb, 0,    0,    0xcf, 0,
525     0,    0,    0,    0xd6, 0,    0,    0,    0xdc, 0,    -1,   0,    0xe4,
526     0,    0,    0xeb, 0,    0,    0xef, 0,    0,    0,    0,    0xf6, 0,
527     0,    0,    0xfc, 0,    -1,   0,    0,    0,    0,    0,    0,    0,
528     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
529     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
530     0,    0,    0,    0,    0,    0,    0,    0,    0xc5, 0,    0,    0,
531     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    -1,
532     0,    0,    0,    0xe5, 0,    0,    0,    0,    0,    0,    0,    0,
533     0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,    0,    -1,
534     0,    0,    0xa3, 0,    0,    0,    0xa6, 0xa8, 0xd1, 0,    -1,   -1,
535     -1,   0,    0,    0,    0,    0,    -1,   0,    0,    0xb3, 0,    0,
536     0,    0xb6, 0xb8, 0xf1, 0,    -1,   -1,   -1,   0,    0,    0,    0,
537     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
538     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
539     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
540     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
541     0,    -1,   0,    0,    0,    -1,   0,    0,    0,    0,    0,    0,
542     0,    0,    0,    0,    0,    0,    0,    0,    -1,   0,    0,    0,
543     -1,   0,    0,    0,    0xa1, 0,    0,    0xca, 0,    0,    0xc7, 0,
544     0,    0,    0,    0,    0,    0,    0,    0xd9, 0,    0,    0,    0xb1,
545     0,    0,    0xea, 0,    0,    0xe7, 0,    0,    0,    0,    0,    0,
546     0,    0,    0xf9, 0,    0,    0,    0,    0xc8, -1,   -1,   0,    0,
547     0,    0,    0,    -1,   -1,   0,    -1,   0xaa, -1,   0,    0,    0,
548     0xac, 0,    0xe8, -1,   -1,   0,    0,    0,    0,    0,    -1,   -1,
549     0,    -1,   0xba, -1,   0,    0,    0,    0xbc
550 #    else
551     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
552     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
553     0,  0,  -1, 0,  0,  -1, 0,  0,  -1, 0,  0,  0,  0,  -1, 0,  0,  0,  -1,
554     0,  0,  0,  -1, 0,  0,  -1, 0,  0,  -1, 0,  0,  0,  0,  -1, 0,  0,  0,
555     -1, 0,  0,  0,  -1, -1, 0,  -1, 0,  0,  -1, 0,  0,  -1, -1, -1, -1, -1,
556     0,  -1, 0,  -1, -1, -1, -1, 0,  -1, 0,  0,  -1, 0,  0,  -1, -1, -1, -1,
557     -1, 0,  -1, 0,  -1, -1, -1, -1, 0,  -1, -1, -1, -1, -1, 0,  0,  0,  -1,
558     0,  -1, 0,  -1, -1, -1, 0,  -1, -1, 0,  -1, -1, -1, -1, -1, 0,  0,  0,
559     -1, 0,  -1, 0,  -1, -1, -1, 0,  -1, 0,  0,  0,  0,  0,  -1, 0,  0,  0,
560     -1, -1, 0,  0,  0,  -1, 0,  0,  0,  -1, 0,  0,  0,  0,  0,  -1, 0,  0,
561     0,  -1, -1, 0,  0,  0,  -1, 0,  0,  0,  -1, 0,  0,  -1, 0,  0,  -1, 0,
562     0,  0,  0,  -1, 0,  0,  0,  -1, 0,  0,  0,  -1, 0,  0,  -1, 0,  0,  -1,
563     0,  0,  0,  0,  -1, 0,  0,  0,  -1, 0,  0,  0,  -1, 0,  0,  0,  -1, 0,
564     0,  0,  0,  0,  0,  0,  0,  0,  0,  -1, 0,  0,  0,  -1, 0,  0,  0,  -1,
565     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  -1, 0,  0,  0,  0,  -1, 0,  -1,
566     -1, 0,  -1, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  -1, 0,  -1, 0,
567     -1, -1, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  -1, -1, 0,
568     0,  -1, 0,  0,  -1, 0,  0,  0,  0,  -1, 0,  0,  0,  -1, 0,  -1, 0,  -1,
569     0,  0,  -1, 0,  0,  -1, 0,  0,  0,  0,  -1, 0,  0,  0,  -1, 0,  -1, 0,
570     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
571     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
572     0,  0,  -1, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  -1,
573     0,  0,  0,  -1, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
574     -1, 0,  0,  0,  0,  -1, 0,  0,  -1, 0,  0,  0,  -1, -1, -1, 0,  -1, -1,
575     -1, 0,  0,  0,  0,  0,  -1, 0,  0,  -1, 0,  0,  0,  -1, -1, -1, 0,  -1,
576     -1, -1, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
577     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
578     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
579     0,  -1, 0,  0,  0,  -1, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
580     0,  0,  -1, 0,  0,  0,  -1, 0,  0,  0,  -1, 0,  0,  -1, 0,  0,  -1, 0,
581     0,  0,  0,  0,  0,  0,  0,  -1, 0,  0,  0,  -1, 0,  0,  -1, 0,  0,  -1,
582     0,  0,  0,  0,  0,  0,  0,  0,  -1, 0,  0,  0,  0,  -1, -1, -1, 0,  0,
583     0,  0,  0,  -1, -1, 0,  -1, -1, -1, 0,  0,  0,  -1, 0,  -1, -1, -1, 0,
584     0,  0,  0,  0,  -1, -1, 0,  -1, -1, -1, 0,  0,  0,  -1
585 #    endif
586 };
587 
588 /*
589 --- T.61 characters [0xA0 .. 0xBF] -----------------
590 */
591 static Couple trans_t61a_iso8859[32] = {
592 #    if (ISO_8859 == 1) || (ISO_8859 == 9)
593     {'N', 'S'}, {0xa1, 0},   {0xa2, 0},  {0xa3, 0},   {'D', 'O'}, {0xa5, 0},
594     {'C', 'u'}, {0xa7, 0},   {0xa4, 0},  {'\'', '6'}, {'"', '6'}, {0xab, 0},
595     {'<', '-'}, {'-', '!'},  {'-', '>'}, {'-', 'v'},  {0xb0, 0},  {0xb1, 0},
596     {0xb2, 0},  {0xb3, 0},   {0xd7, 0},  {0xb5, 0},   {0xb6, 0},  {0xb7, 0},
597     {0xf7, 0},  {'\'', '9'}, {'"', '9'}, {0xbb, 0},   {0xbc, 0},  {0xbd, 0},
598     {0xbe, 0},  {0xbf, 0}
599 #    elif (ISO_8859 == 2) || (ISO_8859 == 4)
600     {'N', 'S'}, {'!', 'I'},  {'C', 't'}, {'P', 'd'},  {'D', 'O'}, {'Y', 'e'},
601     {'C', 'u'}, {0xa7, 0},   {0xa4, 0},  {'\'', '6'}, {'"', '6'}, {'<', '<'},
602     {'<', '-'}, {'-', '!'},  {'-', '>'}, {'-', 'v'},  {0xb0, 0},  {'+', '-'},
603     {'2', 'S'}, {'3', 'S'},  {0xd7, 0},  {'M', 'y'},  {'P', 'I'}, {'.', 'M'},
604     {0xf7, 0},  {'\'', '9'}, {'"', '9'}, {'>', '>'},  {'1', '4'}, {'1', '2'},
605     {'3', '4'}, {'?', 'I'},
606 #    elif (ISO_8859 == 3)
607     {'N', 'S'}, {'!', 'I'},  {'C', 't'}, {0xa3, 0},   {'D', 'O'}, {'Y', 'e'},
608     {'C', 'u'}, {0xa7, 0},   {0xa4, 0},  {'\'', '6'}, {'"', '6'}, {'<', '<'},
609     {'<', '-'}, {'-', '!'},  {'-', '>'}, {'-', 'v'},  {0xb0, 0},  {'+', '-'},
610     {0xb2, 0},  {0xb3, 0},   {0xd7, 0},  {0xb5, 0},   {'P', 'I'}, {0xb7, 0},
611     {0xf7, 0},  {'\'', '9'}, {'"', '9'}, {'>', '>'},  {'1', '4'}, {0xbd, 0},
612     {'3', '4'}, {'?', 'I'}
613 #    elif (ISO_8859 == 10)
614     {'N', 'S'}, {'!', 'I'},  {'C', 't'}, {'P', 'd'},  {'D', 'O'}, {'Y', 'e'},
615     {'C', 'u'}, {0xa7, 0},   {'C', 'u'}, {'\'', '6'}, {'"', '6'}, {'<', '<'},
616     {'<', '-'}, {'-', '!'},  {'-', '>'}, {'-', 'v'},  {0xb0, 0},  {'+', '-'},
617     {'2', 'S'}, {'3', 'S'},  {'*', 'X'}, {'M', 'y'},  {'P', 'I'}, {0xb7, 0},
618     {'-', ':'}, {'\'', '9'}, {'"', '9'}, {'>', '>'},  {'1', '4'}, {'1', '2'},
619     {'3', '4'}, {'?', 'I'}
620 #    else
621     {'N', 'S'}, {'!', 'I'},  {'C', 't'}, {'P', 'd'},  {'D', 'O'}, {'Y', 'e'},
622     {'C', 'u'}, {'S', 'E'},  {'X', 'O'}, {'\'', '6'}, {'"', '6'}, {'<', '<'},
623     {'<', '-'}, {'-', '!'},  {'-', '>'}, {'-', 'v'},  {'D', 'G'}, {'+', '-'},
624     {'2', 'S'}, {'3', 'S'},  {'*', 'X'}, {'M', 'y'},  {'P', 'I'}, {'.', 'M'},
625     {'-', ':'}, {'\'', '9'}, {'"', '9'}, {'>', '>'},  {'1', '4'}, {'1', '2'},
626     {'3', '4'}, {'?', 'I'}
627 #    endif
628 };
629 
630 /*
631 --- T.61 characters [0xE0 .. 0xFF] -----------------
632 */
633 static Couple trans_t61b_iso8859[48] = {
634 #    if (ISO_8859 == 1)
635     {'-', 'M'}, {0xb9, 0},   {0xae, 0},  {0xa9, 0},  {'T', 'M'},
636     {'M', '8'}, {0xac, 0},   {0xa6, 0},  {0, 0},     {0, 0},
637     {0, 0},     {0, 0},      {'1', '8'}, {'3', '8'}, {'5', '8'},
638     {'7', '8'}, {'O', 'm'},  {0xc6, 0},  {0xd0, 0},  {0xaa, 0},
639     {'H', '/'}, {0, 0},      {'I', 'J'}, {'L', '.'}, {'L', '/'},
640     {0xd8, 0},  {'O', 'E'},  {0xba, 0},  {0xde, 0},  {'T', '/'},
641     {'N', 'G'}, {'\'', 'n'}, {'k', 'k'}, {0xe6, 0},  {'d', '/'},
642     {0xf0, 0},  {'h', '/'},  {'i', '.'}, {'i', 'j'}, {'l', '.'},
643     {'l', '/'}, {0xf8, 0},   {'o', 'e'}, {0xdf, 0},  {0xfe, 0},
644     {'t', '/'}, {'n', 'g'},  {'-', '-'}
645 #    elif (ISO_8859 == 2)
646     {'-', 'M'}, {'1', 'S'},  {'R', 'g'}, {'C', 'o'}, {'T', 'M'},
647     {'M', '8'}, {'N', 'O'},  {'B', 'B'}, {0, 0},     {0, 0},
648     {0, 0},     {0, 0},      {'1', '8'}, {'3', '8'}, {'5', '8'},
649     {'7', '8'}, {'O', 'm'},  {'A', 'E'}, {0xd0, 0},  {'-', 'a'},
650     {'H', '/'}, {0, 0},      {'I', 'J'}, {'L', '.'}, {0xa3, 0},
651     {'O', '/'}, {'O', 'E'},  {'-', 'o'}, {'T', 'H'}, {'T', '/'},
652     {'N', 'G'}, {'\'', 'n'}, {'k', 'k'}, {'a', 'e'}, {0xf0, 0},
653     {'d', '-'}, {'h', '/'},  {'i', '.'}, {'i', 'j'}, {'l', '.'},
654     {0xb3, 0},  {'o', '/'},  {'o', 'e'}, {0xdf, 0},  {'t', 'h'},
655     {'t', '/'}, {'n', 'g'},  {'-', '-'}
656 #    elif (ISO_8859 == 3)
657     {'-', 'M'}, {'1', 'S'},  {'R', 'g'}, {'C', 'o'}, {'T', 'M'},
658     {'M', '8'}, {'N', 'O'},  {'B', 'B'}, {0, 0},     {0, 0},
659     {0, 0},     {0, 0},      {'1', '8'}, {'3', '8'}, {'5', '8'},
660     {'7', '8'}, {'O', 'm'},  {'A', 'E'}, {'D', '/'}, {'-', 'a'},
661     {0xa1, 0},  {0, 0},      {'I', 'J'}, {'L', '.'}, {'L', '/'},
662     {'O', '/'}, {'O', 'E'},  {'-', 'o'}, {'T', 'H'}, {'T', '/'},
663     {'N', 'G'}, {'\'', 'n'}, {'k', 'k'}, {'a', 'e'}, {'d', '/'},
664     {'d', '-'}, {0xb1, 0},   {0xb9, 0},  {'i', 'j'}, {'l', '.'},
665     {'l', '/'}, {'o', '/'},  {'o', 'e'}, {0xdf, 0},  {'t', 'h'},
666     {'t', '/'}, {'n', 'g'},  {'-', '-'}
667 #    elif (ISO_8859 == 4)
668     {'-', 'M'}, {'1', 'S'},  {'R', 'g'}, {'C', 'o'}, {'T', 'M'},
669     {'M', '8'}, {'N', 'O'},  {'B', 'B'}, {0, 0},     {0, 0},
670     {0, 0},     {0, 0},      {'1', '8'}, {'3', '8'}, {'5', '8'},
671     {'7', '8'}, {'O', 'm'},  {0xc6, 0},  {0xd0, 0},  {'-', 'a'},
672     {'H', '/'}, {0, 0},      {'I', 'J'}, {'L', '.'}, {'L', '/'},
673     {0xd8, 0},  {'O', 'E'},  {'-', 'o'}, {'T', 'H'}, {0xac, 0},
674     {0xbd, 0},  {'\'', 'n'}, {0xa2, 0},  {0xe6, 0},  {0xf0, 0},
675     {'d', '-'}, {'h', '/'},  {'i', '.'}, {'i', 'j'}, {'l', '.'},
676     {'l', '/'}, {0xf8, 0},   {'o', 'e'}, {0xdf, 0},  {'t', 'h'},
677     {0xbc, 0},  {0xbf, 0},   {'-', '-'}
678 #    elif (ISO_8859 == 9)
679     {'-', 'M'}, {0xb9, 0},   {0xae, 0},  {0xa9, 0},  {'T', 'M'},
680     {'M', '8'}, {0xac, 0},   {0xa6, 0},  {0, 0},     {0, 0},
681     {0, 0},     {0, 0},      {'1', '8'}, {'3', '8'}, {'5', '8'},
682     {'7', '8'}, {'O', 'm'},  {0xc6, 0},  {'D', '/'}, {0xaa, 0},
683     {'H', '/'}, {0, 0},      {'I', 'J'}, {'L', '.'}, {'L', '/'},
684     {0xd8, 0},  {'O', 'E'},  {0xba, 0},  {'T', 'H'}, {'T', '/'},
685     {'N', 'G'}, {'\'', 'n'}, {'k', 'k'}, {0xe6, 0},  {'d', '/'},
686     {'d', '-'}, {'h', '/'},  {0xfd, 0},  {'i', 'j'}, {'l', '.'},
687     {'l', '/'}, {0xf8, 0},   {'o', 'e'}, {0xdf, 0},  {'t', 'h'},
688     {'t', '/'}, {'n', 'g'},  {'-', '-'}
689 #    elif (ISO_8859 == 10)
690     {0xbd, 0},  {'1', 'S'},  {'R', 'g'}, {'C', 'o'}, {'T', 'M'},
691     {'M', '8'}, {'N', 'O'},  {'B', 'B'}, {0, 0},     {0, 0},
692     {0, 0},     {0, 0},      {'1', '8'}, {'3', '8'}, {'5', '8'},
693     {'7', '8'}, {'O', 'm'},  {0xc6, 0},  {0xa9, 0},  {'-', 'a'},
694     {'H', '/'}, {0, 0},      {'I', 'J'}, {'L', '.'}, {'L', '/'},
695     {0xd8, 0},  {'O', 'E'},  {'-', 'o'}, {0xde, 0},  {0xab, 0},
696     {0xaf, 0},  {'\'', 'n'}, {0xff, 0},  {0xe6, 0},  {0xb9, 0},
697     {0xf0, 0},  {'h', '/'},  {'i', '.'}, {'i', 'j'}, {'l', '.'},
698     {'l', '/'}, {0xf8, 0},   {'o', 'e'}, {0xdf, 0},  {0xfe, 0},
699     {0xbb, 0},  {0xbf, 0},   {'-', '-'}
700 #    else
701     {'-', 'M'}, {'1', 'S'},  {'R', 'g'}, {'C', 'o'}, {'T', 'M'},
702     {'M', '8'}, {'N', 'O'},  {'B', 'B'}, {0, 0},     {0, 0},
703     {0, 0},     {0, 0},      {'1', '8'}, {'3', '8'}, {'5', '8'},
704     {'7', '8'}, {'O', 'm'},  {'A', 'E'}, {'D', '/'}, {'-', 'a'},
705     {'H', '/'}, {0, 0},      {'I', 'J'}, {'L', '.'}, {'L', '/'},
706     {'O', '/'}, {'O', 'E'},  {'-', 'o'}, {'T', 'H'}, {'T', '/'},
707     {'N', 'G'}, {'\'', 'n'}, {'k', 'k'}, {'a', 'e'}, {'d', '/'},
708     {'d', '-'}, {'h', '/'},  {'i', '.'}, {'i', 'j'}, {'l', '.'},
709     {'l', '/'}, {'o', '/'},  {'o', 'e'}, {'s', 's'}, {'t', 'h'},
710     {'t', '-'}, {'n', 'g'},  {'-', '-'}
711 #    endif
712 };
713 
714 /*
715 --- ISO 8859-n characters <0xA0 .. 0xFF> -------------------
716 */
717 #    if (ISO_8859 == 1)
718 static Couple trans_iso8859_t61[96] = {
719     {0xa0, 0},     {0xa1, 0},   {0xa2, 0},   {0xa3, 0},     {0xa8, 0},
720     {0xa5, 0},     {0xd7, 0},   {0xa7, 0},   {0xc8, ALONE}, {0xd3, 0},
721     {0xe3, 0},     {0xab, 0},   {0xd6, 0},   {0xff, 0},     {0xd2, 0},
722     {0xc5, ALONE}, {0xb0, 0},   {0xb1, 0},   {0xb2, 0},     {0xb3, 0},
723     {0xc2, ALONE}, {0xb5, 0},   {0xb6, 0},   {0xb7, 0},     {0xcb, ALONE},
724     {0xd1, 0},     {0xeb, 0},   {0xbb, 0},   {0xbc, 0},     {0xbd, 0},
725     {0xbe, 0},     {0xbf, 0},   {0xc1, 'A'}, {0xc2, 'A'},   {0xc3, 'A'},
726     {0xc4, 'A'},   {0xc8, 'A'}, {0xca, 'A'}, {0xe1, 0},     {0xcb, 'C'},
727     {0xc1, 'E'},   {0xc2, 'E'}, {0xc3, 'E'}, {0xc8, 'E'},   {0xc1, 'I'},
728     {0xc2, 'I'},   {0xc3, 'I'}, {0xc8, 'I'}, {0xe2, 0},     {0xc4, 'N'},
729     {0xc1, 'O'},   {0xc2, 'O'}, {0xc3, 'O'}, {0xc4, 'O'},   {0xc8, 'O'},
730     {0xb4, 0},     {0xe9, 0},   {0xc1, 'U'}, {0xc2, 'U'},   {0xc3, 'U'},
731     {0xc8, 'U'},   {0xc2, 'Y'}, {0xec, 0},   {0xfb, 0},     {0xc1, 'a'},
732     {0xc2, 'a'},   {0xc3, 'a'}, {0xc4, 'a'}, {0xc8, 'a'},   {0xca, 'a'},
733     {0xf1, 0},     {0xcb, 'c'}, {0xc1, 'e'}, {0xc2, 'e'},   {0xc3, 'e'},
734     {0xc8, 'e'},   {0xc1, 'i'}, {0xc2, 'i'}, {0xc3, 'i'},   {0xc8, 'i'},
735     {0xf3, 0},     {0xc4, 'n'}, {0xc1, 'o'}, {0xc2, 'o'},   {0xc3, 'o'},
736     {0xc4, 'o'},   {0xc8, 'o'}, {0xb8, 0},   {0xf9, 0},     {0xc1, 'u'},
737     {0xc2, 'u'},   {0xc3, 'u'}, {0xc8, 'u'}, {0xc2, 'y'},   {0xfc, 0},
738     {0xc8, 'y'}};
739 #    elif (ISO_8859 == 2)
740 static Couple trans_iso8859_t61[96] = {
741     {0xa0, 0},     {0xce, 'A'}, {0xc6, ALONE}, {0xe8, 0},     {0xa8, 0},
742     {0xcf, 'L'},   {0xc2, 'S'}, {0xa7, 0},     {0xc8, ALONE}, {0xcf, 'S'},
743     {0xcb, 'S'},   {0xcf, 'T'}, {0xc2, 'Z'},   {0xff, 0},     {0xcf, 'Z'},
744     {0xc7, 'Z'},   {0xb0, 0},   {0xce, 'a'},   {0xce, ALONE}, {0xf8, 0},
745     {0xc2, ALONE}, {0xcf, 'l'}, {0xc2, 's'},   {0xcf, ALONE}, {0xcb, ALONE},
746     {0xcf, 's'},   {0xcb, 's'}, {0xcf, 't'},   {0xc2, 'z'},   {0xcd, ALONE},
747     {0xcf, 'z'},   {0xc7, 'z'}, {0xc2, 'R'},   {0xc2, 'A'},   {0xc3, 'A'},
748     {0xc6, 'A'},   {0xc8, 'A'}, {0xc2, 'L'},   {0xc2, 'C'},   {0xcb, 'C'},
749     {0xcf, 'C'},   {0xc2, 'E'}, {0xce, 'E'},   {0xc8, 'E'},   {0xcf, 'E'},
750     {0xc2, 'I'},   {0xc3, 'I'}, {0xcf, 'D'},   {0xe2, 0},     {0xc2, 'N'},
751     {0xcf, 'N'},   {0xc2, 'O'}, {0xc3, 'O'},   {0xcd, 'O'},   {0xc8, 'O'},
752     {0xb4, 0},     {0xcf, 'R'}, {0xca, 'U'},   {0xc2, 'U'},   {0xcd, 'U'},
753     {0xc8, 'U'},   {0xc2, 'Y'}, {0xcb, 'T'},   {0xfb, 0},     {0xc2, 'r'},
754     {0xc2, 'a'},   {0xc3, 'a'}, {0xc6, 'a'},   {0xc8, 'a'},   {0xc2, 'l'},
755     {0xc2, 'c'},   {0xcb, 'c'}, {0xcf, 'c'},   {0xc2, 'e'},   {0xce, 'e'},
756     {0xc8, 'e'},   {0xcf, 'e'}, {0xc2, 'i'},   {0xc3, 'i'},   {0xcf, 'd'},
757     {0xf2, 0},     {0xc2, 'n'}, {0xcf, 'n'},   {0xc2, 'o'},   {0xc3, 'o'},
758     {0xcd, 'o'},   {0xc8, 'o'}, {0xb8, 0},     {0xcf, 'r'},   {0xca, 'u'},
759     {0xc2, 'u'},   {0xcd, 'u'}, {0xc8, 'u'},   {0xc2, 'y'},   {0xcb, 't'},
760     {0xc7, ALONE}};
761 #    elif (ISO_8859 == 3)
762 static Couple trans_iso8859_t61[96] = {
763     {0xa0, 0},     {0xe4, 0},   {0xc6, ALONE}, {0xa3, 0},     {0xa8, 0},
764     {0, 0},        {0xc3, 'H'}, {0xa7, 0},     {0xc8, ALONE}, {0xc7, 'I'},
765     {0xcb, 'S'},   {0xc6, 'G'}, {0xc3, 'J'},   {0xff, 0},     {0, 0},
766     {0xc7, 'Z'},   {0xb0, 0},   {0xf4, 0},     {0xb2, 0},     {0xb3, 0},
767     {0xc2, ALONE}, {0xb5, 0},   {0xc3, 'h'},   {0xb7, 0},     {0xcb, ALONE},
768     {0xf5, 0},     {0xcb, 's'}, {0xc6, 'g'},   {0xc3, 'j'},   {0xbd, 0},
769     {0, 0},        {0xc7, 'z'}, {0xc1, 'A'},   {0xc2, 'A'},   {0xc3, 'A'},
770     {0, 0},        {0xc8, 'A'}, {0xc7, 'C'},   {0xc3, 'C'},   {0xcb, 'C'},
771     {0xc1, 'E'},   {0xc2, 'E'}, {0xc3, 'E'},   {0xc8, 'E'},   {0xc1, 'I'},
772     {0xc2, 'I'},   {0xc3, 'I'}, {0xc8, 'I'},   {0, 0},        {0xc4, 'N'},
773     {0xc1, 'O'},   {0xc2, 'O'}, {0xc3, 'O'},   {0xc7, 'G'},   {0xc8, 'O'},
774     {0xb4, 0},     {0xc3, 'G'}, {0xc1, 'U'},   {0xc2, 'U'},   {0xc3, 'U'},
775     {0xc8, 'U'},   {0xc6, 'U'}, {0xc3, 'S'},   {0xfb, 0},     {0xc1, 'a'},
776     {0xc2, 'a'},   {0xc3, 'a'}, {0, 0},        {0xc8, 'a'},   {0xc7, 'c'},
777     {0xc3, 'c'},   {0xcb, 'c'}, {0xc1, 'e'},   {0xc2, 'e'},   {0xc3, 'e'},
778     {0xc8, 'e'},   {0xc1, 'i'}, {0xc2, 'i'},   {0xc3, 'i'},   {0xc8, 'i'},
779     {0, 0},        {0xc4, 'n'}, {0xc1, 'o'},   {0xc2, 'o'},   {0xc3, 'o'},
780     {0xc7, 'g'},   {0xc8, 'o'}, {0xb8, 0},     {0xc3, 'g'},   {0xc1, 'u'},
781     {0xc2, 'u'},   {0xc3, 'u'}, {0xc8, 'u'},   {0xc6, 'u'},   {0xc3, 's'},
782     {0xc7, ALONE}};
783 #    elif (ISO_8859 == 4)
784 static Couple trans_iso8859_t61[96] = {
785     {0xa0, 0},     {0xce, 'A'}, {0xf0, 0},   {0xcb, 'R'},   {0xa8, 0},
786     {0xc4, 'I'},   {0xcb, 'L'}, {0xa7, 0},   {0xc8, ALONE}, {0xcf, 'S'},
787     {0xc5, 'E'},   {0xcb, 'G'}, {0xed, 0},   {0xff, 0},     {0xcf, 'Z'},
788     {0xc5, ALONE}, {0xb0, 0},   {0xce, 'a'}, {0xce, ALONE}, {0xcb, 'r'},
789     {0xc2, ALONE}, {0xc4, 'i'}, {0xcb, 'l'}, {0xcf, ALONE}, {0xcb, ALONE},
790     {0xcf, 's'},   {0xc5, 'e'}, {0xcb, 'g'}, {0xfd, 0},     {0xee, 0},
791     {0xcf, 'z'},   {0xfe, 0},   {0xc5, 'A'}, {0xc2, 'A'},   {0xc3, 'A'},
792     {0xc4, 'A'},   {0xc8, 'A'}, {0xca, 'A'}, {0xe1, 0},     {0xce, 'I'},
793     {0xcf, 'C'},   {0xc2, 'E'}, {0xce, 'E'}, {0xc8, 'E'},   {0xc7, 'E'},
794     {0xc2, 'I'},   {0xc3, 'I'}, {0xc5, 'I'}, {0xe2, 0},     {0xcb, 'N'},
795     {0xc5, 'O'},   {0xcb, 'K'}, {0xc3, 'O'}, {0xc4, 'O'},   {0xc8, 'O'},
796     {0xb4, 0},     {0xe9, 0},   {0xce, 'U'}, {0xc2, 'U'},   {0xc3, 'U'},
797     {0xc8, 'U'},   {0xc4, 'U'}, {0xc5, 'U'}, {0xfb, 0},     {0xc5, 'a'},
798     {0xc2, 'a'},   {0xc3, 'a'}, {0xc4, 'a'}, {0xc8, 'a'},   {0xca, 'a'},
799     {0xf1, 0},     {0xce, 'i'}, {0xcf, 'c'}, {0xc2, 'e'},   {0xce, 'e'},
800     {0xc8, 'e'},   {0xc7, 'e'}, {0xc2, 'i'}, {0xc3, 'i'},   {0xc5, 'i'},
801     {0xf2, 0},     {0xcb, 'n'}, {0xc5, 'o'}, {0xcb, 'k'},   {0xc3, 'o'},
802     {0xc4, 'o'},   {0xc8, 'o'}, {0xb8, 0},   {0xf9, 0},     {0xce, 'u'},
803     {0xc2, 'u'},   {0xc3, 'u'}, {0xc8, 'u'}, {0xc4, 'u'},   {0xc5, 'u'},
804     {0xc7, ALONE}};
805 #    elif (ISO_8859 == 9)
806 static Couple trans_iso8859_t61[96] = {
807     {0xa0, 0},     {0xa1, 0},   {0xa2, 0},   {0xa3, 0},     {0xa8, 0},
808     {0xa5, 0},     {0xd7, 0},   {0xa7, 0},   {0xc8, ALONE}, {0xd3, 0},
809     {0xe3, 0},     {0xab, 0},   {0xd6, 0},   {0xff, 0},     {0xd2, 0},
810     {0xc5, ALONE}, {0xb0, 0},   {0xb1, 0},   {0xb2, 0},     {0xb3, 0},
811     {0xc2, ALONE}, {0xb5, 0},   {0xb6, 0},   {0xb7, 0},     {0xcb, ALONE},
812     {0xd1, 0},     {0xeb, 0},   {0xbb, 0},   {0xbc, 0},     {0xbd, 0},
813     {0xbe, 0},     {0xbf, 0},   {0xc1, 'A'}, {0xc2, 'A'},   {0xc3, 'A'},
814     {0xc4, 'A'},   {0xc8, 'A'}, {0xca, 'A'}, {0xe1, 0},     {0xcb, 'C'},
815     {0xc1, 'E'},   {0xc2, 'E'}, {0xc3, 'E'}, {0xc8, 'E'},   {0xc1, 'I'},
816     {0xc2, 'I'},   {0xc3, 'I'}, {0xc8, 'I'}, {0xc6, 'G'},   {0xc4, 'N'},
817     {0xc1, 'O'},   {0xc2, 'O'}, {0xc3, 'O'}, {0xc4, 'O'},   {0xc8, 'O'},
818     {0xb4, 0},     {0xe9, 0},   {0xc1, 'U'}, {0xc2, 'U'},   {0xc3, 'U'},
819     {0xc8, 'U'},   {0xc7, 'I'}, {0xcb, 'S'}, {0xfb, 0},     {0xc1, 'a'},
820     {0xc2, 'a'},   {0xc3, 'a'}, {0xc4, 'a'}, {0xc8, 'a'},   {0xca, 'a'},
821     {0xf1, 0},     {0xcb, 'c'}, {0xc1, 'e'}, {0xc2, 'e'},   {0xce, 'e'},
822     {0xc8, 'e'},   {0xc7, 'e'}, {0xc2, 'i'}, {0xc3, 'i'},   {0xc5, 'i'},
823     {0xc6, 'g'},   {0xc4, 'n'}, {0xc1, 'o'}, {0xc2, 'o'},   {0xc3, 'o'},
824     {0xc4, 'o'},   {0xc8, 'o'}, {0xb8, 0},   {0xf9, 0},     {0xc1, 'u'},
825     {0xc2, 'u'},   {0xc3, 'u'}, {0xc8, 'u'}, {0xf5, 0},     {0xcb, 's'},
826     {0xc8, 'y'}};
827 #    elif (ISO_8859 == 10)
828 static Couple trans_iso8859_t61[96] = {
829     {0xa0, 0},   {0xce, 'A'}, {0xc5, 'E'}, {0xcb, 'G'}, {0xc5, 'I'},
830     {0xc4, 'I'}, {0xcb, 'K'}, {0xa7, 0},   {0xcb, 'L'}, {0xe2, 0},
831     {0xcf, 'S'}, {0xed, 0},   {0xcf, 'Z'}, {0xff, 0},   {0xc5, 'U'},
832     {0xee, 0},   {0xb0, 0},   {0xce, 'a'}, {0xc5, 'e'}, {0xcb, 'g'},
833     {0xc5, 'i'}, {0xc4, 'i'}, {0xcb, 'k'}, {0xb7, 0},   {0xcb, 'l'},
834     {0xf2, 0},   {0xcf, 's'}, {0xfd, 0},   {0xcf, 'z'}, {0xd0, 0},
835     {0xc5, 'u'}, {0xfe, 0},   {0xc5, 'A'}, {0xc2, 'A'}, {0xc3, 'A'},
836     {0xc4, 'A'}, {0xc8, 'A'}, {0xca, 'A'}, {0xe1, 0},   {0xce, 'I'},
837     {0xcf, 'C'}, {0xc2, 'E'}, {0xce, 'E'}, {0xc8, 'E'}, {0xc7, 'E'},
838     {0xc2, 'I'}, {0xc3, 'I'}, {0xc8, 'I'}, {0, 0},      {0xcb, 'N'},
839     {0xc5, 'O'}, {0xc2, 'O'}, {0xc3, 'O'}, {0xc4, 'O'}, {0xc8, 'O'},
840     {0xc4, 'U'}, {0xe9, 0},   {0xce, 'U'}, {0xc2, 'U'}, {0xc3, 'U'},
841     {0xc8, 'U'}, {0xc2, 'Y'}, {0xec, 0},   {0xfb, 0},   {0xc5, 'a'},
842     {0xc2, 'a'}, {0xc3, 'a'}, {0xc4, 'a'}, {0xc8, 'a'}, {0xca, 'a'},
843     {0xf1, 0},   {0xce, 'i'}, {0xcf, 'c'}, {0xc2, 'e'}, {0xce, 'e'},
844     {0xc8, 'e'}, {0xc7, 'e'}, {0xc2, 'i'}, {0xc3, 'i'}, {0xc8, 'i'},
845     {0xf3, 0},   {0xcb, 'n'}, {0xc5, 'o'}, {0xc2, 'o'}, {0xc3, 'o'},
846     {0xc4, 'o'}, {0xc8, 'o'}, {0xc4, 'u'}, {0xf9, 0},   {0xce, 'u'},
847     {0xc2, 'u'}, {0xc3, 'u'}, {0xc8, 'u'}, {0xc2, 'y'}, {0xfc, 0},
848     {0xf0, 0}};
849 #    endif
850 
c_to_hh(Byte * o,Byte c)851 static Byte* c_to_hh(Byte* o, Byte c) {
852   Byte n;
853 
854   *o++ = '{';
855   *o++ = 'x';
856   n = c >> 4;
857   *o++ = ((n < 0xA) ? '0' : 'A' - 0xA) + n;
858   n = c & 0x0F;
859   *o++ = ((n < 0xA) ? '0' : 'A' - 0xA) + n;
860   *o++ = '}';
861   return o;
862 }
863 
c_to_cc(Byte * o,Couple * cc,Byte c)864 static Byte* c_to_cc(Byte* o, Couple* cc, Byte c) {
865   if ((*cc).a != 0) {
866     if ((*cc).b == 0)
867       *o++ = (*cc).a;
868     else {
869       *o++ = '{';
870       *o++ = (*cc).a;
871       *o++ = (*cc).b;
872       *o++ = '}';
873     }
874     return o;
875   } else
876     return c_to_hh(o, c);
877 }
878 
879 /* --- routine to convert from T.61 to ISO 8859-n --- */
880 
ldap_t61_to_8859(char ** bufp,unsigned long * buflenp,int free_input)881 int ldap_t61_to_8859(char** bufp, unsigned long* buflenp, int free_input) {
882   Byte *s, *oo, *o;
883   unsigned int n;
884   int c;
885   unsigned long len;
886   Couple* cc;
887 
888   LDAPDebug(LDAP_DEBUG_TRACE, "ldap_t61_to_8859 input length: %ld\n", *buflenp);
889 
890   len = *buflenp;
891   s = (Byte*)*bufp;
892 
893   if ((o = oo = (Byte*)NSLDAPI_MALLOC(2 * len + 64)) == NULL) {
894     return (1);
895   }
896 
897   while ((char*)s - *(char**)bufp < len) {
898     switch (*s >> 4) {
899       case 0xA:
900       case 0xB:
901         o = c_to_cc(o, &trans_t61a_iso8859[*s - 0xA0], *s);
902         s++;
903         break;
904 
905       case 0xD:
906       case 0xE:
907       case 0xF:
908         o = c_to_cc(o, &trans_t61b_iso8859[*s - 0xD0], *s);
909         s++;
910         break;
911 
912       case 0xC:
913         if ((*s == 0xC0) || (*s == 0xC9) || (*s == 0xCC)) {
914           o = c_to_hh(o, *s++);
915           break;
916         }
917 
918         n = (*s++) - 0xC0;
919         switch (*s) {
920           case 'A':
921             c = letter_w_diacritic[n][0];
922             break;
923           case 'C':
924             c = letter_w_diacritic[n][1];
925             break;
926           case 'D':
927             c = letter_w_diacritic[n][2];
928             break;
929           case 'E':
930             c = letter_w_diacritic[n][3];
931             break;
932           case 'G':
933             c = letter_w_diacritic[n][4];
934             break;
935           case 'H':
936             c = letter_w_diacritic[n][5];
937             break;
938           case 'I':
939             c = letter_w_diacritic[n][6];
940             break;
941           case 'J':
942             c = letter_w_diacritic[n][7];
943             break;
944           case 'K':
945             c = letter_w_diacritic[n][8];
946             break;
947           case 'L':
948             c = letter_w_diacritic[n][9];
949             break;
950           case 'N':
951             c = letter_w_diacritic[n][10];
952             break;
953           case 'O':
954             c = letter_w_diacritic[n][11];
955             break;
956           case 'R':
957             c = letter_w_diacritic[n][12];
958             break;
959           case 'S':
960             c = letter_w_diacritic[n][13];
961             break;
962           case 'T':
963             c = letter_w_diacritic[n][14];
964             break;
965           case 'U':
966             c = letter_w_diacritic[n][15];
967             break;
968           case 'W':
969             c = letter_w_diacritic[n][16];
970             break;
971           case 'Y':
972             c = letter_w_diacritic[n][17];
973             break;
974           case 'Z':
975             c = letter_w_diacritic[n][18];
976             break;
977 
978           case 'a':
979             c = letter_w_diacritic[n][19];
980             break;
981           case 'c':
982             c = letter_w_diacritic[n][20];
983             break;
984           case 'd':
985             c = letter_w_diacritic[n][21];
986             break;
987           case 'e':
988             c = letter_w_diacritic[n][22];
989             break;
990           case 'g':
991             c = letter_w_diacritic[n][23];
992             break;
993           case 'h':
994             c = letter_w_diacritic[n][24];
995             break;
996           case 'i':
997             c = letter_w_diacritic[n][25];
998             break;
999           case 'j':
1000             c = letter_w_diacritic[n][26];
1001             break;
1002           case 'k':
1003             c = letter_w_diacritic[n][27];
1004             break;
1005           case 'l':
1006             c = letter_w_diacritic[n][28];
1007             break;
1008           case 'n':
1009             c = letter_w_diacritic[n][29];
1010             break;
1011           case 'o':
1012             c = letter_w_diacritic[n][30];
1013             break;
1014           case 'r':
1015             c = letter_w_diacritic[n][31];
1016             break;
1017           case 's':
1018             c = letter_w_diacritic[n][32];
1019             break;
1020           case 't':
1021             c = letter_w_diacritic[n][33];
1022             break;
1023           case 'u':
1024             c = letter_w_diacritic[n][34];
1025             break;
1026           case 'w':
1027             c = letter_w_diacritic[n][35];
1028             break;
1029           case 'y':
1030             c = letter_w_diacritic[n][36];
1031             break;
1032           case 'z':
1033             c = letter_w_diacritic[n][37];
1034             break;
1035 
1036           case ALONE:
1037             c = ((!diacritic[n].b) ? diacritic[n].a : -1);
1038             break;
1039 
1040           default:
1041             c = 0;
1042         }
1043 
1044         if (c > 0) {
1045           *o++ = c;
1046           s++;
1047         } else {
1048           *o++ = '{';
1049           if (c == -1) {
1050             *o++ = ((*s == ALONE) ? ' ' : *s);
1051             s++;
1052           } else {
1053             *o++ = '"';
1054           }
1055           *o++ = diacritic[n].a;
1056           *o++ = '}';
1057         }
1058         break;
1059 
1060 #    if (ISO_8859 == 0)
1061       case 0x8:
1062       case 0x9:
1063         *o++ = 0x1B; /* <ESC> */
1064         *o++ = *s++ - 0x40;
1065         break;
1066 #    endif
1067 
1068       default:
1069         *o++ = *s++;
1070     }
1071   }
1072 
1073   len = o - oo;
1074   o = oo;
1075 
1076   if ((oo = (Byte*)NSLDAPI_REALLOC(o, len)) == NULL) {
1077     NSLDAPI_FREE(o);
1078     return (1);
1079   }
1080 
1081   if (free_input) {
1082     NSLDAPI_FREE(*bufp);
1083   }
1084   *bufp = (char*)oo;
1085   *buflenp = len;
1086   return (0);
1087 }
1088 
hh_to_c(Byte * h)1089 static int hh_to_c(Byte* h) {
1090   Byte c;
1091 
1092   if ((*h >= '0') && (*h <= '9'))
1093     c = *h++ - '0';
1094   else if ((*h >= 'A') && (*h <= 'F'))
1095     c = *h++ - 'A' + 10;
1096   else if ((*h >= 'a') && (*h <= 'f'))
1097     c = *h++ - 'a' + 10;
1098   else
1099     return -1;
1100 
1101   c <<= 4;
1102 
1103   if ((*h >= '0') && (*h <= '9'))
1104     c |= *h - '0';
1105   else if ((*h >= 'A') && (*h <= 'F'))
1106     c |= *h - 'A' + 10;
1107   else if ((*h >= 'a') && (*h <= 'f'))
1108     c |= *h - 'a' + 10;
1109   else
1110     return -1;
1111 
1112   return c;
1113 }
1114 
cc_to_t61(Byte * o,Byte * s)1115 static Byte* cc_to_t61(Byte* o, Byte* s) {
1116   int n, c = 0;
1117 
1118   switch (*(s + 1)) {
1119     case '`':
1120       c = -1;
1121       break; /* <grave-accent> */
1122 
1123     case '!':
1124       switch (*s) {
1125         case '!':
1126           c = 0x7C;
1127           break; /* <vertical-line> */
1128         case '(':
1129           c = 0x7B;
1130           break; /* <left-curly-bracket> */
1131         case '-':
1132           c = 0xAD;
1133           break; /* <upwards-arrow> */
1134         default:
1135           c = -1; /* <grave-accent> */
1136       }
1137       break;
1138 
1139 #    if (ISO_8859 == 1) || (ISO_8859 == 2) || (ISO_8859 == 3) || \
1140         (ISO_8859 == 4) || (ISO_8859 == 9)
1141     case 0xB4:
1142 #    endif
1143     case '\'':
1144       c = -2;
1145       break; /* <acute-accent> */
1146 
1147     case '^':
1148       c = -3;
1149       break; /* <circumflex-acent> */
1150 
1151     case '>':
1152       switch (*s) {
1153         case ')':
1154           c = 0x5D;
1155           break; /* <right-square-bracket> */
1156         case '>':
1157           c = 0xBB;
1158           break; /* <right-angle-quotation> */
1159         case '-':
1160           c = 0xAE;
1161           break; /* <rightwards-arrow> */
1162         default:
1163           c = -3; /* <circumflex-acent> */
1164       }
1165       break;
1166 
1167     case '~':
1168     case '?':
1169       c = -4;
1170       break; /* <tilde> */
1171 
1172 #    if (ISO_8859 == 1) || (ISO_8859 == 4) || (ISO_8859 == 9)
1173     case 0xAF:
1174       c = -5;
1175       break; /* <macron> */
1176 #    endif
1177 
1178     case '-':
1179       switch (*s) {
1180         case '-':
1181           c = 0xFF;
1182           break; /* <soft-hyphen> */
1183         case '<':
1184           c = 0xAC;
1185           break; /* <leftwards arrow> */
1186         case '+':
1187           c = 0xB1;
1188           break; /* <plus-minus> */
1189         case 'd':
1190           c = 0xF3;
1191           break; /* <eth> */
1192         default:
1193           c = -5; /* <macron> */
1194       }
1195       break;
1196 
1197 #    if (ISO_8859 == 2) || (ISO_8859 == 3)
1198     case 0xA2:
1199       c = -6;
1200       break; /* <breve> */
1201 #    endif
1202 
1203     case '(':
1204       if (*s == '<')
1205         c = 0x5B; /* <left-square-bracket> */
1206       else
1207         c = -6; /* <breve> */
1208       break;
1209 
1210 #    if (ISO_8859 == 2) || (ISO_8859 == 3) || (ISO_8859 == 4)
1211     case 0xFF:
1212       c = -7;
1213       break; /* <dot-accent> */
1214 #    endif
1215 
1216     case '.':
1217       switch (*s) {
1218         case 'i':
1219           c = 0xF5;
1220           break; /* <dotless-i> */
1221         case 'L':
1222           c = 0xE7;
1223           break; /* <L-middle-dot> */
1224         case 'l':
1225           c = 0xF7;
1226           break; /* <l-middle-dot> */
1227         default:
1228           c = -7; /* <dot-accent> */
1229       }
1230       break;
1231 
1232 #    if (ISO_8859 == 1) || (ISO_8859 == 2) || (ISO_8859 == 3) || \
1233         (ISO_8859 == 4) || (ISO_8859 == 9)
1234     case 0xA8:
1235       c = -8;
1236       break; /* <diaeresis> */
1237 #    endif
1238 
1239     case ':':
1240       if (*s == '-')
1241         c = 0xB8; /* <division-sign> */
1242       else
1243         c = -8; /* <diaeresis> */
1244       break;
1245 
1246 #    if (ISO_8859 == 1) || (ISO_8859 == 2) || (ISO_8859 == 3) || \
1247         (ISO_8859 == 4) || (ISO_8859 == 9) || (ISO_8859 == 10)
1248     case 0xB0:
1249 #    endif
1250     case '0':
1251       c = -10;
1252       break; /* <ring-above> */
1253 
1254 #    if (ISO_8859 == 1) || (ISO_8859 == 2) || (ISO_8859 == 3) || \
1255         (ISO_8859 == 4) || (ISO_8859 == 9)
1256     case 0xB8:
1257 #    endif
1258     case ',':
1259       c = -11;
1260       break; /* <cedilla> */
1261 
1262 #    if (ISO_8859 == 2)
1263     case 0xBD:
1264 #    endif
1265     case '"':
1266       c = -13;
1267       break; /* <double-acute-accent> */
1268 
1269 #    if (ISO_8859 == 2) || (ISO_8859 == 4)
1270     case 0xB2:
1271 #    endif
1272     case ';':
1273       c = -14;
1274       break; /* <ogonek> */
1275 
1276 #    if (ISO_8859 == 2) || (ISO_8859 == 4)
1277     case 0xB7:
1278       c = -15;
1279       break; /* <caron> */
1280 #    endif
1281 
1282     case ')':
1283       if (*s == '!') c = 0x7D; /* <left-curly-bracket> */
1284       break;
1285 
1286     case '<':
1287       if (*s == '<')
1288         c = 0xAB; /* <left-angle-quotation> */
1289       else
1290         c = -15; /* <caron> */
1291       break;
1292 
1293     case '/':
1294       switch (*s) {
1295         case '/':
1296           c = 0x5C;
1297           break; /* <reverse-solidus> */
1298         case 'D':
1299           c = 0xE2;
1300           break; /* <D-stroke> */
1301         case 'd':
1302           c = 0xF2;
1303           break; /* <d-stroke> */
1304         case 'H':
1305           c = 0xE4;
1306           break; /* <H-stroke> */
1307         case 'h':
1308           c = 0xF4;
1309           break; /* <h-stroke> */
1310         case 'L':
1311           c = 0xE8;
1312           break; /* <L-stroke> */
1313         case 'l':
1314           c = 0xF8;
1315           break; /* <l-stroke> */
1316         case 'O':
1317           c = 0xE9;
1318           break; /* <O-stroke> */
1319         case 'o':
1320           c = 0xF9;
1321           break; /* <o-stroke> */
1322         case 'T':
1323           c = 0xED;
1324           break; /* <T-stroke> */
1325         case 't':
1326           c = 0xFD;
1327           break; /* <t-stroke> */
1328       }
1329       break;
1330 
1331     case '2':
1332       if (*s == '1') c = 0xBD; /* <one-half> */
1333       break;
1334 
1335     case '4':
1336       switch (*s) {
1337         case '1':
1338           c = 0xBC;
1339           break; /* <one-quarter> */
1340         case '3':
1341           c = 0xBE;
1342           break; /* <three-quarters> */
1343       }
1344       break;
1345 
1346     case '6':
1347       switch (*s) {
1348         case '\'':
1349           c = 0xA9;
1350           break; /* <left-single-quotation> */
1351         case '"':
1352           c = 0xAA;
1353           break; /* <left-double-quotation> */
1354       }
1355       break;
1356 
1357     case '8':
1358       switch (*s) {
1359         case '1':
1360           c = 0xDC;
1361           break; /* <one-eighth> */
1362         case '3':
1363           c = 0xDD;
1364           break; /* <three-eighths> */
1365         case '5':
1366           c = 0xDE;
1367           break; /* <five-eighths> */
1368         case '7':
1369           c = 0xDF;
1370           break; /* <seven-eighths> */
1371         case 'M':
1372           c = 0xD5;
1373           break; /* <eighth-note> */
1374       }
1375       break;
1376 
1377     case '9':
1378       switch (*s) {
1379         case '\'':
1380           c = 0xB9;
1381           break; /* <right-single-quotation> */
1382         case '"':
1383           c = 0xBA;
1384           break; /* <right-double-quotation> */
1385       }
1386       break;
1387 
1388     case 'A':
1389       if (*s == 'A') c = -10; /* <ring-above> + <A> */
1390       break;
1391 
1392     case 'a':
1393       switch (*s) {
1394         case '-':
1395           c = 0xE3;
1396           break; /* <femenine-ordinal-a> */
1397         case 'a':
1398           c = -10;
1399           break; /* <ring-above> + <a> */
1400       }
1401       break;
1402 
1403     case 'B':
1404       if (*s == 'B') c = 0xD7; /* <broken-bar> */
1405       break;
1406 
1407     case 'b':
1408       if (*s == 'N') c = 0xA6; /* <number-sign> */
1409       break;
1410 
1411     case 'd':
1412       if (*s == 'P') c = 0xA3; /* <pound-sign> */
1413       break;
1414 
1415     case 'E':
1416       switch (*s) {
1417         case 'S':
1418           c = 0xA7;
1419           break; /* <section-sign> */
1420         case 'A':
1421           c = 0xE1;
1422           break; /* <AE> */
1423         case 'O':
1424           c = 0xEA;
1425           break; /* <OE> */
1426       }
1427       break;
1428 
1429     case 'e':
1430       switch (*s) {
1431         case 'a':
1432           c = 0xF1;
1433           break; /* <ae> */
1434         case 'o':
1435           c = 0xFA;
1436           break; /* <oe> */
1437         case 'Y':
1438           c = 0xA5;
1439           break; /* <yen-sign> */
1440       }
1441       break;
1442 
1443     case 'G':
1444       switch (*s) {
1445         case 'D':
1446           c = 0xB0;
1447           break; /* <degree-sign> */
1448         case 'N':
1449           c = 0xEE;
1450           break; /* <Eng> */
1451       }
1452       break;
1453 
1454     case 'g':
1455       switch (*s) {
1456         case 'R':
1457           c = 0xD2;
1458           break; /* <registered-sign> */
1459         case 'n':
1460           c = 0xFE;
1461           break; /* <eng> */
1462       }
1463       break;
1464 
1465     case 'H':
1466       if (*s == 'T') c = 0xEC; /* <Thorn> */
1467       break;
1468 
1469     case 'h':
1470       if (*s == 't') c = 0xFC; /* <thorn> */
1471       break;
1472 
1473     case 'I':
1474       switch (*s) {
1475         case 'P':
1476           c = 0xB6;
1477           break; /* <pilcrow-sign> */
1478         case '!':
1479           c = 0xA1;
1480           break; /* <inverted-exclamation> */
1481         case '?':
1482           c = 0xBF;
1483           break; /* <inverted-question> */
1484       }
1485       break;
1486 
1487     case 'J':
1488       if (*s == 'I') c = 0xE6; /* <IJ> */
1489       break;
1490 
1491     case 'j':
1492       if (*s == 'i') c = 0xF6; /* <ij> */
1493       break;
1494 
1495     case 'k':
1496       if (*s == 'k') c = 0xF0; /* <kra> */
1497       break;
1498 
1499     case 'M':
1500       switch (*s) {
1501         case '.':
1502           c = 0xB7;
1503           break; /* <middle-dot> */
1504         case '-':
1505           c = 0xD0;
1506           break; /* <em-dash> */
1507         case 'T':
1508           c = 0xD4;
1509           break; /* <trade-mark-sign> */
1510       }
1511       break;
1512 
1513     case 'm':
1514       switch (*s) {
1515         case '\'': /* <macron> RFC 1345 */
1516         case ' ':
1517           c = -5;
1518           break; /* <macron> */
1519         case 'O':
1520           c = 0xE0;
1521           break; /* <Ohm sign> */
1522       }
1523       break;
1524 
1525     case 'n':
1526       if (*s == '\'') c = 0xEF; /* <n-preceded-by-apostrophe> */
1527       break;
1528 
1529     case 'O':
1530       switch (*s) {
1531         case 'D':
1532           c = 0xA4;
1533           break; /* <dollar-sign> */
1534         case 'N':
1535           c = 0xD6;
1536           break; /* <not-sign> */
1537       }
1538       break;
1539 
1540     case 'o':
1541       switch (*s) {
1542         case 'C':
1543           c = 0xD3;
1544           break; /* <copyright-sign> */
1545         case '-':
1546           c = 0xEB;
1547           break; /* <masculine-ordinal-o> */
1548       }
1549       break;
1550 
1551     case 'S':
1552       switch (*s) {
1553         case '1':
1554           c = 0xD1;
1555           break; /* <superscript-1> */
1556         case '2':
1557           c = 0xB2;
1558           break; /* <superscript-2> */
1559         case '3':
1560           c = 0xB3;
1561           break; /* <superscript-3> */
1562         case 'N':
1563           c = 0xA0;
1564           break; /* <no-break-space> */
1565       }
1566       break;
1567 
1568     case 's':
1569       if (*s == 's') c = 0xFB; /* <sharp-s> */
1570       break;
1571 
1572     case 't':
1573       if (*s == 'C') c = 0xA2; /* <cent-sign> */
1574       break;
1575 
1576     case 'u':
1577       if (*s == 'C') c = 0xA8; /* <currency-sign> */
1578       break;
1579 
1580     case 'v':
1581       if (*s == '-') c = 0xAF; /* <downwards-arrow> */
1582       break;
1583 
1584     case 'X':
1585       if (*s == '*') c = 0xB4; /* <multiplication-sign> */
1586       break;
1587 
1588     case 'y':
1589       if (*s == 'M') c = 0xB5; /* <micro-sign> */
1590       break;
1591   }
1592 
1593   if (c > 0) {
1594     *o++ = c;
1595     return o;
1596   } else if (!c)
1597     return NULL;
1598 
1599   /* else: c < 0 */
1600   n = -c;
1601   switch (*s) {
1602     case 'A':
1603       c = letter_w_diacritic[n][0];
1604       break;
1605     case 'C':
1606       c = letter_w_diacritic[n][1];
1607       break;
1608     case 'D':
1609       c = letter_w_diacritic[n][2];
1610       break;
1611     case 'E':
1612       c = letter_w_diacritic[n][3];
1613       break;
1614     case 'G':
1615       c = letter_w_diacritic[n][4];
1616       break;
1617     case 'H':
1618       c = letter_w_diacritic[n][5];
1619       break;
1620     case 'I':
1621       c = letter_w_diacritic[n][6];
1622       break;
1623     case 'J':
1624       c = letter_w_diacritic[n][7];
1625       break;
1626     case 'K':
1627       c = letter_w_diacritic[n][8];
1628       break;
1629     case 'L':
1630       c = letter_w_diacritic[n][9];
1631       break;
1632     case 'N':
1633       c = letter_w_diacritic[n][10];
1634       break;
1635     case 'O':
1636       c = letter_w_diacritic[n][11];
1637       break;
1638     case 'R':
1639       c = letter_w_diacritic[n][12];
1640       break;
1641     case 'S':
1642       c = letter_w_diacritic[n][13];
1643       break;
1644     case 'T':
1645       c = letter_w_diacritic[n][14];
1646       break;
1647     case 'U':
1648       c = letter_w_diacritic[n][15];
1649       break;
1650     case 'W':
1651       c = letter_w_diacritic[n][16];
1652       break;
1653     case 'Y':
1654       c = letter_w_diacritic[n][17];
1655       break;
1656     case 'Z':
1657       c = letter_w_diacritic[n][18];
1658       break;
1659 
1660     case 'a':
1661       c = letter_w_diacritic[n][19];
1662       break;
1663     case 'c':
1664       c = letter_w_diacritic[n][20];
1665       break;
1666     case 'd':
1667       c = letter_w_diacritic[n][21];
1668       break;
1669     case 'e':
1670       c = letter_w_diacritic[n][22];
1671       break;
1672     case 'g':
1673       c = letter_w_diacritic[n][23];
1674       break;
1675     case 'h':
1676       c = letter_w_diacritic[n][24];
1677       break;
1678     case 'i':
1679       c = letter_w_diacritic[n][25];
1680       break;
1681     case 'j':
1682       c = letter_w_diacritic[n][26];
1683       break;
1684     case 'k':
1685       c = letter_w_diacritic[n][27];
1686       break;
1687     case 'l':
1688       c = letter_w_diacritic[n][28];
1689       break;
1690     case 'n':
1691       c = letter_w_diacritic[n][29];
1692       break;
1693     case 'o':
1694       c = letter_w_diacritic[n][30];
1695       break;
1696     case 'r':
1697       c = letter_w_diacritic[n][31];
1698       break;
1699     case 's':
1700       c = letter_w_diacritic[n][32];
1701       break;
1702     case 't':
1703       c = letter_w_diacritic[n][33];
1704       break;
1705     case 'u':
1706       c = letter_w_diacritic[n][34];
1707       break;
1708     case 'w':
1709       c = letter_w_diacritic[n][35];
1710       break;
1711     case 'y':
1712       c = letter_w_diacritic[n][36];
1713       break;
1714     case 'z':
1715       c = letter_w_diacritic[n][37];
1716       break;
1717 
1718     case '\'':
1719     case ' ':
1720       c = -1;
1721       break;
1722 
1723     default:
1724       c = 0;
1725   }
1726 
1727   if (!c) return NULL;
1728 
1729   *o++ = n + 0xC0;
1730   *o++ = (((*s == ' ') || (*s == '\'')) ? ALONE : *s);
1731   return o;
1732 }
1733 
1734 /* --- routine to convert from ISO 8859-n to T.61 --- */
1735 
ldap_8859_to_t61(char ** bufp,unsigned long * buflenp,int free_input)1736 int ldap_8859_to_t61(char** bufp, unsigned long* buflenp, int free_input) {
1737   Byte *s, *oo, *o, *aux;
1738   int c;
1739   unsigned long len;
1740   Couple* cc;
1741 
1742   LDAPDebug(LDAP_DEBUG_TRACE, "ldap_8859_to_t61 input length: %ld\n", *buflenp);
1743 
1744   len = *buflenp;
1745   s = (Byte*)*bufp;
1746 
1747   if ((o = oo = (Byte*)NSLDAPI_MALLOC(2 * len + 64)) == NULL) {
1748     return (1);
1749   }
1750 
1751   while ((char*)s - *(char**)bufp < len) {
1752     switch (*s >> 5) {
1753       case 2:
1754         switch (*s) {
1755           case '^':
1756             *o++ = 0xC3;
1757             *o++ = ALONE;
1758             s++;
1759             break;
1760 
1761           case '\\':
1762             s++;
1763             if ((c = hh_to_c(s)) != -1) {
1764               *o++ = c;
1765               s += 2;
1766             } else
1767               *o++ = '\\';
1768             break;
1769 
1770           default:
1771             *o++ = *s++;
1772         }
1773         break;
1774 
1775       case 3:
1776         switch (*s) {
1777           case '`':
1778             *o++ = 0xC1;
1779             *o++ = ALONE;
1780             s++;
1781             break;
1782           case '~':
1783             *o++ = 0xC4;
1784             *o++ = ALONE;
1785             s++;
1786             break;
1787 
1788           case '{':
1789             s++;
1790             if (*(s + 2) == '}') {
1791               if ((aux = cc_to_t61(o, s)) != NULL) {
1792                 o = aux;
1793                 s += 3;
1794               } else {
1795                 *o++ = '{';
1796               }
1797             } else if ((*(s + 3) == '}') && ((*s == 'x') || (*s == 'X')) &&
1798                        ((c = hh_to_c(s + 1)) != -1)) {
1799               *o++ = c;
1800               s += 4;
1801             } else {
1802               *o++ = '{';
1803             }
1804             break;
1805 
1806           default:
1807             *o++ = *s++;
1808         }
1809         break;
1810 
1811 #    if (ISO_8859 == 0)
1812       case 4:
1813       case 5:
1814       case 6:
1815       case 7:
1816         s++;
1817         break;
1818 #    else
1819       case 5:
1820       case 6:
1821       case 7:
1822 #      if (ISO_8859 == 1) || (ISO_8859 == 2) || (ISO_8859 == 3) || \
1823           (ISO_8859 == 4) || (ISO_8859 == 9) || (ISO_8859 == 10)
1824         if ((*(cc = &trans_iso8859_t61[*s - 0xA0])).a) {
1825           *o++ = (*cc).a;
1826           if ((*cc).b) *o++ = (*cc).b;
1827         }
1828 #      endif
1829         s++;
1830         break;
1831 #    endif
1832 
1833       default:
1834         *o++ = *s++;
1835     }
1836   }
1837 
1838   len = o - oo;
1839   o = oo;
1840 
1841   if ((oo = (Byte*)NSLDAPI_REALLOC(o, len)) == NULL) {
1842     NSLDAPI_FREE(o);
1843     return (1);
1844   }
1845 
1846   if (free_input) {
1847     NSLDAPI_FREE(*bufp);
1848   }
1849   *bufp = (char*)oo;
1850   *buflenp = len;
1851   return (0);
1852 }
1853 
1854 #    ifdef NOT_NEEDED_IN_LIBLDAP /* mcs@umich.edu 12 Oct 1995 */
1855 /* --- routine to convert "escaped" (\hh) characters to 8bits --- */
1856 
convert_escaped_to_8bit(s)1857 void convert_escaped_to_8bit(s) char* s;
1858 {
1859   char* o = s;
1860   int c;
1861 
1862   while (*s) {
1863     if (*s == '\\') {
1864       if ((c = hh_to_c(++s)) != -1) {
1865         *o++ = c;
1866         s += 2;
1867       } else
1868         *o++ = '\\';
1869     } else
1870       *o++ = *s++;
1871   }
1872   *o = '\0';
1873 }
1874 
1875 /* --- routine to convert 8bits characters to the "escaped" (\hh) form --- */
1876 
convert_8bit_to_escaped(s)1877 char* convert_8bit_to_escaped(s) Byte* s;
1878 {
1879   Byte *o, *oo;
1880   Byte n;
1881 
1882   if ((o = oo = (Byte*)NSLDAPI_MALLOC(2 * strlen(s) + 64)) == NULL) {
1883     return (NULL);
1884   }
1885 
1886   while (*s) {
1887     if (*s < 0x80)
1888       *o++ = *s++;
1889     else {
1890       *o++ = '\\';
1891       n = *s >> 4;
1892       *o++ = ((n < 0xA) ? '0' : 'A' - 0xA) + n;
1893       n = *s++ & 0x0F;
1894       *o++ = ((n < 0xA) ? '0' : 'A' - 0xA) + n;
1895     }
1896   }
1897   *o = '\0';
1898 
1899   o = oo;
1900 
1901   if ((oo = (Byte*)NSLDAPI_REALLOC(o, strlen(o) + 1)) == NULL) {
1902     NSLDAPI_FREE(o);
1903     return (NULL);
1904   }
1905 
1906   return ((char*)oo);
1907 }
1908 
1909 /* --- routine to convert from T.61 to printable characters --- */
1910 
1911 /*
1912    printable characters [RFC 1488]: 'A'..'Z', 'a'..'z', '0'..'9',
1913        '\'', '(', ')', '+', ',', '-', '.', '/', ':', '?, ' '.
1914 
1915    that conversion is language dependent.
1916 */
1917 
1918 static Couple last_t61_printabled[32] = {
1919     {0, 0},     {'A', 'E'}, {'D', 0},   {0, 0},     {'H', 0},   {0, 0},
1920     {'I', 'J'}, {'L', 0},   {'L', 0},   {'O', 0},   {'O', 'E'}, {0, 0},
1921     {'T', 'H'}, {'T', 0},   {'N', 'G'}, {'n', 0},   {'k', 0},   {'a', 'e'},
1922     {'d', 0},   {'d', 0},   {'h', 0},   {'i', 0},   {'i', 'j'}, {'l', 0},
1923     {'l', 0},   {'o', 0},   {'o', 'e'}, {'s', 's'}, {'t', 'h'}, {'t', 0},
1924     {'n', 'g'}, {0, 0}};
1925 
t61_printable(s)1926 char* t61_printable(s) Byte* s;
1927 {
1928   Byte *o, *oo;
1929   Byte n;
1930   Couple* cc;
1931 
1932   if ((o = oo = (Byte*)NSLDAPI_MALLOC(2 * strlen(s) + 64)) == NULL) {
1933     return (NULL);
1934   }
1935 
1936   while (*s) {
1937     if (((*s >= 'A') && (*s <= 'Z')) || ((*s >= 'a') && (*s <= 'z')) ||
1938         ((*s >= '0') && (*s <= '9')) || ((*s >= '\'') && (*s <= ')')) ||
1939         ((*s >= '+') && (*s <= '/')) || (*s == '?') || (*s == ' '))
1940       *o++ = *s++;
1941     else {
1942       if (*s >= 0xE0) {
1943         if ((*(cc = &last_t61_printabled[*s - 0xE0])).a) {
1944           *o++ = (*cc).a;
1945           if ((*cc).b) *o++ = (*cc).b;
1946         }
1947       } else if ((*s >> 4) == 0xC) {
1948         switch (*s) {
1949           case 0xCA: /* ring */
1950             switch (*(s + 1)) {
1951               case 'A':
1952                 *o++ = 'A';
1953                 *o++ = 'A';
1954                 s++;
1955                 break; /* Swedish */
1956               case 'a':
1957                 *o++ = 'a';
1958                 *o++ = 'a';
1959                 s++;
1960                 break; /* Swedish */
1961             }
1962             break;
1963 
1964           case 0xC8: /* diaeresis */
1965             switch (*(s + 1)) {
1966               case 'Y':
1967                 *o++ = 'I';
1968                 *o++ = 'J';
1969                 s++;
1970                 break; /* Dutch */
1971               case 'y':
1972                 *o++ = 'i';
1973                 *o++ = 'j';
1974                 s++;
1975                 break; /* Dutch */
1976             }
1977             break;
1978         }
1979       }
1980       s++;
1981     }
1982   }
1983   *o = '\0';
1984 
1985   o = oo;
1986 
1987   if ((oo = (Byte*)NSLDAPI_REALLOC(o, strlen(o) + 1)) == NULL) {
1988     NSLDAPI_FREE(o);
1989     return (NULL);
1990   }
1991 
1992   return ((char*)oo);
1993 }
1994 #    endif /* NOT_NEEDED_IN_LIBLDAP */ /* mcs@umich.edu 12 Oct 1995 */
1995 
1996 #  endif /* LDAP_CHARSET_8859 */
1997 #endif   /* STR_TRANSLATION */
1998