From 93588036aa580214313a04828f417c9ca43b4eff Mon Sep 17 00:00:00 2001 From: fedir Date: Fri, 7 Feb 2025 12:42:51 +0100 Subject: [PATCH] Implemented GUI with zenity Now the program is completely functional and is using zenity dialogues. `sources` directory was renamed to `src`. UI related stuff was moved to `src/gui/ui`. --- sources/ui-socket.c | 116 ------------------------ {sources => src/gui}/ui/icfs.cmb | 0 {sources => src/gui}/ui/start_window.ui | 0 {sources => src}/main.c | 47 +++++++++- {sources => src}/sourcefs.c | 32 +++---- {sources => src}/sourcefs.h | 0 src/ui-socket.c | 56 ++++++++++++ {sources => src}/ui-socket.h | 2 - 8 files changed, 114 insertions(+), 139 deletions(-) delete mode 100644 sources/ui-socket.c rename {sources => src/gui}/ui/icfs.cmb (100%) rename {sources => src/gui}/ui/start_window.ui (100%) rename {sources => src}/main.c (93%) rename {sources => src}/sourcefs.c (69%) rename {sources => src}/sourcefs.h (100%) create mode 100644 src/ui-socket.c rename {sources => src}/ui-socket.h (86%) diff --git a/sources/ui-socket.c b/sources/ui-socket.c deleted file mode 100644 index f5ea22a..0000000 --- a/sources/ui-socket.c +++ /dev/null @@ -1,116 +0,0 @@ -#define _GNU_SOURCE -#include "ui-socket.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_MESSAGE_SIZE 1024 - -// Mutex for thread safety -static pthread_mutex_t socket_mutex = PTHREAD_MUTEX_INITIALIZER; -static int ui_socket_fd = -1; // Global socket file descriptor - -int init_ui_socket(const char *filename) { - if (!filename) { - return -1; - } - - // Create the socket - ui_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (ui_socket_fd == -1) { - perror("socket"); - return -1; - } - - // Remove the socket file if it already exists - if (unlink(filename) == -1 && - errno != ENOENT) { // ENOENT means the file does not exist, which is fine - perror("unlink"); - close(ui_socket_fd); - ui_socket_fd = -1; - return -1; - } - - // Set up the socket address structure - struct sockaddr_un addr; - memset(&addr, 0, sizeof(struct sockaddr_un)); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, filename, sizeof(addr.sun_path) - 1); - - // Bind the socket - if (bind(ui_socket_fd, (struct sockaddr *)&addr, - sizeof(struct sockaddr_un)) == -1) { - perror("bind"); - close(ui_socket_fd); - ui_socket_fd = -1; - return -1; - } - - // Listen for incoming connections - if (listen(ui_socket_fd, 5) == -1) { - perror("listen"); - close(ui_socket_fd); - ui_socket_fd = -1; - return -1; - } - - return 0; -} - -int ask_access(const char *filename, struct process_info pi) { - if (!filename || ui_socket_fd == -1) { - return -1; - } - - // Lock the mutex for thread safety - pthread_mutex_lock(&socket_mutex); - - int client_fd = accept(ui_socket_fd, NULL, NULL); - if (client_fd == -1) { - perror("accept"); - pthread_mutex_unlock(&socket_mutex); - return -1; - } - - // Prepare the message to send to the GUI - char message[MAX_MESSAGE_SIZE]; - int len_filename = strlen(filename); - int len_name = strlen(pi.name); - - snprintf(message, sizeof(message), "r%04d%s%04d%04d%s%04d", len_filename, - filename, pi.PID, len_name, pi.name, pi.UID); - - // Send the message to the GUI - if (send(client_fd, message, strlen(message), 0) == -1) { - perror("send"); - close(client_fd); - pthread_mutex_unlock(&socket_mutex); - return -1; - } - - // Receive the response from the GUI - char response[2]; - if (recv(client_fd, response, sizeof(response), 0) == -1) { - perror("recv"); - close(client_fd); - pthread_mutex_unlock(&socket_mutex); - return -1; - } - - close(client_fd); - pthread_mutex_unlock(&socket_mutex); - - // Process the response - if (response[0] == 'a' && response[1] == 'y') { - return 0; // Access granted - } else if (response[0] == 'a' && response[1] == 'n') { - return 1; // Access denied - } - - return -1; // Invalid response -} diff --git a/sources/ui/icfs.cmb b/src/gui/ui/icfs.cmb similarity index 100% rename from sources/ui/icfs.cmb rename to src/gui/ui/icfs.cmb diff --git a/sources/ui/start_window.ui b/src/gui/ui/start_window.ui similarity index 100% rename from sources/ui/start_window.ui rename to src/gui/ui/start_window.ui diff --git a/sources/main.c b/src/main.c similarity index 93% rename from sources/main.c rename to src/main.c index bcb8d41..7e25dee 100644 --- a/sources/main.c +++ b/src/main.c @@ -357,6 +357,28 @@ static int xmp_utimens(const char *path, const struct timespec ts[2], } #endif +// TODO: move this to other file +const char *get_process_name_by_pid(const int pid) { + char *name = (char *)calloc(1024, sizeof(char)); + if (name) { + sprintf(name, "/proc/%d/cmdline", pid); + FILE *f = fopen(name, "r"); + if (f) { + size_t size; + size = fread(name, sizeof(char), 1024, f); + if (size > 0) { + if ('\n' == name[size - 1]) + name[size - 1] = '\0'; + } + fclose(f); + } + } + return name; +} + +// TODO: move this somewhere else +const char *real_filename(const char *filename) { return filename; } + static int xmp_create(const char *path, mode_t mode, struct fuse_file_info *fi) { int fd; @@ -367,9 +389,16 @@ static int xmp_create(const char *path, mode_t mode, pi.PID = fc->pid; pi.UID = fc->uid; - pi.name = ""; + pi.name = get_process_name_by_pid(pi.PID); - printf("%d", ask_access(path, pi)); + // fprintf(stderr, "%s, %d\n", path, ask_access(path, pi)); + + if (ask_access(real_filename(path), pi)) { + free(pi.name); + return -EACCES; + } + + free(pi.name); fd = source_create(path, fi->flags, mode); if (fd == -1) @@ -388,9 +417,15 @@ static int xmp_open(const char *path, struct fuse_file_info *fi) { pi.PID = fc->pid; pi.UID = fc->uid; - pi.name = ""; + pi.name = get_process_name_by_pid(pi.PID); - printf("%d", ask_access(path, pi)); + // fprintf(stderr, "%s, %d\n", path, ask_access(path, pi)); + if (ask_access(real_filename(path), pi)) { + free(pi.name); + return -EACCES; + } + + free(pi.name); fd = source_open(path, fi->flags); if (fd == -1) @@ -694,5 +729,7 @@ int main(int argc, char *argv[]) { exit(EXIT_FAILURE); } - return fuse_main(argc, argv, &xmp_oper, NULL); + ret = fuse_main(argc, argv, &xmp_oper, NULL); + free(mountpoint); + return ret; } diff --git a/sources/sourcefs.c b/src/sourcefs.c similarity index 69% rename from sources/sourcefs.c rename to src/sourcefs.c index 22696a1..fe6766d 100644 --- a/sources/sourcefs.c +++ b/src/sourcefs.c @@ -13,7 +13,7 @@ static struct source_files_handle { int root_fd; } handle; -const char *source_fname_translate(const char *filename) { +const char *source_filename_translate(const char *filename) { if (strcmp("/", filename) == 0) { return "."; } else { @@ -34,32 +34,32 @@ int source_init(const char *root_path) { } int source_mkdir(const char *filename, mode_t mode) { - const char *relative_filename = source_fname_translate(filename); + const char *relative_filename = source_filename_translate(filename); return mkdirat(handle.root_fd, relative_filename, mode); } int source_unlink(const char *filename) { - const char *relative_filename = source_fname_translate(filename); + const char *relative_filename = source_filename_translate(filename); return unlinkat(handle.root_fd, relative_filename, 0); } int source_stat(const char *restrict filename, struct stat *restrict statbuf) { - const char *relative_filename = source_fname_translate(filename); + const char *relative_filename = source_filename_translate(filename); return fstatat(handle.root_fd, relative_filename, statbuf, 0); } int source_rmdir(const char *filename) { - const char *relative_filename = source_fname_translate(filename); + const char *relative_filename = source_filename_translate(filename); return unlinkat(handle.root_fd, relative_filename, AT_REMOVEDIR); } int source_symlink(const char *target, const char *linkpath) { - const char *relative_linkpath = source_fname_translate(linkpath); + const char *relative_linkpath = source_filename_translate(linkpath); return symlinkat(target, handle.root_fd, relative_linkpath); } DIR *source_opendir(const char *filename) { - const char *relative_filename = source_fname_translate(filename); + const char *relative_filename = source_filename_translate(filename); int fd = openat(handle.root_fd, relative_filename, NULL); if (fd < 0) { perror("Openat failed"); @@ -70,33 +70,33 @@ DIR *source_opendir(const char *filename) { } int source_rename(const char *oldpath, const char *newpath) { - const char *relative_oldpath = source_fname_translate(oldpath); - const char *relative_newpath = source_fname_translate(newpath); + const char *relative_oldpath = source_filename_translate(oldpath); + const char *relative_newpath = source_filename_translate(newpath); return renameat(handle.root_fd, relative_oldpath, handle.root_fd, relative_newpath); } int source_link(const char *oldpath, const char *newpath) { - const char *relative_oldpath = source_fname_translate(oldpath); - const char *relative_newpath = source_fname_translate(newpath); + const char *relative_oldpath = source_filename_translate(oldpath); + const char *relative_newpath = source_filename_translate(newpath); return linkat(handle.root_fd, relative_oldpath, handle.root_fd, relative_newpath, 0); // NOTE: perhaps the flags here need to be reevaluated. } int source_chmod(const char *filename, mode_t mode) { - const char *relative_filename = source_fname_translate(filename); + const char *relative_filename = source_filename_translate(filename); return fchmodat(handle.root_fd, relative_filename, mode, 0); // NOTE: perhaps the flags here need to be reevaluated. } int source_chown(const char *filename, uid_t owner, gid_t group) { - const char *relative_filename = source_fname_translate(filename); + const char *relative_filename = source_filename_translate(filename); return fchownat(handle.root_fd, filename, owner, group, AT_SYMLINK_NOFOLLOW); } int source_truncate(const char *filename, off_t length) { - const char *relative_filename = source_fname_translate(filename); + const char *relative_filename = source_filename_translate(filename); int fd = openat(handle.root_fd, relative_filename, NULL); if (fd < 0) { perror("Openat failed"); @@ -106,11 +106,11 @@ int source_truncate(const char *filename, off_t length) { } int source_open(const char *filename, int flags) { - const char *relative_filename = source_fname_translate(filename); + const char *relative_filename = source_filename_translate(filename); return openat(handle.root_fd, relative_filename, flags); } int source_create(const char *filename, int flags, mode_t mode) { - const char *relative_filename = source_fname_translate(filename); + const char *relative_filename = source_filename_translate(filename); return openat(handle.root_fd, relative_filename, flags, mode); } diff --git a/sources/sourcefs.h b/src/sourcefs.h similarity index 100% rename from sources/sourcefs.h rename to src/sourcefs.h diff --git a/src/ui-socket.c b/src/ui-socket.c new file mode 100644 index 0000000..e703106 --- /dev/null +++ b/src/ui-socket.c @@ -0,0 +1,56 @@ +#include +#include +#define _GNU_SOURCE +#include "ui-socket.h" +#include +#include +#include +#include +#include +#include +#include +#include + +int init_ui_socket(const char *filename) { + char line[256]; + FILE *fp; + + // Test if Zenity is installed (get version) + fp = popen("zenity --version", "r"); + if (fp == NULL) { + perror("Pipe returned a error"); + return 1; + } else { + while (fgets(line, sizeof(line), fp)) + printf("%s", line); + pclose(fp); + return 0; + } +} + +/* + * This function is called from the FUSE operations functions. Those are called + * from separate threads. Therefore, there can be multiple threads that try to + * ask for access at the same time, but we have to + */ + +int ask_access(const char *filename, struct process_info pi) { + + FILE *fp; + size_t command_len = + 139 + sizeof(pid_t) * 8 + strlen(pi.name) + strlen(filename); + char *command = (char *)malloc(command_len); + snprintf(command, command_len, + "zenity --question --title \"Allow Access?\" --text \"Allow process " + "%s with PID %d to access %s\"", + pi.name, pi.PID, filename); + // Zenity Question Message Popup + fp = popen(command, "r"); + free(command); + if (fp == NULL) { + perror("Pipe returned a error"); + return -1; + } else { + return WEXITSTATUS(pclose(fp)); + } +} diff --git a/sources/ui-socket.h b/src/ui-socket.h similarity index 86% rename from sources/ui-socket.h rename to src/ui-socket.h index 00db77e..3bb8e92 100644 --- a/sources/ui-socket.h +++ b/src/ui-socket.h @@ -17,8 +17,6 @@ struct process_info { // For default socket location, set socket_path = NULL. int init_ui_socket(const char *socket_path); -// TODO: design an interface for asking user for permission. - int ask_access(const char *filename, struct process_info pi); #endif // !UI_SOCKET_H