diff options
author | Werner Koch <wk@gnupg.org> | 2014-04-15 16:40:48 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2014-04-22 15:58:33 +0200 |
commit | 71a54313adf7b57b7b27bb9ad07b142a34306260 (patch) | |
tree | 5c37da59f48b7c740f0ade7e85c0f22ac089d5a0 /common/stringhelp.c | |
parent | common: Add function gnupg_getcwd. (diff) | |
download | gnupg2-71a54313adf7b57b7b27bb9ad07b142a34306260.tar.xz gnupg2-71a54313adf7b57b7b27bb9ad07b142a34306260.zip |
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.
Diffstat (limited to 'common/stringhelp.c')
-rw-r--r-- | common/stringhelp.c | 100 |
1 files changed, 98 insertions, 2 deletions
diff --git a/common/stringhelp.c b/common/stringhelp.c index 7cbf82ccc..4d7c3a63b 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -1,6 +1,7 @@ /* stringhelp.c - standard string helper functions * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, * 2008, 2009, 2010 Free Software Foundation, Inc. + * Copyright (C) 2014 Werner Koch * * This file is part of JNLIB, which is a subsystem of GnuPG. * @@ -49,9 +50,9 @@ #include "libjnlib-config.h" #include "utf8conv.h" +#include "sysutils.h" #include "stringhelp.h" - #define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a')) /* Sometimes we want to avoid mixing slashes and backslashes on W32 @@ -395,6 +396,12 @@ get_pwdir (int xmode, const char *name) 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 * 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; char *home_buffer = NULL; char *name, *home, *p; + int want_abs; + + want_abs = !!(xmode & 2); + xmode &= 1; n = strlen (first_part) + 1; argc = 0; @@ -478,10 +489,65 @@ do_make_filename (int xmode, const char *first_part, va_list arg_ptr) p = stpcpy (name, first_part); jnlib_free (home_buffer); - for (argc=0; argv[argc]; 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); } @@ -515,6 +581,36 @@ make_filename_try (const char *first_part, ... ) 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 |