1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 29 // MARKER(update_precomp.py): autogen include statement, do not remove 30 #include "precompiled_l10ntools.hxx" 31 #include <l10ntools/directory.hxx> 32 #include "tools/string.hxx" 33 #include <iostream> 34 #include <vector> 35 #include <algorithm> 36 37 namespace transex 38 { 39 40 Directory::Directory( const rtl::OUString sFullpath ) : bSkipLinks( false ) 41 { 42 sFullName = sFullpath; 43 } 44 45 Directory::Directory( const rtl::OUString sFullPath , const rtl::OUString sEntry ) : bSkipLinks( false ) 46 { 47 sFullName = sFullPath; 48 sDirectoryName = sEntry; 49 } 50 51 52 Directory::Directory( const ByteString sFullPath ) : bSkipLinks( false ) 53 { 54 sDirectoryName = rtl::OUString( sFullPath.GetBuffer() , RTL_TEXTENCODING_UTF8 , sFullPath.Len() ); 55 } 56 57 bool Directory::lessDir ( const Directory& rKey1, const Directory& rKey2 ) 58 { 59 rtl::OUString sName1( ( static_cast< Directory >( rKey1 ) ).getDirectoryName() ); 60 rtl::OUString sName2( ( static_cast< Directory >( rKey2 ) ).getDirectoryName() ); 61 62 return sName1.compareTo( sName2 ) < 0 ; 63 } 64 65 66 void Directory::dump() 67 { 68 69 for( std::vector< transex::File >::iterator iter = aFileVec.begin() ; iter != aFileVec.end() ; ++iter ) 70 { 71 std::cout << "FILE " << rtl::OUStringToOString( (*iter).getFullName().getStr() , RTL_TEXTENCODING_UTF8 , (*iter).getFullName().getLength() ).getStr() << "\n"; 72 } 73 74 for( std::vector< transex::Directory >::iterator iter = aDirVec.begin() ; iter != aDirVec.end() ; ++iter ) 75 { 76 std::cout << "DIR " << rtl::OUStringToOString( (*iter).getFullName().getStr() , RTL_TEXTENCODING_UTF8 , (*iter).getFullName().getLength() ).getStr() << "\n"; 77 } 78 79 } 80 81 void Directory::scanSubDir( int nLevels ) 82 { 83 readDirectory( sFullName ); 84 dump(); 85 if( nLevels > 0 ) { 86 for( std::vector< transex::Directory >::iterator iter = aDirVec.begin() ; iter != aDirVec.end() || nLevels > 0 ; ++iter , nLevels-- ) 87 { 88 ( *iter ).scanSubDir(); 89 } 90 } 91 } 92 93 void Directory::setSkipLinks( bool is_skipped ) 94 { 95 bSkipLinks = is_skipped; 96 } 97 98 void Directory::readDirectory() 99 { 100 readDirectory( sFullName ); 101 } 102 103 #ifdef WNT 104 #include <tools/prewin.h> 105 #include <windows.h> 106 #include <tools/postwin.h> 107 108 void Directory::readDirectory ( const rtl::OUString& sFullpath ) 109 { 110 sal_Bool fFinished; 111 HANDLE hList; 112 TCHAR szDir[MAX_PATH+1]; 113 TCHAR szSubDir[MAX_PATH+1]; 114 WIN32_FIND_DATA FileData; 115 116 rtl::OString sFullpathext = rtl::OUStringToOString( sFullpath , RTL_TEXTENCODING_UTF8 , sFullpath.getLength() ); 117 const char *dirname = sFullpathext.getStr(); 118 119 // Get the proper directory path 120 sprintf(szDir, "%s\\*", dirname); 121 122 // Get the first file 123 hList = FindFirstFile(szDir, &FileData); 124 if (hList == INVALID_HANDLE_VALUE) 125 { 126 //FindClose(hList); 127 //printf("No files found %s\n", szDir ); return; 128 } 129 else 130 { 131 fFinished = sal_False; 132 while (!fFinished) 133 { 134 135 sprintf(szSubDir, "%s\\%s", dirname, FileData.cFileName); 136 rtl::OString myfile( FileData.cFileName ); 137 rtl::OString mydir( szSubDir ); 138 139 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 140 { 141 if ( (strcmp(FileData.cFileName, ".") != 0 ) && 142 (strcmp(FileData.cFileName, "..") != 0 ) ) 143 { 144 //sprintf(szSubDir, "%s\\%s", dirname, FileData.cFileName); 145 transex::Directory aDir( rtl::OStringToOUString( mydir , RTL_TEXTENCODING_UTF8 , mydir.getLength() ), 146 rtl::OStringToOUString( myfile , RTL_TEXTENCODING_UTF8 , myfile.getLength() ) ); 147 aDirVec.push_back( aDir ); 148 } 149 } 150 else 151 { 152 transex::File aFile( rtl::OStringToOUString( mydir , RTL_TEXTENCODING_UTF8 , mydir.getLength() ), 153 rtl::OStringToOUString( myfile , RTL_TEXTENCODING_UTF8 , myfile.getLength() ) ); 154 aFileVec.push_back( aFile ); 155 } 156 if (!FindNextFile(hList, &FileData)) 157 { 158 if (GetLastError() == ERROR_NO_MORE_FILES) 159 { 160 fFinished = sal_True; 161 } 162 } 163 } 164 } 165 166 FindClose(hList); 167 168 ::std::sort( aFileVec.begin() , aFileVec.end() , File::lessFile ); 169 ::std::sort( aDirVec.begin() , aDirVec.end() , Directory::lessDir ); 170 } 171 172 #else 173 174 class dirholder 175 { 176 private: 177 DIR *mpDir; 178 public: 179 dirholder(DIR *pDir) : mpDir(pDir) {} 180 int close() { int nRet = mpDir ? closedir(mpDir) : 0; mpDir = NULL; return nRet; } 181 ~dirholder() { close(); } 182 }; 183 184 void Directory::readDirectory( const rtl::OUString& sFullpath ) 185 { 186 struct stat statbuf; 187 struct stat statbuf2; 188 struct dirent *dirp; 189 DIR *dir; 190 191 if( sFullpath.getLength() < 1 ) return; 192 193 rtl::OString sFullpathext = rtl::OUStringToOString( sFullpath , RTL_TEXTENCODING_UTF8 , sFullpath.getLength() ).getStr(); 194 195 // stat 196 if( stat( sFullpathext.getStr() , &statbuf ) < 0 ){ printf("warning: Can not stat %s" , sFullpathext.getStr() ); return; }// error } 197 198 if( S_ISDIR(statbuf.st_mode ) == 0 ) { return; }// error } return; // not dir 199 200 if( (dir = opendir( sFullpathext.getStr() ) ) == NULL ) {printf("readerror 2 in %s \n",sFullpathext.getStr()); return; } // error } return; // error 201 202 dirholder aHolder(dir); 203 204 sFullpathext += rtl::OString( "/" ); 205 206 const rtl::OString sDot ( "." ) ; 207 const rtl::OString sDDot( ".." ); 208 209 if ( chdir( sFullpathext.getStr() ) == -1 ) { printf("chdir error in %s \n",sFullpathext.getStr()); return; } // error 210 211 while( ( dirp = readdir( dir ) ) != NULL ) 212 { 213 rtl::OString sEntryName( dirp->d_name ); 214 215 if( sEntryName.equals( sDot ) || sEntryName.equals( sDDot ) ) 216 continue; 217 218 // add dir entry 219 rtl::OString sEntity = sFullpathext; 220 sEntity += sEntryName; 221 222 // stat new entry 223 if( lstat( sEntity.getStr() , &statbuf2 ) < 0 ) 224 { 225 printf("error on entry %s\n" , sEntity.getStr() ) ; // error 226 continue; 227 } 228 229 // add file / dir to vector 230 switch( statbuf2.st_mode & S_IFMT ) 231 { 232 case S_IFREG: 233 { 234 rtl::OString sFile = sFullpathext; 235 sFile += sEntryName ; 236 transex::File aFile( rtl::OStringToOUString( sEntity , RTL_TEXTENCODING_UTF8 , sEntity.getLength() ) , 237 rtl::OStringToOUString( sEntryName , RTL_TEXTENCODING_UTF8 , sEntryName.getLength() ) 238 ); 239 240 aFileVec.push_back( aFile ) ; 241 break; 242 } 243 case S_IFLNK: 244 { 245 if( bSkipLinks ) break; 246 } 247 case S_IFDIR: 248 { 249 rtl::OString sDir = sFullpathext; 250 sDir += sEntryName ; 251 252 transex::Directory aDir( 253 rtl::OStringToOUString( sEntity , RTL_TEXTENCODING_UTF8 , sEntity.getLength() ) , 254 rtl::OStringToOUString( sEntryName , RTL_TEXTENCODING_UTF8 , sEntryName.getLength() ) 255 ) ; 256 aDirVec.push_back( aDir ) ; 257 break; 258 } 259 } 260 } 261 if ( chdir( ".." ) == -1 ) { printf("chdir error in .. \n"); return; } // error 262 if( aHolder.close() < 0 ) return ; // error 263 264 std::sort( aFileVec.begin() , aFileVec.end() , File::lessFile ); 265 std::sort( aDirVec.begin() , aDirVec.end() , Directory::lessDir ); 266 267 } 268 269 #endif 270 } 271