gdb-server/client.c

113 lines
2.9 KiB
C
Raw Normal View History

2024-10-01 22:48:28 +00:00
#include <client.h>
#include <stdio.h>
2024-10-02 01:24:48 +00:00
#include <stdint.h>
2024-10-01 22:48:28 +00:00
#include <string.h>
#include <unistd.h>
static bool write_char(RdbClient *self, char out) {
if (self->len >= RDB_CLIENT_BUFLEN) {
return false;
}
if (out == '#' || out == '$' || out == '}' || out == '*') {
self->full_buf[self->len++] = '}';
self->chk += '}';
if (self->len >= RDB_CLIENT_BUFLEN) {
return false;
}
out ^= 0x20;
}
self->full_buf[self->len++] = out;
self->chk += out;
return true;
}
bool char_to_hex_digit(char in, char *out) {
if (in & 0xf0) {
return false;
}
in &= 0x0f;
if (in > 9) {
*out = 'a' + in - 10;
} else {
*out = '0' + in;
}
return true;
}
bool char_to_hex_digits(char in, char *hi, char *lo) {
return char_to_hex_digit((in & 0xf0) >> 4, hi)
&& char_to_hex_digit(in & 0x0f, lo);
}
void rdb_client_init(RdbClient *self, int connfd) {
self->connfd = connfd;
self->len = 0;
self->chk = 0;
self->should_ack = true;
}
void rdb_client_begin_packet(RdbClient *self) {
self->len = 0;
self->chk = 0;
if (self->should_ack) {
self->full_buf[self->len++] = '+';
}
self->full_buf[self->len++] = '$';
}
bool rdb_client_write_str(RdbClient *self, const char *str) {
size_t len = strlen(str);
for (size_t i = 0; i < len; ++i) {
if (!write_char(self, str[i])) {
return false;
}
}
return true;
}
bool rdb_client_write_str_hex(RdbClient *self, const char *str) {
size_t len = strlen(str);
for (size_t i = 0; i < len; ++i) {
char hi, lo;
if (!char_to_hex_digits(str[i], &hi, &lo)
|| !write_char(self, hi)
|| !write_char(self, lo)) {
return false;
}
}
return true;
}
2024-10-02 01:24:48 +00:00
bool rdb_client_write_i8_hex(RdbClient *self, uint8_t value) {
char hi, lo;
return char_to_hex_digits(value, &hi, &lo)
&& write_char(self, hi)
&& write_char(self, lo);
}
bool rdb_client_write_i32_hex(RdbClient *self, uint32_t value) {
return rdb_client_write_i8_hex(self, (uint8_t) value)
&& rdb_client_write_i8_hex(self, (uint8_t) (value >> 8))
&& rdb_client_write_i8_hex(self, (uint8_t) (value >> 16))
&& rdb_client_write_i8_hex(self, (uint8_t) (value >> 24));
}
2024-10-01 22:48:28 +00:00
int rdb_client_send_packet(RdbClient *self) {
if (self->len + 3 > RDB_CLIENT_BUFLEN) {
return -1;
}
self->full_buf[self->len++] = '#';
char hi, lo;
if (!char_to_hex_digits(self->chk, &hi, &lo)) {
return -1;
}
self->full_buf[self->len++] = hi;
self->full_buf[self->len++] = lo;
printf("sending command \"%.*s\" %d\n", (int) self->len, self->full_buf, (int)self->len);
ssize_t rwrite = write(self->connfd, self->full_buf, self->len);
if (rwrite == -1) {
return -1;
}
return 0;
}