X Tutup
/* * Copyright (C) 2012 Yee Young Han (http://blog.naver.com/websearch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "Directory.h" #include "Log.h" #ifndef WIN32 #include #include #include #include #endif #include "MemoryDebug.h" /** * @ingroup SipPlatform * @brief µð·ºÅ丮¸¦ »ý¼ºÇÑ´Ù. * * ÀÌ¹Ì µð·ºÅ丮°¡ »ý¼ºµÇ¾î ÀÖÀ¸¸é ¾Æ¹«·± µ¿ÀÛÀ» ÇÏÁö ¾Ê´Â´Ù. * "c:\temp\test" ¿Í °°Àº ¹®ÀÚ¿­À» ÀÔ·ÂÇÏ¸é ´ÙÀ½°ú °°ÀÌ µ¿ÀÛÇÏ´Ù. * "c:\temp" µð·ºÅ丮°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é À̸¦ »ý¼ºÇÑ ÈÄ, "c:\temp\test" µð·ºÅ丮¸¦ »ý¼ºÇÑ´Ù. * * @param szDirName [in] »ý¼ºÇÒ µð·ºÅ丮ÀÇ full pathname * @param iDirMode [in] »ý¼ºÇÒ µð·ºÅ丮ÀÇ ±ÇÇÑ * @return ¼º°øÇϸé true À» ¸®ÅÏÇÏ°í ½ÇÆÐÇϸé false ¸¦ ¸®ÅÏÇÑ´Ù. */ bool CDirectory::Create( const char * szDirName, int iDirMode ) { int i, iLen, iCount, n; char * pszName; char fisNotDirectory = 0; // µð·ºÅ丮°¡ ¾Æ´Ñ°¡? char fisError = 0; // µð·ºÅ丮 »ý¼º½Ã¿¡ ¿¡·¯°¡ ¹ß»ýÇÏ¿´´Â°¡? iLen = (int)strlen( szDirName ); pszName = new char[ iLen + 1 ]; memset( pszName, 0, iLen + 1 ); for( i = 0, iCount = 0; i < iLen; i++ ) { if( szDirName[i] == DIR_SEP ) { iCount++; // µð·ºÅ丮 À̸§ÀÌ "c:\test\temp\" ¶Ç´Â "/test/temp/" À̹ǷΠµÎ¹øÂ° µð·ºÅ丮 // ±¸ºÐÀÚ ºÎÅÍ µð·ºÅ丮¸¦ »ý¼ºÇÏ¸é µÈ´Ù. if( iCount >= 2 ) { n = CDirectory::IsDirectoryCheck( pszName ); if( n == -1 ) { // µð·ºÅ丮°¡ ¾Æ´Ñ °æ¿ì fisNotDirectory = 1; break; } else if( n == -2 ) { // µð·ºÅ丮°¡ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì #ifdef WIN32 if( CreateDirectory( pszName, NULL ) == FALSE ) #else if( mkdir( pszName, iDirMode ) != 0 ) #endif { fisError = 1; break; } } } } pszName[i] = szDirName[i]; } delete [] pszName; if( fisNotDirectory == 1 ) return false; if( fisError == 1 ) return false; // µð·ºÅ丮 À̸§ÀÌ "c:\test\temp" ¶Ç´Â "/test/temp" ÀÏ °æ¿ì, À§ÀÇ loop ¿¡¼­ temp µð·ºÅ丮¸¦ // »ý¼ºÇÏÁö ¾ÊÀ¸¹Ç·Î À̸¦ »ý¼ºÇϱâ À§Çؼ­ ¾Æ·¡ÀÇ Äڵ尡 ÇÊ¿äÇÏ´Ù. if( szDirName[iLen-1] != DIR_SEP ) { n = CDirectory::IsDirectoryCheck( szDirName ); if( n == -1 ) { // µð·ºÅ丮°¡ ¾Æ´Ñ °æ¿ì return false; } else if( n == -2 ) { // µð·ºÅ丮°¡ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì #ifdef WIN32 if( CreateDirectory( szDirName, NULL ) == FALSE ) #else if( mkdir( szDirName, iDirMode ) != 0 ) #endif { return false; } } } return true; } /** * @ingroup SipPlatform * @brief »ç¿ëÀÚ°¡ ÀÔ·ÂÇÑ path °¡ µð·ºÅ丮ÀÎÁö¸¦ Á¡°ËÇÑ´Ù. * @param szDirName [in] µð·ºÅ丮 À̸§ * @return ÀÔ·ÂµÈ path °¡ µð·ºÅ丮À̸é true ¸¦ ¸®ÅÏÇÏ°í ±×·¸Áö ¾ÊÀ¸¸é false ¸¦ ¸®ÅÏÇÑ´Ù. */ bool CDirectory::IsDirectory( const char * szDirName ) { if( CDirectory::IsDirectoryCheck( szDirName ) == 0 ) return true; return false; } /** * @ingroup SipPlatform * @brief »ç¿ëÀÚ°¡ ÀÔ·ÂÇÑ path °¡ µð·ºÅ丮ÀÎÁö¸¦ Á¡°ËÇÑ´Ù. * @param szDirName [in] µð·ºÅ丮 À̸§ * @return ÀÔ·ÂµÈ path °¡ µð·ºÅ丮À̸é 0 À» ¸®ÅÏÇÑ´Ù. * Á¸ÀçÇÏÁö ¾ÊÀ¸¸é -2 À» ¸®ÅÏÇÑ´Ù. * µð·ºÅ丮°¡ ¾Æ´Ï¸é -1 À» ¸®ÅÏÇÑ´Ù. */ int CDirectory::IsDirectoryCheck( const char * szDirName ) { #ifdef WIN32 // ACE ¿¡¼­ S_ISDIR À» Áö¿øÇÏÁö ¾Ê±â ¶§¹®¿¡ À©µµ¿ìÀÇ °æ¿ì¸¦ À§ÇÏ¿© WINAPI ¸¦ »ç¿ëÇÏ¿´À½. DWORD iAttribute = GetFileAttributes( szDirName ); if( iAttribute != -1 ) { if( iAttribute & FILE_ATTRIBUTE_DIRECTORY ) { return 0; } else { return -1; } } else { // ÆÄÀÏÀÌ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì. return -2; } #else struct stat clsStat; if( stat( szDirName, &clsStat ) == 0 ) { if( S_ISDIR( clsStat.st_mode ) ) { return 0; } else { return -1; } } else { // ÆÄÀÏÀÌ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì. return -2; } #endif return 0; } /** * @ingroup SipPlatform * @brief ÆÄÀÏ °æ·Î¿¡ ÆÄÀÏ À̸§À» Ãß°¡ÇÑ´Ù. * @param strFileName ÆÄÀÏ °æ·Î * @param pszAppend Ãß°¡ÇÒ ÆÄÀÏ À̸§ */ void CDirectory::AppendName( std::string & strFileName, const char * pszAppend ) { #ifdef WIN32 strFileName.append( "\\" ); strFileName.append( pszAppend ); #else strFileName.append( "/" ); strFileName.append( pszAppend ); #endif } /** * @ingroup SipPlatform * @brief Æú´õ¿¡ Á¸ÀçÇÏ´Â ¸ðµç ÆÄÀÏ/Æú´õ ¸®½ºÆ®¸¦ °¡Á®¿Â´Ù. * @param pszDirName Æú´õ °æ·Î * @param clsFileList ÆÄÀÏ/Æú´õ ¸®½ºÆ®¸¦ ÀúÀåÇÒ º¯¼ö * @returns ¼º°øÇϸé true ¸¦ ¸®ÅÏÇÏ°í ½ÇÆÐÇϸé false ¸¦ ¸®ÅÏÇÑ´Ù. */ bool CDirectory::List( const char * pszDirName, FILE_LIST & clsFileList ) { clsFileList.clear(); #ifdef WIN32 WIN32_FIND_DATA sttFindData; HANDLE hFind; BOOL bNext = TRUE; std::string strPath = pszDirName; strPath.append( "\\*.*" ); hFind = FindFirstFile( strPath.c_str(), &sttFindData ); if( hFind == INVALID_HANDLE_VALUE ) { CLog::Print( LOG_ERROR, "FindFirstFile(%s) error(%d)", pszDirName, GetLastError() ); return false; } for( ; bNext == TRUE; bNext = FindNextFile( hFind, &sttFindData ) ) { if( !strcmp( sttFindData.cFileName, "." ) || !strcmp( sttFindData.cFileName, ".." ) ) continue; clsFileList.push_back( sttFindData.cFileName ); } FindClose( hFind ); #else DIR * psttDir; struct dirent * psttDirent, sttDirent; int n; psttDir = opendir( pszDirName ); if( psttDir == NULL ) { CLog::Print( LOG_ERROR, "opendir(%s) error(%d)", pszDirName, errno ); return false; } for( n = readdir_r( psttDir, &sttDirent, &psttDirent ); psttDirent && n == 0; n = readdir_r( psttDir, &sttDirent, &psttDirent ) ) { if( !strcmp( psttDirent->d_name, "." ) || !strcmp( psttDirent->d_name, ".." ) ) continue; clsFileList.push_back( psttDirent->d_name ); } closedir( psttDir ); #endif return true; } /** * @ingroup SipPlatform * @brief Æú´õ¿¡ Á¸ÀçÇÏ´Â ¸ðµç ÆÄÀÏ ¸®½ºÆ®¸¦ °¡Á®¿Â´Ù. * @param pszDirName Æú´õ °æ·Î * @param clsFileList ÆÄÀÏ ¸®½ºÆ®¸¦ ÀúÀåÇÒ º¯¼ö * @returns ¼º°øÇϸé true ¸¦ ¸®ÅÏÇÏ°í ½ÇÆÐÇϸé false ¸¦ ¸®ÅÏÇÑ´Ù. */ bool CDirectory::FileList( const char * pszDirName, FILE_LIST & clsFileList ) { clsFileList.clear(); #ifdef WIN32 WIN32_FIND_DATA sttFindData; HANDLE hFind; BOOL bNext = TRUE; std::string strPath = pszDirName; strPath.append( "\\*.*" ); hFind = FindFirstFile( strPath.c_str(), &sttFindData ); if( hFind == INVALID_HANDLE_VALUE ) { CLog::Print( LOG_ERROR, "FindFirstFile(%s) error(%d)", pszDirName, GetLastError() ); return false; } for( ; bNext == TRUE; bNext = FindNextFile( hFind, &sttFindData ) ) { if( !strcmp( sttFindData.cFileName, "." ) || !strcmp( sttFindData.cFileName, ".." ) ) continue; if( sttFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) continue; clsFileList.push_back( sttFindData.cFileName ); } FindClose( hFind ); #else DIR * psttDir; struct dirent * psttDirent, sttDirent; struct stat sttStat; int n; std::string strFileName; psttDir = opendir( pszDirName ); if( psttDir == NULL ) { CLog::Print( LOG_ERROR, "opendir(%s) error(%d)", pszDirName, errno ); return false; } for( n = readdir_r( psttDir, &sttDirent, &psttDirent ); psttDirent && n == 0; n = readdir_r( psttDir, &sttDirent, &psttDirent ) ) { if( !strcmp( psttDirent->d_name, "." ) || !strcmp( psttDirent->d_name, ".." ) ) continue; strFileName = pszDirName; AppendName( strFileName, psttDirent->d_name ); if( lstat( strFileName.c_str(), &sttStat ) < 0 ) continue; if( S_ISDIR( sttStat.st_mode ) ) continue; clsFileList.push_back( psttDirent->d_name ); } closedir( psttDir ); #endif return true; } /** * @ingroup SipPlatform * @brief ÇÁ·Î±×·¥À» ½ÃÀÛÇÑ Æú´õ¸¦ °¡Á®¿Â´Ù. * @returns ÇÁ·Î±×·¥À» ½ÃÀÛÇÑ Æú´õ °æ·Î¸¦ ¸®ÅÏÇÑ´Ù. */ char * CDirectory::GetProgramDirectory( ) { static char szDir[1024]; if( strlen(szDir) == 0 ) { #ifdef WIN32 int i; HMODULE hThis; hThis = GetModuleHandle( NULL ); GetModuleFileName( hThis, szDir, sizeof(szDir)); for( i = (int)strlen( szDir) - 1; i >= 0; i-- ) { if( szDir[i] == '\\' ) { szDir[i] = '\0'; break; } } #else if( readlink( "/proc/self/exe", szDir, sizeof(szDir) ) != -1 ) { for( int i = (int)strlen( szDir) - 1; i >= 0; i-- ) { if( szDir[i] == '/' ) { szDir[i] = '\0'; break; } } } #endif } return szDir; } #define MAX_INT 4294967296L /** * @ingroup SipPlatform * @brief Æú´õ Å©±â¸¦ °¡Á®¿Â´Ù. * @param pszDirName Æú´õ fulll path * @returns Æú´õ Å©±â¸¦ ¸®ÅÏÇÑ´Ù. */ int64_t CDirectory::GetSize( const char * pszDirName ) { uint64_t iTotalSize = 0; #ifdef WIN32 WIN32_FIND_DATA sttFindData; HANDLE hFind; BOOL bNext = TRUE; std::string strPath = pszDirName; strPath.append( "\\*.*" ); hFind = FindFirstFile( strPath.c_str(), &sttFindData ); if( hFind == INVALID_HANDLE_VALUE ) { CLog::Print( LOG_ERROR, "FindFirstFile(%s) error(%d)", pszDirName, GetLastError() ); return false; } for( ; bNext == TRUE; bNext = FindNextFile( hFind, &sttFindData ) ) { if( !strcmp( sttFindData.cFileName, "." ) || !strcmp( sttFindData.cFileName, ".." ) ) continue; if( sttFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { std::string strFolder = pszDirName; AppendName( strFolder, sttFindData.cFileName ); iTotalSize += GetSize( strFolder.c_str() ); continue; } if( sttFindData.nFileSizeHigh > 0 ) { iTotalSize += (uint64_t)sttFindData.nFileSizeHigh * MAX_INT; } iTotalSize += sttFindData.nFileSizeLow; } FindClose( hFind ); #else DIR * psttDir; struct dirent * psttDirent, sttDirent; struct stat sttStat; int n; std::string strFileName; psttDir = opendir( pszDirName ); if( psttDir == NULL ) { CLog::Print( LOG_ERROR, "opendir(%s) error(%d)", pszDirName, errno ); return false; } for( n = readdir_r( psttDir, &sttDirent, &psttDirent ); psttDirent && n == 0; n = readdir_r( psttDir, &sttDirent, &psttDirent ) ) { if( !strcmp( psttDirent->d_name, "." ) || !strcmp( psttDirent->d_name, ".." ) ) continue; strFileName = pszDirName; AppendName( strFileName, psttDirent->d_name ); if( lstat( strFileName.c_str(), &sttStat ) < 0 ) continue; if( S_ISDIR( sttStat.st_mode ) ) { std::string strFolder = pszDirName; AppendName( strFolder, psttDirent->d_name ); iTotalSize += GetSize( strFolder.c_str() ); continue; } iTotalSize += sttStat.st_size; } closedir( psttDir ); #endif return iTotalSize; } /** * @ingroup SipPlatform * @brief Æú´õ¿¡ Æ÷ÇÔµÈ ÆÄÀϵéÀ» ¸ðµÎ »èÁ¦ÇÑ´Ù. * @param pszDirName Æú´õ full path */ void CDirectory::DeleteAllFile( const char * pszDirName ) { FILE_LIST::iterator itFile; FILE_LIST clsFileList; FileList( pszDirName, clsFileList ); for( itFile = clsFileList.begin(); itFile != clsFileList.end(); ++itFile ) { std::string strFileName = pszDirName; CDirectory::AppendName( strFileName, itFile->c_str() ); #ifdef WIN32 DeleteFile( strFileName.c_str() ); #else unlink( strFileName.c_str() ); #endif } } /** * @ingroup SipPlatform * @brief ÆÄÀÏ °æ·Î¿¡¼­ Æú´õ À̸§À» °¡Á®¿Â´Ù. * @param pszFilePath ÆÄÀÏ °æ·Î * @param strDirName Æú´õ À̸§À» ÀúÀåÇÒ º¯¼ö */ void CDirectory::GetDirName( const char * pszFilePath, std::string & strDirName ) { int iLen = (int)strlen( pszFilePath ); strDirName.clear(); for( int i = iLen - 1; i >= 0; --i ) { #ifdef WIN32 if( pszFilePath[i] == '\\' ) #else if( pszFilePath[i] == '/' ) #endif { strDirName.append( pszFilePath, i ); break; } } } /** * @ingroup SipPlatform * @brief ÆÄÀÏ °æ·Î¿¡¼­ ÆÄÀÏ À̸§À» °¡Á®¿Â´Ù. * @param pszFilePath ÆÄÀÏ °æ·Î * @param strFileName ÆÄÀÏ À̸§À» ÀúÀåÇÒ º¯¼ö */ void CDirectory::GetFileName( const char * pszFilePath, std::string & strFileName ) { int iLen = (int)strlen( pszFilePath ); strFileName.clear(); for( int i = iLen - 1; i >= 0; --i ) { #ifdef WIN32 if( pszFilePath[i] == '\\' ) #else if( pszFilePath[i] == '/' ) #endif { strFileName = pszFilePath + i + 1; break; } } } /** * @ingroup SipPlatform * @brief Æú´õ¸¦ ¸ðµÎ »èÁ¦ÇÑ´Ù. * @param pszDirName Æú´õ À̸§ * @returns ¼º°øÇϸé true ¸¦ ¸®ÅÏÇÏ°í ½ÇÆÐÇϸé false ¸¦ ¸®ÅÏÇÑ´Ù. */ bool CDirectory::Delete( const char * pszDirName ) { #ifdef WIN32 WIN32_FIND_DATA sttFindData; HANDLE hFind; BOOL bNext = TRUE; std::string strPath = pszDirName; std::string strFileName; strPath.append( "\\*.*" ); hFind = FindFirstFile( strPath.c_str(), &sttFindData ); if( hFind == INVALID_HANDLE_VALUE ) { CLog::Print( LOG_ERROR, "FindFirstFile(%s) error(%d)", pszDirName, GetLastError() ); return false; } for( ; bNext == TRUE; bNext = FindNextFile( hFind, &sttFindData ) ) { if( !strcmp( sttFindData.cFileName, "." ) || !strcmp( sttFindData.cFileName, ".." ) ) continue; strFileName = pszDirName; CDirectory::AppendName( strFileName, sttFindData.cFileName ); if( sttFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { CDirectory::Delete( strFileName.c_str() ); RemoveDirectory( strFileName.c_str() ); } else { DeleteFile( strFileName.c_str() ); } } FindClose( hFind ); RemoveDirectory( pszDirName ); #else DIR * psttDir; struct dirent * psttDirent, sttDirent; struct stat sttStat; int n; std::string strFileName; psttDir = opendir( pszDirName ); if( psttDir == NULL ) { CLog::Print( LOG_ERROR, "opendir(%s) error(%d)", pszDirName, errno ); return false; } for( n = readdir_r( psttDir, &sttDirent, &psttDirent ); psttDirent && n == 0; n = readdir_r( psttDir, &sttDirent, &psttDirent ) ) { if( !strcmp( psttDirent->d_name, "." ) || !strcmp( psttDirent->d_name, ".." ) ) continue; strFileName = pszDirName; AppendName( strFileName, psttDirent->d_name ); if( lstat( strFileName.c_str(), &sttStat ) < 0 ) continue; if( S_ISDIR( sttStat.st_mode ) ) { CDirectory::Delete( strFileName.c_str() ); rmdir( strFileName.c_str() ); } else { unlink( strFileName.c_str() ); } } closedir( psttDir ); rmdir( pszDirName ); #endif return true; }
X Tutup