* g10.c (i18n_init) [W32]: Pass registry key to gettext
[gnupg.git] / util / strgutil.c
1 /* strgutil.c -  string utilities
2  * Copyright (C) 1994, 1998, 1999, 2000, 2001,
3  *               2003, 2004, 2005 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <errno.h>
27 #ifdef HAVE_LANGINFO_CODESET
28 #include <langinfo.h>
29 #endif
30
31 /* For W32 we use dynamic loading of the iconv dll and don't need any
32  * iconv headers at all. */
33 #ifndef _WIN32
34 # ifndef HAVE_ICONV
35 #  undef USE_GNUPG_ICONV
36 # endif
37 #endif
38
39 #ifdef USE_GNUPG_ICONV
40 # include <limits.h>
41 # ifndef _WIN32
42 #  include <iconv.h>
43 # endif
44 #endif
45
46 #include "types.h"
47 #include "util.h"
48 #include "memory.h"
49 #include "i18n.h"
50 #include "dynload.h"
51
52
53 #ifndef USE_GNUPG_ICONV
54 static ushort koi8_unicode[128] = {
55     0x2500,0x2502,0x250c,0x2510,0x2514,0x2518,0x251c,0x2524,
56     0x252c,0x2534,0x253c,0x2580,0x2584,0x2588,0x258c,0x2590,
57     0x2591,0x2592,0x2593,0x2320,0x25a0,0x2219,0x221a,0x2248,
58     0x2264,0x2265,0x00a0,0x2321,0x00b0,0x00b2,0x00b7,0x00f7,
59     0x2550,0x2551,0x2552,0x0451,0x2553,0x2554,0x2555,0x2556,
60     0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,
61     0x255f,0x2560,0x2561,0x0401,0x2562,0x2563,0x2564,0x2565,
62     0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x00a9,
63     0x044e,0x0430,0x0431,0x0446,0x0434,0x0435,0x0444,0x0433,
64     0x0445,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,
65     0x043f,0x044f,0x0440,0x0441,0x0442,0x0443,0x0436,0x0432,
66     0x044c,0x044b,0x0437,0x0448,0x044d,0x0449,0x0447,0x044a,
67     0x042e,0x0410,0x0411,0x0426,0x0414,0x0415,0x0424,0x0413,
68     0x0425,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,
69     0x041f,0x042f,0x0420,0x0421,0x0422,0x0423,0x0416,0x0412,
70     0x042c,0x042b,0x0417,0x0428,0x042d,0x0429,0x0427,0x042a
71 };
72
73 static ushort latin2_unicode[128] = {
74     0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
75     0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,
76     0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
77     0x0098,0x0099,0x009A,0x009B,0x009C,0x009D,0x009E,0x009F,
78     0x00A0,0x0104,0x02D8,0x0141,0x00A4,0x013D,0x015A,0x00A7,
79     0x00A8,0x0160,0x015E,0x0164,0x0179,0x00AD,0x017D,0x017B,
80     0x00B0,0x0105,0x02DB,0x0142,0x00B4,0x013E,0x015B,0x02C7,
81     0x00B8,0x0161,0x015F,0x0165,0x017A,0x02DD,0x017E,0x017C,
82     0x0154,0x00C1,0x00C2,0x0102,0x00C4,0x0139,0x0106,0x00C7,
83     0x010C,0x00C9,0x0118,0x00CB,0x011A,0x00CD,0x00CE,0x010E,
84     0x0110,0x0143,0x0147,0x00D3,0x00D4,0x0150,0x00D6,0x00D7,
85     0x0158,0x016E,0x00DA,0x0170,0x00DC,0x00DD,0x0162,0x00DF,
86     0x0155,0x00E1,0x00E2,0x0103,0x00E4,0x013A,0x0107,0x00E7,
87     0x010D,0x00E9,0x0119,0x00EB,0x011B,0x00ED,0x00EE,0x010F,
88     0x0111,0x0144,0x0148,0x00F3,0x00F4,0x0151,0x00F6,0x00F7,
89     0x0159,0x016F,0x00FA,0x0171,0x00FC,0x00FD,0x0163,0x02D9
90 };
91 #endif /*!USE_GNUPG_ICONV*/
92
93
94 #ifndef MB_LEN_MAX
95 #define MB_LEN_MAX 16
96 #endif
97
98
99 static const char *active_charset_name = "iso-8859-1";
100 static ushort *active_charset = NULL;
101 static int no_translation = 0;
102 static int use_iconv = 0;
103
104
105 #ifdef _WIN32
106 typedef void* iconv_t;
107 #ifndef ICONV_CONST
108 #define ICONV_CONST const 
109 #endif
110
111 iconv_t (* __stdcall iconv_open) (const char *tocode, const char *fromcode);
112 size_t  (* __stdcall iconv) (iconv_t cd,
113                              const char **inbuf, size_t *inbytesleft,
114                              char **outbuf, size_t *outbytesleft);
115 int     (* __stdcall iconv_close) (iconv_t cd);
116
117 #endif /*_WIN32*/
118
119
120
121 #ifdef _WIN32
122 static int 
123 load_libiconv (void)
124 {
125   static int done;
126   
127   if (!done)
128     {
129       void *handle;
130
131       done = 1; /* Do it right now because we might get called recursivly
132                    through gettext.  */
133     
134       handle = dlopen ("iconv.dll", RTLD_LAZY);
135       if (handle)
136         {
137           iconv_open  = dlsym (handle, "libiconv_open");
138           if (iconv_open)
139             iconv      = dlsym (handle, "libiconv");
140           if (iconv)    
141             iconv_close = dlsym (handle, "libiconv_close");
142         }
143       if (!handle || !iconv_close)
144         {
145           log_info (_("error loading `%s': %s\n"),
146                      "iconv.dll",  dlerror ());
147           log_info(_("please see http://www.gnupg.org/download/iconv.html "
148                      "for more information\n"));
149           iconv_open = NULL;
150           iconv = NULL;
151           iconv_close = NULL;
152           if (handle)
153               dlclose (handle);
154         }
155     }
156   return iconv_open? 0: -1;
157 }    
158 #endif /* _WIN32 */
159
160
161
162
163 void
164 free_strlist( STRLIST sl )
165 {
166     STRLIST sl2;
167
168     for(; sl; sl = sl2 ) {
169         sl2 = sl->next;
170         m_free(sl);
171     }
172 }
173
174
175 STRLIST
176 add_to_strlist( STRLIST *list, const char *string )
177 {
178     STRLIST sl;
179
180     sl = m_alloc( sizeof *sl + strlen(string));
181     sl->flags = 0;
182     strcpy(sl->d, string);
183     sl->next = *list;
184     *list = sl;
185     return sl;
186 }
187
188 /****************
189  * Same as add_to_strlist() but if is_utf8 is *not* set a conversion
190  * to UTF8 is done
191  */
192 STRLIST
193 add_to_strlist2( STRLIST *list, const char *string, int is_utf8 )
194 {
195     STRLIST sl;
196
197     if( is_utf8 )
198         sl = add_to_strlist( list, string );
199     else {
200         char *p = native_to_utf8( string );
201         sl = add_to_strlist( list, p );
202         m_free( p );
203     }
204     return sl;
205 }
206
207 STRLIST
208 append_to_strlist( STRLIST *list, const char *string )
209 {
210     STRLIST r, sl;
211
212     sl = m_alloc( sizeof *sl + strlen(string));
213     sl->flags = 0;
214     strcpy(sl->d, string);
215     sl->next = NULL;
216     if( !*list )
217         *list = sl;
218     else {
219         for( r = *list; r->next; r = r->next )
220             ;
221         r->next = sl;
222     }
223     return sl;
224 }
225
226 STRLIST
227 append_to_strlist2( STRLIST *list, const char *string, int is_utf8 )
228 {
229     STRLIST sl;
230
231     if( is_utf8 )
232         sl = append_to_strlist( list, string );
233     else {
234         char *p = native_to_utf8( string );
235         sl = append_to_strlist( list, p );
236         m_free( p );
237     }
238     return sl;
239 }
240
241
242 STRLIST
243 strlist_prev( STRLIST head, STRLIST node )
244 {
245     STRLIST n;
246
247     for(n=NULL; head && head != node; head = head->next )
248         n = head;
249     return n;
250 }
251
252 STRLIST
253 strlist_last( STRLIST node )
254 {
255     if( node )
256         for( ; node->next ; node = node->next )
257             ;
258     return node;
259 }
260
261 char *
262 pop_strlist( STRLIST *list )
263 {
264   char *str=NULL;
265   STRLIST sl=*list;
266
267   if(sl)
268     {
269       str=m_alloc(strlen(sl->d)+1);
270       strcpy(str,sl->d);
271
272       *list=sl->next;
273       m_free(sl);
274     }
275
276   return str;
277 }
278
279 /****************
280  * Look for the substring SUB in buffer and return a pointer to that
281  * substring in BUF or NULL if not found.
282  * Comparison is case-insensitive.
283  */
284 const char *
285 memistr( const char *buf, size_t buflen, const char *sub )
286 {
287     const byte *t, *s ;
288     size_t n;
289
290     for( t=buf, n=buflen, s=sub ; n ; t++, n-- )
291         if( toupper(*t) == toupper(*s) ) {
292             for( buf=t++, buflen = n--, s++;
293                  n && toupper(*t) == toupper(*s); t++, s++, n-- )
294                 ;
295             if( !*s )
296                 return buf;
297             t = buf; n = buflen; s = sub ;
298         }
299
300     return NULL ;
301 }
302
303 const char *
304 ascii_memistr( const char *buf, size_t buflen, const char *sub )
305 {
306     const byte *t, *s ;
307     size_t n;
308
309     for( t=buf, n=buflen, s=sub ; n ; t++, n-- )
310         if( ascii_toupper(*t) == ascii_toupper(*s) ) {
311             for( buf=t++, buflen = n--, s++;
312                  n && ascii_toupper(*t) == ascii_toupper(*s); t++, s++, n-- )
313                 ;
314             if( !*s )
315                 return buf;
316             t = buf; n = buflen; s = sub ;
317         }
318
319     return NULL ;
320 }
321
322
323 /* Like strncpy() but copy at max N-1 bytes and append a '\0'.  With
324  * N given as 0 nothing is copied at all. With DEST given as NULL
325  * sufficient memory is allocated using m_alloc (note that m_alloc is
326  * guaranteed to succeed or to abort the process).  */
327 char *
328 mem2str( char *dest , const void *src , size_t n )
329 {
330     char *d;
331     const char *s;
332
333     if( n ) {
334         if( !dest )
335             dest = m_alloc( n ) ;
336         d = dest;
337         s = src ;
338         for(n--; n && *s; n-- )
339             *d++ = *s++;
340         *d = '\0' ;
341     }
342
343     return dest ;
344 }
345
346
347 /*
348  * Remove leading and trailing white spaces
349  */
350 char *
351 trim_spaces( char *str )
352 {
353     char *string, *p, *mark;
354
355     string = str;
356     /* Find first non space character. */
357     for( p=string; *p && isspace( *(byte*)p ) ; p++ )
358         ;
359     /* Move characters. */
360     for( (mark = NULL); (*string = *p); string++, p++ )
361         if( isspace( *(byte*)p ) ) {
362             if( !mark )
363                 mark = string ;
364         }
365         else
366             mark = NULL ;
367     if( mark )
368         *mark = '\0' ;  /* Remove trailing spaces.  */
369
370     return str ;
371 }
372
373
374
375 unsigned int
376 trim_trailing_chars( byte *line, unsigned len, const char *trimchars )
377 {
378     byte *p, *mark;
379     unsigned n;
380
381     for(mark=NULL, p=line, n=0; n < len; n++, p++ ) {
382         if( strchr(trimchars, *p ) ) {
383             if( !mark )
384                 mark = p;
385         }
386         else
387             mark = NULL;
388     }
389
390     if( mark ) {
391         *mark = 0;
392         return mark - line;
393     }
394     return len;
395 }
396
397 /****************
398  * Remove trailing white spaces and return the length of the buffer
399  */
400 unsigned
401 trim_trailing_ws( byte *line, unsigned len )
402 {
403     return trim_trailing_chars( line, len, " \t\r\n" );
404 }
405
406
407 unsigned int
408 check_trailing_chars( const byte *line, unsigned int len,
409                       const char *trimchars )
410 {
411     const byte *p, *mark;
412     unsigned int n;
413
414     for(mark=NULL, p=line, n=0; n < len; n++, p++ ) {
415         if( strchr(trimchars, *p ) ) {
416             if( !mark )
417                 mark = p;
418         }
419         else
420             mark = NULL;
421     }
422
423     if( mark ) {
424         return mark - line;
425     }
426     return len;
427 }
428
429
430 /****************
431  * Remove trailing white spaces and return the length of the buffer
432  */
433 unsigned int
434 check_trailing_ws( const byte *line, unsigned int len )
435 {
436     return check_trailing_chars( line, len, " \t\r\n" );
437 }
438
439
440
441 int
442 string_count_chr( const char *string, int c )
443 {
444     int count;
445     for(count=0; *string; string++ )
446         if( *string == c )
447             count++;
448     return count;
449 }
450
451 #ifdef USE_GNUPG_ICONV
452 static void
453 handle_iconv_error (const char *to, const char *from, int use_fallback)
454 {
455   if (errno == EINVAL)
456     {
457       static int shown1, shown2;
458       int x;
459
460       if (to && !strcmp (to, "utf-8"))
461         {
462           x = shown1;
463           shown1 = 1;
464         }
465       else
466         {
467           x = shown2;
468           shown2 = 1;
469         }
470
471       if (!x)
472         log_info (_("conversion from `%s' to `%s' not available\n"),
473                   from, to);
474     }
475   else
476     {
477       static int shown;
478
479       if (!shown)
480         log_info (_("iconv_open failed: %s\n"), strerror (errno));
481       shown = 1;
482     }
483
484   if (use_fallback)
485     {
486       /* To avoid further error messages we fallback to Latin-1 for the
487          native encoding.  This is justified as one can expect that on a
488          utf-8 enabled system nl_langinfo() will work and thus we won't
489          never get to here.  Thus Latin-1 seems to be a reasonable
490          default.  */
491       active_charset_name = "iso-8859-1";
492       no_translation = 0;
493       active_charset = NULL;
494       use_iconv = 0;
495     }
496 }
497 #endif /*USE_GNUPG_ICONV*/
498
499 int
500 set_native_charset( const char *newset )
501 {
502     const char *full_newset;
503
504     if (!newset) {
505 #ifdef _WIN32
506         static char codepage[30];
507         unsigned int cpno;
508         const char *aliases;
509
510         /* We are a console program thus we need to use the
511            GetConsoleOutputCP function and not the the GetACP which
512            would give the codepage for a GUI program.  Note this is
513            not a bulletproof detection because GetConsoleCP might
514            return a different one for console input.  Not sure how to
515            cope with that.  If the console Code page is not known we
516            fall back to the system code page.  */
517         cpno = GetConsoleOutputCP ();
518         if (!cpno)
519           cpno = GetACP ();
520         sprintf (codepage, "CP%u", cpno );
521         /* Resolve alias.  We use a long string string and not the
522            usual array to optimize if the code is taken to a DSO.
523            Taken from libiconv 1.9.2. */
524         newset = codepage;
525         for (aliases = ("CP936"   "\0" "GBK" "\0"
526                         "CP1361"  "\0" "JOHAB" "\0"
527                         "CP20127" "\0" "ASCII" "\0"
528                         "CP20866" "\0" "KOI8-R" "\0"
529                         "CP21866" "\0" "KOI8-RU" "\0"
530                         "CP28591" "\0" "ISO-8859-1" "\0"
531                         "CP28592" "\0" "ISO-8859-2" "\0"
532                         "CP28593" "\0" "ISO-8859-3" "\0"
533                         "CP28594" "\0" "ISO-8859-4" "\0"
534                         "CP28595" "\0" "ISO-8859-5" "\0"
535                         "CP28596" "\0" "ISO-8859-6" "\0"
536                         "CP28597" "\0" "ISO-8859-7" "\0"
537                         "CP28598" "\0" "ISO-8859-8" "\0"
538                         "CP28599" "\0" "ISO-8859-9" "\0"
539                         "CP28605" "\0" "ISO-8859-15" "\0");
540              *aliases;
541              aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
542           {
543             if (!strcmp (codepage, aliases) ||(*aliases == '*' && !aliases[1]))
544               {
545                 newset = aliases + strlen (aliases) + 1;
546                 break;
547               }
548           }
549
550 #else
551 #ifdef HAVE_LANGINFO_CODESET
552         newset = nl_langinfo (CODESET);
553 #else /* !HAVE_LANGINFO_CODESET */
554         /* Try to get the used charset from environment variables.  */
555         static char codepage[30];
556         const char *lc, *dot, *mod;
557
558         strcpy (codepage, "iso-8859-1");
559         lc = getenv ("LC_ALL");
560         if (!lc || !*lc) {
561             lc = getenv ("LC_CTYPE");
562             if (!lc || !*lc)
563                 lc = getenv ("LANG");
564         }
565         if (lc && *lc) {
566             dot = strchr (lc, '.');
567             if (dot) {
568                 mod = strchr (++dot, '@');
569                 if (!mod)
570                     mod = dot + strlen (dot);
571                 if (mod - dot < sizeof codepage && dot != mod) {
572                     memcpy (codepage, dot, mod - dot);
573                     codepage [mod - dot] = 0;
574                 }
575             }
576         }
577         newset = codepage;
578 #endif  /* !HAVE_LANGINFO_CODESET */
579 #endif
580     }
581
582     full_newset = newset;
583     if (strlen (newset) > 3 && !ascii_memcasecmp (newset, "iso", 3)) {
584         newset += 3;
585         if (*newset == '-' || *newset == '_')
586             newset++;
587     }
588
589     /* Note that we silently assume that plain ASCII is actually meant
590        as Latin-1.  This makes sense because many Unix system don't
591        have their locale set up properly and thus would get annoying
592        error messages and we have to handle all the "bug"
593        reports. Latin-1 has always been the character set used for 8
594        bit characters on Unix systems. */
595     if( !*newset
596         || !ascii_strcasecmp (newset, "8859-1" )
597         || !ascii_strcasecmp (newset, "646" )
598         || !ascii_strcasecmp (newset, "ASCII" )
599         || !ascii_strcasecmp (newset, "ANSI_X3.4-1968" )
600         ) {
601         active_charset_name = "iso-8859-1";
602         no_translation = 0;
603         active_charset = NULL;
604         use_iconv = 0;
605     }
606     else if( !ascii_strcasecmp (newset, "utf8" )
607              || !ascii_strcasecmp(newset, "utf-8") ) {
608         active_charset_name = "utf-8";
609         no_translation = 1;
610         active_charset = NULL;
611         use_iconv = 0;
612     }
613 #ifdef USE_GNUPG_ICONV
614     else {
615       iconv_t cd;
616
617 #ifdef _WIN32
618       if (load_libiconv ())
619           return G10ERR_GENERAL;
620 #endif /*_WIN32*/      
621
622       cd = iconv_open (full_newset, "utf-8");
623       if (cd == (iconv_t)-1) {
624           handle_iconv_error (full_newset, "utf-8", 0);
625           return G10ERR_GENERAL;
626       }
627       iconv_close (cd);
628       cd = iconv_open ("utf-8", full_newset);
629       if (cd == (iconv_t)-1) {
630           handle_iconv_error ("utf-8", full_newset, 0);
631           return G10ERR_GENERAL;
632       }
633       iconv_close (cd);
634       active_charset_name = full_newset;
635       no_translation = 0;
636       active_charset = NULL; 
637       use_iconv = 1;
638     }
639 #else /*!USE_GNUPG_ICONV*/
640     else if( !ascii_strcasecmp( newset, "8859-2" ) ) {
641         active_charset_name = "iso-8859-2";
642         no_translation = 0;
643         active_charset = latin2_unicode;
644         use_iconv = 0;
645     }
646     else if( !ascii_strcasecmp( newset, "koi8-r" ) ) {
647         active_charset_name = "koi8-r";
648         no_translation = 0;
649         active_charset = koi8_unicode;
650         use_iconv = 0;
651     }
652     else
653         return G10ERR_GENERAL;
654 #endif /*!USE_GNUPG_ICONV*/
655     return 0;
656 }
657
658 const char*
659 get_native_charset()
660 {
661     return active_charset_name;
662 }
663
664 /****************
665  * Convert string, which is in native encoding to UTF8 and return the
666  * new allocated UTF8 string.
667  */
668 char *
669 native_to_utf8( const char *string )
670 {
671   const byte *s;
672   char *buffer;
673   byte *p;
674   size_t length=0;
675   
676   if (no_translation)
677     { /* Already utf-8 encoded. */
678       buffer = m_strdup (string);
679     }
680   else if( !active_charset && !use_iconv) /* Shortcut implementation
681                                              for Latin-1.  */
682     { 
683       for(s=string; *s; s++ ) 
684         {
685           length++;
686           if( *s & 0x80 )
687             length++;
688         }
689       buffer = m_alloc( length + 1 );
690       for(p=buffer, s=string; *s; s++ )
691         {
692           if( *s & 0x80 )
693             {
694               *p++ = 0xc0 | ((*s >> 6) & 3);
695               *p++ = 0x80 | ( *s & 0x3f );
696             }
697           else
698             *p++ = *s;
699         }
700       *p = 0;
701     }
702   else       /* Need to use a translation table. */
703     { 
704 #ifdef USE_GNUPG_ICONV
705       iconv_t cd;
706       const char *inptr;
707       char *outptr;
708       size_t inbytes, outbytes;
709      
710       cd = iconv_open ("utf-8", active_charset_name);
711       if (cd == (iconv_t)-1)
712         {
713           handle_iconv_error ("utf-8", active_charset_name, 1);
714           return native_to_utf8 (string);
715         }
716
717       for (s=string; *s; s++ ) 
718         {
719           length++;
720           if ((*s & 0x80))
721             length += 5; /* We may need up to 6 bytes for the utf8 output. */
722         }
723       buffer = m_alloc (length + 1);
724
725       inptr = string;
726       inbytes = strlen (string);
727       outptr = buffer;
728       outbytes = length;
729       if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
730                   &outptr, &outbytes) == (size_t)-1)
731         {
732           static int shown;
733
734           if (!shown)
735             log_info (_("conversion from `%s' to `%s' failed: %s\n"),
736                       active_charset_name, "utf-8", strerror (errno));
737           shown = 1;
738           /* We don't do any conversion at all but use the strings as is. */
739           strcpy (buffer, string);
740         }
741       else /* Success.  */
742         {
743           *outptr = 0;
744           /* We could realloc the buffer now but I doubt that it makes
745              much sense given that it will get freed anyway soon
746              after.  */
747         }
748       iconv_close (cd);
749
750 #else /*!USE_GNUPG_ICONV*/
751       for(s=string; *s; s++ ) 
752         {
753           length++;
754           if( *s & 0x80 )
755             length += 2; /* We may need up to 3 bytes. */
756         }
757       buffer = m_alloc( length + 1 );
758       for(p=buffer, s=string; *s; s++ ) {
759         if( *s & 0x80 ) {
760           ushort val = active_charset[ *s & 0x7f ];
761           if( val < 0x0800 ) {
762             *p++ = 0xc0 | ( (val >> 6) & 0x1f );
763             *p++ = 0x80 | (  val & 0x3f );
764           }
765           else {
766             *p++ = 0xe0 | ( (val >> 12) & 0x0f );
767             *p++ = 0x80 | ( (val >>  6) & 0x3f );
768             *p++ = 0x80 | (  val & 0x3f );
769           }
770         }
771         else
772           *p++ = *s;
773       }
774       *p = 0;
775 #endif /*!USE_GNUPG_ICONV*/
776
777     }
778   return buffer;
779 }
780
781
782 /****************
783  * Convert string, which is in UTF8 to native encoding.  illegal
784  * encodings by some "\xnn" and quote all control characters. A
785  * character with value DELIM will always be quoted, it must be a
786  * vanilla ASCII character.  A DELIM value of -1 is special: it disables 
787  * all quoting of control characters.
788  */
789 char *
790 utf8_to_native( const char *string, size_t length, int delim )
791 {
792     int nleft;
793     int i;
794     byte encbuf[8];
795     int encidx;
796     const byte *s;
797     size_t n;
798     byte *buffer = NULL, *p = NULL;
799     unsigned long val = 0;
800     size_t slen;
801     int resync = 0;
802
803     /* 1. pass (p==NULL): count the extended utf-8 characters */
804     /* 2. pass (p!=NULL): create string */
805     for( ;; ) {
806         for( slen=length, nleft=encidx=0, n=0, s=string; slen; s++, slen-- ) {
807             if( resync ) {
808                 if( !(*s < 128 || (*s >= 0xc0 && *s <= 0xfd)) ) {
809                     /* still invalid */
810                     if( p ) {
811                         sprintf(p, "\\x%02x", *s );
812                         p += 4;
813                     }
814                     n += 4;
815                     continue;
816                 }
817                 resync = 0;
818             }
819             if( !nleft ) {
820                 if( !(*s & 0x80) ) { /* plain ascii */
821                     if( delim != -1 
822                         && (*s < 0x20 || *s == 0x7f || *s == delim
823                             || (delim && *s=='\\'))) {
824                         n++;
825                         if( p )
826                             *p++ = '\\';
827                         switch( *s ) {
828                           case '\n': n++; if( p ) *p++ = 'n'; break;
829                           case '\r': n++; if( p ) *p++ = 'r'; break;
830                           case '\f': n++; if( p ) *p++ = 'f'; break;
831                           case '\v': n++; if( p ) *p++ = 'v'; break;
832                           case '\b': n++; if( p ) *p++ = 'b'; break;
833                           case   0 : n++; if( p ) *p++ = '0'; break;
834                           default:
835                             n += 3;
836                             if ( p ) {
837                                 sprintf( p, "x%02x", *s );
838                                 p += 3;
839                             }
840                             break;
841                         }
842                     }
843                     else {
844                         if( p ) *p++ = *s;
845                         n++;
846                     }
847                 }
848                 else if( (*s & 0xe0) == 0xc0 ) { /* 110x xxxx */
849                     val = *s & 0x1f;
850                     nleft = 1;
851                     encidx = 0;
852                     encbuf[encidx++] = *s;
853                 }
854                 else if( (*s & 0xf0) == 0xe0 ) { /* 1110 xxxx */
855                     val = *s & 0x0f;
856                     nleft = 2;
857                     encidx = 0;
858                     encbuf[encidx++] = *s;
859                 }
860                 else if( (*s & 0xf8) == 0xf0 ) { /* 1111 0xxx */
861                     val = *s & 0x07;
862                     nleft = 3;
863                     encidx = 0;
864                     encbuf[encidx++] = *s;
865                 }
866                 else if( (*s & 0xfc) == 0xf8 ) { /* 1111 10xx */
867                     val = *s & 0x03;
868                     nleft = 4;
869                     encidx = 0;
870                     encbuf[encidx++] = *s;
871                 }
872                 else if( (*s & 0xfe) == 0xfc ) { /* 1111 110x */
873                     val = *s & 0x01;
874                     nleft = 5;
875                     encidx = 0;
876                     encbuf[encidx++] = *s;
877                 }
878                 else {  /* invalid encoding: print as \xnn */
879                     if( p ) {
880                         sprintf(p, "\\x%02x", *s );
881                         p += 4;
882                     }
883                     n += 4;
884                     resync = 1;
885                 }
886             }
887             else if( *s < 0x80 || *s >= 0xc0 ) { /* invalid */
888                 if( p ) {
889                     for(i=0; i < encidx; i++ ) {
890                         sprintf(p, "\\x%02x", encbuf[i] );
891                         p += 4;
892                     }
893                     sprintf(p, "\\x%02x", *s );
894                     p += 4;
895                 }
896                 n += 4 + 4*encidx;
897                 nleft = 0;
898                 encidx = 0;
899                 resync = 1;
900             }
901             else {
902                 encbuf[encidx++] = *s;
903                 val <<= 6;
904                 val |= *s & 0x3f;
905                 if( !--nleft ) { /* ready */
906                     if (no_translation) {
907                         if( p ) {
908                             for(i=0; i < encidx; i++ )
909                                 *p++ = encbuf[i];
910                         }
911                         n += encidx;
912                         encidx = 0;
913                     }
914 #ifdef USE_GNUPG_ICONV
915                     else if(use_iconv) {
916                         /* Our strategy for using iconv is a bit
917                          * strange but it better keeps compatibility
918                          * with previous versions in regard to how
919                          * invalid encodings are displayed.  What we
920                          * do is to keep the utf-8 as is and have the
921                          * real translation step then at the end.
922                          * Yes, I know that this is ugly.  However we
923                          * are short of the 1.4 release and for this
924                          * branch we should not mee too much around
925                          * with iconv things.  One reason for this is
926                          * that we don't know enough about non-GNU
927                          * iconv implementation and want to minimize
928                          * the risk of breaking the code on too many
929                          * platforms.  */
930                         if( p ) {
931                             for(i=0; i < encidx; i++ )
932                                 *p++ = encbuf[i];
933                         }
934                         n += encidx;
935                         encidx = 0;
936                     }
937 #endif /*USE_GNUPG_ICONV*/
938                     else if( active_charset ) { /* table lookup */
939                         for(i=0; i < 128; i++ ) {
940                             if( active_charset[i] == val )
941                                 break;
942                         }
943                         if( i < 128 ) { /* we can print this one */
944                             if( p ) *p++ = i+128;
945                             n++;
946                         }
947                         else { /* we do not have a translation: print utf8 */
948                             if( p ) {
949                                 for(i=0; i < encidx; i++ ) {
950                                     sprintf(p, "\\x%02x", encbuf[i] );
951                                     p += 4;
952                                 }
953                             }
954                             n += encidx*4;
955                             encidx = 0;
956                         }
957                     }
958                     else { /* native set */
959                         if( val >= 0x80 && val < 256 ) {
960                             n++;    /* we can simply print this character */
961                             if( p ) *p++ = val;
962                         }
963                         else { /* we do not have a translation: print utf8 */
964                             if( p ) {
965                                 for(i=0; i < encidx; i++ ) {
966                                     sprintf(p, "\\x%02x", encbuf[i] );
967                                     p += 4;
968                                 }
969                             }
970                             n += encidx*4;
971                             encidx = 0;
972                         }
973                     }
974                 }
975
976             }
977         }
978         if( !buffer ) { /* allocate the buffer after the first pass */
979             buffer = p = m_alloc( n + 1 );
980         }
981 #ifdef USE_GNUPG_ICONV
982         else if(use_iconv) {
983             /* Note: See above for comments.  */
984             iconv_t cd;
985             const char *inptr;
986             char *outbuf, *outptr;
987             size_t inbytes, outbytes;
988             
989             *p = 0;  /* Terminate the buffer. */
990
991             cd = iconv_open (active_charset_name, "utf-8");
992             if (cd == (iconv_t)-1)
993                 {
994                     handle_iconv_error (active_charset_name, "utf-8", 1);
995                     m_free (buffer);
996                     return utf8_to_native (string, length, delim);
997                 }
998
999             /* Allocate a new buffer large enough to hold all possible
1000              * encodings. */
1001             n = p - buffer + 1;
1002             inbytes = n - 1;;
1003             inptr = buffer;
1004             outbytes = n * MB_LEN_MAX;
1005             if (outbytes / MB_LEN_MAX != n) 
1006                 BUG (); /* Actually an overflow. */
1007             outbuf = outptr = m_alloc (outbytes);
1008             if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
1009                         &outptr, &outbytes) == (size_t)-1) {
1010                 static int shown;
1011                 
1012                 if (!shown)
1013                   log_info (_("conversion from `%s' to `%s' failed: %s\n"),
1014                             "utf-8", active_charset_name, strerror (errno));
1015                 shown = 1;
1016                 /* Didn't worked out.  Temporary disable the use of
1017                  * iconv and fall back to our old code. */
1018                 m_free (buffer);
1019                 buffer = NULL;
1020                 m_free (outbuf);
1021                 use_iconv = 0;
1022                 outbuf = utf8_to_native (string, length, delim);
1023                 use_iconv = 1;
1024             }
1025             else { /* Success.  */
1026                 *outptr = 0;
1027                 /* We could realloc the buffer now but I doubt that it makes
1028                    much sense given that it will get freed anyway soon
1029                    after.  */
1030                 m_free (buffer);
1031             }
1032             iconv_close (cd);
1033             return outbuf;
1034         }
1035 #endif /*USE_GNUPG_ICONV*/
1036         else {
1037             *p = 0; /* make a string */
1038             return buffer;
1039         }
1040     }
1041 }
1042
1043 /****************************************************
1044  ******** locale insensitive ctype functions ********
1045  ****************************************************/
1046 /* FIXME: replace them by a table lookup and macros */
1047 int
1048 ascii_isupper (int c)
1049 {
1050     return c >= 'A' && c <= 'Z';
1051 }
1052
1053 int
1054 ascii_islower (int c)
1055 {
1056     return c >= 'a' && c <= 'z';
1057 }
1058
1059 int 
1060 ascii_toupper (int c)
1061 {
1062     if (c >= 'a' && c <= 'z')
1063         c &= ~0x20;
1064     return c;
1065 }
1066
1067 int 
1068 ascii_tolower (int c)
1069 {
1070     if (c >= 'A' && c <= 'Z')
1071         c |= 0x20;
1072     return c;
1073 }
1074
1075
1076 int
1077 ascii_strcasecmp (const char *a, const char *b)
1078 {
1079   const unsigned char *p1 = (const unsigned char *)a;
1080   const unsigned char *p2 = (const unsigned char *)b;
1081   unsigned char c1, c2;
1082
1083   if (p1 == p2)
1084     return 0;
1085
1086   do
1087     {
1088       c1 = ascii_tolower (*p1);
1089       c2 = ascii_tolower (*p2);
1090
1091       if (c1 == '\0')
1092         break;
1093
1094       ++p1;
1095       ++p2;
1096     }
1097   while (c1 == c2);
1098   
1099   return c1 - c2;
1100 }
1101
1102 int 
1103 ascii_strncasecmp (const char *a, const char *b, size_t n)
1104 {
1105   const unsigned char *p1 = (const unsigned char *)a;
1106   const unsigned char *p2 = (const unsigned char *)b;
1107   unsigned char c1, c2;
1108
1109   if (p1 == p2 || !n )
1110     return 0;
1111
1112   do
1113     {
1114       c1 = ascii_tolower (*p1);
1115       c2 = ascii_tolower (*p2);
1116
1117       if ( !--n || c1 == '\0')
1118         break;
1119
1120       ++p1;
1121       ++p2;
1122     }
1123   while (c1 == c2);
1124   
1125   return c1 - c2;
1126 }
1127
1128
1129 int
1130 ascii_memcasecmp( const char *a, const char *b, size_t n )
1131 {
1132     if (a == b)
1133         return 0;
1134     for ( ; n; n--, a++, b++ ) {
1135         if( *a != *b  && ascii_toupper (*a) != ascii_toupper (*b) )
1136             return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
1137     }
1138     return 0;
1139 }
1140
1141
1142
1143 /*********************************************
1144  ********** missing string functions *********
1145  *********************************************/
1146
1147 #ifndef HAVE_STPCPY
1148 char *
1149 stpcpy(char *a,const char *b)
1150 {
1151     while( *b )
1152         *a++ = *b++;
1153     *a = 0;
1154
1155     return (char*)a;
1156 }
1157 #endif
1158
1159
1160 #ifndef HAVE_STRSEP
1161 /* code taken from glibc-2.2.1/sysdeps/generic/strsep.c */
1162 char *
1163 strsep (char **stringp, const char *delim)
1164 {
1165   char *begin, *end;
1166
1167   begin = *stringp;
1168   if (begin == NULL)
1169     return NULL;
1170
1171   /* A frequent case is when the delimiter string contains only one
1172      character.  Here we don't need to call the expensive `strpbrk'
1173      function and instead work using `strchr'.  */
1174   if (delim[0] == '\0' || delim[1] == '\0')
1175     {
1176       char ch = delim[0];
1177
1178       if (ch == '\0')
1179         end = NULL;
1180       else
1181         {
1182           if (*begin == ch)
1183             end = begin;
1184           else if (*begin == '\0')
1185             end = NULL;
1186           else
1187             end = strchr (begin + 1, ch);
1188         }
1189     }
1190   else
1191     /* Find the end of the token.  */
1192     end = strpbrk (begin, delim);
1193
1194   if (end)
1195     {
1196       /* Terminate the token and set *STRINGP past NUL character.  */
1197       *end++ = '\0';
1198       *stringp = end;
1199     }
1200   else
1201     /* No more delimiters; this is the last token.  */
1202     *stringp = NULL;
1203
1204   return begin;
1205 }
1206 #endif /*HAVE_STRSEP*/
1207
1208
1209 #ifndef HAVE_STRLWR
1210 char *
1211 strlwr(char *s)
1212 {
1213     char *p;
1214     for(p=s; *p; p++ )
1215         *p = tolower(*(unsigned char *)p);
1216     return s;
1217 }
1218 #endif
1219
1220 #ifndef HAVE_STRCASECMP
1221 int
1222 strcasecmp( const char *a, const char *b )
1223 {
1224     for( ; *a && *b; a++, b++ ) {
1225         if( *a != *b
1226             && toupper(*(const byte *)a) != toupper(*(const byte *)b) )
1227             break;
1228     }
1229     return *(const byte*)a - *(const byte*)b;
1230 }
1231 #endif
1232
1233 #ifndef HAVE_STRNCASECMP
1234 int
1235 strncasecmp( const char *a, const char *b, size_t n )
1236 {
1237     for( ; n && *a && *b; a++, b++, n--) {
1238         if( *a != *b
1239             && toupper(*(const byte *)a) != toupper(*(const byte *)b) )
1240             break;
1241     }
1242     if (!n)
1243       return 0;
1244     return *(const byte*)a - *(const byte*)b;
1245 }
1246 #endif
1247
1248
1249 #ifdef _WIN32
1250 /* 
1251  * Like vsprintf but provides a pointer to malloc'd storage, which
1252  * must be freed by the caller (m_free).  Taken from libiberty as
1253  * found in gcc-2.95.2 and a little bit modernized.
1254  * FIXME: Write a new CRT for W32.
1255  */
1256 int
1257 vasprintf (char **result, const char *format, va_list args)
1258 {
1259   const char *p = format;
1260   /* Add one to make sure that it is never zero, which might cause malloc
1261      to return NULL.  */
1262   int total_width = strlen (format) + 1;
1263   va_list ap;
1264
1265   /* this is not really portable but works under Windows */
1266   memcpy ( &ap, &args, sizeof (va_list));
1267
1268   while (*p != '\0')
1269     {
1270       if (*p++ == '%')
1271         {
1272           while (strchr ("-+ #0", *p))
1273             ++p;
1274           if (*p == '*')
1275             {
1276               ++p;
1277               total_width += abs (va_arg (ap, int));
1278             }
1279           else
1280             {
1281               char *endp;  
1282               total_width += strtoul (p, &endp, 10);
1283               p = endp;
1284             }
1285           if (*p == '.')
1286             {
1287               ++p;
1288               if (*p == '*')
1289                 {
1290                   ++p;
1291                   total_width += abs (va_arg (ap, int));
1292                 }
1293               else
1294                 {
1295                   char *endp;
1296                   total_width += strtoul (p, &endp, 10);
1297                   p = endp;
1298                 }
1299             }
1300           while (strchr ("hlL", *p))
1301             ++p;
1302           /* Should be big enough for any format specifier except %s
1303              and floats.  */
1304           total_width += 30;
1305           switch (*p)
1306             {
1307             case 'd':
1308             case 'i':
1309             case 'o':
1310             case 'u':
1311             case 'x':
1312             case 'X':
1313             case 'c':
1314               (void) va_arg (ap, int);
1315               break;
1316             case 'f':
1317             case 'e':
1318             case 'E':
1319             case 'g':
1320             case 'G':
1321               (void) va_arg (ap, double);
1322               /* Since an ieee double can have an exponent of 307, we'll
1323                  make the buffer wide enough to cover the gross case. */
1324               total_width += 307;
1325             
1326             case 's':
1327               total_width += strlen (va_arg (ap, char *));
1328               break;
1329             case 'p':
1330             case 'n':
1331               (void) va_arg (ap, char *);
1332               break;
1333             }
1334         }
1335     }
1336   *result = m_alloc (total_width);
1337   if (*result != NULL)
1338     return vsprintf (*result, format, args);
1339   else
1340     return 0;
1341 }
1342
1343 int
1344 asprintf (char **buf, const char *fmt, ...)
1345 {
1346   int status;
1347   va_list ap;
1348
1349   va_start (ap, fmt);
1350   status = vasprintf (buf, fmt, ap);
1351   va_end (ap);
1352   return status;  
1353 }
1354
1355 const char *
1356 w32_strerror (int w32_errno)
1357 {
1358   static char strerr[256];
1359   int ec = (int)GetLastError ();
1360   
1361   if (w32_errno == 0)
1362     w32_errno = ec;
1363   FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, w32_errno,
1364                  MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
1365                  strerr, DIM (strerr)-1, NULL);
1366   return strerr;    
1367 }
1368 #endif /*_WIN32*/
1369
1370
1371