]> granicus.if.org Git - p11-kit/commitdiff
More compatible path munging and handling code
authorStef Walter <stefw@redhat.com>
Wed, 3 Apr 2013 08:50:59 +0000 (10:50 +0200)
committerStef Walter <stefw@gnome.org>
Wed, 3 Apr 2013 10:45:43 +0000 (12:45 +0200)
Centralize the path handling code, so we can remove unixy assumptions
and have a chance of running on Windows. The current goal is to run
all the tests on Windows.

Includes some code from LRN <lrn1986@gmail.com>

https://bugs.freedesktop.org/show_bug.cgi?id=63062

19 files changed:
common/Makefile.am
common/compat.c
common/compat.h
common/path.c [new file with mode: 0644]
common/path.h [new file with mode: 0644]
common/tests/Makefile.am
common/tests/test-compat.c
common/tests/test-path.c [new file with mode: 0644]
p11-kit/conf.c
p11-kit/modules.c
tools/tests/test-openssl.c
tools/tests/test-pem.c
tools/tests/test-save.c
tools/tests/test-x509.c
tools/tool.c
trust/module.c
trust/parser.c
trust/tests/test-module.c
trust/token.c

index cb6e95e47376bbe1cce4f00182a7bf5d62a7e4af..b583a5ca5d7a846fcd62994a7ae50196946ccc57 100644 (file)
@@ -26,6 +26,7 @@ libp11_common_la_SOURCES = \
        hash.c hash.h \
        lexer.c lexer.h \
        message.c message.h \
+       path.c path.h \
        pkcs11.h pkcs11x.h \
        url.c url.h \
        $(NULL)
index 2cda460e923d02711bcab01fb25a14397792c7ee..4d8d73c16e94572ff6d8e8f1055ea08da726673e 100644 (file)
@@ -148,40 +148,6 @@ getprogname (void)
 
 #endif /* HAVE_GETPROGNAME */
 
-char *
-p11_basename (const char *name)
-{
-#ifdef OS_WIN32
-       static const char *delims = "/\\";
-#else
-       static const char *delims = "/";
-#endif
-
-       const char *end;
-       const char *beg;
-
-       if (name == NULL)
-               return NULL;
-
-       /* Any trailing slashes */
-       end = name + strlen (name);
-       while (end != name) {
-               if (!strchr (delims, *(end - 1)))
-                       break;
-               end--;
-       }
-
-       /* Find the last slash after those */
-       beg = end;
-       while (beg != name) {
-               if (strchr (delims, *(beg - 1)))
-                       break;
-               beg--;
-       }
-
-       return strndup (beg, end - beg);
-}
-
 #ifdef OS_UNIX
 #include <sys/stat.h>
 #include <sys/mman.h>
index bd933cb934b6592bc7823db9c6968cd39d06ea9e..7435e07fac2d64ce9065d2aaec80a841c663f849 100644 (file)
@@ -84,6 +84,8 @@ char *       mkdtemp     (char *template);
 
 #endif /* HAVE_MKDTEMP */
 
+char *       strdup_path_mangle (const char *template);
+
 /* -----------------------------------------------------------------------------
  * WIN32
  */
@@ -214,13 +216,6 @@ void        p11_mmap_close  (p11_mmap *map);
 
 #endif /* OS_UNIX */
 
-/*
- * The semantics of both POSIX basename() and GNU asename() are so crappy that
- * we just don't even bother. And what's worse is how it completely changes
- * behavior if _GNU_SOURCE is defined. Nasty stuff.
- */
-char *       p11_basename   (const char *name);
-
 /* ----------------------------------------------------------------------------
  * MORE COMPAT
  */
diff --git a/common/path.c b/common/path.c
new file mode 100644 (file)
index 0000000..bba2c23
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2005 Stefan Walter
+ * Copyright (c) 2011 Collabora Ltd.
+ * Copyright (c) 2013 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *     * Redistributions of source code must retain the above
+ *       copyright notice, this list of conditions and the
+ *       following disclaimer.
+ *     * Redistributions in binary form must reproduce the
+ *       above copyright notice, this list of conditions and
+ *       the following disclaimer in the documentation and/or
+ *       other materials provided with the distribution.
+ *     * The names of contributors to this software may not be
+ *       used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * CONTRIBUTORS
+ *  Stef Walter <stefw@redhat.com>
+ */
+
+#include "config.h"
+
+#include "debug.h"
+#include "message.h"
+#include "path.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef OS_UNIX
+#include <paths.h>
+#include <pwd.h>
+#include <unistd.h>
+#endif
+
+#ifdef OS_WIN32
+#include <shlobj.h>
+#endif
+
+
+char *
+p11_path_base (const char *path)
+{
+#ifdef OS_WIN32
+       static const char *delims = "/\\";
+#else
+       static const char *delims = "/";
+#endif
+
+       const char *end;
+       const char *beg;
+
+       return_val_if_fail (path != NULL, NULL);
+
+       /* Any trailing slashes */
+       end = path + strlen (path);
+       while (end != path) {
+               if (!strchr (delims, *(end - 1)))
+                       break;
+               end--;
+       }
+
+       /* Find the last slash after those */
+       beg = end;
+       while (beg != path) {
+               if (strchr (delims, *(beg - 1)))
+                       break;
+               beg--;
+       }
+
+       return strndup (beg, end - beg);
+}
+
+static char *
+expand_homedir (const char *remainder)
+{
+       const char *env;
+
+       env = getenv ("HOME");
+       if (env && env[0]) {
+               return p11_path_build (env, remainder, NULL);
+
+       } else {
+#ifdef OS_UNIX
+               struct passwd *pwd;
+               int error = 0;
+
+               pwd = getpwuid (getuid ());
+               if (!pwd) {
+                       error = errno;
+                       p11_message ("couldn't lookup home directory for user %d: %s",
+                                    getuid (), strerror (errno));
+                       errno = error;
+                       return NULL;
+               }
+
+               return p11_path_build (pwd->pw_dir, remainder, NULL);
+
+#else /* OS_WIN32 */
+               char directory[MAX_PATH + 1];
+
+               if (!SHGetSpecialFolderPathA (NULL, directory, CSIDL_PROFILE, TRUE)) {
+                       p11_message ("couldn't lookup home directory for user");
+                       errno = ENOTDIR;
+                       return NULL;
+               }
+
+               return p11_path_build (directory, remainder, NULL);
+
+#endif /* OS_WIN32 */
+       }
+}
+
+static char *
+expand_tempdir (const char *remainder)
+{
+       const char *env;
+
+       env = getenv ("TEMP");
+       if (env && env[0]) {
+               return p11_path_build (env, remainder, NULL);
+
+       } else {
+#ifdef OS_UNIX
+#ifdef _PATH_TMP
+               return p11_path_build (_PATH_TMP, remainder, NULL);
+#else
+               return p11_path_build ("/tmp", remainder, NULL);
+#endif
+
+#else /* OS_WIN32 */
+               char directory[MAX_PATH + 1];
+
+               if (!GetTempPathA (MAX_PATH + 1, directory)) {
+                       p11_message ("couldn't lookup temp directory");
+                       errno = ENOTDIR;
+                       return NULL;
+               }
+
+               return p11_path_build (directory, remainder, NULL);
+
+#endif /* OS_WIN32 */
+       }
+}
+
+static bool
+is_path_component_or_null (char ch)
+{
+       return (ch == '0' || ch == '/'
+#ifdef OS_WIN32
+                       || ch == '\\'
+#endif
+               );
+}
+
+char *
+p11_path_expand (const char *path)
+{
+       return_val_if_fail (path != NULL, NULL);
+
+       if (strncmp (path, "~", 1) == 0 &&
+           is_path_component_or_null (path[1])) {
+               return expand_homedir (path + 2);
+
+       } else if (strncmp (path, "$HOME", 5) == 0 &&
+           is_path_component_or_null (path[5])) {
+               return expand_homedir (path + 6);
+
+       } else if (strncmp (path, "$TEMP", 5) == 0 &&
+           is_path_component_or_null (path[5])) {
+               return expand_tempdir (path + 6);
+
+       } else {
+               return strdup (path);
+       }
+}
+
+bool
+p11_path_absolute (const char *path)
+{
+       return_val_if_fail (path != NULL, false);
+
+#ifdef OS_UNIX
+       return (path[0] == '/');
+#else
+       return (path[0] != '\0' && path[1] == ':' && path[2] == '\\');
+#endif
+}
+
+char *
+p11_path_build (const char *path,
+                ...)
+{
+#ifdef OS_WIN32
+       static const char delim = '\\';
+#else
+       static const char delim = '/';
+#endif
+       const char *first = path;
+       char *built;
+       size_t len;
+       size_t at;
+       size_t num;
+       va_list va;
+
+       return_val_if_fail (path != NULL, NULL);
+
+       len = 1;
+       va_start (va, path);
+       while (path != NULL) {
+               len += strlen (path) + 1;
+               path = va_arg (va, const char *);
+       }
+       va_end (va);
+
+       built = malloc (len + 1);
+       return_val_if_fail (built != NULL, NULL);
+
+       at = 0;
+       path = first;
+       va_start (va, path);
+       while (path != NULL) {
+               if (at != 0 && built[at - 1] != delim && path[0] != delim)
+                       built[at++] = delim;
+               num = strlen (path);
+               assert (at + num < len);
+               memcpy (built + at, path, num);
+
+               at += num;
+               path = va_arg (va, const char *);
+       }
+       va_end (va);
+
+       assert (at < len);
+       built[at] = '\0';
+       return built;
+}
diff --git a/common/path.h b/common/path.h
new file mode 100644 (file)
index 0000000..a518008
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *     * Redistributions of source code must retain the above
+ *       copyright notice, this list of conditions and the
+ *       following disclaimer.
+ *     * Redistributions in binary form must reproduce the
+ *       above copyright notice, this list of conditions and
+ *       the following disclaimer in the documentation and/or
+ *       other materials provided with the distribution.
+ *     * The names of contributors to this software may not be
+ *       used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@redhat.com>
+ */
+
+#ifndef P11_PATH_H__
+#define P11_PATH_H__
+
+#include "compat.h"
+
+#ifdef OS_WIN32
+#define P11_PATH_SEP   ";"
+#define P11_PATH_SEP_C ';'
+#else
+#define P11_PATH_SEP   ":"
+#define P11_PATH_SEP_C ':'
+#endif
+
+/*
+ * The semantics of both POSIX basename() and GNU asename() are so crappy that
+ * we just don't even bother. And what's worse is how it completely changes
+ * behavior if _GNU_SOURCE is defined. Nasty stuff.
+ */
+char *       p11_path_base      (const char *name);
+
+char *       p11_path_expand    (const char *path);
+
+char *       p11_path_build     (const char *path,
+                                 ...) GNUC_NULL_TERMINATED;
+
+bool         p11_path_absolute  (const char *path);
+
+#endif /* P11_PATH_H__ */
index ba9a72ff71d91e6ebc64de2da4cf20cfc043f3ea..5e844393b8dfc2189d3b837ac1e9bf987e1bf727 100644 (file)
@@ -22,6 +22,7 @@ CHECK_PROGS = \
        test-buffer \
        test-lexer \
        test-url \
+       test-path \
        $(NULL)
 
 noinst_PROGRAMS = \
index a94aaeb2306e5004a6cc9e7cbb1884689f50595c..066e723f2e15d09fcf3937d53c36dc816079b0a3 100644 (file)
 
 #include "compat.h"
 
-static void
-test_basename (CuTest *tc)
-{
-       struct {
-               const char *in;
-               const char *out;
-       } fixtures[] = {
-               { "/this/is/a/path", "path" },
-               { "/this/is/a/folder/", "folder" },
-               { "folder/", "folder" },
-               { "/", "" },
-               { "this", "this" },
-#ifdef OS_WIN32
-               { "\\this\\is\\a\\path", "path" },
-               { "\\this\\is\\a\\folder\\", "folder" },
-               { "folder\\", "folder" },
-               { "\\", "" },
-#endif
-               { NULL },
-       };
-
-       char *out;
-       int i;
-
-       for (i = 0; fixtures[i].in != NULL; i++) {
-               out = p11_basename (fixtures[i].in);
-               CuAssertStrEquals (tc, fixtures[i].out, out);
-               free (out);
-       }
-}
-
 static void
 test_strndup (CuTest *tc)
 {
@@ -94,7 +63,6 @@ main (void)
        CuSuite* suite = CuSuiteNew ();
        int ret;
 
-       SUITE_ADD_TEST (suite, test_basename);
        SUITE_ADD_TEST (suite, test_strndup);
 
        CuSuiteRun (suite);
diff --git a/common/tests/test-path.c b/common/tests/test-path.c
new file mode 100644 (file)
index 0000000..8263d1f
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2013 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *     * Redistributions of source code must retain the above
+ *       copyright notice, this list of conditions and the
+ *       following disclaimer.
+ *     * Redistributions in binary form must reproduce the
+ *       above copyright notice, this list of conditions and
+ *       the following disclaimer in the documentation and/or
+ *       other materials provided with the distribution.
+ *     * The names of contributors to this software may not be
+ *       used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@redhat.com>
+ */
+
+#include "config.h"
+#include "CuTest.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "compat.h"
+#include "path.h"
+
+static void
+test_base (CuTest *tc)
+{
+       struct {
+               const char *in;
+               const char *out;
+       } fixtures[] = {
+               { "/this/is/a/path", "path" },
+               { "/this/is/a/folder/", "folder" },
+               { "folder/", "folder" },
+               { "/", "" },
+               { "this", "this" },
+#ifdef OS_WIN32
+               { "\\this\\is\\a\\path", "path" },
+               { "\\this\\is\\a\\folder\\", "folder" },
+               { "C:\\this\\is\\a\\path", "path" },
+               { "D:\\this\\is\\a\\folder\\", "folder" },
+               { "folder\\", "folder" },
+               { "\\", "" },
+#endif
+               { NULL },
+       };
+
+       char *out;
+       int i;
+
+       for (i = 0; fixtures[i].in != NULL; i++) {
+               out = p11_path_base (fixtures[i].in);
+               CuAssertStrEquals (tc, fixtures[i].out, out);
+               free (out);
+       }
+}
+
+static void
+check_equals_and_free_msg (CuTest *tc,
+                           const char *file,
+                           int line,
+                           const char *ex,
+                           char *ac)
+{
+       CuAssertStrEquals_LineMsg (tc, file, line, NULL, ex, ac);
+       free (ac);
+}
+
+#define check_equals_and_free(tc, ex, ac) \
+       check_equals_and_free_msg ((tc), __FILE__, __LINE__, (ex), (ac))
+
+static void
+test_build (CuTest *tc)
+{
+#ifdef OS_UNIX
+       check_equals_and_free (tc, "/root/second",
+                              p11_path_build ("/root", "second", NULL));
+       check_equals_and_free (tc, "/root/second",
+                              p11_path_build ("/root", "/second", NULL));
+       check_equals_and_free (tc, "/root/second",
+                              p11_path_build ("/root/", "second", NULL));
+       check_equals_and_free (tc, "/root/second/third",
+                              p11_path_build ("/root", "second", "third", NULL));
+       check_equals_and_free (tc, "/root/second/third",
+                              p11_path_build ("/root", "/second/third", NULL));
+#else /* OS_WIN32 */
+       check_equals_and_free (tc, "C:\\root\\second",
+                              p11_path_build ("C:\\root", "second", NULL));
+       check_equals_and_free (tc, "C:\\root\\second",
+                              p11_path_build ("C:\\root", "\\second", NULL));
+       check_equals_and_free (tc, "C:\\root\\second",
+                              p11_path_build ("C:\\root\\", "second", NULL));
+       check_equals_and_free (tc, "C:\\root\\second\\third",
+                              p11_path_build ("C:\\root", "second", "third", NULL));
+       check_equals_and_free (tc, "C:\\root\\second/third",
+                              p11_path_build ("C:\\root", "second/third", NULL));
+#endif
+}
+
+static void
+test_expand (CuTest *tc)
+{
+       char *path;
+
+#ifdef OS_UNIX
+       putenv ("HOME=/home/blah");
+       check_equals_and_free (tc, "/home/blah/my/path",
+                              p11_path_expand ("$HOME/my/path"));
+       check_equals_and_free (tc, "/home/blah/my/path",
+                              p11_path_expand ("~/my/path"));
+       putenv ("TEMP=/tmpdir");
+       check_equals_and_free (tc, "/tmpdir/my/path",
+                              p11_path_expand ("$TEMP/my/path"));
+#else /* OS_WIN32 */
+       putenv ("HOME=C:\\Users\\blah");
+       check_equals_and_free (tc, "C:\\Users\\blah\\path",
+                              p11_path_expand ("$HOME/path"));
+       check_equals_and_free (tc, "C:\\Users\\blah\\path",
+                              p11_path_expand ("$HOME\\path"));
+       check_equals_and_free (tc, "C:\\Users\\blah\\path",
+                              p11_path_expand ("~/path"));
+       check_equals_and_free (tc, "C:\\Users\\blah\\path",
+                              p11_path_expand ("~\\path"));
+
+       putenv ("TEMP=C:\\Temp Directory");
+       check_equals_and_free (tc, "C:\\Temp Directory\\path",
+                              p11_path_expand ("$TEMP/path"));
+       check_equals_and_free (tc, "C:\\Temp Directory\\path",
+                              p11_path_expand ("$TEMP\\path"));
+#endif
+
+       putenv("HOME=");
+       path = p11_path_expand ("$HOME/this/is/my/path");
+       CuAssertTrue (tc, strstr (path, "this/is/my/path") != NULL);
+       free (path);
+
+       putenv("HOME=");
+       path = p11_path_expand ("~/this/is/my/path");
+       CuAssertTrue (tc, strstr (path, "this/is/my/path") != NULL);
+       free (path);
+
+       putenv("TEMP=");
+       path = p11_path_expand ("$TEMP/this/is/my/path");
+       CuAssertTrue (tc, strstr (path, "this/is/my/path") != NULL);
+       free (path);
+}
+
+static void
+test_absolute (CuTest *tc)
+{
+#ifdef OS_UNIX
+       CuAssertTrue (tc, p11_path_absolute ("/home"));
+       CuAssertTrue (tc, !p11_path_absolute ("home"));
+#else /* OS_WIN32 */
+       CuAssertTrue (tc, p11_path_absolute ("C:\\home"));
+       CuAssertTrue (tc, !p11_path_absolute ("home"));
+       CuAssertTrue (tc, !p11_path_absolute ("/home"));
+#endif
+}
+
+int
+main (void)
+{
+       CuString *output = CuStringNew ();
+       CuSuite* suite = CuSuiteNew ();
+       int ret;
+
+       SUITE_ADD_TEST (suite, test_base);
+       SUITE_ADD_TEST (suite, test_build);
+       SUITE_ADD_TEST (suite, test_expand);
+       SUITE_ADD_TEST (suite, test_absolute);
+
+       CuSuiteRun (suite);
+       CuSuiteSummary (suite, output);
+       CuSuiteDetails (suite, output);
+       printf ("%s\n", output->buffer);
+       ret = suite->failCount;
+       CuSuiteDelete (suite);
+       CuStringDelete (output);
+
+       return ret;
+}
index c3eb05efc86970a4beaaf20f7f20411444dbb219..a2b46c48228e486a603bbff02f79967e23f9fbda 100644 (file)
@@ -42,6 +42,7 @@
 #include "debug.h"
 #include "lexer.h"
 #include "message.h"
+#include "path.h"
 #include "private.h"
 
 #include <sys/param.h>
 #include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
-#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
-
-#ifdef OS_UNIX
-#include <pwd.h>
-#endif
-
-#ifdef OS_WIN32
-#include <shlobj.h>
-#endif
 
 static int
 strequal (const char *one, const char *two)
@@ -230,49 +221,6 @@ _p11_conf_parse_file (const char* filename, int flags)
        return map;
 }
 
-static char *
-expand_user_path (const char *path)
-{
-       const char *env;
-
-       if (path[0] != '~' || path[1] != '/')
-               return strdup (path);
-
-       path += 1;
-       env = getenv ("HOME");
-       if (env && env[0]) {
-               return strconcat (env, path, NULL);
-
-       } else {
-#ifdef OS_UNIX
-               struct passwd *pwd;
-               int error = 0;
-
-               pwd = getpwuid (getuid ());
-               if (!pwd) {
-                       error = errno;
-                       p11_message ("couldn't lookup home directory for user %d: %s",
-                                    getuid (), strerror (errno));
-                       errno = error;
-                       return NULL;
-               }
-
-               return strconcat (pwd->pw_dir, path, NULL);
-
-#else /* OS_WIN32 */
-               char directory[MAX_PATH + 1];
-
-               if (!SHGetSpecialFolderPathA (NULL, directory, CSIDL_PROFILE, TRUE)) {
-                       p11_message ("couldn't lookup home directory for user");
-                       errno = ENOTDIR;
-                       return NULL;
-               }
-
-               return strconcat (directory, path, NULL);
-#endif /* OS_WIN32 */
-       }
-}
-
 static int
 user_config_mode (p11_dict *config,
                   int defmode)
@@ -329,7 +277,7 @@ _p11_conf_load_globals (const char *system_conf, const char *user_conf,
        }
 
        if (mode != CONF_USER_NONE) {
-               path = expand_user_path (user_conf);
+               path = p11_path_expand (user_conf);
                if (!path) {
                        error = errno;
                        goto finished;
@@ -504,7 +452,7 @@ load_configs_from_directory (const char *directory,
 
        /* We're within a global mutex, so readdir is safe */
        while ((dp = readdir(dir)) != NULL) {
-               path = strconcat (directory, "/", dp->d_name, NULL);
+               path = p11_path_build (directory, dp->d_name, NULL);
                return_val_if_fail (path != NULL, false);
 
 #ifdef HAVE_STRUCT_DIRENT_D_TYPE
@@ -560,7 +508,7 @@ _p11_conf_load_modules (int mode,
        /* Load each user config first, if user config is allowed */
        if (mode != CONF_USER_NONE) {
                flags = CONF_IGNORE_MISSING | CONF_IGNORE_ACCESS_DENIED;
-               path = expand_user_path (user_dir);
+               path = p11_path_expand (user_dir);
                if (!path)
                        error = errno;
                else if (!load_configs_from_directory (path, configs, flags))
index 18400bbab6a3a11559e312128982a7bb49ba95ac..19ba895b3d71f1f0ef1733cc628b81b9c4802591 100644 (file)
@@ -41,6 +41,7 @@
 #include "dict.h"
 #include "library.h"
 #include "message.h"
+#include "path.h"
 #include "pkcs11.h"
 #include "p11-kit.h"
 #include "private.h"
@@ -217,39 +218,6 @@ alloc_module_unlocked (void)
        return mod;
 }
 
-static int
-is_relative_path (const char *path)
-{
-       assert (path);
-
-       return (*path != '/');
-}
-
-static char*
-build_path (const char *dir, const char *filename)
-{
-       char *path;
-       int len;
-
-       assert (dir);
-       assert (filename);
-
-       len = snprintf (NULL, 0, "%s/%s", dir, filename) + 1;
-       return_val_if_fail (len > 0, NULL);
-
-#ifdef PATH_MAX
-       if (len > PATH_MAX)
-               return NULL;
-#endif
-
-       path = malloc (len);
-       return_val_if_fail (path != NULL, NULL);
-
-       sprintf (path, "%s/%s", dir, filename);
-
-       return path;
-}
-
 static CK_RV
 dlopen_and_get_function_list (Module *mod, const char *path)
 {
@@ -326,9 +294,9 @@ expand_module_path (const char *filename)
 {
        char *path;
 
-       if (is_relative_path (filename)) {
+       if (!p11_path_absolute (filename)) {
                p11_debug ("module path is relative, loading from: %s", P11_MODULE_PATH);
-               path = build_path (P11_MODULE_PATH, filename);
+               path = p11_path_build (P11_MODULE_PATH, filename, NULL);
        } else {
                path = strdup (filename);
        }
index 286b4e9b9f84759cdf21e192e3be6acfdb077598..215e0da3add2457da4cb9e268bdcae7e82469481 100644 (file)
@@ -43,6 +43,7 @@
 #include "extract.h"
 #include "message.h"
 #include "mock.h"
+#include "path.h"
 #include "pkcs11.h"
 #include "pkcs11x.h"
 #include "oid.h"
@@ -78,7 +79,7 @@ setup (CuTest *tc)
 
        p11_extract_info_init (&test.ex);
 
-       test.directory = strdup ("/tmp/test-extract.XXXXXX");
+       test.directory = p11_path_expand ("$TEMP/test-extract.XXXXXX");
        if (!mkdtemp (test.directory))
                assert_not_reached ();
 }
index be792791345b639755c540b5be1683a406eacaf6..dc1cb081b1884b41f3525cbd790f31ae31f8567a 100644 (file)
@@ -42,6 +42,7 @@
 #include "extract.h"
 #include "message.h"
 #include "mock.h"
+#include "path.h"
 #include "pkcs11.h"
 #include "pkcs11x.h"
 #include "oid.h"
@@ -75,7 +76,7 @@ setup (CuTest *tc)
 
        p11_extract_info_init (&test.ex);
 
-       test.directory = strdup ("/tmp/test-extract.XXXXXX");
+       test.directory = p11_path_expand ("$TEMP/test-extract.XXXXXX");
        if (!mkdtemp (test.directory))
                assert_not_reached ();
 }
index d686bd6c064805772f16b92be00df404580d3929..b739c21b28c3b3ef29c9e5b5b4669585f040e489 100644 (file)
@@ -40,6 +40,7 @@
 #include "debug.h"
 #include "dict.h"
 #include "message.h"
+#include "path.h"
 #include "save.h"
 #include "test.h"
 
@@ -62,7 +63,7 @@ struct {
 static void
 setup (CuTest *tc)
 {
-       test.directory = strdup ("/tmp/test-extract.XXXXXX");
+       test.directory = p11_path_expand ("$TEMP/test-extract.XXXXXX");
        if (!mkdtemp (test.directory))
                CuFail (tc, "mkdtemp() failed");
 }
index 138e6b76bfa925e685dadbe4dbdb5f90251e87dd..e952e532782fd6be338116ae0e27b1b1a2eb4642 100644 (file)
@@ -42,6 +42,7 @@
 #include "extract.h"
 #include "message.h"
 #include "mock.h"
+#include "path.h"
 #include "pkcs11.h"
 #include "pkcs11x.h"
 #include "oid.h"
@@ -75,7 +76,7 @@ setup (CuTest *tc)
 
        p11_extract_info_init (&test.ex);
 
-       test.directory = strdup ("/tmp/test-extract.XXXXXX");
+       test.directory = p11_path_expand ("$TEMP/test-extract.XXXXXX");
        if (!mkdtemp (test.directory))
                CuFail (tc, "mkdtemp() failed");
 }
index 9ec41a49147f48439e20d910cb75ce7b73a15f3d..961890dbf125da191da67d8899fd47d080f84db9 100644 (file)
@@ -38,6 +38,7 @@
 #include "compat.h"
 #include "debug.h"
 #include "message.h"
+#include "path.h"
 #include "p11-kit.h"
 
 #include <assert.h>
@@ -201,7 +202,7 @@ exec_external (const char *command,
 
        /* Add our libexec directory to the path */
        path = getenv ("PATH");
-       if (!asprintf (&env, "PATH=%s%s%s", path ? path : "", path ? ":" : "", PKGDATADIR))
+       if (!asprintf (&env, "PATH=%s%s%s", path ? path : "", path ? P11_PATH_SEP : "", PKGDATADIR))
                return_if_reached ();
        putenv (env);
 
index 46ebeb6ab10d0b00c55b84965a41c162bbef69df..e7eff621608734a98677c5211e4d2f974d73d6fa 100644 (file)
@@ -45,6 +45,7 @@
 #include "message.h"
 #include "module.h"
 #include "parser.h"
+#include "path.h"
 #include "pkcs11.h"
 #include "pkcs11x.h"
 #include "session.h"
@@ -202,7 +203,7 @@ create_tokens_inlock (p11_array *tokens,
 
        while (remaining) {
                path = remaining;
-               pos = strchr (remaining, ':');
+               pos = strchr (remaining, P11_PATH_SEP_C);
                if (pos == NULL) {
                        remaining = NULL;
                } else {
@@ -227,7 +228,7 @@ create_tokens_inlock (p11_array *tokens,
 
                        /* Didn't find a label above, then make one based on the path */
                        if (!label) {
-                               label = base = p11_basename (path);
+                               label = base = p11_path_base (path);
                                return_val_if_fail (base != NULL, false);
                        }
 
index 7eb18c92db42b1e2fde930bdd2c16405979772bc..b2555b1bb3061eefd040cc512e32e394b452290a 100644 (file)
@@ -45,6 +45,7 @@
 #include "module.h"
 #include "oid.h"
 #include "parser.h"
+#include "path.h"
 #include "pem.h"
 #include "pkcs11x.h"
 #include "persist.h"
@@ -741,7 +742,7 @@ p11_parse_memory (p11_parser *parser,
 
        return_val_if_fail (parser != NULL, P11_PARSE_FAILURE);
 
-       base = p11_basename (filename);
+       base = p11_path_base (filename);
        parser->basename = base;
        parser->flags = flags;
 
index 525a68e905a9724aca3eef08b1795530e038da61..4facf3bb139045b1a06918d9bd654ee3c5653ac6 100644 (file)
@@ -44,6 +44,7 @@
 #include "attrs.h"
 #include "hash.h"
 #include "library.h"
+#include "path.h"
 #include "pkcs11x.h"
 #include "test-data.h"
 #include "token.h"
@@ -81,7 +82,9 @@ setup (CuTest *cu)
        CuAssertTrue (cu, rv == CKR_OK);
 
        memset (&args, 0, sizeof (args));
-       paths = SRCDIR "/input:" SRCDIR "/files/self-signed-with-ku.der:" SRCDIR "/files/thawte.pem";
+       paths = SRCDIR "/input" P11_PATH_SEP \
+               SRCDIR "/files/self-signed-with-ku.der" P11_PATH_SEP \
+               SRCDIR "/files/thawte.pem";
        if (asprintf (&arguments, "paths='%s'", paths) < 0)
                CuAssertTrue (cu, false && "not reached");
        args.pReserved = arguments;
@@ -204,7 +207,10 @@ test_get_token_info (CuTest *cu)
        CuAssertTrue (cu, rv == CKR_OK);
 
        memset (&args, 0, sizeof (args));
-       args.pReserved = "paths='" SYSCONFDIR "/input:" DATADIR "/files/blah:" "/some/other/path/the-basename'";
+       args.pReserved = "paths='" \
+               SYSCONFDIR "/input" P11_PATH_SEP \
+               DATADIR "/files/blah" P11_PATH_SEP \
+               "/some/other/path/the-basename'";
        args.flags = CKF_OS_LOCKING_OK;
 
        rv = module->C_Initialize (&args);
index e7c91cd58422c5fe88981f1f8246a7f545a35cb1..f48f66b749a1b2ca7e9c9deb6fafe30c2023f54a 100644 (file)
@@ -44,6 +44,7 @@
 #include "message.h"
 #include "module.h"
 #include "parser.h"
+#include "path.h"
 #include "pkcs11.h"
 #include "pkcs11x.h"
 #include "token.h"
@@ -111,7 +112,7 @@ loader_load_directory (p11_token *token,
 
        /* We're within a global mutex, so readdir is safe */
        while ((dp = readdir (dir)) != NULL) {
-               path = strconcat (directory, "/", dp->d_name, NULL);
+               path = p11_path_build (directory, dp->d_name, NULL);
                return_val_if_fail (path != NULL, -1);
 
                if (stat (path, &sb) < 0) {