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