xref: /haiku/src/kits/storage/Statable.cpp (revision 481f986b59e7782458dcc5fe98ad59a57480e5db)
1 /*
2  * Copyright 2002-2009, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Tyler Dauwalder
7  *		Ingo Weinhold, bonefish@users.sf.net
8  */
9 
10 /*!
11 	\file Statable.cpp
12 	BStatable implementation.
13 */
14 
15 #include <Statable.h>
16 
17 #include <sys/stat.h>
18 
19 #include <compat/sys/stat.h>
20 
21 #include <Node.h>
22 #include <NodeMonitor.h>
23 #include <Volume.h>
24 
25 
26 class BStatable::Private {
27 public:
28 	Private(const BStatable* object)
29 		:
30 		fObject(object)
31 	{
32 	}
33 
34 	status_t GetStatBeOS(struct stat_beos* st)
35 	{
36 		return fObject->_GetStat(st);
37 	}
38 
39 private:
40 	const BStatable*	fObject;
41 };
42 
43 
44 #if __GNUC__ > 3
45 BStatable::~BStatable()
46 {
47 }
48 #endif
49 
50 
51 /*!	\fn status_t GetStat(struct stat *st) const
52 	\brief Returns the stat stucture for the node.
53 	\param st the stat structure to be filled in.
54 	\return
55 	- \c B_OK: Worked fine
56 	- \c B_NO_MEMORY: Could not allocate the memory for the call.
57 	- \c B_BAD_VALUE: The current node does not exist.
58 	- \c B_NOT_ALLOWED: Read only node or volume.
59 */
60 
61 
62 /*!	\brief Returns if the current node is a file.
63 	\return \c true, if the BNode is properly initialized and is a file,
64 			\c false otherwise.
65 */
66 bool
67 BStatable::IsFile() const
68 {
69 	struct stat statData;
70 	if (GetStat(&statData) == B_OK)
71 		return S_ISREG(statData.st_mode);
72 	else
73 		return false;
74 }
75 
76 /*!	\brief Returns if the current node is a directory.
77 	\return \c true, if the BNode is properly initialized and is a file,
78 			\c false otherwise.
79 */
80 bool
81 BStatable::IsDirectory() const
82 {
83 	struct stat statData;
84 	if (GetStat(&statData) == B_OK)
85 		return S_ISDIR(statData.st_mode);
86 	else
87 		return false;
88 }
89 
90 /*!	\brief Returns if the current node is a symbolic link.
91 	\return \c true, if the BNode is properly initialized and is a symlink,
92 			\c false otherwise.
93 */
94 bool
95 BStatable::IsSymLink() const
96 {
97 	struct stat statData;
98 	if (GetStat(&statData) == B_OK)
99 		return S_ISLNK(statData.st_mode);
100 	else
101 		return false;
102 }
103 
104 /*!	\brief Returns a node_ref for the current node.
105 	\param ref the node_ref structure to be filled in
106 	\see GetStat() for return codes
107 */
108 status_t
109 BStatable::GetNodeRef(node_ref *ref) const
110 {
111 	status_t error = (ref ? B_OK : B_BAD_VALUE);
112 	struct stat statData;
113 	if (error == B_OK)
114 		error = GetStat(&statData);
115 	if (error == B_OK) {
116 		ref->device  = statData.st_dev;
117 		ref->node = statData.st_ino;
118 	}
119 	return error;
120 }
121 
122 /*!	\brief Returns the owner of the node.
123 	\param owner a pointer to a uid_t variable to be set to the result
124 	\see GetStat() for return codes
125 */
126 status_t
127 BStatable::GetOwner(uid_t *owner) const
128 {
129 	status_t error = (owner ? B_OK : B_BAD_VALUE);
130 	struct stat statData;
131 	if (error == B_OK)
132 		error = GetStat(&statData);
133 	if (error == B_OK)
134 		*owner = statData.st_uid;
135 	return error;
136 }
137 
138 /*!	\brief Sets the owner of the node.
139 	\param owner the new owner
140 	\see GetStat() for return codes
141 */
142 status_t
143 BStatable::SetOwner(uid_t owner)
144 {
145 	struct stat statData;
146 	statData.st_uid = owner;
147 	return set_stat(statData, B_STAT_UID);
148 }
149 
150 /*!	\brief Returns the group owner of the node.
151 	\param group a pointer to a gid_t variable to be set to the result
152 	\see GetStat() for return codes
153 */
154 status_t
155 BStatable::GetGroup(gid_t *group) const
156 {
157 	status_t error = (group ? B_OK : B_BAD_VALUE);
158 	struct stat statData;
159 	if (error == B_OK)
160 		error = GetStat(&statData);
161 	if (error == B_OK)
162 		*group = statData.st_gid;
163 	return error;
164 }
165 
166 /*!	\brief Sets the group owner of the node.
167 	\param group the new group
168 	\see GetStat() for return codes
169 */
170 status_t
171 BStatable::SetGroup(gid_t group)
172 {
173 	struct stat statData;
174 	statData.st_gid = group;
175 	return set_stat(statData, B_STAT_GID);
176 }
177 
178 /*!	\brief Returns the permissions of the node.
179 	\param perms a pointer to a mode_t variable to be set to the result
180 	\see GetStat() for return codes
181 */
182 status_t
183 BStatable::GetPermissions(mode_t *perms) const
184 {
185 	status_t error = (perms ? B_OK : B_BAD_VALUE);
186 	struct stat statData;
187 	if (error == B_OK)
188 		error = GetStat(&statData);
189 	if (error == B_OK)
190 		*perms = (statData.st_mode & S_IUMSK);
191 	return error;
192 }
193 
194 /*!	\brief Sets the permissions of the node.
195 	\param perms the new permissions
196 	\see GetStat() for return codes
197 */
198 status_t
199 BStatable::SetPermissions(mode_t perms)
200 {
201 	struct stat statData;
202 	// the FS should do the correct masking -- only the S_IUMSK part is
203 	// modifiable
204 	statData.st_mode = perms;
205 	return set_stat(statData, B_STAT_MODE);
206 }
207 
208 /*!	\brief Get the size of the node's data (not counting attributes).
209 	\param size a pointer to a variable to be set to the result
210 	\see GetStat() for return codes
211 */
212 status_t
213 BStatable::GetSize(off_t *size) const
214 {
215 	status_t error = (size ? B_OK : B_BAD_VALUE);
216 	struct stat statData;
217 	if (error == B_OK)
218 		error = GetStat(&statData);
219 	if (error == B_OK)
220 		*size = statData.st_size;
221 	return error;
222 }
223 
224 /*!	\brief Returns the last time the node was modified.
225 	\param mtime a pointer to a variable to be set to the result
226 	\see GetStat() for return codes
227 */
228 status_t
229 BStatable::GetModificationTime(time_t *mtime) const
230 {
231 	status_t error = (mtime ? B_OK : B_BAD_VALUE);
232 	struct stat statData;
233 	if (error == B_OK)
234 		error = GetStat(&statData);
235 	if (error == B_OK)
236 		*mtime = statData.st_mtime;
237 	return error;
238 }
239 
240 /*!	\brief Sets the last time the node was modified.
241 	\param mtime the new modification time
242 	\see GetStat() for return codes
243 */
244 status_t
245 BStatable::SetModificationTime(time_t mtime)
246 {
247 	struct stat statData;
248 	statData.st_mtime = mtime;
249 	return set_stat(statData, B_STAT_MODIFICATION_TIME);
250 }
251 
252 /*!	\brief Returns the time the node was created.
253 	\param ctime a pointer to a variable to be set to the result
254 	\see GetStat() for return codes
255 */
256 status_t
257 BStatable::GetCreationTime(time_t *ctime) const
258 {
259 	status_t error = (ctime ? B_OK : B_BAD_VALUE);
260 	struct stat statData;
261 	if (error == B_OK)
262 		error = GetStat(&statData);
263 	if (error == B_OK)
264 		*ctime = statData.st_crtime;
265 	return error;
266 }
267 
268 /*!	\brief Sets the time the node was created.
269 	\param ctime the new creation time
270 	\see GetStat() for return codes
271 */
272 status_t
273 BStatable::SetCreationTime(time_t ctime)
274 {
275 	struct stat statData;
276 	statData.st_crtime = ctime;
277 	return set_stat(statData, B_STAT_CREATION_TIME);
278 }
279 
280 /*!	\brief Returns the time the node was accessed.
281 	Not used.
282 	\see GetModificationTime()
283 	\see GetStat() for return codes
284 */
285 status_t
286 BStatable::GetAccessTime(time_t *atime) const
287 {
288 	status_t error = (atime ? B_OK : B_BAD_VALUE);
289 	struct stat statData;
290 	if (error == B_OK)
291 		error = GetStat(&statData);
292 	if (error == B_OK)
293 		*atime = statData.st_atime;
294 	return error;
295 }
296 
297 /*!	\brief Sets the time the node was accessed.
298 	Not used.
299 	\see GetModificationTime()
300 	\see GetStat() for return codes
301 */
302 status_t
303 BStatable::SetAccessTime(time_t atime)
304 {
305 	struct stat statData;
306 	statData.st_atime = atime;
307 	return set_stat(statData, B_STAT_ACCESS_TIME);
308 }
309 
310 /*!	\brief Returns the volume the node lives on.
311 	\param vol a pointer to a variable to be set to the result
312 	\see BVolume
313 	\see GetStat() for return codes
314 */
315 status_t
316 BStatable::GetVolume(BVolume *vol) const
317 {
318 	status_t error = (vol ? B_OK : B_BAD_VALUE);
319 	struct stat statData;
320 	if (error == B_OK)
321 		error = GetStat(&statData);
322 	if (error == B_OK)
323 		error = vol->SetTo(statData.st_dev);
324 	return error;
325 }
326 
327 
328 // _OhSoStatable1() -> GetStat()
329 extern "C" status_t
330 #if __GNUC__ == 2
331 _OhSoStatable1__9BStatable(const BStatable *self, struct stat *st)
332 #else
333 _ZN9BStatable14_OhSoStatable1Ev(const BStatable *self, struct stat *st)
334 #endif
335 {
336 	// No Perform() method -- we have to use the old GetStat() method instead.
337 	struct stat_beos oldStat;
338 	status_t error = BStatable::Private(self).GetStatBeOS(&oldStat);
339 	if (error != B_OK)
340 		return error;
341 
342 	convert_from_stat_beos(&oldStat, st);
343 	return B_OK;
344 }
345 
346 
347 void BStatable::_OhSoStatable2() {}
348 void BStatable::_OhSoStatable3() {}
349