11590Srgrimes/*
239230Sgibbs * Copyright 2004, Fran��ois Revol.
339230Sgibbs * Copyright 2007-2010, Axel D��rfler, axeld@pinc-software.de.
439230Sgibbs * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
539230Sgibbs * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
639230Sgibbs * Distributed under the terms of the MIT License.
739230Sgibbs */
839230Sgibbs
939230Sgibbs
1039230Sgibbs#include <FindDirectory.h>
1139230Sgibbs
1239230Sgibbs#include <errno.h>
1339230Sgibbs#include <string.h>
1439230Sgibbs#include <sys/stat.h>
1539230Sgibbs#include <stdlib.h>
1639230Sgibbs#include <unistd.h>
1739230Sgibbs
1839230Sgibbs#include <StorageDefs.h>
1939230Sgibbs
2039230Sgibbs#include <find_directory_private.h>
2139230Sgibbs
2239230Sgibbs
2339230Sgibbs#ifndef HAIKU_BUILD_GENERATED_DIRECTORY
2439230Sgibbs#	error HAIKU_BUILD_GENERATED_DIRECTORY not defined!
2539230Sgibbs#endif
2639230Sgibbs
2739230Sgibbs
2839230Sgibbs/*! make dir and its parents if needed */
291590Srgrimesstatic int
301590Srgrimescreate_path(const char *path, mode_t mode)
311590Srgrimes{
321590Srgrimes	char buffer[B_PATH_NAME_LENGTH + 1];
331590Srgrimes	int pathLength;
341590Srgrimes	int i = 0;
351590Srgrimes
361590Srgrimes	if (path == NULL || ((pathLength = strlen(path)) > B_PATH_NAME_LENGTH))
371590Srgrimes		return EINVAL;
381590Srgrimes
391590Srgrimes	while (++i < pathLength) {
401590Srgrimes		const char *slash = strchr(&path[i], '/');
411590Srgrimes		struct stat st;
421590Srgrimes
431590Srgrimes		if (slash == NULL)
441590Srgrimes			i = pathLength;
451590Srgrimes		else if (i != slash - path)
461590Srgrimes			i = slash - path;
471590Srgrimes		else
481590Srgrimes			continue;
491590Srgrimes
501590Srgrimes		strlcpy(buffer, path, i + 1);
511590Srgrimes		if (stat(buffer, &st) < 0) {
521590Srgrimes			errno = 0;
531590Srgrimes			if (mkdir(buffer, mode) < 0)
541590Srgrimes				return errno;
551590Srgrimes		}
561590Srgrimes	}
5787715Smarkm
581590Srgrimes	return 0;
5987715Smarkm}
6087715Smarkm
6187715Smarkm
6287715Smarkmstatus_t
6387715Smarkmfind_directory(directory_which which, dev_t device, bool createIt,
6487715Smarkm	char *returnedPath, int32 pathLength)
651590Srgrimes{
6674671Stmm	// we support only the handful of paths we need
67111007Sphk	const char* path;
681590Srgrimes	switch (which) {
6987715Smarkm		case B_SYSTEM_TEMP_DIRECTORY:
7087715Smarkm			path = HAIKU_BUILD_GENERATED_DIRECTORY "/tmp";
711590Srgrimes			break;
72200462Sdelphij		case B_SYSTEM_SETTINGS_DIRECTORY:
7387715Smarkm			path = HAIKU_BUILD_GENERATED_DIRECTORY "/system/settings";
7487715Smarkm			break;
7587715Smarkm		case B_SYSTEM_CACHE_DIRECTORY:
761590Srgrimes			path = HAIKU_BUILD_GENERATED_DIRECTORY "/system/cache";
771590Srgrimes			break;
7840060Sobrien		case B_USER_SETTINGS_DIRECTORY:
791590Srgrimes			path = HAIKU_BUILD_GENERATED_DIRECTORY "/user/settings";
8039230Sgibbs			break;
811590Srgrimes		case B_USER_CACHE_DIRECTORY:
821590Srgrimes			path = HAIKU_BUILD_GENERATED_DIRECTORY "/user/cache";
831590Srgrimes			break;
841590Srgrimes		default:
8539230Sgibbs			return B_BAD_VALUE;
861590Srgrimes	}
8792922Simp
8892922Simp	// create, if necessary
8992922Simp	status_t error = B_OK;
9092922Simp	struct stat st;
9192922Simp	if (createIt && stat(path, &st) < 0)
921590Srgrimes		error = create_path(path, 0755);
931590Srgrimes
94175387Sdelphij	if (error == B_OK)
951590Srgrimes		strlcpy(returnedPath, path, pathLength);
96158160Sbde
971590Srgrimes	return error;
981590Srgrimes}
991590Srgrimes
100175387Sdelphij
1011590Srgrimesstatus_t
1021590Srgrimes__find_directory(directory_which which, dev_t device, bool createIt,
1031590Srgrimes	char *returnedPath, int32 pathLength)
1041590Srgrimes{
1051590Srgrimes	return find_directory(which, device, createIt, returnedPath, pathLength);
1061590Srgrimes}
1071590Srgrimes