XRootD
XrdFrmAdminUnlink.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d F r m A d m i n U n l i n k . c c */
4 /* */
5 /* (c) 2009 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <cerrno>
32 #include <fcntl.h>
33 #include <sys/param.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 
37 #include "XrdFrc/XrdFrcTrace.hh"
38 #include "XrdFrc/XrdFrcUtils.hh"
39 #include "XrdFrm/XrdFrmAdmin.hh"
40 #include "XrdFrm/XrdFrmCns.hh"
41 #include "XrdFrm/XrdFrmConfig.hh"
43 #include "XrdOss/XrdOss.hh"
44 #include "XrdOss/XrdOssPath.hh"
45 #include "XrdOuc/XrdOucNSWalk.hh"
46 #include "XrdSys/XrdSysPlatform.hh"
47 
48 using namespace XrdFrc;
49 using namespace XrdFrm;
50 
51 /******************************************************************************/
52 /* L o c a l C l a s s e s */
53 /******************************************************************************/
54 
56 {public:
57 
60 
61  XrdFrmAdminNSE() : nP(0), dP(0), nsP(0) {}
63  while((fP = dP)) {dP = dP->Next; delete fP;}
64  while((fP = nP)) {nP = nP->Next; delete fP;}
65  if (nsP) delete nsP;
66  }
67 };
68 
69 /******************************************************************************/
70 /* U n l i n k */
71 /******************************************************************************/
72 
73 int XrdFrmAdmin::Unlink(const char *Path)
74 {
75  static const int ulOpts = XRDOSS_Online | XRDOSS_isPFN;
77  XrdFrmAdminNSE NSE;
78  struct stat Stat;
79  char Resp, lclPath[MAXPATHLEN+8];
80  int aOK = 1, rc;
81 
82 // Get the actual pfn for the base file
83 //
84  if (!Config.LocalPath(Path, lclPath, sizeof(lclPath)-8))
85  {numProb++; return -1;}
86 
87 // Make sure the base file exists
88 //
89  if (stat(lclPath, &Stat))
90  {Emsg(errno,"remove ",lclPath); numProb++; return -1;}
91 
92 // Check if the file is actually a directory or a plain file
93 //
94  if ((Stat.st_mode & S_IFMT) != S_IFDIR)
95  {if (Opt.All) {Emsg(ENOTDIR, "remove ", Path); numProb++; return -1;}
96  return UnlinkFile(lclPath);
97  }
98 
99 // This is a directory, see if a non-recursive delete wanted
100 //
101  if (!Opt.Recurse) return UnlinkDir(Path, lclPath);
102 
103 // Get confirmation unless not wanted
104 //
105  if (!Opt.Force)
106  {Resp = XrdFrcUtils::Ask('n', "Remove EVERYTHING starting at ",Path,"?");
107  if (Resp != 'y') return Resp != 'a';
108  }
109 
110 // Create the name space object to return the contents of each directory
111 //
112  NSE.nsP = new XrdOucNSWalk(&Say, lclPath, 0, XrdOucNSWalk::Recurse
114 
115 // Process each directory
116 //
117  while((NSE.nP = NSE.nsP->Index(rc)) && !rc)
118  {if ((rc = UnlinkDir(NSE.nP, NSE.dP)) < 0) break;
119  rc = 0;
120  }
121  aOK = !rc;
122 
123 // Check if we can now delete the directories
124 //
125  while((fP = NSE.dP))
126  {if (aOK)
127  {if ((rc = Config.ossFS->Remdir(fP->Path, ulOpts)))
128  {Emsg(-rc, "remove directory ", fP->Path); aOK = 0; numProb++;}
129  else {if (Opt.Echo) Msg("Local directory ",fP->Path," removed.");
130  numDirs++; XrdFrmCns::Rmd(fP->Path);
131  }
132  }
133  NSE.dP = NSE.dP->Next; delete fP;
134  }
135 
136 // Now remove the base directory
137 //
138  if (aOK)
139  {if ((rc = Config.ossFS->Remdir(lclPath, ulOpts)))
140  {Emsg(-rc, "remove directory ", lclPath); aOK = 0;}
141  else {numDirs++; XrdFrmCns::Rmd(Path, 1);
142  if (Opt.Echo) Msg("Local directory ", lclPath, " removed.");
143  }
144  }
145 
146 // All done
147 //
148  return aOK ? 1 : -1;
149 }
150 
151 /******************************************************************************/
152 /* U n l i n k D i r */
153 /******************************************************************************/
154 
155 int XrdFrmAdmin::UnlinkDir(const char *Path, const char *lclPath)
156 {
157  static const int ulOpts = XRDOSS_Online | XRDOSS_isPFN;
158  XrdFrmAdminNSE NSE;
160  char Resp;
161  int rc;
162 
163 // Create the name space object to return the contents of each directory
164 //
165  NSE.nsP = new XrdOucNSWalk(&Say, lclPath, 0, XrdOucNSWalk::retAll
167 
168 // Get the entries in this directory
169 //
170  NSE.nP = NSE.nsP->Index(rc);
171  if (rc) {numProb++; return -1;}
172 
173 // If the only entry is the DIR_LOCK file then we can remove it and the
174 // directory without asking
175 //
176  if (!Opt.All)
177  {if (NSE.nP && !NSE.nP->Next && !strcmp(Config.lockFN, NSE.nP->Path))
178  if (unlink(NSE.nP->Path)) {Emsg(-rc, "remove ", lclPath); return -1;}
179  if ((rc = Config.ossFS->Remdir(lclPath, ulOpts)))
180  {Emsg(-rc, "remove directory ", lclPath); numProb++; return -1;}
181  if (Opt.Echo) Msg("Local directory ", Path, " removed.");
182  numDirs++; XrdFrmCns::Rmd(lclPath);
183  return 1;
184  }
185 
186 // Run through the list looking to see if we have any directories
187 //
188  fP = NSE.nP;
189  while(fP)
190  {if (fP->Type != XrdOucNSWalk::NSEnt::isDir) fP = fP->Next;
191  else {Emsg(EISDIR, "remove ", fP->Path); numProb++; return -1;}
192  }
193 
194 // If neither 'all' nor 'force' not specified, then we must ask for permission
195 //
196  if (!Opt.Force)
197  {Resp = XrdFrcUtils::Ask('n', "Remove EVERYTHING in ",Path,"?");
198  if (Resp != 'y') return Resp != 'a';
199  }
200 
201 // Remove all items in this directory
202 //
203  if ((rc = UnlinkDir(NSE.nP, NSE.dP)) < 0) return -1;
204  return 1;
205 }
206 
207 /******************************************************************************/
208 
209 int XrdFrmAdmin::UnlinkDir(XrdOucNSWalk::NSEnt *&nP, XrdOucNSWalk::NSEnt *&dP)
210 {
211 
213  int retval = 1;
214 
215 // Remove each entry but remember any directories
216 //
217  while((fP = nP))
218  {nP = fP->Next;
219  if (fP->Type == XrdOucNSWalk::NSEnt::isDir)
220  {fP->Next = dP; dP = fP;}
221  else {if (UnlinkFile(fP->Path) < 0) retval = -1;
222  delete fP;
223  }
224  }
225 
226 // All done
227 //
228  return retval;
229 }
230 
231 /******************************************************************************/
232 /* U n l i n k F i l e */
233 /******************************************************************************/
234 
235 int XrdFrmAdmin::UnlinkFile(const char *lclPath)
236 {
237  static const int ulOpts = XRDOSS_Online | XRDOSS_isMIG | XRDOSS_isPFN;
238  int rc;
239 
240 // Remove this file as needed
241 //
242  if (XrdOssPath::pathType(lclPath))
243  {if (!unlink(lclPath) || errno == ENOENT) return 1;
244  rc = -errno;
245  } else {
246  if (!(rc = Config.ossFS->Unlink(lclPath, ulOpts)))
247  {if (Opt.Echo) Msg("Local file ", lclPath, " removed.");
248  if (Config.cmsPath) Config.cmsPath->Gone(lclPath);
249  numFiles++; XrdFrmCns::Rm(lclPath);
250  return 1;
251  }
252  }
253 
254 // Unlink failed
255 //
256  Emsg(-rc, "remove ", lclPath);
257  numProb++;
258  return -1;
259 }
struct stat Stat
Definition: XrdCks.cc:49
#define XRDOSS_isPFN
Definition: XrdOss.hh:469
#define XRDOSS_Online
Definition: XrdOss.hh:468
#define XRDOSS_isMIG
Definition: XrdOss.hh:470
int stat(const char *path, struct stat *buf)
int unlink(const char *path)
XrdOucString Path
XrdOss * ossFS
static char Ask(char dflt, const char *Msg1, const char *Msg2="", const char *Msg3="")
Definition: XrdFrcUtils.cc:56
XrdOucNSWalk * nsP
XrdOucNSWalk::NSEnt * dP
XrdOucNSWalk::NSEnt * nP
static void Rmd(const char *Path, int islfn=0)
Definition: XrdFrmCns.hh:56
static void Rm(const char *Path, int islfn=0)
Definition: XrdFrmCns.hh:53
static theSfx pathType(const char *Path, int chkWhat=chkAll)
Definition: XrdOssPath.cc:278
virtual int Remdir(const char *path, int Opts=0, XrdOucEnv *envP=0)=0
virtual int Unlink(const char *path, int Opts=0, XrdOucEnv *envP=0)=0
static const int retAll
static const int retStat
NSEnt * Index(int &rc, const char **dPath=0)
Definition: XrdOucNSWalk.cc:93
static const int Recurse
XrdCmsConfig Config
XrdSysError Say
struct NSEnt * Next
Definition: XrdOucNSWalk.hh:48