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:
Robert Knight 2011-08-22 00:30:40 +01:00
parent 012813fa13
commit 9a0bee0358
5 changed files with 80 additions and 4 deletions

1
TODO
View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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);
};