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