client/server: simplify setup packet handling

Instead of writing (and logging errors for) every parameter, one at a
time, send all fixed size data in a single struct, followed by all the
variable length data.
This commit is contained in:
Daniel Eklöf 2020-11-21 20:21:18 +01:00
parent 3640164917
commit fc81f413c0
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
4 changed files with 127 additions and 178 deletions

141
client.c
View file

@ -15,6 +15,7 @@
#define LOG_MODULE "foot-client"
#define LOG_ENABLE_DBG 0
#include "log.h"
#include "client-protocol.h"
#include "version.h"
#include "xmalloc.h"
@ -150,6 +151,7 @@ main(int argc, char *const *argv)
/* malloc:ed and needs to be in scope of all goto's */
char *cwd = NULL;
struct client_argv *cargv = NULL;
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1) {
@ -205,99 +207,79 @@ main(int argc, char *const *argv)
buf_len *= 2;
} while (errno == ERANGE);
}
const uint16_t cwd_len = strlen(cwd) + 1;
const uint16_t term_len = strlen(term) + 1;
const uint16_t title_len = strlen(title) + 1;
const uint16_t app_id_len = strlen(app_id) + 1;
uint32_t total_len = 0;
/* Calculate total length */
total_len += sizeof(cwd_len) + cwd_len;
total_len += sizeof(term_len) + term_len;
total_len += sizeof(title_len) + title_len;
total_len += sizeof(app_id_len) + app_id_len;
total_len += sizeof(uint8_t); /* maximized */
total_len += sizeof(uint8_t); /* fullscreen */
total_len += sizeof(uint8_t); /* hold */
total_len += sizeof(uint8_t); /* login_shell */
total_len += sizeof(argc);
/* String lengths, including NULL terminator */
const size_t cwd_len = strlen(cwd) + 1;
const size_t term_len = strlen(term) + 1;
const size_t title_len = strlen(title) + 1;
const size_t app_id_len = strlen(app_id) + 1;
for (int i = 0; i < argc; i++) {
uint16_t len = strlen(argv[i]) + 1;
total_len += sizeof(len) + len;
const struct client_data data = {
.maximized = maximized,
.fullscreen = fullscreen,
.hold = hold,
.login_shell = login_shell,
.cwd_len = cwd_len,
.term_len = term_len,
.title_len = title_len,
.app_id_len = app_id_len,
.argc = argc,
};
/* Total packet length, not (yet) including argv[] */
size_t total_len = (
sizeof(data) +
argc * sizeof(uint16_t) +
cwd_len +
term_len +
title_len +
app_id_len);
cargv = xmalloc(argc * sizeof(cargv[0]));
/* Add argv[] size to total packet length */
for (size_t i = 0; i < argc; i++) {
const size_t arg_len = strlen(argv[i]) + 1;
if (arg_len >= 1 << (8 * sizeof(cargv[i].len))) {
LOG_ERR("argv length overflow");
goto err;
}
cargv[i].len = arg_len;
total_len += sizeof(cargv[i]) + cargv[i].len;
}
LOG_DBG("term-len: %hu, argc: %d, total-len: %u",
term_len, argc, total_len);
if (send(fd, &total_len, sizeof(total_len), 0) != sizeof(total_len)) {
LOG_ERRNO("failed to send total length to server");
goto err;
}
if (send(fd, &cwd_len, sizeof(cwd_len), 0) != sizeof(cwd_len) ||
send(fd, cwd, cwd_len, 0) != cwd_len)
/* Check for size overflows */
if (total_len >= 1llu << (8 * sizeof(uint32_t)) ||
cwd_len >= 1 << (8 * sizeof(data.cwd_len)) ||
term_len >= 1 << (8 * sizeof(data.term_len)) ||
title_len >= 1 << (8 * sizeof(data.title_len)) ||
app_id_len >= 1 << (8 * sizeof(data.app_id_len)) ||
argc > data.argc)
{
LOG_ERRNO("failed to send CWD to server");
LOG_ERR("size overflow");
goto err;
}
if (send(fd, &term_len, sizeof(term_len), 0) != sizeof(term_len) ||
send(fd, term, term_len, 0) != term_len)
{
LOG_ERRNO("failed to send TERM to server");
goto err;
}
if (send(fd, &title_len, sizeof(title_len), 0) != sizeof(title_len) ||
send(fd, title, title_len, 0) != title_len)
{
LOG_ERRNO("failed to send title to server");
goto err;
}
if (send(fd, &app_id_len, sizeof(app_id_len), 0) != sizeof(app_id_len) ||
/* Send everything except argv[] */
if (send(fd, &(uint32_t){total_len}, sizeof(uint32_t), 0) != sizeof(uint32_t) ||
send(fd, &data, sizeof(data), 0) != sizeof(data) ||
send(fd, cwd, cwd_len, 0) != cwd_len ||
send(fd, term, term_len, 0) != term_len ||
send(fd, title, title_len, 0) != title_len ||
send(fd, app_id, app_id_len, 0) != app_id_len)
{
LOG_ERRNO("failed to send app-id to server");
LOG_ERRNO("failed to send setup packet to server");
goto err;
}
if (send(fd, &(uint8_t){maximized}, sizeof(uint8_t), 0) != sizeof(uint8_t)) {
LOG_ERRNO("failed to send maximized");
goto err;
}
if (send(fd, &(uint8_t){fullscreen}, sizeof(uint8_t), 0) != sizeof(uint8_t)) {
LOG_ERRNO("failed to send fullscreen");
goto err;
}
if (send(fd, &(uint8_t){hold}, sizeof(uint8_t), 0) != sizeof(uint8_t)) {
LOG_ERRNO("failed to send hold");
goto err;
}
if (send(fd, &(uint8_t){login_shell}, sizeof(uint8_t), 0) != sizeof(uint8_t)) {
LOG_ERRNO("failed to send login-shell");
goto err;
}
LOG_DBG("argc = %d", argc);
if (send(fd, &argc, sizeof(argc), 0) != sizeof(argc)) {
LOG_ERRNO("failed to send argc/argv to server");
goto err;
}
for (int i = 0; i < argc; i++) {
uint16_t len = strlen(argv[i]) + 1;
LOG_DBG("argv[%d] = %s (%hu)", i, argv[i], len);
if (send(fd, &len, sizeof(len), 0) != sizeof(len) ||
send(fd, argv[i], len, 0) != len)
/* Send argv[] */
for (size_t i = 0; i < argc; i++) {
if (send(fd, &cargv[i], sizeof(cargv[i]), 0) != sizeof(cargv[i]) ||
send(fd, argv[i], cargv[i].len, 0) != cargv[i].len)
{
LOG_ERRNO("failed to send argc/argv to server");
LOG_ERRNO("failed to send setup packet to server");
goto err;
}
}
@ -319,6 +301,7 @@ main(int argc, char *const *argv)
ret = exit_code;
err:
free(cargv);
free(cwd);
if (fd != -1)
close(fd);