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