2 * Copyright (c) 2005 Stefan Walter
3 * Copyright (c) 2011 Collabora Ltd.
4 * Copyright (c) 2013 Red Hat Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * * Redistributions of source code must retain the above
11 * copyright notice, this list of conditions and the
12 * following disclaimer.
13 * * Redistributions in binary form must reproduce the
14 * above copyright notice, this list of conditions and
15 * the following disclaimer in the documentation and/or
16 * other materials provided with the distribution.
17 * * The names of contributors to this software may not be
18 * used to endorse or promote products derived from this
19 * software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
31 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
36 * Stef Walter <stefw@redhat.com>
63 p11_path_base (const char *path)
66 static const char *delims = "/\\";
68 static const char *delims = "/";
74 return_val_if_fail (path != NULL, NULL);
76 /* Any trailing slashes */
77 end = path + strlen (path);
79 if (!strchr (delims, *(end - 1)))
84 /* Find the last slash after those */
87 if (strchr (delims, *(beg - 1)))
92 return strndup (beg, end - beg);
96 expand_homedir (const char *remainder)
100 env = getenv ("HOME");
102 return p11_path_build (env, remainder, NULL);
109 pwd = getpwuid (getuid ());
112 p11_message ("couldn't lookup home directory for user %d: %s",
113 getuid (), strerror (errno));
118 return p11_path_build (pwd->pw_dir, remainder, NULL);
121 char directory[MAX_PATH + 1];
123 if (!SHGetSpecialFolderPathA (NULL, directory, CSIDL_PROFILE, TRUE)) {
124 p11_message ("couldn't lookup home directory for user");
129 return p11_path_build (directory, remainder, NULL);
131 #endif /* OS_WIN32 */
136 expand_tempdir (const char *remainder)
140 env = getenv ("TEMP");
142 return p11_path_build (env, remainder, NULL);
147 return p11_path_build (_PATH_TMP, remainder, NULL);
149 return p11_path_build ("/tmp", remainder, NULL);
153 char directory[MAX_PATH + 1];
155 if (!GetTempPathA (MAX_PATH + 1, directory)) {
156 p11_message ("couldn't lookup temp directory");
161 return p11_path_build (directory, remainder, NULL);
163 #endif /* OS_WIN32 */
168 is_path_component_or_null (char ch)
170 return (ch == '0' || ch == '/'
178 p11_path_expand (const char *path)
180 return_val_if_fail (path != NULL, NULL);
182 if (strncmp (path, "~", 1) == 0 &&
183 is_path_component_or_null (path[1])) {
184 return expand_homedir (path + 2);
186 } else if (strncmp (path, "$HOME", 5) == 0 &&
187 is_path_component_or_null (path[5])) {
188 return expand_homedir (path + 6);
190 } else if (strncmp (path, "$TEMP", 5) == 0 &&
191 is_path_component_or_null (path[5])) {
192 return expand_tempdir (path + 6);
195 return strdup (path);
200 p11_path_absolute (const char *path)
202 return_val_if_fail (path != NULL, false);
204 return (path[0] == '/')
206 || (path[0] != '\0' && path[1] == ':' && path[2] == '\\')
212 p11_path_build (const char *path,
216 static const char delim = '\\';
218 static const char delim = '/';
220 const char *first = path;
227 return_val_if_fail (path != NULL, NULL);
231 while (path != NULL) {
232 len += strlen (path) + 1;
233 path = va_arg (va, const char *);
237 built = malloc (len + 1);
238 return_val_if_fail (built != NULL, NULL);
243 while (path != NULL) {
244 if (at != 0 && built[at - 1] != delim && path[0] != delim)
247 assert (at + num < len);
248 memcpy (built + at, path, num);
251 path = va_arg (va, const char *);