00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 const char *XrdFrmAdminUnlinkCVSID = "$Id: XrdFrmAdminUnlink.cc 35287 2010-09-14 21:19:35Z ganis $";
00014
00015 #include <errno.h>
00016 #include <fcntl.h>
00017 #include <sys/param.h>
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020
00021 #include "XrdFrm/XrdFrmAdmin.hh"
00022 #include "XrdFrm/XrdFrmConfig.hh"
00023 #include "XrdFrm/XrdFrmTrace.hh"
00024 #include "XrdFrm/XrdFrmUtils.hh"
00025 #include "XrdNet/XrdNetCmsNotify.hh"
00026 #include "XrdOss/XrdOss.hh"
00027 #include "XrdOss/XrdOssPath.hh"
00028 #include "XrdOuc/XrdOucNSWalk.hh"
00029
00030 using namespace XrdFrm;
00031
00032
00033
00034
00035
00036 class XrdFrmAdminNSE
00037 {public:
00038
00039 XrdOucNSWalk::NSEnt *nP, *dP;
00040 XrdOucNSWalk *nsP;
00041
00042 XrdFrmAdminNSE() : nP(0), dP(0), nsP(0) {}
00043 ~XrdFrmAdminNSE() {XrdOucNSWalk::NSEnt *fP;
00044 while((fP = dP)) {dP = dP->Next; delete fP;}
00045 while((fP = nP)) {nP = nP->Next; delete fP;}
00046 if (nsP) delete nsP;
00047 }
00048 };
00049
00050
00051
00052
00053
00054 int XrdFrmAdmin::Unlink(const char *Path)
00055 {
00056 static const int ulOpts = XRDOSS_Online | XRDOSS_isPFN;
00057 XrdOucNSWalk::NSEnt *fP;
00058 XrdFrmAdminNSE NSE;
00059 struct stat Stat;
00060 char Resp, lclPath[MAXPATHLEN+8];
00061 int aOK = 1, rc;
00062
00063
00064
00065 if (!Config.LocalPath(Path, lclPath, sizeof(lclPath)-8))
00066 {numProb++; return -1;}
00067
00068
00069
00070 if (stat(lclPath, &Stat))
00071 {Emsg(errno,"remove ",lclPath); numProb++; return -1;}
00072
00073
00074
00075 if ((Stat.st_mode & S_IFMT) != S_IFDIR)
00076 {if (Opt.All) {Emsg(ENOTDIR, "remove ", Path); numProb++; return -1;}
00077 return UnlinkFile(lclPath);
00078 }
00079
00080
00081
00082 if (!Opt.Recurse) return UnlinkDir(Path, lclPath);
00083
00084
00085
00086 if (!Opt.Force)
00087 {Resp = XrdFrmUtils::Ask('n', "Remove EVERYTHING starting at ",Path,"?");
00088 if (Resp != 'y') return Resp != 'a';
00089 }
00090
00091
00092
00093 NSE.nsP = new XrdOucNSWalk(&Say,lclPath,Config.lockFN,XrdOucNSWalk::Recurse
00094 |XrdOucNSWalk::retAll | XrdOucNSWalk::retStat);
00095
00096
00097
00098 while((NSE.nP = NSE.nsP->Index(rc)) && !rc)
00099 {if ((rc = UnlinkDir(NSE.nP, NSE.dP)) < 0) break;
00100 rc = 0;
00101 }
00102 aOK = !rc;
00103
00104
00105
00106 while((fP = NSE.dP))
00107 {if (aOK)
00108 {if ((rc = Config.ossFS->Remdir(fP->Path, ulOpts)))
00109 {Emsg(-rc, "remove directory ", fP->Path); aOK = 0; numProb++;}
00110 else {if (Opt.Echo) Msg("Local directory ",fP->Path," removed.");
00111 numDirs++;
00112 }
00113 }
00114 NSE.dP = NSE.dP->Next; delete fP;
00115 }
00116
00117
00118
00119 if (aOK)
00120 {if ((rc = Config.ossFS->Remdir(lclPath, ulOpts)))
00121 {Emsg(-rc, "remove directory ", lclPath); aOK = 0;}
00122 else {numDirs++;
00123 if (Opt.Echo) Msg("Local directory ", lclPath, " removed.");
00124 }
00125 }
00126
00127
00128
00129 return aOK ? 1 : -1;
00130 }
00131
00132
00133
00134
00135
00136 int XrdFrmAdmin::UnlinkDir(const char *Path, const char *lclPath)
00137 {
00138 static const int ulOpts = XRDOSS_Online | XRDOSS_isPFN;
00139 XrdFrmAdminNSE NSE;
00140 XrdOucNSWalk::NSEnt *fP;
00141 char Resp;
00142 int rc;
00143
00144
00145
00146 NSE.nsP = new XrdOucNSWalk(&Say, lclPath, Config.lockFN,
00147 XrdOucNSWalk::retAll | XrdOucNSWalk::retStat);
00148
00149
00150
00151 NSE.nP = NSE.nsP->Index(rc);
00152 if (rc) {numProb++; return -1;}
00153
00154
00155
00156
00157 if (!Opt.All)
00158 {if (NSE.nP && !NSE.nP->Next && !strcmp(Config.lockFN, NSE.nP->Path))
00159 if (unlink(NSE.nP->Path)) {Emsg(-rc, "remove ", lclPath); return -1;}
00160 if ((rc = Config.ossFS->Remdir(lclPath, ulOpts)))
00161 {Emsg(-rc, "remove directory ", lclPath); numProb++; return -1;}
00162 if (Opt.Echo) Msg("Local directory ", Path, " removed.");
00163 numDirs++;
00164 return 1;
00165 }
00166
00167
00168
00169 fP = NSE.nP;
00170 while(fP)
00171 {if (fP->Type != XrdOucNSWalk::NSEnt::isDir) fP = fP->Next;
00172 else {Emsg(EISDIR, "remove ", fP->Path); numProb++; return -1;}
00173 }
00174
00175
00176
00177 if (!Opt.Force)
00178 {Resp = XrdFrmUtils::Ask('n', "Remove EVERYTHING in ",Path,"?");
00179 if (Resp != 'y') return Resp != 'a';
00180 }
00181
00182
00183
00184 if ((rc = UnlinkDir(NSE.nP, NSE.dP)) < 0) return -1;
00185 return 1;
00186 }
00187
00188
00189
00190 int XrdFrmAdmin::UnlinkDir(XrdOucNSWalk::NSEnt *&nP, XrdOucNSWalk::NSEnt *&dP)
00191 {
00192
00193 XrdOucNSWalk::NSEnt *fP;
00194 int retval = 1;
00195
00196
00197
00198 while((fP = nP))
00199 {nP = fP->Next;
00200 if (fP->Type == XrdOucNSWalk::NSEnt::isDir)
00201 {fP->Next = dP; dP = fP;}
00202 else {if (UnlinkFile(fP->Path) < 0) retval = -1;
00203 delete fP;
00204 }
00205 }
00206
00207
00208
00209 return retval;
00210 }
00211
00212
00213
00214
00215
00216 int XrdFrmAdmin::UnlinkFile(const char *lclPath)
00217 {
00218 static const int ulOpts = XRDOSS_Online | XRDOSS_isMIG | XRDOSS_isPFN;
00219 int rc;
00220
00221
00222
00223 if (XrdOssPath::pathType(lclPath))
00224 {if (!unlink(lclPath) || errno == ENOENT) return 1;
00225 rc = -errno;
00226 } else {
00227 if (!(rc = Config.ossFS->Unlink(lclPath, ulOpts)))
00228 {if (Opt.Echo) Msg("Local file ", lclPath, " removed.");
00229 if (Config.cmsPath) Config.cmsPath->Gone(lclPath);
00230 numFiles++;
00231 return 1;
00232 }
00233 }
00234
00235
00236
00237 Emsg(-rc, "remove ", lclPath);
00238 numProb++;
00239 return -1;
00240 }