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