XRootD
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. More...
 
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 }
int closedir(DIR *dirp)
#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(), 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__))
243 do{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
252 do{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
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
int stat(const char *path, struct stat *buf)
struct dirent * readdir(DIR *dirp)
void clear()
Reset data and error information to null. Any appenadges are released.

References XrdDigFS::Emsg(), 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",
170  dir_path+SFS_LCLPLEN, XrdDigConfig::isDir)))
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 }
DIR * opendir(const char *path)
#define SFS_LCLPRFY
#define SFS_LCLPRFX
#define SFS_LCLPLEN
#define dirfd(x)
static int Validate(const char *)
Definition: XrdDigFS.cc:812
XrdCmsConfig Config

References XrdDig::Config, dirfd, XrdDigFS::Emsg(), 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: