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