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