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