117049c45SAxel Dörfler /*
2ded43249SAxel Dörfler * Copyright 2002, Sebastian Nozzi <sebnozzi@gmx.net>.
3ded43249SAxel Dörfler * Copyright 2004, Francois Revol.
4ded43249SAxel Dörfler *
5ded43249SAxel Dörfler * Distributed under the terms of the MIT License.
617049c45SAxel Dörfler */
717049c45SAxel Dörfler
817049c45SAxel Dörfler #include <stdio.h>
917049c45SAxel Dörfler #include <string.h>
1017049c45SAxel Dörfler
11ded43249SAxel Dörfler #include <FindDirectory.h>
12ded43249SAxel Dörfler #include <fs_info.h>
13ded43249SAxel Dörfler
14494301a5SAxel Dörfler
15494301a5SAxel Dörfler #define NO_ERRORS 0
16494301a5SAxel Dörfler #define ARGUMENT_MISSING 1
17494301a5SAxel Dörfler #define WRONG_DIR_TYPE 2
18494301a5SAxel Dörfler
19494301a5SAxel Dörfler typedef struct {
2017049c45SAxel Dörfler const char *key;
2117049c45SAxel Dörfler directory_which value;
2217049c45SAxel Dörfler } directoryType;
2317049c45SAxel Dörfler
2417049c45SAxel Dörfler #define KEYVALUE_PAIR(key) {#key, key}
2517049c45SAxel Dörfler
2617049c45SAxel Dörfler directoryType directoryTypes[] = {
27ded43249SAxel Dörfler // Generic directories
2817049c45SAxel Dörfler KEYVALUE_PAIR(B_DESKTOP_DIRECTORY),
2917049c45SAxel Dörfler KEYVALUE_PAIR(B_TRASH_DIRECTORY),
3017049c45SAxel Dörfler KEYVALUE_PAIR(B_APPS_DIRECTORY),
313dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_PACKAGE_LINKS_DIRECTORY),
3217049c45SAxel Dörfler KEYVALUE_PAIR(B_PREFERENCES_DIRECTORY),
33ded43249SAxel Dörfler KEYVALUE_PAIR(B_UTILITIES_DIRECTORY),
34ded43249SAxel Dörfler
35ded43249SAxel Dörfler // System directories
36ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_DIRECTORY),
37ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_ADDONS_DIRECTORY),
38ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_BOOT_DIRECTORY),
39ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_FONTS_DIRECTORY),
40ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_LIB_DIRECTORY),
41ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_SERVERS_DIRECTORY),
42ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_APPS_DIRECTORY),
43ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_BIN_DIRECTORY),
44ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_DOCUMENTATION_DIRECTORY),
45ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_PREFERENCES_DIRECTORY),
46ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_TRANSLATORS_DIRECTORY),
47ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_MEDIA_NODES_DIRECTORY),
48ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_SOUNDS_DIRECTORY),
49ded43249SAxel Dörfler KEYVALUE_PAIR(B_SYSTEM_DATA_DIRECTORY),
503dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_SYSTEM_DEVELOP_DIRECTORY),
513dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_SYSTEM_PACKAGES_DIRECTORY),
523dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_SYSTEM_HEADERS_DIRECTORY),
53*c237c4ceSAlexander von Gluck KEYVALUE_PAIR(B_SYSTEM_DESKBAR_DIRECTORY),
54ded43249SAxel Dörfler
5538fa81bfSIngo Weinhold // Writable system directories
564b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_ETC_DIRECTORY),
574b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_SETTINGS_DIRECTORY),
584b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_LOG_DIRECTORY),
594b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_SPOOL_DIRECTORY),
604b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_TEMP_DIRECTORY),
614b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_VAR_DIRECTORY),
624b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_CACHE_DIRECTORY),
634b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_DIRECTORY),
644b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY),
654b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_TRANSLATORS_DIRECTORY),
664b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_MEDIA_NODES_DIRECTORY),
674b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_BIN_DIRECTORY),
684b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_DATA_DIRECTORY),
694b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_FONTS_DIRECTORY),
704b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_SOUNDS_DIRECTORY),
714b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_DOCUMENTATION_DIRECTORY),
724b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_LIB_DIRECTORY),
734b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_HEADERS_DIRECTORY),
744b7e2196SIngo Weinhold KEYVALUE_PAIR(B_SYSTEM_NONPACKAGED_DEVELOP_DIRECTORY),
75ded43249SAxel Dörfler
76ded43249SAxel Dörfler // User directories
7717049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_DIRECTORY),
7817049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_CONFIG_DIRECTORY),
7917049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_ADDONS_DIRECTORY),
8017049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_BOOT_DIRECTORY),
8117049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_FONTS_DIRECTORY),
8217049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_LIB_DIRECTORY),
8317049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_SETTINGS_DIRECTORY),
8417049c45SAxel Dörfler KEYVALUE_PAIR(B_USER_DESKBAR_DIRECTORY),
85ded43249SAxel Dörfler KEYVALUE_PAIR(B_USER_PRINTERS_DIRECTORY),
86ded43249SAxel Dörfler KEYVALUE_PAIR(B_USER_TRANSLATORS_DIRECTORY),
87ded43249SAxel Dörfler KEYVALUE_PAIR(B_USER_MEDIA_NODES_DIRECTORY),
88ded43249SAxel Dörfler KEYVALUE_PAIR(B_USER_SOUNDS_DIRECTORY),
89ded43249SAxel Dörfler KEYVALUE_PAIR(B_USER_DATA_DIRECTORY),
90ded43249SAxel Dörfler KEYVALUE_PAIR(B_USER_CACHE_DIRECTORY),
913dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_PACKAGES_DIRECTORY),
923f85cfc1SIngo Weinhold KEYVALUE_PAIR(B_USER_DEVELOP_DIRECTORY),
933f85cfc1SIngo Weinhold KEYVALUE_PAIR(B_USER_DOCUMENTATION_DIRECTORY),
943dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_HEADERS_DIRECTORY),
95635d2ac4SIngo Weinhold KEYVALUE_PAIR(B_USER_SERVERS_DIRECTORY),
96635d2ac4SIngo Weinhold KEYVALUE_PAIR(B_USER_APPS_DIRECTORY),
97635d2ac4SIngo Weinhold KEYVALUE_PAIR(B_USER_BIN_DIRECTORY),
98635d2ac4SIngo Weinhold KEYVALUE_PAIR(B_USER_PREFERENCES_DIRECTORY),
99635d2ac4SIngo Weinhold KEYVALUE_PAIR(B_USER_ETC_DIRECTORY),
100635d2ac4SIngo Weinhold KEYVALUE_PAIR(B_USER_LOG_DIRECTORY),
101635d2ac4SIngo Weinhold KEYVALUE_PAIR(B_USER_SPOOL_DIRECTORY),
102635d2ac4SIngo Weinhold KEYVALUE_PAIR(B_USER_VAR_DIRECTORY),
1033dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_NONPACKAGED_DIRECTORY),
1043dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_NONPACKAGED_ADDONS_DIRECTORY),
1053dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_NONPACKAGED_TRANSLATORS_DIRECTORY),
1063dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_NONPACKAGED_MEDIA_NODES_DIRECTORY),
1073dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_NONPACKAGED_BIN_DIRECTORY),
1083dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_NONPACKAGED_DATA_DIRECTORY),
1093dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_NONPACKAGED_FONTS_DIRECTORY),
1103dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_NONPACKAGED_SOUNDS_DIRECTORY),
1113dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_NONPACKAGED_DOCUMENTATION_DIRECTORY),
1123dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_NONPACKAGED_LIB_DIRECTORY),
1133dfd9cb9SOliver Tappe KEYVALUE_PAIR(B_USER_NONPACKAGED_HEADERS_DIRECTORY),
1143f85cfc1SIngo Weinhold KEYVALUE_PAIR(B_USER_NONPACKAGED_DEVELOP_DIRECTORY),
115ded43249SAxel Dörfler
116ded43249SAxel Dörfler // Legacy system directories
117ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_DIRECTORY),
118ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_SYSTEM_DIRECTORY),
119ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_ADDONS_DIRECTORY),
120ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_BOOT_DIRECTORY),
121ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_FONTS_DIRECTORY),
122ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_LIB_DIRECTORY),
123ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_SERVERS_DIRECTORY),
124ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_APPS_DIRECTORY),
125ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_BIN_DIRECTORY),
126ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_ETC_DIRECTORY),
127ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_DOCUMENTATION_DIRECTORY),
128ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_PREFERENCES_DIRECTORY),
129ded43249SAxel Dörfler KEYVALUE_PAIR(B_BEOS_TRANSLATORS_DIRECTORY),
13017049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_MEDIA_NODES_DIRECTORY),
13117049c45SAxel Dörfler KEYVALUE_PAIR(B_BEOS_SOUNDS_DIRECTORY),
132ded43249SAxel Dörfler
13379ce2c2dSAdrien Destugues // Legacy "common" directories, for BeOS compatibility only.
13479ce2c2dSAdrien Destugues {"B_COMMON_DIRECTORY", B_SYSTEM_NONPACKAGED_DIRECTORY},
13579ce2c2dSAdrien Destugues {"B_COMMON_SYSTEM_DIRECTORY", B_SYSTEM_NONPACKAGED_DIRECTORY},
13679ce2c2dSAdrien Destugues {"B_COMMON_ADDONS_DIRECTORY", B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY},
13779ce2c2dSAdrien Destugues {"B_COMMON_BIN_DIRECTORY", B_SYSTEM_NONPACKAGED_BIN_DIRECTORY},
13879ce2c2dSAdrien Destugues {"B_COMMON_DEVELOP_DIRECTORY", B_SYSTEM_NONPACKAGED_DEVELOP_DIRECTORY},
13979ce2c2dSAdrien Destugues {"B_COMMON_DOCUMENTATION_DIRECTORY",
14079ce2c2dSAdrien Destugues B_SYSTEM_NONPACKAGED_DOCUMENTATION_DIRECTORY},
14179ce2c2dSAdrien Destugues {"B_COMMON_FONTS_DIRECTORY",B_SYSTEM_NONPACKAGED_FONTS_DIRECTORY},
14279ce2c2dSAdrien Destugues {"B_COMMON_LIB_DIRECTORY", B_SYSTEM_NONPACKAGED_LIB_DIRECTORY},
14379ce2c2dSAdrien Destugues
14479ce2c2dSAdrien Destugues {"B_COMMON_BOOT_DIRECTORY", B_SYSTEM_BOOT_DIRECTORY},
14579ce2c2dSAdrien Destugues {"B_COMMON_ETC_DIRECTORY", B_SYSTEM_ETC_DIRECTORY},
14679ce2c2dSAdrien Destugues {"B_COMMON_LOG_DIRECTORY", B_SYSTEM_LOG_DIRECTORY},
14779ce2c2dSAdrien Destugues {"B_COMMON_SERVERS_DIRECTORY", B_SYSTEM_SERVERS_DIRECTORY},
14879ce2c2dSAdrien Destugues {"B_COMMON_SETTINGS_DIRECTORY", B_SYSTEM_SETTINGS_DIRECTORY},
14979ce2c2dSAdrien Destugues {"B_COMMON_SPOOL_DIRECTORY", B_SYSTEM_SPOOL_DIRECTORY},
15079ce2c2dSAdrien Destugues {"B_COMMON_TEMP_DIRECTORY", B_SYSTEM_TEMP_DIRECTORY},
15179ce2c2dSAdrien Destugues {"B_COMMON_VAR_DIRECTORY", B_SYSTEM_VAR_DIRECTORY},
15279ce2c2dSAdrien Destugues
15317049c45SAxel Dörfler {NULL, B_USER_DESKBAR_DIRECTORY}
15417049c45SAxel Dörfler };
15517049c45SAxel Dörfler
156494301a5SAxel Dörfler
157494301a5SAxel Dörfler static void
listDirectoryWhich(void)158494301a5SAxel Dörfler listDirectoryWhich(void)
15917049c45SAxel Dörfler {
16017049c45SAxel Dörfler int i;
16117049c45SAxel Dörfler
16217049c45SAxel Dörfler for (i = 0; directoryTypes[i].key; i++) {
16317049c45SAxel Dörfler printf("%s\n", directoryTypes[i].key);
16417049c45SAxel Dörfler }
16517049c45SAxel Dörfler }
16617049c45SAxel Dörfler
167494301a5SAxel Dörfler
168494301a5SAxel Dörfler static bool
retrieveDirValue(directoryType * list,const char * key,directory_which * valueOut)169ded43249SAxel Dörfler retrieveDirValue(directoryType *list, const char *key,
170ded43249SAxel Dörfler directory_which *valueOut)
17117049c45SAxel Dörfler {
17217049c45SAxel Dörfler unsigned i = 0;
17317049c45SAxel Dörfler
174494301a5SAxel Dörfler while (list[i].key != NULL) {
175494301a5SAxel Dörfler if (strcmp(list[i].key, key) == 0) {
176ded43249SAxel Dörfler *valueOut = list[i].value;
17717049c45SAxel Dörfler return true;
17817049c45SAxel Dörfler }
17917049c45SAxel Dörfler
18017049c45SAxel Dörfler i++;
18117049c45SAxel Dörfler }
18217049c45SAxel Dörfler
18317049c45SAxel Dörfler return false;
18417049c45SAxel Dörfler }
18517049c45SAxel Dörfler
186494301a5SAxel Dörfler
187494301a5SAxel Dörfler static void
usageMsg()188494301a5SAxel Dörfler usageMsg()
18917049c45SAxel Dörfler {
19017049c45SAxel Dörfler printf("usage: /bin/finddir -l | [ -v volume ] directory_which\n");
19117049c45SAxel Dörfler printf("\t-l\t list valid which constants to use\n");
19217049c45SAxel Dörfler printf("\t-v <file> use the specified volume for directory\n");
19317049c45SAxel Dörfler printf("\t\t constants that are volume-specific.\n");
19417049c45SAxel Dörfler printf("\t\t <file> can be any file on that volume.\n");
19517049c45SAxel Dörfler printf("\t\t defaults to the boot volume.\n");
19617049c45SAxel Dörfler printf(" For a description of recognized directory_which constants,\n");
19717049c45SAxel Dörfler printf(" see the find_directory(...) documentation in the Be Book.\n");
19817049c45SAxel Dörfler }
19917049c45SAxel Dörfler
20017049c45SAxel Dörfler
201494301a5SAxel Dörfler int
main(int argc,char * argv[])202494301a5SAxel Dörfler main(int argc, char *argv[])
20317049c45SAxel Dörfler {
20417049c45SAxel Dörfler int directoryArgNr;
20517049c45SAxel Dörfler int status;
20617049c45SAxel Dörfler dev_t volume;
20717049c45SAxel Dörfler directory_which dirType;
20817049c45SAxel Dörfler int returnCode;
20917049c45SAxel Dörfler
21017049c45SAxel Dörfler status = NO_ERRORS;
21117049c45SAxel Dörfler directoryArgNr = 1;
21217049c45SAxel Dörfler returnCode = 0;
21317049c45SAxel Dörfler
21417049c45SAxel Dörfler dirType = B_BEOS_DIRECTORY; /* so that it compiles */
21517049c45SAxel Dörfler
21617049c45SAxel Dörfler /* By default use boot volume*/
21717049c45SAxel Dörfler volume = dev_for_path("/boot");
21817049c45SAxel Dörfler
21917049c45SAxel Dörfler if (argc <= 1) {
22017049c45SAxel Dörfler status = ARGUMENT_MISSING;
22117049c45SAxel Dörfler } else {
22217049c45SAxel Dörfler if (strcmp(argv[1], "-l") == 0 ) {
22317049c45SAxel Dörfler listDirectoryWhich();
22417049c45SAxel Dörfler return 0;
22517049c45SAxel Dörfler }
22617049c45SAxel Dörfler if (strcmp(argv[1], "-v") == 0 ) {
22717049c45SAxel Dörfler if (argc >= 3) {
22817049c45SAxel Dörfler dev_t temp_volume;
22917049c45SAxel Dörfler /* get volume from second arg */
23017049c45SAxel Dörfler temp_volume = dev_for_path(argv[2]);
23117049c45SAxel Dörfler
23217049c45SAxel Dörfler /* Keep default value in case of error */
23317049c45SAxel Dörfler if (temp_volume >= 0)
23417049c45SAxel Dörfler volume = temp_volume;
23517049c45SAxel Dörfler
23617049c45SAxel Dörfler /* two arguments were used for volume */
23717049c45SAxel Dörfler directoryArgNr+=2;
23817049c45SAxel Dörfler } else {
23917049c45SAxel Dörfler /* set status to argument missing */
24017049c45SAxel Dörfler status = ARGUMENT_MISSING;
24117049c45SAxel Dörfler }
24217049c45SAxel Dörfler }
24317049c45SAxel Dörfler }
24417049c45SAxel Dörfler
24517049c45SAxel Dörfler if (status == NO_ERRORS && argc > directoryArgNr) {
24617049c45SAxel Dörfler /* get directory constant from next argument */
24717049c45SAxel Dörfler
248ded43249SAxel Dörfler if (!retrieveDirValue(directoryTypes, argv[directoryArgNr], &dirType))
24917049c45SAxel Dörfler status = WRONG_DIR_TYPE;
25017049c45SAxel Dörfler } else {
25117049c45SAxel Dörfler status = ARGUMENT_MISSING;
25217049c45SAxel Dörfler }
25317049c45SAxel Dörfler
25417049c45SAxel Dörfler /* Do the actual directoy finding */
25517049c45SAxel Dörfler
25617049c45SAxel Dörfler if (status == NO_ERRORS) {
25717049c45SAxel Dörfler /* Question: would B_PATH_NAME_LENGTH alone have been enough? */
25817049c45SAxel Dörfler char buffer[B_PATH_NAME_LENGTH+B_FILE_NAME_LENGTH];
259ded43249SAxel Dörfler status_t result = find_directory (dirType, volume, false, buffer,
260ded43249SAxel Dörfler sizeof(buffer));
26117049c45SAxel Dörfler if (result == B_OK) {
26217049c45SAxel Dörfler printf("%s\n", buffer);
26317049c45SAxel Dörfler } else {
264f7d5bd46SIngo Weinhold fprintf(stderr, "Failed to get directory: %s\n", strerror(result));
265f7d5bd46SIngo Weinhold return 1;
26617049c45SAxel Dörfler }
26717049c45SAxel Dörfler }
26817049c45SAxel Dörfler
26917049c45SAxel Dörfler /* Error messages and return code setting */
27017049c45SAxel Dörfler
27117049c45SAxel Dörfler if (status == WRONG_DIR_TYPE) {
272d38e0056SPhilippe Houdoin fprintf(stderr, "%s: unrecognized directory_which constant \'%s\'\n", argv[0],
273ded43249SAxel Dörfler argv[directoryArgNr]);
27417049c45SAxel Dörfler returnCode = 252;
27517049c45SAxel Dörfler }
27617049c45SAxel Dörfler
27717049c45SAxel Dörfler if (status == ARGUMENT_MISSING) {
27817049c45SAxel Dörfler usageMsg();
27917049c45SAxel Dörfler returnCode = 255;
28017049c45SAxel Dörfler }
28117049c45SAxel Dörfler
28217049c45SAxel Dörfler return returnCode;
28317049c45SAxel Dörfler }
28417049c45SAxel Dörfler
285