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