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 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* stat) 31 { 32 return fObject->_GetStat(stat); 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 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. 60 bool 61 BStatable::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. 72 bool 73 BStatable::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. 84 status_t 85 BStatable::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. 103 status_t 104 BStatable::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. 120 status_t 121 BStatable::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. 131 status_t 132 BStatable::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. 148 status_t 149 BStatable::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. 159 status_t 160 BStatable::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. 176 status_t 177 BStatable::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. 189 status_t 190 BStatable::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. 206 status_t 207 BStatable::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. 223 status_t 224 BStatable::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 234 status_t 235 BStatable::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. 251 status_t 252 BStatable::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. 262 status_t 263 BStatable::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. 279 status_t 280 BStatable::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. 290 status_t 291 BStatable::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() 306 extern "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 325 void BStatable::_OhSoStatable2() {} 326 void BStatable::_OhSoStatable3() {} 327