mirror of
https://github.com/etlegacy/Update-Installer.git
synced 2025-01-22 15:31:08 +00:00
Implement elevation under Linux using one of kdesudo, gksudo or gksu
* Add FileOps::fileName() to get the base name for a file * Add ProcessUtils::runSync() to run a process, wait for it to exit and then return the status code from that process. * Change ProcessUtils::runAsyncUnix() to use execvp() in order to search PATH for the specified binary if the filename is not absolute.
This commit is contained in:
parent
012813fa13
commit
9a0bee0358
5 changed files with 80 additions and 4 deletions
1
TODO
1
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -17,6 +17,27 @@
|
|||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
int ProcessUtils::runSync(const std::string& executable,
|
||||
const std::list<std::string>& 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<std::string>& 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<std::string>& args)
|
||||
{
|
||||
|
@ -73,6 +94,44 @@ bool ProcessUtils::waitForProcess(long long pid)
|
|||
void ProcessUtils::runElevatedLinux(const std::string& executable,
|
||||
const std::list<std::string>& args)
|
||||
{
|
||||
std::string sudoMessage = FileOps::fileName(executable.c_str()) + " needs administrative privileges. Please enter your password.";
|
||||
|
||||
std::vector<std::string> 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<std::string> 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<std::string>& 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);
|
||||
|
|
|
@ -8,6 +8,9 @@ class ProcessUtils
|
|||
public:
|
||||
static std::string currentProcessPath();
|
||||
|
||||
static int runSync(const std::string& executable,
|
||||
const std::list<std::string>& args);
|
||||
|
||||
static void runAsync(const std::string& executable,
|
||||
const std::list<std::string>& args);
|
||||
|
||||
|
@ -24,9 +27,11 @@ class ProcessUtils
|
|||
static void runElevatedWindows(const std::string& executable,
|
||||
const std::list<std::string>& args);
|
||||
|
||||
static void runAsyncUnix(const std::string& executable,
|
||||
static int runAsyncUnix(const std::string& executable,
|
||||
const std::list<std::string>& args);
|
||||
static void runAsyncWindows(const std::string& executable,
|
||||
const std::list<std::string>& args);
|
||||
static int runSyncUnix(const std::string& executable,
|
||||
const std::list<std::string>& args);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue