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

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

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