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 */
27static int
28create_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
60status_t
61find_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