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

vcollapsebase.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 // vcollapsebase.C - Utility for asking the repository to replace the
00021 // chain of basis directories of a mutable or immutable directory with
00022 // a collapsed representation for increased efficiency.
00023 //
00024 // Last modified on Fri Apr 22 13:48:04 EDT 2005 by ken@xorian.net  
00025 
00026 #include <Basics.H>
00027 #include <Text.H>
00028 #include <VestaConfig.H>
00029 #include <VestaSource.H>
00030 #include <VDirSurrogate.H>
00031 #include <signal.h>
00032 #include <ReposUI.H>
00033 
00034 extern "C" {
00035 #include <getopt.h>
00036 }
00037 
00038 using std::cerr;
00039 using std::endl;
00040 
00041 Text program_name;
00042 
00043 void usage()
00044 {
00045   cerr << "Usage: " << program_name << endl <<
00046     "        [-c] [-R repos]" << endl <<
00047     "        directory" << endl << endl;
00048   exit(1);
00049 }
00050 
00051 struct EntryData
00052 {
00053   struct EntryData *next;
00054 
00055   VestaSource::typeTag type;
00056   Text arc;
00057   unsigned int index;
00058   Bit32 pseudoInode;
00059   ShortId fileSid;
00060   bool master;
00061 
00062   EntryData(VestaSource::typeTag type, Arc arc,
00063             unsigned int index, Bit32 pseudoInode,
00064             ShortId fileSid, bool master)
00065     : type(type), arc(arc), index(index), pseudoInode(pseudoInode),
00066       fileSid(fileSid), master(master), next(0)
00067   { }
00068 };
00069 
00070 struct RecordClosure
00071 {
00072   struct EntryData *first, *last;
00073 
00074   RecordClosure()
00075     : first(0), last(0)
00076     { }
00077 };
00078 
00079 bool recordListCB(void* closure, VestaSource::typeTag type, Arc arc,
00080                   unsigned int index, Bit32 pseudoInode,
00081                   ShortId fileSid, bool master)
00082 {
00083   RecordClosure *rclosure = (RecordClosure *) closure;
00084 
00085   EntryData *thisEntry = NEW_CONSTR(EntryData,
00086                                     (type, arc, index, pseudoInode,
00087                                      fileSid, master));
00088 
00089   if(rclosure->last == 0)
00090     {
00091       rclosure->last = thisEntry;
00092       rclosure->first = thisEntry;
00093     }
00094   else
00095     {
00096       assert(rclosure->last->next == 0);
00097       rclosure->last->next = thisEntry;
00098       rclosure->last = thisEntry;
00099       assert(rclosure->first != 0);
00100     }
00101 
00102   return true;
00103 }
00104 
00105 struct CompareClosure
00106 {
00107   const struct EntryData *list;
00108   unsigned int raw_index;
00109   bool miscompare;
00110 
00111   CompareClosure(const struct EntryData *list)
00112     : list(list), raw_index(0), miscompare(false)
00113     { }
00114 
00115   void advance()
00116     {
00117       raw_index++;
00118       if(list != 0)
00119         list = list->next;
00120     }
00121 };
00122 
00123 bool compareListCB(void* closure, VestaSource::typeTag type, Arc arc,
00124                    unsigned int index, Bit32 pseudoInode,
00125                    ShortId fileSid, bool master)
00126 {
00127   CompareClosure *cclosure = (CompareClosure *) closure;
00128 
00129   if(cclosure->list == 0)
00130     {
00131       cclosure->miscompare = true;
00132       cerr << "directory entry " << cclosure->raw_index
00133            << " not present in original:" << endl
00134            << "\tarc   = \"" << arc << "\"" << endl
00135            << "\ttype  = " << VestaSource::typeTagString(type) << endl
00136            << "\tindex = " << index << endl;
00137     }
00138   else
00139     {
00140       bool type_match = (cclosure->list->type == type);
00141       bool arc_match = (cclosure->list->arc == arc);
00142       bool index_match = (cclosure->list->index == index);
00143       bool pinode_match = (cclosure->list->pseudoInode == pseudoInode);
00144       bool sid_match = (cclosure->list->fileSid == fileSid);
00145       bool master_match = ((cclosure->list->master && master) ||
00146                            (!cclosure->list->master && !master));
00147 
00148       // Mismatch on anything?
00149       if(!type_match || !arc_match || !index_match ||
00150          !pinode_match || !sid_match || !master_match)
00151         {
00152           cclosure->miscompare = true;
00153           cerr << "directory entry " << cclosure->raw_index
00154                << "mismatch:" << endl;
00155 
00156           // First print information we want to display if it matched
00157           // even though there was a mismatch on something else.
00158           if(arc_match)
00159             {
00160               cerr << "\tarc   = \"" << arc << "\"" << endl;
00161             }
00162           if(type_match)
00163             {
00164               cerr << "\ttype  = " << VestaSource::typeTagString(type) << endl;
00165             }
00166           if(index_match)
00167             {
00168               cerr << "\tindex = " << index << endl;
00169             }
00170 
00171           if(!arc_match)
00172             {
00173               cerr << "\tarc was \"" << cclosure->list->arc 
00174                    << "\", is \"" << arc << "\"" << endl;
00175             }
00176           if(!type_match)
00177             {
00178               cerr << "\ttype was "
00179                    << VestaSource::typeTagString(cclosure->list->type)
00180                    << ", is " << VestaSource::typeTagString(type) << endl;
00181             }
00182           if(!index_match)
00183             {
00184               cerr << "\tindex was " << cclosure->list->index
00185                    << ", is " << index << endl;
00186             }
00187           if(!pinode_match)
00188             {
00189               cerr << "\tpseudoInode was " << cclosure->list->pseudoInode
00190                    << ", is " << pseudoInode << endl;
00191             }
00192           if(!pinode_match)
00193             {
00194               cerr << "\tfileSid was " << cclosure->list->fileSid
00195                    << ", is " << fileSid << endl;
00196             }
00197           if(!master_match)
00198             {
00199               cerr << "\tmaster was " << (cclosure->list->master
00200                                           ?"true":"false")
00201                    << ", is " << (master?"true":"false") << endl;
00202             }
00203         }
00204     }
00205 
00206   // Advance the closure to the next directory entry.
00207   cclosure->advance();
00208 
00209   return true;
00210 }
00211 
00212 int
00213 main(int argc, char* argv[])
00214 {
00215   // Save the program name
00216   program_name = Text(argv[0]);
00217 
00218   bool consistency_check = false;
00219   Text repos;
00220   bool default_repos = true;
00221 
00222   VestaSource::errorCode err;
00223 
00224   try
00225     {
00226       // Use the repository from the config file by default
00227       Text host(VDirSurrogate::defaultHost());
00228       Text port(VDirSurrogate::defaultPort());
00229 
00230       // Parse command line
00231       opterr = 0;
00232       for(;;)
00233         {
00234           int c = getopt(argc, argv, "cR:");
00235           if(c == EOF) break;
00236           switch(c)
00237             {
00238             case 'c':
00239               consistency_check = true;
00240               break;
00241             case 'R':
00242               repos = optarg;
00243               default_repos = false;
00244               break;
00245             case '?':
00246             default:
00247               usage();
00248             }
00249         }
00250       if (argc <= optind)
00251         {
00252           usage();
00253         }
00254 
00255       // Use a nondefault repository if specified
00256       if (!default_repos)
00257         {
00258           int colon = repos.FindCharR(':');
00259           if (colon == -1)
00260             {
00261               host = repos;
00262               repos = repos + ":" + port;
00263             }
00264           else
00265             {
00266               host = repos.Sub(0, colon);
00267               port = repos.Sub(colon+1);
00268             }
00269         }
00270 
00271       for(unsigned int i = optind; i < argc; i++)
00272         {
00273           // Canonicalize name
00274           Text name = Text(argv[i]);
00275           Text cname = ReposUI::canonicalize(name);
00276 
00277           // Look up in the repository
00278           VestaSource *vs = ReposUI::filenameToVS(cname, host, port);
00279 
00280           // If we're doing consistency checking, list the directory and
00281           // record its contents before calling collapseBase.
00282           RecordClosure recorded;
00283           if(consistency_check)
00284             {
00285               err = vs->list(0, recordListCB, &recorded);
00286               if (err != VestaSource::ok)
00287                 {
00288                   cerr << program_name 
00289                        << ": error listing directory " << name
00290                        << " (recording): "
00291                        << ReposUI::errorCodeText(err) << endl;
00292                   exit(1);
00293                 }
00294             }
00295 
00296           // Collapse the base of this directory
00297           err = vs->collapseBase();
00298           if (err != VestaSource::ok)
00299             {
00300               cerr << program_name 
00301                    << ": error collapsing base of directory " << name << ": "
00302                    << ReposUI::errorCodeText(err) << endl;
00303               exit(1);
00304             }
00305 
00306           // Now that the base has been replaced with a collapsed
00307           // representation, perform the consistency check.
00308           if(consistency_check)
00309             {
00310               CompareClosure compare(recorded.first);
00311               err = vs->list(0, compareListCB, &compare);
00312               if (err != VestaSource::ok)
00313                 {
00314                   cerr << program_name 
00315                        << ": error listing directory " << name
00316                        << " (comparing): "
00317                        << ReposUI::errorCodeText(err) << endl;
00318                   exit(1);
00319                 }
00320               // In the event of a mis-compare, exit with error status.
00321               if(compare.miscompare)
00322                 {
00323                   cerr << program_name 
00324                        << ": collapseBase changed directory " << name << "!"
00325                        << endl;
00326                   exit(1);
00327                 }
00328             }
00329         }
00330     }
00331   catch(VestaConfig::failure f)
00332     {
00333       cerr << program_name << ": " << f.msg << endl;
00334       exit(2);
00335     }
00336   catch(SRPC::failure f)
00337     {
00338       cerr << program_name
00339            << ": SRPC failure; " << f.msg << " (" << f.r << ")" << endl;
00340       exit(2);
00341     }
00342   catch(ReposUI::failure f)
00343     {
00344       cerr << program_name << ": " << f.msg << endl;
00345       exit(2);
00346     }
00347 }

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