xref: /haiku/src/bin/finddir.c (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
1 /*
2  * finddir.c -
3  * (c) 2002, Sebastian Nozzi <sebnozzi@gmx.net>
4  * 08/24/2004 - Francois Revol - added -l option.
5  */
6 
7 #include <FindDirectory.h>
8 #include <fs_info.h>
9 
10 #include <stdio.h>
11 #include <string.h>
12 
13 
14 #define NO_ERRORS			0
15 #define ARGUMENT_MISSING	1
16 #define WRONG_DIR_TYPE		2
17 
18 typedef struct {
19 	const char *key;
20 	directory_which value;
21 } directoryType;
22 
23 #define KEYVALUE_PAIR(key) {#key,key}
24 
25 directoryType directoryTypes[] = {
26 	KEYVALUE_PAIR(B_DESKTOP_DIRECTORY),
27 	KEYVALUE_PAIR(B_TRASH_DIRECTORY),
28 	KEYVALUE_PAIR(B_APPS_DIRECTORY),
29 	KEYVALUE_PAIR(B_PREFERENCES_DIRECTORY),
30 	KEYVALUE_PAIR(B_BEOS_DIRECTORY),
31 	KEYVALUE_PAIR(B_BEOS_SYSTEM_DIRECTORY),
32 	KEYVALUE_PAIR(B_BEOS_ADDONS_DIRECTORY),
33 	KEYVALUE_PAIR(B_BEOS_BOOT_DIRECTORY),
34 	KEYVALUE_PAIR(B_BEOS_FONTS_DIRECTORY),
35 	KEYVALUE_PAIR(B_BEOS_LIB_DIRECTORY),
36 	KEYVALUE_PAIR(B_BEOS_SERVERS_DIRECTORY),
37 	KEYVALUE_PAIR(B_BEOS_APPS_DIRECTORY),
38 	KEYVALUE_PAIR(B_BEOS_BIN_DIRECTORY),
39 	KEYVALUE_PAIR(B_BEOS_ETC_DIRECTORY),
40 	KEYVALUE_PAIR(B_BEOS_DOCUMENTATION_DIRECTORY),
41 	KEYVALUE_PAIR(B_BEOS_PREFERENCES_DIRECTORY),
42 	KEYVALUE_PAIR(B_COMMON_DIRECTORY),
43 	KEYVALUE_PAIR(B_COMMON_SYSTEM_DIRECTORY),
44 	KEYVALUE_PAIR(B_COMMON_ADDONS_DIRECTORY),
45 	KEYVALUE_PAIR(B_COMMON_BOOT_DIRECTORY),
46 	KEYVALUE_PAIR(B_COMMON_FONTS_DIRECTORY),
47 	KEYVALUE_PAIR(B_COMMON_LIB_DIRECTORY),
48 	KEYVALUE_PAIR(B_COMMON_SERVERS_DIRECTORY),
49 	KEYVALUE_PAIR(B_COMMON_BIN_DIRECTORY),
50 	KEYVALUE_PAIR(B_COMMON_ETC_DIRECTORY),
51 	KEYVALUE_PAIR(B_COMMON_DOCUMENTATION_DIRECTORY),
52 	KEYVALUE_PAIR(B_COMMON_SETTINGS_DIRECTORY),
53 	KEYVALUE_PAIR(B_COMMON_DEVELOP_DIRECTORY),
54 	KEYVALUE_PAIR(B_COMMON_LOG_DIRECTORY),
55 	KEYVALUE_PAIR(B_COMMON_SPOOL_DIRECTORY),
56 	KEYVALUE_PAIR(B_COMMON_TEMP_DIRECTORY),
57 	KEYVALUE_PAIR(B_COMMON_VAR_DIRECTORY),
58 	KEYVALUE_PAIR(B_USER_DIRECTORY),
59 	KEYVALUE_PAIR(B_USER_CONFIG_DIRECTORY),
60 	KEYVALUE_PAIR(B_USER_ADDONS_DIRECTORY),
61 	KEYVALUE_PAIR(B_USER_BOOT_DIRECTORY),
62 	KEYVALUE_PAIR(B_USER_FONTS_DIRECTORY),
63 	KEYVALUE_PAIR(B_USER_LIB_DIRECTORY),
64 	KEYVALUE_PAIR(B_USER_SETTINGS_DIRECTORY),
65 	KEYVALUE_PAIR(B_USER_DESKBAR_DIRECTORY),
66 	/* some more */
67 	KEYVALUE_PAIR(B_BEOS_MEDIA_NODES_DIRECTORY),
68 	KEYVALUE_PAIR(B_BEOS_SOUNDS_DIRECTORY),
69 	KEYVALUE_PAIR(B_BEOS_TRANSLATORS_DIRECTORY),
70 	KEYVALUE_PAIR(B_COMMON_MEDIA_NODES_DIRECTORY),
71 	KEYVALUE_PAIR(B_COMMON_SOUNDS_DIRECTORY),
72 	KEYVALUE_PAIR(B_COMMON_TRANSLATORS_DIRECTORY),
73 	KEYVALUE_PAIR(B_USER_MEDIA_NODES_DIRECTORY),
74 	KEYVALUE_PAIR(B_USER_PRINTERS_DIRECTORY),
75 	KEYVALUE_PAIR(B_USER_SOUNDS_DIRECTORY),
76 	KEYVALUE_PAIR(B_USER_TRANSLATORS_DIRECTORY),
77 	KEYVALUE_PAIR(B_UTILITIES_DIRECTORY),
78 #ifdef B_BEOS_VERSION_DANO
79 	/* Dano specific */
80 	KEYVALUE_PAIR(B_ROOT_DIRECTORY),
81 #endif /* B_BEOS_VERSION_DANO */
82 	{NULL,B_USER_DESKBAR_DIRECTORY}
83 };
84 
85 
86 static void
87 listDirectoryWhich(void)
88 {
89 	int i;
90 
91 	for (i = 0; directoryTypes[i].key; i++) {
92 		printf("%s\n", directoryTypes[i].key);
93 	}
94 }
95 
96 
97 static bool
98 retrieveDirValue(directoryType *list, const char *key, directory_which *value_out)
99 {
100 	unsigned i = 0;
101 
102 	while (list[i].key != NULL) {
103 		if (strcmp(list[i].key, key) == 0) {
104 			*value_out = list[i].value;
105 			return true;
106 		}
107 
108 		i++;
109 	}
110 
111 	return false;
112 }
113 
114 
115 static void
116 usageMsg()
117 {
118 	printf("usage:  /bin/finddir -l | [ -v volume ] directory_which\n");
119 	printf("\t-l\t    list valid which constants to use\n");
120 	printf("\t-v <file>   use the specified volume for directory\n");
121 	printf("\t\t    constants that are volume-specific.\n");
122 	printf("\t\t    <file> can be any file on that volume.\n");
123 	printf("\t\t    defaults to the boot volume.\n");
124 	printf(" For a description of recognized directory_which constants,\n");
125 	printf(" see the find_directory(...) documentation in the Be Book.\n");
126 }
127 
128 
129 int
130 main(int argc, char *argv[])
131 {
132 	int directoryArgNr;
133 	int status;
134 	dev_t volume;
135 	directory_which dirType;
136 	int returnCode;
137 
138 	status = NO_ERRORS;
139 	directoryArgNr = 1;
140 	returnCode = 0;
141 
142 	dirType = B_BEOS_DIRECTORY; /* so that it compiles */
143 
144 	/* By default use boot volume*/
145 	volume = dev_for_path("/boot");
146 
147 	if (argc <= 1) {
148 		status = ARGUMENT_MISSING;
149 	} else {
150 		if (strcmp(argv[1], "-l") == 0 ) {
151 			listDirectoryWhich();
152 			return 0;
153 		}
154 		if (strcmp(argv[1], "-v") == 0 ) {
155 			if (argc >= 3) {
156 				dev_t temp_volume;
157 				/* get volume from second arg */
158 				temp_volume = dev_for_path(argv[2]);
159 
160 				/* Keep default value in case of error */
161 				if (temp_volume >= 0)
162 					volume = temp_volume;
163 
164 				/* two arguments were used for volume */
165 				directoryArgNr+=2;
166 			} else {
167 				/* set status to argument missing */
168 				status = ARGUMENT_MISSING;
169 			}
170 		}
171 	}
172 
173 	if (status == NO_ERRORS && argc > directoryArgNr) {
174 		/* get directory constant from next argument */
175 
176 		if (retrieveDirValue(directoryTypes, argv[directoryArgNr], &dirType) == false) {
177 			status = WRONG_DIR_TYPE;
178 		}
179 
180 	} else {
181 		status = ARGUMENT_MISSING;
182 	}
183 
184 	/* Do the actual directoy finding */
185 
186 	if (status == NO_ERRORS) {
187 		/* Question: would B_PATH_NAME_LENGTH alone have been enough? */
188 		char buffer[B_PATH_NAME_LENGTH+B_FILE_NAME_LENGTH];
189 		status_t result;
190 
191 		result = find_directory (dirType, volume, /*create it*/ false, buffer, sizeof(buffer));
192 
193 		if (result == B_OK) {
194 			printf("%s\n", buffer);
195 		} else {
196 			/* else what? */
197 			/* this can not happen! */
198 			printf("Serious internal error; contact support\n");
199 		}
200 	}
201 
202 	/* Error messages and return code setting */
203 
204 	if (status == WRONG_DIR_TYPE) {
205 		printf("%s: unrecognized directory_which constant \'%s\'\n", argv[0], argv[directoryArgNr]);
206 		returnCode = 252;
207 	}
208 
209 	if (status == ARGUMENT_MISSING) {
210 		usageMsg();
211 		returnCode = 255;
212 	}
213 
214 	return returnCode;
215 }
216 
217