XRootD
Loading...
Searching...
No Matches
XrdDigDirectory Class Reference

#include <XrdDigFS.hh>

+ Inheritance diagram for XrdDigDirectory:
+ Collaboration diagram for XrdDigDirectory:

Public Member Functions

 XrdDigDirectory (char *user=0, int monid=0)
 
 ~XrdDigDirectory ()
 
int autoStat (struct stat *buf)
 
int close ()
 
const char * FName ()
 
const char * nextEntry ()
 
int open (const char *dirName, const XrdSecClientName *client=0, const char *opaque=0)
 
- Public Member Functions inherited from XrdSfsDirectory
 XrdSfsDirectory (const char *user=0, int MonID=0)
 
 XrdSfsDirectory (XrdOucErrInfo &eInfo)
 
 XrdSfsDirectory (XrdSfsDirectory &wrapD)
 
virtual ~XrdSfsDirectory ()
 Destructor.
 
virtual int open (const char *path, const XrdSecEntity *client=0, const char *opaque=0)=0
 

Additional Inherited Members

- Public Attributes inherited from XrdSfsDirectory
XrdOucErrInfoerror
 

Detailed Description

Definition at line 45 of file XrdDigFS.hh.

Constructor & Destructor Documentation

◆ XrdDigDirectory()

XrdDigDirectory::XrdDigDirectory ( char * user = 0,
int monid = 0 )
inline

Definition at line 61 of file XrdDigFS.hh.

62 : XrdSfsDirectory(user, monid),
63 dh((DIR *)0), fname(0), sBuff(0),
64 d_pnt(&dirent_full.d_entry),
65 dirFD(-1), ateof(false),
66 isProc(false), isBase(false) {}
XrdSfsDirectory(const char *user=0, int MonID=0)

◆ ~XrdDigDirectory()

XrdDigDirectory::~XrdDigDirectory ( )
inline

Definition at line 68 of file XrdDigFS.hh.

68{if (dh) close();}

References close().

+ Here is the call graph for this function:

Member Function Documentation

◆ autoStat()

int XrdDigDirectory::autoStat ( struct stat * buf)
inlinevirtual

Set the stat() buffer where stat information is to be placed corresponding to the directory entry returned by nextEntry().

Returns
If supported, SFS_OK should be returned. If not supported, then SFS_ERROR should be returned with error.code set to ENOTSUP.
Note
: When autoStat() is in effect, directory entries that have been deleted from the target directory are quietly skipped.

Reimplemented from XrdSfsDirectory.

Definition at line 59 of file XrdDigFS.hh.

59{sBuff = buf; return SFS_OK;}
#define SFS_OK

References SFS_OK.

◆ close()

int XrdDigDirectory::close ( )
virtual

Close the directory.

Returns
One of SFS_OK or SFS_ERROR

Implements XrdSfsDirectory.

Definition at line 314 of file XrdDigFS.cc.

322{
323 static const char *epname = "closedir";
324
325// Release the handle
326//
327 sBuff = 0;
328 if (dh && closedir(dh))
329 {XrdDigFS::Emsg(epname, error, errno, "close directory", fname);
330 return SFS_ERROR;
331 }
332
333// Do some clean-up
334//
335 if (fname) {free(fname); fname = 0;}
336 dh = (DIR *)0;
337 isProc = isBase = false;
338 return SFS_OK;
339}
#define closedir(a)
Definition XrdPosix.hh:50
#define SFS_ERROR
static int Emsg(const char *, XrdOucErrInfo &, int, const char *x, const char *y="")
Definition XrdDigFS.cc:605
XrdOucErrInfo & error

References closedir, XrdDigFS::Emsg(), XrdSfsDirectory::error, SFS_ERROR, and SFS_OK.

Referenced by ~XrdDigDirectory().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ FName()

const char * XrdDigDirectory::FName ( )
inlinevirtual

Get the directory path.

Returns
Null terminated string of the path used in open().

Implements XrdSfsDirectory.

Definition at line 57 of file XrdDigFS.hh.

57{return (const char *)fname;}

◆ nextEntry()

const char * XrdDigDirectory::nextEntry ( )
virtual

Get the next directory entry.

Returns
A null terminated string with the directory name. Normally, "." ".." are not returned. If a null pointer is returned then if this is due to an error, error.code should contain errno. Otherwise, error.code should contain zero to indicate that no more entries exist (i.e. end of list). See autoStat() for additional caveats.

Implements XrdSfsDirectory.

Definition at line 204 of file XrdDigFS.cc.

215{
216 static const char *epname = "nextEntry";
217 static const int wMask = ~(S_IWUSR | S_IWGRP | S_IWOTH);
218 struct dirent *rp;
219 int retc;
220
221// Check for base listing
222//
223 if (isBase)
224 {if (dirFD > 0) return dirent_full.aEnt[--dirFD];
225 ateof = true;
226 return (const char *)0;
227 }
228
229// Lock the direcrtory and do any required tracing
230//
231 if (!dh)
232 {XrdDigFS::Emsg(epname,error,EBADF,"read directory",fname);
233 return (const char *)0;
234 }
235
236// Check if we are at EOF (once there we stay there)
237//
238 if (ateof) return (const char *)0;
239
240// Read the next directory entry
241//
242#if defined(__linux__) || defined(__GNU__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
243do{errno = 0;
244 rp = readdir(dh);
245 if (!rp)
246 {if (!(retc = errno)) {ateof = 1; error.clear();}
247 else XrdDigFS::Emsg(epname,error,retc,"read directory",fname);
248 d_pnt->d_name[0] = '\0';
249 return (const char *)0;
250 }
251#else
252do{if ((retc = readdir_r(dh, d_pnt, &rp)))
253 {XrdDigFS::Emsg(epname,error,retc,"read directory",fname);
254 d_pnt->d_name[0] = '\0';
255 return (const char *)0;
256 }
257
258// Check if we have reached end of file
259//
260 if (!rp || !d_pnt->d_name[0])
261 {ateof = true;
262 error.clear();
263 return (const char *)0;
264 }
265#endif
266
267// If autostat wanted, do so here
268//
269 if (sBuff)
270 {
271#ifdef HAVE_FSTATAT
272 int sFlags = (isProc ? AT_SYMLINK_NOFOLLOW : 0);
273 if (fstatat(dirFD, rp->d_name, sBuff, sFlags)) continue;
274 sBuff->st_mode = (sBuff->st_mode & wMask) | S_IRUSR;
275#else
276 char dPath[2048];
277 snprintf(dPath, sizeof(dPath), "%s%s", fname, rp->d_name);
278 if (stat(dPath, sBuff)) continue;
279 sBuff->st_mode = (sBuff->st_mode & wMask) | S_IRUSR;
280#endif
281 }
282
283// We want to extend the directory entry information with symlink information
284// if this is a symlink. This is only done for /proc (Linux only)
285//
286#ifdef __linux__
287 if (isProc)
288 {struct stat Stat, *sP = (sBuff ? sBuff : &Stat);
289 char *dP;
290 int n, rc;
291 rc = (sBuff ? 0:fstatat(dirFD,rp->d_name,&Stat,AT_SYMLINK_NOFOLLOW));
292 if (!rc && !noTag && S_ISLNK(sP->st_mode))
293 {n = strlen(rp->d_name);
294 dP = rp->d_name + n + 4;
295 n = sizeof(dirent_full.nbf) - (n + 8);
296 if ((n = readlinkat(dirFD,rp->d_name,dP,n)) < 0) strcpy(dP,"?");
297 else *(dP+n) = 0;
298 memcpy(dP-4, " -> ", 4);
299 }
300 }
301#endif
302
303// Return the actual entry
304//
305 return (const char *)(rp->d_name);
306 } while(1);
307 return 0; // Keep compiler happy
308}
struct stat Stat
Definition XrdCks.cc:49
#define readdir_r(a, b, c)
Definition XrdPosix.hh:89
#define stat(a, b)
Definition XrdPosix.hh:101
#define readdir(a)
Definition XrdPosix.hh:86
void clear()
Reset data and error information to null. Any appenadges are released.

References XrdOucErrInfo::clear(), XrdDigFS::Emsg(), XrdSfsDirectory::error, readdir, readdir_r, Stat, and stat.

+ Here is the call graph for this function:

◆ open()

int XrdDigDirectory::open ( const char * dirName,
const XrdSecClientName * client = 0,
const char * opaque = 0 )

Definition at line 135 of file XrdDigFS.cc.

147{
148 static const char *epname = "opendir";
149 int retc;
150
151// Verify that this object is not already associated with an open directory
152//
153 if (dh || isBase) return XrdDigFS::Emsg(epname, error, EADDRINUSE,
154 "open directory", dir_path);
155
156// Check if we are trying to open the root to list it
157//
158 if (!strcmp(dir_path, SFS_LCLPRFX) || !strcmp(dir_path, SFS_LCLPRFY))
159 {isBase = true;
160 if ((dirFD = Config.GenAccess(client, dirent_full.aEnt, aESZ)) < 0)
161 return XrdDigFS::Emsg(epname,error,EACCES,"open directory",dir_path);
162 ateof = dirFD == 0;
163 return SFS_OK;
164 }
165
166// Authorize this open and get actual file name to open
167//
168 if ( (retc = XrdDigFS::Validate(dir_path))
169 || !(fname = Config.GenPath(retc, client, "opendir",
171 return XrdDigFS::Emsg(epname,error,retc,"open directory",dir_path);
172
173// Set up values for this directory object
174//
175 ateof = false;
176
177// Open the directory and get it's id
178//
179 if (!(dh = opendir(fname)))
180 {if (fname) {free(fname); fname = 0;}
181 return XrdDigFS::Emsg(epname,error,errno,"open directory",dir_path);
182 }
183
184// Check if this is a reference to /proc (Linux only)
185//
186#ifdef __linux__
187 if (IS_PROC(dir_path))
188 {noTag = *(dir_path+SFS_LCLPLEN+4) == 0
189 || !strcmp(dir_path+SFS_LCLPLEN+4, "/");
190 isProc = true;
191 dirFD = dirfd(dh);
192 }
193#endif
194
195// All done
196//
197 return SFS_OK;
198}
#define opendir(a)
Definition XrdPosix.hh:78
#define SFS_LCLPRFY
#define SFS_LCLPRFX
#define SFS_LCLPLEN
#define dirfd(x)
int GenAccess(const XrdSecEntity *client, const char *aList[], int aMax)
char * GenPath(int &rc, const XrdSecEntity *client, const char *opname, const char *lfn, pType lfnType=isAny)
static int Validate(const char *)
Definition XrdDigFS.cc:812
XrdDigConfig Config

References XrdDig::Config, dirfd, XrdDigFS::Emsg(), XrdSfsDirectory::error, XrdDigConfig::GenAccess(), XrdDigConfig::GenPath(), XrdDigConfig::isDir, opendir, SFS_LCLPLEN, SFS_LCLPRFX, SFS_LCLPRFY, SFS_OK, and XrdDigFS::Validate().

+ Here is the call graph for this function:

The documentation for this class was generated from the following files: