00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
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;
00074
00075
00076
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
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
00115
00116 Text cname, cparent, newpart;
00117 cname = ReposUI::canonicalize(name);
00118 ReposUI::split(cname, cparent, newpart, "name");
00119
00120
00121
00122
00123 VestaSource* vs_parent =
00124 ReposUI::filenameToVS(cparent, host, port);
00125
00126
00127
00128
00129 VestaSource::errorCode err;
00130 switch (vs_parent->type) {
00131 case VestaSource::immutableDirectory:
00132 {
00133
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
00143
00144 case VestaSource::mutableDirectory:
00145
00146 err = vs_parent->reallyDelete(newpart.cchars(), 0, true);
00147 break;
00148
00149 case VestaSource::appendableDirectory:
00150
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
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 }