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

vwhohas.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 // vwhohas.C
00021 // Last modified on Sun Jun  5 21:54:26 EDT 2005 by ken@xorian.net         
00022 //      modified on Fri Jan 21 09:07:46 EST 2005 by irina.furman@intel.com 
00023 //      modified on Wed Jul 11 22:27:52 PDT 2001 by mann  
00024 //      modified on Tue May  4 11:34:41 PDT 1999 by heydon
00025 //
00026 
00027 // Who has a given Vesta package checked out?
00028 // See documentation in vwhohas.1.mtex
00029 
00030 #include <Basics.H>
00031 #include <Text.H>
00032 #include <VestaConfig.H>
00033 #include <VestaSource.H>
00034 #include <VDirSurrogate.H>
00035 #include "ReposUI.H"
00036 
00037 #if !defined(__sun__)
00038 extern "C" {
00039 #include <getopt.h>
00040 }
00041 #endif
00042 
00043 using std::cout;
00044 using std::cerr;
00045 using std::endl;
00046 
00047 enum Recursion {
00048     r_none, r_pkg, r_branch
00049   };
00050 
00051 Text program_name, defpkgpar;
00052 int errcount = 0;
00053 
00054 void
00055 Usage()
00056 {
00057     cerr << "Usage: " << program_name
00058       <<  " [-n | -p | -b] [-m] [-t] [-v] [-R repos] [package]" << endl;
00059     exit(1);
00060 }
00061 
00062 struct verclosure {
00063     VestaSource* parent;
00064     Text prefix;
00065     Recursion recurse;
00066     bool mast;
00067     int elide;
00068     bool comment;
00069     Text lhost, lport;
00070 };
00071 
00072 static bool
00073 vercallback(void* closure, VestaSource::typeTag type, Arc arc,
00074             unsigned int index, Bit32 pseudoInode, ShortId filesid,
00075             bool master);
00076 
00077 static void
00078 printwhohas(VestaSource* vs, Text prefix, Recursion recurse,
00079             bool mast, int elide, bool comment, Text lhost, Text lport)
00080 {
00081     verclosure cl;
00082     cl.parent = vs;
00083     cl.prefix = prefix;
00084     cl.recurse = recurse;
00085     cl.mast = mast;
00086     cl.elide = elide;
00087     cl.comment = comment;
00088     cl.lhost = lhost;
00089     cl.lport = lport;
00090     VestaSource::errorCode err = vs->list(0, vercallback, &cl);
00091     if (err != VestaSource::ok) {
00092         cerr << program_name 
00093           << ": error listing directory " << cl.prefix << ": " 
00094             << ReposUI::errorCodeText(err) << endl;
00095         errcount++;
00096     }
00097 }
00098 
00099 static bool
00100 vercallback(void* closure, VestaSource::typeTag type, Arc arc,
00101             unsigned int index, Bit32 pseudoInode, ShortId filesid,
00102             bool master)
00103 {
00104     verclosure* cl = (verclosure*) closure;
00105     char* endptr;
00106     char* v;
00107     VestaSource* vs;
00108 
00109     if (cl->mast && !master &&
00110        type != VestaSource::immutableDirectory &&
00111        type != VestaSource::immutableFile) {
00112       try {
00113         vs = ReposUI::filenameToMasterVS(cl->prefix + arc,
00114                                          cl->parent->host() + ":" +
00115                                          cl->parent->port() + " " +
00116                                          cl->lhost + ":" + cl->lport);
00117       } catch (ReposUI::failure f) {
00118         cerr << program_name << ": " << f.msg << endl;
00119         errcount++;
00120         return true;
00121       }
00122     } else {
00123       VestaSource::errorCode err = cl->parent->lookupIndex(index, vs);
00124       if (err != VestaSource::ok) {
00125        cerr << program_name << ": error on lookupIndex: "
00126             << ReposUI::errorCodeText(err) << endl;
00127        errcount++;
00128        return true;
00129       }
00130     }
00131 
00132     if (vs->type == VestaSource::stub) {
00133         char* owner = vs->getAttrib("checkout-by");
00134         char* dest = vs->getAttrib("checkout-to");
00135         if (owner) {
00136             cout << cl->prefix.Sub(cl->elide) << arc << "  " << owner;
00137             delete owner;
00138             if (dest) {
00139               cout << "  " << dest;
00140               delete dest;
00141             }
00142             cout << endl;
00143             if(cl->comment)
00144               {
00145                 char* message = vs->getAttrib("message");
00146                 if(message)
00147                   {
00148                     cout << "\t" << message << endl;
00149                     delete message;
00150                   }
00151               }
00152         }
00153     } else if (vs->type == VestaSource::appendableDirectory) {
00154         if (cl->recurse == r_none) {
00155             delete vs;
00156             return true;
00157         }
00158         if (!vs->inAttribs("type", "checkout") &&
00159             (cl->recurse >= r_branch || !vs->inAttribs("type", "branch"))) {
00160             // OK to recurse
00161             printwhohas(vs, cl->prefix + arc + "/", cl->recurse,
00162                         cl->mast, cl->elide, cl->comment, cl->lhost, cl->lport);
00163         }
00164     }
00165     delete vs;
00166     return true;
00167 }
00168 
00169 void
00170 doit(Text pkg, Recursion recurse, bool mast, bool fullpath, bool comment,
00171      Text lhost, Text lport)
00172 {
00173     Text cpkg = ReposUI::canonicalize(pkg, defpkgpar);
00174     VestaSource* vs_pkg;
00175     if (mast) {
00176       vs_pkg = ReposUI::filenameToMasterVS(cpkg, lhost + ":" + lport);
00177     } else {
00178       vs_pkg = ReposUI::filenameToVS(cpkg, lhost, lport);
00179     }
00180     
00181     // Sanity checking
00182     if (vs_pkg->type != VestaSource::appendableDirectory) {
00183         // No error message; could be a ghost (etc.) that matched a "*"
00184         return;
00185     }
00186     if (recurse == r_none && !vs_pkg->inAttribs("type", "package")) {
00187         cerr << program_name << ": " << cpkg << " is not a package" << endl;
00188         errcount++;
00189         return;
00190     }
00191     printwhohas(vs_pkg, cpkg + "/", recurse, mast, 
00192                 fullpath ? 0 : (cpkg.Length() + 1), comment, lhost, lport);
00193 }
00194 
00195 int
00196 main(int argc, char* argv[])
00197 {
00198     program_name = argv[0];
00199     try {
00200         //
00201         // Read config file
00202         //
00203         defpkgpar = VestaConfig::get_Text("UserInterface",
00204                                           "DefaultPackageParent");
00205         
00206         Recursion recurse = r_pkg;
00207         bool mast = false;
00208         bool fullpath = true;
00209         bool comment = false;
00210         Text repos;
00211         
00212         // 
00213         // Parse command line
00214         //
00215         opterr = 0;
00216         for (;;) {
00217             char* slash;
00218             int c = getopt(argc, argv, "npbmtvR:");
00219             if (c == EOF) break;
00220             switch (c) {
00221               case 'n':
00222                 recurse = r_none;
00223                 break;
00224               case 'p':
00225                 recurse = r_pkg;
00226                 break;
00227               case 'b':
00228                 recurse = r_branch;
00229                 break;
00230               case 'm':
00231                 mast = true;
00232                 break;
00233               case 't':
00234                 fullpath = false;
00235                 break;
00236               case 'v':
00237                 comment = true;
00238                 break;
00239               case 'R':
00240                 repos = optarg;
00241                 break;
00242               case '?':
00243               default:
00244                 Usage();
00245             }
00246         }
00247 
00248         Text lhost(VDirSurrogate::defaultHost());
00249         Text lport(VDirSurrogate::defaultPort());
00250         if (repos != "") {
00251           int colon = repos.FindCharR(':');
00252           if (colon == -1) {
00253             lhost = repos;
00254             repos = repos + ":" + lport;
00255           } else {
00256             lhost = repos.Sub(0, colon);
00257             lport = repos.Sub(colon+1);
00258           }
00259         }
00260 
00261         if (optind > argc) {
00262             Usage();
00263             /* not reached */
00264         }
00265         if (optind == argc) {
00266             doit("/vesta", recurse, mast, fullpath, comment, lhost, lport);
00267         } else {
00268             if (!fullpath) {
00269                 cerr << program_name <<
00270                   ": only one package allowed with -t flag" << endl;
00271                 exit(errcount + 1);
00272             }
00273             while (optind < argc) {
00274                 doit(argv[optind++], recurse, mast, fullpath, 
00275                      comment, lhost, lport);
00276             }
00277         }
00278         
00279     } catch (VestaConfig::failure f) {
00280         cerr << program_name << ": " << f.msg << endl;
00281         exit(errcount + 1);
00282     } catch (SRPC::failure f) {
00283         cerr << program_name
00284           << ": SRPC failure; " << f.msg << " (" << f.r << ")" << endl;
00285         exit(errcount + 1);
00286     } catch (ReposUI::failure f) {
00287         cerr << program_name << ": " << f.msg << endl;
00288         exit(errcount + 1);
00289     }
00290     return errcount;
00291 }
00292 
00293 
00294 

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