* strgutil.c (set_native_charset) [_WIN32]: Add alias for codepage
[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                         "CP65001" "\0" "UTF-8" "\0");
541              *aliases;
542              aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
543           {
544             if (!strcmp (codepage, aliases) ||(*aliases == '*' && !aliases[1]))
545               {
546                 newset = aliases + strlen (aliases) + 1;
547                 break;
548               }
549           }
550
551 #else
552 #ifdef HAVE_LANGINFO_CODESET
553         newset = nl_langinfo (CODESET);
554 #else /* !HAVE_LANGINFO_CODESET */
555         /* Try to get the used charset from environment variables.  */
556         static char codepage[30];
557         const char *lc, *dot, *mod;
558
559         strcpy (codepage, "iso-8859-1");
560         lc = getenv ("LC_ALL");
561         if (!lc || !*lc) {
562             lc = getenv ("LC_CTYPE");
563             if (!lc || !*lc)
564                 lc = getenv ("LANG");
565         }
566         if (lc && *lc) {
567             dot = strchr (lc, '.');
568             if (dot) {
569                 mod = strchr (++dot, '@');
570                 if (!mod)
571                     mod = dot + strlen (dot);
572                 if (mod - dot < sizeof codepage && dot != mod) {
573                     memcpy (codepage, dot, mod - dot);
574                     codepage [mod - dot] = 0;
575                 }
576             }
577         }
578         newset = codepage;
579 #endif  /* !HAVE_LANGINFO_CODESET */
580 #endif
581     }
582
583     full_newset = newset;
584     if (strlen (newset) > 3 && !ascii_memcasecmp (newset, "iso", 3)) {
585         newset += 3;
586         if (*newset == '-' || *newset == '_')
587             newset++;
588     }
589
590     /* Note that we silently assume that plain ASCII is actually meant
591        as Latin-1.  This makes sense because many Unix system don't
592        have their locale set up properly and thus would get annoying
593        error messages and we have to handle all the "bug"
594        reports. Latin-1 has always been the character set used for 8
595        bit characters on Unix systems. */
596     if( !*newset
597         || !ascii_strcasecmp (newset, "8859-1" )
598         || !ascii_strcasecmp (newset, "646" )
599         || !ascii_strcasecmp (newset, "ASCII" )
600         || !ascii_strcasecmp (newset, "ANSI_X3.4-1968" )
601         ) {
602         active_charset_name = "iso-8859-1";
603         no_translation = 0;
604         active_charset = NULL;
605         use_iconv = 0;
606     }
607     else if( !ascii_strcasecmp (newset, "utf8" )
608              || !ascii_strcasecmp(newset, "utf-8") ) {
609         active_charset_name = "utf-8";
610         no_translation = 1;
611         active_charset = NULL;
612         use_iconv = 0;
613     }
614 #ifdef USE_GNUPG_ICONV
615     else {
616       iconv_t cd;
617
618 #ifdef _WIN32
619       if (load_libiconv ())
620           return G10ERR_GENERAL;
621 #endif /*_WIN32*/      
622
623       cd = iconv_open (full_newset, "utf-8");
624       if (cd == (iconv_t)-1) {
625           handle_iconv_error (full_newset, "utf-8", 0);
626           return G10ERR_GENERAL;
627       }
628       iconv_close (cd);
629       cd = iconv_open ("utf-8", full_newset);
630       if (cd == (iconv_t)-1) {
631           handle_iconv_error ("utf-8", full_newset, 0);
632           return G10ERR_GENERAL;
633       }
634       iconv_close (cd);
635       active_charset_name = full_newset;
636       no_translation = 0;
637       active_charset = NULL; 
638       use_iconv = 1;
639     }
640 #else /*!USE_GNUPG_ICONV*/
641     else if( !ascii_strcasecmp( newset, "8859-2" ) ) {
642         active_charset_name = "iso-8859-2";
643         no_translation = 0;
644         active_charset = latin2_unicode;
645         use_iconv = 0;
646     }
647     else if( !ascii_strcasecmp( newset, "koi8-r" ) ) {
648         active_charset_name = "koi8-r";
649         no_translation = 0;
650         active_charset = koi8_unicode;
651         use_iconv = 0;
652     }
653     else
654         return G10ERR_GENERAL;
655 #endif /*!USE_GNUPG_ICONV*/
656     return 0;
657 }
658
659 const char*
660 get_native_charset()
661 {
662     return active_charset_name;
663 }
664
665 /****************
666  * Convert string, which is in native encoding to UTF8 and return the
667  * new allocated UTF8 string.
668  */
669 char *
670 native_to_utf8( const char *string )
671 {
672   const byte *s;
673   char *buffer;
674   byte *p;
675   size_t length=0;
676   
677   if (no_translation)
678     { /* Already utf-8 encoded. */
679       buffer = m_strdup (string);
680     }
681   else if( !active_charset && !use_iconv) /* Shortcut implementation
682                                              for Latin-1.  */
683     { 
684       for(s=string; *s; s++ ) 
685         {
686           length++;
687           if( *s & 0x80 )
688             length++;
689         }
690       buffer = m_alloc( length + 1 );
691       for(p=buffer, s=string; *s; s++ )
692         {
693           if( *s & 0x80 )
694             {
695               *p++ = 0xc0 | ((*s >> 6) & 3);
696               *p++ = 0x80 | ( *s & 0x3f );
697             }
698           else
699             *p++ = *s;
700         }
701       *p = 0;
702     }
703   else       /* Need to use a translation table. */
704     { 
705 #ifdef USE_GNUPG_ICONV
706       iconv_t cd;
707       const char *inptr;
708       char *outptr;
709       size_t inbytes, outbytes;
710      
711       cd = iconv_open ("utf-8", active_charset_name);
712       if (cd == (iconv_t)-1)
713         {
714           handle_iconv_error ("utf-8", active_charset_name, 1);
715           return native_to_utf8 (string);
716         }
717
718       for (s=string; *s; s++ ) 
719         {
720           length++;
721           if ((*s & 0x80))
722             length += 5; /* We may need up to 6 bytes for the utf8 output. */
723         }
724       buffer = m_alloc (length + 1);
725
726       inptr = string;
727       inbytes = strlen (string);
728       outptr = buffer;
729       outbytes = length;
730       if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
731                   &outptr, &outbytes) == (size_t)-1)
732         {
733           static int shown;
734
735           if (!shown)
736             log_info (_("conversion from `%s' to `%s' failed: %s\n"),
737                       active_charset_name, "utf-8", strerror (errno));
738           shown = 1;
739           /* We don't do any conversion at all but use the strings as is. */
740           strcpy (buffer, string);
741         }
742       else /* Success.  */
743         {
744           *outptr = 0;
745           /* We could realloc the buffer now but I doubt that it makes
746              much sense given that it will get freed anyway soon
747              after.  */
748         }
749       iconv_close (cd);
750
751 #else /*!USE_GNUPG_ICONV*/
752       for(s=string; *s; s++ ) 
753         {
754           length++;
755           if( *s & 0x80 )
756             length += 2; /* We may need up to 3 bytes. */
757         }
758       buffer = m_alloc( length + 1 );
759       for(p=buffer, s=string; *s; s++ ) {
760         if( *s & 0x80 ) {
761           ushort val = active_charset[ *s & 0x7f ];
762           if( val < 0x0800 ) {
763             *p++ = 0xc0 | ( (val >> 6) & 0x1f );
764             *p++ = 0x80 | (  val & 0x3f );
765           }
766           else {
767             *p++ = 0xe0 | ( (val >> 12) & 0x0f );
768             *p++ = 0x80 | ( (val >>  6) & 0x3f );
769             *p++ = 0x80 | (  val & 0x3f );
770           }
771         }
772         else
773           *p++ = *s;
774       }
775       *p = 0;
776 #endif /*!USE_GNUPG_ICONV*/
777
778     }
779   return buffer;
780 }
781
782
783 /****************
784  * Convert string, which is in UTF8 to native encoding.  illegal
785  * encodings by some "\xnn" and quote all control characters. A
786  * character with value DELIM will always be quoted, it must be a
787  * vanilla ASCII character.  A DELIM value of -1 is special: it disables 
788  * all quoting of control characters.
789  */
790 char *
791 utf8_to_native( const char *string, size_t length, int delim )
792 {
793     int nleft;
794     int i;
795     byte encbuf[8];
796     int encidx;
797     const byte *s;
798     size_t n;
799     byte *buffer = NULL, *p = NULL;
800     unsigned long val = 0;
801     size_t slen;
802     int resync = 0;
803
804     /* 1. pass (p==NULL): count the extended utf-8 characters */
805     /* 2. pass (p!=NULL): create string */
806     for( ;; ) {
807         for( slen=length, nleft=encidx=0, n=0, s=string; slen; s++, slen-- ) {
808             if( resync ) {
809                 if( !(*s < 128 || (*s >= 0xc0 && *s <= 0xfd)) ) {
810                     /* still invalid */
811                     if( p ) {
812                         sprintf(p, "\\x%02x", *s );
813                         p += 4;
814                     }
815                     n += 4;
816                     continue;
817                 }
818                 resync = 0;
819             }
820             if( !nleft ) {
821                 if( !(*s & 0x80) ) { /* plain ascii */
822                     if( delim != -1 
823                         && (*s < 0x20 || *s == 0x7f || *s == delim
824                             || (delim && *s=='\\'))) {
825                         n++;
826                         if( p )
827                             *p++ = '\\';
828                         switch( *s ) {
829                           case '\n': n++; if( p ) *p++ = 'n'; break;
830                           case '\r': n++; if( p ) *p++ = 'r'; break;
831                           case '\f': n++; if( p ) *p++ = 'f'; break;
832                           case '\v': n++; if( p ) *p++ = 'v'; break;
833                           case '\b': n++; if( p ) *p++ = 'b'; break;
834                           case   0 : n++; if( p ) *p++ = '0'; break;
835                           default:
836                             n += 3;
837                             if ( p ) {
838                                 sprintf( p, "x%02x", *s );
839                                 p += 3;
840                             }
841                             break;
842                         }
843                     }
844                     else {
845                         if( p ) *p++ = *s;
846                         n++;
847                     }
848                 }
849                 else if( (*s & 0xe0) == 0xc0 ) { /* 110x xxxx */
850                     val = *s & 0x1f;
851                     nleft = 1;
852                     encidx = 0;
853                     encbuf[encidx++] = *s;
854                 }
855                 else if( (*s & 0xf0) == 0xe0 ) { /* 1110 xxxx */
856                     val = *s & 0x0f;
857                     nleft = 2;
858                     encidx = 0;
859                     encbuf[encidx++] = *s;
860                 }
861                 else if( (*s & 0xf8) == 0xf0 ) { /* 1111 0xxx */
862                     val = *s & 0x07;
863                     nleft = 3;
864                     encidx = 0;
865                     encbuf[encidx++] = *s;
866                 }
867                 else if( (*s & 0xfc) == 0xf8 ) { /* 1111 10xx */
868                     val = *s & 0x03;
869                     nleft = 4;
870                     encidx = 0;
871                     encbuf[encidx++] = *s;
872                 }
873                 else if( (*s & 0xfe) == 0xfc ) { /* 1111 110x */
874                     val = *s & 0x01;
875                     nleft = 5;
876                     encidx = 0;
877                     encbuf[encidx++] = *s;
878                 }
879                 else {  /* invalid encoding: print as \xnn */
880                     if( p ) {
881                         sprintf(p, "\\x%02x", *s );
882                         p += 4;
883                     }
884                     n += 4;
885                     resync = 1;
886                 }
887             }
888             else if( *s < 0x80 || *s >= 0xc0 ) { /* invalid */
889                 if( p ) {
890                     for(i=0; i < encidx; i++ ) {
891                         sprintf(p, "\\x%02x", encbuf[i] );
892                         p += 4;
893                     }
894                     sprintf(p, "\\x%02x", *s );
895                     p += 4;
896                 }
897                 n += 4 + 4*encidx;
898                 nleft = 0;
899                 encidx = 0;
900                 resync = 1;
901             }
902             else {
903                 encbuf[encidx++] = *s;
904                 val <<= 6;
905                 val |= *s & 0x3f;
906                 if( !--nleft ) { /* ready */
907                     if (no_translation) {
908                         if( p ) {
909                             for(i=0; i < encidx; i++ )
910                                 *p++ = encbuf[i];
911                         }
912                         n += encidx;
913                         encidx = 0;
914                     }
915 #ifdef USE_GNUPG_ICONV
916                     else if(use_iconv) {
917                         /* Our strategy for using iconv is a bit
918                          * strange but it better keeps compatibility
919                          * with previous versions in regard to how
920                          * invalid encodings are displayed.  What we
921                          * do is to keep the utf-8 as is and have the
922                          * real translation step then at the end.
923                          * Yes, I know that this is ugly.  However we
924                          * are short of the 1.4 release and for this
925                          * branch we should not mee too much around
926                          * with iconv things.  One reason for this is
927                          * that we don't know enough about non-GNU
928                          * iconv implementation and want to minimize
929                          * the risk of breaking the code on too many
930                          * platforms.  */
931                         if( p ) {
932                             for(i=0; i < encidx; i++ )
933                                 *p++ = encbuf[i];
934                         }
935                         n += encidx;
936                         encidx = 0;
937                     }
938 #endif /*USE_GNUPG_ICONV*/
939                     else if( active_charset ) { /* table lookup */
940                         for(i=0; i < 128; i++ ) {
941                             if( active_charset[i] == val )
942                                 break;
943                         }
944                         if( i < 128 ) { /* we can print this one */
945                             if( p ) *p++ = i+128;
946                             n++;
947                         }
948                         else { /* we do not have a translation: print utf8 */
949                             if( p ) {
950                                 for(i=0; i < encidx; i++ ) {
951                                     sprintf(p, "\\x%02x", encbuf[i] );
952                                     p += 4;
953                                 }
954                             }
955                             n += encidx*4;
956                             encidx = 0;
957                         }
958                     }
959                     else { /* native set */
960                         if( val >= 0x80 && val < 256 ) {
961                             n++;    /* we can simply print this character */
962                             if( p ) *p++ = val;
963                         }
964                         else { /* we do not have a translation: print utf8 */
965                             if( p ) {
966                                 for(i=0; i < encidx; i++ ) {
967                                     sprintf(p, "\\x%02x", encbuf[i] );
968                                     p += 4;
969                                 }
970                             }
971                             n += encidx*4;
972                             encidx = 0;
973                         }
974                     }
975                 }
976
977             }
978         }
979         if( !buffer ) { /* allocate the buffer after the first pass */
980             buffer = p = m_alloc( n + 1 );
981         }
982 #ifdef USE_GNUPG_ICONV
983         else if(use_iconv) {
984             /* Note: See above for comments.  */
985             iconv_t cd;
986             const char *inptr;
987             char *outbuf, *outptr;
988             size_t inbytes, outbytes;
989             
990             *p = 0;  /* Terminate the buffer. */
991
992             cd = iconv_open (active_charset_name, "utf-8");
993             if (cd == (iconv_t)-1)
994                 {
995                     handle_iconv_error (active_charset_name, "utf-8", 1);
996                     m_free (buffer);
997                     return utf8_to_native (string, length, delim);
998                 }
999
1000             /* Allocate a new buffer large enough to hold all possible
1001              * encodings. */
1002             n = p - buffer + 1;
1003             inbytes = n - 1;;
1004             inptr = buffer;
1005             outbytes = n * MB_LEN_MAX;
1006             if (outbytes / MB_LEN_MAX != n) 
1007                 BUG (); /* Actually an overflow. */
1008             outbuf = outptr = m_alloc (outbytes);
1009             if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
1010                         &outptr, &outbytes) == (size_t)-1) {
1011                 static int shown;
1012                 
1013                 if (!shown)
1014                   log_info (_("conversion from `%s' to `%s' failed: %s\n"),
1015                             "utf-8", active_charset_name, strerror (errno));
1016                 shown = 1;
1017                 /* Didn't worked out.  Temporary disable the use of
1018                  * iconv and fall back to our old code. */
1019                 m_free (buffer);
1020                 buffer = NULL;
1021                 m_free (outbuf);
1022                 use_iconv = 0;
1023                 outbuf = utf8_to_native (string, length, delim);
1024                 use_iconv = 1;
1025             }
1026             else { /* Success.  */
1027                 *outptr = 0;
1028                 /* We could realloc the buffer now but I doubt that it makes
1029                    much sense given that it will get freed anyway soon
1030                    after.  */
1031                 m_free (buffer);
1032             }
1033             iconv_close (cd);
1034             return outbuf;
1035         }
1036 #endif /*USE_GNUPG_ICONV*/
1037         else {
1038             *p = 0; /* make a string */
1039             return buffer;
1040         }
1041     }
1042 }
1043
1044 /****************************************************
1045  ******** locale insensitive ctype functions ********
1046  ****************************************************/
1047 /* FIXME: replace them by a table lookup and macros */
1048 int
1049 ascii_isupper (int c)
1050 {
1051     return c >= 'A' && c <= 'Z';
1052 }
1053
1054 int
1055 ascii_islower (int c)
1056 {
1057     return c >= 'a' && c <= 'z';
1058 }
1059
1060 int 
1061 ascii_toupper (int c)
1062 {
1063     if (c >= 'a' && c <= 'z')
1064         c &= ~0x20;
1065     return c;
1066 }
1067
1068 int 
1069 ascii_tolower (int c)
1070 {
1071     if (c >= 'A' && c <= 'Z')
1072         c |= 0x20;
1073     return c;
1074 }
1075
1076
1077 int
1078 ascii_strcasecmp (const char *a, const char *b)
1079 {
1080   const unsigned char *p1 = (const unsigned char *)a;
1081   const unsigned char *p2 = (const unsigned char *)b;
1082   unsigned char c1, c2;
1083
1084   if (p1 == p2)
1085     return 0;
1086
1087   do
1088     {
1089       c1 = ascii_tolower (*p1);
1090       c2 = ascii_tolower (*p2);
1091
1092       if (c1 == '\0')
1093         break;
1094
1095       ++p1;
1096       ++p2;
1097     }
1098   while (c1 == c2);
1099   
1100   return c1 - c2;
1101 }
1102
1103 int 
1104 ascii_strncasecmp (const char *a, const char *b, size_t n)
1105 {
1106   const unsigned char *p1 = (const unsigned char *)a;
1107   const unsigned char *p2 = (const unsigned char *)b;
1108   unsigned char c1, c2;
1109
1110   if (p1 == p2 || !n )
1111     return 0;
1112
1113   do
1114     {
1115       c1 = ascii_tolower (*p1);
1116       c2 = ascii_tolower (*p2);
1117
1118       if ( !--n || c1 == '\0')
1119         break;
1120
1121       ++p1;
1122       ++p2;
1123     }
1124   while (c1 == c2);
1125   
1126   return c1 - c2;
1127 }
1128
1129
1130 int
1131 ascii_memcasecmp( const char *a, const char *b, size_t n )
1132 {
1133     if (a == b)
1134         return 0;
1135     for ( ; n; n--, a++, b++ ) {
1136         if( *a != *b  && ascii_toupper (*a) != ascii_toupper (*b) )
1137             return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
1138     }
1139     return 0;
1140 }
1141
1142
1143
1144 /*********************************************
1145  ********** missing string functions *********
1146  *********************************************/
1147
1148 #ifndef HAVE_STPCPY
1149 char *
1150 stpcpy(char *a,const char *b)
1151 {
1152     while( *b )
1153         *a++ = *b++;
1154     *a = 0;
1155
1156     return (char*)a;
1157 }
1158 #endif
1159
1160
1161 #ifndef HAVE_STRSEP
1162 /* code taken from glibc-2.2.1/sysdeps/generic/strsep.c */
1163 char *
1164 strsep (char **stringp, const char *delim)
1165 {
1166   char *begin, *end;
1167
1168   begin = *stringp;
1169   if (begin == NULL)
1170     return NULL;
1171
1172   /* A frequent case is when the delimiter string contains only one
1173      character.  Here we don't need to call the expensive `strpbrk'
1174      function and instead work using `strchr'.  */
1175   if (delim[0] == '\0' || delim[1] == '\0')
1176     {
1177       char ch = delim[0];
1178
1179       if (ch == '\0')
1180         end = NULL;
1181       else
1182         {
1183           if (*begin == ch)
1184             end = begin;
1185           else if (*begin == '\0')
1186             end = NULL;
1187           else
1188             end = strchr (begin + 1, ch);
1189         }
1190     }
1191   else
1192     /* Find the end of the token.  */
1193     end = strpbrk (begin, delim);
1194
1195   if (end)
1196     {
1197       /* Terminate the token and set *STRINGP past NUL character.  */
1198       *end++ = '\0';
1199       *stringp = end;
1200     }
1201   else
1202     /* No more delimiters; this is the last token.  */
1203     *stringp = NULL;
1204
1205   return begin;
1206 }
1207 #endif /*HAVE_STRSEP*/
1208
1209
1210 #ifndef HAVE_STRLWR
1211 char *
1212 strlwr(char *s)
1213 {
1214     char *p;
1215     for(p=s; *p; p++ )
1216         *p = tolower(*(unsigned char *)p);
1217     return s;
1218 }
1219 #endif
1220
1221 #ifndef HAVE_STRCASECMP
1222 int
1223 strcasecmp( const char *a, const char *b )
1224 {
1225     for( ; *a && *b; a++, b++ ) {
1226         if( *a != *b
1227             && toupper(*(const byte *)a) != toupper(*(const byte *)b) )
1228             break;
1229     }
1230     return *(const byte*)a - *(const byte*)b;
1231 }
1232 #endif
1233
1234 #ifndef HAVE_STRNCASECMP
1235 int
1236 strncasecmp( const char *a, const char *b, size_t n )
1237 {
1238     for( ; n && *a && *b; a++, b++, n--) {
1239         if( *a != *b
1240             && toupper(*(const byte *)a) != toupper(*(const byte *)b) )
1241             break;
1242     }
1243     if (!n)
1244       return 0;
1245     return *(const byte*)a - *(const byte*)b;
1246 }
1247 #endif
1248
1249
1250 #ifdef _WIN32
1251 /* 
1252  * Like vsprintf but provides a pointer to malloc'd storage, which
1253  * must be freed by the caller (m_free).  Taken from libiberty as
1254  * found in gcc-2.95.2 and a little bit modernized.
1255  * FIXME: Write a new CRT for W32.
1256  */
1257 int
1258 vasprintf (char **result, const char *format, va_list args)
1259 {
1260   const char *p = format;
1261   /* Add one to make sure that it is never zero, which might cause malloc
1262      to return NULL.  */
1263   int total_width = strlen (format) + 1;
1264   va_list ap;
1265
1266   /* this is not really portable but works under Windows */
1267   memcpy ( &ap, &args, sizeof (va_list));
1268
1269   while (*p != '\0')
1270     {
1271       if (*p++ == '%')
1272         {
1273           while (strchr ("-+ #0", *p))
1274             ++p;
1275           if (*p == '*')
1276             {
1277               ++p;
1278               total_width += abs (va_arg (ap, int));
1279             }
1280           else
1281             {
1282               char *endp;  
1283               total_width += strtoul (p, &endp, 10);
1284               p = endp;
1285             }
1286           if (*p == '.')
1287             {
1288               ++p;
1289               if (*p == '*')
1290                 {
1291                   ++p;
1292                   total_width += abs (va_arg (ap, int));
1293                 }
1294               else
1295                 {
1296                   char *endp;
1297                   total_width += strtoul (p, &endp, 10);
1298                   p = endp;
1299                 }
1300             }
1301           while (strchr ("hlL", *p))
1302             ++p;
1303           /* Should be big enough for any format specifier except %s
1304              and floats.  */
1305           total_width += 30;
1306           switch (*p)
1307             {
1308             case 'd':
1309             case 'i':
1310             case 'o':
1311             case 'u':
1312             case 'x':
1313             case 'X':
1314             case 'c':
1315               (void) va_arg (ap, int);
1316               break;
1317             case 'f':
1318             case 'e':
1319             case 'E':
1320             case 'g':
1321             case 'G':
1322               (void) va_arg (ap, double);
1323               /* Since an ieee double can have an exponent of 307, we'll
1324                  make the buffer wide enough to cover the gross case. */
1325               total_width += 307;
1326             
1327             case 's':
1328               total_width += strlen (va_arg (ap, char *));
1329               break;
1330             case 'p':
1331             case 'n':
1332               (void) va_arg (ap, char *);
1333               break;
1334             }
1335         }
1336     }
1337   *result = m_alloc (total_width);
1338   if (*result != NULL)
1339     return vsprintf (*result, format, args);
1340   else
1341     return 0;
1342 }
1343
1344 int
1345 asprintf (char **buf, const char *fmt, ...)
1346 {
1347   int status;
1348   va_list ap;
1349
1350   va_start (ap, fmt);
1351   status = vasprintf (buf, fmt, ap);
1352   va_end (ap);
1353   return status;  
1354 }
1355
1356 const char *
1357 w32_strerror (int w32_errno)
1358 {
1359   static char strerr[256];
1360   int ec = (int)GetLastError ();
1361   
1362   if (w32_errno == 0)
1363     w32_errno = ec;
1364   FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, w32_errno,
1365                  MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
1366                  strerr, DIM (strerr)-1, NULL);
1367   return strerr;    
1368 }
1369 #endif /*_WIN32*/
1370
1371
1372