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