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 26class BStatable::Private { 27public: 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 39private: 40 const BStatable* fObject; 41}; 42 43 44#if __GNUC__ > 3 45BStatable::~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*/ 66bool 67BStatable::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*/ 80bool 81BStatable::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*/ 94bool 95BStatable::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*/ 108status_t 109BStatable::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*/ 126status_t 127BStatable::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*/ 142status_t 143BStatable::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*/ 154status_t 155BStatable::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*/ 170status_t 171BStatable::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*/ 182status_t 183BStatable::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*/ 198status_t 199BStatable::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*/ 212status_t 213BStatable::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*/ 228status_t 229BStatable::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*/ 244status_t 245BStatable::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*/ 256status_t 257BStatable::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*/ 272status_t 273BStatable::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*/ 285status_t 286BStatable::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*/ 302status_t 303BStatable::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*/ 315status_t 316BStatable::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() 329extern "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 347void BStatable::_OhSoStatable2() {} 348void BStatable::_OhSoStatable3() {} 349