xref: /haiku/src/build/libroot/find_directory.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
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 #include <find_directory_private.h>
21 
22 
23 #ifndef HAIKU_BUILD_GENERATED_DIRECTORY
24 #	error HAIKU_BUILD_GENERATED_DIRECTORY not defined!
25 #endif
26 
27 
28 /*! make dir and its parents if needed */
29 static int
30 create_path(const char *path, mode_t mode)
31 {
32 	char buffer[B_PATH_NAME_LENGTH + 1];
33 	int pathLength;
34 	int i = 0;
35 
36 	if (path == NULL || ((pathLength = strlen(path)) > B_PATH_NAME_LENGTH))
37 		return EINVAL;
38 
39 	while (++i < pathLength) {
40 		const char *slash = strchr(&path[i], '/');
41 		struct stat st;
42 
43 		if (slash == NULL)
44 			i = pathLength;
45 		else if (i != slash - path)
46 			i = slash - path;
47 		else
48 			continue;
49 
50 		strlcpy(buffer, path, i + 1);
51 		if (stat(buffer, &st) < 0) {
52 			errno = 0;
53 			if (mkdir(buffer, mode) < 0)
54 				return errno;
55 		}
56 	}
57 
58 	return 0;
59 }
60 
61 
62 status_t
63 find_directory(directory_which which, dev_t device, bool createIt,
64 	char *returnedPath, int32 pathLength)
65 {
66 	// we support only the handful of paths we need
67 	const char* path;
68 	switch (which) {
69 		case B_SYSTEM_TEMP_DIRECTORY:
70 			path = HAIKU_BUILD_GENERATED_DIRECTORY "/tmp";
71 			break;
72 		case B_SYSTEM_SETTINGS_DIRECTORY:
73 			path = HAIKU_BUILD_GENERATED_DIRECTORY "/system/settings";
74 			break;
75 		case B_SYSTEM_CACHE_DIRECTORY:
76 			path = HAIKU_BUILD_GENERATED_DIRECTORY "/system/cache";
77 			break;
78 		case B_USER_SETTINGS_DIRECTORY:
79 			path = HAIKU_BUILD_GENERATED_DIRECTORY "/user/settings";
80 			break;
81 		case B_USER_CACHE_DIRECTORY:
82 			path = HAIKU_BUILD_GENERATED_DIRECTORY "/user/cache";
83 			break;
84 		default:
85 			return B_BAD_VALUE;
86 	}
87 
88 	// create, if necessary
89 	status_t error = B_OK;
90 	struct stat st;
91 	if (createIt && stat(path, &st) < 0)
92 		error = create_path(path, 0755);
93 
94 	if (error == B_OK)
95 		strlcpy(returnedPath, path, pathLength);
96 
97 	return error;
98 }
99 
100 
101 status_t
102 __find_directory(directory_which which, dev_t device, bool createIt,
103 	char *returnedPath, int32 pathLength)
104 {
105 	return find_directory(which, device, createIt, returnedPath, pathLength);
106 }
107