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

VestaSourceCommon.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 // VestaSourceCommon.C
00021 // Last modified on Fri Feb 10 16:11:43 EST 2006 by ken@xorian.net        
00022 //      modified on Mon Nov 15 08:53:38 EST 2004 by irina.furman@intel.com
00023 //      modified on Mon Nov 27 17:12:54 PST 2000 by mann
00024 //
00025 // Some common code between local and remote VestaSource clients
00026 //
00027 
00028 #include "VestaSource.H"
00029 #include "VDirSurrogate.H"
00030 
00031 const LongId RootLongId =            { 0, };
00032 const LongId MutableRootLongId =     { 0, 1, 0, };
00033 const LongId VolatileRootLongId =    { 0, 2, 0, };
00034 const LongId DirShortIdRootLongId =  { 0, 3, 0, };
00035 const LongId FileShortIdRootLongId = { 0, 4, 0, };
00036 const LongId NullLongId =            { 0, 255, 0, };
00037 
00038 // Length of a LongId 
00039 int
00040 LongId::length() const throw()
00041 {
00042     if (value.byte[0] == 0 && value.byte[1] == 4) {
00043         // { 0, 4, s0, s1, s2, s3, s4, 0, fp0, ... fp15, 0, ... }
00044         return 24;
00045     } else {
00046       unsigned int len = 1;
00047       while((len < sizeof(value.byte)) && (value.byte[len] != 0))
00048         {
00049           len++;
00050         }
00051       return len;
00052     }
00053 }
00054 
00055 // Construct a LongId from a ShortId
00056 LongId
00057 LongId::fromShortId(ShortId sid, const FP::Tag* fptag) throw ()
00058 {
00059     if (SourceOrDerived::dirShortId(sid)) {
00060         return DirShortIdRootLongId.append((unsigned int) sid);
00061     } else {
00062         assert(fptag != NULL);
00063         LongId ret = FileShortIdRootLongId.append((unsigned int) sid);
00064         unsigned char fpbytes[FP::ByteCnt];
00065         fptag->ToBytes(fpbytes);
00066         memcpy((void*) &ret.value.byte[8],
00067                (const void*) fpbytes, FP::ByteCnt);
00068         return ret;
00069     }
00070 }
00071 
00072 // Get the LongId of this source's index'th child.  Return NullLongId
00073 // if there is no room for more children.  Assert false if the input
00074 // was NullLongId.
00075 LongId
00076 LongId::append(unsigned int index) const throw ()
00077 {
00078     LongId result = *this;
00079     Bit8* start = &result.value.byte[0];
00080     Bit8* end =
00081       (Bit8*) memchr((const void*) (start + 1), 0, sizeof(result.value)-1);
00082     if (end == NULL) {
00083         // No more indices will fit
00084         return NullLongId;
00085     }
00086     if (start[0] == 0) {
00087         switch (start[1]) {
00088           case 0:
00089             // {0, 0... }: assume it's RootLongId
00090             end = start;
00091             break;
00092           case 1:
00093             // {0, 1... }: it's a mutable directory
00094             break;
00095           case 2:
00096             // {0, 2... }: it's a volatile directory
00097             break;
00098           case 3:
00099             // {0, 3... }: it's an immutable directory short id
00100             assert((ShortId) index != NullShortId);
00101             break;
00102           case 4:
00103             // {0, 4... }: it's a file short id
00104             // Appending beyond the short id itself is invalid
00105             assert(start[2] == 0);
00106             break;
00107           case 255:
00108             // {0, 255... }: it's NullLongId or invalid
00109             assert(false);
00110             break;
00111           default:
00112             assert(false);
00113             break;
00114         }
00115     }
00116     while (index > 0) {
00117         if (end >= &result.value.byte[sizeof(result.value)]) {
00118             // This index won't fit
00119             return NullLongId;
00120         }
00121         int newbyte = index & 0x7f;
00122         index >>= 7;
00123         if (index > 0) newbyte |= 0x80;
00124         *end++ = newbyte;
00125     }       
00126     return result;
00127 }
00128 
00129 // Get the LongId of this source's parent directory.  Return
00130 // NullLongId if this source has no parent.
00131 LongId
00132 LongId::getParent(unsigned int* index) const throw ()
00133 {
00134     unsigned int idx;
00135     if (value.byte[0] == 0 && value.byte[1] == 4) {
00136         // File short id; parent unknown
00137         return NullLongId;
00138     }
00139     LongId result = *this;
00140     Bit8* end = &result.value.byte[sizeof(result.value) - 1];
00141     while (*end == 0) {
00142         end--;
00143         if (end < &result.value.byte[0]) {
00144             // input was RootLongId
00145             return NullLongId; // no parent
00146         }
00147     }
00148     idx = *end;
00149     *end = 0;
00150     end--;
00151     while (end >= &result.value.byte[0]) {
00152         if ((*end & 0x80) == 0) {
00153             if (*end == 0) {
00154                 // input was NullLongId, mutable root, volatile root,
00155                 // or shortid root.
00156                 return NullLongId;
00157             }
00158             break;
00159         }
00160         idx = (idx << 7) | (*end & 0x7f);
00161         *end = 0;
00162         end--;
00163     }
00164     if (index != NULL) *index = idx;
00165     return result;
00166 }
00167 
00168 // Return true if this LongId is an ancestor of the given child.
00169 // A LongId is considered to be its own ancestor.
00170 bool
00171 LongId::isAncestorOf(const LongId& child) const throw ()
00172 {
00173     int i = 0;
00174     if (value.byte[0] == 0) {
00175         // Special cases
00176         switch(value.byte[1]) {
00177           case 0:
00178             // Assume this is RootLongId.
00179             return (bool) (child.value.byte[0] != 0 ||
00180                            child.value.byte[1] == 0);
00181           case 1:
00182           case 2:
00183           case 3:
00184           case 4:
00185             if (child.value.byte[0] != 0 ||
00186                 child.value.byte[1] != value.byte[1]) {
00187                 return false;
00188             }
00189             // Skip testing the first two bytes
00190             i = 2;
00191             break;
00192 
00193           case 255:
00194           default:
00195             return false;
00196         }
00197     }
00198     for (; i < sizeof(value); i++) {
00199         // We do not have to extract and re-form the multi-byte
00200         // values packed into a LongId because the packing is done in
00201         // a canonical way; we need only scan for a difference and
00202         // look to see whether it occurs where the putative parent has
00203         // a zero byte, indicating its end.  Type 4 LongIds add a
00204         // minor complication; bytes 8-23 are a literal fingerprint,
00205         // not packed as a multi-byte value, so zeros in it are not
00206         // terminators.
00207 
00208         if (value.byte[i] != child.value.byte[i]) {
00209             if (i >= 8 && value.byte[0] == 0 && value.byte[1] == 4) {
00210                 return false;
00211             } else {
00212                 return (bool) (value.byte[i] == 0);
00213             }
00214         }
00215     }
00216     return true;
00217 }
00218 
00219 
00220 // Default methods; mostly return inappropriateOp
00221 
00222 static VestaSource::errorCode
00223 badFileOp(VestaSource::typeTag type)
00224 {
00225     if (type == VestaSource::immutableDirectory ||
00226         type == VestaSource::evaluatorDirectory ||
00227         type == VestaSource::evaluatorROEDirectory ||
00228         type == VestaSource::appendableDirectory ||
00229         type == VestaSource::mutableDirectory ||
00230         type == VestaSource::volatileDirectory ||
00231         type == VestaSource::volatileROEDirectory)
00232       return VestaSource::isADirectory;
00233     else 
00234       return VestaSource::inappropriateOp;
00235 }
00236 
00237 static VestaSource::errorCode
00238 badDirectoryOp(VestaSource::typeTag type)
00239 {
00240     if (type == VestaSource::immutableDirectory ||
00241         type == VestaSource::evaluatorDirectory ||
00242         type == VestaSource::evaluatorROEDirectory ||
00243         type == VestaSource::appendableDirectory ||
00244         type == VestaSource::mutableDirectory ||
00245         type == VestaSource::volatileDirectory ||
00246         type == VestaSource::volatileROEDirectory)
00247       return VestaSource::inappropriateOp;
00248     else 
00249       return VestaSource::notADirectory;
00250 }
00251 
00252 VestaSource::errorCode
00253 VestaSource::read(void* buffer, /*INOUT*/int* nbytes,
00254                   Basics::uint64 offset, AccessControl::Identity who)
00255      throw (SRPC::failure)
00256 {
00257     return badFileOp(type);
00258 }
00259 
00260 VestaSource::errorCode
00261 VestaSource::readWhole(std::ostream &out, AccessControl::Identity who)
00262      throw (SRPC::failure)
00263 {
00264     return badFileOp(type);
00265 }
00266 
00267 bool
00268 VestaSource::executable()
00269      throw (SRPC::failure)
00270 {
00271     return false;
00272 }
00273 
00274 
00275 Basics::uint64
00276 VestaSource::size()
00277      throw (SRPC::failure)
00278 {
00279     return 0;
00280 }
00281 
00282 
00283 VestaSource::errorCode
00284 VestaSource::write(const void* buffer, /*INOUT*/int* nbytes,
00285                    Basics::uint64 offset, AccessControl::Identity who)
00286      throw (SRPC::failure)
00287 {
00288     return badFileOp(type);
00289 }
00290 
00291 
00292 VestaSource::errorCode 
00293 VestaSource::setExecutable(bool x, AccessControl::Identity who)
00294      throw (SRPC::failure)
00295 {
00296     return badFileOp(type);
00297 }
00298 
00299 
00300 VestaSource::errorCode 
00301 VestaSource::setSize(Basics::uint64 s, AccessControl::Identity who)
00302      throw (SRPC::failure)
00303 {
00304     return badFileOp(type);
00305 }
00306 
00307 void
00308 VestaSource::resync(AccessControl::Identity who)
00309      throw (SRPC::failure)
00310 {
00311     // No-op
00312     return;
00313 }
00314 
00315 ShortId
00316 VestaSource::shortId()
00317      throw (SRPC::failure)
00318 {
00319     return NullShortId;
00320 }
00321 
00322 
00323 VestaSource::errorCode
00324 VestaSource::lookup(Arc arc, VestaSource*& result, 
00325                     AccessControl::Identity who, unsigned int indexOffset)
00326      throw (SRPC::failure)
00327 {
00328   result = 0;
00329 
00330     return badDirectoryOp(type);
00331 }
00332 
00333 
00334 VestaSource::errorCode
00335 VestaSource::reallyDelete(Arc arc, AccessControl::Identity who,
00336                           bool existCheck, time_t timestamp)
00337      throw (SRPC::failure)
00338 {
00339     return badDirectoryOp(type);
00340 }
00341 
00342 
00343 VestaSource::errorCode
00344 VestaSource::insertFile(Arc arc, ShortId sid, bool master, 
00345                         AccessControl::Identity who,
00346                         dupeCheck chk, VestaSource** newvs, 
00347                         time_t timestamp, FP::Tag* fptag)
00348      throw (SRPC::failure)
00349 {
00350     return badDirectoryOp(type);
00351 }
00352 
00353 VestaSource::errorCode
00354 VestaSource::insertMutableFile(Arc arc, ShortId sid, bool master, 
00355                                AccessControl::Identity who,
00356                                dupeCheck chk, VestaSource** newvs,
00357                                time_t timestamp)
00358      throw (SRPC::failure)
00359 {
00360     return badDirectoryOp(type);
00361 }
00362 
00363 VestaSource::errorCode
00364 VestaSource::insertImmutableDirectory(Arc arc, VestaSource* dir,
00365                                       bool master, AccessControl::Identity who,
00366                                       dupeCheck chk, VestaSource** newvs,
00367                                       time_t timestamp, FP::Tag* fptag)
00368      throw (SRPC::failure)
00369 {
00370     return badDirectoryOp(type);
00371 }
00372 
00373 VestaSource::errorCode
00374 VestaSource::insertAppendableDirectory(Arc arc, bool master, 
00375                                        AccessControl::Identity who,
00376                                        dupeCheck chk, VestaSource** newvs,
00377                                        time_t timestamp)
00378      throw (SRPC::failure)
00379 {
00380     return badDirectoryOp(type);
00381 }
00382 
00383 VestaSource::errorCode
00384 VestaSource::insertMutableDirectory(Arc arc, VestaSource* dir,
00385                                     bool master, AccessControl::Identity who,
00386                                     dupeCheck chk, VestaSource** newvs,
00387                                     time_t timestamp)
00388      throw (SRPC::failure)
00389 {
00390     return badDirectoryOp(type);
00391 }
00392 
00393 
00394 VestaSource::errorCode
00395 VestaSource::insertGhost(Arc arc, bool master, AccessControl::Identity who,
00396                          dupeCheck chk, VestaSource** newvs, time_t timestamp)
00397      throw (SRPC::failure)
00398 {
00399     return badDirectoryOp(type);
00400 }
00401 
00402 
00403 VestaSource::errorCode
00404 VestaSource::insertStub(Arc arc, bool master, AccessControl::Identity who,
00405                         dupeCheck chk, VestaSource** newvs, time_t timestamp)
00406      throw (SRPC::failure)
00407 {
00408     return badDirectoryOp(type);
00409 }
00410 
00411 
00412 VestaSource::errorCode
00413 VestaSource::renameTo(Arc arc, VestaSource* fromDir, Arc fromArc,
00414                       AccessControl::Identity who,
00415                       dupeCheck chk, time_t timestamp)
00416      throw (SRPC::failure)
00417 {
00418     return badDirectoryOp(type);
00419 }
00420 
00421 
00422 VestaSource::errorCode
00423 VestaSource::getBase(VestaSource*& result, AccessControl::Identity who)
00424      throw (SRPC::failure)
00425 {
00426         return badDirectoryOp(type);
00427 }
00428 
00429 
00430 VestaSource::errorCode
00431 VestaSource::list(unsigned int firstIndex,
00432                   VestaSource::listCallback callback, void* closure,
00433                   AccessControl::Identity who,
00434                   bool deltaOnly, unsigned int indexOffset)
00435 {
00436     return badDirectoryOp(type);
00437 }
00438 
00439 VestaSource::errorCode
00440 VestaSource::lookupIndex(unsigned int index, VestaSource*& result,
00441                          char *arcbuf)
00442      throw (SRPC::failure)
00443 {
00444   result = 0;
00445 
00446     return badDirectoryOp(type);
00447 }
00448 
00449 VestaSource::errorCode
00450 VestaSource::setIndexMaster(unsigned int index, bool state,
00451                             AccessControl::Identity who)
00452      throw (SRPC::failure)
00453 {
00454     return badDirectoryOp(type);
00455 }
00456 
00457 
00458 time_t
00459 VestaSource::timestamp()
00460      throw (SRPC::failure)
00461 {
00462     return 2;  // arbitrary nonzero value used for ghosts, etc.
00463 }
00464 
00465 
00466 VestaSource::errorCode
00467 VestaSource::setTimestamp(time_t ts, AccessControl::Identity who)
00468      throw (SRPC::failure)
00469 {
00470     return badFileOp(type);
00471 }
00472 
00473 bool
00474 VestaSource::hasName() throw ()
00475 {
00476     assert(false);
00477     return false;
00478 }
00479 
00480 void
00481 VestaSource::setHasName(bool val) throw ()
00482 {
00483     assert(false);
00484 }
00485 
00486 bool
00487 VestaSource::visited() throw ()
00488 {
00489     assert(false);
00490     return false;
00491 }
00492 
00493 void
00494 VestaSource::setVisited(bool val) throw ()
00495 {
00496     assert(false);
00497 }
00498 
00499 void
00500 VestaSource::mark(bool byName, ArcTable* hidden) throw ()
00501 {
00502     assert(false);
00503 }
00504 
00505 Bit32
00506 VestaSource::checkpoint(Bit32& nextSP, std::fstream& ckpt) throw ()
00507 {
00508     assert(false);
00509     return 0;
00510 }
00511 
00512 void
00513 VestaSource::freeTree() throw ()
00514 {
00515     assert(false);
00516 }
00517 
00518 static char *errText[] = { "ok", "notFound", "noPermission", "nameInUse",
00519                            "inappropriateOp", "pathnameTooLong", "rpcFailure",
00520                            "notADirectory", "isADirectory", "invalidArgs",
00521                            "outOfSpace", "notMaster", "longIdOverflow",
00522                            // These would be the next two, but they're
00523                            // currently not valid.
00524                            "13?", "14?" };
00525 static char *typeText[] = { "immutableFile", "mutableFile",
00526                             "immutableDirectory", "appendableDirectory",
00527                             "mutableDirectory", "ghost", "stub", "deleted",
00528                             "outdated", "volatileDirectory",
00529                             "evaluatorDirectory", "device",
00530                             "volatileROEDirectory", "evaluatorROEDirectory",
00531                             "gap", "unused" };
00532 static char typeChar[] = { 'f', 'u', 'i', 'a', 'm', 'g', 's', 'd', 'o', 'v',
00533                            'e', 'n', 'r', 'l', 'p', 'x' };
00534 static char *opText[] = { "opSet", "opClear", "opAdd", "opRemove" };
00535 static char opChar[] = { 's', 'c', 'a', 'r' };
00536 
00537 const char*
00538 VestaSource::errorCodeString(VestaSource::errorCode err) throw ()
00539 {
00540     return errText[(int) err];
00541 }
00542 
00543 const char*
00544 VestaSource::typeTagString(VestaSource::typeTag type) throw ()
00545 {
00546     return typeText[(int) type];
00547 }   
00548 
00549 char
00550 VestaSource::typeTagChar(VestaSource::typeTag type) throw ()
00551 {
00552     return typeChar[(int) type];
00553 }   
00554 
00555 const char*
00556 VestaAttribs::attribOpString(VestaSource::attribOp op) throw ()
00557 {
00558     return opText[(int) op];
00559 }   
00560 
00561 char
00562 VestaAttribs::attribOpChar(VestaSource::attribOp op) throw ()
00563 {
00564     return opChar[(int) op];
00565 }   
00566 
00567 VestaSource::errorCode
00568 VestaSource::setMaster(bool state, AccessControl::Identity who)
00569      throw (SRPC::failure)
00570 {
00571     unsigned int index;
00572 
00573     VestaSource *parent = longid.getParent(&index).lookup();
00574     if (parent == NULL) return VestaSource::notFound;
00575     VestaSource::errorCode err = parent->setIndexMaster(index, state, who);
00576     delete parent;
00577     if (err == VestaSource::ok) master = state;
00578     return err;
00579 }
00580 
00581 // If it's not the VDirSurrogate subclass, must be local
00582 Text
00583 VestaSource::host() throw()
00584 {
00585     return VDirSurrogate::defaultHost();
00586 }
00587 
00588 Text
00589 VestaSource::port() throw()
00590 {
00591     return VDirSurrogate::defaultPort();
00592 }
00593 
00594 VestaSource::errorCode
00595 VestaSource::measureDirectory(/*OUT*/VestaSource::directoryStats &result,
00596                               AccessControl::Identity who)
00597   throw (SRPC::failure)
00598 {
00599   return VestaSource::inappropriateOp;
00600 }
00601 
00602 VestaSource::errorCode
00603 VestaSource::collapseBase(AccessControl::Identity who)
00604   throw (SRPC::failure)
00605 {
00606   return VestaSource::inappropriateOp;
00607 }
00608 
00609 unsigned int VestaSource::linkCount()
00610 {
00611   return 1;
00612 }
00613 
00614 VestaSource *VestaSource::copy() throw()
00615 {
00616   // This operation is for concrete subclasses.
00617   assert(false);
00618   return 0;
00619 }

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