w32: Make make_absfilename work with drive letters.
[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 /* Print a BUFFER to stream FP while replacing all control characters
675    and the characters DELIM and DELIM2 with standard C escape
676    sequences.  Returns the number of characters printed. */
677 size_t
678 print_sanitized_buffer2 (FILE *fp, const void *buffer, size_t length,
679                          int delim, int delim2)
680 {
681   const unsigned char *p = buffer;
682   size_t count = 0;
683
684   for (; length; length--, p++, count++)
685     {
686       if (*p < 0x20
687           || *p == 0x7f
688           || *p == delim
689           || *p == delim2
690           || ((delim || delim2) && *p=='\\'))
691         {
692           putc ('\\', fp);
693           count++;
694           if (*p == '\n')
695             {
696               putc ('n', fp);
697               count++;
698             }
699           else if (*p == '\r')
700             {
701               putc ('r', fp);
702               count++;
703             }
704           else if (*p == '\f')
705             {
706               putc ('f', fp);
707               count++;
708             }
709           else if (*p == '\v')
710             {
711               putc ('v', fp);
712               count++;
713             }
714           else if (*p == '\b')
715             {
716               putc ('b', fp);
717               count++;
718             }
719           else if (!*p)
720             {
721               putc('0', fp);
722               count++;
723             }
724           else
725             {
726               fprintf (fp, "x%02x", *p);
727               count += 3;
728             }
729         }
730       else
731         {
732           putc (*p, fp);
733           count++;
734         }
735     }
736
737   return count;
738 }
739
740 /* Same as print_sanitized_buffer2 but with just one delimiter. */
741 size_t
742 print_sanitized_buffer (FILE *fp, const void *buffer, size_t length,
743                         int delim)
744 {
745   return print_sanitized_buffer2 (fp, buffer, length, delim, 0);
746 }
747
748
749 size_t
750 print_sanitized_utf8_buffer (FILE *fp, const void *buffer,
751                              size_t length, int delim)
752 {
753   const char *p = buffer;
754   size_t i;
755
756   /* We can handle plain ascii simpler, so check for it first. */
757   for (i=0; i < length; i++ )
758     {
759       if ( (p[i] & 0x80) )
760         break;
761     }
762   if (i < length)
763     {
764         char *buf = utf8_to_native (p, length, delim);
765         /*(utf8 conversion already does the control character quoting)*/
766         i = strlen (buf);
767         fputs (buf, fp);
768         jnlib_free (buf);
769         return i;
770     }
771   else
772     return print_sanitized_buffer (fp, p, length, delim);
773 }
774
775
776 size_t
777 print_sanitized_string2 (FILE *fp, const char *string, int delim, int delim2)
778 {
779   return string? print_sanitized_buffer2 (fp, string, strlen (string),
780                                           delim, delim2):0;
781 }
782
783 size_t
784 print_sanitized_string (FILE *fp, const char *string, int delim)
785 {
786   return string? print_sanitized_buffer (fp, string, strlen (string), delim):0;
787 }
788
789 size_t
790 print_sanitized_utf8_string (FILE *fp, const char *string, int delim)
791 {
792   return string? print_sanitized_utf8_buffer (fp,
793                                               string, strlen (string),
794                                               delim) : 0;
795 }
796
797 /* Create a string from the buffer P_ARG of length N which is suitable
798    for printing.  Caller must release the created string using xfree.
799    This function terminates the process on memory shortage.  */
800 char *
801 sanitize_buffer (const void *p_arg, size_t n, int delim)
802 {
803   const unsigned char *p = p_arg;
804   size_t save_n, buflen;
805   const unsigned char *save_p;
806   char *buffer, *d;
807
808   /* First count length. */
809   for (save_n = n, save_p = p, buflen=1 ; n; n--, p++ )
810     {
811       if ( *p < 0x20 || *p == 0x7f || *p == delim  || (delim && *p=='\\'))
812         {
813           if ( *p=='\n' || *p=='\r' || *p=='\f'
814                || *p=='\v' || *p=='\b' || !*p )
815             buflen += 2;
816           else
817             buflen += 5;
818         }
819       else
820         buflen++;
821     }
822   p = save_p;
823   n = save_n;
824   /* And now make the string */
825   d = buffer = jnlib_xmalloc( buflen );
826   for ( ; n; n--, p++ )
827     {
828       if (*p < 0x20 || *p == 0x7f || *p == delim || (delim && *p=='\\')) {
829         *d++ = '\\';
830         if( *p == '\n' )
831           *d++ = 'n';
832         else if( *p == '\r' )
833           *d++ = 'r';
834         else if( *p == '\f' )
835           *d++ = 'f';
836         else if( *p == '\v' )
837           *d++ = 'v';
838         else if( *p == '\b' )
839           *d++ = 'b';
840         else if( !*p )
841           *d++ = '0';
842         else {
843           sprintf(d, "x%02x", *p );
844           d += 3;
845         }
846       }
847       else
848         *d++ = *p;
849     }
850   *d = 0;
851   return buffer;
852 }
853
854
855 /* Given a string containing an UTF-8 encoded text, return the number
856    of characters in this string.  It differs from strlen in that it
857    only counts complete UTF-8 characters.  Note, that this function
858    does not take combined characters into account.  */
859 size_t
860 utf8_charcount (const char *s)
861 {
862   size_t n;
863
864   for (n=0; *s; s++)
865     if ( (*s&0xc0) != 0x80 ) /* Exclude continuation bytes: 10xxxxxx */
866       n++;
867
868   return n;
869 }
870
871
872 /****************************************************
873  **********  W32 specific functions  ****************
874  ****************************************************/
875
876 #ifdef HAVE_W32_SYSTEM
877 const char *
878 w32_strerror (int ec)
879 {
880   static char strerr[256];
881
882   if (ec == -1)
883     ec = (int)GetLastError ();
884 #ifdef HAVE_W32CE_SYSTEM
885   /* There is only a wchar_t FormatMessage.  It does not make much
886      sense to play the conversion game; we print only the code.  */
887   snprintf (strerr, sizeof strerr, "ec=%d", (int)GetLastError ());
888 #else
889   FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
890                  MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
891                  strerr, DIM (strerr)-1, NULL);
892 #endif
893   return strerr;
894 }
895 #endif /*HAVE_W32_SYSTEM*/
896
897
898 /****************************************************
899  ******** Locale insensitive ctype functions ********
900  ****************************************************/
901 /* FIXME: replace them by a table lookup and macros */
902 int
903 ascii_isupper (int c)
904 {
905     return c >= 'A' && c <= 'Z';
906 }
907
908 int
909 ascii_islower (int c)
910 {
911     return c >= 'a' && c <= 'z';
912 }
913
914 int
915 ascii_toupper (int c)
916 {
917     if (c >= 'a' && c <= 'z')
918         c &= ~0x20;
919     return c;
920 }
921
922 int
923 ascii_tolower (int c)
924 {
925     if (c >= 'A' && c <= 'Z')
926         c |= 0x20;
927     return c;
928 }
929
930
931 int
932 ascii_strcasecmp( const char *a, const char *b )
933 {
934     if (a == b)
935         return 0;
936
937     for (; *a && *b; a++, b++) {
938         if (*a != *b && ascii_toupper(*a) != ascii_toupper(*b))
939             break;
940     }
941     return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
942 }
943
944 int
945 ascii_strncasecmp (const char *a, const char *b, size_t n)
946 {
947   const unsigned char *p1 = (const unsigned char *)a;
948   const unsigned char *p2 = (const unsigned char *)b;
949   unsigned char c1, c2;
950
951   if (p1 == p2 || !n )
952     return 0;
953
954   do
955     {
956       c1 = ascii_tolower (*p1);
957       c2 = ascii_tolower (*p2);
958
959       if ( !--n || c1 == '\0')
960         break;
961
962       ++p1;
963       ++p2;
964     }
965   while (c1 == c2);
966
967   return c1 - c2;
968 }
969
970
971 int
972 ascii_memcasecmp (const void *a_arg, const void *b_arg, size_t n )
973 {
974   const char *a = a_arg;
975   const char *b = b_arg;
976
977   if (a == b)
978     return 0;
979   for ( ; n; n--, a++, b++ )
980     {
981       if( *a != *b  && ascii_toupper (*a) != ascii_toupper (*b) )
982         return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
983     }
984   return 0;
985 }
986
987 int
988 ascii_strcmp( const char *a, const char *b )
989 {
990     if (a == b)
991         return 0;
992
993     for (; *a && *b; a++, b++) {
994         if (*a != *b )
995             break;
996     }
997     return *a == *b? 0 : (*(signed char *)a - *(signed char *)b);
998 }
999
1000
1001 void *
1002 ascii_memcasemem (const void *haystack, size_t nhaystack,
1003                   const void *needle, size_t nneedle)
1004 {
1005
1006   if (!nneedle)
1007     return (void*)haystack; /* finding an empty needle is really easy */
1008   if (nneedle <= nhaystack)
1009     {
1010       const char *a = haystack;
1011       const char *b = a + nhaystack - nneedle;
1012
1013       for (; a <= b; a++)
1014         {
1015           if ( !ascii_memcasecmp (a, needle, nneedle) )
1016             return (void *)a;
1017         }
1018     }
1019   return NULL;
1020 }
1021
1022 /*********************************************
1023  ********** missing string functions *********
1024  *********************************************/
1025
1026 #ifndef HAVE_STPCPY
1027 char *
1028 stpcpy(char *a,const char *b)
1029 {
1030     while( *b )
1031         *a++ = *b++;
1032     *a = 0;
1033
1034     return (char*)a;
1035 }
1036 #endif
1037
1038 #ifndef HAVE_STRSEP
1039 /* Code taken from glibc-2.2.1/sysdeps/generic/strsep.c. */
1040 char *
1041 strsep (char **stringp, const char *delim)
1042 {
1043   char *begin, *end;
1044
1045   begin = *stringp;
1046   if (begin == NULL)
1047     return NULL;
1048
1049   /* A frequent case is when the delimiter string contains only one
1050      character.  Here we don't need to call the expensive 'strpbrk'
1051      function and instead work using 'strchr'.  */
1052   if (delim[0] == '\0' || delim[1] == '\0')
1053     {
1054       char ch = delim[0];
1055
1056       if (ch == '\0')
1057         end = NULL;
1058       else
1059         {
1060           if (*begin == ch)
1061             end = begin;
1062           else if (*begin == '\0')
1063             end = NULL;
1064           else
1065             end = strchr (begin + 1, ch);
1066         }
1067     }
1068   else
1069     /* Find the end of the token.  */
1070     end = strpbrk (begin, delim);
1071
1072   if (end)
1073     {
1074       /* Terminate the token and set *STRINGP past NUL character.  */
1075       *end++ = '\0';
1076       *stringp = end;
1077     }
1078   else
1079     /* No more delimiters; this is the last token.  */
1080     *stringp = NULL;
1081
1082   return begin;
1083 }
1084 #endif /*HAVE_STRSEP*/
1085
1086
1087 #ifndef HAVE_STRLWR
1088 char *
1089 strlwr(char *s)
1090 {
1091     char *p;
1092     for(p=s; *p; p++ )
1093         *p = tolower(*p);
1094     return s;
1095 }
1096 #endif
1097
1098
1099 #ifndef HAVE_STRCASECMP
1100 int
1101 strcasecmp( const char *a, const char *b )
1102 {
1103     for( ; *a && *b; a++, b++ ) {
1104         if( *a != *b && toupper(*a) != toupper(*b) )
1105             break;
1106     }
1107     return *(const byte*)a - *(const byte*)b;
1108 }
1109 #endif
1110
1111
1112 /****************
1113  * mingw32/cpd has a memicmp()
1114  */
1115 #ifndef HAVE_MEMICMP
1116 int
1117 memicmp( const char *a, const char *b, size_t n )
1118 {
1119     for( ; n; n--, a++, b++ )
1120         if( *a != *b  && toupper(*(const byte*)a) != toupper(*(const byte*)b) )
1121             return *(const byte *)a - *(const byte*)b;
1122     return 0;
1123 }
1124 #endif
1125
1126
1127 #ifndef HAVE_MEMRCHR
1128 void *
1129 memrchr (const void *buffer, int c, size_t n)
1130 {
1131   const unsigned char *p = buffer;
1132
1133   for (p += n; n ; n--)
1134     if (*--p == c)
1135       return (void *)p;
1136   return NULL;
1137 }
1138 #endif /*HAVE_MEMRCHR*/
1139
1140 \f
1141 /* Percent-escape the string STR by replacing colons with '%3a'.  If
1142    EXTRA is not NULL all characters in EXTRA are also escaped.  */
1143 static char *
1144 do_percent_escape (const char *str, const char *extra, int die)
1145 {
1146   int i, j;
1147   char *ptr;
1148
1149   if (!str)
1150     return NULL;
1151
1152   for (i=j=0; str[i]; i++)
1153     if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i])))
1154       j++;
1155   if (die)
1156     ptr = jnlib_xmalloc (i + 2 * j + 1);
1157   else
1158     {
1159       ptr = jnlib_malloc (i + 2 * j + 1);
1160       if (!ptr)
1161         return NULL;
1162     }
1163   i = 0;
1164   while (*str)
1165     {
1166       if (*str == ':')
1167         {
1168           ptr[i++] = '%';
1169           ptr[i++] = '3';
1170           ptr[i++] = 'a';
1171         }
1172       else if (*str == '%')
1173         {
1174           ptr[i++] = '%';
1175           ptr[i++] = '2';
1176           ptr[i++] = '5';
1177         }
1178       else if (extra && strchr (extra, *str))
1179         {
1180           ptr[i++] = '%';
1181           ptr[i++] = tohex_lower ((*str>>4)&15);
1182           ptr[i++] = tohex_lower (*str&15);
1183         }
1184       else
1185         ptr[i++] = *str;
1186       str++;
1187     }
1188   ptr[i] = '\0';
1189
1190   return ptr;
1191 }
1192
1193 /* Percent-escape the string STR by replacing colons with '%3a'.  If
1194    EXTRA is not NULL all characters in EXTRA are also escaped.  This
1195    function terminates the process on memory shortage.  */
1196 char *
1197 percent_escape (const char *str, const char *extra)
1198 {
1199   return do_percent_escape (str, extra, 1);
1200 }
1201
1202 /* Same as percent_escape but return NULL instead of exiting on memory
1203    error. */
1204 char *
1205 try_percent_escape (const char *str, const char *extra)
1206 {
1207   return do_percent_escape (str, extra, 0);
1208 }
1209
1210
1211
1212 static char *
1213 do_strconcat (const char *s1, va_list arg_ptr)
1214 {
1215   const char *argv[48];
1216   size_t argc;
1217   size_t needed;
1218   char *buffer, *p;
1219
1220   argc = 0;
1221   argv[argc++] = s1;
1222   needed = strlen (s1);
1223   while (((argv[argc] = va_arg (arg_ptr, const char *))))
1224     {
1225       needed += strlen (argv[argc]);
1226       if (argc >= DIM (argv)-1)
1227         {
1228           jnlib_set_errno (EINVAL);
1229           return NULL;
1230         }
1231       argc++;
1232     }
1233   needed++;
1234   buffer = jnlib_malloc (needed);
1235   if (buffer)
1236     {
1237       for (p = buffer, argc=0; argv[argc]; argc++)
1238         p = stpcpy (p, argv[argc]);
1239     }
1240   return buffer;
1241 }
1242
1243
1244 /* Concatenate the string S1 with all the following strings up to a
1245    NULL.  Returns a malloced buffer with the new string or NULL on a
1246    malloc error or if too many arguments are given.  */
1247 char *
1248 strconcat (const char *s1, ...)
1249 {
1250   va_list arg_ptr;
1251   char *result;
1252
1253   if (!s1)
1254     result = jnlib_strdup ("");
1255   else
1256     {
1257       va_start (arg_ptr, s1);
1258       result = do_strconcat (s1, arg_ptr);
1259       va_end (arg_ptr);
1260     }
1261   return result;
1262 }
1263
1264 /* Same as strconcat but terminate the process with an error message
1265    if something goes wrong.  */
1266 char *
1267 xstrconcat (const char *s1, ...)
1268 {
1269   va_list arg_ptr;
1270   char *result;
1271
1272   if (!s1)
1273     result = jnlib_xstrdup ("");
1274   else
1275     {
1276       va_start (arg_ptr, s1);
1277       result = do_strconcat (s1, arg_ptr);
1278       va_end (arg_ptr);
1279     }
1280   if (!result)
1281     {
1282       if (errno == EINVAL)
1283         fputs ("\nfatal: too many args for xstrconcat\n", stderr);
1284       else
1285         fputs ("\nfatal: out of memory\n", stderr);
1286       exit (2);
1287     }
1288   return result;
1289 }