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