diff options
Diffstat (limited to 'dbus/client/dbus_client.c')
-rw-r--r-- | dbus/client/dbus_client.c | 269 |
1 files changed, 0 insertions, 269 deletions
diff --git a/dbus/client/dbus_client.c b/dbus/client/dbus_client.c deleted file mode 100644 index de2df62..0000000 --- a/dbus/client/dbus_client.c +++ /dev/null @@ -1,269 +0,0 @@ -#include "dbus_client.h" -#include "../protocol.h" - -#include <sys/socket.h> -#include <sys/wait.h> -#include <sys/prctl.h> -#include <unistd.h> -#include <poll.h> - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> - -// TODO: Error checking for write/read - -static bool gsr_dbus_client_wait_for_startup(gsr_dbus_client *self) { - struct pollfd poll_fd = { - .fd = self->socket_pair[0], - .events = POLLIN, - .revents = 0 - }; - for(;;) { - int poll_res = poll(&poll_fd, 1, 100); - if(poll_res > 0 && (poll_fd.revents & POLLIN)) { - char msg; - read(self->socket_pair[0], &msg, 1); - return true; - } else { - int status = 0; - int wait_result = waitpid(self->pid, &status, WNOHANG); - if(wait_result != 0) { - int exit_code = -1; - if(WIFEXITED(status)) - exit_code = WEXITSTATUS(status); - fprintf(stderr, "gsr error: gsr_dbus_client_init: server died or never started, exit code: %d\n", exit_code); - self->pid = 0; - return false; - } - } - } -} - -bool gsr_dbus_client_init(gsr_dbus_client *self, const char *screencast_restore_token) { - memset(self, 0, sizeof(*self)); - - if(socketpair(AF_UNIX, SOCK_STREAM, 0, self->socket_pair) == -1) { - fprintf(stderr, "gsr error: gsr_dbus_client_init: socketpair failed, error: %s\n", strerror(errno)); - return false; - } - - if(screencast_restore_token) { - self->screencast_restore_token = strdup(screencast_restore_token); - if(!self->screencast_restore_token) { - fprintf(stderr, "gsr error: gsr_dbus_client_init: failed to clone restore token\n"); - gsr_dbus_client_deinit(self); - return false; - } - } - - self->pid = fork(); - if(self->pid == -1) { - fprintf(stderr, "gsr error: gsr_dbus_client_init: failed to fork process\n"); - gsr_dbus_client_deinit(self); - return false; - } else if(self->pid == 0) { /* child */ - char socket_pair_server_str[32]; - snprintf(socket_pair_server_str, sizeof(socket_pair_server_str), "%d", self->socket_pair[1]); - - /* Needed for NixOS for example, to make sure gsr-dbus-server doesn't inherit cap_sys_nice */ - prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0); - - const char *args[] = { "gsr-dbus-server", socket_pair_server_str, self->screencast_restore_token ? self->screencast_restore_token : "", NULL }; - execvp(args[0], (char *const*)args); - - fprintf(stderr, "gsr error: gsr_dbus_client_init: failed to launch \"gsr-dbus-server\", error: %s\n", strerror(errno)); - _exit(127); - } else { /* parent */ - if(!gsr_dbus_client_wait_for_startup(self)) { - gsr_dbus_client_deinit(self); - return false; - } - } - - return true; -} - -void gsr_dbus_client_deinit(gsr_dbus_client *self) { - for(int i = 0; i < 2; ++i) { - if(self->socket_pair[i] > 0) { - close(self->socket_pair[i]); - self->socket_pair[i] = -1; - } - } - - if(self->screencast_restore_token) { - free(self->screencast_restore_token); - self->screencast_restore_token = NULL; - } - - if(self->pid > 0) { - kill(self->pid, SIGKILL); - int status = 0; - waitpid(self->pid, &status, 0); - self->pid = 0; - } -} - -int gsr_dbus_client_screencast_create_session(gsr_dbus_client *self, char *session_handle, size_t session_handle_size) { - const gsr_dbus_request_message request = { - .protocol_version = GSR_DBUS_PROTOCOL_VERSION, - .type = GSR_DBUS_MESSAGE_REQ_CREATE_SESSION, - .create_session = (gsr_dbus_message_req_create_session) {} - }; - write(self->socket_pair[0], &request, sizeof(request)); - - gsr_dbus_response_message response = {0}; - read(self->socket_pair[0], &response, sizeof(response)); - - if(response.protocol_version != GSR_DBUS_PROTOCOL_VERSION) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_create_session: server uses protocol version %d while the client is using protocol version %d", response.protocol_version, GSR_DBUS_PROTOCOL_VERSION); - return -1; - } - - if(response.type == GSR_DBUS_MESSAGE_RESP_ERROR) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_create_session: server return error: %s (%d)\n", response.error.message, (int)response.error.error_code); - return response.error.error_code; - } - - if(response.type != GSR_DBUS_MESSAGE_RESP_CREATE_SESSION) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_create_session: received incorrect response type. Expected %d got %d\n", GSR_DBUS_MESSAGE_RESP_CREATE_SESSION, response.type); - return -1; - } - - snprintf(session_handle, session_handle_size, "%s", response.create_session.session_handle); - return 0; -} - -int gsr_dbus_client_screencast_select_sources(gsr_dbus_client *self, const char *session_handle, uint32_t capture_type, uint32_t cursor_mode) { - gsr_dbus_request_message request = { - .protocol_version = GSR_DBUS_PROTOCOL_VERSION, - .type = GSR_DBUS_MESSAGE_REQ_SELECT_SOURCES, - .select_sources = (gsr_dbus_message_req_select_sources) { - .capture_type = capture_type, - .cursor_mode = cursor_mode - } - }; - snprintf(request.select_sources.session_handle, sizeof(request.select_sources.session_handle), "%s", session_handle); - write(self->socket_pair[0], &request, sizeof(request)); - - gsr_dbus_response_message response = {0}; - read(self->socket_pair[0], &response, sizeof(response)); - - if(response.protocol_version != GSR_DBUS_PROTOCOL_VERSION) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_select_sources: server uses protocol version %d while the client is using protocol version %d", response.protocol_version, GSR_DBUS_PROTOCOL_VERSION); - return -1; - } - - if(response.type == GSR_DBUS_MESSAGE_RESP_ERROR) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_select_sources: server return error: %s (%d)\n", response.error.message, (int)response.error.error_code); - return response.error.error_code; - } - - if(response.type != GSR_DBUS_MESSAGE_RESP_SELECT_SOURCES) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_select_sources: received incorrect response type. Expected %d got %d\n", GSR_DBUS_MESSAGE_RESP_SELECT_SOURCES, response.type); - return -1; - } - - return 0; -} - -int gsr_dbus_client_screencast_start(gsr_dbus_client *self, const char *session_handle, uint32_t *pipewire_node) { - *pipewire_node = 0; - - gsr_dbus_request_message request = { - .protocol_version = GSR_DBUS_PROTOCOL_VERSION, - .type = GSR_DBUS_MESSAGE_REQ_START, - .start = (gsr_dbus_message_req_start) {} - }; - snprintf(request.start.session_handle, sizeof(request.start.session_handle), "%s", session_handle); - write(self->socket_pair[0], &request, sizeof(request)); - - gsr_dbus_response_message response = {0}; - read(self->socket_pair[0], &response, sizeof(response)); - - if(response.protocol_version != GSR_DBUS_PROTOCOL_VERSION) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_start: server uses protocol version %d while the client is using protocol version %d", response.protocol_version, GSR_DBUS_PROTOCOL_VERSION); - return -1; - } - - if(response.type == GSR_DBUS_MESSAGE_RESP_ERROR) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_start: server return error: %s (%d)\n", response.error.message, (int)response.error.error_code); - return response.error.error_code; - } - - if(response.type != GSR_DBUS_MESSAGE_RESP_START) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_start: received incorrect response type. Expected %d got %d\n", GSR_DBUS_MESSAGE_RESP_START, response.type); - return -1; - } - - if(self->screencast_restore_token) { - free(self->screencast_restore_token); - if(response.start.restore_token[0] == '\0') - self->screencast_restore_token = NULL; - else - self->screencast_restore_token = strdup(response.start.restore_token); - } - - *pipewire_node = response.start.pipewire_node; - return 0; -} - -bool gsr_dbus_client_screencast_open_pipewire_remote(gsr_dbus_client *self, const char *session_handle, int *pipewire_fd) { - *pipewire_fd = 0; - - gsr_dbus_request_message request = { - .protocol_version = GSR_DBUS_PROTOCOL_VERSION, - .type = GSR_DBUS_MESSAGE_REQ_OPEN_PIPEWIRE_REMOTE, - .open_pipewire_remote = (gsr_dbus_message_req_open_pipewire_remote) {} - }; - snprintf(request.open_pipewire_remote.session_handle, sizeof(request.open_pipewire_remote.session_handle), "%s", session_handle); - write(self->socket_pair[0], &request, sizeof(request)); - - gsr_dbus_response_message response = {0}; - struct iovec iov = { - .iov_base = &response, - .iov_len = sizeof(response) - }; - - char msg_control[CMSG_SPACE(sizeof(int))]; - - struct msghdr message = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = msg_control, - .msg_controllen = sizeof(msg_control) - }; - - const int bla = recvmsg(self->socket_pair[0], &message, MSG_WAITALL); - (void)bla; - - if(response.protocol_version != GSR_DBUS_PROTOCOL_VERSION) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_open_pipewire_remote: server uses protocol version %d while the client is using protocol version %d", response.protocol_version, GSR_DBUS_PROTOCOL_VERSION); - return false; - } - - if(response.type == GSR_DBUS_MESSAGE_RESP_ERROR) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_open_pipewire_remote: server return error: %s (%d)\n", response.error.message, (int)response.error.error_code); - return false; - } - - if(response.type != GSR_DBUS_MESSAGE_RESP_OPEN_PIPEWIRE_REMOTE) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_open_pipewire_remote: received incorrect response type. Expected %d got %d\n", GSR_DBUS_MESSAGE_RESP_OPEN_PIPEWIRE_REMOTE, response.type); - return false; - } - - struct cmsghdr *cmsg = CMSG_FIRSTHDR(&message); - if(!cmsg || cmsg->cmsg_type != SCM_RIGHTS) { - fprintf(stderr, "gsr error: gsr_dbus_client_screencast_open_pipewire_remote: returned message data is missing file descriptor\n"); - return false; - } - - memcpy(pipewire_fd, CMSG_DATA(cmsg), sizeof(*pipewire_fd)); - return true; -} - -const char* gsr_dbus_client_screencast_get_restore_token(gsr_dbus_client *self) { - return self->screencast_restore_token; -} |