xref: /haiku/src/bin/finddir.c (revision 3f85cfc1322254c2be3b8ef4aa54ea39616e91ed)
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),
53ded43249SAxel Dörfler 
54ded43249SAxel Dörfler 	// Common directories
5517049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_DIRECTORY),
5617049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_SYSTEM_DIRECTORY),
5717049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_ADDONS_DIRECTORY),
5817049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_BOOT_DIRECTORY),
5917049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_FONTS_DIRECTORY),
6017049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_LIB_DIRECTORY),
6117049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_SERVERS_DIRECTORY),
6217049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_BIN_DIRECTORY),
6317049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_ETC_DIRECTORY),
6417049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_DOCUMENTATION_DIRECTORY),
6517049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_SETTINGS_DIRECTORY),
6617049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_DEVELOP_DIRECTORY),
6717049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_LOG_DIRECTORY),
6817049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_SPOOL_DIRECTORY),
6917049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_TEMP_DIRECTORY),
7017049c45SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_VAR_DIRECTORY),
71ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_TRANSLATORS_DIRECTORY),
72ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_MEDIA_NODES_DIRECTORY),
73ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_SOUNDS_DIRECTORY),
74ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_COMMON_DATA_DIRECTORY),
75f011dde5SJonas Sundström 	KEYVALUE_PAIR(B_COMMON_CACHE_DIRECTORY),
763dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_PACKAGES_DIRECTORY),
773dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_HEADERS_DIRECTORY),
783dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_DIRECTORY),
793dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_ADDONS_DIRECTORY),
803dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_TRANSLATORS_DIRECTORY),
813dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_MEDIA_NODES_DIRECTORY),
823dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_BIN_DIRECTORY),
833dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_DATA_DIRECTORY),
843dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_FONTS_DIRECTORY),
853dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_SOUNDS_DIRECTORY),
863dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_DOCUMENTATION_DIRECTORY),
873dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_LIB_DIRECTORY),
883dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_HEADERS_DIRECTORY),
89*3f85cfc1SIngo Weinhold 	KEYVALUE_PAIR(B_COMMON_NONPACKAGED_DEVELOP_DIRECTORY),
90ded43249SAxel Dörfler 
91ded43249SAxel Dörfler 	// User directories
9217049c45SAxel Dörfler 	KEYVALUE_PAIR(B_USER_DIRECTORY),
9317049c45SAxel Dörfler 	KEYVALUE_PAIR(B_USER_CONFIG_DIRECTORY),
9417049c45SAxel Dörfler 	KEYVALUE_PAIR(B_USER_ADDONS_DIRECTORY),
9517049c45SAxel Dörfler 	KEYVALUE_PAIR(B_USER_BOOT_DIRECTORY),
9617049c45SAxel Dörfler 	KEYVALUE_PAIR(B_USER_FONTS_DIRECTORY),
9717049c45SAxel Dörfler 	KEYVALUE_PAIR(B_USER_LIB_DIRECTORY),
9817049c45SAxel Dörfler 	KEYVALUE_PAIR(B_USER_SETTINGS_DIRECTORY),
9917049c45SAxel Dörfler 	KEYVALUE_PAIR(B_USER_DESKBAR_DIRECTORY),
100ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_USER_PRINTERS_DIRECTORY),
101ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_USER_TRANSLATORS_DIRECTORY),
102ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_USER_MEDIA_NODES_DIRECTORY),
103ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_USER_SOUNDS_DIRECTORY),
104ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_USER_DATA_DIRECTORY),
105ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_USER_CACHE_DIRECTORY),
1063dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_PACKAGES_DIRECTORY),
107*3f85cfc1SIngo Weinhold 	KEYVALUE_PAIR(B_USER_DEVELOP_DIRECTORY),
108*3f85cfc1SIngo Weinhold 	KEYVALUE_PAIR(B_USER_DOCUMENTATION_DIRECTORY),
1093dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_HEADERS_DIRECTORY),
1103dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_NONPACKAGED_DIRECTORY),
1113dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_NONPACKAGED_ADDONS_DIRECTORY),
1123dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_NONPACKAGED_TRANSLATORS_DIRECTORY),
1133dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_NONPACKAGED_MEDIA_NODES_DIRECTORY),
1143dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_NONPACKAGED_BIN_DIRECTORY),
1153dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_NONPACKAGED_DATA_DIRECTORY),
1163dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_NONPACKAGED_FONTS_DIRECTORY),
1173dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_NONPACKAGED_SOUNDS_DIRECTORY),
1183dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_NONPACKAGED_DOCUMENTATION_DIRECTORY),
1193dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_NONPACKAGED_LIB_DIRECTORY),
1203dfd9cb9SOliver Tappe 	KEYVALUE_PAIR(B_USER_NONPACKAGED_HEADERS_DIRECTORY),
121*3f85cfc1SIngo Weinhold 	KEYVALUE_PAIR(B_USER_NONPACKAGED_DEVELOP_DIRECTORY),
122ded43249SAxel Dörfler 
123ded43249SAxel Dörfler 	// Legacy system directories
124ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_DIRECTORY),
125ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_SYSTEM_DIRECTORY),
126ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_ADDONS_DIRECTORY),
127ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_BOOT_DIRECTORY),
128ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_FONTS_DIRECTORY),
129ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_LIB_DIRECTORY),
130ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_SERVERS_DIRECTORY),
131ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_APPS_DIRECTORY),
132ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_BIN_DIRECTORY),
133ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_ETC_DIRECTORY),
134ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_DOCUMENTATION_DIRECTORY),
135ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_PREFERENCES_DIRECTORY),
136ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_TRANSLATORS_DIRECTORY),
13717049c45SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_MEDIA_NODES_DIRECTORY),
13817049c45SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_SOUNDS_DIRECTORY),
139ded43249SAxel Dörfler 	KEYVALUE_PAIR(B_BEOS_DATA_DIRECTORY),
140ded43249SAxel Dörfler 
14117049c45SAxel Dörfler 	{NULL, B_USER_DESKBAR_DIRECTORY}
14217049c45SAxel Dörfler };
14317049c45SAxel Dörfler 
144494301a5SAxel Dörfler 
145494301a5SAxel Dörfler static void
146494301a5SAxel Dörfler listDirectoryWhich(void)
14717049c45SAxel Dörfler {
14817049c45SAxel Dörfler 	int i;
14917049c45SAxel Dörfler 
15017049c45SAxel Dörfler 	for (i = 0; directoryTypes[i].key; i++) {
15117049c45SAxel Dörfler 		printf("%s\n", directoryTypes[i].key);
15217049c45SAxel Dörfler 	}
15317049c45SAxel Dörfler }
15417049c45SAxel Dörfler 
155494301a5SAxel Dörfler 
156494301a5SAxel Dörfler static bool
157ded43249SAxel Dörfler retrieveDirValue(directoryType *list, const char *key,
158ded43249SAxel Dörfler 	directory_which *valueOut)
15917049c45SAxel Dörfler {
16017049c45SAxel Dörfler 	unsigned i = 0;
16117049c45SAxel Dörfler 
162494301a5SAxel Dörfler 	while (list[i].key != NULL) {
163494301a5SAxel Dörfler 		if (strcmp(list[i].key, key) == 0) {
164ded43249SAxel Dörfler 			*valueOut = list[i].value;
16517049c45SAxel Dörfler 			return true;
16617049c45SAxel Dörfler 		}
16717049c45SAxel Dörfler 
16817049c45SAxel Dörfler 		i++;
16917049c45SAxel Dörfler 	}
17017049c45SAxel Dörfler 
17117049c45SAxel Dörfler 	return false;
17217049c45SAxel Dörfler }
17317049c45SAxel Dörfler 
174494301a5SAxel Dörfler 
175494301a5SAxel Dörfler static void
176494301a5SAxel Dörfler usageMsg()
17717049c45SAxel Dörfler {
17817049c45SAxel Dörfler 	printf("usage:  /bin/finddir -l | [ -v volume ] directory_which\n");
17917049c45SAxel Dörfler 	printf("\t-l\t    list valid which constants to use\n");
18017049c45SAxel Dörfler 	printf("\t-v <file>   use the specified volume for directory\n");
18117049c45SAxel Dörfler 	printf("\t\t    constants that are volume-specific.\n");
18217049c45SAxel Dörfler 	printf("\t\t    <file> can be any file on that volume.\n");
18317049c45SAxel Dörfler 	printf("\t\t    defaults to the boot volume.\n");
18417049c45SAxel Dörfler 	printf(" For a description of recognized directory_which constants,\n");
18517049c45SAxel Dörfler 	printf(" see the find_directory(...) documentation in the Be Book.\n");
18617049c45SAxel Dörfler }
18717049c45SAxel Dörfler 
18817049c45SAxel Dörfler 
189494301a5SAxel Dörfler int
190494301a5SAxel Dörfler main(int argc, char *argv[])
19117049c45SAxel Dörfler {
19217049c45SAxel Dörfler 	int directoryArgNr;
19317049c45SAxel Dörfler 	int status;
19417049c45SAxel Dörfler 	dev_t volume;
19517049c45SAxel Dörfler 	directory_which dirType;
19617049c45SAxel Dörfler 	int returnCode;
19717049c45SAxel Dörfler 
19817049c45SAxel Dörfler 	status = NO_ERRORS;
19917049c45SAxel Dörfler 	directoryArgNr = 1;
20017049c45SAxel Dörfler 	returnCode = 0;
20117049c45SAxel Dörfler 
20217049c45SAxel Dörfler 	dirType = B_BEOS_DIRECTORY; /* so that it compiles */
20317049c45SAxel Dörfler 
20417049c45SAxel Dörfler 	/* By default use boot volume*/
20517049c45SAxel Dörfler 	volume = dev_for_path("/boot");
20617049c45SAxel Dörfler 
20717049c45SAxel Dörfler 	if (argc <= 1) {
20817049c45SAxel Dörfler 		status = ARGUMENT_MISSING;
20917049c45SAxel Dörfler 	} else {
21017049c45SAxel Dörfler 		if (strcmp(argv[1], "-l") == 0 ) {
21117049c45SAxel Dörfler 			listDirectoryWhich();
21217049c45SAxel Dörfler 			return 0;
21317049c45SAxel Dörfler 		}
21417049c45SAxel Dörfler 		if (strcmp(argv[1], "-v") == 0 ) {
21517049c45SAxel Dörfler 			if (argc >= 3) {
21617049c45SAxel Dörfler 				dev_t temp_volume;
21717049c45SAxel Dörfler 				/* get volume from second arg */
21817049c45SAxel Dörfler 				temp_volume = dev_for_path(argv[2]);
21917049c45SAxel Dörfler 
22017049c45SAxel Dörfler 				/* Keep default value in case of error */
22117049c45SAxel Dörfler 				if (temp_volume >= 0)
22217049c45SAxel Dörfler 					volume = temp_volume;
22317049c45SAxel Dörfler 
22417049c45SAxel Dörfler 				/* two arguments were used for volume */
22517049c45SAxel Dörfler 				directoryArgNr+=2;
22617049c45SAxel Dörfler 			} else {
22717049c45SAxel Dörfler 				/* set status to argument missing */
22817049c45SAxel Dörfler 				status = ARGUMENT_MISSING;
22917049c45SAxel Dörfler 			}
23017049c45SAxel Dörfler 		}
23117049c45SAxel Dörfler 	}
23217049c45SAxel Dörfler 
23317049c45SAxel Dörfler 	if (status == NO_ERRORS && argc > directoryArgNr) {
23417049c45SAxel Dörfler 		/* get directory constant from next argument */
23517049c45SAxel Dörfler 
236ded43249SAxel Dörfler 		if (!retrieveDirValue(directoryTypes, argv[directoryArgNr], &dirType))
23717049c45SAxel Dörfler 			status = WRONG_DIR_TYPE;
23817049c45SAxel Dörfler 	} else {
23917049c45SAxel Dörfler 		status = ARGUMENT_MISSING;
24017049c45SAxel Dörfler 	}
24117049c45SAxel Dörfler 
24217049c45SAxel Dörfler 	/* Do the actual directoy finding */
24317049c45SAxel Dörfler 
24417049c45SAxel Dörfler 	if (status == NO_ERRORS) {
24517049c45SAxel Dörfler 		/* Question: would B_PATH_NAME_LENGTH alone have been enough? */
24617049c45SAxel Dörfler 		char buffer[B_PATH_NAME_LENGTH+B_FILE_NAME_LENGTH];
247ded43249SAxel Dörfler 		status_t result = find_directory (dirType, volume, false, buffer,
248ded43249SAxel Dörfler 			sizeof(buffer));
24917049c45SAxel Dörfler 		if (result == B_OK) {
25017049c45SAxel Dörfler 			printf("%s\n", buffer);
25117049c45SAxel Dörfler 		} else {
25217049c45SAxel Dörfler 			/* else what? */
25317049c45SAxel Dörfler 			/* this can not happen! */
254d38e0056SPhilippe Houdoin 			fprintf(stderr, "Serious internal error; contact support\n");
25517049c45SAxel Dörfler 		}
25617049c45SAxel Dörfler 	}
25717049c45SAxel Dörfler 
25817049c45SAxel Dörfler 	/* Error messages and return code setting */
25917049c45SAxel Dörfler 
26017049c45SAxel Dörfler 	if (status == WRONG_DIR_TYPE) {
261d38e0056SPhilippe Houdoin 		fprintf(stderr, "%s: unrecognized directory_which constant \'%s\'\n", argv[0],
262ded43249SAxel Dörfler 			argv[directoryArgNr]);
26317049c45SAxel Dörfler 		returnCode = 252;
26417049c45SAxel Dörfler 	}
26517049c45SAxel Dörfler 
26617049c45SAxel Dörfler 	if (status == ARGUMENT_MISSING) {
26717049c45SAxel Dörfler 		usageMsg();
26817049c45SAxel Dörfler 		returnCode = 255;
26917049c45SAxel Dörfler 	}
27017049c45SAxel Dörfler 
27117049c45SAxel Dörfler 	return returnCode;
27217049c45SAxel Dörfler }
27317049c45SAxel Dörfler 
274