BOOL CPackage::setFragDownloaded( LPCTSTR lpstrFragID) { CString csTask, csTempTask, csBuffer; CStdioFile fileTask, fileTempTask; UINT uIndex = 0; ASSERT( lpstrFragID); try { csTask.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_TASK); // First, create a backup copy of task file csTempTask.Format( _T( "%s\\%s\\%s.tmp"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_TASK); if (!CopyFile( csTask, csTempTask, FALSE)) return FALSE; // Now, write task backup content to task, except when lpstrID if (!fileTask.Open( csTask, CFile::modeCreate|CFile::modeWrite|CFile::typeText|CFile::shareDenyWrite)) return FALSE; if (!fileTempTask.Open( csTempTask, CFile::modeRead|CFile::typeText|CFile::shareDenyNone)) { fileTask.Abort(); return FALSE; } while (fileTempTask.ReadString( csBuffer)) { if (csBuffer.CompareNoCase( lpstrFragID) != 0) { // This is not our fragment ID fileTask.WriteString( csBuffer); fileTask.WriteString( _T( "\n")); } } fileTask.Close(); fileTempTask.Close(); // Success, so delete backup file return DeleteFile( csTempTask); } catch( CException *pEx) { pEx->Delete(); fileTempTask.Abort(); fileTask.Abort(); return FALSE; } }
BOOL CPackage::setDone( LPCTSTR lpstrCode, LPCTSTR lpstrOutput) { CStdioFile myFile; CString csFile, csResult; csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_DONE); try { if (!myFile.Open( csFile, CFile::modeCreate|CFile::modeWrite|CFile::typeText|CFile::shareDenyWrite)) return FALSE; // First line is result code csResult.Format( _T( "%s\n"), lpstrCode); myFile.WriteString( csResult); if (lpstrOutput) // Following lines are command ouput myFile.WriteString( lpstrOutput); myFile.Close(); } catch( CException *pEx) { pEx->Delete(); myFile.Abort(); DeleteFile( csFile); return FALSE; } return TRUE; }
BOOL CPackage::getDone( CString &csCode, CString &csOutput) { CString csFile, csBuffer; CStdioFile myFile; csCode = ERR_DONE_FAILED; try { // Open package done file csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_DONE); if (!myFile.Open( csFile, CFile::modeRead|CFile::typeText|CFile::shareDenyNone)) return FALSE; // Read first line to get result code myFile.ReadString( csCode); // Following lines are command ouput while (myFile.ReadString( csBuffer)) csOutput.AppendFormat( _T( "%s\n"), csBuffer); myFile.Close(); return TRUE; } catch( CException *pEx) { pEx->Delete(); myFile.Abort(); csCode = ERR_DONE_FAILED; return FALSE; } }
BOOL CPackage::getDone( CString &csCode) { CString csFile; CStdioFile myFile; csCode = ERR_DONE_FAILED; try { // Open package done file csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_DONE); if (!myFile.Open( csFile, CFile::modeRead|CFile::typeText|CFile::shareDenyNone)) return FALSE; // Read only first line to get OCS result code myFile.ReadString( csCode); myFile.Close(); return TRUE; } catch( CException *pEx) { pEx->Delete(); myFile.Abort(); csCode = ERR_DONE_FAILED; return FALSE; } }
BOOL CPackage::createTask() { CString csTask, csBuffer; CStdioFile myFile; csTask.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_TASK); try { if (!myFile.Open( csTask, CFile::modeCreate|CFile::modeWrite|CFile::typeText|CFile::shareDenyWrite)) return FALSE; for (UINT uIndex=1; uIndex<=m_uFrags; uIndex++) { csBuffer.Format( _T( "%s-%u\n"), m_csID, uIndex); myFile.WriteString( csBuffer); } myFile.Close(); } catch( CException *pEx) { pEx->Delete(); myFile.Abort(); DeleteFile( csTask); return FALSE; } return TRUE; }
BOOL CPackage::existTask() { CString csTask; csTask.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_TASK); return fileExists( csTask); }
time_t COptDownloadPackage::getTimeStamp() { CString csFilename, csTimestamp; // Check if not already retrieved from file if (m_tTimePack != 0) return m_tTimePack; try { // Load "since" file content csFilename.Format(_T("%s\\%s\\%s"), getDownloadFolder(), m_csId, OCS_DOWNLOAD_TIMESTAMP); if (!LoadFileToText(csTimestamp, csFilename)) { m_tTimePack = 0; return m_tTimePack; } m_tTimePack = (time_t)_ttol(csTimestamp); } catch (CException *pEx) { pEx->Delete(); m_tTimePack = 0; } return m_tTimePack; }
BOOL CPackage::existDone() { CString csTaskDone; // Is package done file existing csTaskDone.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_DONE); return fileExists( csTaskDone);; }
LPCTSTR CPackage::getFragLocalPath( LPCTSTR lpstrFragID) { static CString csBuffer; ASSERT( lpstrFragID); csBuffer.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, lpstrFragID); return csBuffer; }
BOOL CCapDownload::checkOcsAgentSetupResult() { CString csFile, csCode = ERR_DONE_FAILED, csID; CStdioFile myFile; csFile.Format(_T("%s\\%s"), getDownloadFolder(), OCS_AGENT_SETUP_DONE); if (!fileExists(csFile)) // No OCS Agent Setup done file return TRUE; m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Found OCS Inventory Agent Setup result file <%s>"), csFile); // Open OCS Agent Setup done file to read exit code and package ID try { if (!myFile.Open(csFile, CFile::modeRead | CFile::typeText | CFile::shareDenyNone)) return FALSE; // First line contains result code and seconf line contains package ID myFile.ReadString(csCode); myFile.ReadString(csID); myFile.Close(); } catch (CException *pEx) { pEx->Delete(); myFile.Abort(); m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Failed reading OCS Inventory Agent Setup result file <%s>"), csFile); return FALSE; } if (csID.IsEmpty()) { // Upgrading from agent 1.X or previous to 2.0.0.22 ? m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Found result code <%s> for OCS Inventory Agent Setup package but no package ID specified, so remove all packages to avoid running Agent setup in loop !"), csCode); COptDownloadPackage::cleanAll(); return FALSE; } // All information available => copy result file to Package directory csFile.Format(_T("%s\\%s\\%s"), getDownloadFolder(), csID, OCS_DOWNLOAD_DONE); if (!CopyFile(myFile.GetFilePath(), csFile, FALSE)) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Failed to copy result code for OCS Inventory Agent Setup package to file <%s>"), csFile); return FALSE; } DeleteFile(myFile.GetFilePath()); m_pLogger->log(LOG_PRIORITY_NOTICE, _T("DOWNLOAD => Validated result code <%s> for OCS Inventory Agent Setup package <%s>"), csCode, csID); return TRUE; }
BOOL CPackage::isFragTodownload() { CString csTask, csTempTask; CFileStatus rStatus; csTask.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_TASK); // Check if task.tmp exists (task save before update). If so, use it csTempTask.Format( _T( "%s\\%s\\%s.tmp"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_TASK); if (fileExists( csTempTask)) { DeleteFile( csTask); MoveFile( csTempTask, csTask); } // If task filesize > 0, there is frag to download if (CFile::GetStatus( csTask, rStatus)) return (rStatus.m_size > 0); return FALSE; }
BOOL CPackage::clean( LPCTSTR lpstrID) { CString csPath; ASSERT( lpstrID); // Now, really delete package directory csPath.Format( _T( "%s\\%s"), getDownloadFolder(), lpstrID); return directoryDelete( csPath); }
BOOL CPackage::isBuilt() { CString csFile; // If there is no fragement, assume package built if (m_uFrags == 0) // No fragment return TRUE; // Check if first fragment exist csFile.Format( _T( "%s\\%s\\%s-1"), getDownloadFolder(), m_csID, m_csID); if (fileExists( csFile)) // Package not built, or previous build unsuccessfull return FALSE; // Check if ZIP exist csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_BUILD); if (!fileExists( csFile)) // build.zip not existing return FALSE; return TRUE; }
BOOL CPackage::deleteFragement() { CString csFile; for (UINT uIndex=1; uIndex<=m_uFrags; uIndex++) { csFile.Format( _T( "%s\\%s\\%s-%u"), getDownloadFolder(), m_csID, m_csID, uIndex); DeleteFile( csFile); } return TRUE; }
BOOL CPackage::clean() { CString csPath; // Only delete unzip directory if is not a store action if ((m_csAction != OCS_DOWNLOAD_ACTION_STORE) && !m_csPath.IsEmpty() && fileExists( m_csPath)) directoryDelete( m_csPath); // Delete scheduler if needed deleteScheduler(); // Delete download package directory and registry key csPath.Format( _T( "%s\\%s"), getDownloadFolder(), m_csID); return (regDeletePackageDigest() && directoryDelete( csPath)); }
BOOL CPackage::checkSignature() { CString csFile, csDigest, csRegDigest; BOOL bRes; // Read meta data digest in the registry and verify it if (!regReadPackageDigest( csRegDigest)) // No digest registered in Registry return FALSE; csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_METADATA); if (!fileDigest( csFile, csDigest)) // Unable to compute digest on meta data return FALSE; if (csRegDigest.Compare( csDigest) != 0) // Digest registered in Registry is not the same return FALSE; // Now, check ZIP digest if (m_uFrags > 0) { // Compute digest on build.zip file csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_BUILD); if (isBase64()) bRes = fileDigest( csFile, csDigest, m_csDigestAlgo); else if (isHexadecimal()) bRes = fileDigest( csFile, csDigest, m_csDigestAlgo, FALSE); else // Unsupported encoding return FALSE; // Digest compute successfully if (bRes && (m_csDigest.Compare( csDigest) == 0)) return TRUE; else return FALSE; } // No ZIP file return TRUE; }
BOOL CPackage::isExpired( UINT uTimeOut) { time_t tTimeNow; CString csFile; // Check if timestamp exist first csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_TIMESTAMP); if (!fileExists( csFile)) // Timestamp does not exist, so not expired return FALSE; // Timestamp exists, verify expiration tTimeNow = time( NULL); return (((tTimeNow - getTimeStamp())/86400) > uTimeOut); }
BOOL CCapDownload::writeConfig() { CString csFileName; BOOL bResult = TRUE; csFileName.Format(_T("%s\\%s"), getDownloadFolder(), OCS_CONFIG_FILENAME); bResult = WritePrivateProfileString(OCS_AGENT_SECTION, _T("FragLatency"), m_csDownloadFragLatency, csFileName); bResult = bResult && WritePrivateProfileString(OCS_AGENT_SECTION, _T("CycleLatency"), m_csDownloadCycleLatency, csFileName); bResult = bResult && WritePrivateProfileString(OCS_AGENT_SECTION, _T("PeriodLatency"), m_csDownloadPeriodLatency, csFileName); bResult = bResult && WritePrivateProfileString(OCS_AGENT_SECTION, _T("PeriodLength"), m_csDownloadPeriodLength, csFileName); bResult = bResult && WritePrivateProfileString(OCS_AGENT_SECTION, _T("Timeout"), m_csDownloadTimeout, csFileName); bResult = bResult && WritePrivateProfileString(OCS_AGENT_SECTION, _T("CommandTimeout"), m_csCommandTimeout, csFileName); bResult = bResult && WritePrivateProfileString(OCS_AGENT_SECTION, _T("On"), m_csDownloadOn, csFileName); return bResult; }
BOOL COptDownloadPackage::clean(LPCTSTR lpstrID) { CString csPath; ASSERT(lpstrID); // Delete tmp path folder where package was unzipped (not an eror if not existing) if (GetTempPath(_MAX_PATH, csPath.GetBufferSetLength(_MAX_PATH + 1)) == 0) return FALSE; csPath.ReleaseBuffer(); csPath.AppendFormat(_T("\\%s.OCS"), lpstrID); directoryDelete(csPath); // Delete scheuler if needed deletePackageScheduler(lpstrID); // Now, really delete package directory and registry signature csPath.Format(_T("%s\\%s"), getDownloadFolder(), lpstrID); regDeletePackageDigest(lpstrID); return (directoryDelete(csPath)); }
BOOL CPackage::unZip() { CZipArchive cZip; CString csFile; // If there is no fragement, assume package unzipped if (m_uFrags == 0) // No fragment return TRUE; csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_BUILD); try { cZip.Open( csFile); for(ZIP_INDEX_TYPE i=0; i<cZip.GetCount();i++) cZip.ExtractFile(i, m_csPath); cZip.Close(); // Create package ID file into unzip directory only if not in store action if (m_csAction != OCS_DOWNLOAD_ACTION_STORE) { CStdioFile cFile; csFile.Format( _T( "%s\\%s"), m_csPath, OCS_DOWNLOAD_PACKAGE_ID); if (cFile.Open( csFile, CFile::modeCreate|CFile::modeWrite|CFile::typeText)) { cFile.WriteString( m_csID); cFile.Close(); } } } catch (CException *pE) { pE->Delete(); cZip.Close( CZipArchive::afAfterException); return FALSE; } catch (std::exception *pEx) { cZip.Close( CZipArchive::afAfterException); delete pEx; return FALSE; } return TRUE; }
BOOL COptDownloadPackage::cleanAll() { CString csPath; CFileFind cFinder; BOOL bWorking; csPath.Format(_T("%s\\*.*"), getDownloadFolder()); bWorking = cFinder.FindFile(csPath); while (bWorking) { bWorking = cFinder.FindNextFile(); // Skip . and .. files; otherwise, we'd recur infinitely! if (cFinder.IsDots()) continue; // if it's a directory, delete corresponding package if (cFinder.IsDirectory()) COptDownloadPackage::clean(cFinder.GetFileName()); } cFinder.Close(); return TRUE; }
BOOL CPackage::getFragToDownload( CString &csFragID) { CStdioFile myFile; CString csTask; csFragID.Empty(); try { csTask.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_TASK); if (!myFile.Open( csTask, CFile::modeRead|CFile::typeText|CFile::shareDenyNone)) return FALSE; myFile.ReadString( csFragID); myFile.Close(); } catch( CException *pEx) { pEx->Delete(); myFile.Abort(); return FALSE; } return TRUE; }
BOOL CPackage::setExecTry( UINT uTry) { CStdioFile myFile; CString csFile; csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_EXECUTE_TRY); try { if (!myFile.Open( csFile, CFile::modeCreate|CFile::modeWrite|CFile::typeText|CFile::shareDenyWrite)) return FALSE; // First line is result code csFile.Format( _T( "%u"), uTry); myFile.WriteString( csFile); myFile.Close(); } catch( CException *pEx) { pEx->Delete(); myFile.Abort(); DeleteFile( csFile); return FALSE; } return TRUE; }
BOOL CPackage::getExecTry( UINT *puTry) { CString csFile; CStdioFile myFile; try { // Open package done file csFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_EXECUTE_TRY); if (!myFile.Open( csFile, CFile::modeRead|CFile::typeText|CFile::shareDenyNone)) return FALSE; // Read only first line to get OCS result code myFile.ReadString( csFile); *puTry = _ttol( csFile); myFile.Close(); return TRUE; } catch( CException *pEx) { pEx->Delete(); myFile.Abort(); return FALSE; } }
int COptDownloadPackage::downloadInfoFile() { CConfig *pAgentConfig = getAgentConfig(); CComProvider *pProvider = getComServerProvider(); CServerConfig *pServerConfig = pProvider->newConfig(); CConnexionAbstract *pConnexion = NULL; TCHAR szDummy[_MAX_PATH + 1]; ASSERT(pAgentConfig); ASSERT(pProvider); ASSERT(pServerConfig); // Create provider connection object using default Provider configuration if ((pConnexion = pProvider->newConnexion(pServerConfig)) == NULL) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Failed creating connection for Communication Provider <%s>"), pAgentConfig->getCommunicationProvider()); pProvider->deleteConfig(pServerConfig); return FALSE; } // Download metadata info file m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Metadata file <info> for package <%s> is located at <%s>"), m_csId, getRemoteMetadataURL()); if (!pConnexion->getFile(getRemoteMetadataURL(), getLocalMetadataFilename())) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Failed to download Metadata file <%s> to <%s>"), getRemoteMetadataURL(), getLocalMetadataFilename()); pProvider->deleteConnexion(pConnexion); pProvider->deleteConfig(pServerConfig); return FALSE; } m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Unloading communication provider")); // Use provider to delete connexion and server config pProvider->deleteConnexion(pConnexion); pProvider->deleteConfig(pServerConfig); // Open metadata file to add fragment location CString csBuffer; CMarkup xml; if (!xml.LoadFile(getLocalMetadataFilename())) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Cannot read or parse Metadata file <%s>"), getLocalMetadataFilename()); return FALSE; } // Add fragment location to meta data xml.FindFirstElem(_T("DOWNLOAD")); xml.SetAttrib(_T("LOC"), m_csRemotePackLoc); // Add package schedule to meta data xml.SetAttrib(_T("SCHEDULE"), m_csSchedule); // Add post execution command to meta data xml.SetAttrib(_T("POSTCMD"), m_csPostCmd); // Write meta data file if (!xml.SaveFile(getLocalMetadataFilename())) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Can't update Metadata file <%s>"), getLocalMetadataFilename()); return FALSE; } // Compute digest on meta data and add it to Registry if (!fileDigest(getLocalMetadataFilename(), csBuffer)) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Can't register package <%s> into Registry"), m_csId); DeleteFile(getLocalMetadataFilename()); return FALSE; } if (!regAddPackageDigest(m_csId, csBuffer)) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Can't register package <%s> into Registry"), m_csId); DeleteFile(getLocalMetadataFilename()); return FALSE; } // Now create a timestamp csBuffer.Format(_T("%s\\%s\\%s"), getDownloadFolder(), m_csId, OCS_DOWNLOAD_TIMESTAMP); if (!fileExists(csBuffer)) { _ltot(time(NULL), szDummy, 10); if (!WriteTextToFile(szDummy, csBuffer)) m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Can't create timestamp file <%s>"), csBuffer); } else m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Timestamp file <%s> already exists"), csBuffer); m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Retrieve info file...OK (pack %s)"), m_csId); return TRUE; }
BOOL CCapDownload::retrievePackages() { CString csCertFile, csId, csValue; COptDownloadPackage *pOptDownloadPackage; CMapStringToStringArray *pMapArray = NULL; CMapStringToString *pMap = NULL; INT_PTR nPack = 0; /*** * * Environnement checking * ***/ // Working directory if (directoryCreate(getDownloadFolder()) == FALSE) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Cannot create working directory (%s)"), LookupError(GetLastError())); return FALSE; } // Open package history file, create it if needed CFilePackageHistory cFileHistory; if (!cFileHistory.Open(getPackageHistoryFilename(), FALSE, TRUE)) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Cannot create history file <%>"), getPackageHistoryFilename()); return FALSE; } if (!m_pPrologResp->isDownloadRequired()) { m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => No package available for download")); return FALSE; } // Trying to create suspend Download tool if (!suspendDownload()) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Cannot suspend Download and Setup Tool using <%s> file"), OCS_DOWNLOAD_SUSPEND); return FALSE; } // Trying to get exclusive access to download if (!lockDownload()) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Cannot lock directory <%s>"), getDownloadFolder()); resumeDownload(); return FALSE; } // Get generic download parameters and write them for using with download tool pMapArray = m_pPrologResp->getDownloadParameters(); if ((pMapArray == NULL) || pMapArray->IsEmpty()) { m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => No download parameter available")); unlockDownload(); resumeDownload(); return FALSE; } // There is only one record for download parameters pMap = pMapArray->GetAt(0); pMap->Lookup(_T("FRAG_LATENCY"), m_csDownloadFragLatency); pMap->Lookup(_T("CYCLE_LATENCY"), m_csDownloadCycleLatency); pMap->Lookup(_T("PERIOD_LATENCY"), m_csDownloadPeriodLatency); pMap->Lookup(_T("PERIOD_LENGTH"), m_csDownloadPeriodLength); pMap->Lookup(_T("TIMEOUT"), m_csDownloadTimeout); pMap->Lookup(_T("EXECUTION_TIMEOUT"), m_csCommandTimeout); if (m_csCommandTimeout.IsEmpty()) m_csCommandTimeout = COMMAND_TIMEOUT_DEFAULT; pMap->Lookup(_T("ON"), m_csDownloadOn); writeConfig(); delete pMapArray; pMapArray = NULL; // Now get each package information pMapArray = m_pPrologResp->getDownloadPackages(); for (nPack = 0; (pMapArray != NULL) && (nPack<pMapArray->GetCount()); nPack++) { if (((pMap = pMapArray->GetAt(nPack)) == NULL) || pMap->IsEmpty()) continue; csId.Empty(); pMap->Lookup(_T("ID"), csId); // Try to find if package was not previously downloaded, parsing package history file CString csHistBuf; BOOL bAlreadySetup = FALSE; cFileHistory.SeekToBegin(); while (cFileHistory.ReadPackage(csHistBuf)) { if (csHistBuf.Find(csId) != -1) { // Package ID found in history bAlreadySetup = TRUE; break; } } pOptDownloadPackage = new COptDownloadPackage(this); pOptDownloadPackage->setId(csId); // If CERT_PATH or CERT_FILE option is provided csValue.Empty(); pMap->Lookup(_T("CERT_PATH"), csValue); pOptDownloadPackage->setCertPath(csValue); csValue.Empty(); pMap->Lookup(_T("CERT_FILE"), csValue); pOptDownloadPackage->setCertFile(csValue); // Set URL where to download INFO metadata csValue.Empty(); pMap->Lookup(_T("INFO_LOC"), csValue); pOptDownloadPackage->setInfoLocation(csValue); // Set URL where to download fragment csValue.Empty(); pMap->Lookup(_T("PACK_LOC"), csValue); pOptDownloadPackage->setPackLocation(csValue); // Set if we have to force package setup, even if already installed csValue.Empty(); pMap->Lookup(_T("FORCE"), csValue); pOptDownloadPackage->setForce(csValue); // Set if we have to schedule package setup at specified date csValue.Empty(); pMap->Lookup(_T("SCHEDULE"), csValue); pOptDownloadPackage->setSchedule(csValue); // Set post execution command if package action succeeded csValue.Empty(); pMap->Lookup(_T("POSTCMD"), csValue); pOptDownloadPackage->setPostCmd(csValue); if (bAlreadySetup && !pOptDownloadPackage->isForced()) { // Package ID found in history, do not download m_pLogger->log(LOG_PRIORITY_NOTICE, _T("DOWNLOAD => Will not download package <%s>, already in the package history"), csId); sendMessage(csId, SUCCESS_ALREADY_SETUP); // Delete already download directory if needed pOptDownloadPackage->clean(); delete pOptDownloadPackage; } else { // Package not already downloaded, or setup forced, put it in the download queue if (pOptDownloadPackage->isForced()) m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Package <%s> forced, ignoring package history check"), csId); m_tPackages.Add(pOptDownloadPackage); } } cFileHistory.Close(); delete pMapArray; // Cleaning file history for duplicates switch (CFilePackageHistory::CleanDuplicates(getPackageHistoryFilename())) { case 1: m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Package history file successfully cleaned for duplicate IDs")); break; case 2: m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Package history file cleaning not required")); break; default: m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Failed to clean Package history file for duplicate IDs")); break; } // Now, prepare directories and download instructions for download tool for (nPack = 0; nPack<m_tPackages.GetSize(); nPack++) { pOptDownloadPackage = (COptDownloadPackage*)(m_tPackages[nPack]); // Check if package is not expired if (pOptDownloadPackage->isExpired(m_csDownloadTimeout)) { ULONG ulNow = time(NULL); m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Package <%s> timed out (now:%lu, since:%lu, Timeout:%s)"), pOptDownloadPackage->getId(), ulNow, (ULONG)pOptDownloadPackage->getTimeStamp(), m_csDownloadTimeout); if (sendMessage(pOptDownloadPackage->getId(), ERR_TIMEOUT)) // Server successfully notified => remove package if (!pOptDownloadPackage->clean()) m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Failed to remove timed out package <%s>"), pOptDownloadPackage->getId()); } else { // Check if package not already added to download queue if (pOptDownloadPackage->makeDirectory() && !fileExists(pOptDownloadPackage->getLocalMetadataFilename())) { // Download metadata from deployment server if (pOptDownloadPackage->downloadInfoFile()) m_pLogger->log(LOG_PRIORITY_NOTICE, _T("DOWNLOAD => Package <%s> added to download queue"), pOptDownloadPackage->getId()); else // Error dowloading metadata => remove package directory to avoid error message into download tool pOptDownloadPackage->clean(); } else m_pLogger->log(LOG_PRIORITY_DEBUG, _T("DOWNLOAD => Package <%s> already in download queue, keeping on package"), pOptDownloadPackage->getId()); } } // Now, allow Download tool unlockDownload(); resumeDownload(); return TRUE; }
BOOL CPackage::build() { CString csFile, csZipFile; CFileStatus cfStatus; __int64 i64BuildSize = 0; UINT uIndex; CLog *pLog = getOcsLogger(); CFile fileZip, fileFrag; if (m_uFrags == 0) { pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => No fragment files for package <%s>, nothing to build"), m_csID); return TRUE; } // Ensure all fragment are available pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Verifying fragment files of package <%s>"), m_csID); for (uIndex=1; uIndex<=m_uFrags; uIndex++) { csFile.Format( _T( "%s\\%s\\%s-%u"), getDownloadFolder(), m_csID, m_csID, uIndex); if (!CFile::GetStatus( csFile, cfStatus)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Fragment file <%s> is missing or unreadable"), csFile); setDone( ERR_BUILD); return FALSE; } i64BuildSize += cfStatus.m_size; } pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Checking free disk space for package <%s>"), m_csID); GetCurrentDirectory( 4*_MAX_PATH, csFile.GetBuffer( 4*_MAX_PATH)); csFile.ReleaseBuffer(); if (GetDiskFree( csFile) < (3*i64BuildSize)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Free disk space missing for package <%s> (required at least %I64d bytes)"), m_csID, 3*i64BuildSize); setDone( ERR_OUT_OF_SPACE); return FALSE; } // Concatenate each fragment file into build.zip pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Building ZIP for package <%s>"), m_csID); csZipFile.Format( _T( "%s\\%s\\%s"), getDownloadFolder(), m_csID, OCS_DOWNLOAD_BUILD); try { if (!fileZip.Open( csZipFile, CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Cannot create Zip <%s> from fragment files"), csZipFile); setDone( ERR_BUILD); return FALSE; } for (uIndex=1; uIndex<=m_uFrags; uIndex++) { // Read data in frag file and write it in zip file csFile.Format( _T( "%s\\%s\\%s-%u"), getDownloadFolder(), m_csID, m_csID, uIndex); if (!fileFrag.Open( csFile, CFile::modeRead|CFile::shareDenyNone)) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Cannot read Fragment file <%s>"), csFile); setDone( ERR_BUILD); return FALSE; } UINT uLength; BYTE pBuffer[1024]; BOOL bContinue = TRUE; while (bContinue) { uLength = fileFrag.Read( pBuffer, 1024); fileZip.Write( pBuffer, uLength); // Stop if read less than 1024 bytes if (uLength < 1024) bContinue = FALSE; } fileFrag.Close(); } fileZip.Close(); } catch (CException *pEx) { pEx->Delete(); fileZip.Abort(); fileFrag.Abort(); DeleteFile( csZipFile); pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Cannot read Fragment file <%s>"), csFile); setDone( ERR_BUILD); return FALSE; } // Verify signature pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Verifying ZIP signature for package <%s>"), m_csID); if (!checkSignature()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed verifying signature for Package <%s>"), m_csID); setDone( ERR_BAD_DIGEST); return FALSE; } // Delete frag files, no more needed deleteFragement(); return TRUE; }