summaryrefslogtreecommitdiffstats
path: root/mmc_updater/src/UpdateInstaller.cpp
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2015-06-07 21:10:18 +0200
committerPetr Mrázek <peterix@gmail.com>2015-06-07 21:10:18 +0200
commit6d7bff2476459049f4f554291a680e0f6003ea66 (patch)
tree4202e9f1cd843197648fec93b48a5bc88407dc2e /mmc_updater/src/UpdateInstaller.cpp
parent977e11ef8d6780b173ad5ca6d13e29e721d0c6a0 (diff)
downloadMultiMC-6d7bff2476459049f4f554291a680e0f6003ea66.tar
MultiMC-6d7bff2476459049f4f554291a680e0f6003ea66.tar.gz
MultiMC-6d7bff2476459049f4f554291a680e0f6003ea66.tar.lz
MultiMC-6d7bff2476459049f4f554291a680e0f6003ea66.tar.xz
MultiMC-6d7bff2476459049f4f554291a680e0f6003ea66.zip
GH-1060 remove updater code
Diffstat (limited to 'mmc_updater/src/UpdateInstaller.cpp')
-rw-r--r--mmc_updater/src/UpdateInstaller.cpp479
1 files changed, 0 insertions, 479 deletions
diff --git a/mmc_updater/src/UpdateInstaller.cpp b/mmc_updater/src/UpdateInstaller.cpp
deleted file mode 100644
index b29c5316..00000000
--- a/mmc_updater/src/UpdateInstaller.cpp
+++ /dev/null
@@ -1,479 +0,0 @@
-#include "UpdateInstaller.h"
-
-#include "AppInfo.h"
-#include "FileUtils.h"
-#include "Log.h"
-#include "ProcessUtils.h"
-#include "UpdateObserver.h"
-
-void UpdateInstaller::setWaitPid(PLATFORM_PID pid)
-{
- m_waitPid = pid;
-}
-
-void UpdateInstaller::setInstallDir(const std::string& path)
-{
- m_installDir = path;
-}
-
-void UpdateInstaller::setPackageDir(const std::string& path)
-{
- m_packageDir = path;
-}
-
-void UpdateInstaller::setBackupDir(const std::string& path)
-{
- m_backupDir = path;
-}
-
-void UpdateInstaller::setMode(Mode mode)
-{
- m_mode = mode;
-}
-
-void UpdateInstaller::setScript(UpdateScript* script)
-{
- m_script = script;
-}
-
-void UpdateInstaller::setForceElevated(bool elevated)
-{
- m_forceElevated = elevated;
-}
-
-void UpdateInstaller::setFinishCmd(const std::string& cmd)
-{
- m_finishCmd = cmd;
-}
-
-void UpdateInstaller::setFinishDir(const std::string &dir)
-{
- m_finishDir = dir;
-}
-
-std::list<std::string> UpdateInstaller::updaterArgs() const
-{
- std::list<std::string> args;
- args.push_back("--install-dir");
- args.push_back(m_installDir);
- args.push_back("--package-dir");
- args.push_back(m_packageDir);
- args.push_back("--script");
- args.push_back(m_script->path());
- if (m_autoClose)
- {
- args.push_back("--auto-close");
- }
- if (m_dryRun)
- {
- args.push_back("--dry-run");
- }
- if (m_finishDir.size())
- {
- args.push_back("--dir");
- args.push_back(m_finishDir);
- }
- return args;
-}
-
-void UpdateInstaller::reportError(const std::string& error)
-{
- if (m_observer)
- {
- m_observer->updateError(error);
- m_observer->updateFinished();
- }
-}
-
-std::string UpdateInstaller::friendlyErrorForError(const FileUtils::IOException& exception) const
-{
- std::string friendlyError;
-
- switch (exception.type())
- {
- case FileUtils::IOException::ReadOnlyFileSystem:
-#ifdef PLATFORM_MAC
- friendlyError = AppInfo::appName() + " was started from a read-only location. "
- "Copy it to the Applications folder on your Mac and run "
- "it from there.";
-#else
- friendlyError = AppInfo::appName() + " was started from a read-only location. "
- "Re-install it to a location that can be updated and run it from there.";
-#endif
- break;
- case FileUtils::IOException::DiskFull:
- friendlyError = "The disk is full. Please free up some space and try again.";
- break;
- default:
- break;
- }
-
- return friendlyError;
-}
-
-void UpdateInstaller::run() throw ()
-{
- if (!m_script || !m_script->isValid())
- {
- reportError("Unable to read update script");
- return;
- }
- if (m_installDir.empty())
- {
- reportError("No installation directory specified");
- return;
- }
-
- std::string updaterPath;
- try
- {
- updaterPath = ProcessUtils::currentProcessPath();
- }
- catch (const FileUtils::IOException&)
- {
- LOG(Error,"error reading process path with mode " + intToStr(m_mode));
- reportError("Unable to determine path of updater");
- return;
- }
-
- if (m_mode == Setup)
- {
- if (m_waitPid != 0)
- {
- LOG(Info,"Waiting for main app process to finish");
- ProcessUtils::waitForProcess(m_waitPid);
- }
-
- std::list<std::string> args = updaterArgs();
- args.push_back("--mode");
- args.push_back("main");
- args.push_back("--wait");
- args.push_back(intToStr(ProcessUtils::currentProcessId()));
-
- int installStatus = 0;
- if (m_forceElevated || !checkAccess())
- {
- LOG(Info,"Insufficient rights to install app to " + m_installDir + " requesting elevation");
-
- // start a copy of the updater with admin rights
- installStatus = ProcessUtils::runElevated(updaterPath,args,AppInfo::name());
- }
- else
- {
- LOG(Info,"Sufficient rights to install app - restarting with same permissions");
- installStatus = ProcessUtils::runSync(updaterPath,args);
- }
-
- if (installStatus == 0)
- {
- LOG(Info,"Update install completed");
- }
- else
- {
- LOG(Error,"Update install failed with status " + intToStr(installStatus));
- }
-
- // restart the main application - this is currently done
- // regardless of whether the installation succeeds or not
- restartMainApp();
-
- // clean up files created by the updater
- cleanup();
- }
- else if (m_mode == Main)
- {
- LOG(Info,"Starting update installation");
-
- // the detailed error string returned by the OS
- std::string error;
- // the message to present to the user. This may be the same
- // as 'error' or may be different if a more helpful suggestion
- // can be made for a particular problem
- std::string friendlyError;
-
- try
- {
- LOG(Info,"Installing new and updated files");
- installFiles();
-
- LOG(Info,"Uninstalling removed files");
- uninstallFiles();
-
- LOG(Info,"Removing backups");
- removeBackups();
-
- postInstallUpdate();
- }
- catch (const FileUtils::IOException& exception)
- {
- error = exception.what();
- friendlyError = friendlyErrorForError(exception);
- }
- catch (const std::string& genericError)
- {
- error = genericError;
- }
-
- if (!error.empty())
- {
- LOG(Error,std::string("Error installing update ") + error);
-
- try
- {
- revert();
- }
- catch (const FileUtils::IOException& exception)
- {
- LOG(Error,"Error reverting partial update " + std::string(exception.what()));
- }
-
- if (m_observer)
- {
- if (friendlyError.empty())
- {
- friendlyError = error;
- }
- m_observer->updateError(friendlyError);
- }
- }
-
- if (m_observer)
- {
- m_observer->updateFinished();
- }
- }
-}
-
-void UpdateInstaller::cleanup()
-{
- try
- {
- FileUtils::rmdirRecursive(m_packageDir.c_str());
- }
- catch (const FileUtils::IOException& ex)
- {
- LOG(Error,"Error cleaning up updater " + std::string(ex.what()));
- }
- LOG(Info,"Updater files removed");
-}
-
-void UpdateInstaller::revert()
-{
- LOG(Info,"Reverting installation!");
- std::map<std::string,std::string>::const_iterator iter = m_backups.begin();
- for (;iter != m_backups.end();iter++)
- {
- const std::string& installedFile = iter->first;
- const std::string& backupFile = iter->second;
- LOG(Info,"Restoring " + installedFile);
- if(!m_dryRun)
- {
- if (FileUtils::fileExists(installedFile.c_str()))
- {
- FileUtils::removeFile(installedFile.c_str());
- }
- FileUtils::moveFile(backupFile.c_str(),installedFile.c_str());
- }
- }
-}
-
-void UpdateInstaller::installFile(const UpdateScriptFile& file)
-{
- std::string sourceFile = file.source;
- std::string destPath = file.dest;
- std::string absDestPath = FileUtils::makeAbsolute(destPath.c_str(), m_installDir.c_str());
-
- LOG(Info,"Installing file " + sourceFile + " to " + absDestPath);
-
- // backup the existing file if any
- backupFile(absDestPath);
-
- // create the target directory if it does not exist
- std::string destDir = FileUtils::dirname(absDestPath.c_str());
- if (!FileUtils::fileExists(destDir.c_str()))
- {
- LOG(Info,"Destination path missing. Creating " + destDir);
- if(!m_dryRun)
- {
- FileUtils::mkpath(destDir.c_str());
- }
- }
-
- if (!FileUtils::fileExists(sourceFile.c_str()))
- {
- throw "Source file does not exist: " + sourceFile;
- }
- if(!m_dryRun)
- {
- FileUtils::copyFile(sourceFile.c_str(),absDestPath.c_str());
-
- // set the permissions on the newly extracted file
- FileUtils::chmod(absDestPath.c_str(),file.permissions);
- }
-}
-
-void UpdateInstaller::installFiles()
-{
- LOG(Info,"Installing files.");
- std::vector<UpdateScriptFile>::const_iterator iter = m_script->filesToInstall().begin();
- int filesInstalled = 0;
- for (;iter != m_script->filesToInstall().end();iter++)
- {
- installFile(*iter);
- ++filesInstalled;
- if (m_observer)
- {
- int toInstallCount = static_cast<int>(m_script->filesToInstall().size());
- double percentage = ((1.0 * filesInstalled) / toInstallCount) * 100.0;
- m_observer->updateProgress(static_cast<int>(percentage));
- }
- }
-}
-
-void UpdateInstaller::uninstallFiles()
-{
- LOG(Info,"Uninstalling files.");
- std::vector<std::string>::const_iterator iter = m_script->filesToUninstall().begin();
- for (;iter != m_script->filesToUninstall().end();iter++)
- {
- std::string path = FileUtils::makeAbsolute(iter->c_str(), m_installDir.c_str());
- if (FileUtils::fileExists(path.c_str()))
- {
- LOG(Info,"Uninstalling " + path);
- if(!m_dryRun)
- {
- FileUtils::removeFile(path.c_str());
- }
- }
- else
- {
- LOG(Warn,"Unable to uninstall file " + path + " because it does not exist.");
- }
- }
-}
-
-void UpdateInstaller::backupFile(const std::string& path)
-{
- if (!FileUtils::fileExists(path.c_str()))
- {
- // no existing file to backup
- return;
- }
- std::string backupPath = path + ".bak";
- LOG(Info,"Backing up file: " + path + " as " + backupPath);
- if(!m_dryRun)
- {
- FileUtils::removeFile(backupPath.c_str());
- FileUtils::moveFile(path.c_str(), backupPath.c_str());
- }
- m_backups[path] = backupPath;
-}
-
-void UpdateInstaller::removeBackups()
-{
- LOG(Info,"Removing backups.");
- std::map<std::string,std::string>::const_iterator iter = m_backups.begin();
- for (;iter != m_backups.end();iter++)
- {
- const std::string& backupFile = iter->second;
- LOG(Info,"Removing " + backupFile);
- if(!m_dryRun)
- {
- FileUtils::removeFile(backupFile.c_str());
- }
- }
-}
-
-bool UpdateInstaller::checkAccess()
-{
- std::string testFile = m_installDir + "/update-installer-test-file";
- LOG(Info,"Checking for access: " + testFile);
- try
- {
- if(!m_dryRun)
- {
- FileUtils::removeFile(testFile.c_str());
- }
- }
- catch (const FileUtils::IOException& error)
- {
- LOG(Info,"Removing existing access check file failed " + std::string(error.what()));
- }
-
- try
- {
- if(!m_dryRun)
- {
- FileUtils::touch(testFile.c_str());
- FileUtils::removeFile(testFile.c_str());
- }
- return true;
- }
- catch (const FileUtils::IOException& error)
- {
- LOG(Info,"checkAccess() failed " + std::string(error.what()));
- return false;
- }
-}
-
-void UpdateInstaller::setObserver(UpdateObserver* observer)
-{
- m_observer = observer;
-}
-
-void UpdateInstaller::restartMainApp()
-{
- try
- {
- std::string command = m_finishCmd;
- std::list<std::string> args;
-
- if (!command.empty())
- {
- if(!m_finishDir.empty())
- {
- args.push_back("--dir");
- args.push_back(m_finishDir);
- }
- LOG(Info,"Starting main application " + command);
- if(!m_dryRun)
- {
- ProcessUtils::runAsync(command,args);
- }
- }
- else
- {
- LOG(Error,"No main binary specified");
- }
- }
- catch (const std::exception& ex)
- {
- LOG(Error,"Unable to restart main app " + std::string(ex.what()));
- }
-}
-
-void UpdateInstaller::postInstallUpdate()
-{
- // perform post-install actions
-
-#ifdef PLATFORM_MAC
- // touch the application's bundle directory so that
- // OS X' Launch Services notices any changes in the application's
- // Info.plist file.
- LOG(Info,"Touching " + m_installDir + " to notify OSX of metadata changes.");
- if(!m_dryRun)
- {
- FileUtils::touch(m_installDir.c_str());
- }
-#endif
-}
-
-void UpdateInstaller::setAutoClose(bool autoClose)
-{
- m_autoClose = autoClose;
-}
-
-void UpdateInstaller::setDryRun(bool dryRun)
-{
- m_dryRun = dryRun;
-}