00001 #ifndef __XRDOUCNSWALK_HH 00002 #define __XRDOUCNSWALK_HH 00003 /******************************************************************************/ 00004 /* */ 00005 /* X r d O u c N S W a l k . h h */ 00006 /* */ 00007 /* (c) 2009 by the Board of Trustees of the Leland Stanford, Jr., University */ 00008 /* All Rights Reserved */ 00009 /* Produced by Andrew Hanushevsky for Stanford University under contract */ 00010 /* DE-AC02-76-SFO0515 with the Department of Energy */ 00011 /******************************************************************************/ 00012 00013 #include <stdlib.h> 00014 #include <fcntl.h> 00015 #include <sys/types.h> 00016 #include <sys/stat.h> 00017 00018 // $Id: XrdOucNSWalk.hh 34000 2010-06-21 06:49:56Z ganis $ 00019 00020 class XrdOucTList; 00021 class XrdSysError; 00022 00023 class XrdOucNSWalk 00024 { 00025 public: 00026 00027 struct NSEnt 00028 { 00029 struct NSEnt *Next; // -> Next entry in the indexed directory 00030 char *Path; // Path name to file if opts & noPath (Path == File) 00031 char *File; // File name component 00032 int Plen; // strlen(Path) 00033 struct stat Stat; // stat() of Path if opts & retStat 00034 char *Link; // -> Link data if opts & retLink 00035 int Lksz; // Length of link data 00036 00037 enum Etype {isBad = 0, isDir, isFile, isLink, isMisc}; 00038 00039 Etype Type; // One of the above. If isLink then Link is invalid! 00040 00041 NSEnt() : Next(0), Path(0), Plen(0), Link(0), Lksz(0) {} 00042 ~NSEnt() {if (Path) free(Path); 00043 if (Link) free(Link); 00044 } 00045 }; 00046 00047 // Calling Index() provides the requested directory entries with a return code: 00048 // NSEnts != 0 && rc == 0: Normal ending. 00049 // NSEnts != 0 && rc != 0: Potentially short list as indexing aborted w/ err. 00050 // NSEnts == 0 && rc == 0: End of indexing no more entries can be returned. 00051 // NSEnts == 0 && rc != 0: Abort occured before any entries could be returned. 00052 // 00053 // When opts & skpErrs is true, then rc may be zero even when an error occured. 00054 // 00055 // If opts & Recurse, indexing will traverse the directory tree, one directory 00056 // at a time. For a complete traversal you sould keep calling Index() until 00057 // it returns 0 with rc == 0. When dPath is supplied, a pointer to the base 00058 // directory is returned as well (see noPath). 00059 // 00060 NSEnt *Index(int &rc, const char **dPath=0); 00061 00062 // The CallBack class is used to intercept empty directories. When set by a 00063 // call to setCallBack(); should an empty directory (i.e., one with no entries 00064 // or only with a lock file) in encountered a call is made to to the isEmpty() 00065 // method. If lkFn is zero, the directory is empty; otherwise, lkFn is the name 00066 // of the singleton lock file. To unset the callback use setCallBack(0); 00067 // 00068 class CallBack 00069 {public: 00070 virtual 00071 void isEmpty(struct stat *dStat, const char *dPath, const char *lkFn)=0; 00072 00073 CallBack() {} 00074 virtual ~CallBack() {} 00075 }; 00076 00077 void setCallBack(CallBack *cbP=0) {edCB = cbP;} 00078 00079 // The following are processing options passed to the constructor 00080 // 00081 static const int retDir = 0x0001; // Return directories (implies retStat) 00082 static const int retFile= 0x0002; // Return files (implies retStat) 00083 static const int retLink= 0x0004; // Return link data (implies retStat) 00084 static const int retMisc= 0x0008; // Return other types (implies retStat) 00085 static const int retAll = 0x000f; // Return everything 00086 00087 static const int retStat= 0x0010; // return stat() information 00088 static const int retIDLO= 0x0020; // Names returned in decreasing length order 00089 static const int retIILO= 0x0040; // Names returned in increasing length order 00090 static const int Recurse= 0x0080; // Recursive traversal, 1 Level per Index() 00091 static const int noPath = 0x0100; // Do not include the full directory path 00092 static const int skpErrs= 0x8000; // Skip any entry causing an error 00093 00094 XrdOucNSWalk(XrdSysError *erp, // Error msg object. If 0->silent 00095 const char *dname, // Initial directory path 00096 const char *LKfn=0, // Lock file name (see note below) 00097 int opts=retAll, // Options (see above) 00098 XrdOucTList *xP=0); // 1st Level dir exclude list 00099 ~XrdOucNSWalk(); 00100 00101 // Note: When Lkfn is supplied and it exists in a directory about to be indexed 00102 // then the file is opened in r/w mode and an exclusive lock is obtained. 00103 // If either fails, the the directory is not indexed and Index() will 00104 // return null pointer with rc != 0. Note that the lkfn is not returned 00105 // as a directory entry if an empty directory call back has been set. 00106 00107 private: 00108 void addEnt(XrdOucNSWalk::NSEnt *eP); 00109 int Build(); 00110 int getLink(XrdOucNSWalk::NSEnt *eP); 00111 int getStat(XrdOucNSWalk::NSEnt *eP, int doLstat=0); 00112 int getStat(); 00113 int inXList(const char *dName); 00114 int isSymlink(); 00115 int LockFile(); 00116 void setPath(char *newpath); 00117 00118 XrdSysError *eDest; 00119 XrdOucTList *DList; 00120 XrdOucTList *XList; 00121 struct NSEnt *DEnts; 00122 struct stat dStat; 00123 CallBack *edCB; 00124 char DPath[1032]; 00125 char *File; 00126 char *LKFn; 00127 int LKfd; 00128 int DPfd; 00129 int Opts; 00130 int errOK; 00131 int isEmpty; 00132 }; 00133 #endif