00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "CeylanLibfatDirectory.h"
00028
00029
00030 #include "CeylanFileSystemManager.h"
00031 #include "CeylanLibfatFileSystemManager.h"
00032
00033 #include "CeylanLogLight.h"
00034 #include "CeylanLogPlug.h"
00035 #include "CeylanOperators.h"
00036
00037
00038
00039 #ifdef CEYLAN_USES_CONFIG_H
00040 #include "CeylanConfig.h"
00041 #endif // CEYLAN_USES_CONFIG_H
00042
00043
00044
00045
00046 extern "C"
00047 {
00048
00049 #if CEYLAN_ARCH_NINTENDO_DS
00050
00051 #include "fat.h"
00052
00053
00054
00055
00056
00057
00058 #include "sys/dir.h"
00059
00060 #include <fcntl.h>
00061 #include <unistd.h>
00062
00063 #endif // CEYLAN_ARCH_NINTENDO_DS
00064
00065 }
00066
00067
00068 #include <cstdlib>
00069
00070 #include <cerrno>
00071 #include <cstdio>
00072
00073
00074 #ifndef PATH_MAX
00075 #define PATH_MAX 256
00076 #endif // PATH_MAX
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 using std::string ;
00094 using std::list ;
00095
00096 using namespace Ceylan::Log ;
00097 using namespace Ceylan::System ;
00098
00099
00100
00101
00102 LibfatDirectory::~LibfatDirectory() throw()
00103 {
00104
00105
00106
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 bool LibfatDirectory::hasDirectory( const string & subdirectoryName ) const
00125 {
00126
00127 #if CEYLAN_ARCH_NINTENDO_DS
00128
00129 #ifdef CEYLAN_RUNS_ON_ARM7
00130
00131 throw DirectoryLookupFailed( "LibfatDirectory::hasDirectory: "
00132 "not supported on the ARM7 (no libfat available)" ) ;
00133
00134 #else // CEYLAN_RUNS_ON_ARM7
00135
00136 FileSystemManager * fsManager ;
00137
00138 try
00139 {
00140
00141 fsManager = & getCorrespondingFileSystemManager() ;
00142
00143 }
00144 catch( const DirectoryDelegatingException & e )
00145 {
00146
00147 throw DirectoryLookupFailed(
00148 "LibfatDirectory::hasDirectory failed: " + e.toString() ) ;
00149
00150 }
00151
00152 if ( ( subdirectoryName == fsManager->getAliasForCurrentDirectory() )
00153 || ( subdirectoryName == fsManager->getAliasForParentDirectory() ) )
00154 return true ;
00155
00156 string fullDirPath = fsManager->joinPath( _path, subdirectoryName ) ;
00157
00158
00159
00160 struct stat buf ;
00161
00162 return ( ( ::stat( fullDirPath.c_str(), & buf ) == 0 )
00163 && ( buf.st_mode & S_IFDIR ) ) ;
00164
00165
00166 #endif // CEYLAN_RUNS_ON_ARM7
00167
00168
00169 #else // CEYLAN_ARCH_NINTENDO_DS
00170
00171 throw DirectoryLookupFailed( "LibfatDirectory::hasDirectory: "
00172 "not supported on this platform" ) ;
00173
00174 #endif // CEYLAN_ARCH_NINTENDO_DS
00175
00176
00177 }
00178
00179
00180
00181 bool LibfatDirectory::hasFile( const string & fileName ) const
00182 {
00183
00184 #if CEYLAN_ARCH_NINTENDO_DS
00185
00186 #ifdef CEYLAN_RUNS_ON_ARM7
00187
00188 throw DirectoryLookupFailed( "LibfatDirectory::hasFile: "
00189 "not supported on the ARM7 (no libfat available)" ) ;
00190
00191 #else // CEYLAN_RUNS_ON_ARM7
00192
00193 FileSystemManager * fsManager ;
00194
00195 try
00196 {
00197
00198 fsManager = & getCorrespondingFileSystemManager() ;
00199
00200 }
00201 catch( const DirectoryDelegatingException & e )
00202 {
00203
00204 throw DirectoryLookupFailed(
00205 "LibfatDirectory::hasFile failed: " + e.toString() ) ;
00206
00207 }
00208
00209 string fullDirPath = fsManager->joinPath( _path, fileName ) ;
00210
00211
00212
00213 struct stat buf ;
00214
00215 return ( ( ::stat( fullDirPath.c_str(), & buf ) == 0 )
00216 && ( buf.st_mode & S_IFREG ) ) ;
00217
00218
00219 #endif // CEYLAN_RUNS_ON_ARM7
00220
00221
00222 #else // CEYLAN_ARCH_NINTENDO_DS
00223
00224 throw DirectoryLookupFailed( "LibfatDirectory::hasFile: "
00225 "not supported on this platform" ) ;
00226
00227 #endif // CEYLAN_ARCH_NINTENDO_DS
00228
00229 }
00230
00231
00232
00233 bool LibfatDirectory::hasEntry( const string & entryName ) const
00234 {
00235
00236 #if CEYLAN_ARCH_NINTENDO_DS
00237
00238 #ifdef CEYLAN_RUNS_ON_ARM7
00239
00240 throw DirectoryLookupFailed( "LibfatDirectory::hasEntry: "
00241 "not supported on the ARM7 (no libfat available)" ) ;
00242
00243 #else // CEYLAN_RUNS_ON_ARM7
00244
00245 FileSystemManager * fsManager ;
00246
00247 try
00248 {
00249
00250 fsManager = & getCorrespondingFileSystemManager() ;
00251
00252 }
00253 catch( const DirectoryDelegatingException & e )
00254 {
00255
00256 throw DirectoryLookupFailed(
00257 "LibfatDirectory::hasEntry failed: " + e.toString() ) ;
00258
00259 }
00260
00261 if ( ( entryName == fsManager->getAliasForCurrentDirectory() )
00262 || ( entryName == fsManager->getAliasForParentDirectory() ) )
00263 return true ;
00264
00265 string fullDirPath = fsManager->joinPath( _path, entryName ) ;
00266
00267
00268
00269
00270 return ( ::stat( fullDirPath.c_str(), 0 ) == 0 ) ;
00271
00272
00273 #endif // CEYLAN_RUNS_ON_ARM7
00274
00275
00276 #else // CEYLAN_ARCH_NINTENDO_DS
00277
00278 throw DirectoryLookupFailed( "LibfatDirectory::hasEntry: "
00279 "not supported on this platform" ) ;
00280
00281 #endif // CEYLAN_ARCH_NINTENDO_DS
00282
00283 }
00284
00285
00286
00287
00288 void LibfatDirectory::getSubdirectories( list<string> & subDirectories ) const
00289 {
00290
00291 #if CEYLAN_ARCH_NINTENDO_DS
00292
00293 #ifdef CEYLAN_RUNS_ON_ARM7
00294
00295 throw DirectoryLookupFailed( "LibfatDirectory::getSubdirectories: "
00296 "not supported on the ARM7 (no libfat available)" ) ;
00297
00298 #else // CEYLAN_RUNS_ON_ARM7
00299
00300
00301 DIR_ITER* dirIterator = ::diropen( _path.c_str() ) ;
00302
00303
00304 char filenameBuf[PATH_MAX] ;
00305
00306 struct stat statBuf ;
00307
00308 if ( dirIterator == 0 )
00309 {
00310
00311 ::dirclose( dirIterator ) ;
00312 throw DirectoryLookupFailed(
00313 "LibfatDirectory::getSubdirectories failed: "
00314 "unable to open the directory " + _path ) ;
00315 }
00316
00317 while ( ::dirnext( dirIterator, filenameBuf, & statBuf ) == 0 )
00318 if ( statBuf.st_mode & S_IFDIR )
00319 subDirectories.push_back( string( filenameBuf ) ) ;
00320
00321 ::dirclose( dirIterator ) ;
00322
00323 #endif // CEYLAN_RUNS_ON_ARM7
00324
00325
00326 #else // CEYLAN_ARCH_NINTENDO_DS
00327
00328 throw DirectoryLookupFailed( "LibfatDirectory::getSubdirectories: "
00329 "not supported on this platform" ) ;
00330
00331 #endif // CEYLAN_ARCH_NINTENDO_DS
00332
00333 }
00334
00335
00336
00337 void LibfatDirectory::getFiles( list<string> & files ) const
00338 {
00339
00340 #if CEYLAN_ARCH_NINTENDO_DS
00341
00342 #ifdef CEYLAN_RUNS_ON_ARM7
00343
00344 throw DirectoryLookupFailed( "LibfatDirectory::getFiles: "
00345 "not supported on the ARM7 (no libfat available)" ) ;
00346
00347 #else // CEYLAN_RUNS_ON_ARM7
00348
00349
00350 DIR_ITER * dirIterator = ::diropen( _path.c_str() ) ;
00351
00352
00353 char filenameBuf[PATH_MAX] ;
00354
00355 struct stat statBuf ;
00356
00357 if ( dirIterator == 0 )
00358 {
00359 ::dirclose( dirIterator ) ;
00360 throw DirectoryLookupFailed( "LibfatDirectory::getFiles failed: "
00361 "unable to open the directory " + _path ) ;
00362 }
00363
00364 while ( ::dirnext( dirIterator, filenameBuf, & statBuf ) == 0 )
00365 if ( statBuf.st_mode & S_IFREG )
00366 files.push_back( string( filenameBuf ) ) ;
00367
00368 ::dirclose( dirIterator ) ;
00369
00370 #endif // CEYLAN_RUNS_ON_ARM7
00371
00372
00373 #else // CEYLAN_ARCH_NINTENDO_DS
00374
00375 throw DirectoryLookupFailed( "LibfatDirectory::getFiles: "
00376 "not supported on this platform" ) ;
00377
00378 #endif // CEYLAN_ARCH_NINTENDO_DS
00379
00380 }
00381
00382
00383
00384 void LibfatDirectory::getEntries( list<string> & entries ) const
00385 {
00386
00387 #if CEYLAN_ARCH_NINTENDO_DS
00388
00389 #ifdef CEYLAN_RUNS_ON_ARM7
00390
00391 throw DirectoryLookupFailed( "LibfatDirectory::getEntries: "
00392 "not supported on the ARM7 (no libfat available)" ) ;
00393
00394 #else // CEYLAN_RUNS_ON_ARM7
00395
00396
00397 DIR_ITER * dirIterator = ::diropen( _path.c_str() ) ;
00398
00399
00400 char filenameBuf[PATH_MAX] ;
00401
00402 if ( dirIterator == 0 )
00403 {
00404 ::dirclose( dirIterator ) ;
00405 throw DirectoryLookupFailed( "LibfatDirectory::getEntries failed: "
00406 "unable to open the directory " + _path ) ;
00407 }
00408
00409 while ( ::dirnext( dirIterator, filenameBuf, 0 ) == 0 )
00410 entries.push_back( string( filenameBuf ) ) ;
00411
00412 ::dirclose( dirIterator ) ;
00413
00414 #endif // CEYLAN_RUNS_ON_ARM7
00415
00416
00417 #else // CEYLAN_ARCH_NINTENDO_DS
00418
00419 throw DirectoryLookupFailed( "LibfatDirectory::getEntries: "
00420 "not supported on this platform" ) ;
00421
00422 #endif // CEYLAN_ARCH_NINTENDO_DS
00423
00424
00425 }
00426
00427
00428
00429 void LibfatDirectory::getSortedEntries( list<string> & subDirectories,
00430 list<string> & files, list<string> & otherEntries ) const
00431 {
00432
00433 #if CEYLAN_ARCH_NINTENDO_DS
00434
00435 #ifdef CEYLAN_RUNS_ON_ARM7
00436
00437 throw DirectoryLookupFailed( "LibfatDirectory::getSortedEntries: "
00438 "not supported on the ARM7 (no libfat available)" ) ;
00439
00440 #else // CEYLAN_RUNS_ON_ARM7
00441
00442
00443 DIR_ITER * dirIterator = ::diropen( _path.c_str() ) ;
00444
00445
00446 char filenameBuf[PATH_MAX] ;
00447
00448 struct stat statBuf ;
00449
00450 if ( dirIterator == 0 )
00451 {
00452
00453 ::dirclose( dirIterator ) ;
00454 throw DirectoryLookupFailed(
00455 "LibfatDirectory::getSortedEntries failed: "
00456 "unable to open the directory " + _path ) ;
00457 }
00458
00459
00460 while ( ::dirnext( dirIterator, filenameBuf, & statBuf ) == 0 )
00461 if ( statBuf.st_mode & S_IFDIR )
00462 subDirectories.push_back( string( filenameBuf ) ) ;
00463 else if ( statBuf.st_mode & S_IFREG )
00464 files.push_back( string( filenameBuf ) ) ;
00465 else
00466 otherEntries.push_back( string( filenameBuf ) ) ;
00467
00468 ::dirclose( dirIterator ) ;
00469
00470 #endif // CEYLAN_RUNS_ON_ARM7
00471
00472
00473 #else // CEYLAN_ARCH_NINTENDO_DS
00474
00475 throw DirectoryLookupFailed( "LibfatDirectory::getSortedEntries: "
00476 "not supported on this platform" ) ;
00477
00478 #endif // CEYLAN_ARCH_NINTENDO_DS
00479
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489 const string LibfatDirectory::toString( Ceylan::VerbosityLevels level ) const
00490 {
00491
00492 return "Libfat directory referring to path '" + _path + "'" ;
00493
00494 }
00495
00496
00497
00498
00499
00500
00501
00502 LibfatDirectory & LibfatDirectory::Create( const string & newDirectoryName )
00503 {
00504
00505 return * new LibfatDirectory( newDirectoryName, true ) ;
00506
00507 }
00508
00509
00510
00511 LibfatDirectory & LibfatDirectory::Open( const string & directoryName )
00512 {
00513
00514 return * new LibfatDirectory( directoryName, false ) ;
00515
00516 }
00517
00518
00519
00520 LibfatDirectory::LibfatDirectory( const string & directoryName,
00521 bool create ) :
00522 Directory( directoryName )
00523 {
00524
00525 #if CEYLAN_ARCH_NINTENDO_DS
00526
00527 #ifdef CEYLAN_RUNS_ON_ARM7
00528
00529 throw DirectoryCreationFailed( "LibfatDirectory constructor: "
00530 "not supported on the ARM7 (no libfat available)" ) ;
00531
00532 #else // CEYLAN_ARCH_NINTENDO_DS
00533
00534
00535
00536 FileSystemManager & fsManager = getCorrespondingFileSystemManager() ;
00537
00538 if ( _path.empty() )
00539 _path = fsManager.getCurrentWorkingDirectoryPath() ;
00540
00541
00542
00543 removeLeadingSeparator() ;
00544
00545
00546 CEYLAN_LOG( "LibfatDirectory constructor: "
00547 "creating directory reference for " + _path ) ;
00548
00549 if ( create && ! isValid() )
00550 {
00551
00552 CEYLAN_LOG( "LibfatDirectory constructor: directory '" + _path
00553 + "' does not exist yet and is to be created." ) ;
00554
00555
00556
00557
00558
00559
00560
00561 string path ;
00562
00563
00564
00565 if ( fsManager.isAbsolutePath( _path ) )
00566 path = fsManager.getRootDirectoryPrefix()
00567 + fsManager.getSeparatorAsString() ;
00568
00569
00570
00571
00572 list<string> nodes = fsManager.splitPath( _path ) ;
00573
00574 CEYLAN_LOG( "LibfatDirectory constructor: creating sub-elements." ) ;
00575
00576 for ( list<string>::const_iterator it = nodes.begin();
00577 it != nodes.end(); it++ )
00578 {
00579
00580 path += *it ;
00581
00582
00583 CEYLAN_LOG( "LibfatDirectory constructor: examining " + path ) ;
00584
00585 if ( ! fsManager.existsAsDirectory( path ) )
00586 {
00587
00588 CEYLAN_LOG( "LibfatDirectory constructor: creating "
00589 + path ) ;
00590
00591
00592
00593
00594
00595
00596 if ( ::mkdir( path.c_str(), 0 ) == -1 )
00597 throw DirectoryCreationFailed(
00598 "LibfatDirectory constructor failed for path "
00599 + path + ": " + explainError() ) ;
00600 }
00601
00602 path += fsManager.getSeparatorAsString() ;
00603
00604 }
00605
00606 }
00607
00608
00609 if ( ! fsManager.isAbsolutePath( _path ) )
00610 _path = fsManager.joinPath(
00611 fsManager.getCurrentWorkingDirectoryPath(), _path ) ;
00612
00613 CEYLAN_LOG( "Directory reference to " + _path + " done." ) ;
00614
00615
00616 #endif // CEYLAN_RUNS_ON_ARM7
00617
00618
00619 #else // CEYLAN_ARCH_NINTENDO_DS
00620
00621 throw DirectoryCreationFailed( "LibfatDirectory constructor "
00622 "not supported on this platform" ) ;
00623
00624 #endif // CEYLAN_ARCH_NINTENDO_DS
00625
00626 }
00627
00628
00629
00630
00631
00632
00633
00634 FileSystemManager & LibfatDirectory::getCorrespondingFileSystemManager() const
00635 {
00636
00637 try
00638 {
00639
00640 return LibfatFileSystemManager::GetLibfatFileSystemManager() ;
00641
00642 }
00643 catch ( const LibfatFileSystemManagerException & e )
00644 {
00645
00646 throw DirectoryDelegatingException(
00647 "LibfatDirectory::getCorrespondingFileSystemManager failed: "
00648 + e.toString() ) ;
00649
00650 }
00651
00652 }
00653
00654
00655
00656 void LibfatDirectory::secureCorrespondingFileSystemManager() const
00657 {
00658
00659 try
00660 {
00661
00662 LibfatFileSystemManager::SecureLibfatFileSystemManager() ;
00663
00664 }
00665 catch ( const LibfatFileSystemManagerException & e )
00666 {
00667
00668 throw DirectoryDelegatingException(
00669 "LibfatDirectory::secureCorrespondingFileSystemManager failed: "
00670 + e.toString() ) ;
00671
00672 }
00673
00674 }
00675