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 */
29static int
30create_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
62status_t
63find_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
101status_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