00001
00002
00003 #include <string.h>
00004 #include <errno.h>
00005 #include "gdir.h"
00006 #include "gfilestat.h"
00007
00008
00009
00010 t_uchar gDirGeneric::slashChr=gSLASHCHR;
00011
00012
00013 gFileSysName::gFileSysName (char* s,
00014 eFileSystemName aFSysName,
00015 bool isADirectory)
00016 : gString( s ),
00017 fsysName( aFSysName ),
00018 isDirectory( isADirectory ),
00019 myStat( nil )
00020 {
00021 }
00022
00023 gFileSysName::gFileSysName (char* s,
00024 eFileSystemName aFSysName,
00025 gFileStat& aStat)
00026 : gString( s ),
00027 fsysName( aFSysName ),
00028 isDirectory( aFSysName==e_FSysDir )
00029 {
00030 myStat = new gFileStat;
00031 ASSERTION(myStat!=nil,"myStat!=nil");
00032 myStat->CopyStat( aStat );
00033 }
00034
00035 gFileSysName::~gFileSysName ()
00036 {
00037 delete myStat;
00038 myStat = nil;
00039 }
00040
00041 bool gFileSysName::IsStrOk ()
00042 {
00043 bool isStrict = isDirectory==false;
00044 unsigned i, n=Length();
00045
00046 if ( IsOk()==false ) return false;
00047 for (i=0; i<n; i++) {
00048 if ( gFileControl::Self().IsOkStrict( str[i], isStrict )==false )
00049 return false;
00050 }
00051 return true;
00052 }
00053
00054 char* gFileSysName::Str ()
00055 {
00056 ASSERTION(str!=nil,"str!=nil");
00057 return gString::Str();
00058 }
00059
00060 gFileStat& gFileSysName::GetStat ()
00061 {
00062 ASSERTION(myStat!=nil,"myStat!=nil");
00063 return *myStat;
00064 }
00065
00066 gFileName::gFileName ()
00067 : gFileSysName( "\0", e_FSysNoName, false )
00068 {
00069 }
00070
00071 gFileName::gFileName (char* s)
00072 : gFileSysName( s, e_FSysFile, false )
00073 {
00074 }
00075
00076 gFileName::gFileName (gString& s)
00077 : gFileSysName( s.Str(), e_FSysFile, false )
00078 {
00079 }
00080
00081 gFileName::gFileName (gString& s, gFileStat& aStat)
00082 : gFileSysName( s.Str(), e_FSysFile, aStat )
00083 {
00084 }
00085
00086 gFileName::~gFileName ()
00087 {
00088 }
00089
00090 gDirName::gDirName ()
00091 : gFileSysName( "\0", e_FSysNoName, true )
00092 {
00093 }
00094
00095 gDirName::gDirName (char* s)
00096 : gFileSysName( "\0", e_FSysDir, true )
00097 {
00098 SetDirName( s );
00099 }
00100
00101 gDirName::gDirName (gString& s)
00102 : gFileSysName( "\0", e_FSysDir, true )
00103 {
00104 SetDirName( s.Str() );
00105 }
00106
00107 gDirName::gDirName (gString& s, gFileStat& aStat)
00108 : gFileSysName( s.Str(), e_FSysDir, aStat )
00109 {
00110 SetDirName( s.Str() );
00111 }
00112
00113 gDirName::~gDirName ()
00114 {
00115 }
00116
00117 char* gDirName::Str ()
00118 {
00119 return dirStr.Str();
00120 }
00121
00122 char* gDirName::Name ()
00123 {
00124 ASSERTION(str!=nil,"str!=nil");
00125 return (char*)str;
00126 }
00127
00128 void gDirName::SetDirName (char* s)
00129 {
00130 ASSERTION(s!=nil,"s!=nil");
00131 thisBuildDirStr( s );
00132 }
00133
00134 t_uchar* gDirName::ToString (t_uchar* uBuf)
00135 {
00136 return dirStr.ToString( uBuf );
00137 }
00138
00139 void gDirName::thisBuildDirStr (char* s)
00140 {
00141 gString sTemp( s );
00142 char* sPtr = sTemp.Str();
00143 int pIdx, len = (int)sTemp.Length();
00144
00145 for (pIdx=len; pIdx>0; ) {
00146 pIdx--;
00147 if ( sPtr[pIdx]==gSLASHCHR )
00148 sPtr[pIdx] = 0;
00149 else
00150 break;
00151 }
00152 Set( sPtr );
00153 dirStr.Set( sPtr );
00154 dirStr.Add( gSLASHCHR );
00155 }
00156
00157 gDirStream::gDirStream (char* dName)
00158 : gFile( gFile::e_Binary, dName, true ),
00159 pdir( nil ),
00160 dirName( dName ),
00161 dStat( dName ),
00162 isDirOpened( false )
00163 {
00164 #ifdef gDOS_SPEC
00165 lastOpError = 0;
00166 #endif //gDOS_SPEC
00167 if ( lastOpError==0 ) doOpenDir( dName );
00168 }
00169
00170 gDirStream::~gDirStream ()
00171 {
00172 doCloseDir();
00173 }
00174
00175 bool gDirStream::IsOpened ()
00176 {
00177 return isDirOpened;
00178 }
00179
00180 int gDirStream::doOpenDir (char* dName)
00181 {
00182 ASSERTION(dName!=0 && dName[0]!=0,"dName!=0");
00183 lastOpError = 0;
00184 pdir = opendir( dName );
00185 isDirOpened = pdir!=NULL;
00186 DBGPRINT_MIN("doOpenDir(%s): isDirOpened?%d\n",dName,isDirOpened);
00187 if ( isDirOpened==false ) return lastOpError = errno;
00188 return 0;
00189 }
00190
00191 int gDirStream::doCloseDir ()
00192 {
00193 if ( isDirOpened ) {
00194 ASSERTION(pdir!=nil,"pdir!=nil");
00195 closedir( pdir );
00196 pdir = nil;
00197 }
00198 isDirOpened = false;
00199 return 0;
00200 }
00201
00202
00203
00204 gDirGeneric::gDirGeneric (eStorage kind)
00205 : lastOpError( 0 ),
00206 slashStr( (char)slashChr )
00207 {
00208 }
00209
00210 gDirGeneric::~gDirGeneric ()
00211 {
00212 }
00213
00214 bool gDirGeneric::IsNameOk (char* s)
00215 {
00216 unsigned posBad;
00217 return thisNameOk( s, posBad );
00218 }
00219
00220 bool gDirGeneric::AllNamesOk (int depthLevel)
00221 {
00222 unsigned posBad;
00223 int notOkDepth;
00224 if ( depthLevel<0 ) return true;
00225 return thisAllNamesOk( depthLevel, posBad, notOkDepth );
00226 }
00227
00228 gFileSysName* gDirGeneric::GetName (unsigned idx)
00229 {
00230 gFileSysName* fSysPtr = (gFileSysName*)GetObjectPtr( idx );
00231 ASSERTION(fSysPtr!=nil,"fSysPtr!=nil");
00232 return fSysPtr;
00233 }
00234
00235 t_uchar* gDirGeneric::ToString (t_uchar* uBuf)
00236 {
00237 return nil;
00238 }
00239
00240 bool gDirGeneric::SaveGuts (FILE* f)
00241 {
00242 bool isOk=true;
00243 unsigned i, n=N();
00244 char* s;
00245
00246 if ( CanSave( f )==false ) return false;
00247
00248
00249 isOk = AllNamesOk( 0 );
00250 if ( isOk==false ) return false;
00251 for (i=1; i<=n; i++) {
00252 gStorage* aObj = GetObjectPtr( i );
00253 s = ((gString*)aObj)->Str();
00254 isOk = fprintf( f, "%s\n", s )==1;
00255 }
00256 return isOk;
00257 }
00258
00259 bool gDirGeneric::RestoreGuts (FILE* f)
00260 {
00261 gUCharBuffer sTemp;
00262 char* s;
00263
00264 if ( CanRestore( f )==false ) return false;
00265
00266 while ( fgets( (char*)sTemp.uBuf, sTemp.size, f )!=nil ) {
00267 s = sTemp.Str();
00268 if ( IsNameOk( s )==false ) return false;
00269 Add( s );
00270 }
00271 return true;
00272 }
00273
00274 bool gDirGeneric::thisNameOk (char* s, unsigned& posBad)
00275 {
00276 unsigned pos=0, countSlash=0;
00277 char c='\0';
00278 t_uchar chr=0;
00279
00280 ASSERTION(s!=nil,"s!=nil");
00281 posBad = 0;
00282 while ( (c = s[pos++])!=0 ) {
00283 chr = (t_uchar)c;
00284 posBad = pos;
00285 if ( chr<' ' ) return false;
00286 countSlash += chr==slashChr;
00287 }
00288 if ( chr==0 ) return false;
00289 posBad = 1;
00290 if ( strcmp(s,".")==0 || strcmp(s,"..")==0 ) return false;
00291
00292
00293 if ( countSlash>1 ) return false;
00294 if ( countSlash>0 && chr!=slashChr ) return false;
00295 if ( slashStr.Match( s ) ) return false;
00296 posBad = 0;
00297 return true;
00298 }
00299
00300 bool gDirGeneric::thisAllNamesOk (unsigned depthLevel,
00301 unsigned& posBad,
00302 int& notOkDepth)
00303 {
00304 bool isOk;
00305 char* s;
00306
00307 posBad = 0;
00308 notOkDepth = 0;
00309 ASSERTION(depthLevel>=0,"depthLevel>=0");
00310 ASSERTION(depthLevel==0,"TODO: depthLevel not 0...");
00311 unsigned i, n=N();
00312
00313 for (i=1; i<=n; i++) {
00314 gStorage* aObj = GetObjectPtr( i );
00315 s = ((gString*)aObj)->Str();
00316 isOk = IsNameOk( s );
00317 if ( isOk==false ) {
00318 posBad = i;
00319 return false;
00320 }
00321 }
00322 return true;
00323 }
00324
00325 gDir::gDir (char* dName)
00326 : gDirGeneric( e_StoreExtend ),
00327 dirStream( dName ),
00328 dirCount( -1 )
00329 {
00330 lastOpError = dirStream.lastOpError;
00331
00332 if ( dName!=nil ) sDirName.SetDirName( dName );
00333 if ( dirStream.IsOpened() ) {
00334 thisDelete();
00335 thisScanDir();
00336 }
00337 }
00338
00339 gDir::gDir (gString& dName)
00340 : gDirGeneric( e_StoreExtend ),
00341 dirStream( dName.Str() ),
00342 dirCount( -1 )
00343 {
00344 lastOpError = dirStream.lastOpError;
00345 if ( dName.IsEmpty()==false ) sDirName.SetDirName( dName.Str() );
00346 if ( dirStream.IsOpened() ) {
00347 thisDelete();
00348 thisScanDir();
00349 }
00350 }
00351
00352 gDir::~gDir ()
00353 {
00354 }
00355
00356 gFileStat* gDir::GetStat (unsigned idx)
00357 {
00358 gFileSysName* fSysPtr = GetName( idx );
00359
00360 gFileStat* statPtr = fSysPtr->GetStatPtr();
00361 ASSERTION(statPtr!=nil,"statPtr!=nil");
00362 return statPtr;
00363 }
00364
00365 bool gDir::GetNameDir (unsigned idx, gString& resName)
00366 {
00367 gString resFullName;
00368 return GetFullNameDir( idx, resName, resFullName );
00369 }
00370
00371 bool gDir::GetFullNameDir (unsigned idx, gString& resName, gString& resFullName)
00372 {
00373 gFileSysName* fSysPtr = GetName( idx );
00374 resName.Set( fSysPtr->Str() );
00375 resFullName = sDirName.Str();
00376 resFullName.AddString( resName );
00377 return fSysPtr->GetStatPtr()->IsDirectory();
00378 }
00379
00380 void gDir::AddDir (char* s)
00381 {
00382 ASSERTION(s!=nil && s[0]!=0,"AddDir(1)");
00383 gString sTemp( s );
00384 gDirName* sName = new gDirName( sTemp );
00385 thisAddSystemName( sName );
00386 }
00387
00388 void gDir::AddFile (char* s)
00389 {
00390 ASSERTION(s!=nil && s[0]!=0,"AddFile(1)");
00391 gString sTemp( s );
00392 gFileName* sName = new gFileName( sTemp );
00393 thisAddSystemName( sName );
00394 }
00395
00396 int gDir::thisScanDir ()
00397 {
00398 bool isOk, isDir;
00399 struct dirent tDirEnt;
00400 struct dirent* dp;
00401 char* s;
00402 int counter=0;
00403 DIR* apDir;
00404
00405 apDir = dirStream.pdir;
00406 ASSERTION(dirStream.dirName.IsEmpty()==false,"thisScanDir(1)");
00407 ASSERTION(apDir!=NULL,"thisScanDir(2)");
00408
00409
00410
00411
00412 for (lastOpError=0; ; counter++) {
00413 gFileStat aStat;
00414 dp = readdir( apDir );
00415 if ( counter==0 && dp==NULL ) lastOpError = errno;
00416 if ( dp==NULL ) break;
00417 memset( &tDirEnt, 0, sizeof(tDirEnt) );
00418 memcpy( &tDirEnt, dp, sizeof(tDirEnt) );
00419
00420 s = (char*)tDirEnt.d_name;
00421 if ( strcmp(s,".")==0 || strcmp(s,"..")==0 ) continue;
00422 gString sTemp( sDirName.Name() );
00423 sTemp.Add( gSLASHCHR );
00424 sTemp.Add( s );
00425 aStat.Update( sTemp.Str() );
00426 isOk = aStat.HasStat();
00427 if ( isOk==false ) {
00428 errUnstatL.Add( sTemp );
00429 continue;
00430 }
00431 isDir = aStat.statusL.IsDirectory();
00432 thisAddStatName( isDir?e_FSysDir:e_FSysFile, s, aStat );
00433 }
00434 DBGPRINT_MIN("dirStream(%s):%d\n",dirStream.Name(),lastOpError);
00435 return lastOpError;
00436 }
00437
00438 int gDir::thisAddStatName (eFileSystemName aFSysName, char* s, gFileStat& aStat)
00439 {
00440 gFileSysName* aPtr=nil;
00441
00442 ASSERTION(s!=nil && s[0]!=0,"AddDir(1)");
00443 gString sTemp( s );
00444
00445 switch ( aFSysName ) {
00446 case e_FSysFile:
00447 aPtr = new gFileName( sTemp, aStat );
00448 break;
00449 case e_FSysDir:
00450 aPtr = new gDirName( sTemp, aStat );
00451 case e_FSysNoName:
00452 default:
00453 break;
00454 }
00455
00456 return thisAddSystemName( aPtr );
00457 }
00458
00459 int gDir::thisAddSystemName (gFileSysName* aPtr)
00460 {
00461 ASSERTION(aPtr!=nil,"aPtr!=nil");
00462 return thisAppend( aPtr )==false;
00463 }
00464
00465