xref: /haiku/src/bin/finddir.c (revision 494301a5aa9fb6356e6f229c18905b3a10905aa8)
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