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 22class BStatable::Private { 23public: 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 35private: 36 const BStatable* fObject; 37}; 38 39 40#if __GNUC__ > 3 41BStatable::~BStatable() 42{ 43} 44#endif 45 46 47// Returns whether or not the current node is a file. 48bool 49BStatable::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. 60bool 61BStatable::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. 72bool 73BStatable::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. 84status_t 85BStatable::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. 103status_t 104BStatable::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. 120status_t 121BStatable::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. 131status_t 132BStatable::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. 148status_t 149BStatable::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. 159status_t 160BStatable::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. 176status_t 177BStatable::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. 189status_t 190BStatable::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. 206status_t 207BStatable::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. 223status_t 224BStatable::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 234status_t 235BStatable::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. 251status_t 252BStatable::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. 262status_t 263BStatable::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. 279status_t 280BStatable::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. 290status_t 291BStatable::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() 306extern "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 325void BStatable::_OhSoStatable2() {} 326void BStatable::_OhSoStatable3() {} 327