2024-10-08 02:18:42 +00:00
|
|
|
#include <response.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2024-10-10 22:38:40 +00:00
|
|
|
static bool writeChar(RdbResponse *res, char out) {
|
2024-10-08 02:18:42 +00:00
|
|
|
if (res->len >= res->buflen) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (out == '#' || out == '$' || out == '}' || out == '*') {
|
|
|
|
res->buf[res->len++] = '}';
|
|
|
|
res->chk += '}';
|
|
|
|
if (res->len >= res->buflen) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
out ^= 0x20;
|
|
|
|
}
|
|
|
|
res->buf[res->len++] = out;
|
|
|
|
res->chk += out;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-10-10 22:38:40 +00:00
|
|
|
bool charToHexDigit(char in, char *out) {
|
2024-10-08 02:18:42 +00:00
|
|
|
if (in & 0xf0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
in &= 0x0f;
|
|
|
|
if (in > 9) {
|
|
|
|
*out = 'a' + in - 10;
|
|
|
|
} else {
|
|
|
|
*out = '0' + in;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-10-10 22:38:40 +00:00
|
|
|
bool charToHexDigits(char in, char *hi, char *lo) {
|
|
|
|
return charToHexDigit((in & 0xf0) >> 4, hi)
|
|
|
|
&& charToHexDigit(in & 0x0f, lo);
|
2024-10-08 02:18:42 +00:00
|
|
|
}
|
|
|
|
|
2024-10-10 22:38:40 +00:00
|
|
|
void rdbResponseInit(RdbResponse *res, int connfd, char *buf, size_t buflen) {
|
2024-10-08 02:18:42 +00:00
|
|
|
res->connfd = connfd;
|
|
|
|
res->buf = buf;
|
|
|
|
res->buflen = buflen;
|
|
|
|
res->len = 0;
|
|
|
|
res->chk = 0;
|
|
|
|
res->should_ack = true;
|
|
|
|
}
|
|
|
|
|
2024-10-10 22:38:40 +00:00
|
|
|
void rdbResponseBeginPacket(RdbResponse *res) {
|
2024-10-08 02:18:42 +00:00
|
|
|
res->len = 0;
|
|
|
|
res->chk = 0;
|
|
|
|
if (res->should_ack) {
|
|
|
|
res->buf[res->len++] = '+';
|
|
|
|
}
|
|
|
|
res->buf[res->len++] = '$';
|
|
|
|
}
|
|
|
|
|
2024-10-10 22:38:40 +00:00
|
|
|
bool rdbResponseWriteStr(RdbResponse *res, const char *str) {
|
2024-10-08 02:42:28 +00:00
|
|
|
size_t i, len = strlen(str);
|
|
|
|
for (i = 0; i < len; ++i) {
|
2024-10-10 22:38:40 +00:00
|
|
|
if (!writeChar(res, str[i])) {
|
2024-10-08 02:18:42 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-10-10 22:38:40 +00:00
|
|
|
bool rdbResponseWriteStrHex(RdbResponse *res, const char *str) {
|
2024-10-08 02:42:28 +00:00
|
|
|
size_t i, len = strlen(str);
|
|
|
|
for (i = 0; i < len; ++i) {
|
2024-10-08 02:18:42 +00:00
|
|
|
char hi, lo;
|
2024-10-10 22:38:40 +00:00
|
|
|
if (!charToHexDigits(str[i], &hi, &lo)
|
|
|
|
|| !writeChar(res, hi)
|
|
|
|
|| !writeChar(res, lo)) {
|
2024-10-08 02:18:42 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-10-10 22:38:40 +00:00
|
|
|
bool rdbResponseWriteI8Hex(RdbResponse *res, uint8_t value) {
|
2024-10-08 02:18:42 +00:00
|
|
|
char hi, lo;
|
2024-10-10 22:38:40 +00:00
|
|
|
return charToHexDigits(value, &hi, &lo)
|
|
|
|
&& writeChar(res, hi)
|
|
|
|
&& writeChar(res, lo);
|
2024-10-08 02:18:42 +00:00
|
|
|
}
|
|
|
|
|
2024-10-10 22:38:40 +00:00
|
|
|
bool rdbResponseWriteI32Hex(RdbResponse *res, uint32_t value) {
|
|
|
|
return rdbResponseWriteI8Hex(res, (uint8_t) value)
|
|
|
|
&& rdbResponseWriteI8Hex(res, (uint8_t) (value >> 8))
|
|
|
|
&& rdbResponseWriteI8Hex(res, (uint8_t) (value >> 16))
|
|
|
|
&& rdbResponseWriteI8Hex(res, (uint8_t) (value >> 24));
|
2024-10-08 02:18:42 +00:00
|
|
|
}
|
|
|
|
|
2024-10-10 22:38:40 +00:00
|
|
|
int rdbResponseSendPacket(RdbResponse *res) {
|
2024-10-08 02:42:28 +00:00
|
|
|
char hi, lo;
|
|
|
|
ssize_t rwrite;
|
|
|
|
|
2024-10-08 02:18:42 +00:00
|
|
|
if (res->len + 3 > res->buflen) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
res->buf[res->len++] = '#';
|
2024-10-10 22:38:40 +00:00
|
|
|
if (!charToHexDigits(res->chk, &hi, &lo)) {
|
2024-10-08 02:18:42 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
res->buf[res->len++] = hi;
|
|
|
|
res->buf[res->len++] = lo;
|
|
|
|
printf("sending command \"%.*s\" %d\n", (int) res->len, res->buf, (int)res->len);
|
|
|
|
|
2024-10-08 02:42:28 +00:00
|
|
|
rwrite = write(res->connfd, res->buf, res->len);
|
2024-10-08 02:18:42 +00:00
|
|
|
if (rwrite == -1) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|