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