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

vrm.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 // vrm.C
00021 // Last modified on Sun Jun  5 21:53:54 EDT 2005 by ken@xorian.net      
00022 //      modified on Tue Jun  3 23:27:05 PDT 2003 by mann@mumblefrotz.org
00023 //      modified on Fri May 30 15:21:40 EDT 2003 by scott@scooter.cx
00024 //
00025 
00026 // Remove a file or directory from the Vesta repository.  Removing an
00027 // object under the appendable root leaves a ghost behind.  Provides
00028 // an alternative to the NFS interface on platforms with obstinate NFS
00029 // client code (e.g. some of the Linux 2.4 series).
00030 
00031 // See documentation in vrm.1.mtex
00032 
00033 #include <Basics.H>
00034 #include <Text.H>
00035 #include <VestaConfig.H>
00036 #include <VestaSource.H>
00037 #include <VDirSurrogate.H>
00038 #include <VestaSourceAtomic.H>
00039 #include <Replicator.H>
00040 #include "ReposUI.H"
00041 
00042 #if !defined(__sun__)
00043 extern "C" {
00044 #include <getopt.h>
00045 }
00046 #endif
00047 
00048 using std::cout;
00049 using std::cerr;
00050 using std::endl;
00051 
00052 Text program_name;
00053 
00054 void usage()
00055 {
00056   cerr << "Usage: " << program_name << " [-R repos] name" << endl << endl;
00057   exit(1);
00058 }
00059 
00060 int
00061 main(int argc, char* argv[])
00062 {
00063   program_name = argv[0];
00064   try {
00065     //
00066     // Read config file
00067     //
00068     Text repos;
00069     bool default_repos = true;
00070 
00071     Text host(VDirSurrogate::defaultHost());
00072     Text port(VDirSurrogate::defaultPort());
00073     const int vlen = 7; // ==strlen("/vesta/")
00074 
00075     //
00076     // Parse command line
00077     //
00078     Text name;
00079 
00080     opterr = 0;
00081     for (;;) {
00082       int c = getopt(argc, argv, "R:");
00083       if (c == EOF) break;
00084       switch (c) {
00085       case 'R':
00086         repos = optarg;
00087         default_repos = false;
00088         break;
00089       case '?':
00090       default:
00091         usage();
00092       }
00093     }
00094     if (argc != optind + 1) {
00095       usage();
00096     }
00097     name = Text(argv[optind]);
00098 
00099     //
00100     // Use a nondefault repository if specified
00101     //
00102     if (!default_repos) {
00103       int colon = repos.FindCharR(':');
00104       if (colon == -1) {
00105         host = repos;
00106         repos = repos + ":" + port;
00107       } else {
00108         host = repos.Sub(0, colon);
00109         port = repos.Sub(colon+1);
00110       }
00111     }
00112 
00113     //
00114     // Qualify and canonicalize name
00115     //
00116     Text cname, cparent, newpart;
00117     cname = ReposUI::canonicalize(name);
00118     ReposUI::split(cname, cparent, newpart, "name");
00119 
00120     //
00121     // Look up parent
00122     //
00123     VestaSource* vs_parent =
00124       ReposUI::filenameToVS(cparent, host, port);
00125 
00126     //
00127     // Do the deed
00128     //
00129     VestaSource::errorCode err;
00130     switch (vs_parent->type) {
00131       case VestaSource::immutableDirectory:
00132         {
00133             // Try to do copy-on-write
00134             VestaSource* newvs;
00135             err = vs_parent->makeMutable(newvs);
00136             if (err != VestaSource::ok) {
00137                 goto finish;
00138             }
00139             delete vs_parent;
00140             vs_parent = newvs;
00141         }
00142         // fall through
00143 
00144       case VestaSource::mutableDirectory:
00145         // Do the deletion
00146         err = vs_parent->reallyDelete(newpart.cchars(), 0, true);
00147         break;
00148         
00149       case VestaSource::appendableDirectory:
00150         // Check that this isn't already a ghost
00151         VestaSource* newvs;
00152         err = vs_parent->lookup(newpart.cchars(), newvs);
00153         if (err != VestaSource::ok) {
00154             goto finish;
00155         }
00156         if (newvs->type == VestaSource::ghost) {
00157             delete newvs;
00158             err = VRErrorCode::noPermission;
00159             goto finish;
00160         }
00161         // Replace with a ghost
00162         VestaSource* ghostvs;
00163         err = vs_parent->insertGhost(newpart.cchars(), newvs->master, 0,
00164                                      VestaSource::replaceDiff, &ghostvs);
00165         delete newvs;
00166         break;
00167         
00168       default:
00169         err = VRErrorCode::notADirectory;
00170         goto finish;
00171     }
00172 
00173   finish:
00174     if (err != VestaSource::ok) {
00175         cerr << program_name << ": " << name << ": "
00176              << ReposUI::errorCodeText(err) << endl;
00177         exit(2);
00178     }
00179     if (vs_parent != NULL) delete vs_parent;
00180 
00181 
00182   } catch (VestaConfig::failure f) {
00183     cerr << program_name << ": " << f.msg << endl;
00184     exit(2);
00185   } catch (SRPC::failure f) {
00186     cerr << program_name
00187          << ": SRPC failure; " << f.msg << " (" << f.r << ")" << endl;
00188     exit(2);
00189   } catch (ReposUI::failure f) {
00190     cerr << program_name << ": " << f.msg << endl;
00191     exit(2);
00192   }
00193 
00194   return 0;
00195 }

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