~ubuntu-branches/ubuntu/karmic/gnupg2/karmic-updates

« back to all changes in this revision

Viewing changes to jnlib/stringhelp.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* stringhelp.c -  standard string helper functions
2
 
 * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3
 
 *               2004, 2005  Free Software Foundation, Inc.
4
 
 *
5
 
 * This file is part of GnuPG.
6
 
 *
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.
11
 
 *
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.
16
 
 *
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.
 
4
 *
 
5
 * This file is part of JNLIB.
 
6
 *
 
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.
 
11
 *
 
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.
 
16
 *
 
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/>.
20
19
 */
21
20
 
22
21
#include <config.h>
33
32
#include "stringhelp.h"
34
33
 
35
34
 
 
35
#define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a'))
 
36
 
36
37
/*
37
38
 * Look for the substring SUB in buffer and return a pointer to that
38
39
 * substring in BUFFER or NULL if not found.
218
219
  return len;
219
220
}
220
221
 
221
 
/****************
222
 
 * remove trailing white spaces and return the length of the buffer
 
222
/*
 
223
 *  Return the length of line ignoring trailing white-space.
223
224
 */
224
225
size_t
225
226
length_sans_trailing_ws (const unsigned char *line, size_t len)
234
235
 *
235
236
 */
236
237
char *
237
 
make_basename(const char *filepath)
 
238
make_basename(const char *filepath, const char *inputpath)
238
239
{
239
240
    char *p;
240
241
 
 
242
#ifdef __riscos__
 
243
    return riscos_make_basename(filepath, inputpath);
 
244
#endif
 
245
 
241
246
    if ( !(p=strrchr(filepath, '/')) )
242
 
      #ifdef HAVE_DRIVE_LETTERS
 
247
#ifdef HAVE_DRIVE_LETTERS
243
248
        if ( !(p=strrchr(filepath, '\\')) )
244
249
            if ( !(p=strrchr(filepath, ':')) )
245
 
      #endif
 
250
#endif
246
251
              {
247
252
                return jnlib_xstrdup(filepath);
248
253
              }
266
271
    char *p;
267
272
 
268
273
    if ( !(p=strrchr(filepath, '/')) )
269
 
      #ifdef HAVE_DRIVE_LETTERS
 
274
#ifdef HAVE_DRIVE_LETTERS
270
275
        if ( !(p=strrchr(filepath, '\\')) )
271
276
            if ( !(p=strrchr(filepath, ':')) )
272
 
      #endif
 
277
#endif
273
278
              {
274
279
                return jnlib_xstrdup(".");
275
280
              }
291
296
char *
292
297
make_filename( const char *first_part, ... )
293
298
{
294
 
    va_list arg_ptr ;
295
 
    size_t n;
296
 
    const char *s;
297
 
    char *name, *home, *p;
298
 
 
299
 
    va_start( arg_ptr, first_part ) ;
300
 
    n = strlen(first_part)+1;
301
 
    while( (s=va_arg(arg_ptr, const char *)) )
302
 
        n += strlen(s) + 1;
303
 
    va_end(arg_ptr);
304
 
 
305
 
    home = NULL;
306
 
    if( *first_part == '~' && first_part[1] == '/'
307
 
                           && (home = getenv("HOME")) && *home )
308
 
        n += strlen(home);
309
 
 
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);
316
 
    va_end(arg_ptr);
317
 
 
318
 
    return name;
 
299
  va_list arg_ptr ;
 
300
  size_t n;
 
301
  const char *s;
 
302
  char *name, *home, *p;
 
303
  
 
304
  va_start (arg_ptr, first_part);
 
305
  n = strlen (first_part) + 1;
 
306
  while ( (s = va_arg (arg_ptr, const char *)) )
 
307
    n += strlen(s) + 1;
 
308
  va_end(arg_ptr);
 
309
  
 
310
  home = NULL;
 
311
  if ( *first_part == '~' && first_part[1] == '/'
 
312
       && (home = getenv("HOME")) && *home )
 
313
    n += strlen (home);
 
314
  
 
315
  name = jnlib_xmalloc (n);
 
316
  p = (home 
 
317
       ? stpcpy (stpcpy (name,home), first_part + 1)
 
318
       : stpcpy(name, first_part));
 
319
 
 
320
  va_start (arg_ptr, first_part) ;
 
321
  while ( (s = va_arg(arg_ptr, const char *)) )
 
322
    p = stpcpy (stpcpy (p,"/"), s);
 
323
  va_end(arg_ptr);
 
324
 
 
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, '\\'))
 
331
    {
 
332
      for (p=name; *p; p++)
 
333
        if (*p == '/')
 
334
          *p = '\\';
 
335
    }
 
336
#endif /*HAVE_DRIVE_LETTERS*/
 
337
  return name;
319
338
}
320
339
 
321
340
 
 
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(). */
322
346
int
323
 
compare_filenames( const char *a, const char *b )
 
347
compare_filenames (const char *a, const char *b)
324
348
{
325
 
    /* ? check whether this is an absolute filename and
326
 
     * resolve symlinks?
327
 
     */
328
349
#ifdef HAVE_DRIVE_LETTERS
329
 
    return stricmp(a,b);
 
350
  for ( ; *a && *b; a++, b++ ) 
 
351
    {
 
352
      if (*a != *b 
 
353
          && (toupper (*(const unsigned char*)a)
 
354
              != toupper (*(const unsigned char*)b) )
 
355
          && !((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/')))
 
356
        break;
 
357
    }
 
358
  if ((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/'))
 
359
    return 0;
 
360
  else
 
361
    return (toupper (*(const unsigned char*)a) 
 
362
            - toupper (*(const unsigned char*)b));
330
363
#else
331
364
    return strcmp(a,b);
332
365
#endif
333
366
}
334
367
 
 
368
 
 
369
/* Convert 2 hex characters at S to a byte value.  Return this value
 
370
   or -1 if there is an error. */
 
371
int
 
372
hextobyte (const char *s)
 
373
{
 
374
  int c;
 
375
 
 
376
  if ( *s >= '0' && *s <= '9' )
 
377
    c = 16 * (*s - '0');
 
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');
 
382
  else
 
383
    return -1;
 
384
  s++;
 
385
  if ( *s >= '0' && *s <= '9' )
 
386
    c += *s - '0';
 
387
  else if ( *s >= 'A' && *s <= 'F' )
 
388
    c += 10 + *s - 'A';
 
389
  else if ( *s >= 'a' && *s <= 'f' )
 
390
    c += 10 + *s - 'a';
 
391
  else
 
392
    return -1;
 
393
  return c;
 
394
}
 
395
 
 
396
 
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. */
338
400
size_t 
339
 
print_sanitized_buffer (FILE *fp, const void *buffer, size_t length,
340
 
                        int delim)
 
401
print_sanitized_buffer2 (FILE *fp, const void *buffer, size_t length,
 
402
                         int delim, int delim2)
341
403
{
342
404
  const unsigned char *p = buffer;
343
405
  size_t count = 0;
344
406
 
345
407
  for (; length; length--, p++, count++)
346
408
    {
347
 
      if (*p < 0x20 || *p == 0x7f || *p == delim)
 
409
      /* Fixme: Check whether *p < 0xa0 is correct for utf8 encoding. */
 
410
      if (*p < 0x20 
 
411
          || (*p >= 0x7f && *p < 0xa0)
 
412
          || *p == delim 
 
413
          || *p == delim2
 
414
          || ((delim || delim2) && *p=='\\'))
348
415
        {
349
416
          putc ('\\', fp);
350
417
          count++;
351
418
          if (*p == '\n')
352
 
            putc ('n', fp);
 
419
            {
 
420
              putc ('n', fp);
 
421
              count++;
 
422
            }
353
423
          else if (*p == '\r')
354
 
            putc ('r', fp);
 
424
            {
 
425
              putc ('r', fp);
 
426
              count++;
 
427
            }
355
428
          else if (*p == '\f')
356
 
            putc ('f', fp);
 
429
            {
 
430
              putc ('f', fp);
 
431
              count++;
 
432
            }
357
433
          else if (*p == '\v')
358
 
            putc ('v', fp);
 
434
            {
 
435
              putc ('v', fp);
 
436
              count++;
 
437
            }
359
438
          else if (*p == '\b')
360
 
            putc ('b', fp);
 
439
            {
 
440
              putc ('b', fp);
 
441
              count++;
 
442
            }
361
443
          else if (!*p)
362
 
            putc('0', fp);
 
444
            {
 
445
              putc('0', fp);
 
446
              count++;
 
447
            }
363
448
          else
364
449
            {
365
450
              fprintf (fp, "x%02x", *p);
366
 
              count += 2;
 
451
              count += 3;
367
452
            }
368
453
        }
369
454
      else
370
 
        putc (*p, fp);
 
455
        {
 
456
          putc (*p, fp);
 
457
          count++;
 
458
        }
371
459
    }
372
460
 
373
461
  return count;
374
462
}
375
463
 
 
464
/* Same as print_sanitized_buffer2 but with just one delimiter. */
 
465
size_t 
 
466
print_sanitized_buffer (FILE *fp, const void *buffer, size_t length,
 
467
                        int delim)
 
468
{
 
469
  return print_sanitized_buffer2 (fp, buffer, length, delim, 0);
 
470
}
 
471
 
 
472
 
376
473
size_t 
377
474
print_sanitized_utf8_buffer (FILE *fp, const void *buffer,
378
475
                             size_t length, int delim)
401
498
 
402
499
 
403
500
size_t 
 
501
print_sanitized_string2 (FILE *fp, const char *string, int delim, int delim2)
 
502
{
 
503
  return string? print_sanitized_buffer2 (fp, string, strlen (string),
 
504
                                          delim, delim2):0;
 
505
}
 
506
 
 
507
size_t 
404
508
print_sanitized_string (FILE *fp, const char *string, int delim)
405
509
{
406
510
  return string? print_sanitized_buffer (fp, string, strlen (string), delim):0;
424
528
  const unsigned char *save_p;
425
529
  char *buffer, *d;
426
530
 
427
 
  /* first count length */
 
531
  /* First count length. */
428
532
  for (save_n = n, save_p = p, buflen=1 ; n; n--, p++ ) 
429
533
    {
430
534
      if ( *p < 0x20 || *p == 0x7f || *p == delim  || (delim && *p=='\\'))
433
537
               || *p=='\v' || *p=='\b' || !*p )
434
538
            buflen += 2;
435
539
          else
436
 
            buflen += 4;
 
540
            buflen += 5;
437
541
        }
438
542
      else
439
543
        buflen++;
440
544
    }
441
545
  p = save_p;
442
546
  n = save_n;
443
 
  /* and now make the string */
 
547
  /* And now make the string */
444
548
  d = buffer = jnlib_xmalloc( buflen );
445
549
  for ( ; n; n--, p++ )
446
550
    {
460
564
          *d++ = '0';
461
565
        else {
462
566
          sprintf(d, "x%02x", *p );
463
 
          d += 2;
 
567
          d += 3;
464
568
        }
465
569
      }
466
570
      else
471
575
}
472
576
 
473
577
 
 
578
/* Given a string containing an UTF-8 encoded text, return the number
 
579
   of characters in this string.  It differs from strlen in that it
 
580
   only counts complete UTF-8 characters.  Note, that this function
 
581
   does not take combined characters into account.  */
 
582
size_t
 
583
utf8_charcount (const char *s)
 
584
{
 
585
  size_t n;
 
586
 
 
587
  for (n=0; *s; s++)
 
588
    if ( (*s&0xc0) != 0x80 ) /* Exclude continuation bytes: 10xxxxxx */
 
589
      n++;
 
590
 
 
591
  return n;
 
592
}
 
593
 
 
594
 
474
595
/****************************************************
475
596
 **********  W32 specific functions  ****************
476
597
 ****************************************************/
631
752
}
632
753
#endif
633
754
 
 
755
#ifndef HAVE_STRSEP
 
756
/* Code taken from glibc-2.2.1/sysdeps/generic/strsep.c. */
 
757
char *
 
758
strsep (char **stringp, const char *delim)
 
759
{
 
760
  char *begin, *end;
 
761
 
 
762
  begin = *stringp;
 
763
  if (begin == NULL)
 
764
    return NULL;
 
765
 
 
766
  /* A frequent case is when the delimiter string contains only one
 
767
     character.  Here we don't need to call the expensive `strpbrk'
 
768
     function and instead work using `strchr'.  */
 
769
  if (delim[0] == '\0' || delim[1] == '\0')
 
770
    {
 
771
      char ch = delim[0];
 
772
 
 
773
      if (ch == '\0')
 
774
        end = NULL;
 
775
      else
 
776
        {
 
777
          if (*begin == ch)
 
778
            end = begin;
 
779
          else if (*begin == '\0')
 
780
            end = NULL;
 
781
          else
 
782
            end = strchr (begin + 1, ch);
 
783
        }
 
784
    }
 
785
  else
 
786
    /* Find the end of the token.  */
 
787
    end = strpbrk (begin, delim);
 
788
 
 
789
  if (end)
 
790
    {
 
791
      /* Terminate the token and set *STRINGP past NUL character.  */
 
792
      *end++ = '\0';
 
793
      *stringp = end;
 
794
    }
 
795
  else
 
796
    /* No more delimiters; this is the last token.  */
 
797
    *stringp = NULL;
 
798
 
 
799
  return begin;
 
800
}
 
801
#endif /*HAVE_STRSEP*/
 
802
 
 
803
 
634
804
#ifndef HAVE_STRLWR
635
805
char *
636
806
strlwr(char *s)
671
841
#endif
672
842
 
673
843
 
 
844
#ifndef HAVE_MEMRCHR
 
845
void *
 
846
memrchr (const void *buffer, int c, size_t n)
 
847
{
 
848
  const unsigned char *p = buffer;
 
849
 
 
850
  for (p += n; n ; n--)
 
851
    if (*--p == c)
 
852
      return (void *)p;
 
853
  return NULL;
 
854
}
 
855
#endif /*HAVE_MEMRCHR*/
 
856
 
 
857
 
 
858
/* Percent-escape the string STR by replacing colons with '%3a'.  If
 
859
   EXTRA is not NULL all characters in EXTRA are also escaped.  */
 
860
static char *
 
861
do_percent_escape (const char *str, const char *extra, int die)
 
862
{
 
863
  int i, j;
 
864
  char *ptr;
 
865
 
 
866
  if (!str)
 
867
    return NULL;
 
868
 
 
869
  for (i=j=0; str[i]; i++)
 
870
    if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i])))
 
871
      j++;
 
872
  if (die)
 
873
    ptr = jnlib_xmalloc (i + 2 * j + 1);
 
874
  else
 
875
    {
 
876
      ptr = jnlib_malloc (i + 2 * j + 1);
 
877
      if (!ptr)
 
878
        return NULL;
 
879
    }
 
880
  i = 0;
 
881
  while (*str)
 
882
    {
 
883
      if (*str == ':')
 
884
        {
 
885
          ptr[i++] = '%';
 
886
          ptr[i++] = '3';
 
887
          ptr[i++] = 'a';
 
888
        }
 
889
      else if (*str == '%')
 
890
        {
 
891
          ptr[i++] = '%';
 
892
          ptr[i++] = '2';
 
893
          ptr[i++] = '5';
 
894
        }
 
895
      else if (extra && strchr (extra, *str))
 
896
        {
 
897
          ptr[i++] = '%';
 
898
          ptr[i++] = tohex_lower ((*str>>4)&15);
 
899
          ptr[i++] = tohex_lower (*str&15);
 
900
        }
 
901
      else
 
902
        ptr[i++] = *str;
 
903
      str++;
 
904
    }
 
905
  ptr[i] = '\0';
 
906
 
 
907
  return ptr;
 
908
}
 
909
 
 
910
/* Percent-escape the string STR by replacing colons with '%3a'.  If
 
911
   EXTRA is not NULL all characters in EXTRA are also escaped.  */
 
912
char *
 
913
percent_escape (const char *str, const char *extra)
 
914
{
 
915
  return do_percent_escape (str, extra, 1);
 
916
}
 
917
 
 
918
/* Same as percent_escape but return NULL instead of exiting on memory
 
919
   error. */
 
920
char *
 
921
try_percent_escape (const char *str, const char *extra)
 
922
{
 
923
  return do_percent_escape (str, extra, 0);
 
924
}