xref: /haiku/src/kits/storage/FindDirectory.cpp (revision db10640de90f7f9519ba2da9577b7c1af3c64f6b)
1 //----------------------------------------------------------------------
2 //  This software is part of the OpenBeOS distribution and is covered
3 //  by the OpenBeOS license.
4 //---------------------------------------------------------------------
5 /*!
6 	\file FindDirectory.cpp
7 	find_directory() implementations.
8 */
9 
10 #include <FindDirectory.h>
11 
12 #include <errno.h>
13 #include <string.h>
14 
15 #include <Directory.h>
16 #include <Entry.h>
17 #include <fs_info.h>
18 #include <Path.h>
19 #include <Volume.h>
20 
21 #ifdef USE_OPENBEOS_NAMESPACE
22 namespace OpenBeOS {
23 #endif
24 
25 enum {
26 	NOT_IMPLEMENTED	= B_ERROR,
27 };
28 
29 // find_directory
30 /*!	\brief Internal find_directory() helper function, that does the real work.
31 	\param which the directory_which constant specifying the directory
32 	\param path a BPath object to be initialized to the directory's path
33 	\param createIt \c true, if the directory shall be created, if it doesn't
34 		   already exist, \c false otherwise.
35 	\param device the volume on which the directory is located
36 	\return \c B_OK if everything went fine, an error code otherwise.
37 */
38 static
39 status_t
40 find_directory(directory_which which, BPath &path, bool createIt, dev_t device)
41 {
42 	status_t error = B_BAD_VALUE;
43 	switch (which) {
44 		// volume relative dirs
45 		case B_DESKTOP_DIRECTORY:
46 		{
47 			if (device < 0)
48 				device = dev_for_path("/boot");
49 			fs_info info;
50 			if (fs_stat_dev(device, &info) == 0) {
51 				if (!strcmp(info.fsh_name, "bfs")) {
52 					entry_ref ref(device, info.root, "home");
53 					BPath homePath(&ref);
54 					error = homePath.InitCheck();
55 					if (error == B_OK)
56 						path.SetTo(homePath.Path(), "Desktop");
57 				} else
58 					error = B_ENTRY_NOT_FOUND;
59 			} else
60 				error = errno;
61 			break;
62 		}
63 		case B_TRASH_DIRECTORY:
64 		{
65 			if (device < 0)
66 				device = dev_for_path("/boot");
67 			fs_info info;
68 			if (fs_stat_dev(device, &info) == 0) {
69 				if (!strcmp(info.fsh_name, "bfs")) {
70 					entry_ref ref(device, info.root, "home");
71 					BPath homePath(&ref);
72 					error = homePath.InitCheck();
73 					if (error == B_OK)
74 						path.SetTo(homePath.Path(), "Desktop/Trash");
75 				} else if (!strcmp(info.fsh_name, "dos")) {
76 					entry_ref ref(device, info.root, "RECYCLED");
77 					BPath recycledPath(&ref);
78 					error = recycledPath.InitCheck();
79 					if (error == B_OK)
80 						path.SetTo(recycledPath.Path(), "_BEOS_");
81 				} else
82 					error = B_ENTRY_NOT_FOUND;
83 			} else
84 				error = errno;
85 			break;
86 		}
87 		// BeOS directories.  These are mostly accessed read-only.
88 		case B_BEOS_DIRECTORY:
89 			error = path.SetTo("/boot/beos");
90 			break;
91 		case B_BEOS_SYSTEM_DIRECTORY:
92 			error = path.SetTo("/boot/beos/system");
93 			break;
94 		case B_BEOS_ADDONS_DIRECTORY:
95 			error = path.SetTo("/boot/beos/system/add-ons");
96 			break;
97 		case B_BEOS_BOOT_DIRECTORY:
98 			error = path.SetTo("/boot/beos/system/boot");
99 			break;
100 		case B_BEOS_FONTS_DIRECTORY:
101 			error = path.SetTo("/boot/beos/etc/fonts");
102 			break;
103 		case B_BEOS_LIB_DIRECTORY:
104 			error = path.SetTo("/boot/beos/system/lib");
105 			break;
106  		case B_BEOS_SERVERS_DIRECTORY:
107 			error = path.SetTo("/boot/beos/system/servers");
108 			break;
109 		case B_BEOS_APPS_DIRECTORY:
110 			error = path.SetTo("/boot/beos/apps");
111 			break;
112 		case B_BEOS_BIN_DIRECTORY:
113 			error = path.SetTo("/boot/beos/bin");
114 			break;
115 		case B_BEOS_ETC_DIRECTORY:
116 			error = path.SetTo("/boot/beos/etc");
117 			break;
118 		case B_BEOS_DOCUMENTATION_DIRECTORY:
119 			error = path.SetTo("/boot/beos/documentation");
120 			break;
121 		case B_BEOS_PREFERENCES_DIRECTORY:
122 			error = path.SetTo("/boot/beos/preferences");
123 			break;
124 		case B_BEOS_TRANSLATORS_DIRECTORY:
125 			error = path.SetTo("/boot/beos/system/add-ons/Translators");
126 			break;
127 		case B_BEOS_MEDIA_NODES_DIRECTORY:
128 			error = path.SetTo("/boot/beos/system/add-ons/media");
129 			break;
130 		case B_BEOS_SOUNDS_DIRECTORY:
131 			error = path.SetTo("/boot/beos/etc/sounds");
132 			break;
133 		// Common directories, shared among all users.
134 		case B_COMMON_DIRECTORY:
135 			error = path.SetTo("/boot/home");
136 			break;
137 		case B_COMMON_SYSTEM_DIRECTORY:
138 			error = path.SetTo("/boot/home/config");
139 			break;
140 		case B_COMMON_ADDONS_DIRECTORY:
141 			error = path.SetTo("/boot/home/config/add-ons");
142 			break;
143 		case B_COMMON_BOOT_DIRECTORY:
144 			error = path.SetTo("/boot/home/config/boot");
145 			break;
146 		case B_COMMON_FONTS_DIRECTORY:
147 			error = path.SetTo("/boot/home/config/fonts");
148 			break;
149 		case B_COMMON_LIB_DIRECTORY:
150 			error = path.SetTo("/boot/home/config/lib");
151 			break;
152 		case B_COMMON_SERVERS_DIRECTORY:
153 			error = path.SetTo("/boot/home/config/servers");
154 			break;
155 		case B_COMMON_BIN_DIRECTORY:
156 			error = path.SetTo("/boot/home/config/bin");
157 			break;
158 		case B_COMMON_ETC_DIRECTORY:
159 			error = path.SetTo("/boot/home/config/etc");
160 			break;
161 		case B_COMMON_DOCUMENTATION_DIRECTORY:
162 			error = path.SetTo("/boot/home/config/documentation");
163 			break;
164 		case B_COMMON_SETTINGS_DIRECTORY:
165 			error = path.SetTo("/boot/home/config/settings");
166 			break;
167 		case B_COMMON_DEVELOP_DIRECTORY:
168 			error = path.SetTo("/boot/develop");
169 			break;
170 		case B_COMMON_LOG_DIRECTORY:
171 			error = path.SetTo("/boot/var/log");
172 			break;
173 		case B_COMMON_SPOOL_DIRECTORY:
174 			error = path.SetTo("/boot/var/spool");
175 			break;
176 		case B_COMMON_TEMP_DIRECTORY:
177 			error = path.SetTo("/boot/var/tmp");
178 			break;
179 		case B_COMMON_VAR_DIRECTORY:
180 			error = path.SetTo("/boot/var");
181 			break;
182 		case B_COMMON_TRANSLATORS_DIRECTORY:
183 			error = path.SetTo("/boot/home/config/add-ons/Translators");
184 			break;
185 		case B_COMMON_MEDIA_NODES_DIRECTORY:
186 			error = path.SetTo("/boot/home/config/add-ons/media");
187 			break;
188 		case B_COMMON_SOUNDS_DIRECTORY:
189 			error = path.SetTo("/boot/home/config/sounds");
190 			break;
191 		// User directories.  These are interpreted in the context
192 		// of the user making the find_directory call.
193 		case B_USER_DIRECTORY:
194 			error = path.SetTo("/boot/home");
195 			break;
196 		case B_USER_CONFIG_DIRECTORY:
197 			error = path.SetTo("/boot/home/config");
198 			break;
199 		case B_USER_ADDONS_DIRECTORY:
200 			error = path.SetTo("/boot/home/config/add-ons");
201 			break;
202 		case B_USER_BOOT_DIRECTORY:
203 			error = path.SetTo("/boot/home/config/boot");
204 			break;
205 		case B_USER_FONTS_DIRECTORY:
206 			error = path.SetTo("/boot/home/config/fonts");
207 			break;
208 		case B_USER_LIB_DIRECTORY:
209 			error = path.SetTo("/boot/home/config/lib");
210 			break;
211 		case B_USER_SETTINGS_DIRECTORY:
212 			error = path.SetTo("/boot/home/config/settings");
213 			break;
214 		case B_USER_DESKBAR_DIRECTORY:
215 			error = path.SetTo("/boot/home/config/be");
216 			break;
217 		case B_USER_PRINTERS_DIRECTORY:
218 			error = path.SetTo("/boot/home/config/settings/printers");
219 			break;
220 		case B_USER_TRANSLATORS_DIRECTORY:
221 			error = path.SetTo("/boot/home/config/add-ons/Translators");
222 			break;
223 		case B_USER_MEDIA_NODES_DIRECTORY:
224 			error = path.SetTo("/boot/home/config/add-ons/media");
225 			break;
226 		case B_USER_SOUNDS_DIRECTORY:
227 			error = path.SetTo("/boot/home/config/sounds");
228 			break;
229 		// Global directories.
230 		case B_APPS_DIRECTORY:
231 			error = path.SetTo("/boot/apps");
232 			break;
233 		case B_PREFERENCES_DIRECTORY:
234 			error = path.SetTo("/boot/preferences");
235 			break;
236 		case B_UTILITIES_DIRECTORY:
237 			error = path.SetTo("/boot/utilities");
238 			break;
239 	}
240 	// create the directory, if desired
241 	if (error == B_OK && createIt)
242 		create_directory(path.Path(), S_IRWXU | S_IRWXG | S_IRWXO);
243 	return error;
244 }
245 
246 
247 // find_directory
248 //!	Returns a path of a directory specified by a directory_which constant.
249 /*!	If the supplied volume ID is
250 	\param which the directory_which constant specifying the directory
251 	\param volume the volume on which the directory is located
252 	\param createIt \c true, if the directory shall be created, if it doesn't
253 		   already exist, \c false otherwise.
254 	\param pathString a pointer to a buffer into which the directory path
255 		   shall be written.
256 	\param length the size of the buffer
257 	\return
258 	- \c B_OK: Everything went fine.
259 	- \c B_BAD_VALUE: \c NULL \a pathString.
260 	- \c E2BIG: Buffer is too small for path.
261 	- another error code
262 */
263 status_t
264 find_directory(directory_which which, dev_t volume, bool createIt,
265 			   char *pathString, int32 length)
266 {
267 	status_t error = (pathString ? B_OK : B_BAD_VALUE);
268 	if (error == B_OK) {
269 		BPath path;
270 		error = find_directory(which, path, createIt, volume);
271 		if (error == B_OK && (int32)strlen(path.Path()) >= length)
272 			error = E2BIG;
273 		if (error == B_OK)
274 			strcpy(pathString, path.Path());
275 	}
276 	return error;
277 }
278 
279 // find_directory
280 //!	Returns a path of a directory specified by a directory_which constant.
281 /*!	\param which the directory_which constant specifying the directory
282 	\param path a BPath object to be initialized to the directory's path
283 	\param createIt \c true, if the directory shall be created, if it doesn't
284 		   already exist, \c false otherwise.
285 	\param volume the volume on which the directory is located
286 	\return
287 	- \c B_OK: Everything went fine.
288 	- \c B_BAD_VALUE: \c NULL \a path.
289 	- another error code
290 */
291 status_t
292 find_directory(directory_which which, BPath *path, bool createIt,
293 			   BVolume *volume)
294 {
295 	status_t error = (path ? B_OK : B_BAD_VALUE);
296 	if (error == B_OK) {
297 		dev_t device = (dev_t)-1;
298 		if (volume && volume->InitCheck() == B_OK)
299 			device = volume->Device();
300 		error = find_directory(which, *path, createIt, device);
301 	}
302 	return error;
303 }
304 
305 
306 #ifdef USE_OPENBEOS_NAMESPACE
307 };		// namespace OpenBeOS
308 #endif
309 
310 
311 
312 
313