From 6d7bff2476459049f4f554291a680e0f6003ea66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 7 Jun 2015 21:10:18 +0200 Subject: GH-1060 remove updater code --- mmc_updater/src/ProcessUtils.cpp | 536 --------------------------------------- 1 file changed, 536 deletions(-) delete mode 100644 mmc_updater/src/ProcessUtils.cpp (limited to 'mmc_updater/src/ProcessUtils.cpp') 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 -#include -#include - -#ifdef PLATFORM_WINDOWS -#include -#else -#include -#include -#include -#include -#endif - -#ifdef PLATFORM_MAC -#include -#include -#endif - -PLATFORM_PID ProcessUtils::currentProcessId() -{ -#ifdef PLATFORM_UNIX - return getpid(); -#else - return GetCurrentProcessId(); -#endif -} - -int ProcessUtils::runSync(const std::string& executable, - const std::list& 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& args) -{ - PLATFORM_PID pid = runAsyncUnix(executable,args); - int status = 0; - if (waitpid(pid,&status,0) != -1) - { - if (WIFEXITED(status)) - { - return static_cast(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& 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& 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& 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 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 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& 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::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& arguments) -{ - std::string quotedArgs; - for (std::list::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& 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& 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::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& _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 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 - -- cgit v1.2.3