49 const char *lkfn,
int opts,
57 if (lkfn) LKFn = strdup(lkfn);
67 if (!xlist) XList = 0;
84 while((tP = DList)) {DList = tP->
next;
delete tP;}
86 while((tP = XList)) {XList = tP->
next;
delete tP;}
100 rc = 0; *DPath =
'\0';
103 DList = tP->
next;
delete tP;
104 if (LKFn && (rc = LockFile()))
break;
106 if (LKfd >= 0)
close(LKfd);
107 if (DEnts || (rc && !errOK))
break;
108 if (edCB && isEmpty) edCB->
isEmpty(&dStat, DPath, LKFn);
113 eP = DEnts; DEnts = 0;
114 if (dPath) *dPath = DPath;
132 else {eP->
Path = strdup(DPath);
133 eP->
File = eP->
Path + (File - DPath);
139 if (!(Opts & retIxLO)) {eP->
Next = DEnts; DEnts = eP;}
140 else {NSEnt *pP = 0, *nP = DEnts;
142 while(nP && eP->
Plen < nP->Plen) {pP = nP; nP = nP->
Next;}
144 while(nP && eP->
Plen > nP->Plen) {pP = nP; nP = nP->
Next;}
145 if (pP) {eP->
Next = nP; pP->
Next = eP;}
146 else {eP->
Next = nP; DEnts = eP;}
154 int XrdOucNSWalk::Build()
159 Helper() : P(0), D(0), F(-1) {}
160 ~Helper() {
if (P)
delete P;
167 int nEnt = 0, xLKF = 0, chkED = (edCB != 0) && (LKFn != 0);
176 if ((DPfd =
open(DPath, O_RDONLY)) < 0) rc = errno;
177 else theEnt.F = DPfd;
184 if (!(theEnt.D =
opendir(DPath)))
185 return Emsg(
"Build", errno,
"open directory", DPath);
190 while((dp =
readdir(theEnt.D)))
191 {
if (!strcmp(dp->d_name,
".") || !strcmp(dp->d_name,
".."))
continue;
192 strcpy(
File, dp->d_name); nEnt++;
193 if (!theEnt.P) theEnt.P =
new NSEnt();
194 rc = getStat(theEnt.P, getLI);
195 switch(theEnt.P->Type)
198 && (!XList || !inXList(
File)))
203 if ((chkED && !xLKF && (xLKF = !strcmp(
File, LKFn)))
207 if ((rc = getLink(theEnt.P)))
208 memset(&theEnt.P->Stat, 0,
sizeof(
struct stat));
209 else if ((
Opts &
retStat) && (rc = getStat(theEnt.P)))
216 if (!rc) rc = EINVAL;
220 if (rc) {
if (errOK)
continue;
return rc;}
221 addEnt(theEnt.P); theEnt.P = 0;
227 if ((rc = errno) && !errOK)
228 return Emsg(
"Build", rc,
"read directory", DPath);
232 if (edCB && xLKF == nEnt && !DEnts)
233 {
if ((DPfd < 0 ? !
stat(DPath, &dStat) : !
fstat(DPfd, &dStat))) isEmpty=1;
234 else Emsg(
"Build", errno,
"stat directory", DPath);
243 int XrdOucNSWalk::Emsg(
const char *pfx,
int rc,
const char *txt1,
249 std::cerr <<mPfx <<
": Unable to " <<txt1;
250 if (txt2) std::cerr <<
' ' <<txt2;
251 std::cerr <<
"; " <<(etxt) <<
"\n" << std::flush;
265 if ((rc = readlink(DPath, lnkbuff,
sizeof(lnkbuff))) < 0)
266 return Emsg(
"getLink", errno,
"read link of", DPath);
269 eP->
Link = (
char *)malloc(rc+1);
270 memcpy(eP->
Link, lnkbuff, rc);
271 *(eP->
Link+rc) =
'\0';
286 do{rc = fstatat(DPfd,
File, &(eP->
Stat), (doLstat ? AT_SYMLINK_NOFOLLOW : 0));
290 }
while(rc && errno == EINTR);
296 if (rc != ENOENT && rc != ELOOP) Emsg(
"getStat", rc,
"stat", DPath);
297 memset(&eP->
Stat, 0,
sizeof(
struct stat));
316 int XrdOucNSWalk::inXList(
const char *dName)
322 while(xTP && strcmp(DPath, xTP->
text)) {pTP = xTP; xTP = xTP->
next;}
328 else XList = xTP->
next;
337 int XrdOucNSWalk::isSymlink()
346 do{rc = fstatat(DPfd,
File, &buf, AT_SYMLINK_NOFOLLOW);
348 do{rc =
lstat(DPath, &buf);
350 }
while(rc && errno == EINTR);
355 return (buf.st_mode & S_IFMT) == S_IFLNK;
362 int XrdOucNSWalk::LockFile()
370 do {LKfd =
open(DPath, O_RDWR);}
while(LKfd < 0 && errno == EINTR);
372 {
if (errno == ENOENT) {*
File =
'\0';
return 0;}
374 return Emsg(
"LockFile", errno,
"open", DPath);
380 bzero(&lock_args,
sizeof(lock_args));
381 lock_args.l_type = F_WRLCK;
385 do {rc =
fcntl(LKfd,F_SETLKW,&lock_args);}
386 while(rc < 0 && errno == EINTR);
387 if (rc < 0) rc = Emsg(
"LockFile", errno,
"lock", DPath);
399 void XrdOucNSWalk::setPath(
char *newpath)
403 strcpy(DPath, newpath);
405 if (DPath[n-1] !=
'/')
406 {DPath[n++] =
'/'; DPath[n] =
'\0';}
static XrdSysError eDest(0,"crypto_")
int stat(const char *path, struct stat *buf)
struct dirent * readdir(DIR *dirp)
int open(const char *path, int oflag,...)
int fstat(int fildes, struct stat *buf)
int lstat(const char *path, struct stat *buf)
int fcntl(int fd, int cmd,...)
DIR * opendir(const char *path)
const char * XrdSysE2T(int errcode)
virtual void isEmpty(struct stat *dStat, const char *dPath, const char *lkFn)=0
XrdOucNSWalk(XrdSysError *erp, const char *dname, const char *LKfn=0, int opts=retAll, XrdOucTList *xP=0)
NSEnt * Index(int &rc, const char **dPath=0)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)