1 /* 2 * Copyright 2002, Sebastian Nozzi <sebnozzi@gmx.net>. 3 * Copyright 2004, Francois Revol. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8 #include <stdio.h> 9 #include <string.h> 10 11 #include <FindDirectory.h> 12 #include <fs_info.h> 13 14 15 #define NO_ERRORS 0 16 #define ARGUMENT_MISSING 1 17 #define WRONG_DIR_TYPE 2 18 19 typedef struct { 20 const char *key; 21 directory_which value; 22 } directoryType; 23 24 #define KEYVALUE_PAIR(key) {#key, key} 25 26 directoryType directoryTypes[] = { 27 // Generic directories 28 KEYVALUE_PAIR(B_DESKTOP_DIRECTORY), 29 KEYVALUE_PAIR(B_TRASH_DIRECTORY), 30 KEYVALUE_PAIR(B_APPS_DIRECTORY), 31 KEYVALUE_PAIR(B_PACKAGE_LINKS_DIRECTORY), 32 KEYVALUE_PAIR(B_PREFERENCES_DIRECTORY), 33 KEYVALUE_PAIR(B_UTILITIES_DIRECTORY), 34 35 // System directories 36 KEYVALUE_PAIR(B_SYSTEM_DIRECTORY), 37 KEYVALUE_PAIR(B_SYSTEM_ADDONS_DIRECTORY), 38 KEYVALUE_PAIR(B_SYSTEM_BOOT_DIRECTORY), 39 KEYVALUE_PAIR(B_SYSTEM_FONTS_DIRECTORY), 40 KEYVALUE_PAIR(B_SYSTEM_LIB_DIRECTORY), 41 KEYVALUE_PAIR(B_SYSTEM_SERVERS_DIRECTORY), 42 KEYVALUE_PAIR(B_SYSTEM_APPS_DIRECTORY), 43 KEYVALUE_PAIR(B_SYSTEM_BIN_DIRECTORY), 44 KEYVALUE_PAIR(B_SYSTEM_DOCUMENTATION_DIRECTORY), 45 KEYVALUE_PAIR(B_SYSTEM_PREFERENCES_DIRECTORY), 46 KEYVALUE_PAIR(B_SYSTEM_TRANSLATORS_DIRECTORY), 47 KEYVALUE_PAIR(B_SYSTEM_MEDIA_NODES_DIRECTORY), 48 KEYVALUE_PAIR(B_SYSTEM_SOUNDS_DIRECTORY), 49 KEYVALUE_PAIR(B_SYSTEM_DATA_DIRECTORY), 50 KEYVALUE_PAIR(B_SYSTEM_DEVELOP_DIRECTORY), 51 KEYVALUE_PAIR(B_SYSTEM_PACKAGES_DIRECTORY), 52 KEYVALUE_PAIR(B_SYSTEM_HEADERS_DIRECTORY), 53 KEYVALUE_PAIR(B_SYSTEM_DESKBAR_DIRECTORY), 54 55 // Writable system directories 56 KEYVALUE_PAIR(B_SYSTEM_ETC_DIRECTORY), 57 KEYVALUE_PAIR(B_SYSTEM_SETTINGS_DIRECTORY), 58 KEYVALUE_PAIR(B_SYSTEM_LOG_DIRECTORY), 59 KEYVALUE_PAIR(B_SYSTEM_SPOOL_DIRECTORY), 60 KEYVALUE_PAIR(B_SYSTEM_TEMP_DIRECTORY), 61 KEYVALUE_PAIR(B_SYSTEM_VAR_DIRECTORY), 62 KEYVALUE_PAIR(B_SYSTEM_CACHE_DIRECTORY), 63 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_DIRECTORY), 64 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY), 65 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_TRANSLATORS_DIRECTORY), 66 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_MEDIA_NODES_DIRECTORY), 67 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_BIN_DIRECTORY), 68 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_DATA_DIRECTORY), 69 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_FONTS_DIRECTORY), 70 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_SOUNDS_DIRECTORY), 71 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_DOCUMENTATION_DIRECTORY), 72 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_LIB_DIRECTORY), 73 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_HEADERS_DIRECTORY), 74 KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_DEVELOP_DIRECTORY), 75 76 // User directories 77 KEYVALUE_PAIR(B_USER_DIRECTORY), 78 KEYVALUE_PAIR(B_USER_CONFIG_DIRECTORY), 79 KEYVALUE_PAIR(B_USER_ADDONS_DIRECTORY), 80 KEYVALUE_PAIR(B_USER_BOOT_DIRECTORY), 81 KEYVALUE_PAIR(B_USER_FONTS_DIRECTORY), 82 KEYVALUE_PAIR(B_USER_LIB_DIRECTORY), 83 KEYVALUE_PAIR(B_USER_SETTINGS_DIRECTORY), 84 KEYVALUE_PAIR(B_USER_DESKBAR_DIRECTORY), 85 KEYVALUE_PAIR(B_USER_PRINTERS_DIRECTORY), 86 KEYVALUE_PAIR(B_USER_TRANSLATORS_DIRECTORY), 87 KEYVALUE_PAIR(B_USER_MEDIA_NODES_DIRECTORY), 88 KEYVALUE_PAIR(B_USER_SOUNDS_DIRECTORY), 89 KEYVALUE_PAIR(B_USER_DATA_DIRECTORY), 90 KEYVALUE_PAIR(B_USER_CACHE_DIRECTORY), 91 KEYVALUE_PAIR(B_USER_PACKAGES_DIRECTORY), 92 KEYVALUE_PAIR(B_USER_DEVELOP_DIRECTORY), 93 KEYVALUE_PAIR(B_USER_DOCUMENTATION_DIRECTORY), 94 KEYVALUE_PAIR(B_USER_HEADERS_DIRECTORY), 95 KEYVALUE_PAIR(B_USER_SERVERS_DIRECTORY), 96 KEYVALUE_PAIR(B_USER_APPS_DIRECTORY), 97 KEYVALUE_PAIR(B_USER_BIN_DIRECTORY), 98 KEYVALUE_PAIR(B_USER_PREFERENCES_DIRECTORY), 99 KEYVALUE_PAIR(B_USER_ETC_DIRECTORY), 100 KEYVALUE_PAIR(B_USER_LOG_DIRECTORY), 101 KEYVALUE_PAIR(B_USER_SPOOL_DIRECTORY), 102 KEYVALUE_PAIR(B_USER_VAR_DIRECTORY), 103 KEYVALUE_PAIR(B_USER_NONPACKAGED_DIRECTORY), 104 KEYVALUE_PAIR(B_USER_NONPACKAGED_ADDONS_DIRECTORY), 105 KEYVALUE_PAIR(B_USER_NONPACKAGED_TRANSLATORS_DIRECTORY), 106 KEYVALUE_PAIR(B_USER_NONPACKAGED_MEDIA_NODES_DIRECTORY), 107 KEYVALUE_PAIR(B_USER_NONPACKAGED_BIN_DIRECTORY), 108 KEYVALUE_PAIR(B_USER_NONPACKAGED_DATA_DIRECTORY), 109 KEYVALUE_PAIR(B_USER_NONPACKAGED_FONTS_DIRECTORY), 110 KEYVALUE_PAIR(B_USER_NONPACKAGED_SOUNDS_DIRECTORY), 111 KEYVALUE_PAIR(B_USER_NONPACKAGED_DOCUMENTATION_DIRECTORY), 112 KEYVALUE_PAIR(B_USER_NONPACKAGED_LIB_DIRECTORY), 113 KEYVALUE_PAIR(B_USER_NONPACKAGED_HEADERS_DIRECTORY), 114 KEYVALUE_PAIR(B_USER_NONPACKAGED_DEVELOP_DIRECTORY), 115 116 // Legacy system directories 117 KEYVALUE_PAIR(B_BEOS_DIRECTORY), 118 KEYVALUE_PAIR(B_BEOS_SYSTEM_DIRECTORY), 119 KEYVALUE_PAIR(B_BEOS_ADDONS_DIRECTORY), 120 KEYVALUE_PAIR(B_BEOS_BOOT_DIRECTORY), 121 KEYVALUE_PAIR(B_BEOS_FONTS_DIRECTORY), 122 KEYVALUE_PAIR(B_BEOS_LIB_DIRECTORY), 123 KEYVALUE_PAIR(B_BEOS_SERVERS_DIRECTORY), 124 KEYVALUE_PAIR(B_BEOS_APPS_DIRECTORY), 125 KEYVALUE_PAIR(B_BEOS_BIN_DIRECTORY), 126 KEYVALUE_PAIR(B_BEOS_ETC_DIRECTORY), 127 KEYVALUE_PAIR(B_BEOS_DOCUMENTATION_DIRECTORY), 128 KEYVALUE_PAIR(B_BEOS_PREFERENCES_DIRECTORY), 129 KEYVALUE_PAIR(B_BEOS_TRANSLATORS_DIRECTORY), 130 KEYVALUE_PAIR(B_BEOS_MEDIA_NODES_DIRECTORY), 131 KEYVALUE_PAIR(B_BEOS_SOUNDS_DIRECTORY), 132 133 // Legacy "common" directories, for BeOS compatibility only. 134 {"B_COMMON_DIRECTORY", B_SYSTEM_NONPACKAGED_DIRECTORY}, 135 {"B_COMMON_SYSTEM_DIRECTORY", B_SYSTEM_NONPACKAGED_DIRECTORY}, 136 {"B_COMMON_ADDONS_DIRECTORY", B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY}, 137 {"B_COMMON_BIN_DIRECTORY", B_SYSTEM_NONPACKAGED_BIN_DIRECTORY}, 138 {"B_COMMON_DEVELOP_DIRECTORY", B_SYSTEM_NONPACKAGED_DEVELOP_DIRECTORY}, 139 {"B_COMMON_DOCUMENTATION_DIRECTORY", 140 B_SYSTEM_NONPACKAGED_DOCUMENTATION_DIRECTORY}, 141 {"B_COMMON_FONTS_DIRECTORY",B_SYSTEM_NONPACKAGED_FONTS_DIRECTORY}, 142 {"B_COMMON_LIB_DIRECTORY", B_SYSTEM_NONPACKAGED_LIB_DIRECTORY}, 143 144 {"B_COMMON_BOOT_DIRECTORY", B_SYSTEM_BOOT_DIRECTORY}, 145 {"B_COMMON_ETC_DIRECTORY", B_SYSTEM_ETC_DIRECTORY}, 146 {"B_COMMON_LOG_DIRECTORY", B_SYSTEM_LOG_DIRECTORY}, 147 {"B_COMMON_SERVERS_DIRECTORY", B_SYSTEM_SERVERS_DIRECTORY}, 148 {"B_COMMON_SETTINGS_DIRECTORY", B_SYSTEM_SETTINGS_DIRECTORY}, 149 {"B_COMMON_SPOOL_DIRECTORY", B_SYSTEM_SPOOL_DIRECTORY}, 150 {"B_COMMON_TEMP_DIRECTORY", B_SYSTEM_TEMP_DIRECTORY}, 151 {"B_COMMON_VAR_DIRECTORY", B_SYSTEM_VAR_DIRECTORY}, 152 153 {NULL, B_USER_DESKBAR_DIRECTORY} 154 }; 155 156 157 static void 158 listDirectoryWhich(void) 159 { 160 int i; 161 162 for (i = 0; directoryTypes[i].key; i++) { 163 printf("%s\n", directoryTypes[i].key); 164 } 165 } 166 167 168 static bool 169 retrieveDirValue(directoryType *list, const char *key, 170 directory_which *valueOut) 171 { 172 unsigned i = 0; 173 174 while (list[i].key != NULL) { 175 if (strcmp(list[i].key, key) == 0) { 176 *valueOut = list[i].value; 177 return true; 178 } 179 180 i++; 181 } 182 183 return false; 184 } 185 186 187 static void 188 usageMsg() 189 { 190 printf("usage: /bin/finddir -l | [ -v volume ] directory_which\n"); 191 printf("\t-l\t list valid which constants to use\n"); 192 printf("\t-v <file> use the specified volume for directory\n"); 193 printf("\t\t constants that are volume-specific.\n"); 194 printf("\t\t <file> can be any file on that volume.\n"); 195 printf("\t\t defaults to the boot volume.\n"); 196 printf(" For a description of recognized directory_which constants,\n"); 197 printf(" see the find_directory(...) documentation in the Be Book.\n"); 198 } 199 200 201 int 202 main(int argc, char *argv[]) 203 { 204 int directoryArgNr; 205 int status; 206 dev_t volume; 207 directory_which dirType; 208 int returnCode; 209 210 status = NO_ERRORS; 211 directoryArgNr = 1; 212 returnCode = 0; 213 214 dirType = B_BEOS_DIRECTORY; /* so that it compiles */ 215 216 /* By default use boot volume*/ 217 volume = dev_for_path("/boot"); 218 219 if (argc <= 1) { 220 status = ARGUMENT_MISSING; 221 } else { 222 if (strcmp(argv[1], "-l") == 0 ) { 223 listDirectoryWhich(); 224 return 0; 225 } 226 if (strcmp(argv[1], "-v") == 0 ) { 227 if (argc >= 3) { 228 dev_t temp_volume; 229 /* get volume from second arg */ 230 temp_volume = dev_for_path(argv[2]); 231 232 /* Keep default value in case of error */ 233 if (temp_volume >= 0) 234 volume = temp_volume; 235 236 /* two arguments were used for volume */ 237 directoryArgNr+=2; 238 } else { 239 /* set status to argument missing */ 240 status = ARGUMENT_MISSING; 241 } 242 } 243 } 244 245 if (status == NO_ERRORS && argc > directoryArgNr) { 246 /* get directory constant from next argument */ 247 248 if (!retrieveDirValue(directoryTypes, argv[directoryArgNr], &dirType)) 249 status = WRONG_DIR_TYPE; 250 } else { 251 status = ARGUMENT_MISSING; 252 } 253 254 /* Do the actual directoy finding */ 255 256 if (status == NO_ERRORS) { 257 /* Question: would B_PATH_NAME_LENGTH alone have been enough? */ 258 char buffer[B_PATH_NAME_LENGTH+B_FILE_NAME_LENGTH]; 259 status_t result = find_directory (dirType, volume, false, buffer, 260 sizeof(buffer)); 261 if (result == B_OK) { 262 printf("%s\n", buffer); 263 } else { 264 fprintf(stderr, "Failed to get directory: %s\n", strerror(result)); 265 return 1; 266 } 267 } 268 269 /* Error messages and return code setting */ 270 271 if (status == WRONG_DIR_TYPE) { 272 fprintf(stderr, "%s: unrecognized directory_which constant \'%s\'\n", argv[0], 273 argv[directoryArgNr]); 274 returnCode = 252; 275 } 276 277 if (status == ARGUMENT_MISSING) { 278 usageMsg(); 279 returnCode = 255; 280 } 281 282 return returnCode; 283 } 284 285