00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #if defined(__linux__)
00029
00030
00031
00032
00033
00034 #define _FILE_OFFSET_BITS 64
00035 #endif
00036
00037 #include "VLeaf.H"
00038 #include "FdCache.H"
00039 #include "ShortIdBlock.H"
00040 #include "logging.H"
00041 #include <unistd.h>
00042
00043 VestaSource::errorCode
00044 VLeaf::read(void* buffer, int* nbytes, Basics::uint64 offset,
00045 AccessControl::Identity who) throw ()
00046 {
00047 switch (type) {
00048 case VestaSource::immutableFile:
00049 case VestaSource::mutableFile:
00050 break;
00051 case VestaSource::immutableDirectory:
00052 case VestaSource::appendableDirectory:
00053 case VestaSource::mutableDirectory:
00054 case VestaSource::volatileDirectory:
00055 case VestaSource::evaluatorDirectory:
00056 case VestaSource::volatileROEDirectory:
00057 case VestaSource::evaluatorROEDirectory:
00058 assert(false);
00059 return VestaSource::isADirectory;
00060 case VestaSource::ghost:
00061 case VestaSource::stub:
00062 return VestaSource::invalidArgs;
00063 case VestaSource::deleted:
00064 case VestaSource::outdated:
00065 assert(false);
00066 return VestaSource::invalidArgs;
00067 case VestaSource::device:
00068 *nbytes = 0;
00069 return VestaSource::ok;
00070 }
00071 if (!ac.check(who, AccessControl::read))
00072 return VestaSource::noPermission;
00073
00074 FdCache::OFlag ofl;
00075 int fd = FdCache::open(shortId(), FdCache::any, &ofl);
00076 if (fd == -1) {
00077 return Repos::errno_to_errorCode(errno);
00078 }
00079 errno = 0;
00080 if(lseek(fd, offset, SEEK_SET) != -1) {
00081 *nbytes = ::read(fd, buffer, *nbytes);
00082 }
00083 VestaSource::errorCode err = Repos::errno_to_errorCode(errno);
00084 FdCache::close(shortId(), fd, ofl);
00085 return err;
00086 }
00087
00088
00089 bool
00090 VLeaf::executable() throw ()
00091 {
00092 switch (type) {
00093 case VestaSource::immutableFile:
00094 case VestaSource::mutableFile:
00095 break;
00096 case VestaSource::immutableDirectory:
00097 case VestaSource::appendableDirectory:
00098 case VestaSource::mutableDirectory:
00099 case VestaSource::volatileDirectory:
00100 case VestaSource::evaluatorDirectory:
00101 case VestaSource::volatileROEDirectory:
00102 case VestaSource::evaluatorROEDirectory:
00103 assert(false);
00104 return false;
00105 case VestaSource::ghost:
00106 case VestaSource::stub:
00107 return false;
00108 case VestaSource::deleted:
00109 case VestaSource::outdated:
00110 assert(false);
00111 return false;
00112 case VestaSource::device:
00113 return false;
00114 }
00115 FdCache::OFlag ofl;
00116 int fd = FdCache::open(shortId(), FdCache::any, &ofl);
00117 if (fd == -1) {
00118 return false;
00119 }
00120 bool ret = false;
00121 struct stat st;
00122 if (fstat(fd, &st) != -1) {
00123 ret = (st.st_mode & 0111) != 0;
00124 }
00125 FdCache::close(shortId(), fd, ofl);
00126 return ret;
00127 }
00128
00129
00130 Basics::uint64
00131 VLeaf::size() throw ()
00132 {
00133 switch (type) {
00134 case VestaSource::immutableFile:
00135 case VestaSource::mutableFile:
00136 break;
00137 case VestaSource::immutableDirectory:
00138 case VestaSource::appendableDirectory:
00139 case VestaSource::mutableDirectory:
00140 case VestaSource::volatileDirectory:
00141 case VestaSource::evaluatorDirectory:
00142 case VestaSource::volatileROEDirectory:
00143 case VestaSource::evaluatorROEDirectory:
00144 assert(false);
00145 return 0;
00146 case VestaSource::ghost:
00147 case VestaSource::stub:
00148 return 0;
00149 case VestaSource::deleted:
00150 case VestaSource::outdated:
00151 assert(false);
00152 return 0;
00153 case VestaSource::device:
00154 return 0;
00155 }
00156 FdCache::OFlag ofl;
00157 int fd = FdCache::open(shortId(), FdCache::any, &ofl);
00158 if (fd == -1) {
00159 return 0;
00160 }
00161 struct stat st;
00162 Basics::uint64 ret = 0;
00163 if (fstat(fd, &st) != -1) {
00164 ret = st.st_size;
00165 }
00166 FdCache::close(shortId(), fd, ofl);
00167 return ret;
00168 }
00169
00170
00171 VestaSource::errorCode
00172 VLeaf::write(const void* buffer, int* nbytes, Basics::uint64 offset,
00173 AccessControl::Identity who) throw ()
00174 {
00175 switch (type) {
00176 case VestaSource::immutableFile:
00177 return VestaSource::inappropriateOp;
00178 case VestaSource::mutableFile:
00179 break;
00180 case VestaSource::immutableDirectory:
00181 case VestaSource::appendableDirectory:
00182 case VestaSource::mutableDirectory:
00183 case VestaSource::volatileDirectory:
00184 case VestaSource::evaluatorDirectory:
00185 case VestaSource::volatileROEDirectory:
00186 case VestaSource::evaluatorROEDirectory:
00187 assert(false);
00188 return VestaSource::isADirectory;
00189 case VestaSource::ghost:
00190 case VestaSource::stub:
00191 return VestaSource::invalidArgs;
00192 case VestaSource::deleted:
00193 case VestaSource::outdated:
00194 assert(false);
00195 return VestaSource::invalidArgs;
00196 case VestaSource::device:
00197 *nbytes = 0;
00198 return VestaSource::ok;
00199 }
00200 if (!ac.check(who, AccessControl::write))
00201 return VestaSource::noPermission;
00202 FdCache::OFlag ofl;
00203 int fd = FdCache::open(shortId(), FdCache::rw, &ofl);
00204 if (fd == -1) {
00205 return Repos::errno_to_errorCode(errno);
00206 }
00207 errno = 0;
00208 if (lseek(fd, offset, SEEK_SET) != -1) {
00209 *nbytes = ::write(fd, buffer, *nbytes);
00210 }
00211 VestaSource::errorCode err = Repos::errno_to_errorCode(errno);
00212 FdCache::close(shortId(), fd, ofl);
00213 return err;
00214 }
00215
00216
00217 VestaSource::errorCode
00218 VLeaf::setExecutable(bool x, AccessControl::Identity who) throw ()
00219 {
00220 switch (type) {
00221 case VestaSource::immutableFile:
00222 return VestaSource::inappropriateOp;
00223 case VestaSource::mutableFile:
00224 break;
00225 case VestaSource::immutableDirectory:
00226 case VestaSource::appendableDirectory:
00227 case VestaSource::mutableDirectory:
00228 case VestaSource::volatileDirectory:
00229 case VestaSource::evaluatorDirectory:
00230 case VestaSource::volatileROEDirectory:
00231 case VestaSource::evaluatorROEDirectory:
00232 assert(false);
00233 return VestaSource::isADirectory;
00234 case VestaSource::ghost:
00235 case VestaSource::stub:
00236 return VestaSource::invalidArgs;
00237 case VestaSource::deleted:
00238 case VestaSource::outdated:
00239 assert(false);
00240 return VestaSource::invalidArgs;
00241 case VestaSource::device:
00242 return VestaSource::ok;
00243 }
00244 if (!ac.check(who, AccessControl::ownership))
00245 return VestaSource::noPermission;
00246
00247 FdCache::OFlag ofl;
00248 int fd = FdCache::open(shortId(), FdCache::any, &ofl);
00249 if (fd == -1) {
00250 return Repos::errno_to_errorCode(errno);
00251 }
00252 errno = 0;
00253 struct stat st;
00254 if (fstat(fd, &st) != -1) {
00255 fchmod(fd, (st.st_mode & ~0111) | (x ? 0111 : 0));
00256 }
00257 VestaSource::errorCode err = Repos::errno_to_errorCode(errno);
00258 FdCache::close(shortId(), fd, ofl);
00259 return err;
00260 }
00261
00262
00263 VestaSource::errorCode
00264 VLeaf::setSize(Basics::uint64 s, AccessControl::Identity who) throw ()
00265 {
00266 switch (type) {
00267 case VestaSource::immutableFile:
00268 return VestaSource::inappropriateOp;
00269 case VestaSource::mutableFile:
00270 break;
00271 case VestaSource::immutableDirectory:
00272 case VestaSource::appendableDirectory:
00273 case VestaSource::mutableDirectory:
00274 case VestaSource::volatileDirectory:
00275 case VestaSource::evaluatorDirectory:
00276 case VestaSource::volatileROEDirectory:
00277 case VestaSource::evaluatorROEDirectory:
00278 assert(false);
00279 return VestaSource::isADirectory;
00280 case VestaSource::ghost:
00281 case VestaSource::stub:
00282 return VestaSource::invalidArgs;
00283 case VestaSource::deleted:
00284 case VestaSource::outdated:
00285 assert(false);
00286 return VestaSource::invalidArgs;
00287 case VestaSource::device:
00288 return VestaSource::ok;
00289 }
00290 if (!ac.check(who, AccessControl::write))
00291 return VestaSource::noPermission;
00292 FdCache::OFlag ofl;
00293 int fd = FdCache::open(shortId(), FdCache::rw, &ofl);
00294 if (fd == -1) {
00295 return Repos::errno_to_errorCode(errno);
00296 }
00297 errno = 0;
00298 ftruncate(fd, s);
00299 VestaSource::errorCode err = Repos::errno_to_errorCode(errno);
00300 FdCache::close(shortId(), fd, ofl);
00301 return err;
00302 }
00303
00304
00305 time_t
00306 VLeaf::timestamp() throw ()
00307 {
00308 switch (type) {
00309 case VestaSource::immutableFile:
00310 case VestaSource::mutableFile:
00311 break;
00312 case VestaSource::immutableDirectory:
00313 case VestaSource::appendableDirectory:
00314 case VestaSource::mutableDirectory:
00315 case VestaSource::volatileDirectory:
00316 case VestaSource::evaluatorDirectory:
00317 case VestaSource::volatileROEDirectory:
00318 case VestaSource::evaluatorROEDirectory:
00319 assert(false);
00320 return 2;
00321 case VestaSource::ghost:
00322 case VestaSource::stub:
00323 return 2;
00324 case VestaSource::deleted:
00325 case VestaSource::outdated:
00326 assert(false);
00327 return -1;
00328 case VestaSource::device:
00329 return 2;
00330 }
00331 FdCache::OFlag ofl;
00332 int fd = FdCache::open(shortId(), FdCache::any, &ofl);
00333 if (fd == -1) {
00334 return -1;
00335 }
00336 errno = 0;
00337 time_t ts = -1;
00338 struct stat st;
00339 if (fstat(fd, &st) != -1) {
00340 ts = st.st_mtime;
00341 }
00342 FdCache::close(shortId(), fd, ofl);
00343 return ts;
00344 }
00345
00346
00347 VestaSource::errorCode
00348 VLeaf::setTimestamp(time_t ts, AccessControl::Identity who) throw ()
00349 {
00350 switch (type) {
00351 case VestaSource::immutableFile:
00352 return VestaSource::inappropriateOp;
00353 case VestaSource::mutableFile:
00354 break;
00355 case VestaSource::immutableDirectory:
00356 case VestaSource::appendableDirectory:
00357 case VestaSource::mutableDirectory:
00358 case VestaSource::volatileDirectory:
00359 case VestaSource::evaluatorDirectory:
00360 case VestaSource::volatileROEDirectory:
00361 case VestaSource::evaluatorROEDirectory:
00362 assert(false);
00363 return VestaSource::isADirectory;
00364 case VestaSource::ghost:
00365 case VestaSource::stub:
00366 return VestaSource::invalidArgs;
00367 case VestaSource::deleted:
00368 case VestaSource::outdated:
00369 assert(false);
00370 return VestaSource::invalidArgs;
00371 case VestaSource::device:
00372 return VestaSource::invalidArgs;
00373 }
00374 if (!ac.check(who, AccessControl::write) &&
00375 !ac.check(who, AccessControl::ownership))
00376 return VestaSource::noPermission;
00377 char *path = ShortIdBlock::shortIdToName(shortId());
00378 struct timeval tvp[2];
00379 tvp[0].tv_sec = ts;
00380 tvp[0].tv_usec = 0;
00381 tvp[1].tv_sec = ts;
00382 tvp[1].tv_usec = 0;
00383 errno = 0;
00384 utimes(path, tvp);
00385 delete path;
00386 return Repos::errno_to_errorCode(errno);
00387 }