Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/AppConsole.vala
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public class AppConsole : GLib.Object {
return 0;
}

Main.copy_env();

LOG_ENABLE = false;
init_tmp();
LOG_ENABLE = true;
Expand Down
2 changes: 2 additions & 0 deletions src/AppGtk.vala
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public class AppGtk : GLib.Object {
}
}

Main.copy_env();

Gtk.init(ref args);

GTK_INITIALIZED = true;
Expand Down
18 changes: 18 additions & 0 deletions src/Core/Main.vala
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,24 @@ public class Main : GLib.Object{
}
}

// copy env from the spawning parent to this
public static void copy_env() {
Pid user_pid = TeeJee.ProcessHelper.get_user_process();
string[]? user_env = TeeJee.ProcessHelper.get_process_env(user_pid);
if(user_env == null) {
return;
}

// copy all required enviroment vars from the user to this process
string[] targets = {"DISPLAY", "XAUTHORITY", "DBUS_SESSION_BUS_ADDRESS"};
foreach (string target in targets) {
string user_var = TeeJee.ProcessHelper.get_env(user_env, target);
if(user_var != null) {
GLib.Environment.set_variable(target, user_var, true);
}
}
}

private int[]? get_btrfs_version_array () {
string stdout;
string stderr;
Expand Down
31 changes: 31 additions & 0 deletions src/Utility/TeeJee.FileSystem.vala
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@

public bool file_exists (string file_path){
/* Check if file exists */
return (FileUtils.test(file_path, GLib.FileTest.EXISTS)

Check failure on line 70 in src/Utility/TeeJee.FileSystem.vala

View workflow job for this annotation

GitHub Actions / build / build (mint22, linuxmintd/mint22-amd64, Mint 22, true) / Mint 22

FileTest ==> file test
&& !FileUtils.test(file_path, GLib.FileTest.IS_DIR));

Check failure on line 71 in src/Utility/TeeJee.FileSystem.vala

View workflow job for this annotation

GitHub Actions / build / build (mint22, linuxmintd/mint22-amd64, Mint 22, true) / Mint 22

FileTest ==> file test
}

public bool file_delete(string file_path){
Expand Down Expand Up @@ -131,6 +131,37 @@
return null;
}

// read a file with a delimiter into an array
// this function is not very optimized so avoid using it for large files
public string[]? file_read_array(string file_path, char delimiter = '\n'){
try{
uint8[] content;
GLib.FileUtils.get_data(file_path, out content);

// count elements
string[] parsed = {""};
int element = 0;
foreach (uint8 byte in content) {
// create a new element
if(byte == delimiter) {
element ++;
parsed += "";
continue;
}

parsed[element] += ((char) byte).to_string();
}

return parsed;
}
catch (Error e){
log_error (e.message);
log_error(_("Failed to read file") + ": %s".printf(file_path));
}

return null;
}

public bool file_write (string file_path, string contents){

/* Write text to file */
Expand Down Expand Up @@ -265,7 +296,7 @@

public bool dir_exists (string dir_path){
/* Check if directory exists */
return ( FileUtils.test(dir_path, GLib.FileTest.EXISTS) && FileUtils.test(dir_path, GLib.FileTest.IS_DIR));

Check failure on line 299 in src/Utility/TeeJee.FileSystem.vala

View workflow job for this annotation

GitHub Actions / build / build (mint22, linuxmintd/mint22-amd64, Mint 22, true) / Mint 22

FileTest ==> file test

Check failure on line 299 in src/Utility/TeeJee.FileSystem.vala

View workflow job for this annotation

GitHub Actions / build / build (mint22, linuxmintd/mint22-amd64, Mint 22, true) / Mint 22

FileTest ==> file test
}

public bool dir_create (string dir_path, bool show_message = false){
Expand Down
65 changes: 65 additions & 0 deletions src/Utility/TeeJee.Process.vala
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,71 @@
return GLib.Path.get_basename(link);
}

// get the parent pid of process or self
public Pid get_process_parent(Pid process = -1) {
string pidStr = (process <= 0 ? "self" : process.to_string());
string path = "/proc/%s/stat".printf(pidStr);
string stats = file_read(path);
string details = stats.split(")", 2)[1];
string[] splitted = details.split(" ", 3);

Check failure on line 311 in src/Utility/TeeJee.Process.vala

View workflow job for this annotation

GitHub Actions / build / build (mint22, linuxmintd/mint22-amd64, Mint 22, true) / Mint 22

splitted ==> split
if(splitted.length == 3) {
return int.parse(splitted[2]);
}

log_debug("can not parse process stat %s".printf(stats));
return -1;
}

// get the effective user pid of an process
// returns -1 on error
public int get_euid_of_process(Pid process) {
GLib.File file = GLib.File.new_for_path("/proc/%d".printf(process));
try {
GLib.FileInfo info = file.query_info(FileAttribute.UNIX_UID, GLib.FileQueryInfoFlags.NONE);
return (int) info.get_attribute_uint32(FileAttribute.UNIX_UID);
} catch(GLib.Error e) {
log_debug("failed to fetch user of process %i %s".printf(process, e.message));
}
return -1;
}

// find the first parent process, that is owned by the user and not root
public Pid get_user_process() {
Pid ppid = -1;
int targetUser = TeeJee.System.get_user_id();
int user = 0;

do {
ppid = get_process_parent(ppid);
user = get_euid_of_process (ppid);
} while(user != targetUser && ppid > 1);
if(user == targetUser) {
return ppid;
}
return -1;
}

// get the env of an process
public string[]? get_process_env(Pid pid) {
if(pid < 1) {
return null;
}
return file_read_array("/proc/%i/environ".printf(pid), '\0');
}

// get the value of name in env if it exists or return default_value
public string? get_env(string[] env, string name, string? default_value = null) {
foreach(string env_var in env) {
string[] splitted = env_var.split("=", 2);
if(splitted[0] == name) {
if (splitted.length == 2) {
return splitted[1];
}
}
}
return default_value;
}

public Pid[] get_process_children (Pid parent_pid){

/* Returns the list of child processes owned by a given process */
Expand Down
6 changes: 3 additions & 3 deletions src/timeshift-launcher
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ else
# user is not admin
if echo $- | grep "i" >/dev/null 2>&1; then
# script is running in interactive mode
su - -c "pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY ${app_command}"
su - -c "${app_command}"
else
# script is running in non-interactive mode
if [ "$XDG_SESSION_TYPE" = "wayland" ] ; then
xhost +SI:localuser:root
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY ${app_command}
pkexec "${app_command}"
xhost -SI:localuser:root
xhost
elif command -v pkexec >/dev/null 2>&1; then
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY ${app_command}
pkexec "${app_command}"
elif command -v sudo >/dev/null 2>&1; then
x-terminal-emulator -e "sudo ${app_command}"
elif command -v su >/dev/null 2>&1; then
Expand Down
Loading