diff options
author | Kenny Levinsen <kl@kl.wtf> | 2020-08-07 15:48:24 +0200 |
---|---|---|
committer | Kenny Levinsen <kl@kl.wtf> | 2020-08-07 15:50:27 +0200 |
commit | a98e0c4ce90347d37370f2debcbed8ae9678a990 (patch) | |
tree | 47f3d10b51f6329103c8878e5a53da10b192600c /seatd | |
parent | 420f97300489f9fa10cea036c0d0f6d893c343d6 (diff) |
seatd: Add command-line arguments
Diffstat (limited to 'seatd')
-rw-r--r-- | seatd/seatd.c | 125 | ||||
-rw-r--r-- | seatd/server.c | 96 |
2 files changed, 127 insertions, 94 deletions
diff --git a/seatd/seatd.c b/seatd/seatd.c index 2dba9ba..30b0c27 100644 --- a/seatd/seatd.c +++ b/seatd/seatd.c @@ -1,5 +1,7 @@ #include <errno.h> +#include <grp.h> #include <poll.h> +#include <pwd.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> @@ -13,10 +15,44 @@ #include "poller.h" #include "server.h" -int main(int argc, char *argv[]) { - (void)argc; - (void)argv; +#define LISTEN_BACKLOG 16 + +static int open_socket(char *path, int uid, int gid) { + union { + struct sockaddr_un unix; + struct sockaddr generic; + } addr = {{0}}; + int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); + if (fd == -1) { + log_errorf("could not create socket: %s", strerror(errno)); + return -1; + } + addr.unix.sun_family = AF_UNIX; + strncpy(addr.unix.sun_path, path, sizeof addr.unix.sun_path - 1); + socklen_t size = offsetof(struct sockaddr_un, sun_path) + strlen(addr.unix.sun_path); + if (bind(fd, &addr.generic, size) == -1) { + log_errorf("could not bind socket: %s", strerror(errno)); + close(fd); + return -1; + } + if (listen(fd, LISTEN_BACKLOG) == -1) { + log_errorf("could not listen on socket: %s", strerror(errno)); + close(fd); + return -1; + } + if (uid != 0 || gid != 0) { + if (fchown(fd, uid, gid) == -1) { + log_errorf("could not chown socket to uid %d, gid %d: %s", uid, gid, + strerror(errno)); + } else if (fchmod(fd, 0770) == -1) { + log_errorf("could not chmod socket: %s", strerror(errno)); + } + } + return fd; +} + +int main(int argc, char *argv[]) { char *loglevel = getenv("SEATD_LOGLEVEL"); enum log_level level = LOGLEVEL_ERROR; if (loglevel != NULL) { @@ -30,23 +66,82 @@ int main(int argc, char *argv[]) { } log_init(level); - struct server server = {0}; - if (server_init(&server) == -1) { - log_errorf("server_create failed: %s", strerror(errno)); - return 1; + const char *usage = "Usage: seatd [options]\n" + "\n" + " -h Show this help message\n" + " -u <user> User to own the seatd socket\n" + " -g <group> Group to own the seatd socket\n" + " -s <path> Where to create the seatd socket\n" + " -v Show the version number\n" + "\n"; + + int c; + int uid = 0, gid = 0; + char *socket_path = getenv("SEATD_SOCK"); + while ((c = getopt(argc, argv, "vhs:g:u:")) != -1) { + switch (c) { + case 's': + socket_path = optarg; + break; + case 'u': { + struct passwd *pw = getpwnam(optarg); + if (pw == NULL) { + fprintf(stderr, "Could not find user by name '%s'.\n", optarg); + return 1; + } else { + uid = pw->pw_uid; + } + break; + } + case 'g': { + struct group *gr = getgrnam(optarg); + if (gr == NULL) { + fprintf(stderr, "Could not find group by name '%s'.\n", optarg); + return 1; + } else { + gid = gr->gr_gid; + } + break; + } + case 'v': + printf("seatd version %s\n", SEATD_VERSION); + return 0; + case 'h': + printf("%s", usage); + return 0; + case '?': + fprintf(stderr, "Try '%s -h' for more information.\n", argv[0]); + return 1; + default: + abort(); + } } - char *path = getenv("SEATD_SOCK"); - if (path == NULL) { - path = "/run/seatd.sock"; + + if (socket_path == NULL) { + socket_path = "/run/seatd.sock"; struct stat st; - if (stat(path, &st) == 0) { + if (stat(socket_path, &st) == 0) { log_info("removing leftover seatd socket"); - unlink(path); + unlink(socket_path); } } - if (server_listen(&server, path) == -1) { - log_errorf("server_listen failed: %s", strerror(errno)); + struct server server = {0}; + if (server_init(&server) == -1) { + log_errorf("server_create failed: %s", strerror(errno)); + return 1; + } + + int socket_fd = open_socket(socket_path, uid, gid); + if (socket_fd == -1) { + log_errorf("could not create server socket: %s", strerror(errno)); + server_finish(&server); + return 1; + } + if (poller_add_fd(&server.poller, socket_fd, EVENT_READABLE, server_handle_connection, + &server) == NULL) { + log_errorf("could not add socket to poller: %s", strerror(errno)); + close(socket_fd); server_finish(&server); return 1; } @@ -61,6 +156,6 @@ int main(int argc, char *argv[]) { } server_finish(&server); - unlink(path); + unlink(socket_path); return 0; } diff --git a/seatd/server.c b/seatd/server.c index 799fda0..7368ea3 100644 --- a/seatd/server.c +++ b/seatd/server.c @@ -1,7 +1,6 @@ #include <assert.h> #include <errno.h> #include <fcntl.h> -#include <grp.h> #include <signal.h> #include <stddef.h> #include <stdlib.h> @@ -20,8 +19,6 @@ #include "server.h" #include "terminal.h" -#define LISTEN_BACKLOG 16 - static int server_handle_vt_acq(int signal, void *data); static int server_handle_vt_rel(int signal, void *data); static int server_handle_kill(int signal, void *data); @@ -117,42 +114,6 @@ static int set_nonblock(int fd) { return 0; } -static int server_handle_connection(int fd, uint32_t mask, void *data) { - struct server *server = data; - if (mask & (EVENT_ERROR | EVENT_HANGUP)) { - shutdown(fd, SHUT_RDWR); - server->running = false; - log_errorf("server socket recieved an error: %s", strerror(errno)); - return -1; - } - - if (mask & EVENT_READABLE) { - int new_fd = accept(fd, NULL, NULL); - if (fd == -1) { - log_errorf("could not accept client connection: %s", strerror(errno)); - return 0; - } - - if (set_nonblock(new_fd) != 0) { - close(new_fd); - log_errorf("could not prepare new client socket: %s", strerror(errno)); - return 0; - } - - struct client *client = client_create(server, new_fd); - client->event_source = poller_add_fd(&server->poller, new_fd, EVENT_READABLE, - client_handle_connection, client); - if (client->event_source == NULL) { - client_destroy(client); - log_errorf("could not add client socket to poller: %s", strerror(errno)); - return 0; - } - log_infof("new client connected (pid: %d, uid: %d, gid: %d)", client->pid, - client->uid, client->gid); - } - return 0; -} - int server_add_client(struct server *server, int fd) { if (set_nonblock(fd) != 0) { close(fd); @@ -168,53 +129,30 @@ int server_add_client(struct server *server, int fd) { log_errorf("could not add client socket to poller: %s", strerror(errno)); return -1; } + log_infof("new client connected (pid: %d, uid: %d, gid: %d)", client->pid, client->uid, + client->gid); return 0; } -int server_listen(struct server *server, const char *path) { - union { - struct sockaddr_un unix; - struct sockaddr generic; - } addr = {{0}}; - int fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) { - log_errorf("could not create socket: %s", strerror(errno)); - return -1; - } - if (set_nonblock(fd) == -1) { - close(fd); - log_errorf("could not prepare socket: %s", strerror(errno)); +int server_handle_connection(int fd, uint32_t mask, void *data) { + struct server *server = data; + if (mask & (EVENT_ERROR | EVENT_HANGUP)) { + shutdown(fd, SHUT_RDWR); + server->running = false; + log_errorf("server socket recieved an error: %s", strerror(errno)); return -1; } - addr.unix.sun_family = AF_UNIX; - strncpy(addr.unix.sun_path, path, sizeof addr.unix.sun_path - 1); - socklen_t size = offsetof(struct sockaddr_un, sun_path) + strlen(addr.unix.sun_path); - if (bind(fd, &addr.generic, size) == -1) { - log_errorf("could not bind socket: %s", strerror(errno)); - close(fd); - return -1; - } - if (listen(fd, LISTEN_BACKLOG) == -1) { - log_errorf("could not listen on socket: %s", strerror(errno)); - close(fd); - return -1; - } - struct group *videogrp = getgrnam("video"); - if (videogrp != NULL) { - if (chown(path, 0, videogrp->gr_gid) == -1) { - log_errorf("could not chown socket to video group: %s", strerror(errno)); - } else if (chmod(path, 0770) == -1) { - log_errorf("could not chmod socket: %s", strerror(errno)); + if (mask & EVENT_READABLE) { + int new_fd = accept(fd, NULL, NULL); + if (fd == -1) { + log_errorf("could not accept client connection: %s", strerror(errno)); + return 0; + } + + if (server_add_client(server, new_fd) == -1) { + return 0; } - } else { - log_errorf("could not get video group: %s", strerror(errno)); - } - if (poller_add_fd(&server->poller, fd, EVENT_READABLE, server_handle_connection, server) == - NULL) { - log_errorf("could not add socket to poller: %s", strerror(errno)); - close(fd); - return -1; } return 0; } |