diff --git a/TODO b/TODO index b0c04a7..28ef858 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,6 @@ Updater Tasks: * Basic functionality for Windows * Basic functionality for Mac - * Elevation for Linux * Elevation for Windows * Elevation for Mac * Win32 UI for Windows diff --git a/src/FileOps.cpp b/src/FileOps.cpp index b829c9f..8743675 100644 --- a/src/FileOps.cpp +++ b/src/FileOps.cpp @@ -179,6 +179,18 @@ void FileOps::removeFile(const char* src) throw (IOException) #endif } +std::string FileOps::fileName(const char* path) +{ +#ifdef PLATFORM_UNIX + char* pathCopy = strdup(path); + std::string basename = ::basename(pathCopy); + free(pathCopy); + return basename; +#else + throw IOException("not implemented"); +#endif +} + std::string FileOps::dirname(const char* path) { #ifdef PLATFORM_UNIX diff --git a/src/FileOps.h b/src/FileOps.h index 907c650..cbc8fdc 100644 --- a/src/FileOps.h +++ b/src/FileOps.h @@ -34,6 +34,7 @@ class FileOps 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 std::string fileName(const char* path); static std::string dirname(const char* path); static void rmdirRecursive(const char* dir) throw (IOException); static std::string canonicalPath(const char* path); diff --git a/src/ProcessUtils.cpp b/src/ProcessUtils.cpp index fb1b424..824378a 100644 --- a/src/ProcessUtils.cpp +++ b/src/ProcessUtils.cpp @@ -17,6 +17,27 @@ #include #endif +int ProcessUtils::runSync(const std::string& executable, + const std::list& args) +{ +#ifdef PLATFORM_UNIX + return runSyncUnix(executable,args); +#else + return runSyncWindows(executable,args); +#endif +} + +#ifdef PLATFORM_UNIX +int ProcessUtils::runSyncUnix(const std::string& executable, + const std::list& args) +{ + int pid = runAsyncUnix(executable,args); + int status = 0; + waitpid(pid,&status,0); + return status; +} +#endif + void ProcessUtils::runAsync(const std::string& executable, const std::list& args) { @@ -73,6 +94,44 @@ bool ProcessUtils::waitForProcess(long long pid) void ProcessUtils::runElevatedLinux(const std::string& executable, const std::list& args) { + std::string sudoMessage = FileOps::fileName(executable.c_str()) + " needs administrative privileges. Please enter your password."; + + std::vector sudos; + sudos.push_back("kdesudo"); + sudos.push_back("gksudo"); + sudos.push_back("gksu"); + + for (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"); + sudoArgs.push_back(sudoMessage); + } + else + { + sudoArgs.push_back(sudoMessage); + } + + sudoArgs.push_back("--"); + sudoArgs.push_back(executable); + std::copy(args.begin(),args.end(),std::back_inserter(sudoArgs)); + + // != 255: some sudo has been found and user failed to authenticate + // or user authenticated correctly + int result = ProcessUtils::runSync(sudoBinary,sudoArgs); + if (result != 255) + { + break; + } + } } #endif @@ -186,7 +245,7 @@ void ProcessUtils::runElevatedWindows(const std::string& executable, #endif #ifdef PLATFORM_UNIX -void ProcessUtils::runAsyncUnix(const std::string& executable, +int ProcessUtils::runAsyncUnix(const std::string& executable, const std::list& args) { pid_t child = fork(); @@ -203,7 +262,7 @@ void ProcessUtils::runAsyncUnix(const std::string& executable, } argBuffer[i] = 0; - if (execve(executable.c_str(),argBuffer,environ) == -1) + if (execvp(executable.c_str(),argBuffer) == -1) { LOG(Error,"error starting child: " + std::string(strerror(errno))); exit(1); diff --git a/src/ProcessUtils.h b/src/ProcessUtils.h index 9d3134e..6f88249 100644 --- a/src/ProcessUtils.h +++ b/src/ProcessUtils.h @@ -8,6 +8,9 @@ class ProcessUtils public: static std::string currentProcessPath(); + static int runSync(const std::string& executable, + const std::list& args); + static void runAsync(const std::string& executable, const std::list& args); @@ -24,9 +27,11 @@ class ProcessUtils static void runElevatedWindows(const std::string& executable, const std::list& args); - static void runAsyncUnix(const std::string& executable, + static int runAsyncUnix(const std::string& executable, const std::list& args); static void runAsyncWindows(const std::string& executable, const std::list& args); + static int runSyncUnix(const std::string& executable, + const std::list& args); };