XrdFrmAdminUnlink.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                  X r d F r m A d m i n U n l i n k . c c                   */
00004 /*                                                                            */
00005 /* (c) 2009 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //         $Id: XrdFrmAdminUnlink.cc 35287 2010-09-14 21:19:35Z ganis $
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 /*                         L o c a l   C l a s s e s                          */
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 /*                                U n l i n k                                 */
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 // Get the actual pfn for the base file
00064 //
00065    if (!Config.LocalPath(Path, lclPath, sizeof(lclPath)-8))
00066       {numProb++; return -1;}
00067 
00068 // Make sure the base file exists
00069 //
00070    if (stat(lclPath, &Stat))
00071       {Emsg(errno,"remove ",lclPath); numProb++; return -1;}
00072 
00073 // Check if the file is actually a directory or a plain file
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 // This is a directory, see if a non-recursive delete wanted
00081 //
00082    if (!Opt.Recurse) return UnlinkDir(Path, lclPath);
00083 
00084 // Get confirmation unless not wanted
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 // Create the name space object to return the contents of each directory
00092 //
00093    NSE.nsP = new XrdOucNSWalk(&Say,lclPath,Config.lockFN,XrdOucNSWalk::Recurse
00094                              |XrdOucNSWalk::retAll | XrdOucNSWalk::retStat);
00095 
00096 // Process each directory
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 // Check if we can now delete the directories
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 // Now remove the base directory
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 // All done
00128 //
00129    return aOK ? 1 : -1;
00130 }
00131 
00132 /******************************************************************************/
00133 /*                             U n l i n k D i r                              */
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 // Create the name space object to return the contents of each directory
00145 //
00146    NSE.nsP = new XrdOucNSWalk(&Say, lclPath, Config.lockFN,
00147                               XrdOucNSWalk::retAll | XrdOucNSWalk::retStat);
00148 
00149 // Get the entries in this directory
00150 //
00151    NSE.nP = NSE.nsP->Index(rc);
00152    if (rc) {numProb++; return -1;}
00153 
00154 // If the only entry is the DIR_LOCK file then we can remove it and the
00155 // directory without asking
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 // Run through the list looking to see if we have any directories
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 // If neither 'all' nor 'force' not specified, then we must ask for permission
00176 //
00177    if (!Opt.Force)
00178       {Resp = XrdFrmUtils::Ask('n', "Remove EVERYTHING in ",Path,"?");
00179        if (Resp != 'y') return Resp != 'a';
00180       }
00181                                                                                
00182 // Remove all items in this directory
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 // Remove each entry but remember any directories
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 // All done
00208 //
00209    return retval;
00210 }
00211 
00212 /******************************************************************************/
00213 /*                            U n l i n k F i l e                             */
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 // Remove this file as needed
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 // Unlink failed
00236 //
00237    Emsg(-rc, "remove ", lclPath);
00238    numProb++;
00239    return -1;
00240 }

Generated on Tue Jul 5 14:46:35 2011 for ROOT_528-00b_version by  doxygen 1.5.1