mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-18 14:17:03 +01:00
common: Add functions make_absfilename and make_absfilename_try.
* common/stringhelp.c (do_make_filename): Add modes 2 and 3. (make_absfilename): New. (make_absfilename_try): New.
This commit is contained in:
parent
1a87edab66
commit
71a54313ad
@ -1,6 +1,7 @@
|
|||||||
/* stringhelp.c - standard string helper functions
|
/* stringhelp.c - standard string helper functions
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007,
|
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007,
|
||||||
* 2008, 2009, 2010 Free Software Foundation, Inc.
|
* 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||||
|
* Copyright (C) 2014 Werner Koch
|
||||||
*
|
*
|
||||||
* This file is part of JNLIB, which is a subsystem of GnuPG.
|
* This file is part of JNLIB, which is a subsystem of GnuPG.
|
||||||
*
|
*
|
||||||
@ -49,9 +50,9 @@
|
|||||||
|
|
||||||
#include "libjnlib-config.h"
|
#include "libjnlib-config.h"
|
||||||
#include "utf8conv.h"
|
#include "utf8conv.h"
|
||||||
|
#include "sysutils.h"
|
||||||
#include "stringhelp.h"
|
#include "stringhelp.h"
|
||||||
|
|
||||||
|
|
||||||
#define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a'))
|
#define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a'))
|
||||||
|
|
||||||
/* Sometimes we want to avoid mixing slashes and backslashes on W32
|
/* Sometimes we want to avoid mixing slashes and backslashes on W32
|
||||||
@ -395,6 +396,12 @@ get_pwdir (int xmode, const char *name)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* xmode 0 := Return NULL on error
|
||||||
|
1 := Terminate on error
|
||||||
|
2 := Make sure that name is absolute; return NULL on error
|
||||||
|
3 := Make sure that name is absolute; terminate on error
|
||||||
|
*/
|
||||||
static char *
|
static char *
|
||||||
do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
|
do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
|
||||||
{
|
{
|
||||||
@ -404,6 +411,10 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
|
|||||||
int skip = 1;
|
int skip = 1;
|
||||||
char *home_buffer = NULL;
|
char *home_buffer = NULL;
|
||||||
char *name, *home, *p;
|
char *name, *home, *p;
|
||||||
|
int want_abs;
|
||||||
|
|
||||||
|
want_abs = !!(xmode & 2);
|
||||||
|
xmode &= 1;
|
||||||
|
|
||||||
n = strlen (first_part) + 1;
|
n = strlen (first_part) + 1;
|
||||||
argc = 0;
|
argc = 0;
|
||||||
@ -478,10 +489,65 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
|
|||||||
p = stpcpy (name, first_part);
|
p = stpcpy (name, first_part);
|
||||||
|
|
||||||
jnlib_free (home_buffer);
|
jnlib_free (home_buffer);
|
||||||
|
|
||||||
for (argc=0; argv[argc]; argc++)
|
for (argc=0; argv[argc]; argc++)
|
||||||
p = stpcpy (stpcpy (p, "/"), argv[argc]);
|
p = stpcpy (stpcpy (p, "/"), argv[argc]);
|
||||||
|
|
||||||
|
if (want_abs)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_DRIVE_LETTERS
|
||||||
|
p = strchr (name, ':');
|
||||||
|
if (!p)
|
||||||
|
p = name;
|
||||||
|
#else
|
||||||
|
p = name;
|
||||||
|
#endif
|
||||||
|
if (*p != '/'
|
||||||
|
#ifdef HAVE_DRIVE_LETTERS
|
||||||
|
&& *p != '\\'
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
home = gnupg_getcwd ();
|
||||||
|
if (!home)
|
||||||
|
{
|
||||||
|
if (xmode)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "\nfatal: getcwd failed: %s\n",
|
||||||
|
strerror (errno));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
jnlib_free (name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
n = strlen (home) + 1 + strlen (name) + 1;
|
||||||
|
if (xmode)
|
||||||
|
home_buffer = jnlib_xmalloc (n);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
home_buffer = jnlib_malloc (n);
|
||||||
|
if (!home_buffer)
|
||||||
|
{
|
||||||
|
jnlib_free (name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p == name)
|
||||||
|
p = home_buffer;
|
||||||
|
else /* Windows case. */
|
||||||
|
{
|
||||||
|
memcpy (home_buffer, p, p - name + 1);
|
||||||
|
p = home_buffer + (p - name + 1);
|
||||||
|
}
|
||||||
|
strcpy (stpcpy (stpcpy (p, home), "/"), name);
|
||||||
|
jnlib_free (name);
|
||||||
|
name = home_buffer;
|
||||||
|
/* Let's do a simple compression to catch the most common
|
||||||
|
case of using "." for gpg's --homedir option. */
|
||||||
|
n = strlen (name);
|
||||||
|
if (n > 2 && name[n-2] == '/' && name[n-1] == '.')
|
||||||
|
name[n-2] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
return change_slashes (name);
|
return change_slashes (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,6 +581,36 @@ make_filename_try (const char *first_part, ... )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Construct an absolute filename from the NULL terminated list of
|
||||||
|
parts. Tilde expansion is done for the first argument. This
|
||||||
|
function terminates the process on memory shortage. */
|
||||||
|
char *
|
||||||
|
make_absfilename (const char *first_part, ... )
|
||||||
|
{
|
||||||
|
va_list arg_ptr;
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
va_start (arg_ptr, first_part);
|
||||||
|
result = do_make_filename (3, first_part, arg_ptr);
|
||||||
|
va_end (arg_ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Construct an absolute filename from the NULL terminated list of
|
||||||
|
parts. Tilde expansion is done for the first argument. This
|
||||||
|
function may return NULL on error. */
|
||||||
|
char *
|
||||||
|
make_absfilename_try (const char *first_part, ... )
|
||||||
|
{
|
||||||
|
va_list arg_ptr;
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
va_start (arg_ptr, first_part);
|
||||||
|
result = do_make_filename (2, first_part, arg_ptr);
|
||||||
|
va_end (arg_ptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Compare whether the filenames are identical. This is a
|
/* Compare whether the filenames are identical. This is a
|
||||||
|
@ -53,6 +53,9 @@ char *make_basename(const char *filepath, const char *inputpath);
|
|||||||
char *make_dirname(const char *filepath);
|
char *make_dirname(const char *filepath);
|
||||||
char *make_filename( const char *first_part, ... ) GNUPG_GCC_A_SENTINEL(0);
|
char *make_filename( const char *first_part, ... ) GNUPG_GCC_A_SENTINEL(0);
|
||||||
char *make_filename_try (const char *first_part, ... ) GNUPG_GCC_A_SENTINEL(0);
|
char *make_filename_try (const char *first_part, ... ) GNUPG_GCC_A_SENTINEL(0);
|
||||||
|
char *make_absfilename (const char *first_part, ...) GNUPG_GCC_A_SENTINEL(0);
|
||||||
|
char *make_absfilename_try (const char *first_part,
|
||||||
|
...) GNUPG_GCC_A_SENTINEL(0);
|
||||||
int compare_filenames( const char *a, const char *b );
|
int compare_filenames( const char *a, const char *b );
|
||||||
|
|
||||||
int hextobyte (const char *s);
|
int hextobyte (const char *s);
|
||||||
|
@ -71,6 +71,34 @@ gethome (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
mygetcwd (void)
|
||||||
|
{
|
||||||
|
char *buffer;
|
||||||
|
size_t size = 100;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
buffer = xmalloc (size+1);
|
||||||
|
#ifdef HAVE_W32CE_SYSTEM
|
||||||
|
strcpy (buffer, "/"); /* Always "/". */
|
||||||
|
return buffer;
|
||||||
|
#else
|
||||||
|
if (getcwd (buffer, size) == buffer)
|
||||||
|
return buffer;
|
||||||
|
xfree (buffer);
|
||||||
|
if (errno != ERANGE)
|
||||||
|
{
|
||||||
|
fprintf (stderr,"error getting current cwd: %s\n",
|
||||||
|
strerror (errno));
|
||||||
|
exit (2);
|
||||||
|
}
|
||||||
|
size *= 2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_percent_escape (void)
|
test_percent_escape (void)
|
||||||
{
|
{
|
||||||
@ -407,6 +435,50 @@ test_make_filename_try (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_make_absfilename_try (void)
|
||||||
|
{
|
||||||
|
char *out;
|
||||||
|
char *cwd = mygetcwd ();
|
||||||
|
size_t cwdlen = strlen (cwd);
|
||||||
|
|
||||||
|
out = make_absfilename_try ("foo", "bar", NULL);
|
||||||
|
if (!out)
|
||||||
|
fail (0);
|
||||||
|
if (strlen (out) < cwdlen + 7)
|
||||||
|
fail (0);
|
||||||
|
if (strncmp (out, cwd, cwdlen))
|
||||||
|
fail (0);
|
||||||
|
if (strcmp (out+cwdlen, "/foo/bar"))
|
||||||
|
fail (0);
|
||||||
|
xfree (out);
|
||||||
|
|
||||||
|
out = make_absfilename_try ("./foo", NULL);
|
||||||
|
if (!out)
|
||||||
|
fail (1);
|
||||||
|
if (strlen (out) < cwdlen + 5)
|
||||||
|
fail (1);
|
||||||
|
if (strncmp (out, cwd, cwdlen))
|
||||||
|
fail (1);
|
||||||
|
if (strcmp (out+cwdlen, "/./foo"))
|
||||||
|
fail (1);
|
||||||
|
xfree (out);
|
||||||
|
|
||||||
|
out = make_absfilename_try (".", NULL);
|
||||||
|
if (!out)
|
||||||
|
fail (2);
|
||||||
|
if (strlen (out) < cwdlen)
|
||||||
|
fail (2);
|
||||||
|
if (strncmp (out, cwd, cwdlen))
|
||||||
|
fail (2);
|
||||||
|
if (strcmp (out+cwdlen, ""))
|
||||||
|
fail (2);
|
||||||
|
xfree (out);
|
||||||
|
|
||||||
|
xfree (cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -418,6 +490,7 @@ main (int argc, char **argv)
|
|||||||
test_strconcat ();
|
test_strconcat ();
|
||||||
test_xstrconcat ();
|
test_xstrconcat ();
|
||||||
test_make_filename_try ();
|
test_make_filename_try ();
|
||||||
|
test_make_absfilename_try ();
|
||||||
|
|
||||||
xfree (home_buffer);
|
xfree (home_buffer);
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user