00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "wvdiriter.h"
00011
00012 #if defined(_WIN32) && !defined(S_ISDIR)
00013 #define S_ISDIR(x) (_S_IFDIR | (x))
00014 #endif
00015 #ifdef _WIN32
00016 #define lstat stat
00017 #endif
00018
00019 WvDirIter::WvDirIter( WvStringParm _dirname,
00020 bool _recurse, bool _skip_mounts, size_t sizeof_stat )
00021 : relpath(""), dir(dirs)
00022
00023 {
00024
00025
00026
00027 assert(sizeof_stat == sizeof(struct stat));
00028
00029 recurse = _recurse;
00030 go_up = false;
00031 skip_mounts = _skip_mounts;
00032 found_top = false;
00033
00034 WvString dirname(_dirname);
00035 int dl = strlen(dirname);
00036 if (dl != 0 && dirname[dl-1] == '/')
00037 dirname.edit()[dl-1] = 0;
00038
00039 DIR * d = opendir( dirname );
00040 if( d ) {
00041 Dir * dd = new Dir( d, dirname );
00042 dirs.prepend( dd, true );
00043 }
00044 }
00045
00046 WvDirIter::~WvDirIter()
00047
00048 {
00049 dirs.zap();
00050 }
00051
00052 bool WvDirIter::isok() const
00053
00054 {
00055 return( !dirs.isempty() );
00056 }
00057
00058 bool WvDirIter::isdir() const
00059
00060 {
00061 return( S_ISDIR( info.st_mode ) );
00062 }
00063
00064 void WvDirIter::rewind()
00065
00066 {
00067
00068
00069 while( dirs.count() > 1 ) {
00070 dir.rewind();
00071 dir.next();
00072 dir.unlink();
00073 }
00074
00075 if( isok() ) {
00076 dir.rewind();
00077 dir.next();
00078 rewinddir( dir->d );
00079 }
00080 }
00081
00082
00083 bool WvDirIter::next()
00084
00085
00086
00087 {
00088 struct dirent * dent = NULL;
00089
00090 if( !isok() )
00091 return( false );
00092
00093 bool tryagain;
00094 do {
00095 bool ok = false;
00096 tryagain = false;
00097
00098
00099 if( go_up ) {
00100 go_up = false;
00101 if( dirs.count() > 1 ) {
00102 dir.unlink();
00103 dir.rewind();
00104 dir.next();
00105 } else
00106 return( false );
00107 }
00108
00109 do {
00110 dent = readdir( dir->d );
00111 if( dent ) {
00112 info.fullname = WvString( "%s/%s", dir->dirname, dent->d_name );
00113 info.name = dent->d_name;
00114
00115 if (relpath == "")
00116 info.relname = info.name;
00117 else
00118 info.relname = WvString("%s%s", relpath, info.name);
00119
00120 ok = ( lstat( info.fullname, &info ) == 0
00121 && strcmp( dent->d_name, "." )
00122 && strcmp( dent->d_name, ".." ) );
00123
00124 if (ok && !found_top)
00125 {
00126 lstat(info.fullname, &topdir);
00127 topdir.fullname = info.fullname;
00128 topdir.name = info.name;
00129 topdir.relname = info.relname;
00130 found_top = true;
00131 }
00132 }
00133 } while( dent && !ok );
00134
00135 if( dent ) {
00136
00137 if( recurse && S_ISDIR( info.st_mode ) &&
00138 ( !skip_mounts || info.st_dev == topdir.st_dev) ) {
00139 DIR * d = opendir( info.fullname );
00140 if( d ) {
00141 relpath = WvString( "%s%s/", relpath, info.name );
00142 Dir * dd = new Dir( d, info.fullname );
00143 dirs.prepend( dd, true );
00144 dir.rewind();
00145 dir.next();
00146 }
00147 }
00148 } else {
00149
00150
00151
00152 if( dirs.count() > 1 ) {
00153 if (dirs.count() == 2)
00154 relpath = WvString("");
00155 else
00156 relpath = WvString( "%s/", getdirname(relpath) );
00157
00158 dir.unlink();
00159 dir.rewind();
00160 dir.next();
00161 tryagain = true;
00162 }
00163 }
00164
00165 } while( tryagain );
00166
00167 return( dent != NULL );
00168 }
00169