576c2eaedb2dea90dfc61c603f6f8f316878b1fe
[platform/upstream/gpg2.git] / common / stringhelp.c
1 /* stringhelp.c -  standard string helper functions
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007,
3  *               2008, 2009, 2010  Free Software Foundation, Inc.
4  * Copyright (C) 2014 Werner Koch
5  * Copyright (C) 2015  g10 Code GmbH
6  *
7  * This file is part of GnuPG.
8  *
9  * GnuPG is free software; you can redistribute it and/or modify it
10  * under the terms of either
11  *
12  *   - the GNU Lesser General Public License as published by the Free
13  *     Software Foundation; either version 3 of the License, or (at
14  *     your option) any later version.
15  *
16  * or
17  *
18  *   - the GNU General Public License as published by the Free
19  *     Software Foundation; either version 2 of the License, or (at
20  *     your option) any later version.
21  *
22  * or both in parallel, as here.
23  *
24  * GnuPG is distributed in the hope that it will be useful, but
25  * WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27  * General Public License for more details.
28  *
29  * You should have received a copies of the GNU General Public License
30  * and the GNU Lesser General Public License along with this program;
31  * if not, see <http://www.gnu.org/licenses/>.
32  */
33
34 #include <config.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdarg.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #ifdef HAVE_PWD_H
41 # include <pwd.h>
42 #endif
43 #include <unistd.h>
44 #include <sys/types.h>
45 #ifdef HAVE_W32_SYSTEM
46 # ifdef HAVE_WINSOCK2_H
47 #  include <winsock2.h>
48 # endif
49 # include <windows.h>
50 #endif
51 #include <assert.h>
52
53 #include "util.h"
54 #include "common-defs.h"
55 #include "utf8conv.h"
56 #include "sysutils.h"
57 #include "stringhelp.h"
58
59 #define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a'))
60
61 /* Sometimes we want to avoid mixing slashes and backslashes on W32
62    and prefer backslashes.  There is usual no problem with mixing
63    them, however a very few W32 API calls can't grok plain slashes.
64    Printing filenames with mixed slashes also looks a bit strange.
65    This function has no effext on POSIX. */
66 static inline char *
67 change_slashes (char *name)
68 {
69 #ifdef HAVE_DOSISH_SYSTEM
70   char *p;
71
72   if (strchr (name, '\\'))
73     {
74       for (p=name; *p; p++)
75         if (*p == '/')
76           *p = '\\';
77     }
78 #endif /*HAVE_DOSISH_SYSTEM*/
79   return name;
80 }
81
82
83 /*
84  * Check whether STRING starts with KEYWORD.  The keyword is
85  * delimited by end of string, a space or a tab.  Returns NULL if not
86  * found or a pointer into STRING to the next non-space character
87  * after the KEYWORD (which may be end of string).
88  */
89 char *
90 has_leading_keyword (const char *string, const char *keyword)
91 {
92   size_t n = strlen (keyword);
93
94   if (!strncmp (string, keyword, n)
95       && (!string[n] || string[n] == ' ' || string[n] == '\t'))
96     {
97       string += n;
98       while (*string == ' ' || *string == '\t')
99         string++;
100       return (char*)string;
101     }
102   return NULL;
103 }
104
105
106 /*
107  * Look for the substring SUB in buffer and return a pointer to that
108  * substring in BUFFER or NULL if not found.
109  * Comparison is case-insensitive.
110  */
111 const char *
112 memistr (const void *buffer, size_t buflen, const char *sub)
113 {
114   const unsigned char *buf = buffer;
115   const unsigned char *t = (const unsigned char *)buffer;
116   const unsigned char *s = (const unsigned char *)sub;
117   size_t n = buflen;
118
119   for ( ; n ; t++, n-- )
120     {
121       if ( toupper (*t) == toupper (*s) )
122         {
123           for ( buf=t++, buflen = n--, s++;
124                 n && toupper (*t) == toupper (*s); t++, s++, n-- )
125             ;
126           if (!*s)
127             return (const char*)buf;
128           t = buf;
129           s = (const unsigned char *)sub ;
130           n = buflen;
131         }
132     }
133   return NULL;
134 }
135
136 const char *
137 ascii_memistr ( const void *buffer, size_t buflen, const char *sub )
138 {
139   const unsigned char *buf = buffer;
140   const unsigned char *t = (const unsigned char *)buf;
141   const unsigned char *s = (const unsigned char *)sub;
142   size_t n = buflen;
143
144   for ( ; n ; t++, n-- )
145     {
146       if (ascii_toupper (*t) == ascii_toupper (*s) )
147         {
148           for ( buf=t++, buflen = n--, s++;
149                 n && ascii_toupper (*t) == ascii_toupper (*s); t++, s++, n-- )
150             ;
151           if (!*s)
152             return (const char*)buf;
153           t = (const unsigned char *)buf;
154           s = (const unsigned char *)sub ;
155           n = buflen;
156         }
157     }
158   return NULL;
159 }
160
161 /* This function is similar to strncpy().  However it won't copy more
162    than N - 1 characters and makes sure that a '\0' is appended. With
163    N given as 0, nothing will happen.  With DEST given as NULL, memory
164    will be allocated using xmalloc (i.e. if it runs out of core
165    the function terminates).  Returns DES or a pointer to the
166    allocated memory.
167  */
168 char *
169 mem2str( char *dest , const void *src , size_t n )
170 {
171     char *d;
172     const char *s;
173
174     if( n ) {
175         if( !dest )
176             dest = xmalloc( n ) ;
177         d = dest;
178         s = src ;
179         for(n--; n && *s; n-- )
180             *d++ = *s++;
181         *d = '\0' ;
182     }
183
184     return dest ;
185 }
186
187
188 /****************
189  * remove leading and trailing white spaces
190  */
191 char *
192 trim_spaces( char *str )
193 {
194     char *string, *p, *mark;
195
196     string = str;
197     /* find first non space character */
198     for( p=string; *p && isspace( *(byte*)p ) ; p++ )
199         ;
200     /* move characters */
201     for( (mark = NULL); (*string = *p); string++, p++ )
202         if( isspace( *(byte*)p ) ) {
203             if( !mark )
204                 mark = string ;
205         }
206         else
207             mark = NULL ;
208     if( mark )
209         *mark = '\0' ;  /* remove trailing spaces */
210
211     return str ;
212 }
213
214 /****************
215  * remove trailing white spaces
216  */
217 char *
218 trim_trailing_spaces( char *string )
219 {
220     char *p, *mark;
221
222     for( mark = NULL, p = string; *p; p++ ) {
223         if( isspace( *(byte*)p ) ) {
224             if( !mark )
225                 mark = p;
226         }
227         else
228             mark = NULL;
229     }
230     if( mark )
231         *mark = '\0' ;
232
233     return string ;
234 }
235
236
237 unsigned
238 trim_trailing_chars( byte *line, unsigned len, const char *trimchars )
239 {
240     byte *p, *mark;
241     unsigned n;
242
243     for(mark=NULL, p=line, n=0; n < len; n++, p++ ) {
244         if( strchr(trimchars, *p ) ) {
245             if( !mark )
246                 mark = p;
247         }
248         else
249             mark = NULL;
250     }
251
252     if( mark ) {
253         *mark = 0;
254         return mark - line;
255     }
256     return len;
257 }
258
259 /****************
260  * remove trailing white spaces and return the length of the buffer
261  */
262 unsigned
263 trim_trailing_ws( byte *line, unsigned len )
264 {
265     return trim_trailing_chars( line, len, " \t\r\n" );
266 }
267
268 size_t
269 length_sans_trailing_chars (const unsigned char *line, size_t len,
270                             const char *trimchars )
271 {
272   const unsigned char *p, *mark;
273   size_t n;
274
275   for( mark=NULL, p=line, n=0; n < len; n++, p++ )
276     {
277       if (strchr (trimchars, *p ))
278         {
279           if( !mark )
280             mark = p;
281         }
282       else
283         mark = NULL;
284     }
285
286   if (mark)
287     return mark - line;
288   return len;
289 }
290
291 /*
292  *  Return the length of line ignoring trailing white-space.
293  */
294 size_t
295 length_sans_trailing_ws (const unsigned char *line, size_t len)
296 {
297   return length_sans_trailing_chars (line, len, " \t\r\n");
298 }
299
300
301
302 /*
303  * Extract from a given path the filename component.  This function
304  * terminates the process on memory shortage.
305  */
306 char *
307 make_basename(const char *filepath, const char *inputpath)
308 {
309 #ifdef __riscos__
310     return riscos_make_basename(filepath, inputpath);
311 #else
312     char *p;
313
314     (void)inputpath; /* Only required for riscos.  */
315
316     if ( !(p=strrchr(filepath, '/')) )
317 #ifdef HAVE_DOSISH_SYSTEM
318         if ( !(p=strrchr(filepath, '\\')) )
319 #endif
320 #ifdef HAVE_DRIVE_LETTERS
321             if ( !(p=strrchr(filepath, ':')) )
322 #endif
323               {
324                 return xstrdup(filepath);
325               }
326
327     return xstrdup(p+1);
328 #endif
329 }
330
331
332
333 /*
334  * Extract from a given filename the path prepended to it.  If there
335  * isn't a path prepended to the filename, a dot is returned ('.').
336  * This function terminates the process on memory shortage.
337  */
338 char *
339 make_dirname(const char *filepath)
340 {
341     char *dirname;
342     int  dirname_length;
343     char *p;
344
345     if ( !(p=strrchr(filepath, '/')) )
346 #ifdef HAVE_DOSISH_SYSTEM
347         if ( !(p=strrchr(filepath, '\\')) )
348 #endif
349 #ifdef HAVE_DRIVE_LETTERS
350             if ( !(p=strrchr(filepath, ':')) )
351 #endif
352               {
353                 return xstrdup(".");
354               }
355
356     dirname_length = p-filepath;
357     dirname = xmalloc(dirname_length+1);
358     strncpy(dirname, filepath, dirname_length);
359     dirname[dirname_length] = 0;
360
361     return dirname;
362 }
363
364
365 \f
366 static char *
367 get_pwdir (int xmode, const char *name)
368 {
369   char *result = NULL;
370 #ifdef HAVE_PWD_H
371   struct passwd *pwd = NULL;
372
373   if (name)
374     {
375 #ifdef HAVE_GETPWNAM
376       /* Fixme: We should use getpwnam_r if available.  */
377       pwd = getpwnam (name);
378 #endif
379     }
380   else
381     {
382 #ifdef HAVE_GETPWUID
383       /* Fixme: We should use getpwuid_r if available.  */
384       pwd = getpwuid (getuid());
385 #endif
386     }
387   if (pwd)
388     {
389       if (xmode)
390         result = xstrdup (pwd->pw_dir);
391       else
392         result = xtrystrdup (pwd->pw_dir);
393     }
394 #else /*!HAVE_PWD_H*/
395   /* No support at all.  */
396   (void)xmode;
397   (void)name;
398 #endif /*HAVE_PWD_H*/
399   return result;
400 }
401
402
403 /* xmode 0 := Return NULL on error
404          1 := Terminate on error
405          2 := Make sure that name is absolute; return NULL on error
406          3 := Make sure that name is absolute; terminate on error
407  */
408 static char *
409 do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
410 {
411   const char *argv[32];
412   int argc;
413   size_t n;
414   int skip = 1;
415   char *home_buffer = NULL;
416   char *name, *home, *p;
417   int want_abs;
418
419   want_abs = !!(xmode & 2);
420   xmode &= 1;
421
422   n = strlen (first_part) + 1;
423   argc = 0;
424   while ( (argv[argc] = va_arg (arg_ptr, const char *)) )
425     {
426       n += strlen (argv[argc]) + 1;
427       if (argc >= DIM (argv)-1)
428         {
429           if (xmode)
430             BUG ();
431           gpg_err_set_errno (EINVAL);
432           return NULL;
433         }
434       argc++;
435     }
436   n++;
437
438   home = NULL;
439   if (*first_part == '~')
440     {
441       if (first_part[1] == '/' || !first_part[1])
442         {
443           /* This is the "~/" or "~" case.  */
444           home = getenv("HOME");
445           if (!home)
446             home = home_buffer = get_pwdir (xmode, NULL);
447           if (home && *home)
448             n += strlen (home);
449         }
450       else
451         {
452           /* This is the "~username/" or "~username" case.  */
453           char *user;
454
455           if (xmode)
456             user = xstrdup (first_part+1);
457           else
458             {
459               user = xtrystrdup (first_part+1);
460               if (!user)
461                 return NULL;
462             }
463           p = strchr (user, '/');
464           if (p)
465             *p = 0;
466           skip = 1 + strlen (user);
467
468           home = home_buffer = get_pwdir (xmode, user);
469           xfree (user);
470           if (home)
471             n += strlen (home);
472           else
473             skip = 1;
474         }
475     }
476
477   if (xmode)
478     name = xmalloc (n);
479   else
480     {
481       name = xtrymalloc (n);
482       if (!name)
483         {
484           xfree (home_buffer);
485           return NULL;
486         }
487     }
488
489   if (home)
490     p = stpcpy (stpcpy (name, home), first_part + skip);
491   else
492     p = stpcpy (name, first_part);
493
494   xfree (home_buffer);
495   for (argc=0; argv[argc]; argc++)
496     {
497       /* Avoid a leading double slash if the first part was "/".  */
498       if (!argc && name[0] == '/' && !name[1])
499         p = stpcpy (p, argv[argc]);
500       else
501         p = stpcpy (stpcpy (p, "/"), argv[argc]);
502     }
503
504   if (want_abs)
505     {
506 #ifdef HAVE_DRIVE_LETTERS
507       p = strchr (name, ':');
508       if (p)
509         p++;
510       else
511         p = name;
512 #else
513       p = name;
514 #endif
515       if (*p != '/'
516 #ifdef HAVE_DRIVE_LETTERS
517           && *p != '\\'
518 #endif
519           )
520         {
521           home = gnupg_getcwd ();
522           if (!home)
523             {
524               if (xmode)
525                 {
526                   fprintf (stderr, "\nfatal: getcwd failed: %s\n",
527                            strerror (errno));
528                   exit(2);
529                 }
530               xfree (name);
531               return NULL;
532             }
533           n = strlen (home) + 1 + strlen (name) + 1;
534           if (xmode)
535             home_buffer = xmalloc (n);
536           else
537             {
538               home_buffer = xtrymalloc (n);
539               if (!home_buffer)
540                 {
541                   xfree (name);
542                   return NULL;
543                 }
544             }
545           if (p == name)
546             p = home_buffer;
547           else /* Windows case.  */
548             {
549               memcpy (home_buffer, p, p - name + 1);
550               p = home_buffer + (p - name + 1);
551             }
552
553           /* Avoid a leading double slash if the cwd is "/".  */
554           if (home[0] == '/' && !home[1])
555             strcpy (stpcpy (p, "/"), name);
556           else
557             strcpy (stpcpy (stpcpy (p, home), "/"), name);
558
559           xfree (name);
560           name = home_buffer;
561           /* Let's do a simple compression to catch the most common
562              case of using "." for gpg's --homedir option.  */
563           n = strlen (name);
564           if (n > 2 && name[n-2] == '/' && name[n-1] == '.')
565             name[n-2] = 0;
566         }
567     }
568   return change_slashes (name);
569 }
570
571 /* Construct a filename from the NULL terminated list of parts.  Tilde
572    expansion is done for the first argument.  This function terminates
573    the process on memory shortage. */
574 char *
575 make_filename (const char *first_part, ... )
576 {
577   va_list arg_ptr;
578   char *result;
579
580   va_start (arg_ptr, first_part);
581   result = do_make_filename (1, first_part, arg_ptr);
582   va_end (arg_ptr);
583   return result;
584 }
585
586 /* Construct a filename from the NULL terminated list of parts.  Tilde
587    expansion is done for the first argument.  This function may return
588    NULL on error. */
589 char *
590 make_filename_try (const char *first_part, ... )
591 {
592   va_list arg_ptr;
593   char *result;
594
595   va_start (arg_ptr, first_part);
596   result = do_make_filename (0, first_part, arg_ptr);
597   va_end (arg_ptr);
598   return result;
599 }
600
601 /* Construct an absolute filename from the NULL terminated list of
602    parts.  Tilde expansion is done for the first argument.  This
603    function terminates the process on memory shortage. */
604 char *
605 make_absfilename (const char *first_part, ... )
606 {
607   va_list arg_ptr;
608   char *result;
609
610   va_start (arg_ptr, first_part);
611   result = do_make_filename (3, first_part, arg_ptr);
612   va_end (arg_ptr);
613   return result;
614 }
615
616 /* Construct an absolute filename from the NULL terminated list of
617    parts.  Tilde expansion is done for the first argument.  This
618    function may return NULL on error. */
619 char *
620 make_absfilename_try (const char *first_part, ... )
621 {
622   va_list arg_ptr;
623   char *result;
624
625   va_start (arg_ptr, first_part);
626   result = do_make_filename (2, first_part, arg_ptr);
627   va_end (arg_ptr);
628   return result;
629 }
630
631
632 \f
633 /* Compare whether the filenames are identical.  This is a
634    special version of strcmp() taking the semantics of filenames in
635    account.  Note that this function works only on the supplied names
636    without considering any context like the current directory.  See
637    also same_file_p(). */
638 int
639 compare_filenames (const char *a, const char *b)
640 {
641 #ifdef HAVE_DOSISH_SYSTEM
642   for ( ; *a && *b; a++, b++ )
643     {
644       if (*a != *b
645           && (toupper (*(const unsigned char*)a)
646               != toupper (*(const unsigned char*)b) )
647           && !((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/')))
648         break;
649     }
650   if ((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/'))
651     return 0;
652   else
653     return (toupper (*(const unsigned char*)a)
654             - toupper (*(const unsigned char*)b));
655 #else
656     return strcmp(a,b);
657 #endif
658 }
659
660
661 /* Convert 2 hex characters at S to a byte value.  Return this value
662    or -1 if there is an error. */
663 int
664 hextobyte (const char *s)
665 {
666   int c;
667
668   if ( *s >= '0' && *s <= '9' )
669     c = 16 * (*s - '0');
670   else if ( *s >= 'A' && *s <= 'F' )
671     c = 16 * (10 + *s - 'A');
672   else if ( *s >= 'a' && *s <= 'f' )
673     c = 16 * (10 + *s - 'a');
674   else
675     return -1;
676   s++;
677   if ( *s >= '0' && *s <= '9' )
678     c += *s - '0';
679   else if ( *s >= 'A' && *s <= 'F' )
680     c += 10 + *s - 'A';
681   else if ( *s >= 'a' && *s <= 'f' )
682     c += 10 + *s - 'a';
683   else
684     return -1;
685   return c;
686 }
687
688
689 /* Create a string from the buffer P_ARG of length N which is suitable
690    for printing.  Caller must release the created string using xfree.
691    This function terminates the process on memory shortage.  */
692 char *
693 sanitize_buffer (const void *p_arg, size_t n, int delim)
694 {
695   const unsigned char *p = p_arg;
696   size_t save_n, buflen;
697   const unsigned char *save_p;
698   char *buffer, *d;
699
700   /* First count length. */
701   for (save_n = n, save_p = p, buflen=1 ; n; n--, p++ )
702     {
703       if ( *p < 0x20 || *p == 0x7f || *p == delim  || (delim && *p=='\\'))
704         {
705           if ( *p=='\n' || *p=='\r' || *p=='\f'
706                || *p=='\v' || *p=='\b' || !*p )
707             buflen += 2;
708           else
709             buflen += 5;
710         }
711       else
712         buflen++;
713     }
714   p = save_p;
715   n = save_n;
716   /* And now make the string */
717   d = buffer = xmalloc( buflen );
718   for ( ; n; n--, p++ )
719     {
720       if (*p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) {
721         *d++ = '\\';
722         if( *p == '\n' )
723           *d++ = 'n';
724         else if( *p == '\r' )
725           *d++ = 'r';
726         else if( *p == '\f' )
727           *d++ = 'f';
728         else if( *p == '\v' )
729           *d++ = 'v';
730         else if( *p == '\b' )
731           *d++ = 'b';
732         else if( !*p )
733           *d++ = '0';
734         else {
735           sprintf(d, "x%02x", *p );
736           d += 3;
737         }
738       }
739       else
740         *d++ = *p;
741     }
742   *d = 0;
743   return buffer;
744 }
745
746
747 /* Given a string containing an UTF-8 encoded text, return the number
748    of characters in this string.  It differs from strlen in that it
749    only counts complete UTF-8 characters.  Note, that this function
750    does not take combined characters into account.  */
751 size_t
752 utf8_charcount (const char *s)
753 {
754   size_t n;
755
756   for (n=0; *s; s++)
757     if ( (*s&0xc0) != 0x80 ) /* Exclude continuation bytes: 10xxxxxx */
758       n++;
759
760   return n;
761 }
762
763
764 /****************************************************
765  **********  W32 specific functions  ****************
766  ****************************************************/
767
768 #ifdef HAVE_W32_SYSTEM
769 const char *
770 w32_strerror (int ec)
771 {
772   static char strerr[256];
773
774   if (ec == -1)
775     ec = (int)GetLastError ();
776 #ifdef HAVE_W32CE_SYSTEM
777   /* There is only a wchar_t FormatMessage.  It does not make much
778      sense to play the conversion game; we print only the code.  */
779   snprintf (strerr, sizeof strerr, "ec=%d", (int)GetLastError ());
780 #else
781   FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
782                  MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
783                  strerr, DIM (strerr)-1, NULL);
784 #endif
785   return strerr;
786 }
787 #endif /*HAVE_W32_SYSTEM*/
788
789
790 /****************************************************
791  ******** Locale insensitive ctype functions ********
792  ****************************************************/
793 /* FIXME: replace them by a table lookup and macros */
794 int
795 ascii_isupper (int c)
796 {
797     return c >= 'A' && c <= 'Z';
798 }
799
800 int
801 ascii_islower (int c)
802 {
803     return c >= 'a' && c <= 'z';
804 }
805
806 int
807 ascii_toupper (int c)
808 {
809     if (c >= 'a' && c <= 'z')
810         c &= ~0x20;
811     return c;
812 }
813
814 int
815 ascii_tolower (int c)
816 {
817     if (c >= 'A' && c <= 'Z')
818         c |= 0x20;
819     return c;
820 }
821
822 /* Lowercase all ASCII characters in S.  */
823 char *
824 ascii_strlwr (char *s)
825 {
826   char *p = s;
827
828   for (p=s; *p; p++ )
829     if (isascii (*p) && *p >= 'A' && *p <= 'Z')
830       *p |= 0x20;
831
832   return s;
833 }
834
835 int
836 ascii_strcasecmp( const char *a, const char *b )
837 {
838     if (a == b)
839         return 0;
840
841     for (; *a && *b; a++, b++) {
842         if (*a != *b && ascii_toupper(*a) != ascii_toupper(*b))
843             break;
844     }
845     return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
846 }
847
848 int
849 ascii_strncasecmp (const char *a, const char *b, size_t n)
850 {
851   const unsigned char *p1 = (const unsigned char *)a;
852   const unsigned char *p2 = (const unsigned char *)b;
853   unsigned char c1, c2;
854
855   if (p1 == p2 || !n )
856     return 0;
857
858   do
859     {
860       c1 = ascii_tolower (*p1);
861       c2 = ascii_tolower (*p2);
862
863       if ( !--n || c1 == '\0')
864         break;
865
866       ++p1;
867       ++p2;
868     }
869   while (c1 == c2);
870
871   return c1 - c2;
872 }
873
874
875 int
876 ascii_memcasecmp (const void *a_arg, const void *b_arg, size_t n )
877 {
878   const char *a = a_arg;
879   const char *b = b_arg;
880
881   if (a == b)
882     return 0;
883   for ( ; n; n--, a++, b++ )
884     {
885       if( *a != *b  && ascii_toupper (*a) != ascii_toupper (*b) )
886         return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
887     }
888   return 0;
889 }
890
891 int
892 ascii_strcmp( const char *a, const char *b )
893 {
894     if (a == b)
895         return 0;
896
897     for (; *a && *b; a++, b++) {
898         if (*a != *b )
899             break;
900     }
901     return *a == *b? 0 : (*(signed char *)a - *(signed char *)b);
902 }
903
904
905 void *
906 ascii_memcasemem (const void *haystack, size_t nhaystack,
907                   const void *needle, size_t nneedle)
908 {
909
910   if (!nneedle)
911     return (void*)haystack; /* finding an empty needle is really easy */
912   if (nneedle <= nhaystack)
913     {
914       const char *a = haystack;
915       const char *b = a + nhaystack - nneedle;
916
917       for (; a <= b; a++)
918         {
919           if ( !ascii_memcasecmp (a, needle, nneedle) )
920             return (void *)a;
921         }
922     }
923   return NULL;
924 }
925
926 /*********************************************
927  ********** missing string functions *********
928  *********************************************/
929
930 #ifndef HAVE_STPCPY
931 char *
932 stpcpy(char *a,const char *b)
933 {
934     while( *b )
935         *a++ = *b++;
936     *a = 0;
937
938     return (char*)a;
939 }
940 #endif
941
942 #ifndef HAVE_STRPBRK
943 /* Find the first occurrence in S of any character in ACCEPT.
944    Code taken from glibc-2.6/string/strpbrk.c (LGPLv2.1+) and modified. */
945 char *
946 strpbrk (const char *s, const char *accept)
947 {
948   while (*s != '\0')
949     {
950       const char *a = accept;
951       while (*a != '\0')
952         if (*a++ == *s)
953           return (char *) s;
954       ++s;
955     }
956
957   return NULL;
958 }
959 #endif /*!HAVE_STRPBRK*/
960
961
962 #ifndef HAVE_STRSEP
963 /* Code taken from glibc-2.2.1/sysdeps/generic/strsep.c. */
964 char *
965 strsep (char **stringp, const char *delim)
966 {
967   char *begin, *end;
968
969   begin = *stringp;
970   if (begin == NULL)
971     return NULL;
972
973   /* A frequent case is when the delimiter string contains only one
974      character.  Here we don't need to call the expensive 'strpbrk'
975      function and instead work using 'strchr'.  */
976   if (delim[0] == '\0' || delim[1] == '\0')
977     {
978       char ch = delim[0];
979
980       if (ch == '\0')
981         end = NULL;
982       else
983         {
984           if (*begin == ch)
985             end = begin;
986           else if (*begin == '\0')
987             end = NULL;
988           else
989             end = strchr (begin + 1, ch);
990         }
991     }
992   else
993     /* Find the end of the token.  */
994     end = strpbrk (begin, delim);
995
996   if (end)
997     {
998       /* Terminate the token and set *STRINGP past NUL character.  */
999       *end++ = '\0';
1000       *stringp = end;
1001     }
1002   else
1003     /* No more delimiters; this is the last token.  */
1004     *stringp = NULL;
1005
1006   return begin;
1007 }
1008 #endif /*HAVE_STRSEP*/
1009
1010
1011 #ifndef HAVE_STRLWR
1012 char *
1013 strlwr(char *s)
1014 {
1015     char *p;
1016     for(p=s; *p; p++ )
1017         *p = tolower(*p);
1018     return s;
1019 }
1020 #endif
1021
1022
1023 #ifndef HAVE_STRCASECMP
1024 int
1025 strcasecmp( const char *a, const char *b )
1026 {
1027     for( ; *a && *b; a++, b++ ) {
1028         if( *a != *b && toupper(*a) != toupper(*b) )
1029             break;
1030     }
1031     return *(const byte*)a - *(const byte*)b;
1032 }
1033 #endif
1034
1035
1036 /****************
1037  * mingw32/cpd has a memicmp()
1038  */
1039 #ifndef HAVE_MEMICMP
1040 int
1041 memicmp( const char *a, const char *b, size_t n )
1042 {
1043     for( ; n; n--, a++, b++ )
1044         if( *a != *b  && toupper(*(const byte*)a) != toupper(*(const byte*)b) )
1045             return *(const byte *)a - *(const byte*)b;
1046     return 0;
1047 }
1048 #endif
1049
1050
1051 #ifndef HAVE_MEMRCHR
1052 void *
1053 memrchr (const void *buffer, int c, size_t n)
1054 {
1055   const unsigned char *p = buffer;
1056
1057   for (p += n; n ; n--)
1058     if (*--p == c)
1059       return (void *)p;
1060   return NULL;
1061 }
1062 #endif /*HAVE_MEMRCHR*/
1063
1064 \f
1065 /* Percent-escape the string STR by replacing colons with '%3a'.  If
1066    EXTRA is not NULL all characters in EXTRA are also escaped.  */
1067 static char *
1068 do_percent_escape (const char *str, const char *extra, int die)
1069 {
1070   int i, j;
1071   char *ptr;
1072
1073   if (!str)
1074     return NULL;
1075
1076   for (i=j=0; str[i]; i++)
1077     if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i])))
1078       j++;
1079   if (die)
1080     ptr = xmalloc (i + 2 * j + 1);
1081   else
1082     {
1083       ptr = xtrymalloc (i + 2 * j + 1);
1084       if (!ptr)
1085         return NULL;
1086     }
1087   i = 0;
1088   while (*str)
1089     {
1090       if (*str == ':')
1091         {
1092           ptr[i++] = '%';
1093           ptr[i++] = '3';
1094           ptr[i++] = 'a';
1095         }
1096       else if (*str == '%')
1097         {
1098           ptr[i++] = '%';
1099           ptr[i++] = '2';
1100           ptr[i++] = '5';
1101         }
1102       else if (extra && strchr (extra, *str))
1103         {
1104           ptr[i++] = '%';
1105           ptr[i++] = tohex_lower ((*str>>4)&15);
1106           ptr[i++] = tohex_lower (*str&15);
1107         }
1108       else
1109         ptr[i++] = *str;
1110       str++;
1111     }
1112   ptr[i] = '\0';
1113
1114   return ptr;
1115 }
1116
1117 /* Percent-escape the string STR by replacing colons with '%3a'.  If
1118    EXTRA is not NULL all characters in EXTRA are also escaped.  This
1119    function terminates the process on memory shortage.  */
1120 char *
1121 percent_escape (const char *str, const char *extra)
1122 {
1123   return do_percent_escape (str, extra, 1);
1124 }
1125
1126 /* Same as percent_escape but return NULL instead of exiting on memory
1127    error. */
1128 char *
1129 try_percent_escape (const char *str, const char *extra)
1130 {
1131   return do_percent_escape (str, extra, 0);
1132 }
1133
1134
1135
1136 static char *
1137 do_strconcat (const char *s1, va_list arg_ptr)
1138 {
1139   const char *argv[48];
1140   size_t argc;
1141   size_t needed;
1142   char *buffer, *p;
1143
1144   argc = 0;
1145   argv[argc++] = s1;
1146   needed = strlen (s1);
1147   while (((argv[argc] = va_arg (arg_ptr, const char *))))
1148     {
1149       needed += strlen (argv[argc]);
1150       if (argc >= DIM (argv)-1)
1151         {
1152           gpg_err_set_errno (EINVAL);
1153           return NULL;
1154         }
1155       argc++;
1156     }
1157   needed++;
1158   buffer = xtrymalloc (needed);
1159   if (buffer)
1160     {
1161       for (p = buffer, argc=0; argv[argc]; argc++)
1162         p = stpcpy (p, argv[argc]);
1163     }
1164   return buffer;
1165 }
1166
1167
1168 /* Concatenate the string S1 with all the following strings up to a
1169    NULL.  Returns a malloced buffer with the new string or NULL on a
1170    malloc error or if too many arguments are given.  */
1171 char *
1172 strconcat (const char *s1, ...)
1173 {
1174   va_list arg_ptr;
1175   char *result;
1176
1177   if (!s1)
1178     result = xtrystrdup ("");
1179   else
1180     {
1181       va_start (arg_ptr, s1);
1182       result = do_strconcat (s1, arg_ptr);
1183       va_end (arg_ptr);
1184     }
1185   return result;
1186 }
1187
1188 /* Same as strconcat but terminate the process with an error message
1189    if something goes wrong.  */
1190 char *
1191 xstrconcat (const char *s1, ...)
1192 {
1193   va_list arg_ptr;
1194   char *result;
1195
1196   if (!s1)
1197     result = xstrdup ("");
1198   else
1199     {
1200       va_start (arg_ptr, s1);
1201       result = do_strconcat (s1, arg_ptr);
1202       va_end (arg_ptr);
1203     }
1204   if (!result)
1205     {
1206       if (errno == EINVAL)
1207         fputs ("\nfatal: too many args for xstrconcat\n", stderr);
1208       else
1209         fputs ("\nfatal: out of memory\n", stderr);
1210       exit (2);
1211     }
1212   return result;
1213 }
1214
1215 /* Split a string into fields at DELIM.  REPLACEMENT is the character
1216    to replace the delimiter with (normally: '\0' so that each field is
1217    NUL terminated).  The caller is responsible for freeing the result.
1218    Note: this function modifies STRING!  If you need the original
1219    value, then you should pass a copy to this function.
1220
1221    If malloc fails, this function returns NULL.  */
1222 char **
1223 strsplit (char *string, char delim, char replacement, int *count)
1224 {
1225   int fields = 1;
1226   char *t;
1227   char **result;
1228
1229   /* First, count the number of fields.  */
1230   for (t = strchr (string, delim); t; t = strchr (t + 1, delim))
1231     fields ++;
1232
1233   result = xtrycalloc (sizeof (*result), (fields + 1));
1234   if (! result)
1235     return NULL;
1236
1237   result[0] = string;
1238   fields = 1;
1239   for (t = strchr (string, delim); t; t = strchr (t + 1, delim))
1240     {
1241       result[fields ++] = t + 1;
1242       *t = replacement;
1243     }
1244
1245   if (count)
1246     *count = fields;
1247
1248   return result;
1249 }
1250
1251
1252 /* Tokenize STRING using the set of delimiters in DELIM.  Leading
1253  * spaces and tabs are removed from all tokens.  The caller must xfree
1254  * the result.
1255  *
1256  * Returns: A malloced and NULL delimited array with the tokens.  On
1257  *          memory error NULL is returned and ERRNO is set.
1258  */
1259 char **
1260 strtokenize (const char *string, const char *delim)
1261 {
1262   const char *s;
1263   size_t fields;
1264   size_t bytes, n;
1265   char *buffer;
1266   char *p, *px, *pend;
1267   char **result;
1268
1269   /* Count the number of fields.  */
1270   for (fields = 1, s = strpbrk (string, delim); s; s = strpbrk (s + 1, delim))
1271     fields++;
1272   fields++; /* Add one for the terminating NULL.  */
1273
1274   /* Allocate an array for all fields, a terminating NULL, and space
1275      for a copy of the string.  */
1276   bytes = fields * sizeof *result;
1277   if (bytes / sizeof *result != fields)
1278     {
1279       gpg_err_set_errno (ENOMEM);
1280       return NULL;
1281     }
1282   n = strlen (string) + 1;
1283   bytes += n;
1284   if (bytes < n)
1285     {
1286       gpg_err_set_errno (ENOMEM);
1287       return NULL;
1288     }
1289   result = xtrymalloc (bytes);
1290   if (!result)
1291     return NULL;
1292   buffer = (char*)(result + fields);
1293
1294   /* Copy and parse the string.  */
1295   strcpy (buffer, string);
1296   for (n = 0, p = buffer; (pend = strpbrk (p, delim)); p = pend + 1)
1297     {
1298       *pend = 0;
1299       while (spacep (p))
1300         p++;
1301       for (px = pend - 1; px >= p && spacep (px); px--)
1302         *px = 0;
1303       result[n++] = p;
1304     }
1305   while (spacep (p))
1306     p++;
1307   for (px = p + strlen (p) - 1; px >= p && spacep (px); px--)
1308     *px = 0;
1309   result[n++] = p;
1310   result[n] = NULL;
1311
1312   assert ((char*)(result + n + 1) == buffer);
1313
1314   return result;
1315 }