Skip to content

Commit

Permalink
Add workarounds for Flatpak
Browse files Browse the repository at this point in the history
Related to #83 and #295
  • Loading branch information
TheTumultuousUnicornOfDarkness committed Oct 15, 2023
1 parent b71c171 commit 741ec48
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 24 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ option(WITH_LIBSTATGRAB "Use Libstatgrab library"
option(WITH_DMIDECODE "Built-in Dmidecode" ON)
option(WITH_BANDWIDTH "Built-in Bandwidth" ON)
option(FORCE_LIBSTATGRAB "Force use of Libstatgrab instead of Libprocps (GNU/Linux system)" OFF)
option(FLATPAK "Enable workarounds for Flatpak" OFF)

# Colours
string(ASCII 27 Esc)
Expand Down
10 changes: 10 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,16 @@ if(${LIBSYSTEM} EQUAL 0 OR ${LIBSYSTEM} EQUAL 2) # When Libstatgrab is used
add_definitions(-DHAS_LIBPROCPS=0 -DLIBPROCPS_VERSION=NULL)
endif()

# Flatpak workarounds
if(FLATPAK)
add_definitions(-DFLATPAK)
set(DAEMON_SOCKET cpu-x.sock)
if(LIBCPUID_FOUND)
# flatpak-spawn command will not be able to find libcpuid.so when starting cpu-x-daemon
set(LIBCPUID_LIBRARIES "-l:libcpuid.a")
endif(LIBCPUID_FOUND)
endif(FLATPAK)

# Various definitions
add_definitions(-DPRGVER="${PROJECT_VERSION}"
-DGITREV="${GIT_REVISION}"
Expand Down
96 changes: 82 additions & 14 deletions src/daemon_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <cstdlib>
#include <cassert>
#include <filesystem>
#include <fstream>
#include <regex>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/un.h>
Expand All @@ -35,23 +37,60 @@
namespace fs = std::filesystem;


static char *get_daemon_socket()
{
static char *socket = NULL;

if(socket == NULL)
{
#ifdef FLATPAK
asprintf(&socket, "%s/app/%s/%s", std::getenv("XDG_RUNTIME_DIR"), std::getenv("FLATPAK_ID"), SOCKET_NAME);
#else
asprintf(&socket, "%s", SOCKET_NAME);
#endif /* FLATPAK */
}
MSG_DEBUG("get_daemon_socket: socket_path=%s", socket);

return socket;
}

/* Start daemon in background */
const char *start_daemon(bool graphical)
{
int wstatus = -1;
pid_t pid;
char const *msg = NULL;
char const *appdir = std::getenv("APPDIR");
char const *daemon = (appdir == NULL) ? DAEMON_PATH : DAEMON_TMP_EXEC;
char const *msg = NULL;
char const *daemon_args = get_daemon_socket();

MSG_VERBOSE("%s", _("Starting daemon in background…"));
#ifdef FLATPAK
std::string line, app_path;
std::ifstream stream("/.flatpak-info");
std::regex regex("^app-path=(.*?)$");
std::smatch match;

while(std::getline(stream, line))
{
if(std::regex_search(line, match, regex))
{
app_path = match[1].str() + "/lib/" + PRGNAME_LOW + "/" + DAEMON_EXEC;
break;
}
}

char const *daemon_exec = app_path.c_str();
#else
char const *appdir = std::getenv("APPDIR");
char const *daemon_exec = (appdir == NULL) ? DAEMON_PATH : DAEMON_TMP_EXEC;

/* Hack to allow pkexec to run daemon (when running from AppImage) */
if(appdir != NULL)
{
const std::string appdir_daemon_path = std::string(appdir) + std::string(DAEMON_PATH);
MSG_DEBUG("start_daemon: copy '%s' to '%s'", appdir_daemon_path.c_str(), daemon);
fs::copy(appdir_daemon_path, daemon, fs::copy_options::overwrite_existing);
MSG_DEBUG("start_daemon: copy '%s' to '%s'", appdir_daemon_path.c_str(), daemon_exec);
fs::copy(appdir_daemon_path, daemon_exec, fs::copy_options::overwrite_existing);
}
#endif /* FLATPAK */

pid = fork();
if(pid < 0)
Expand All @@ -60,18 +99,48 @@ const char *start_daemon(bool graphical)
{
if(graphical)
{
const char* const args[] = { "pkexec", "--disable-internal-agent", daemon, nullptr };
execvp_cpp("pkexec", args);
const char* const args[] =
{
#ifdef FLATPAK
"flatpak-spawn",
"--host",
#endif /* FLATPAK */
"pkexec",
"--disable-internal-agent",
daemon_exec,
daemon_args,
nullptr
};
execvp_cpp(args[0], args);
}
else if(IS_ROOT)
{
const char* const args[] = { daemon, nullptr };
execvp_cpp(daemon, args);
const char* const args[] =
{
#ifdef FLATPAK
"flatpak-spawn",
"--host",
#endif /* FLATPAK */
daemon_exec,
daemon_args,
nullptr
};
execvp_cpp(args[0], args);
}
else
{
const char* const args[] = { "pkexec", daemon, nullptr };
execvp_cpp("pkexec", args);
const char* const args[] =
{
#ifdef FLATPAK
"flatpak-spawn",
"--host",
#endif /* FLATPAK */
"pkexec",
daemon_exec,
daemon_args,
nullptr
};
execvp_cpp(args[0], args);
}
}
else
Expand Down Expand Up @@ -105,7 +174,7 @@ const char *start_daemon(bool graphical)
/* Check if daemon is running */
bool daemon_is_alive()
{
const fs::file_status status = fs::status(SOCKET_NAME);
const fs::file_status status = fs::status(get_daemon_socket());
const fs::perms perms = status.permissions();
const bool is_socket = fs::is_socket(status);
const bool perms_all = (perms == fs::perms::all);
Expand All @@ -130,8 +199,7 @@ int connect_to_daemon(int &socket_fd)
/* Connect socket to socket address */
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
MSG_DEBUG("connect_to_daemon: socket_path=%s", SOCKET_NAME);
strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1);
strncpy(addr.sun_path, get_daemon_socket(), sizeof(addr.sun_path) - 1);
if(connect(socket_fd, (const struct sockaddr*) &addr, sizeof(struct sockaddr_un)) < 0)
GOTO_ERROR("connect");

Expand Down
14 changes: 10 additions & 4 deletions src/daemon_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ static void sighandler([[maybe_unused]] int __signum)
quit_loop = true;
}

int main([[maybe_unused]] int argc, char *argv[])
int main(int argc, char *argv[])
{
bool background = true;
int listen_socket, data_socket, ret, err = EXIT_SUCCESS;
Expand All @@ -279,6 +279,12 @@ int main([[maybe_unused]] int argc, char *argv[])
struct sockaddr_un name;
struct pollfd fds[NFDS];

if(argc < 2)
{
MSG_ERROR("%s requires socket path as argument.", argv[0]);
return 1;
}

if(!IS_ROOT)
{
MSG_ERROR("%s cannot be executed as regular user.", argv[0]);
Expand All @@ -294,7 +300,7 @@ int main([[maybe_unused]] int argc, char *argv[])

/* Pre-initialization */
umask(0);
fs::remove(SOCKET_NAME);
fs::remove(argv[1]);
std::signal(SIGINT, sighandler);
std::signal(SIGTERM, sighandler);

Expand All @@ -314,7 +320,7 @@ int main([[maybe_unused]] int argc, char *argv[])
/* Bind socket to socket name. */
memset(&name, 0, sizeof(struct sockaddr_un));
name.sun_family = AF_UNIX;
std::strncpy(name.sun_path, SOCKET_NAME, sizeof(name.sun_path) - 1);
std::strncpy(name.sun_path, argv[1], sizeof(name.sun_path) - 1);
if(bind(listen_socket, (const struct sockaddr*) &name, sizeof(struct sockaddr_un)) < 0)
GOTO_ERROR("bind");

Expand Down Expand Up @@ -370,7 +376,7 @@ int main([[maybe_unused]] int argc, char *argv[])

clean:
std::fclose(stdout);
fs::remove(SOCKET_NAME);
fs::remove(argv[1]);
close(listen_socket);

if(std::getenv("APPDIR") != NULL)
Expand Down
4 changes: 3 additions & 1 deletion src/gui_gtk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ void GtkData::set_all_labels()
const auto margin = 6;
const auto width_full = EXT_LABEL(this->data.system.os.hostname)->value->get_allocated_width();
const auto width_half = width_full - EXT_LABEL(this->data.system.memory.used)->value->get_allocated_width() - margin;
const int pkcheck = run_command("pkcheck --action-id org.freedesktop.policykit.exec --process %u > /dev/null 2>&1", getpid());
const int pkcheck = run_command("pkcheck --action-id org.freedesktop.policykit.exec --process %u > /dev/null 2>&1", getpid()); // getpid() returns 2 on Flatpak

/* Common */
notebook->set_current_page(Options::get_selected_page());
Expand All @@ -401,8 +401,10 @@ void GtkData::set_all_labels()
this->daemonbutton->set_sensitive(false);
if(DAEMON_UP)
this->daemonbutton->set_tooltip_text(_("Connected to daemon"));
#ifndef FLATPAK
else if(WEXITSTATUS(pkcheck) > 2)
this->daemonbutton->set_tooltip_text(_("No polkit authentication agent found"));
#endif /* !FLATPAK */
else
{
this->daemonbutton->set_sensitive(true);
Expand Down
27 changes: 22 additions & 5 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,23 +256,32 @@ std::string fopen_to_str(const char *str, Args... args)
/* Run a command and put output in a variable ('str' accept printf-like format) */
int popen_to_str(std::string &out, const char *str, ...)
{
char *cmd_str = NULL;
char *cmd_tmp = NULL, *cmd_str = NULL;
char buffer[MAXSTR];
FILE *pipe_descr = NULL;
va_list aptr;

out.clear();
va_start(aptr, str);
vasprintf(&cmd_str, str, aptr);
vasprintf(&cmd_tmp, str, aptr);
va_end(aptr);

#ifdef FLATPAK
asprintf(&cmd_str, "flatpak-spawn --host %s", cmd_tmp);
free(cmd_tmp);
#else
cmd_str = cmd_tmp;
#endif /* FLATPAK */

MSG_DEBUG("popen_to_str: running '%s'", cmd_str);
pipe_descr = popen(cmd_str, "r");
free(cmd_str);
if(pipe_descr == NULL)
{
MSG_ERROR(_("an error occurred while running command '%s'"), cmd_str);
free(cmd_str);
return 1;
}
free(cmd_str);

while(fgets(buffer, MAXSTR, pipe_descr) != NULL)
{
Expand All @@ -287,13 +296,21 @@ int popen_to_str(std::string &out, const char *str, ...)
int run_command(const char *str, ...)
{
int ret;
char *cmd_str = NULL;
char *cmd_tmp = NULL, *cmd_str = NULL;
va_list aptr;

va_start(aptr, str);
vasprintf(&cmd_str, str, aptr);
vasprintf(&cmd_tmp, str, aptr);
va_end(aptr);

#ifdef FLATPAK
asprintf(&cmd_str, "flatpak-spawn --host %s", cmd_tmp);
free(cmd_tmp);
#else
cmd_str = cmd_tmp;
#endif /* FLATPAK */

MSG_DEBUG("run_command: running '%s'", cmd_str);
ret = std::system(cmd_str);
free(cmd_str);

Expand Down

0 comments on commit 741ec48

Please sign in to comment.