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