XRootD
Loading...
Searching...
No Matches
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"
43#include "XrdOss/XrdOss.hh"
44#include "XrdOss/XrdOssPath.hh"
47
48using namespace XrdFrc;
49using 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
73int XrdFrmAdmin::Unlink(const char *Path)
74{
75 static const int ulOpts = XRDOSS_Online | XRDOSS_isPFN;
76 XrdOucNSWalk::NSEnt *fP;
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
155int XrdFrmAdmin::UnlinkDir(const char *Path, const char *lclPath)
156{
157 static const int ulOpts = XRDOSS_Online | XRDOSS_isPFN;
158 XrdFrmAdminNSE NSE;
159 XrdOucNSWalk::NSEnt *fP;
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
209int XrdFrmAdmin::UnlinkDir(XrdOucNSWalk::NSEnt *&nP, XrdOucNSWalk::NSEnt *&dP)
210{
211
212 XrdOucNSWalk::NSEnt *fP;
213 int retval = 1;
214
215// Remove each entry but remember any directories
216//
217 while((fP = nP))
218 {nP = fP->Next;
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
235int 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
XrdOucPup XrdCmsParser::Pup & Say
#define XRDOSS_isPFN
Definition XrdOss.hh:469
#define XRDOSS_Online
Definition XrdOss.hh:468
#define XRDOSS_isMIG
Definition XrdOss.hh:470
#define unlink(a)
Definition XrdPosix.hh:108
#define stat(a, b)
Definition XrdPosix.hh:96
XrdOucString Path
static char Ask(char dflt, const char *Msg1, const char *Msg2="", const char *Msg3="")
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
XrdNetCmsNotify * cmsPath
XrdOss * ossFS
int LocalPath(const char *oldp, char *newp, int newpsz)
const char * lockFN
int Gone(const char *Path, int isPfn=1)
static theSfx pathType(const char *Path, int chkWhat=chkAll)
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)
static const int Recurse
XrdFrmConfig Config
struct NSEnt * Next