xref: /haiku/src/build/libroot/find_directory.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
1 /*
2  * Copyright 2004, François Revol.
3  * Copyright 2007-2010, Axel Dörfler, axeld@pinc-software.de.
4  * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
5  * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
6  * Distributed under the terms of the MIT License.
7  */
8 
9 
10 #include <FindDirectory.h>
11 
12 #include <errno.h>
13 #include <string.h>
14 #include <sys/stat.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 
18 #include <StorageDefs.h>
19 
20 
21 #ifndef HAIKU_BUILD_GENERATED_DIRECTORY
22 #	error HAIKU_BUILD_GENERATED_DIRECTORY not defined!
23 #endif
24 
25 
26 /*! make dir and its parents if needed */
27 static int
28 create_path(const char *path, mode_t mode)
29 {
30 	char buffer[B_PATH_NAME_LENGTH + 1];
31 	int pathLength;
32 	int i = 0;
33 
34 	if (path == NULL || ((pathLength = strlen(path)) > B_PATH_NAME_LENGTH))
35 		return EINVAL;
36 
37 	while (++i < pathLength) {
38 		const char *slash = strchr(&path[i], '/');
39 		struct stat st;
40 
41 		if (slash == NULL)
42 			i = pathLength;
43 		else if (i != slash - path)
44 			i = slash - path;
45 		else
46 			continue;
47 
48 		strlcpy(buffer, path, i + 1);
49 		if (stat(buffer, &st) < 0) {
50 			errno = 0;
51 			if (mkdir(buffer, mode) < 0)
52 				return errno;
53 		}
54 	}
55 
56 	return 0;
57 }
58 
59 
60 status_t
61 find_directory(directory_which which, dev_t device, bool createIt,
62 	char *returnedPath, int32 pathLength)
63 {
64 	// we support only the handful of paths we need
65 	const char* path;
66 	switch (which) {
67 		case B_COMMON_TEMP_DIRECTORY:
68 			path = HAIKU_BUILD_GENERATED_DIRECTORY "/tmp";
69 			break;
70 		case B_COMMON_SETTINGS_DIRECTORY:
71 			path = HAIKU_BUILD_GENERATED_DIRECTORY "/common/settings";
72 			break;
73 		case B_COMMON_CACHE_DIRECTORY:
74 			path = HAIKU_BUILD_GENERATED_DIRECTORY "/common/cache";
75 			break;
76 		case B_USER_SETTINGS_DIRECTORY:
77 			path = HAIKU_BUILD_GENERATED_DIRECTORY "/user/settings";
78 			break;
79 		case B_USER_CACHE_DIRECTORY:
80 			path = HAIKU_BUILD_GENERATED_DIRECTORY "/user/cache";
81 			break;
82 		default:
83 			return B_BAD_VALUE;
84 	}
85 
86 	// create, if necessary
87 	status_t error = B_OK;
88 	struct stat st;
89 	if (createIt && stat(path, &st) < 0)
90 		error = create_path(path, 0755);
91 
92 	if (error == B_OK)
93 		strlcpy(returnedPath, path, pathLength);
94 
95 	return error;
96 }
97 
98