STDMETHODIMP GuestSessionWrap::DirectoryCreate(IN_BSTR aPath, ULONG aMode, ComSafeArrayIn(DirectoryCreateFlag_T, aFlags)) { LogRelFlow(("{%p} %s:enter aPath=%ls aMode=%RU32 aFlags=%zu\n", this, "GuestSession::directoryCreate", aPath, aMode, aFlags)); VirtualBoxBase::clearError(); HRESULT hrc; try { AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) throw autoCaller.rc(); hrc = directoryCreate(BSTRInConverter(aPath).str(), aMode, ArrayInConverter<DirectoryCreateFlag_T>(ComSafeArrayInArg(aFlags)).array()); } catch (HRESULT hrc2) { hrc = hrc2; } catch (...) { hrc = VirtualBoxBase::handleUnexpectedExceptions(this, RT_SRC_POS); } LogRelFlow(("{%p} %s: leave hrc=%Rhrc\n", this, "GuestSession::directoryCreate", hrc)); return hrc; }
bool File::directoryCreate( Path const & p_path, FlagCombination< CreateMode > const & p_flags ) { Path path = p_path.getPath(); if ( !path.empty() && !directoryExists( path ) ) { directoryCreate( path, p_flags ); } mode_t mode = 0; if ( checkFlag( p_flags, CreateMode::eUserRead ) ) { mode |= S_IRUSR; } if ( checkFlag( p_flags, CreateMode::eUserWrite ) ) { mode |= S_IWUSR; } if ( checkFlag( p_flags, CreateMode::eUserExec ) ) { mode |= S_IXUSR; } if ( checkFlag( p_flags, CreateMode::eGroupRead ) ) { mode |= S_IRGRP; } if ( checkFlag( p_flags, CreateMode::eGroupWrite ) ) { mode |= S_IWGRP; } if ( checkFlag( p_flags, CreateMode::eGroupExec ) ) { mode |= S_IXGRP; } if ( checkFlag( p_flags, CreateMode::eOthersRead ) ) { mode |= S_IROTH; } if ( checkFlag( p_flags, CreateMode::eOthersWrite ) ) { mode |= S_IWOTH; } if ( checkFlag( p_flags, CreateMode::eOthersExec ) ) { mode |= S_IXOTH; } return mkdir( string::stringCast< char >( p_path ).c_str(), mode ) == 0; }
BOOL COptDownloadPackage::makeDirectory() { if (!directoryCreate(m_csLocalPackLoc)) { m_pLogger->log(LOG_PRIORITY_ERROR, _T("DOWNLOAD => Cannot create package <%s> directory (%s)"), m_csId, LookupError(GetLastError())); return FALSE; } 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; }
UINT CPackage::execute( UINT uCommandTimeOut) { CLog *pLog = getOcsLogger(); CExecCommand cmProcess; CString csBuffer; UINT uTry; // Check signature before executing package if (!checkSignature()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed verifying signature for Package <%s>"), m_csID); setDone( ERR_BAD_DIGEST); return FALSE; } // Check if package not crashing all time if (!getExecTry( &uTry)) // Assuming first execution try uTry = 0; uTry++; if (uTry > MAX_ERROR_COUNT) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Max try count (%u) reached while executing Package <%s>"), uTry, m_csID); setDone( ERR_EXECUTE_TOO_MANY_TRY); return FALSE; } else setExecTry( uTry); if (m_csAction == OCS_DOWNLOAD_ACTION_LAUNCH) { // We need to wait for all threads/processes started // First, extrac build.zip to tmp folder if (!directoryCreate( m_csPath) || !unZip()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to unzip package <%s> to folder <%s>"), m_csID, m_csPath); setDone( ERR_UNZIP); return FALSE; } pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Launching command <%s> for package <%s> on <%s>"), m_csCommand, m_csID, CTime::GetCurrentTime().Format( _T( "%#c"))); if (m_csCommand.IsEmpty()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => No command provided for <%s> action of package <%s>"), OCS_DOWNLOAD_ACTION_LAUNCH, m_csID); setDone( ERR_BAD_PARAM); return FALSE; } // Set command time out in milliseconds cmProcess.setTimeout( uCommandTimeOut * 60 * 1000); // Execute command and wait for all childs to terminate switch (cmProcess.execWaitForAllChilds( m_csCommand, m_csPath)) { case EXEC_ERROR_START_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to launch command <%s> for package <%s> (%s)"), m_csCommand, m_csID, cmProcess.getOutput()); setDone( ERR_EXECUTE); return FALSE; case EXEC_ERROR_WAIT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to get command <%s> result code for package <%s> (%s)"), m_csCommand, m_csID, cmProcess.getOutput()); csBuffer = ERR_EXECUTE_NO_EXIT_CODE; break; case EXEC_ERROR_TIMEOUT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Command <%s> execution reached timeout on <%s> (%s)"), m_csCommand, CTime::GetCurrentTime().Format( _T( "%#c")), cmProcess.getOutput()); csBuffer = ERR_EXECUTE_TIMEOUT; break; default: isExecSuccessful( cmProcess.getExitValue(), csBuffer); pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Package <%s> successfully launched. Command exit code is <%d>. Package return code is <%s>"), m_csID, cmProcess.getExitValue(), csBuffer); break; } setDone( csBuffer); return TRUE; } if (m_csAction == OCS_DOWNLOAD_ACTION_EXECUTE) { // We only need to wait for cmmand result // First, extrac build.zip to tmp folder if (!directoryCreate( m_csPath) || !unZip()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to unzip package <%s> to folder <%s>"), m_csID, m_csPath); setDone( ERR_UNZIP); return FALSE; } pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Executing command <%s> for package <%s> on <%s>"), m_csCommand, m_csID, CTime::GetCurrentTime().Format( _T( "%#c"))); if (m_csCommand.IsEmpty()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => No command provided for <%s> action of package <%s>"), OCS_DOWNLOAD_ACTION_EXECUTE, m_csID); setDone( ERR_BAD_PARAM); return FALSE; } // Set command time out in milliseconds cmProcess.setTimeout( uCommandTimeOut * 60 * 1000); // Execute command and wait only for main process to terminate switch (cmProcess.execWait( m_csCommand, m_csPath)) { case EXEC_ERROR_START_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to execute command <%s> for package <%s> (%s)"), m_csCommand, m_csID, cmProcess.getOutput()); setDone( ERR_EXECUTE); return FALSE; case EXEC_ERROR_WAIT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to get command <%s> result code for package <%s> (%s)"), m_csCommand, m_csID, cmProcess.getOutput()); csBuffer = ERR_EXECUTE_NO_EXIT_CODE; break; case EXEC_ERROR_TIMEOUT_COMMAND: pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Command <%s> execution reached timeout on <%s> (%s)"), m_csCommand, CTime::GetCurrentTime().Format( _T( "%#c")), cmProcess.getOutput()); csBuffer = ERR_EXECUTE_TIMEOUT; break; default: isExecSuccessful( cmProcess.getExitValue(), csBuffer); pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Package <%s> successfully executed. Command exit code is <%d>. Package return code is <%s>"), m_csID, cmProcess.getExitValue(), csBuffer); } setDone( csBuffer, GetUnicodeFromAnsi( cmProcess.getOutput())); return TRUE; } if (m_csAction == OCS_DOWNLOAD_ACTION_STORE) { // We just want to unzip data to specified folder pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Unzipping data to folder <%s> for package <%s> on <%s>"), m_csPath, m_csID, CTime::GetCurrentTime().Format( _T( "%#c"))); if (m_csPath.IsEmpty()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => No path provided for <%s> action of package <%s>"), OCS_DOWNLOAD_ACTION_STORE, m_csID); setDone( ERR_BAD_PARAM); return FALSE; } if (!directoryCreate( m_csPath) || !unZip()) { pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Failed to unzip package <%s> to folder <%s>"), m_csID, m_csPath); setDone( ERR_UNZIP); return FALSE; } pLog->log( LOG_PRIORITY_DEBUG, _T( "PACKAGE => Package <%s> successfully stored to folder <%s>"), m_csID, m_csPath); setDone( CODE_SUCCESS); return TRUE; } // Unknown action pLog->log( LOG_PRIORITY_WARNING, _T( "PACKAGE => Unknown action <%s> for package <%s>"), m_csAction, m_csID); setDone( ERR_BAD_PARAM); return FALSE; }