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