diff options
author | Petr Mrázek <peterix@gmail.com> | 2015-06-07 21:10:18 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2015-06-07 21:10:18 +0200 |
commit | 6d7bff2476459049f4f554291a680e0f6003ea66 (patch) | |
tree | 4202e9f1cd843197648fec93b48a5bc88407dc2e /mmc_updater/src | |
parent | 977e11ef8d6780b173ad5ca6d13e29e721d0c6a0 (diff) | |
download | MultiMC-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')
58 files changed, 0 insertions, 4557 deletions
diff --git a/mmc_updater/src/AppInfo.cpp b/mmc_updater/src/AppInfo.cpp deleted file mode 100644 index a5a9bb63..00000000 --- a/mmc_updater/src/AppInfo.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "AppInfo.h" - -#include "FileUtils.h" -#include "Platform.h" -#include "StringUtils.h" -#include "StandardDirs.h" - -#include <iostream> - -std::string AppInfo::logFilePath() -{ - return StandardDirs::appDataPath(organizationName(),appName()) + '/' + "update-log.txt"; -} - -std::string AppInfo::updateErrorMessage(const std::string& details) -{ - std::string result = "There was a problem installing the update:\n\n"; - result += details; - result += "\n\nYou can try downloading and installing the latest version of " - "MultiMC from http://multimc.org/"; - return result; -} - diff --git a/mmc_updater/src/AppInfo.h b/mmc_updater/src/AppInfo.h deleted file mode 100644 index 51d95886..00000000 --- a/mmc_updater/src/AppInfo.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include <string> - -/** This class provides project-specific updater properties, - * such as the name of the application being updated and - * the path to log details of the update install to. - */ -class AppInfo -{ - public: - // Basic application information - static std::string name(); - static std::string appName(); - static std::string organizationName(); - - static std::string logFilePath(); - - /** Returns a message to display to the user in the event - * of a problem installing the update. - */ - static std::string updateErrorMessage(const std::string& details); -}; - -inline std::string AppInfo::name() -{ - return "MultiMC Updater"; -} - -inline std::string AppInfo::appName() -{ - return "MultiMC"; -} - -inline std::string AppInfo::organizationName() -{ - return "MultiMC Contributors"; -} - diff --git a/mmc_updater/src/CMakeLists.txt b/mmc_updater/src/CMakeLists.txt deleted file mode 100644 index d27fbe00..00000000 --- a/mmc_updater/src/CMakeLists.txt +++ /dev/null @@ -1,116 +0,0 @@ - -add_subdirectory(tests) - -find_package(Threads REQUIRED) -include(GenerateCppResourceFile) - -set(UPDATER_SOURCES - AppInfo.cpp - AppInfo.h - DirIterator.cpp - DirIterator.h - FileUtils.cpp - FileUtils.h - Log.cpp - Log.h - ProcessUtils.cpp - ProcessUtils.h - StandardDirs.cpp - StandardDirs.h - UpdateDialog.cpp - UpdateInstaller.cpp - UpdateInstaller.h - UpdateScript.cpp - UpdateScript.h - UpdaterOptions.cpp - UpdaterOptions.h -) - -add_definitions(-DTIXML_USE_STL) - -if(WIN32) - set(UPDATER_SOURCES ${UPDATER_SOURCES} UpdateDialogWin32.cpp UpdateDialogWin32.h) -endif() - -if(UNIX) - set(UPDATER_SOURCES ${UPDATER_SOURCES} UpdateDialogAscii.cpp UpdateDialogAscii.h) - add_definitions(-Wall -Wconversion) - if(APPLE) - set(MAC_DOCK_ICON_CPP_FILE ${CMAKE_CURRENT_BINARY_DIR}/mac_dock_icon.cpp) - set(MAC_INFO_PLIST_FILE ${CMAKE_CURRENT_BINARY_DIR}/mac_info_plist.cpp) - generate_cpp_resource_file(resource_macdockicon ${CMAKE_CURRENT_SOURCE_DIR}/resources/mac.icns ${MAC_DOCK_ICON_CPP_FILE}) - generate_cpp_resource_file(resource_macplist ${CMAKE_CURRENT_SOURCE_DIR}/resources/Info.plist ${MAC_INFO_PLIST_FILE}) - set(UPDATER_SOURCES ${UPDATER_SOURCES} - MacBundle.h - MacBundle.cpp - StandardDirs.mm - StlSymbolsLeopard.cpp - UpdateDialogCocoa.mm - UpdateDialogCocoa.h - mac_dock_icon.cpp - mac_info_plist.cpp - ) - else() # linuxes and other similar systems - find_package(GTK2 REQUIRED gtk) - include_directories(${GTK2_INCLUDE_DIRS}) - add_library(updatergtk SHARED UpdateDialogGtk.cpp UpdateDialogGtk.h) - target_link_libraries(updatergtk ${GTK2_LIBRARIES}) - - # embed the GTK helper library into the updater binary. - # At runtime it will be extracted and loaded if the - # GTK libraries are available - get_property(GTK_UPDATER_LIB TARGET updatergtk PROPERTY LOCATION) - set(GTK_BIN_CPP_FILE ${CMAKE_CURRENT_BINARY_DIR}/libupdatergtk.cpp) - generate_cpp_resource_file(resource_updatergtk ${GTK_UPDATER_LIB} ${GTK_BIN_CPP_FILE}) - add_dependencies(resource_updatergtk updatergtk) - - set(UPDATER_SOURCES ${UPDATER_SOURCES} UpdateDialogGtkFactory.cpp UpdateDialogGtkFactory.h ${GTK_BIN_CPP_FILE}) - endif() -endif() - -add_library(updatershared STATIC ${UPDATER_SOURCES}) - -target_link_libraries(updatershared anyoption tinyxml) - -if(UNIX) - if(APPLE) - find_library(COCOA_LIBRARY Cocoa) - find_library(SECURITY_LIBRARY Security) - target_link_libraries(updatershared ${SECURITY_LIBRARY} ${COCOA_LIBRARY}) - else() - add_dependencies(updatershared resource_updatergtk) - endif() - target_link_libraries(updatershared pthread dl) -endif() - -if(WIN32) - set(EXE_FLAGS WIN32 resources/updater.rc) -endif() - -add_executable(updater ${EXE_FLAGS} main.cpp) - -target_link_libraries(updater updatershared) - - -#### Updater Executable #### -if(WIN32) - install(TARGETS updater - BUNDLE DESTINATION . COMPONENT Runtime - LIBRARY DESTINATION . COMPONENT Runtime - RUNTIME DESTINATION . COMPONENT Runtime - ) -endif() -if(UNIX) - if(APPLE) - install(TARGETS updater - BUNDLE DESTINATION . COMPONENT Runtime - RUNTIME DESTINATION MultiMC.app/Contents/MacOS COMPONENT Runtime - ) - else() - install(TARGETS updater - BUNDLE DESTINATION . COMPONENT Runtime - RUNTIME DESTINATION bin COMPONENT Runtime - ) - endif() -endif() - diff --git a/mmc_updater/src/DirIterator.cpp b/mmc_updater/src/DirIterator.cpp deleted file mode 100644 index a4604f05..00000000 --- a/mmc_updater/src/DirIterator.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "DirIterator.h" - -#include "Log.h" -#include "StringUtils.h" - -#ifdef PLATFORM_UNIX - #include <dirent.h> -#endif - -#include <string.h> - -DirIterator::DirIterator(const char* path) -{ - m_path = path; - -#ifdef PLATFORM_UNIX - m_dir = opendir(path); - m_entry = 0; -#else - // to list the contents of a directory, the first - // argument to FindFirstFile needs to be a wildcard - // of the form: C:\path\to\dir\* - std::string searchPath = m_path; - if (!endsWith(searchPath,"/")) - { - searchPath.append("/"); - } - searchPath.append("*"); - m_findHandle = FindFirstFile(searchPath.c_str(),&m_findData); - m_firstEntry = true; -#endif -} - -DirIterator::~DirIterator() -{ -#ifdef PLATFORM_UNIX - closedir(m_dir); -#else - FindClose(m_findHandle); -#endif -} - -bool DirIterator::next() -{ -#ifdef PLATFORM_UNIX - m_entry = readdir(m_dir); - return m_entry != 0; -#else - bool result; - if (m_firstEntry) - { - m_firstEntry = false; - return m_findHandle != INVALID_HANDLE_VALUE; - } - else - { - result = FindNextFile(m_findHandle,&m_findData); - } - return result; -#endif -} - -std::string DirIterator::fileName() const -{ -#ifdef PLATFORM_UNIX - return m_entry->d_name; -#else - return m_findData.cFileName; -#endif -} - -std::string DirIterator::filePath() const -{ - return m_path + '/' + fileName(); -} - -bool DirIterator::isDir() const -{ -#ifdef PLATFORM_UNIX - return m_entry->d_type == DT_DIR; -#else - return (m_findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; -#endif -} - diff --git a/mmc_updater/src/DirIterator.h b/mmc_updater/src/DirIterator.h deleted file mode 100644 index f3fbb955..00000000 --- a/mmc_updater/src/DirIterator.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "Platform.h" - -#include <string> - -#ifdef PLATFORM_UNIX -#include <dirent.h> -#endif - -/** Simple class for iterating over the files in a directory - * and reporting their names and types. - */ -class DirIterator -{ - public: - DirIterator(const char* path); - ~DirIterator(); - - // iterate to the next entry in the directory - bool next(); - - // methods to return information about - // the current entry - std::string fileName() const; - std::string filePath() const; - bool isDir() const; - - private: - std::string m_path; - -#ifdef PLATFORM_UNIX - DIR* m_dir; - dirent* m_entry; -#endif - -#ifdef PLATFORM_WINDOWS - HANDLE m_findHandle; - WIN32_FIND_DATA m_findData; - bool m_firstEntry; -#endif -}; - diff --git a/mmc_updater/src/FileUtils.cpp b/mmc_updater/src/FileUtils.cpp deleted file mode 100644 index 712c0c5d..00000000 --- a/mmc_updater/src/FileUtils.cpp +++ /dev/null @@ -1,517 +0,0 @@ -#include "FileUtils.h" - -#include "DirIterator.h" -#include "Log.h" -#include "Platform.h" -#include "StringUtils.h" - -#include <algorithm> -#include <assert.h> -#include <string.h> -#include <fstream> -#include <iostream> -// this actually works with mingw32, which we use. -#include <libgen.h> - -#ifdef PLATFORM_UNIX -#include <unistd.h> -#include <stdio.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <errno.h> -#endif - -FileUtils::IOException::IOException(const std::string& error) -{ - init(errno,error); -} - -FileUtils::IOException::IOException(int errorCode, const std::string& error) -{ - init(errorCode,error); -} - -void FileUtils::IOException::init(int errorCode, const std::string& error) -{ - m_error = error; - -#ifdef PLATFORM_UNIX - m_errorCode = errorCode; - - if (m_errorCode > 0) - { - m_error += " details: " + std::string(strerror(m_errorCode)); - } -#endif - -#ifdef PLATFORM_WINDOWS - m_errorCode = 0; - m_error += " GetLastError returned: " + intToStr(GetLastError()); -#endif -} - -FileUtils::IOException::~IOException() throw () -{ -} - -FileUtils::IOException::Type FileUtils::IOException::type() const -{ -#ifdef PLATFORM_UNIX - switch (m_errorCode) - { - case 0: - return NoError; - case EROFS: - return ReadOnlyFileSystem; - case ENOSPC: - return DiskFull; - default: - return Unknown; - } -#else - return Unknown; -#endif -} - -bool FileUtils::fileExists(const char* path) throw (IOException) -{ -#ifdef PLATFORM_UNIX - struct stat fileInfo; - if (lstat(path,&fileInfo) != 0) - { - if (errno == ENOENT) - { - return false; - } - else - { - throw IOException("Error checking for file " + std::string(path)); - } - } - return true; -#else - DWORD result = GetFileAttributes(path); - if (result == INVALID_FILE_ATTRIBUTES) - { - return false; - } - return true; -#endif -} - -int FileUtils::fileMode(const char* path) throw (IOException) -{ -#ifdef PLATFORM_UNIX - struct stat fileInfo; - if (stat(path,&fileInfo) != 0) - { - throw IOException("Error reading file permissions for " + std::string(path)); - } - return fileInfo.st_mode; -#else - // not implemented for Windows - return 0; -#endif -} - -void FileUtils::chmod(const char* path, int mode) throw (IOException) -{ -#ifdef PLATFORM_UNIX - if (::chmod(path,static_cast<mode_t>(mode)) != 0) - { - throw IOException("Failed to set permissions on " + std::string(path) + " to " + intToStr(mode)); - } -#else - // TODO - Not implemented under Windows - all files - // get default permissions -#endif -} - -void FileUtils::moveFile(const char* src, const char* dest) throw (IOException) -{ -#ifdef PLATFORM_UNIX - if (rename(src,dest) != 0) - { - throw IOException("Unable to rename " + std::string(src) + " to " + std::string(dest)); - } -#else - if (!MoveFile(src,dest)) - { - throw IOException("Unable to rename " + std::string(src) + " to " + std::string(dest)); - } -#endif -} - -void FileUtils::mkpath(const char* dir) throw (IOException) -{ - std::string currentPath; - std::istringstream stream(dir); - while (!stream.eof()) - { - std::string segment; - std::getline(stream,segment,'/'); - currentPath += segment; - if (!currentPath.empty() && !fileExists(currentPath.c_str())) - { - mkdir(currentPath.c_str()); - } - currentPath += '/'; - } -} - -void FileUtils::mkdir(const char* dir) throw (IOException) -{ -#ifdef PLATFORM_UNIX - if (::mkdir(dir,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) - { - throw IOException("Unable to create directory " + std::string(dir)); - } -#else - if (!CreateDirectory(dir,0 /* default security attributes */)) - { - throw IOException("Unable to create directory " + std::string(dir)); - } -#endif -} - -void FileUtils::rmdir(const char* dir) throw (IOException) -{ -#ifdef PLATFORM_UNIX - if (::rmdir(dir) != 0) - { - throw IOException("Unable to remove directory " + std::string(dir)); - } -#else - if (!RemoveDirectory(dir)) - { - throw IOException("Unable to remove directory " + std::string(dir)); - } -#endif -} - -void FileUtils::createSymLink(const char* link, const char* target) throw (IOException) -{ -#ifdef PLATFORM_UNIX - if (symlink(target,link) != 0) - { - throw IOException("Unable to create symlink " + std::string(link) + " to " + std::string(target)); - } -#else - // symlinks are not supported under Windows (at least, not universally. - // Windows Vista and later do actually support symlinks) - LOG(Warn,"Skipping symlink creation - not implemented in Windows"); -#endif -} - -void FileUtils::removeFile(const char* src) throw (IOException) -{ -#ifdef PLATFORM_UNIX - if (unlink(src) != 0) - { - if (errno != ENOENT) - { - throw IOException("Unable to remove file " + std::string(src)); - } - } -#else - if (!DeleteFile(src)) - { - if (GetLastError() == ERROR_ACCESS_DENIED) - { - // if another process is using the file, try moving it to - // a temporary directory and then - // scheduling it for deletion on reboot - std::string tempDeletePathBase = tempPath(); - tempDeletePathBase += '/'; - tempDeletePathBase += fileName(src); - - int suffix = 0; - std::string tempDeletePath = tempDeletePathBase; - while (fileExists(tempDeletePath.c_str())) - { - ++suffix; - tempDeletePath = tempDeletePathBase + '_' + intToStr(suffix); - } - - LOG(Warn,"Unable to remove file " + std::string(src) + " - it may be in use. Moving to " - + tempDeletePath + " and scheduling delete on reboot."); - moveFile(src,tempDeletePath.c_str()); - MoveFileEx(tempDeletePath.c_str(),0,MOVEFILE_DELAY_UNTIL_REBOOT); - } - else if (GetLastError() != ERROR_FILE_NOT_FOUND) - { - throw IOException("Unable to remove file " + std::string(src)); - } - } -#endif -} - -std::string FileUtils::fileName(const char* path) -{ - char* pathCopy = strdup(path); - std::string basename = ::basename(pathCopy); - free(pathCopy); - return basename; -} - -std::string FileUtils::dirname(const char* path) -{ - char* pathCopy = strdup(path); - std::string dirname = ::dirname(pathCopy); - free(pathCopy); - return dirname; -} - -void FileUtils::touch(const char* path) throw (IOException) -{ -#ifdef PLATFORM_UNIX - // see http://pubs.opengroup.org/onlinepubs/9699919799/utilities/touch.html - // - // we use utimes/futimes instead of utimensat/futimens for compatibility - // with older Linux and Mac - - if (fileExists(path)) - { - utimes(path,0 /* use current date/time */); - } - else - { - int fd = creat(path,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - if (fd != -1) - { - futimes(fd,0 /* use current date/time */); - close(fd); - } - else - { - throw IOException("Unable to touch file " + std::string(path)); - } - } -#else - HANDLE result = CreateFile(path,GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - 0); - if (result == INVALID_HANDLE_VALUE) - { - throw IOException("Unable to touch file " + std::string(path)); - } - else - { - CloseHandle(result); - } -#endif -} - -void FileUtils::rmdirRecursive(const char* path) throw (IOException) -{ - // remove dir contents - DirIterator dir(path); - while (dir.next()) - { - std::string name = dir.fileName(); - if (name != "." && name != "..") - { - if (dir.isDir()) - { - rmdir(dir.filePath().c_str()); - } - else - { - removeFile(dir.filePath().c_str()); - } - } - } - - // remove the directory itself - rmdir(path); -} - -std::string FileUtils::canonicalPath(const char* path) -{ -#ifdef PLATFORM_UNIX - // on Linux and Mac OS 10.6, realpath() can allocate the required - // amount of memory automatically, however Mac OS 10.5 does not support - // this, so we used a fixed-sized buffer on all platforms - char canonicalPathBuffer[PATH_MAX+1]; - if (realpath(path,canonicalPathBuffer) != 0) - { - return std::string(canonicalPathBuffer); - } - else - { - throw IOException("Error reading canonical path for " + std::string(path)); - } -#else - throw IOException("canonicalPath() not implemented"); -#endif -} - -std::string FileUtils::toWindowsPathSeparators(const std::string& str) -{ - std::string result = str; - std::replace(result.begin(),result.end(),'/','\\'); - return result; -} - -std::string FileUtils::toUnixPathSeparators(const std::string& str) -{ - std::string result = str; - std::replace(result.begin(),result.end(),'\\','/'); - return result; -} - -std::string FileUtils::tempPath() -{ -#ifdef PLATFORM_UNIX - std::string tmpDir(notNullString(getenv("TMPDIR"))); - if (tmpDir.empty()) - { - tmpDir = "/tmp"; - } - return tmpDir; -#else - char buffer[MAX_PATH+1]; - GetTempPath(MAX_PATH+1,buffer); - return toUnixPathSeparators(buffer); -#endif -} - -bool startsWithDriveLetter(const char* path) -{ - return strlen(path) >= 2 && - (isalpha(path[0])) && - path[1] == ':'; -} - -bool FileUtils::isRelative(const char* path) -{ -#ifdef PLATFORM_UNIX - return strlen(path) == 0 || path[0] != '/'; -#else - // on Windows, a path is relative if it does not start with: - // - '\\' (a UNC name) - // - '[Drive Letter]:\' - // - A single backslash - // - // the input path is assumed to have already been converted to use - // Unix-style path separators - - std::string pathStr(path); - - if ((!pathStr.empty() && pathStr.at(0) == '/') || - (startsWith(pathStr,"//")) || - (startsWithDriveLetter(pathStr.c_str()))) - { - return false; - } - else - { - return true; - } -#endif -} - -void FileUtils::writeFile(const char* path, const char* data, int length) throw (IOException) -{ - std::ofstream stream(path,std::ios::binary | std::ios::trunc); - stream.write(data,length); -} - -std::string FileUtils::readFile(const char* path) throw (IOException) -{ - std::ifstream inputFile(path, std::ios::in | std::ios::binary); - std::string content; - inputFile.seekg(0, std::ios::end); - content.resize(static_cast<unsigned int>(inputFile.tellg())); - inputFile.seekg(0, std::ios::beg); - inputFile.read(&content[0], static_cast<int>(content.size())); - return content; -} - -void FileUtils::copyFile(const char* src, const char* dest) throw (IOException) -{ -#ifdef PLATFORM_UNIX - std::ifstream inputFile(src,std::ios::binary); - std::ofstream outputFile(dest,std::ios::binary | std::ios::trunc); - - if (!inputFile.good()) - { - throw IOException("Failed to read file " + std::string(src)); - } - if (!outputFile.good()) - { - throw IOException("Failed to write file " + std::string(dest)); - } - - outputFile << inputFile.rdbuf(); - - if (inputFile.bad()) - { - throw IOException("Error reading file " + std::string(src)); - } - if (outputFile.bad()) - { - throw IOException("Error writing file " + std::string(dest)); - } - - chmod(dest,fileMode(src)); -#else - if (!CopyFile(src,dest,FALSE)) - { - throw IOException("Failed to copy " + std::string(src) + " to " + std::string(dest)); - } -#endif -} - -std::string FileUtils::makeAbsolute(const char* path, const char* basePath) -{ - if (isRelative(path)) - { - assert(!isRelative(basePath)); - return std::string(basePath) + '/' + std::string(path); - } - else - { - return path; - } -} - -void FileUtils::chdir(const char* path) throw (IOException) -{ -#ifdef PLATFORM_UNIX - if (::chdir(path) != 0) - { - throw FileUtils::IOException("Unable to change directory"); - } -#else - if (!SetCurrentDirectory(path)) - { - throw FileUtils::IOException("Unable to change directory"); - } -#endif -} - -std::string FileUtils::getcwd() throw (IOException) -{ -#ifdef PLATFORM_UNIX - char path[PATH_MAX]; - if (!::getcwd(path,PATH_MAX)) - { - throw FileUtils::IOException("Failed to get current directory"); - } - return std::string(path); -#else - char path[MAX_PATH]; - if (GetCurrentDirectory(MAX_PATH,path) == 0) - { - throw FileUtils::IOException("Failed to get current directory"); - } - return toUnixPathSeparators(std::string(path)); -#endif -} - diff --git a/mmc_updater/src/FileUtils.h b/mmc_updater/src/FileUtils.h deleted file mode 100644 index cb5830ae..00000000 --- a/mmc_updater/src/FileUtils.h +++ /dev/null @@ -1,141 +0,0 @@ -#pragma once - -#include <exception> -#include <string> - -#include "Platform.h" -#include "StringUtils.h" - - -/** A set of functions for performing common operations - * on files, throwing exceptions if an operation fails. - * - * Path arguments to FileUtils functions should use Unix-style path - * separators. - */ -class FileUtils -{ - public: - /** Base class for exceptions reported by - * FileUtils methods if an operation fails. - */ - class IOException : public std::exception - { - public: - IOException(const std::string& error); - IOException(int errorCode, const std::string& error); - - virtual ~IOException() throw (); - - enum Type - { - NoError, - /** Unknown error type. Call what() to get the description - * provided by the OS. - */ - Unknown, - ReadOnlyFileSystem, - DiskFull - }; - - virtual const char* what() const throw () - { - return m_error.c_str(); - } - - Type type() const; - - private: - void init(int errorCode, const std::string& error); - - std::string m_error; - int m_errorCode; - }; - - /** Remove a file. Throws an exception if the file - * could not be removed. - * - * On Unix, a file can be removed even if it is in use if the user - * has the necessary permissions. removeFile() tries to simulate - * this behavior on Windows. If a file cannot be removed on Windows - * because it is in use it will be moved to a temporary directory and - * scheduled for deletion on the next restart. - */ - static void removeFile(const char* src) throw (IOException); - - /** Set the permissions of a file. @p permissions uses the standard - * Unix mode_t values. - */ - static void chmod(const char* path, int permissions) throw (IOException); - - /** Returns true if the file at @p path exists. If @p path is a symlink, - * returns true if the symlink itself exists, not the target. - */ - static bool fileExists(const char* path) throw (IOException); - - /** Returns the Unix mode flags of @p path. If @p path is a symlink, - * returns the mode flags of the target. - */ - static int fileMode(const char* path) throw (IOException); - - static void moveFile(const char* src, const char* dest) throw (IOException); - static void mkdir(const char* dir) throw (IOException); - static void rmdir(const char* dir) throw (IOException); - static void createSymLink(const char* link, const char* target) throw (IOException); - static void touch(const char* path) throw (IOException); - static void copyFile(const char* src, const char* dest) throw (IOException); - - /** Create all the directories in @p path which do not yet exist. - * @p path may be relative or absolute. - */ - static void mkpath(const char* path) throw (IOException); - - /** Returns the file name part of a file path, including the extension. */ - static std::string fileName(const char* path); - - /** Returns the directory part of a file path. - * On Windows this includes the drive letter, if present in @p path. - */ - static std::string dirname(const char* path); - - /** Remove a directory and all of its contents. */ - static void rmdirRecursive(const char* dir) throw (IOException); - - /** Return the full, absolute path to a file, resolving any - * symlinks and removing redundant sections. - */ - static std::string canonicalPath(const char* path); - - /** Returns the path to a directory for storing temporary files. */ - static std::string tempPath(); - - /** Returns a copy of the path 'str' with Windows-style '\' - * dir separators converted to Unix-style '/' separators - */ - static std::string toUnixPathSeparators(const std::string& str); - - static std::string toWindowsPathSeparators(const std::string& str); - - /** Returns true if the provided path is relative. - * Or false if absolute. - */ - static bool isRelative(const char* path); - - /** Converts @p path to an absolute path. If @p path is already absolute, - * just returns @p path, otherwise prefixes it with @p basePath to make it absolute. - * - * @p basePath should be absolute. - */ - static std::string makeAbsolute(const char* path, const char* basePath); - - static void writeFile(const char* path, const char* data, int length) throw (IOException); - - static std::string readFile(const char* path) throw (IOException); - - /** Changes the current working directory to @p path */ - static void chdir(const char* path) throw (IOException); - - /** Returns the current working directory of the application. */ - static std::string getcwd() throw (IOException); -}; - diff --git a/mmc_updater/src/Log.cpp b/mmc_updater/src/Log.cpp deleted file mode 100644 index d4e5a214..00000000 --- a/mmc_updater/src/Log.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "Log.h" - -#include "Platform.h" -#include "StringUtils.h" -#include "ProcessUtils.h" - -#include <string.h> -#include <iostream> - -Log m_globalLog; - -Log* Log::instance() -{ - return &m_globalLog; -} - -Log::Log() -{ -} - -Log::~Log() -{ -} - -void Log::open(const std::string& path) -{ - m_mutex.lock(); - m_output.open(path.c_str(),std::ios_base::out | std::ios_base::app); - m_mutex.unlock(); -} - -void Log::writeToStream(std::ostream& stream, Type type, const char* text) -{ - // Multiple processes may be writing to the same log file during - // an update. No attempt is made to synchronize access to the file. - // - // Under Unix, appends to a single file on a local FS by multiple writers should be atomic - // provided that the length of 'text' is less than PIPE_BUF - // - switch (type) - { - case Info: - stream << "INFO "; - break; - case Warn: - stream << "WARN "; - break; - case Error: - stream << "ERROR "; - break; - } - stream << '(' << intToStr(ProcessUtils::currentProcessId()) << ") " << text << std::endl; -} - -void Log::write(Type type, const char* text) -{ - m_mutex.lock(); - writeToStream(std::cerr,type,text); - if (m_output.is_open()) - { - writeToStream(m_output,type,text); - } - m_mutex.unlock(); -} - diff --git a/mmc_updater/src/Log.h b/mmc_updater/src/Log.h deleted file mode 100644 index cf6be832..00000000 --- a/mmc_updater/src/Log.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include <string> -#include <fstream> - -#include <thread> -#include <mutex> - -class Log -{ - public: - enum Type - { - Info, - Warn, - Error - }; - - Log(); - ~Log(); - - void open(const std::string& path); - - /** Write @p text to the log. This method is thread-safe. */ - void write(Type type, const std::string& text); - /** Write @p text to the log. This method is thread-safe. */ - void write(Type type, const char* text); - - static Log* instance(); - - private: - static void writeToStream(std::ostream& stream, Type type, const char* text); - - std::mutex m_mutex; - std::ofstream m_output; -}; - -inline void Log::write(Type type, const std::string& text) -{ - write(type,text.c_str()); -} - -#define LOG(type,text) \ - Log::instance()->write(Log::type,text) - - diff --git a/mmc_updater/src/MacBundle.cpp b/mmc_updater/src/MacBundle.cpp deleted file mode 100644 index 205869eb..00000000 --- a/mmc_updater/src/MacBundle.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "MacBundle.h" - -#include "FileUtils.h" -#include "Log.h" - -MacBundle::MacBundle(const std::string& path, const std::string& appName) -: m_appName(appName) -{ - m_path = path + '/' + appName + ".app"; -} - -std::string MacBundle::bundlePath() const -{ - return m_path; -} - -void MacBundle::create(const std::string& infoPlist, - const std::string& icon, - const std::string& exePath) -{ - try - { - // create the bundle directories - FileUtils::mkpath(m_path.c_str()); - - std::string contentDir = m_path + "/Contents"; - std::string resourceDir = contentDir + "/Resources"; - std::string binDir = contentDir + "/MacOS"; - - FileUtils::mkpath(resourceDir.c_str()); - FileUtils::mkpath(binDir.c_str()); - - // create the Contents/Info.plist file - FileUtils::writeFile((contentDir + "/Info.plist").c_str(),infoPlist.c_str(),static_cast<int>(infoPlist.size())); - - // save the icon to Contents/Resources/<appname>.icns - FileUtils::writeFile((resourceDir + '/' + m_appName + ".icns").c_str(),icon.c_str(),static_cast<int>(icon.size())); - - // copy the app binary to Contents/MacOS/<appname> - m_exePath = binDir + '/' + m_appName; - FileUtils::copyFile(exePath.c_str(),m_exePath.c_str()); - } - catch (const FileUtils::IOException& exception) - { - LOG(Error,"Unable to create app bundle. " + std::string(exception.what())); - } -} - -std::string MacBundle::executablePath() const -{ - return m_exePath; -} - diff --git a/mmc_updater/src/MacBundle.h b/mmc_updater/src/MacBundle.h deleted file mode 100644 index 2b119d8f..00000000 --- a/mmc_updater/src/MacBundle.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include <string> - -/** Class for creating minimal Mac app bundles. */ -class MacBundle -{ - public: - /** Create a MacBundle instance representing the bundle - * in <path>/<appName>.app - */ - MacBundle(const std::string& path, const std::string& appName); - - /** Create a simple Mac bundle. - * - * @param infoPlist The content of the Info.plist file - * @param icon The content of the app icon - * @param exePath The path of the file to use for the main app in the bundle. - */ - void create(const std::string& infoPlist, - const std::string& icon, - const std::string& exePath); - - /** Returns the path of the main executable within the Mac bundle. */ - std::string executablePath() const; - - /** Returns the path of the bundle */ - std::string bundlePath() const; - - private: - std::string m_path; - std::string m_appName; - std::string m_exePath; -}; - diff --git a/mmc_updater/src/Platform.h b/mmc_updater/src/Platform.h deleted file mode 100644 index 97867d6a..00000000 --- a/mmc_updater/src/Platform.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -// basic platform defines -#ifdef __linux__ - #define PLATFORM_LINUX -#endif - -#ifdef WIN32 - #define PLATFORM_WINDOWS - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - #include <shellapi.h> - - // disable warnings about exception specifications, - // which are not implemented in Visual C++ - #ifdef MSVC - #pragma warning(disable:4290) - #endif -#endif - -#ifdef __APPLE__ - #define PLATFORM_MAC -#endif - -#if defined(PLATFORM_LINUX) || defined(PLATFORM_MAC) - #define PLATFORM_UNIX -#endif - -// platform-specific type aliases -#if defined(PLATFORM_UNIX) - #define PLATFORM_PID pid_t -#else - #define PLATFORM_PID DWORD -#endif diff --git a/mmc_updater/src/ProcessUtils.cpp b/mmc_updater/src/ProcessUtils.cpp deleted file mode 100644 index 3b9ffac2..00000000 --- a/mmc_updater/src/ProcessUtils.cpp +++ /dev/null @@ -1,536 +0,0 @@ -#include "ProcessUtils.h" - -#include "FileUtils.h" -#include "Platform.h" -#include "StringUtils.h" -#include "Log.h" - -#include <string.h> -#include <vector> -#include <iostream> - -#ifdef PLATFORM_WINDOWS -#include <windows.h> -#else -#include <unistd.h> -#include <stdlib.h> -#include <sys/wait.h> -#include <errno.h> -#endif - -#ifdef PLATFORM_MAC -#include <Security/Security.h> -#include <mach-o/dyld.h> -#endif - -PLATFORM_PID ProcessUtils::currentProcessId() -{ -#ifdef PLATFORM_UNIX - return getpid(); -#else - return GetCurrentProcessId(); -#endif -} - -int ProcessUtils::runSync(const std::string& executable, - const std::list<std::string>& args) -{ -#ifdef PLATFORM_UNIX - return runSyncUnix(executable,args); -#else - return runWindows(executable,args,RunSync); -#endif -} - -#ifdef PLATFORM_UNIX -int ProcessUtils::runSyncUnix(const std::string& executable, - const std::list<std::string>& args) -{ - PLATFORM_PID pid = runAsyncUnix(executable,args); - int status = 0; - if (waitpid(pid,&status,0) != -1) - { - if (WIFEXITED(status)) - { - return static_cast<char>(WEXITSTATUS(status)); - } - else - { - LOG(Warn,"Child exited abnormally"); - return -1; - } - } - else - { - LOG(Warn,"Failed to get exit status of child " + intToStr(pid)); - return WaitFailed; - } -} -#endif - -void ProcessUtils::runAsync(const std::string& executable, - const std::list<std::string>& args) -{ -#ifdef PLATFORM_WINDOWS - runWindows(executable,args,RunAsync); -#elif defined(PLATFORM_UNIX) - runAsyncUnix(executable,args); -#endif -} - -int ProcessUtils::runElevated(const std::string& executable, - const std::list<std::string>& args, - const std::string& task) -{ -#ifdef PLATFORM_WINDOWS - (void)task; - return runElevatedWindows(executable,args); -#elif defined(PLATFORM_MAC) - (void)task; - return runElevatedMac(executable,args); -#elif defined(PLATFORM_LINUX) - return runElevatedLinux(executable,args,task); -#endif -} - -bool ProcessUtils::waitForProcess(PLATFORM_PID pid) -{ -#ifdef PLATFORM_UNIX - pid_t result = ::waitpid(pid, 0, 0); - if (result < 0) - { - LOG(Error,"waitpid() failed with error: " + std::string(strerror(errno))); - } - return result > 0; -#elif defined(PLATFORM_WINDOWS) - HANDLE hProc; - - if (!(hProc = OpenProcess(SYNCHRONIZE, FALSE, pid))) - { - LOG(Error,"Unable to get process handle for pid " + intToStr(pid) + " last error " + intToStr(GetLastError())); - return false; - } - - DWORD dwRet = WaitForSingleObject(hProc, INFINITE); - CloseHandle(hProc); - - if (dwRet == WAIT_FAILED) - { - LOG(Error,"WaitForSingleObject failed with error " + intToStr(GetLastError())); - } - - return (dwRet == WAIT_OBJECT_0); -#endif -} - -#ifdef PLATFORM_LINUX -int ProcessUtils::runElevatedLinux(const std::string& executable, - const std::list<std::string>& args, - const std::string& _task) -{ - std::string task(_task); - if (task.empty()) - { - task = FileUtils::fileName(executable.c_str()); - } - - // try available graphical sudo instances until we find one that works. - // The different sudo front-ends have different behaviors with respect to error codes: - // - // - 'kdesudo': return 1 if the user enters the wrong password 3 times or if - // they cancel elevation - // - // - recent 'gksudo' versions: return 1 if the user enters the wrong password - // : return -1 if the user cancels elevation - // - // - older 'gksudo' versions : return 0 if the user cancels elevation - - std::vector<std::string> sudos; - - if (getenv("KDE_SESSION_VERSION")) - { - sudos.push_back("kdesudo"); - } - sudos.push_back("gksudo"); - - for (unsigned int i=0; i < sudos.size(); i++) - { - const std::string& sudoBinary = sudos.at(i); - - std::list<std::string> sudoArgs; - sudoArgs.push_back("-u"); - sudoArgs.push_back("root"); - - if (sudoBinary == "kdesudo") - { - sudoArgs.push_back("-d"); - sudoArgs.push_back("--comment"); - std::string sudoMessage = task + " needs administrative privileges. Please enter your password."; - sudoArgs.push_back(sudoMessage); - } - else if (sudoBinary == "gksudo") - { - sudoArgs.push_back("--description"); - sudoArgs.push_back(task); - } - else - { - sudoArgs.push_back(task); - } - - sudoArgs.push_back("--"); - sudoArgs.push_back(executable); - std::copy(args.begin(),args.end(),std::back_inserter(sudoArgs)); - - int result = ProcessUtils::runSync(sudoBinary,sudoArgs); - - LOG(Info,"Tried to use sudo " + sudoBinary + " with response " + intToStr(result)); - - if (result != RunFailed) - { - return result; - break; - } - } - return RunElevatedFailed; -} -#endif - -#ifdef PLATFORM_MAC -int ProcessUtils::runElevatedMac(const std::string& executable, - const std::list<std::string>& args) -{ - // request elevation using the Security Service. - // - // This only works when the application is being run directly - // from the Mac. Attempting to run the app via a remote SSH session - // (for example) will fail with an interaction-not-allowed error - - OSStatus status; - AuthorizationRef authorizationRef; - - status = AuthorizationCreate( - NULL, - kAuthorizationEmptyEnvironment, - kAuthorizationFlagDefaults, - &authorizationRef); - - AuthorizationItem right = { kAuthorizationRightExecute, 0, NULL, 0 }; - AuthorizationRights rights = { 1, &right }; - - AuthorizationFlags flags = kAuthorizationFlagDefaults | - kAuthorizationFlagInteractionAllowed | - kAuthorizationFlagPreAuthorize | - kAuthorizationFlagExtendRights; - - if (status == errAuthorizationSuccess) - { - status = AuthorizationCopyRights(authorizationRef, &rights, NULL, - flags, NULL); - - if (status == errAuthorizationSuccess) - { - char** argv; - argv = (char**) malloc(sizeof(char*) * args.size() + 1); - - unsigned int i = 0; - for (std::list<std::string>::const_iterator iter = args.begin(); iter != args.end(); iter++) - { - argv[i] = strdup(iter->c_str()); - ++i; - } - argv[i] = NULL; - - FILE* pipe = NULL; - - char* tool = strdup(executable.c_str()); - - status = AuthorizationExecuteWithPrivileges(authorizationRef, tool, - kAuthorizationFlagDefaults, argv, &pipe); - - if (status == errAuthorizationSuccess) - { - // AuthorizationExecuteWithPrivileges does not provide a way to get the process ID - // of the child process. - // - // Discussions on Apple development forums suggest two approaches for working around this, - // - // - Modify the child process to sent its process ID back to the parent via - // the pipe passed to AuthorizationExecuteWithPrivileges. - // - // - Use the generic Unix wait() call. - // - // This code uses wait(), which is simpler, but suffers from the problem that wait() waits - // for any child process, not necessarily the specific process launched - // by AuthorizationExecuteWithPrivileges. - // - // Apple's documentation (see 'Authorization Services Programming Guide') suggests - // installing files in an installer as a legitimate use for - // AuthorizationExecuteWithPrivileges but in general strongly recommends - // not using this call and discusses a number of other alternatives - // for performing privileged operations, - // which we could consider in future. - - int childStatus; - pid_t childPid = wait(&childStatus); - - if (childStatus != 0) - { - LOG(Error,"elevated process failed with status " + intToStr(childStatus) + " pid " - + intToStr(childPid)); - } - else - { - LOG(Info,"elevated process succeded with pid " + intToStr(childPid)); - } - - return childStatus; - } - else - { - LOG(Error,"failed to launch elevated process " + intToStr(status)); - return RunElevatedFailed; - } - - // If we want to know more information about what has happened: - // http://developer.apple.com/mac/library/documentation/Security/Reference/authorization_ref/Reference/reference.html#//apple_ref/doc/uid/TP30000826-CH4g-CJBEABHG - free(tool); - for (i = 0; i < args.size(); i++) - { - free(argv[i]); - } - } - else - { - LOG(Error,"failed to get rights to launch elevated process. status: " + intToStr(status)); - return RunElevatedFailed; - } - } - else - { - return RunElevatedFailed; - } -} -#endif - -// convert a list of arguments in a space-separated string. -// Arguments containing spaces are enclosed in quotes -std::string quoteArgs(const std::list<std::string>& arguments) -{ - std::string quotedArgs; - for (std::list<std::string>::const_iterator iter = arguments.begin(); - iter != arguments.end(); - iter++) - { - std::string arg = *iter; - - bool isQuoted = !arg.empty() && - arg.at(0) == '"' && - arg.at(arg.size()-1) == '"'; - - if (!isQuoted && arg.find(' ') != std::string::npos) - { - arg.insert(0,"\""); - arg.append("\""); - } - quotedArgs += arg; - quotedArgs += " "; - } - return quotedArgs; -} - -#ifdef PLATFORM_WINDOWS -int ProcessUtils::runElevatedWindows(const std::string& executable, - const std::list<std::string>& arguments) -{ - std::string args = quoteArgs(arguments); - - SHELLEXECUTEINFO executeInfo; - ZeroMemory(&executeInfo,sizeof(executeInfo)); - executeInfo.cbSize = sizeof(SHELLEXECUTEINFO); - executeInfo.fMask = SEE_MASK_NOCLOSEPROCESS; - // request UAC elevation - executeInfo.lpVerb = "runas"; - executeInfo.lpFile = executable.c_str(); - executeInfo.lpParameters = args.c_str(); - executeInfo.nShow = SW_SHOWNORMAL; - - LOG(Info,"Attempting to execute " + executable + " with administrator priviledges"); - if (!ShellExecuteEx(&executeInfo)) - { - LOG(Error,"Failed to start with admin priviledges using ShellExecuteEx()"); - return RunElevatedFailed; - } - - WaitForSingleObject(executeInfo.hProcess, INFINITE); - - // this assumes the process succeeded - we need to check whether - // this is actually the case. - return 0; -} -#endif - -#ifdef PLATFORM_UNIX -PLATFORM_PID ProcessUtils::runAsyncUnix(const std::string& executable, - const std::list<std::string>& args) -{ - pid_t child = fork(); - if (child == 0) - { - // in child process - char** argBuffer = new char*[args.size() + 2]; - argBuffer[0] = strdup(executable.c_str()); - int i = 1; - for (std::list<std::string>::const_iterator iter = args.begin(); iter != args.end(); iter++) - { - argBuffer[i] = strdup(iter->c_str()); - ++i; - } - argBuffer[i] = 0; - - if (execvp(executable.c_str(),argBuffer) == -1) - { - LOG(Error,"error starting child: " + std::string(strerror(errno))); - exit(RunFailed); - } - } - else - { - LOG(Info,"Started child process " + intToStr(child)); - } - return child; -} -#endif - -#ifdef PLATFORM_WINDOWS -int ProcessUtils::runWindows(const std::string& _executable, - const std::list<std::string>& _args, - RunMode runMode) -{ - // most Windows API functions allow back and forward slashes to be - // used interchangeably. However, an application started with - // CreateProcess() may fail to find Side-by-Side library dependencies - // in the same directory as the executable if forward slashes are - // used as path separators, so convert the path to use back slashes here. - // - // This may be related to LoadLibrary() requiring backslashes instead - // of forward slashes. - std::string executable = FileUtils::toWindowsPathSeparators(_executable); - - std::list<std::string> args(_args); - args.push_front(executable); - std::string commandLine = quoteArgs(args); - - STARTUPINFO startupInfo; - ZeroMemory(&startupInfo,sizeof(startupInfo)); - startupInfo.cb = sizeof(startupInfo); - - PROCESS_INFORMATION processInfo; - ZeroMemory(&processInfo,sizeof(processInfo)); - - char* commandLineStr = strdup(commandLine.c_str()); - bool result = CreateProcess( - executable.c_str(), - commandLineStr, - 0 /* process attributes */, - 0 /* thread attributes */, - false /* inherit handles */, - NORMAL_PRIORITY_CLASS /* creation flags */, - 0 /* environment */, - 0 /* current directory */, - &startupInfo /* startup info */, - &processInfo /* process information */ - ); - - if (!result) - { - LOG(Error,"Failed to start child process. " + executable + " Last error: " + intToStr(GetLastError())); - return RunFailed; - } - else - { - if (runMode == RunSync) - { - if (WaitForSingleObject(processInfo.hProcess,INFINITE) == WAIT_OBJECT_0) - { - DWORD status = WaitFailed; - if (GetExitCodeProcess(processInfo.hProcess,&status) != 0) - { - LOG(Error,"Failed to get exit code for process"); - } - return status; - } - else - { - LOG(Error,"Failed to wait for process to finish"); - return WaitFailed; - } - } - else - { - // process is being run asynchronously - return zero as if it had - // succeeded - return 0; - } - } -} -#endif - -std::string ProcessUtils::currentProcessPath() -{ -#ifdef PLATFORM_LINUX - std::string path = FileUtils::canonicalPath("/proc/self/exe"); - LOG(Info,"Current process path " + path); - return path; -#elif defined(PLATFORM_MAC) - uint32_t bufferSize = PATH_MAX; - char buffer[bufferSize]; - _NSGetExecutablePath(buffer,&bufferSize); - return buffer; -#else - char fileName[MAX_PATH]; - GetModuleFileName(0 /* get path of current process */,fileName,MAX_PATH); - return fileName; -#endif -} - -#ifdef PLATFORM_WINDOWS -void ProcessUtils::convertWindowsCommandLine(LPCWSTR commandLine, int& argc, char**& argv) -{ - argc = 0; - LPWSTR* argvUnicode = CommandLineToArgvW(commandLine,&argc); - - argv = new char*[argc]; - for (int i=0; i < argc; i++) - { - const int BUFFER_SIZE = 4096; - char buffer[BUFFER_SIZE]; - - int length = WideCharToMultiByte(CP_ACP, - 0 /* flags */, - argvUnicode[i], - -1, /* argvUnicode is null terminated */ - buffer, - BUFFER_SIZE, - 0, - false); - - // note: if WideCharToMultiByte() fails it will return zero, - // in which case we store a zero-length argument in argv - if (length == 0) - { - argv[i] = new char[1]; - argv[i][0] = '\0'; - } - else - { - // if the input string to WideCharToMultiByte is null-terminated, - // the output is also null-terminated - argv[i] = new char[length]; - strncpy(argv[i],buffer,length); - } - } - LocalFree(argvUnicode); -} -#endif - diff --git a/mmc_updater/src/ProcessUtils.h b/mmc_updater/src/ProcessUtils.h deleted file mode 100644 index e0cc3dc0..00000000 --- a/mmc_updater/src/ProcessUtils.h +++ /dev/null @@ -1,101 +0,0 @@ -#pragma once - -#include "Platform.h" - -#include <list> -#include <string> - -#ifndef PLATFORM_WINDOWS -#include <unistd.h> -#endif - -/** A set of functions to get information about the current - * process and launch new processes. - */ -class ProcessUtils -{ - public: - enum Errors - { - /** Status code returned by runElevated() if launching - * the elevated process fails. - */ - RunElevatedFailed = 255, - /** Status code returned by runSync() if the application - * cannot be started. - */ - RunFailed = -8, - /** Status code returned by runSync() if waiting for - * the application to exit and reading its status code fails. - */ - WaitFailed = -1 - }; - - static PLATFORM_PID currentProcessId(); - - /** Returns the absolute path to the main binary for - * the current process. - */ - static std::string currentProcessPath(); - - /** Start a process and wait for it to finish before - * returning its exit code. - * - * Returns -1 if the process cannot be started. - */ - static int runSync(const std::string& executable, - const std::list<std::string>& args); - - /** Start a process and return without waiting for - * it to finish. - */ - static void runAsync(const std::string& executable, - const std::list<std::string>& args); - - /** Run a process with administrative privileges and return the - * status code of the process, or 0 on Windows. - * - * Returns RunElevatedFailed if the elevated process could - * not be started. - */ - static int runElevated(const std::string& executable, - const std::list<std::string>& args, - const std::string& task); - - /** Wait for a process to exit. - * Returns true if the process was found and has exited or false - * otherwise. - */ - static bool waitForProcess(PLATFORM_PID pid); - -#ifdef PLATFORM_WINDOWS - /** Convert a unicode command line returned by GetCommandLineW() - * to a standard (argc,argv) pair. The resulting argv array and each - * element of argv must be freed using free() - */ - static void convertWindowsCommandLine(LPCWSTR commandLine, int& argc, char**& argv); -#endif - - private: - enum RunMode - { - RunSync, - RunAsync - }; - static int runElevatedLinux(const std::string& executable, - const std::list<std::string>& args, - const std::string& task); - static int runElevatedMac(const std::string& executable, - const std::list<std::string>& args); - static int runElevatedWindows(const std::string& executable, - const std::list<std::string>& args); - - static PLATFORM_PID runAsyncUnix(const std::string& executable, - const std::list<std::string>& args); - static int runWindows(const std::string& executable, - const std::list<std::string>& args, - RunMode runMode); - static int runSyncUnix(const std::string& executable, - const std::list<std::string>& args); -}; - diff --git a/mmc_updater/src/StandardDirs.cpp b/mmc_updater/src/StandardDirs.cpp deleted file mode 100644 index 72743d5e..00000000 --- a/mmc_updater/src/StandardDirs.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "StandardDirs.h" - -#include "FileUtils.h" -#include "StringUtils.h" - -#ifdef PLATFORM_UNIX - #include <stdlib.h> - #include <pwd.h> - #include <unistd.h> -#endif - -#ifdef PLATFORM_WINDOWS -#include <shlobj.h> -#endif - -#ifdef PLATFORM_UNIX -std::string StandardDirs::homeDir() -{ - std::string dir = notNullString(getenv("HOME")); - if (!dir.empty()) - { - return dir; - } - else - { - // note: if this process has been elevated with sudo, - // this will return the home directory of the root user - struct passwd* userData = getpwuid(getuid()); - return notNullString(userData->pw_dir); - } -} -#endif - -std::string StandardDirs::appDataPath(const std::string& organizationName, - const std::string& appName) -{ -#ifdef PLATFORM_LINUX - std::string xdgDataHome = notNullString(getenv("XDG_DATA_HOME")); - if (xdgDataHome.empty()) - { - xdgDataHome = homeDir() + "/.local/share"; - } - xdgDataHome += "/data/" + organizationName + '/' + appName; - return xdgDataHome; - -#elif defined(PLATFORM_MAC) - std::string path = applicationSupportFolderPath(); - path += '/' + appName; - return path; -#elif defined(PLATFORM_WINDOWS) - char buffer[MAX_PATH + 1]; - if (SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0 /* hToken */, SHGFP_TYPE_CURRENT, buffer) == S_OK) - { - std::string path = FileUtils::toUnixPathSeparators(notNullString(buffer)); - path += '/' + organizationName + '/' + appName; - return path; - } - else - { - return std::string(); - } -#endif -} diff --git a/mmc_updater/src/StandardDirs.h b/mmc_updater/src/StandardDirs.h deleted file mode 100644 index 18526173..00000000 --- a/mmc_updater/src/StandardDirs.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "Platform.h" - -#include <string> - -class StandardDirs -{ - public: - static std::string appDataPath(const std::string& organizationName, - const std::string& appName); - - private: -#ifdef PLATFORM_UNIX - static std::string homeDir(); -#endif - -#ifdef PLATFORM_MAC - static std::string applicationSupportFolderPath(); -#endif -}; - diff --git a/mmc_updater/src/StandardDirs.mm b/mmc_updater/src/StandardDirs.mm deleted file mode 100644 index 53eecd47..00000000 --- a/mmc_updater/src/StandardDirs.mm +++ /dev/null @@ -1,18 +0,0 @@ -#include <Foundation/Foundation.h> - -#include "StandardDirs.h" - -std::string StandardDirs::applicationSupportFolderPath() -{ - NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, - NSUserDomainMask, - true /* expand tildes */); - - for (unsigned int i=0; i < [paths count]; i++) - { - NSString* path = [paths objectAtIndex:i]; - return std::string([path UTF8String]); - } - return std::string(); -} - diff --git a/mmc_updater/src/StlSymbolsLeopard.cpp b/mmc_updater/src/StlSymbolsLeopard.cpp deleted file mode 100644 index 932c78f0..00000000 --- a/mmc_updater/src/StlSymbolsLeopard.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Workarounds for iostream symbols that are referenced when building on OS X 10.7 but missing from -// OS X 10.5's stdlibc++.dylib. -// -// In the <iostream> headers these are declared as extern templates but the symbols are not present under 10.5. -// This file forces the compiler to instantiate the templates. -// -// see http://stackoverflow.com/questions/3484043/os-x-program-runs-on-dev-machine-crashing-horribly-on-others - -// Only do this on GCC. It fails builds on clang. -#if defined(__GCC__) - -#include <iostream> - -_GLIBCXX_BEGIN_NAMESPACE(std) -// From ostream_insert.h -template ostream& __ostream_insert(ostream&, const char*, streamsize); - -#ifdef _GLIBCXX_USE_WCHAR_T -template wostream& __ostream_insert(wostream&, const wchar_t*, streamsize); -#endif - -// From ostream.tcc -template ostream& ostream::_M_insert(long); -template ostream& ostream::_M_insert(unsigned long); -template ostream& ostream::_M_insert(bool); -#ifdef _GLIBCXX_USE_LONG_LONG -template ostream& ostream::_M_insert(long long); -template ostream& ostream::_M_insert(unsigned long long); -#endif -template ostream& ostream::_M_insert(double); -template ostream& ostream::_M_insert(long double); -template ostream& ostream::_M_insert(const void*); - -#ifdef _GLIBCXX_USE_WCHAR_T -template wostream& wostream::_M_insert(long); -template wostream& wostream::_M_insert(unsigned long); -template wostream& wostream::_M_insert(bool); -#ifdef _GLIBCXX_USE_LONG_LONG -template wostream& wostream::_M_insert(long long); -template wostream& wostream::_M_insert(unsigned long long); -#endif -template wostream& wostream::_M_insert(double); -template wostream& wostream::_M_insert(long double); -template wostream& wostream::_M_insert(const void*); -#endif - -// From istream.tcc -template istream& istream::_M_extract(unsigned short&); -template istream& istream::_M_extract(unsigned int&); -template istream& istream::_M_extract(long&); -template istream& istream::_M_extract(unsigned long&); -template istream& istream::_M_extract(bool&); -#ifdef _GLIBCXX_USE_LONG_LONG -template istream& istream::_M_extract(long long&); -template istream& istream::_M_extract(unsigned long long&); -#endif -template istream& istream::_M_extract(float&); -template istream& istream::_M_extract(double&); -template istream& istream::_M_extract(long double&); -template istream& istream::_M_extract(void*&); - -#ifdef _GLIBCXX_USE_WCHAR_T -template wistream& wistream::_M_extract(unsigned short&); -template wistream& wistream::_M_extract(unsigned int&); -template wistream& wistream::_M_extract(long&); -template wistream& wistream::_M_extract(unsigned long&); -template wistream& wistream::_M_extract(bool&); -#ifdef _GLIBCXX_USE_LONG_LONG -template wistream& wistream::_M_extract(long long&); -template wistream& wistream::_M_extract(unsigned long long&); -#endif -template wistream& wistream::_M_extract(float&); -template wistream& wistream::_M_extract(double&); -template wistream& wistream::_M_extract(long double&); -template wistream& wistream::_M_extract(void*&); -#endif - -_GLIBCXX_END_NAMESPACE - -#endif - diff --git a/mmc_updater/src/StringUtils.h b/mmc_updater/src/StringUtils.h deleted file mode 100644 index 745b71c9..00000000 --- a/mmc_updater/src/StringUtils.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include <string.h> -#include <string> -#include <sstream> -#include <stdlib.h> - -template <class T> -inline std::string intToStr(T i) -{ - std::stringstream stream; - stream << i; - return stream.str(); -} - -inline bool strToBool(const std::string& str) -{ - return str == "true" || atoi(str.c_str()) != 0; -} - -/** Returns @p text if non-null or a pointer - * to an empty null-terminated string otherwise. - */ -inline const char* notNullString(const char* text) -{ - if (text) - { - return text; - } - else - { - return ""; - } -} - -inline bool endsWith(const std::string& str, const char* text) -{ - size_t length = strlen(text); - return str.find(text,str.size() - length) != std::string::npos; -} - -inline bool startsWith(const std::string& str, const char* text) -{ - return str.find(text,0) == 0; -} - diff --git a/mmc_updater/src/UpdateDialog.cpp b/mmc_updater/src/UpdateDialog.cpp deleted file mode 100644 index 5f181a1c..00000000 --- a/mmc_updater/src/UpdateDialog.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "UpdateDialog.h" - -UpdateDialog::UpdateDialog() -: m_autoClose(false) -{ -} - -void UpdateDialog::setAutoClose(bool autoClose) -{ - m_autoClose = autoClose; -} - -bool UpdateDialog::autoClose() const -{ - return m_autoClose; -} - -void UpdateDialog::updateFinished() -{ - if (m_autoClose) - { - quit(); - } -} - diff --git a/mmc_updater/src/UpdateDialog.h b/mmc_updater/src/UpdateDialog.h deleted file mode 100644 index d0782f8f..00000000 --- a/mmc_updater/src/UpdateDialog.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "UpdateObserver.h" - -/** Base class for the updater's UI, sub-classed - * by the different platform implementations. - */ -class UpdateDialog : public UpdateObserver -{ - public: - UpdateDialog(); - virtual ~UpdateDialog() {}; - - /** Sets whether the updater should automatically - * exit once the update has been installed. - */ - void setAutoClose(bool autoClose); - bool autoClose() const; - - virtual void init(int argc, char** argv) = 0; - virtual void exec() = 0; - virtual void quit() = 0; - - virtual void updateFinished(); - - private: - bool m_autoClose; -}; - diff --git a/mmc_updater/src/UpdateDialogAscii.cpp b/mmc_updater/src/UpdateDialogAscii.cpp deleted file mode 100644 index 78eb7433..00000000 --- a/mmc_updater/src/UpdateDialogAscii.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "UpdateDialogAscii.h" - -#include "AppInfo.h" -#include "ProcessUtils.h" -#include "StringUtils.h" - -const char* introMessage = - "%s (ASCII-art edition)\n" - "====================================\n" - "\n" - "We have a nice graphical interface for the %s, but unfortunately\n" - "we can't show it to you :(\n" - "\n" - "You can fix this by installing the GTK 2 libraries.\n\n" - "Installing Updates...\n"; - -void UpdateDialogAscii::init(int /* argc */, char** /* argv */) -{ - const char* path = "/tmp/update-progress"; - m_output.open(path); - - char message[4096]; - sprintf(message,introMessage,AppInfo::name().c_str()); - m_output << message; - - std::string command = "xterm"; - std::list<std::string> args; - args.push_back("-hold"); - args.push_back("-T"); - args.push_back(AppInfo::name()); - args.push_back("-e"); - args.push_back("tail"); - args.push_back("-n+1"); - args.push_back("-f"); - args.push_back(path); - - ProcessUtils::runAsync(command,args); -} - -void UpdateDialogAscii::updateError(const std::string& errorMessage) -{ - m_mutex.lock(); - m_output << "\nThere was a problem installing the update: " << errorMessage << std::endl; - m_mutex.unlock(); -} - -void UpdateDialogAscii::updateProgress(int percentage) -{ - m_mutex.lock(); - m_output << "Update Progress: " << intToStr(percentage) << '%' << std::endl; - m_mutex.unlock(); -} - -void UpdateDialogAscii::updateFinished() -{ - m_mutex.lock(); - m_output << "\nUpdate Finished. You can now restart " << AppInfo::appName() << "." << std::endl; - m_mutex.unlock(); - - UpdateDialog::updateFinished(); -} - -void UpdateDialogAscii::quit() -{ -} - -void UpdateDialogAscii::exec() -{ -} - diff --git a/mmc_updater/src/UpdateDialogAscii.h b/mmc_updater/src/UpdateDialogAscii.h deleted file mode 100644 index 138194c5..00000000 --- a/mmc_updater/src/UpdateDialogAscii.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "UpdateDialog.h" - -#include <fstream> -#include <thread> -#include <mutex> - -/** A fallback auto-update progress 'dialog' for use on - * Linux when the GTK UI cannot be loaded. - * - * The 'dialog' consists of an xterm tailing the contents - * of a file, into which progress messages are written. - */ -class UpdateDialogAscii : public UpdateDialog -{ - public: - // implements UpdateDialog - virtual void init(int argc, char** argv); - virtual void exec(); - virtual void quit(); - - // implements UpdateObserver - virtual void updateError(const std::string& errorMessage); - virtual void updateProgress(int percentage); - virtual void updateFinished(); - - private: - std::mutex m_mutex; - std::ofstream m_output; -}; - diff --git a/mmc_updater/src/UpdateDialogCocoa.h b/mmc_updater/src/UpdateDialogCocoa.h deleted file mode 100644 index 586fdc8e..00000000 --- a/mmc_updater/src/UpdateDialogCocoa.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "UpdateDialog.h" -#include "UpdateObserver.h" - -class UpdateDialogPrivate; - -class UpdateDialogCocoa : public UpdateDialog -{ - public: - UpdateDialogCocoa(); - ~UpdateDialogCocoa(); - - // implements UpdateDialog - virtual void init(int argc, char** argv); - virtual void exec(); - virtual void quit(); - - // implements UpdateObserver - virtual void updateError(const std::string& errorMessage); - virtual void updateProgress(int percentage); - virtual void updateFinished(); - - static void* createAutoreleasePool(); - static void releaseAutoreleasePool(void* data); - - private: - void enableDockIcon(); - - UpdateDialogPrivate* d; -}; - diff --git a/mmc_updater/src/UpdateDialogCocoa.mm b/mmc_updater/src/UpdateDialogCocoa.mm deleted file mode 100644 index f24f3c4d..00000000 --- a/mmc_updater/src/UpdateDialogCocoa.mm +++ /dev/null @@ -1,194 +0,0 @@ -#include "UpdateDialogCocoa.h" - -#include <Cocoa/Cocoa.h> -#include <Carbon/Carbon.h> - -#include "AppInfo.h" -#include "Log.h" -#include "StringUtils.h" - -@interface UpdateDialogDelegate : NSObject -{ - @public UpdateDialogPrivate* dialog; -} -- (void) finishClicked; -- (void) reportUpdateError:(id)arg; -- (void) reportUpdateProgress:(id)arg; -- (void) reportUpdateFinished:(id)arg; -@end - -class UpdateDialogPrivate -{ - public: - UpdateDialogPrivate() - : hadError(false) - { - } - - UpdateDialogDelegate* delegate; - NSAutoreleasePool* pool; - NSWindow* window; - NSButton* finishButton; - NSTextField* progressLabel; - NSProgressIndicator* progressBar; - bool hadError; -}; - -@implementation UpdateDialogDelegate -- (void) finishClicked -{ - [NSApp stop:self]; -} -- (void) reportUpdateError: (id)arg -{ - dialog->hadError = true; - - NSAlert* alert = [NSAlert - alertWithMessageText: @"Update Problem" - defaultButton: nil - alternateButton: nil - otherButton: nil - informativeTextWithFormat: @"There was a problem installing the update:\n\n%@", arg]; - [alert runModal]; -} -- (void) reportUpdateProgress: (id)arg -{ - int percentage = [arg intValue]; - [dialog->progressBar setDoubleValue:(percentage/100.0)]; -} -- (void) reportUpdateFinished: (id)arg -{ - NSMutableString* message = [[NSMutableString alloc] init]; - if (!dialog->hadError) - { - [message appendString:@"Updates installed."]; - } - else - { - [message appendString:@"Update failed."]; - } - - [message appendString:@" Click 'Finish' to restart the application."]; - [dialog->progressLabel setTitleWithMnemonic:message]; - [message release]; -} -@end - -UpdateDialogCocoa::UpdateDialogCocoa() -: d(new UpdateDialogPrivate) -{ - [NSApplication sharedApplication]; - d->pool = [[NSAutoreleasePool alloc] init]; -} - -UpdateDialogCocoa::~UpdateDialogCocoa() -{ - [d->pool release]; -} - -void UpdateDialogCocoa::enableDockIcon() -{ - // convert the application to a foreground application and in - // the process, enable the dock icon - - // the reverse transformation is not possible, according to - // http://stackoverflow.com/questions/2832961/is-it-possible-to-hide-the-dock-icon-programmatically - ProcessSerialNumber psn; - GetCurrentProcess(&psn); - TransformProcessType(&psn,kProcessTransformToForegroundApplication); -} - -void UpdateDialogCocoa::init(int /* argc */, char** /* argv */) -{ - enableDockIcon(); - - // make the updater the active application. This does not - // happen automatically because the updater starts as a - // background application - [NSApp activateIgnoringOtherApps:YES]; - - d->delegate = [[UpdateDialogDelegate alloc] init]; - d->delegate->dialog = d; - - int width = 370; - int height = 100; - - d->window = [[NSWindow alloc] initWithContentRect:NSMakeRect(200, 200, width, height) - styleMask:NSTitledWindowMask | NSMiniaturizableWindowMask - backing:NSBackingStoreBuffered defer:NO]; - [d->window setTitle:[NSString stringWithUTF8String:AppInfo::name().c_str()]]; - - d->finishButton = [[NSButton alloc] init]; - [d->finishButton setTitle:@"Finish"]; - [d->finishButton setButtonType:NSMomentaryLightButton]; - [d->finishButton setBezelStyle:NSRoundedBezelStyle]; - [d->finishButton setTarget:d->delegate]; - [d->finishButton setAction:@selector(finishClicked)]; - - d->progressBar = [[NSProgressIndicator alloc] init]; - [d->progressBar setIndeterminate:false]; - [d->progressBar setMinValue:0.0]; - [d->progressBar setMaxValue:1.0]; - - d->progressLabel = [[NSTextField alloc] init]; - [d->progressLabel setEditable:false]; - [d->progressLabel setSelectable:false]; - [d->progressLabel setTitleWithMnemonic:@"Installing Updates"]; - [d->progressLabel setBezeled:false]; - [d->progressLabel setDrawsBackground:false]; - - NSView* windowContent = [d->window contentView]; - [windowContent addSubview:d->progressLabel]; - [windowContent addSubview:d->progressBar]; - [windowContent addSubview:d->finishButton]; - - [d->progressLabel setFrame:NSMakeRect(10,70,width - 10,20)]; - [d->progressBar setFrame:NSMakeRect(10,40,width - 20,20)]; - [d->finishButton setFrame:NSMakeRect(width - 85,5,80,30)]; -} - -void UpdateDialogCocoa::exec() -{ - [d->window makeKeyAndOrderFront:d->window]; - [d->window center]; - [NSApp run]; -} - -void UpdateDialogCocoa::updateError(const std::string& errorMessage) -{ - [d->delegate performSelectorOnMainThread:@selector(reportUpdateError:) - withObject:[NSString stringWithUTF8String:errorMessage.c_str()] - waitUntilDone:false]; -} - -void UpdateDialogCocoa::updateProgress(int percentage) -{ - [d->delegate performSelectorOnMainThread:@selector(reportUpdateProgress:) - withObject:[NSNumber numberWithInt:percentage] - waitUntilDone:false]; -} - -void UpdateDialogCocoa::updateFinished() -{ - [d->delegate performSelectorOnMainThread:@selector(reportUpdateFinished:) - withObject:nil - waitUntilDone:false]; - UpdateDialog::updateFinished(); -} - -void* UpdateDialogCocoa::createAutoreleasePool() -{ - return [[NSAutoreleasePool alloc] init]; -} - -void UpdateDialogCocoa::releaseAutoreleasePool(void* arg) -{ - [(id)arg release]; -} - -void UpdateDialogCocoa::quit() -{ - [NSApp performSelectorOnMainThread:@selector(stop:) withObject:d->delegate waitUntilDone:false]; -} - - diff --git a/mmc_updater/src/UpdateDialogGtk.cpp b/mmc_updater/src/UpdateDialogGtk.cpp deleted file mode 100644 index d91144f5..00000000 --- a/mmc_updater/src/UpdateDialogGtk.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include "UpdateDialogGtk.h" - -#include "AppInfo.h" -#include "StringUtils.h" - -#include <glib.h> -#include <gtk/gtk.h> - -UpdateDialogGtk* update_dialog_gtk_new() -{ - return new UpdateDialogGtk(); -} - -UpdateDialogGtk::UpdateDialogGtk() -: m_hadError(false) -{ -} - -void UpdateDialogGtk::init(int argc, char** argv) -{ - gtk_init(&argc,&argv); - - m_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(m_window),AppInfo::name().c_str()); - - m_progressLabel = gtk_label_new("Installing Updates"); - - GtkWidget* windowLayout = gtk_vbox_new(FALSE,3); - GtkWidget* buttonLayout = gtk_hbox_new(FALSE,3); - GtkWidget* labelLayout = gtk_hbox_new(FALSE,3); - - m_finishButton = gtk_button_new_with_label("Finish"); - gtk_widget_set_sensitive(m_finishButton,false); - - m_progressBar = gtk_progress_bar_new(); - - // give the dialog a sensible default size by setting a minimum - // width on the progress bar. This is used instead of setting - // a default size for the dialog since gtk_window_set_default_size() - // is ignored when a dialog is marked as non-resizable - gtk_widget_set_usize(m_progressBar,350,-1); - - gtk_signal_connect(GTK_OBJECT(m_finishButton),"clicked", - GTK_SIGNAL_FUNC(UpdateDialogGtk::finish),this); - - gtk_container_add(GTK_CONTAINER(m_window),windowLayout); - gtk_container_set_border_width(GTK_CONTAINER(m_window),12); - - gtk_box_pack_start(GTK_BOX(labelLayout),m_progressLabel,false,false,0); - gtk_box_pack_end(GTK_BOX(buttonLayout),m_finishButton,false,false,0); - - gtk_box_pack_start(GTK_BOX(windowLayout),labelLayout,false,false,0); - gtk_box_pack_start(GTK_BOX(windowLayout),m_progressBar,false,false,0); - gtk_box_pack_start(GTK_BOX(windowLayout),buttonLayout,false,false,0); - - - gtk_widget_show(m_progressLabel); - gtk_widget_show(labelLayout); - gtk_widget_show(windowLayout); - gtk_widget_show(buttonLayout); - gtk_widget_show(m_finishButton); - gtk_widget_show(m_progressBar); - - gtk_window_set_resizable(GTK_WINDOW(m_window),false); - gtk_window_set_position(GTK_WINDOW(m_window),GTK_WIN_POS_CENTER); - - gtk_widget_show(m_window); -} - -void UpdateDialogGtk::exec() -{ - gtk_main(); -} - -void UpdateDialogGtk::finish(GtkWidget* widget, gpointer _dialog) -{ - UpdateDialogGtk* dialog = static_cast<UpdateDialogGtk*>(_dialog); - dialog->quit(); -} - -void UpdateDialogGtk::quit() -{ - gtk_main_quit(); -} - -gboolean UpdateDialogGtk::notify(void* _message) -{ - UpdateMessage* message = static_cast<UpdateMessage*>(_message); - UpdateDialogGtk* dialog = static_cast<UpdateDialogGtk*>(message->receiver); - switch (message->type) - { - case UpdateMessage::UpdateProgress: - gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(dialog->m_progressBar),message->progress/100.0); - break; - case UpdateMessage::UpdateFailed: - { - dialog->m_hadError = true; - std::string errorMessage = AppInfo::updateErrorMessage(message->message); - GtkWidget* errorDialog = gtk_message_dialog_new (GTK_WINDOW(dialog->m_window), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "%s", - errorMessage.c_str()); - gtk_dialog_run (GTK_DIALOG (errorDialog)); - gtk_widget_destroy (errorDialog); - gtk_widget_set_sensitive(dialog->m_finishButton,true); - } - break; - case UpdateMessage::UpdateFinished: - { - std::string message; - if (dialog->m_hadError) - { - message = "Update failed."; - } - else - { - message = "Update installed."; - } - message += " Click 'Finish' to restart the application."; - gtk_label_set_text(GTK_LABEL(dialog->m_progressLabel),message.c_str()); - gtk_widget_set_sensitive(dialog->m_finishButton,true); - } - break; - } - delete message; - - // do not invoke this function again - return false; -} - -// callbacks during update installation -void UpdateDialogGtk::updateError(const std::string& errorMessage) -{ - UpdateMessage* message = new UpdateMessage(this,UpdateMessage::UpdateFailed); - message->message = errorMessage; - g_idle_add(&UpdateDialogGtk::notify,message); -} - -void UpdateDialogGtk::updateProgress(int percentage) -{ - UpdateMessage* message = new UpdateMessage(this,UpdateMessage::UpdateProgress); - message->progress = percentage; - g_idle_add(&UpdateDialogGtk::notify,message); -} - -void UpdateDialogGtk::updateFinished() -{ - UpdateMessage* message = new UpdateMessage(this,UpdateMessage::UpdateFinished); - g_idle_add(&UpdateDialogGtk::notify,message); - UpdateDialog::updateFinished(); -} - - diff --git a/mmc_updater/src/UpdateDialogGtk.h b/mmc_updater/src/UpdateDialogGtk.h deleted file mode 100644 index 70e29c78..00000000 --- a/mmc_updater/src/UpdateDialogGtk.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "UpdateDialog.h" -#include "UpdateMessage.h" -#include "UpdateObserver.h" - -#include <gtk/gtk.h> - -class UpdateDialogGtk : public UpdateDialog -{ - public: - UpdateDialogGtk(); - - // implements UpdateDialog - virtual void init(int argc, char** argv); - virtual void exec(); - virtual void quit(); - - // observer callbacks - these may be called - // from a background thread - virtual void updateError(const std::string& errorMessage); - virtual void updateProgress(int percentage); - virtual void updateFinished(); - - private: - static void finish(GtkWidget* widget, gpointer dialog); - static gboolean notify(void* message); - - GtkWidget* m_window; - GtkWidget* m_progressLabel; - GtkWidget* m_finishButton; - GtkWidget* m_progressBar; - bool m_hadError; -}; - -// helper functions which allow the GTK dialog to be loaded dynamically -// at runtime and used only if the GTK libraries are actually present -extern "C" { - UpdateDialogGtk* update_dialog_gtk_new(); -} - - diff --git a/mmc_updater/src/UpdateDialogGtkFactory.cpp b/mmc_updater/src/UpdateDialogGtkFactory.cpp deleted file mode 100644 index 313da31a..00000000 --- a/mmc_updater/src/UpdateDialogGtkFactory.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "UpdateDialogGtkFactory.h" - -#include "Log.h" -#include "UpdateDialog.h" -#include "StringUtils.h" - -#include <dlfcn.h> -#include <errno.h> -#include <fcntl.h> -#include <string.h> -#include <sys/stat.h> -#include <unistd.h> - -class UpdateDialogGtk; - -// GTK updater UI library embedded into -// the updater binary -extern unsigned char libupdatergtk_so[]; -extern unsigned int libupdatergtk_so_len; - -// pointers to helper functions in the GTK updater UI library -UpdateDialogGtk* (*update_dialog_gtk_new)() = 0; - -bool extractFileFromBinary(const char* path, const void* buffer, size_t length) -{ - int fd = open(path,O_CREAT | O_WRONLY | O_TRUNC,0755); - size_t count = write(fd,buffer,length); - if (fd < 0 || count < length) - { - if (fd >= 0) - { - close(fd); - } - return false; - } - close(fd); - return true; -} - -UpdateDialog* UpdateDialogGtkFactory::createDialog() -{ - const char* libPath = "/tmp/libupdatergtk.so"; - - if (!extractFileFromBinary(libPath,libupdatergtk_so,libupdatergtk_so_len)) - { - LOG(Warn,"Failed to load the GTK UI library - " + std::string(strerror(errno))); - return 0; - } - - void* gtkLib = dlopen(libPath,RTLD_LAZY); - if (!gtkLib) - { - LOG(Warn,"Failed to load the GTK UI - " + std::string(dlerror())); - return 0; - } - update_dialog_gtk_new = (UpdateDialogGtk* (*)()) dlsym(gtkLib,"update_dialog_gtk_new"); - return reinterpret_cast<UpdateDialog*>(update_dialog_gtk_new()); -} - diff --git a/mmc_updater/src/UpdateDialogGtkFactory.h b/mmc_updater/src/UpdateDialogGtkFactory.h deleted file mode 100644 index 1806c252..00000000 --- a/mmc_updater/src/UpdateDialogGtkFactory.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -class UpdateDialog; - -/** Factory for loading the GTK version of the update dialog - * dynamically at runtime if the GTK libraries are available. - */ -class UpdateDialogGtkFactory -{ - public: - static UpdateDialog* createDialog(); -}; - diff --git a/mmc_updater/src/UpdateDialogWin32.cpp b/mmc_updater/src/UpdateDialogWin32.cpp deleted file mode 100644 index 8b38bed2..00000000 --- a/mmc_updater/src/UpdateDialogWin32.cpp +++ /dev/null @@ -1,215 +0,0 @@ -#include "UpdateDialogWin32.h" - -#include "AppInfo.h" -#include "Log.h" - -// enable themed controls -// see http://msdn.microsoft.com/en-us/library/bb773175%28v=vs.85%29.aspx -// for details -#pragma comment(linker,"\"/manifestdependency:type='win32' \ -name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ -processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") - -static const char* updateDialogClassName = "UPDATEDIALOG"; - -static std::map<HWND,UpdateDialogWin32*> windowDialogMap; - -// enable the standard Windows font for a widget -// (typically Tahoma or Segoe UI) -void setDefaultFont(HWND window) -{ - SendMessage(window, WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0)); -} - -LRESULT WINAPI updateDialogWindowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) -{ - std::map<HWND,UpdateDialogWin32*>::const_iterator iter = windowDialogMap.find(window); - if (iter != windowDialogMap.end()) - { - return iter->second->windowProc(window,message,wParam,lParam); - } - else - { - return DefWindowProc(window,message,wParam,lParam); - } -}; - -void registerWindowClass() -{ - WNDCLASSEX wcex; - ZeroMemory(&wcex,sizeof(WNDCLASSEX)); - - wcex.cbSize = sizeof(WNDCLASSEX); - - HBRUSH background = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); - - wcex.style = CS_HREDRAW | CS_VREDRAW; - wcex.lpfnWndProc = updateDialogWindowProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hIcon = LoadIcon(GetModuleHandle(0),"IDI_APPICON"); - wcex.hCursor = LoadCursor(0,IDC_ARROW); - wcex.hbrBackground = (HBRUSH)background; - wcex.lpszMenuName = (LPCTSTR)0; - wcex.lpszClassName = updateDialogClassName; - wcex.hIconSm = 0; - wcex.hInstance = GetModuleHandle(0); - - RegisterClassEx(&wcex); -} - -UpdateDialogWin32::UpdateDialogWin32() -: m_hadError(false) -{ - registerWindowClass(); -} - -UpdateDialogWin32::~UpdateDialogWin32() -{ - for (std::map<HWND,UpdateDialogWin32*>::iterator iter = windowDialogMap.begin(); - iter != windowDialogMap.end(); - iter++) - { - if (iter->second == this) - { - std::map<HWND,UpdateDialogWin32*>::iterator oldIter = iter; - ++iter; - windowDialogMap.erase(oldIter); - } - else - { - ++iter; - } - } -} - -void UpdateDialogWin32::init(int /* argc */, char** /* argv */) -{ - int width = 400; - int height = 150; - - DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; - m_window.CreateEx(0 /* dwExStyle */, - updateDialogClassName /* class name */, - AppInfo::name().c_str(), - style, - 0, 0, width, height, - 0 /* parent */, 0 /* menu */, 0 /* reserved */); - m_progressBar.Create(&m_window); - m_finishButton.Create(&m_window); - m_progressLabel.Create(&m_window); - - installWindowProc(&m_window); - installWindowProc(&m_finishButton); - - setDefaultFont(m_progressLabel); - setDefaultFont(m_finishButton); - - m_progressBar.SetRange(0,100); - m_finishButton.SetWindowText("Finish"); - m_finishButton.EnableWindow(false); - m_progressLabel.SetWindowText("Installing Updates"); - - m_window.SetWindowPos(0,0,0,width,height,0); - m_progressBar.SetWindowPos(0,10,40,width - 30,20,0); - m_progressLabel.SetWindowPos(0,10,15,width - 30,20,0); - m_finishButton.SetWindowPos(0,width-100,70,80,25,0); - m_window.CenterWindow(); - m_window.ShowWindow(); -} - -void UpdateDialogWin32::exec() -{ - m_app.Run(); -} - -void UpdateDialogWin32::updateError(const std::string& errorMessage) -{ - UpdateMessage* message = new UpdateMessage(UpdateMessage::UpdateFailed); - message->message = errorMessage; - SendNotifyMessage(m_window.GetHwnd(),WM_USER,reinterpret_cast<WPARAM>(message),0); -} - -void UpdateDialogWin32::updateProgress(int percentage) -{ - UpdateMessage* message = new UpdateMessage(UpdateMessage::UpdateProgress); - message->progress = percentage; - SendNotifyMessage(m_window.GetHwnd(),WM_USER,reinterpret_cast<WPARAM>(message),0); -} - -void UpdateDialogWin32::updateFinished() -{ - UpdateMessage* message = new UpdateMessage(UpdateMessage::UpdateFinished); - SendNotifyMessage(m_window.GetHwnd(),WM_USER,reinterpret_cast<WPARAM>(message),0); - UpdateDialog::updateFinished(); -} - -void UpdateDialogWin32::quit() -{ - PostThreadMessage(GetWindowThreadProcessId(m_window.GetHwnd(), 0 /* process ID */), WM_QUIT, 0, 0); -} - -LRESULT WINAPI UpdateDialogWin32::windowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_CLOSE: - if (window == m_window.GetHwnd()) - { - return 0; - } - break; - case WM_COMMAND: - { - if (reinterpret_cast<HWND>(lParam) == m_finishButton.GetHwnd()) - { - quit(); - } - } - break; - case WM_USER: - { - if (window == m_window.GetHwnd()) - { - UpdateMessage* message = reinterpret_cast<UpdateMessage*>(wParam); - switch (message->type) - { - case UpdateMessage::UpdateFailed: - { - m_hadError = true; - std::string text = AppInfo::updateErrorMessage(message->message); - MessageBox(m_window.GetHwnd(),text.c_str(),"Update Problem",MB_OK); - } - break; - case UpdateMessage::UpdateProgress: - m_progressBar.SetPos(message->progress); - break; - case UpdateMessage::UpdateFinished: - { - std::string message; - m_finishButton.EnableWindow(true); - if (m_hadError) - { - message = "Update failed."; - } - else - { - message = "Updates installed."; - } - message += " Click 'Finish' to restart the application."; - m_progressLabel.SetWindowText(message.c_str()); - } - break; - } - delete message; - } - } - break; - } - return DefWindowProc(window,message,wParam,lParam); -} - -void UpdateDialogWin32::installWindowProc(CWnd* window) -{ - windowDialogMap[window->GetHwnd()] = this; -} diff --git a/mmc_updater/src/UpdateDialogWin32.h b/mmc_updater/src/UpdateDialogWin32.h deleted file mode 100644 index fe4208c8..00000000 --- a/mmc_updater/src/UpdateDialogWin32.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "Platform.h" -#include "UpdateDialog.h" -#include "UpdateMessage.h" - -#include "wincore.h" -#include "controls.h" -#include "stdcontrols.h" - -class UpdateDialogWin32 : public UpdateDialog -{ - public: - UpdateDialogWin32(); - ~UpdateDialogWin32(); - - // implements UpdateDialog - virtual void init(int argc, char** argv); - virtual void exec(); - virtual void quit(); - - // implements UpdateObserver - virtual void updateError(const std::string& errorMessage); - virtual void updateProgress(int percentage); - virtual void updateFinished(); - - LRESULT WINAPI windowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam); - - private: - void installWindowProc(CWnd* window); - - CWinApp m_app; - CWnd m_window; - CStatic m_progressLabel; - CProgressBar m_progressBar; - CButton m_finishButton; - bool m_hadError; -}; - 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; -} diff --git a/mmc_updater/src/UpdateInstaller.h b/mmc_updater/src/UpdateInstaller.h deleted file mode 100644 index 5920deec..00000000 --- a/mmc_updater/src/UpdateInstaller.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include "Platform.h" -#include "FileUtils.h" -#include "UpdateScript.h" - -#include <list> -#include <string> -#include <map> - -class UpdateObserver; - -/** Central class responsible for installing updates, - * launching an elevated copy of the updater if required - * and restarting the main application once the update - * is installed. - */ -class UpdateInstaller -{ - public: - enum Mode - { - Setup, - Main - }; - - void setInstallDir(const std::string& path); - void setPackageDir(const std::string& path); - void setBackupDir(const std::string& path); - void setMode(Mode mode); - void setScript(UpdateScript* script); - void setWaitPid(PLATFORM_PID pid); - void setForceElevated(bool elevated); - void setAutoClose(bool autoClose); - void setDryRun(bool dryRun); - void setFinishCmd(const std::string& cmd); - void setFinishDir(const std::string& dir); - - void setObserver(UpdateObserver* observer); - - void run() throw (); - - void restartMainApp(); - - private: - void cleanup(); - void revert(); - void removeBackups(); - bool checkAccess(); - - void installFiles(); - void uninstallFiles(); - void installFile(const UpdateScriptFile& file); - void backupFile(const std::string& path); - void reportError(const std::string& error); - void postInstallUpdate(); - - std::list<std::string> updaterArgs() const; - std::string friendlyErrorForError(const FileUtils::IOException& ex) const; - - Mode m_mode = Setup; - std::string m_installDir; - std::string m_packageDir; - std::string m_backupDir; - std::string m_finishCmd; - std::string m_finishDir; - PLATFORM_PID m_waitPid = 0; - UpdateScript* m_script = nullptr; - UpdateObserver* m_observer = nullptr; - std::map<std::string,std::string> m_backups; - bool m_forceElevated = false; - bool m_autoClose = false; - bool m_dryRun = false; -}; diff --git a/mmc_updater/src/UpdateMessage.h b/mmc_updater/src/UpdateMessage.h deleted file mode 100644 index fee51ab8..00000000 --- a/mmc_updater/src/UpdateMessage.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include <string> - -/** UpdateMessage stores information for a message - * about the status of update installation sent - * between threads. - */ -class UpdateMessage -{ - public: - enum Type - { - UpdateFailed, - UpdateProgress, - UpdateFinished - }; - - UpdateMessage(void* receiver, Type type) - { - init(receiver,type); - } - - UpdateMessage(Type type) - { - init(0,type); - } - - void* receiver; - Type type; - std::string message; - int progress; - - private: - void init(void* receiver, Type type) - { - this->progress = 0; - this->receiver = receiver; - this->type = type; - } -}; - diff --git a/mmc_updater/src/UpdateObserver.h b/mmc_updater/src/UpdateObserver.h deleted file mode 100644 index 84d47325..00000000 --- a/mmc_updater/src/UpdateObserver.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <string> - -/** Base class for observers of update installation status. - * See UpdateInstaller::setObserver() - */ -class UpdateObserver -{ - public: - virtual void updateError(const std::string& errorMessage) = 0; - virtual void updateProgress(int percentage) = 0; - virtual void updateFinished() = 0; -}; - diff --git a/mmc_updater/src/UpdateScript.cpp b/mmc_updater/src/UpdateScript.cpp deleted file mode 100644 index 849a2217..00000000 --- a/mmc_updater/src/UpdateScript.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include "UpdateScript.h" - -#include "Log.h" -#include "StringUtils.h" - -#include "tinyxml/tinyxml.h" - -std::string elementText(const TiXmlElement* element) -{ - if (!element) - { - return std::string(); - } - return element->GetText(); -} - -UpdateScript::UpdateScript() -{ -} - -void UpdateScript::parse(const std::string& path) -{ - m_path.clear(); - - TiXmlDocument document(path); - if (document.LoadFile()) - { - m_path = path; - - LOG(Info,"Loaded script from " + path); - - const TiXmlElement* updateNode = document.RootElement(); - parseUpdate(updateNode); - } - else - { - LOG(Error,"Unable to load script " + path); - } -} - -bool UpdateScript::isValid() const -{ - return !m_path.empty(); -} - -void UpdateScript::parseUpdate(const TiXmlElement* updateNode) -{ - const TiXmlElement* installNode = updateNode->FirstChildElement("install"); - if (installNode) - { - const TiXmlElement* installFileNode = installNode->FirstChildElement("file"); - while (installFileNode) - { - m_filesToInstall.push_back(parseFile(installFileNode)); - installFileNode = installFileNode->NextSiblingElement("file"); - } - } - - const TiXmlElement* uninstallNode = updateNode->FirstChildElement("uninstall"); - if (uninstallNode) - { - const TiXmlElement* uninstallFileNode = uninstallNode->FirstChildElement("file"); - while (uninstallFileNode) - { - m_filesToUninstall.push_back(uninstallFileNode->GetText()); - uninstallFileNode = uninstallFileNode->NextSiblingElement("file"); - } - } -} - -UpdateScriptFile UpdateScript::parseFile(const TiXmlElement* element) -{ - UpdateScriptFile file; - // The name within the update files folder. - file.source = elementText(element->FirstChildElement("source")); - // The path to install to. - file.dest = elementText(element->FirstChildElement("dest")); - - std::string modeString = elementText(element->FirstChildElement("mode")); - sscanf(modeString.c_str(),"%i",&file.permissions); - - return file; -} - -const std::vector<UpdateScriptFile>& UpdateScript::filesToInstall() const -{ - return m_filesToInstall; -} - -const std::vector<std::string>& UpdateScript::filesToUninstall() const -{ - return m_filesToUninstall; -} - -const std::string UpdateScript::path() const -{ - return m_path; -} - diff --git a/mmc_updater/src/UpdateScript.h b/mmc_updater/src/UpdateScript.h deleted file mode 100644 index f55c7236..00000000 --- a/mmc_updater/src/UpdateScript.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include <string> -#include <vector> - -class TiXmlElement; - -/** Represents a package containing one or more - * files for an update. - */ -class UpdateScriptPackage -{ - public: - UpdateScriptPackage() - : size(0) - {} - - std::string name; - std::string sha1; - std::string source; - int size; - - bool operator==(const UpdateScriptPackage& other) const - { - return name == other.name && - sha1 == other.sha1 && - source == other.source && - size == other.size; - } -}; - -/** Represents a file to be installed as part of an update. */ -class UpdateScriptFile -{ - public: - UpdateScriptFile() - : permissions(0) - {} - - /// Path to copy from. - std::string source; - /// The path to copy to. - std::string dest; - - /** The permissions for this file, specified - * using the standard Unix mode_t values. - */ - int permissions; - - bool operator==(const UpdateScriptFile& other) const - { - return source == other.source && - dest == other.dest && - permissions == other.permissions; - } -}; - -/** Stores information about the files included in an update, parsed from an XML file. */ -class UpdateScript -{ - public: - UpdateScript(); - - /** Initialize this UpdateScript with the script stored - * in the XML file at @p path. - */ - void parse(const std::string& path); - - bool isValid() const; - const std::string path() const; - const std::vector<UpdateScriptFile>& filesToInstall() const; - const std::vector<std::string>& filesToUninstall() const; - - private: - void parseUpdate(const TiXmlElement* element); - UpdateScriptFile parseFile(const TiXmlElement* element); - - std::string m_path; - std::vector<UpdateScriptFile> m_filesToInstall; - std::vector<std::string> m_filesToUninstall; -}; - diff --git a/mmc_updater/src/UpdaterOptions.cpp b/mmc_updater/src/UpdaterOptions.cpp deleted file mode 100644 index abc7c6d7..00000000 --- a/mmc_updater/src/UpdaterOptions.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include "UpdaterOptions.h" - -#include "Log.h" -#include "AnyOption/anyoption.h" -#include "FileUtils.h" -#include "Platform.h" -#include "StringUtils.h" - -#include <cstdlib> -#include <iostream> - -UpdaterOptions::UpdaterOptions() -: mode(UpdateInstaller::Setup) -, waitPid(0) -, showVersion(false) -, forceElevated(false) -, autoClose(false) -{ -} - -UpdateInstaller::Mode stringToMode(const std::string& modeStr) -{ - if (modeStr == "main") - { - return UpdateInstaller::Main; - } - else - { - if (!modeStr.empty()) - { - LOG(Error,"Unknown mode " + modeStr); - } - return UpdateInstaller::Setup; - } -} - -void UpdaterOptions::parse(int argc, char** argv) -{ - AnyOption parser; - parser.setOption("install-dir"); - parser.setOption("package-dir"); - parser.setOption("finish-cmd"); - parser.setOption("finish-dir"); - parser.setOption("script"); - parser.setOption("wait"); - parser.setOption("mode"); - parser.setFlag("version"); - parser.setFlag("force-elevated"); - parser.setFlag("dry-run"); - parser.setFlag("auto-close"); - - parser.processCommandArgs(argc,argv); - - if (parser.getValue("mode")) - { - mode = stringToMode(parser.getValue("mode")); - } - if (parser.getValue("install-dir")) - { - installDir = parser.getValue("install-dir"); - } - if (parser.getValue("package-dir")) - { - packageDir = parser.getValue("package-dir"); - } - if (parser.getValue("script")) - { - scriptPath = parser.getValue("script"); - } - if (parser.getValue("wait")) - { - waitPid = static_cast<PLATFORM_PID>(atoll(parser.getValue("wait"))); - } - if (parser.getValue("finish-cmd")) - { - finishCmd = parser.getValue("finish-cmd"); - } - if (parser.getValue("finish-dir")) - { - finishDir = parser.getValue("finish-dir"); - } - - showVersion = parser.getFlag("version"); - forceElevated = parser.getFlag("force-elevated"); - dryRun = parser.getFlag("dry-run"); - autoClose = parser.getFlag("auto-close"); -} diff --git a/mmc_updater/src/UpdaterOptions.h b/mmc_updater/src/UpdaterOptions.h deleted file mode 100644 index d4345490..00000000 --- a/mmc_updater/src/UpdaterOptions.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "UpdateInstaller.h" - -/** Parses the command-line options to the updater binary. */ -class UpdaterOptions -{ - public: - UpdaterOptions(); - - void parse(int argc, char** argv); - - UpdateInstaller::Mode mode; - std::string installDir; - std::string packageDir; - std::string scriptPath; - std::string finishCmd; - std::string finishDir; - PLATFORM_PID waitPid; - std::string logFile; - bool showVersion; - bool dryRun; - bool forceElevated; - bool autoClose; -}; - diff --git a/mmc_updater/src/main.cpp b/mmc_updater/src/main.cpp deleted file mode 100644 index 602c30a6..00000000 --- a/mmc_updater/src/main.cpp +++ /dev/null @@ -1,206 +0,0 @@ -#include "AppInfo.h" -#include "FileUtils.h" -#include "Log.h" -#include "Platform.h" -#include "ProcessUtils.h" -#include "StringUtils.h" -#include "UpdateScript.h" -#include "UpdaterOptions.h" - -#include <thread> - -#if defined(PLATFORM_LINUX) - #include "UpdateDialogGtkFactory.h" - #include "UpdateDialogAscii.h" -#endif - -#if defined(PLATFORM_MAC) - #include "MacBundle.h" - #include "UpdateDialogCocoa.h" -#endif - -#if defined(PLATFORM_WINDOWS) - #include "UpdateDialogWin32.h" -#endif - -#include <iostream> -#include <memory> - -#define UPDATER_VERSION "0.16" - -UpdateDialog* createUpdateDialog(); - -void runUpdaterThread(void* arg) -{ -#ifdef PLATFORM_MAC - // create an autorelease pool to free any temporary objects - // created by Cocoa whilst handling notifications from the UpdateInstaller - void* pool = UpdateDialogCocoa::createAutoreleasePool(); -#endif - - try - { - UpdateInstaller* installer = static_cast<UpdateInstaller*>(arg); - installer->run(); - } - catch (const std::exception& ex) - { - LOG(Error,"Unexpected exception " + std::string(ex.what())); - } - -#ifdef PLATFORM_MAC - UpdateDialogCocoa::releaseAutoreleasePool(pool); -#endif -} - -#ifdef PLATFORM_MAC -extern unsigned char Info_plist[]; -extern unsigned int Info_plist_len; - -extern unsigned char mac_icns[]; -extern unsigned int mac_icns_len; - -bool unpackBundle(int argc, char** argv) -{ - MacBundle bundle(FileUtils::tempPath(),AppInfo::name()); - std::string currentExePath = ProcessUtils::currentProcessPath(); - - if (currentExePath.find(bundle.bundlePath()) != std::string::npos) - { - // already running from a bundle - return false; - } - LOG(Info,"Creating bundle " + bundle.bundlePath()); - - // create a Mac app bundle - std::string plistContent(reinterpret_cast<const char*>(Info_plist),Info_plist_len); - std::string iconContent(reinterpret_cast<const char*>(mac_icns),mac_icns_len); - bundle.create(plistContent,iconContent,ProcessUtils::currentProcessPath()); - - std::list<std::string> args; - for (int i = 1; i < argc; i++) - { - args.push_back(argv[i]); - } - ProcessUtils::runSync(bundle.executablePath(),args); - return true; -} -#endif - -void setupConsole() -{ -#ifdef PLATFORM_WINDOWS - // see http://stackoverflow.com/questions/587767/how-to-output-to-console-in-c-windows - // and http://www.libsdl.org/cgi/docwiki.cgi/FAQ_Console - AttachConsole(ATTACH_PARENT_PROCESS); - freopen( "CON", "w", stdout ); - freopen( "CON", "w", stderr ); -#endif -} - -int main(int argc, char** argv) -{ -#ifdef PLATFORM_MAC - void* pool = UpdateDialogCocoa::createAutoreleasePool(); -#endif - - Log::instance()->open(AppInfo::logFilePath()); - -#ifdef PLATFORM_MAC - // when the updater is run for the first time, create a Mac app bundle - // and re-launch the application from the bundle. This permits - // setting up bundle properties (such as application icon) - if (unpackBundle(argc,argv)) - { - return 0; - } -#endif - - UpdaterOptions options; - options.parse(argc,argv); - if (options.showVersion) - { - setupConsole(); - std::cout << "Update installer version " << UPDATER_VERSION << std::endl; - return 0; - } - - UpdateInstaller installer; - UpdateScript script; - - if (!options.scriptPath.empty()) - { - script.parse(FileUtils::makeAbsolute(options.scriptPath.c_str(),options.packageDir.c_str())); - } - - LOG(Info,"started updater. install-dir: " + options.installDir - + ", package-dir: " + options.packageDir - + ", wait-pid: " + intToStr(options.waitPid) - + ", script-path: " + options.scriptPath - + ", mode: " + intToStr(options.mode) - + ", finish-cmd: " + options.finishCmd - + ", finish-dir: " + options.finishDir); - - installer.setMode(options.mode); - installer.setInstallDir(options.installDir); - installer.setPackageDir(options.packageDir); - installer.setScript(&script); - installer.setWaitPid(options.waitPid); - installer.setForceElevated(options.forceElevated); - installer.setAutoClose(options.autoClose); - installer.setFinishCmd(options.finishCmd); - installer.setFinishDir(options.finishDir); - installer.setDryRun(options.dryRun); - - if (options.mode == UpdateInstaller::Main) - { - LOG(Info, "Showing updater UI - auto close? " + intToStr(options.autoClose)); - std::auto_ptr<UpdateDialog> dialog(createUpdateDialog()); - dialog->setAutoClose(options.autoClose); - dialog->init(argc, argv); - installer.setObserver(dialog.get()); - std::thread updaterThread(runUpdaterThread, &installer); - dialog->exec(); - updaterThread.join(); - } - else - { - installer.run(); - } - -#ifdef PLATFORM_MAC - UpdateDialogCocoa::releaseAutoreleasePool(pool); -#endif - - return 0; -} - -UpdateDialog* createUpdateDialog() -{ -#if defined(PLATFORM_WINDOWS) - return new UpdateDialogWin32(); -#elif defined(PLATFORM_MAC) - return new UpdateDialogCocoa(); -#elif defined(PLATFORM_LINUX) - UpdateDialog* dialog = UpdateDialogGtkFactory::createDialog(); - if (!dialog) - { - dialog = new UpdateDialogAscii(); - } - return dialog; -#endif -} - -#ifdef PLATFORM_WINDOWS -// application entry point under Windows -int CALLBACK WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) -{ - int argc = 0; - char** argv; - ProcessUtils::convertWindowsCommandLine(GetCommandLineW(),argc,argv); - return main(argc,argv); -} -#endif diff --git a/mmc_updater/src/resources/Info.plist b/mmc_updater/src/resources/Info.plist deleted file mode 100644 index 93e97ccd..00000000 --- a/mmc_updater/src/resources/Info.plist +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <!-- Note - The name of the application specified here must match the value - returned by AppInfo::name() - !--> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>MultiMC Updater</string> - <key>CFBundleIconFile</key> - <string>MultiMC Updater.icns</string> - <key>CFBundleIdentifier</key> - <string>org.multimc.MultiMCUpdater</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1.0</string> - <key>NSMainNibFile</key> - <string>MainMenu</string> - <key>NSPrincipalClass</key> - <string>NSApplication</string> - <key>LSMinimumSystemVersion</key> - <string>10.5</string> - <key>LSMinimumSystemVersionByArchitecture</key> - <dict> - <key>i386</key> - <string>10.5.0</string> - <key>x86_64</key> - <string>10.5.0</string> - </dict> -</dict> -</plist> diff --git a/mmc_updater/src/resources/icon128.png b/mmc_updater/src/resources/icon128.png Binary files differdeleted file mode 100644 index 324452aa..00000000 --- a/mmc_updater/src/resources/icon128.png +++ /dev/null diff --git a/mmc_updater/src/resources/icon64.png b/mmc_updater/src/resources/icon64.png Binary files differdeleted file mode 100644 index 5e3373e2..00000000 --- a/mmc_updater/src/resources/icon64.png +++ /dev/null diff --git a/mmc_updater/src/resources/mac.icns b/mmc_updater/src/resources/mac.icns Binary files differdeleted file mode 100644 index 7c8fa2ef..00000000 --- a/mmc_updater/src/resources/mac.icns +++ /dev/null diff --git a/mmc_updater/src/resources/updater.ico b/mmc_updater/src/resources/updater.ico Binary files differdeleted file mode 100644 index b011bac9..00000000 --- a/mmc_updater/src/resources/updater.ico +++ /dev/null diff --git a/mmc_updater/src/resources/updater.manifest b/mmc_updater/src/resources/updater.manifest deleted file mode 100644 index cafc47d3..00000000 --- a/mmc_updater/src/resources/updater.manifest +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> - <assemblyIdentity name="MultiMC.Updater.1" type="win32" version="1.0.0.0" /> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> - <security> - <requestedPrivileges> - <requestedExecutionLevel level="asInvoker" uiAccess="false"/> - </requestedPrivileges> - </security> - </trustInfo> - <dependency> - <dependentAssembly> - <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"/> - </dependentAssembly> - </dependency> - <description>Software updater for MultiMC.</description> - <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> - <application> - <!--The ID below indicates app support for Windows Vista --> - <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> - <!--The ID below indicates app support for Windows 7 --> - <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> - <!--The ID below indicates app support for Windows Developer Preview / Windows 8 --> - <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> - </application> - </compatibility> -</assembly>
\ No newline at end of file diff --git a/mmc_updater/src/resources/updater.rc b/mmc_updater/src/resources/updater.rc deleted file mode 100644 index 9c7c5711..00000000 --- a/mmc_updater/src/resources/updater.rc +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> - -IDI_APPICON ICON DISCARDABLE "updater.ico" - -1 RT_MANIFEST "updater.manifest" - -VS_VERSION_INFO VERSIONINFO -FILEVERSION 1,0,0,0 -FILEOS VOS_NT_WINDOWS32 -FILETYPE VFT_APP -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "CompanyName", "MultiMC Contributors" - VALUE "FileDescription", "Software Update Tool" - VALUE "FileVersion", "1.0.0.0" - VALUE "ProductName", "MultiMC Software Updater" - VALUE "ProductVersion", "1.0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0000, 0x04b0 // Unicode - END -END
\ No newline at end of file diff --git a/mmc_updater/src/tests/CMakeLists.txt b/mmc_updater/src/tests/CMakeLists.txt deleted file mode 100644 index 5a96d7c9..00000000 --- a/mmc_updater/src/tests/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ - -include_directories("${CMAKE_CURRENT_SOURCE_DIR}/..") - -if(APPLE) - set(HELPER_SHARED_SOURCES ../StlSymbolsLeopard.cpp) -endif() - -# # Create helper binaries for unit tests -# add_executable(oldapp -# old_app.cpp -# ${HELPER_SHARED_SOURCES} -# ) -# add_executable(newapp -# new_app.cpp -# ${HELPER_SHARED_SOURCES} -# ) - -# Install data files required by unit tests -set(TEST_FILES - file_list.xml -) - -foreach(TEST_FILE ${TEST_FILES}) - execute_process( - COMMAND - "${CMAKE_COMMAND}" -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/${TEST_FILE}" "${CMAKE_CURRENT_BINARY_DIR}" - ) -endforeach() - -# Add unit test binaries -macro(ADD_UPDATER_TEST CLASS) - set(TEST_TARGET updater_${CLASS}) - unset(srcs) - list(APPEND srcs ${CLASS}.cpp) - if(WIN32) - list(APPEND srcs ${CMAKE_CURRENT_SOURCE_DIR}/test.rc) - endif() - add_executable(${TEST_TARGET} ${srcs}) - target_link_libraries(${TEST_TARGET} updatershared) - add_test(NAME ${TEST_TARGET} COMMAND ${TEST_TARGET}) - if(APPLE) - set_target_properties(${TEST_TARGET} PROPERTIES LINK_FLAGS "-framework Security -framework Cocoa") - endif() -endmacro() - -add_updater_test(TestParseScript) -add_updater_test(TestFileUtils) diff --git a/mmc_updater/src/tests/TestFileUtils.cpp b/mmc_updater/src/tests/TestFileUtils.cpp deleted file mode 100644 index f8535a28..00000000 --- a/mmc_updater/src/tests/TestFileUtils.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "TestFileUtils.h" - -#include "FileUtils.h" -#include "TestUtils.h" - -void TestFileUtils::testDirName() -{ - std::string dirName; - std::string fileName; - -#ifdef PLATFORM_WINDOWS - // absolute paths - dirName = FileUtils::dirname("E:/Some Dir/App.exe"); - TEST_COMPARE(dirName,"E:/Some Dir"); - fileName = FileUtils::fileName("E:/Some Dir/App.exe"); - TEST_COMPARE(fileName,"App.exe"); - - dirName = FileUtils::dirname("C:/Users/kitteh/AppData/Local/Temp/MultiMC5-yidaaa/MultiMC.exe"); - TEST_COMPARE(dirName,"C:/Users/kitteh/AppData/Local/Temp/MultiMC5-yidaaa"); - fileName = FileUtils::fileName("C:/Users/kitteh/AppData/Local/Temp/MultiMC5-yidaaa/MultiMC.exe"); - TEST_COMPARE(fileName,"MultiMC.exe"); - -#else - // absolute paths - dirName = FileUtils::dirname("/home/tester/foo bar/baz"); - TEST_COMPARE(dirName,"/home/tester/foo bar"); - fileName = FileUtils::fileName("/home/tester/foo bar/baz"); - TEST_COMPARE(fileName,"baz"); -#endif - // current directory - dirName = FileUtils::dirname("App.exe"); - TEST_COMPARE(dirName,"."); - fileName = FileUtils::fileName("App.exe"); - TEST_COMPARE(fileName,"App.exe"); - - // relative paths - dirName = FileUtils::dirname("Foo/App.exe"); - TEST_COMPARE(dirName,"Foo"); - fileName = FileUtils::fileName("Foo/App.exe"); - TEST_COMPARE(fileName,"App.exe"); -} - -void TestFileUtils::testIsRelative() -{ -#ifdef PLATFORM_WINDOWS - TEST_COMPARE(FileUtils::isRelative("temp"),true); - TEST_COMPARE(FileUtils::isRelative("D:/temp"),false); - TEST_COMPARE(FileUtils::isRelative("d:/temp"),false); -#else - TEST_COMPARE(FileUtils::isRelative("/tmp"),false); - TEST_COMPARE(FileUtils::isRelative("tmp"),true); -#endif -} - -void TestFileUtils::testSymlinkFileExists() -{ -#ifdef PLATFORM_UNIX - const char* linkName = "link-name"; - FileUtils::removeFile(linkName); - FileUtils::createSymLink(linkName, "target-that-does-not-exist"); - TEST_COMPARE(FileUtils::fileExists(linkName), true); -#endif -} - -void TestFileUtils::testStandardDirs() -{ - std::string tmpDir = FileUtils::tempPath(); - TEST_COMPARE(FileUtils::fileExists(tmpDir.data()), true); -} - -int main(int,char**) -{ - TestList<TestFileUtils> tests; - tests.addTest(&TestFileUtils::testDirName); - tests.addTest(&TestFileUtils::testIsRelative); - tests.addTest(&TestFileUtils::testSymlinkFileExists); - tests.addTest(&TestFileUtils::testStandardDirs); - return TestUtils::runTest(tests); -} diff --git a/mmc_updater/src/tests/TestFileUtils.h b/mmc_updater/src/tests/TestFileUtils.h deleted file mode 100644 index 1a45164b..00000000 --- a/mmc_updater/src/tests/TestFileUtils.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -class TestFileUtils -{ - public: - void testDirName(); - void testIsRelative(); - void testSymlinkFileExists(); - void testStandardDirs(); -}; diff --git a/mmc_updater/src/tests/TestParseScript.cpp b/mmc_updater/src/tests/TestParseScript.cpp deleted file mode 100644 index f4453957..00000000 --- a/mmc_updater/src/tests/TestParseScript.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "TestParseScript.h" - -#include "TestUtils.h" -#include "UpdateScript.h" - -#include <iostream> -#include <algorithm> - -void TestParseScript::testParse() -{ - UpdateScript script; - - script.parse("file_list.xml"); - - TEST_COMPARE(script.isValid(),true); -} - -int main(int,char**) -{ - TestList<TestParseScript> tests; - tests.addTest(&TestParseScript::testParse); - return TestUtils::runTest(tests); -} - diff --git a/mmc_updater/src/tests/TestParseScript.h b/mmc_updater/src/tests/TestParseScript.h deleted file mode 100644 index 528e97a8..00000000 --- a/mmc_updater/src/tests/TestParseScript.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -class TestParseScript -{ - public: - void testParse(); -}; - diff --git a/mmc_updater/src/tests/TestUtils.h b/mmc_updater/src/tests/TestUtils.h deleted file mode 100644 index 68d97da5..00000000 --- a/mmc_updater/src/tests/TestUtils.h +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once - -#include <iostream> -#include <functional> -#include <string> -#include <vector> - -template <class T> -class TestList -{ - public: - void addTest(void (T::*test)()) - { - m_tests.push_back(std::mem_fun(test)); - } - - int size() const - { - return m_tests.size(); - } - - void runTest(T* testInstance, int i) - { - m_tests.at(i)(testInstance); - } - - private: - std::vector<std::mem_fun_t<void,T> > m_tests; -}; - -class TestUtils -{ - public: - template <class X, class Y> - static void compare(const X& x, const Y& y, const char* xString, const char* yString) - { - if (x != y) - { - throw "Actual and expected values differ. " - "Actual: " + toString(x,xString) + - " Expected: " + toString(y,yString); - } - } - - template <typename T> - static std::string toString(T value, const char* context) - { - return "Unprintable: " + std::string(context); - } - - template <class T> - static int runTest(class TestList<T>& tests) throw () - { - std::string errorText; - try - { - T testInstance; - for (int i=0; i < tests.size(); i++) - { - tests.runTest(&testInstance,i); - } - } - catch (const std::exception& ex) - { - errorText = ex.what(); - } - catch (const std::string& error) - { - errorText = error; - } - catch (...) - { - errorText = "Unknown exception"; - } - - if (errorText.empty()) - { - std::cout << "Test passed" << std::endl; - return 0; - } - else - { - std::cout << "Test failed: " << errorText << std::endl; - return 1; - } - } -}; - -template <> -inline std::string TestUtils::toString(const std::string& value, const char*) -{ - return value; -} -template <> -inline std::string TestUtils::toString(std::string value, const char*) -{ - return value; -} -template <> -inline std::string TestUtils::toString(const char* value, const char*) -{ - return value; -} - -#define TEST_COMPARE(x,y) \ - TestUtils::compare(x,y,#x,#y); - - diff --git a/mmc_updater/src/tests/file_list.xml b/mmc_updater/src/tests/file_list.xml deleted file mode 100644 index 06ba501d..00000000 --- a/mmc_updater/src/tests/file_list.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0"?> -<update version="3"> - <install> - <file> - <name>$APP_FILENAME</name> - <hash>$UPDATED_APP_HASH</hash> - <size>$UPDATED_APP_SIZE</size> - <permissions>0755</permissions> - <package>app-pkg</package> - <is-main-binary>true</is-main-binary> - </file> - <file> - <name>$UPDATER_FILENAME</name> - <hash>$UPDATER_HASH</hash> - <size>$UPDATER_SIZE</size> - <permissions>0755</permissions> - </file> - <!-- Test symlink !--> - <file> - <name>test-dir/app-symlink</name> - <target>../app</target> - </file> - <!-- Test file in new directory !--> - <file> - <name>new-dir/new-dir2/new-file.txt</name> - <hash>$TEST_FILENAME</hash> - <size>$TEST_SIZE</size> - <package>app-pkg</package> - <permissions>0644</permissions> - </file> - </install> - <uninstall> - <!-- TODO - List some files to uninstall here !--> - <file>file-to-uninstall.txt</file> - <file>symlink-to-file-to-uninstall.txt</file> - </uninstall> -</update> diff --git a/mmc_updater/src/tests/new_app.cpp b/mmc_updater/src/tests/new_app.cpp deleted file mode 100644 index 7fad1380..00000000 --- a/mmc_updater/src/tests/new_app.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include <iostream> - -int main(int,char**) -{ - std::cout << "new app starting" << std::endl; - return 0; -} - diff --git a/mmc_updater/src/tests/old_app.cpp b/mmc_updater/src/tests/old_app.cpp deleted file mode 100644 index 476a3405..00000000 --- a/mmc_updater/src/tests/old_app.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include <iostream> - -int main(int,char**) -{ - std::cout << "old app starting" << std::endl; - return 0; -} diff --git a/mmc_updater/src/tests/test.manifest b/mmc_updater/src/tests/test.manifest deleted file mode 100644 index 8b4dbb98..00000000 --- a/mmc_updater/src/tests/test.manifest +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> - <assemblyIdentity name="MultiMC.Test.0" type="win32" version="5.0.0.0" /> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> - <security> - <requestedPrivileges> - <requestedExecutionLevel level="asInvoker" uiAccess="false"/> - </requestedPrivileges> - </security> - </trustInfo> - <dependency> - <dependentAssembly> - <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"/> - </dependentAssembly> - </dependency> - <description>Custom Minecraft launcher for managing multiple installs.</description> - <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> - <application> - <!--The ID below indicates app support for Windows Vista --> - <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> - <!--The ID below indicates app support for Windows 7 --> - <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> - <!--The ID below indicates app support for Windows Developer Preview / Windows 8 --> - <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> - </application> - </compatibility> -</assembly>
\ No newline at end of file diff --git a/mmc_updater/src/tests/test.rc b/mmc_updater/src/tests/test.rc deleted file mode 100644 index a288dba6..00000000 --- a/mmc_updater/src/tests/test.rc +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> - -1 RT_MANIFEST "test.manifest" - -VS_VERSION_INFO VERSIONINFO -FILEVERSION 1,0,0,0 -FILEOS VOS_NT_WINDOWS32 -FILETYPE VFT_APP -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "CompanyName", "MultiMC Contributors" - VALUE "FileDescription", "Testcase" - VALUE "FileVersion", "1.0.0.0" - VALUE "ProductName", "MultiMC Testcase" - VALUE "ProductVersion", "5" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0000, 0x04b0 // Unicode - END -END |