1//----------------------------------------------------------------------
2//  This software is part of the Haiku distribution and is covered
3//  by the MIT license.
4//---------------------------------------------------------------------
5/*!
6	\file Statable.cpp
7	BStatable implementation.
8*/
9
10#include <Statable.h>
11#include <Node.h>
12#include <NodeMonitor.h>
13#include <Volume.h>
14
15#include <sys/stat.h>
16
17/*!	\fn status_t GetStat(struct stat *st) const
18	\brief Returns the stat stucture for the node.
19	\param st the stat structure to be filled in.
20	\return
21	- \c B_OK: Worked fine
22	- \c B_NO_MEMORY: Could not allocate the memory for the call.
23	- \c B_BAD_VALUE: The current node does not exist.
24	- \c B_NOT_ALLOWED: Read only node or volume.
25*/
26
27
28BStatable::~BStatable()
29{
30}
31
32/*!	\brief Returns if the current node is a file.
33	\return \c true, if the BNode is properly initialized and is a file,
34			\c false otherwise.
35*/
36bool
37BStatable::IsFile() const
38{
39	struct stat statData;
40	if (GetStat(&statData) == B_OK)
41		return S_ISREG(statData.st_mode);
42	else
43		return false;
44}
45
46/*!	\brief Returns if the current node is a directory.
47	\return \c true, if the BNode is properly initialized and is a file,
48			\c false otherwise.
49*/
50bool
51BStatable::IsDirectory() const
52{
53	struct stat statData;
54	if (GetStat(&statData) == B_OK)
55		return S_ISDIR(statData.st_mode);
56	else
57		return false;
58}
59
60/*!	\brief Returns if the current node is a symbolic link.
61	\return \c true, if the BNode is properly initialized and is a symlink,
62			\c false otherwise.
63*/
64bool
65BStatable::IsSymLink() const
66{
67	struct stat statData;
68	if (GetStat(&statData) == B_OK)
69		return S_ISLNK(statData.st_mode);
70	else
71		return false;
72}
73
74/*!	\brief Returns a node_ref for the current node.
75	\param ref the node_ref structure to be filled in
76	\see GetStat() for return codes
77*/
78status_t
79BStatable::GetNodeRef(node_ref *ref) const
80{
81	status_t error = (ref ? B_OK : B_BAD_VALUE);
82	struct stat statData;
83	if (error == B_OK)
84		error = GetStat(&statData);
85	if (error == B_OK) {
86		ref->device  = statData.st_dev;
87		ref->node = statData.st_ino;
88	}
89	return error;
90}
91
92/*!	\brief Returns the owner of the node.
93	\param owner a pointer to a uid_t variable to be set to the result
94	\see GetStat() for return codes
95*/
96status_t
97BStatable::GetOwner(uid_t *owner) const
98{
99	status_t error = (owner ? B_OK : B_BAD_VALUE);
100	struct stat statData;
101	if (error == B_OK)
102		error = GetStat(&statData);
103	if (error == B_OK)
104		*owner = statData.st_uid;
105	return error;
106}
107
108/*!	\brief Sets the owner of the node.
109	\param owner the new owner
110	\see GetStat() for return codes
111*/
112status_t
113BStatable::SetOwner(uid_t owner)
114{
115	struct stat statData = {};
116	statData.st_uid = owner;
117	return set_stat(statData, B_STAT_UID);
118}
119
120/*!	\brief Returns the group owner of the node.
121	\param group a pointer to a gid_t variable to be set to the result
122	\see GetStat() for return codes
123*/
124status_t
125BStatable::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/*!	\brief Sets the group owner of the node.
137	\param group the new group
138	\see GetStat() for return codes
139*/
140status_t
141BStatable::SetGroup(gid_t group)
142{
143	struct stat statData = {};
144	statData.st_gid = group;
145	return set_stat(statData, B_STAT_GID);
146}
147
148/*!	\brief Returns the permissions of the node.
149	\param perms a pointer to a mode_t variable to be set to the result
150	\see GetStat() for return codes
151*/
152status_t
153BStatable::GetPermissions(mode_t *perms) const
154{
155	status_t error = (perms ? B_OK : B_BAD_VALUE);
156	struct stat statData;
157	if (error == B_OK)
158		error = GetStat(&statData);
159	if (error == B_OK)
160		*perms = (statData.st_mode & S_IUMSK);
161	return error;
162}
163
164/*!	\brief Sets the permissions of the node.
165	\param perms the new permissions
166	\see GetStat() for return codes
167*/
168status_t
169BStatable::SetPermissions(mode_t perms)
170{
171	struct stat statData = {};
172	// the FS should do the correct masking -- only the S_IUMSK part is
173	// modifiable
174	statData.st_mode = perms;
175	return set_stat(statData, B_STAT_MODE);
176}
177
178/*!	\brief Get the size of the node's data (not counting attributes).
179	\param size a pointer to a variable to be set to the result
180	\see GetStat() for return codes
181*/
182status_t
183BStatable::GetSize(off_t *size) const
184{
185	status_t error = (size ? B_OK : B_BAD_VALUE);
186	struct stat statData = {};
187	if (error == B_OK)
188		error = GetStat(&statData);
189	if (error == B_OK)
190		*size = statData.st_size;
191	return error;
192}
193
194/*!	\brief Returns the last time the node was modified.
195	\param mtime a pointer to a variable to be set to the result
196	\see GetStat() for return codes
197*/
198status_t
199BStatable::GetModificationTime(time_t *mtime) const
200{
201	status_t error = (mtime ? B_OK : B_BAD_VALUE);
202	struct stat statData;
203	if (error == B_OK)
204		error = GetStat(&statData);
205	if (error == B_OK)
206		*mtime = statData.st_mtime;
207	return error;
208}
209
210/*!	\brief Sets the last time the node was modified.
211	\param mtime the new modification time
212	\see GetStat() for return codes
213*/
214status_t
215BStatable::SetModificationTime(time_t mtime)
216{
217	struct stat statData = {};
218	statData.st_mtime = mtime;
219	return set_stat(statData, B_STAT_MODIFICATION_TIME);
220}
221
222/*!	\brief Returns the time the node was accessed.
223	Not used.
224	\see GetModificationTime()
225	\see GetStat() for return codes
226*/
227status_t
228BStatable::GetAccessTime(time_t *atime) const
229{
230	status_t error = (atime ? B_OK : B_BAD_VALUE);
231	struct stat statData;
232	if (error == B_OK)
233		error = GetStat(&statData);
234	if (error == B_OK)
235		*atime = statData.st_atime;
236	return error;
237}
238
239/*!	\brief Sets the time the node was accessed.
240	Not used.
241	\see GetModificationTime()
242	\see GetStat() for return codes
243*/
244status_t
245BStatable::SetAccessTime(time_t atime)
246{
247	struct stat statData = {};
248	statData.st_atime = atime;
249	return set_stat(statData, B_STAT_ACCESS_TIME);
250}
251
252/*!	\brief Returns the volume the node lives on.
253	\param vol a pointer to a variable to be set to the result
254	\see BVolume
255	\see GetStat() for return codes
256*/
257status_t
258BStatable::GetVolume(BVolume *vol) const
259{
260	status_t error = (vol ? B_OK : B_BAD_VALUE);
261	struct stat statData;
262	if (error == B_OK)
263		error = GetStat(&statData);
264	if (error == B_OK)
265		error = vol->SetTo(statData.st_dev);
266	return error;
267}
268
269void BStatable::_OhSoStatable1() {}
270void BStatable::_OhSoStatable2() {}
271void BStatable::_OhSoStatable3() {}
272
273