117049c45SAxel Dörfler /* 217049c45SAxel Dörfler * finddir.c - 317049c45SAxel Dörfler * (c) 2002, Sebastian Nozzi <sebnozzi@gmx.net> 417049c45SAxel Dörfler * 08/24/2004 - Francois Revol - added -l option. 517049c45SAxel Dörfler */ 617049c45SAxel Dörfler 717049c45SAxel Dörfler #include <FindDirectory.h> 817049c45SAxel Dörfler #include <fs_info.h> 917049c45SAxel Dörfler 1017049c45SAxel Dörfler #include <stdio.h> 1117049c45SAxel Dörfler #include <string.h> 1217049c45SAxel Dörfler 13*494301a5SAxel Dörfler 14*494301a5SAxel Dörfler #define NO_ERRORS 0 15*494301a5SAxel Dörfler #define ARGUMENT_MISSING 1 16*494301a5SAxel Dörfler #define WRONG_DIR_TYPE 2 17*494301a5SAxel Dörfler 18*494301a5SAxel Dörfler typedef struct { 1917049c45SAxel Dörfler const char *key; 2017049c45SAxel Dörfler directory_which value; 2117049c45SAxel Dörfler } directoryType; 2217049c45SAxel Dörfler 2317049c45SAxel Dörfler #define KEYVALUE_PAIR(key) {#key,key} 2417049c45SAxel Dörfler 2517049c45SAxel Dörfler directoryType directoryTypes[] = { 2617049c45SAxel Dörfler KEYVALUE_PAIR(B_DESKTOP_DIRECTORY), 2717049c45SAxel Dörfler KEYVALUE_PAIR(B_TRASH_DIRECTORY), 2817049c45SAxel Dörfler KEYVALUE_PAIR(B_APPS_DIRECTORY), 2917049c45SAxel Dörfler KEYVALUE_PAIR(B_PREFERENCES_DIRECTORY), 3017049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_DIRECTORY), 3117049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_SYSTEM_DIRECTORY), 3217049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_ADDONS_DIRECTORY), 3317049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_BOOT_DIRECTORY), 3417049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_FONTS_DIRECTORY), 3517049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_LIB_DIRECTORY), 3617049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_SERVERS_DIRECTORY), 3717049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_APPS_DIRECTORY), 3817049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_BIN_DIRECTORY), 3917049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_ETC_DIRECTORY), 4017049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_DOCUMENTATION_DIRECTORY), 4117049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_PREFERENCES_DIRECTORY), 4217049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_DIRECTORY), 4317049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_SYSTEM_DIRECTORY), 4417049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_ADDONS_DIRECTORY), 4517049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_BOOT_DIRECTORY), 4617049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_FONTS_DIRECTORY), 4717049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_LIB_DIRECTORY), 4817049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_SERVERS_DIRECTORY), 4917049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_BIN_DIRECTORY), 5017049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_ETC_DIRECTORY), 5117049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_DOCUMENTATION_DIRECTORY), 5217049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_SETTINGS_DIRECTORY), 5317049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_DEVELOP_DIRECTORY), 5417049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_LOG_DIRECTORY), 5517049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_SPOOL_DIRECTORY), 5617049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_TEMP_DIRECTORY), 5717049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_VAR_DIRECTORY), 5817049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_DIRECTORY), 5917049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_CONFIG_DIRECTORY), 6017049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_ADDONS_DIRECTORY), 6117049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_BOOT_DIRECTORY), 6217049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_FONTS_DIRECTORY), 6317049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_LIB_DIRECTORY), 6417049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_SETTINGS_DIRECTORY), 6517049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_DESKBAR_DIRECTORY), 6617049c45SAxel Dörfler /* some more */ 6717049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_MEDIA_NODES_DIRECTORY), 6817049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_SOUNDS_DIRECTORY), 6917049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_TRANSLATORS_DIRECTORY), 7017049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_MEDIA_NODES_DIRECTORY), 7117049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_SOUNDS_DIRECTORY), 7217049c45SAxel Dörfler KEYVALUE_PAIR(B_COMMON_TRANSLATORS_DIRECTORY), 7317049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_MEDIA_NODES_DIRECTORY), 7417049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_PRINTERS_DIRECTORY), 7517049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_SOUNDS_DIRECTORY), 7617049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_TRANSLATORS_DIRECTORY), 7717049c45SAxel Dörfler KEYVALUE_PAIR(B_UTILITIES_DIRECTORY), 7817049c45SAxel Dörfler #ifdef B_BEOS_VERSION_DANO 7917049c45SAxel Dörfler /* Dano specific */ 8017049c45SAxel Dörfler KEYVALUE_PAIR(B_ROOT_DIRECTORY), 8117049c45SAxel Dörfler #endif /* B_BEOS_VERSION_DANO */ 8217049c45SAxel Dörfler {NULL,B_USER_DESKBAR_DIRECTORY} 8317049c45SAxel Dörfler }; 8417049c45SAxel Dörfler 85*494301a5SAxel Dörfler 86*494301a5SAxel Dörfler static void 87*494301a5SAxel Dörfler listDirectoryWhich(void) 8817049c45SAxel Dörfler { 8917049c45SAxel Dörfler int i; 9017049c45SAxel Dörfler 9117049c45SAxel Dörfler for (i = 0; directoryTypes[i].key; i++) { 9217049c45SAxel Dörfler printf("%s\n", directoryTypes[i].key); 9317049c45SAxel Dörfler } 9417049c45SAxel Dörfler } 9517049c45SAxel Dörfler 96*494301a5SAxel Dörfler 97*494301a5SAxel Dörfler static bool 98*494301a5SAxel Dörfler retrieveDirValue(directoryType *list, const char *key, directory_which *value_out) 9917049c45SAxel Dörfler { 10017049c45SAxel Dörfler unsigned i = 0; 10117049c45SAxel Dörfler 102*494301a5SAxel Dörfler while (list[i].key != NULL) { 103*494301a5SAxel Dörfler if (strcmp(list[i].key, key) == 0) { 10417049c45SAxel Dörfler *value_out = list[i].value; 10517049c45SAxel Dörfler return true; 10617049c45SAxel Dörfler } 10717049c45SAxel Dörfler 10817049c45SAxel Dörfler i++; 10917049c45SAxel Dörfler } 11017049c45SAxel Dörfler 11117049c45SAxel Dörfler return false; 11217049c45SAxel Dörfler } 11317049c45SAxel Dörfler 114*494301a5SAxel Dörfler 115*494301a5SAxel Dörfler static void 116*494301a5SAxel Dörfler usageMsg() 11717049c45SAxel Dörfler { 11817049c45SAxel Dörfler printf("usage: /bin/finddir -l | [ -v volume ] directory_which\n"); 11917049c45SAxel Dörfler printf("\t-l\t list valid which constants to use\n"); 12017049c45SAxel Dörfler printf("\t-v <file> use the specified volume for directory\n"); 12117049c45SAxel Dörfler printf("\t\t constants that are volume-specific.\n"); 12217049c45SAxel Dörfler printf("\t\t <file> can be any file on that volume.\n"); 12317049c45SAxel Dörfler printf("\t\t defaults to the boot volume.\n"); 12417049c45SAxel Dörfler printf(" For a description of recognized directory_which constants,\n"); 12517049c45SAxel Dörfler printf(" see the find_directory(...) documentation in the Be Book.\n"); 12617049c45SAxel Dörfler } 12717049c45SAxel Dörfler 12817049c45SAxel Dörfler 129*494301a5SAxel Dörfler int 130*494301a5SAxel Dörfler main(int argc, char *argv[]) 13117049c45SAxel Dörfler { 13217049c45SAxel Dörfler int directoryArgNr; 13317049c45SAxel Dörfler int status; 13417049c45SAxel Dörfler dev_t volume; 13517049c45SAxel Dörfler directory_which dirType; 13617049c45SAxel Dörfler int returnCode; 13717049c45SAxel Dörfler 13817049c45SAxel Dörfler status = NO_ERRORS; 13917049c45SAxel Dörfler directoryArgNr = 1; 14017049c45SAxel Dörfler returnCode = 0; 14117049c45SAxel Dörfler 14217049c45SAxel Dörfler dirType = B_BEOS_DIRECTORY; /* so that it compiles */ 14317049c45SAxel Dörfler 14417049c45SAxel Dörfler /* By default use boot volume*/ 14517049c45SAxel Dörfler volume = dev_for_path("/boot"); 14617049c45SAxel Dörfler 14717049c45SAxel Dörfler if (argc <= 1) { 14817049c45SAxel Dörfler status = ARGUMENT_MISSING; 14917049c45SAxel Dörfler } else { 15017049c45SAxel Dörfler if (strcmp(argv[1], "-l") == 0 ) { 15117049c45SAxel Dörfler listDirectoryWhich(); 15217049c45SAxel Dörfler return 0; 15317049c45SAxel Dörfler } 15417049c45SAxel Dörfler if (strcmp(argv[1], "-v") == 0 ) { 15517049c45SAxel Dörfler if (argc >= 3) { 15617049c45SAxel Dörfler dev_t temp_volume; 15717049c45SAxel Dörfler /* get volume from second arg */ 15817049c45SAxel Dörfler temp_volume = dev_for_path(argv[2]); 15917049c45SAxel Dörfler 16017049c45SAxel Dörfler /* Keep default value in case of error */ 16117049c45SAxel Dörfler if (temp_volume >= 0) 16217049c45SAxel Dörfler volume = temp_volume; 16317049c45SAxel Dörfler 16417049c45SAxel Dörfler /* two arguments were used for volume */ 16517049c45SAxel Dörfler directoryArgNr+=2; 16617049c45SAxel Dörfler } else { 16717049c45SAxel Dörfler /* set status to argument missing */ 16817049c45SAxel Dörfler status = ARGUMENT_MISSING; 16917049c45SAxel Dörfler } 17017049c45SAxel Dörfler } 17117049c45SAxel Dörfler } 17217049c45SAxel Dörfler 17317049c45SAxel Dörfler if (status == NO_ERRORS && argc > directoryArgNr) { 17417049c45SAxel Dörfler /* get directory constant from next argument */ 17517049c45SAxel Dörfler 17617049c45SAxel Dörfler if (retrieveDirValue(directoryTypes, argv[directoryArgNr], &dirType) == false) { 17717049c45SAxel Dörfler status = WRONG_DIR_TYPE; 17817049c45SAxel Dörfler } 17917049c45SAxel Dörfler 18017049c45SAxel Dörfler } else { 18117049c45SAxel Dörfler status = ARGUMENT_MISSING; 18217049c45SAxel Dörfler } 18317049c45SAxel Dörfler 18417049c45SAxel Dörfler /* Do the actual directoy finding */ 18517049c45SAxel Dörfler 18617049c45SAxel Dörfler if (status == NO_ERRORS) { 18717049c45SAxel Dörfler /* Question: would B_PATH_NAME_LENGTH alone have been enough? */ 18817049c45SAxel Dörfler char buffer[B_PATH_NAME_LENGTH+B_FILE_NAME_LENGTH]; 18917049c45SAxel Dörfler status_t result; 19017049c45SAxel Dörfler 19117049c45SAxel Dörfler result = find_directory (dirType, volume, /*create it*/ false, buffer, sizeof(buffer)); 19217049c45SAxel Dörfler 19317049c45SAxel Dörfler if (result == B_OK) { 19417049c45SAxel Dörfler printf("%s\n", buffer); 19517049c45SAxel Dörfler } else { 19617049c45SAxel Dörfler /* else what? */ 19717049c45SAxel Dörfler /* this can not happen! */ 19817049c45SAxel Dörfler printf("Serious internal error; contact support\n"); 19917049c45SAxel Dörfler } 20017049c45SAxel Dörfler } 20117049c45SAxel Dörfler 20217049c45SAxel Dörfler /* Error messages and return code setting */ 20317049c45SAxel Dörfler 20417049c45SAxel Dörfler if (status == WRONG_DIR_TYPE) { 20517049c45SAxel Dörfler printf("%s: unrecognized directory_which constant \'%s\'\n", argv[0], argv[directoryArgNr]); 20617049c45SAxel Dörfler returnCode = 252; 20717049c45SAxel Dörfler } 20817049c45SAxel Dörfler 20917049c45SAxel Dörfler if (status == ARGUMENT_MISSING) { 21017049c45SAxel Dörfler usageMsg(); 21117049c45SAxel Dörfler returnCode = 255; 21217049c45SAxel Dörfler } 21317049c45SAxel Dörfler 21417049c45SAxel Dörfler return returnCode; 21517049c45SAxel Dörfler } 21617049c45SAxel Dörfler 217