xref: /haiku/src/kits/storage/Statable.cpp (revision 14b32de1d5efe99b4c6d4ef8c25df47eb009cf0f)
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 #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* st)
31 	{
32 		return fObject->_GetStat(st);
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 statData;
52 	if (GetStat(&statData) == B_OK)
53 		return S_ISREG(statData.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 statData;
64 	if (GetStat(&statData) == B_OK)
65 		return S_ISDIR(statData.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 statData;
76 	if (GetStat(&statData) == B_OK)
77 		return S_ISLNK(statData.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 error = (ref ? B_OK : B_BAD_VALUE);
88 	struct stat statData;
89 	if (error == B_OK)
90 		error = GetStat(&statData);
91 	if (error == B_OK) {
92 		ref->device  = statData.st_dev;
93 		ref->node = statData.st_ino;
94 	}
95 	return error;
96 }
97 
98 
99 // Fills out the node's UID into owner.
100 status_t
101 BStatable::GetOwner(uid_t *owner) const
102 {
103 	status_t error = (owner ? B_OK : B_BAD_VALUE);
104 	struct stat statData;
105 	if (error == B_OK)
106 		error = GetStat(&statData);
107 	if (error == B_OK)
108 		*owner = statData.st_uid;
109 	return error;
110 }
111 
112 
113 // Sets the node's UID to owner.
114 status_t
115 BStatable::SetOwner(uid_t owner)
116 {
117 	struct stat statData;
118 	statData.st_uid = owner;
119 	return set_stat(statData, B_STAT_UID);
120 }
121 
122 
123 // Fills out the node's GID into group.
124 status_t
125 BStatable::GetGroup(gid_t *group) const
126 {
127 	status_t error = (group ? B_OK : B_BAD_VALUE);
128 	struct stat statData;
129 	if (error == B_OK)
130 		error = GetStat(&statData);
131 	if (error == B_OK)
132 		*group = statData.st_gid;
133 	return error;
134 }
135 
136 
137 // Sets the node's GID to group.
138 status_t
139 BStatable::SetGroup(gid_t group)
140 {
141 	struct stat statData;
142 	statData.st_gid = group;
143 	return set_stat(statData, B_STAT_GID);
144 }
145 
146 
147 // Fills out perms with the node's permissions.
148 status_t
149 BStatable::GetPermissions(mode_t *perms) const
150 {
151 	status_t error = (perms ? B_OK : B_BAD_VALUE);
152 	struct stat statData;
153 	if (error == B_OK)
154 		error = GetStat(&statData);
155 	if (error == B_OK)
156 		*perms = (statData.st_mode & S_IUMSK);
157 	return error;
158 }
159 
160 
161 // Sets the node's permissions to perms.
162 status_t
163 BStatable::SetPermissions(mode_t perms)
164 {
165 	struct stat statData;
166 	// the FS should do the correct masking -- only the S_IUMSK part is
167 	// modifiable
168 	statData.st_mode = perms;
169 	return set_stat(statData, B_STAT_MODE);
170 }
171 
172 
173 // Fills out the size of the node's data (not counting attributes) into size.
174 status_t
175 BStatable::GetSize(off_t *size) const
176 {
177 	status_t error = (size ? B_OK : B_BAD_VALUE);
178 	struct stat statData;
179 	if (error == B_OK)
180 		error = GetStat(&statData);
181 	if (error == B_OK)
182 		*size = statData.st_size;
183 	return error;
184 }
185 
186 
187 // Fills out mtime with the last modification time of the node.
188 status_t
189 BStatable::GetModificationTime(time_t *mtime) const
190 {
191 	status_t error = (mtime ? B_OK : B_BAD_VALUE);
192 	struct stat statData;
193 	if (error == B_OK)
194 		error = GetStat(&statData);
195 	if (error == B_OK)
196 		*mtime = statData.st_mtime;
197 	return error;
198 }
199 
200 
201 // Sets the node's last modification time to mtime.
202 status_t
203 BStatable::SetModificationTime(time_t mtime)
204 {
205 	struct stat statData;
206 	statData.st_mtime = mtime;
207 	return set_stat(statData, B_STAT_MODIFICATION_TIME);
208 }
209 
210 
211 // Fills out ctime with the creation time of the node
212 status_t
213 BStatable::GetCreationTime(time_t *ctime) const
214 {
215 	status_t error = (ctime ? B_OK : B_BAD_VALUE);
216 	struct stat statData;
217 	if (error == B_OK)
218 		error = GetStat(&statData);
219 	if (error == B_OK)
220 		*ctime = statData.st_crtime;
221 	return error;
222 }
223 
224 
225 // Sets the node's creation time to ctime.
226 status_t
227 BStatable::SetCreationTime(time_t ctime)
228 {
229 	struct stat statData;
230 	statData.st_crtime = ctime;
231 	return set_stat(statData, B_STAT_CREATION_TIME);
232 }
233 
234 
235 // Fills out atime with the access time of the node.
236 status_t
237 BStatable::GetAccessTime(time_t *atime) const
238 {
239 	status_t error = (atime ? B_OK : B_BAD_VALUE);
240 	struct stat statData;
241 	if (error == B_OK)
242 		error = GetStat(&statData);
243 	if (error == B_OK)
244 		*atime = statData.st_atime;
245 	return error;
246 }
247 
248 
249 // Sets the node's access time to atime.
250 status_t
251 BStatable::SetAccessTime(time_t atime)
252 {
253 	struct stat statData;
254 	statData.st_atime = atime;
255 	return set_stat(statData, B_STAT_ACCESS_TIME);
256 }
257 
258 
259 // Fills out vol with the the volume that the node lives on.
260 status_t
261 BStatable::GetVolume(BVolume *vol) const
262 {
263 	status_t error = (vol ? B_OK : B_BAD_VALUE);
264 	struct stat statData;
265 	if (error == B_OK)
266 		error = GetStat(&statData);
267 	if (error == B_OK)
268 		error = vol->SetTo(statData.st_dev);
269 	return error;
270 }
271 
272 
273 // _OhSoStatable1() -> GetStat()
274 extern "C" status_t
275 #if __GNUC__ == 2
276 _OhSoStatable1__9BStatable(const BStatable *self, struct stat *st)
277 #else
278 _ZN9BStatable14_OhSoStatable1Ev(const BStatable *self, struct stat *st)
279 #endif
280 {
281 	// No Perform() method -- we have to use the old GetStat() method instead.
282 	struct stat_beos oldStat;
283 	status_t error = BStatable::Private(self).GetStatBeOS(&oldStat);
284 	if (error != B_OK)
285 		return error;
286 
287 	convert_from_stat_beos(&oldStat, st);
288 	return B_OK;
289 }
290 
291 
292 void BStatable::_OhSoStatable2() {}
293 void BStatable::_OhSoStatable3() {}
294