1
1
/* stringhelp.c - standard string helper functions
2
* Copyright (C) 1998, 1999, 2000, 2001, 2003,
3
* 2004, 2005 Free Software Foundation, Inc.
5
* This file is part of GnuPG.
7
* GnuPG is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* GnuPG is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
2
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005,
3
* 2006, 2007 Free Software Foundation, Inc.
5
* This file is part of JNLIB.
7
* JNLIB is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU Lesser General Public License as
9
* published by the Free Software Foundation; either version 3 of
10
* the License, or (at your option) any later version.
12
* JNLIB is distributed in the hope that it will be useful, but
13
* WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
22
21
#include <config.h>
292
297
make_filename( const char *first_part, ... )
297
char *name, *home, *p;
299
va_start( arg_ptr, first_part ) ;
300
n = strlen(first_part)+1;
301
while( (s=va_arg(arg_ptr, const char *)) )
306
if( *first_part == '~' && first_part[1] == '/'
307
&& (home = getenv("HOME")) && *home )
310
name = jnlib_xmalloc(n);
311
p = home ? stpcpy(stpcpy(name,home), first_part+1)
312
: stpcpy(name, first_part);
313
va_start( arg_ptr, first_part ) ;
314
while( (s=va_arg(arg_ptr, const char *)) )
315
p = stpcpy(stpcpy(p,"/"), s);
302
char *name, *home, *p;
304
va_start (arg_ptr, first_part);
305
n = strlen (first_part) + 1;
306
while ( (s = va_arg (arg_ptr, const char *)) )
311
if ( *first_part == '~' && first_part[1] == '/'
312
&& (home = getenv("HOME")) && *home )
315
name = jnlib_xmalloc (n);
317
? stpcpy (stpcpy (name,home), first_part + 1)
318
: stpcpy(name, first_part));
320
va_start (arg_ptr, first_part) ;
321
while ( (s = va_arg(arg_ptr, const char *)) )
322
p = stpcpy (stpcpy (p,"/"), s);
325
#ifdef HAVE_DRIVE_LETTERS
326
/* We better avoid mixing slashes and backslashes and prefer
327
backslashes. There is usual no problem with mixing them, however
328
a very few W32 API calls can't grok plain slashes. Printing
329
filenames with mixed slashes also looks a bit strange. */
330
if (strchr (name, '\\'))
332
for (p=name; *p; p++)
336
#endif /*HAVE_DRIVE_LETTERS*/
341
/* Compare whether the filenames are identical. This is a
342
special version of strcmp() taking the semantics of filenames in
343
account. Note that this function works only on the supplied names
344
without considereing any context like the current directory. See
345
also same_file_p(). */
323
compare_filenames( const char *a, const char *b )
347
compare_filenames (const char *a, const char *b)
325
/* ? check whether this is an absolute filename and
328
349
#ifdef HAVE_DRIVE_LETTERS
350
for ( ; *a && *b; a++, b++ )
353
&& (toupper (*(const unsigned char*)a)
354
!= toupper (*(const unsigned char*)b) )
355
&& !((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/')))
358
if ((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/'))
361
return (toupper (*(const unsigned char*)a)
362
- toupper (*(const unsigned char*)b));
331
364
return strcmp(a,b);
369
/* Convert 2 hex characters at S to a byte value. Return this value
370
or -1 if there is an error. */
372
hextobyte (const char *s)
376
if ( *s >= '0' && *s <= '9' )
378
else if ( *s >= 'A' && *s <= 'F' )
379
c = 16 * (10 + *s - 'A');
380
else if ( *s >= 'a' && *s <= 'f' )
381
c = 16 * (10 + *s - 'a');
385
if ( *s >= '0' && *s <= '9' )
387
else if ( *s >= 'A' && *s <= 'F' )
389
else if ( *s >= 'a' && *s <= 'f' )
335
397
/* Print a BUFFER to stream FP while replacing all control characters
336
and the character DELIM with standard C escape sequences. Returns
337
the number of characters printed. */
398
and the characters DELIM and DELIM2 with standard C escape
399
sequences. Returns the number of characters printed. */
339
print_sanitized_buffer (FILE *fp, const void *buffer, size_t length,
401
print_sanitized_buffer2 (FILE *fp, const void *buffer, size_t length,
402
int delim, int delim2)
342
404
const unsigned char *p = buffer;
343
405
size_t count = 0;
345
407
for (; length; length--, p++, count++)
347
if (*p < 0x20 || *p == 0x7f || *p == delim)
409
/* Fixme: Check whether *p < 0xa0 is correct for utf8 encoding. */
411
|| (*p >= 0x7f && *p < 0xa0)
414
|| ((delim || delim2) && *p=='\\'))
353
423
else if (*p == '\r')
355
428
else if (*p == '\f')
357
433
else if (*p == '\v')
359
438
else if (*p == '\b')
365
450
fprintf (fp, "x%02x", *p);
464
/* Same as print_sanitized_buffer2 but with just one delimiter. */
466
print_sanitized_buffer (FILE *fp, const void *buffer, size_t length,
469
return print_sanitized_buffer2 (fp, buffer, length, delim, 0);
377
474
print_sanitized_utf8_buffer (FILE *fp, const void *buffer,
378
475
size_t length, int delim)
846
memrchr (const void *buffer, int c, size_t n)
848
const unsigned char *p = buffer;
850
for (p += n; n ; n--)
855
#endif /*HAVE_MEMRCHR*/
858
/* Percent-escape the string STR by replacing colons with '%3a'. If
859
EXTRA is not NULL all characters in EXTRA are also escaped. */
861
do_percent_escape (const char *str, const char *extra, int die)
869
for (i=j=0; str[i]; i++)
870
if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i])))
873
ptr = jnlib_xmalloc (i + 2 * j + 1);
876
ptr = jnlib_malloc (i + 2 * j + 1);
889
else if (*str == '%')
895
else if (extra && strchr (extra, *str))
898
ptr[i++] = tohex_lower ((*str>>4)&15);
899
ptr[i++] = tohex_lower (*str&15);
910
/* Percent-escape the string STR by replacing colons with '%3a'. If
911
EXTRA is not NULL all characters in EXTRA are also escaped. */
913
percent_escape (const char *str, const char *extra)
915
return do_percent_escape (str, extra, 1);
918
/* Same as percent_escape but return NULL instead of exiting on memory
921
try_percent_escape (const char *str, const char *extra)
923
return do_percent_escape (str, extra, 0);