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