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