Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

VLeaf.C

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 //
00020 // VLeaf.C
00021 // Last modified on Thu Jul 29 14:20:50 EDT 2004 by ken@xorian.net
00022 //      modified on Tue Aug  7 17:41:12 PDT 2001 by mann
00023 //
00024 // Derived class for in-memory representation of Vesta sources of
00025 // type immutableFile, mutableFile, ghost, and stub. 
00026 //
00027 
00028 #if defined(__linux__)
00029 // Several methods in this file (VLeaf::read, VLeaf::write,
00030 // VLeaf::setSize, VLeaf::size) use 64-bit file offsets/sizes.
00031 
00032 // This macro asks the Linux system headers for 64-bit file operations
00033 // (lseek, fstat, ftruncate, and others).
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, /*INOUT*/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, /*INOUT*/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 }

Generated on Mon May 8 00:48:53 2006 for Vesta by  doxygen 1.4.2