From 943d784fd0b42b3c10f084a8e5c33a7130a77205 Mon Sep 17 00:00:00 2001 From: "Nikita Tyukalov, ASUS, Linux" Date: Mon, 27 Jul 2026 16:27:50 +0300 Subject: [PATCH] Abandonment of the project --- base64.c | 83 +++++++++++++++++++++++++++++++++++++++++++ base64.h | 27 ++++++++++++++ build.sh | 2 +- connection.c | 1 + main.c | 23 ++++++++++++ medium.c | 41 +++++++++++++++++++++ medium.h | 57 +++++++++++++++++++++++++++++ medium_list.h | 13 +++++++ mediums/medium_pipe.c | 40 +++++++++++++++++++++ mediums/medium_pipe.h | 9 +++++ priv_medium.c | 58 ++++++++++++++++++++++++++++++ priv_medium.h | 48 +++++++++++++++++++++++++ server.c | 4 +-- 13 files changed, 403 insertions(+), 3 deletions(-) create mode 100644 base64.c create mode 100644 base64.h create mode 100644 medium.c create mode 100644 medium.h create mode 100644 medium_list.h create mode 100644 mediums/medium_pipe.c create mode 100644 mediums/medium_pipe.h create mode 100644 priv_medium.c create mode 100644 priv_medium.h diff --git a/base64.c b/base64.c new file mode 100644 index 0000000..4fbb84b --- /dev/null +++ b/base64.c @@ -0,0 +1,83 @@ +#include "base64.h" + +// Thanks, ryyst https://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c + +#include +#include +#include + +/* + * Data + */ +static const int mod_table[] = {0, 2, 1}; +static const char *encoding_table = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; +static char decoding_table[256] = {}; + +/* + * Private API + */ +static void build_decoding_table() { + for (int i = 0; i < 64; ++i) { + decoding_table[(uint8_t)encoding_table[i]] = i; + } +} + +/* + * Public API + */ +char *base64_encode(const void *_data, uint32_t size) { + uint32_t out_size = 4 * ((size + 2) / 3) + 1; + char *out_data = malloc(out_size); + if (!out_size) { + return NULL; + } + const char *data = _data; + for (int i = 0, j = 0; i < size;) { + uint32_t octet_a = i < size ? (uint8_t)data[i++] : 0; + uint32_t octet_b = i < size ? (uint8_t)data[i++] : 0; + uint32_t octet_c = i < size ? (uint8_t)data[i++] : 0; + + uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c; + + out_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F]; + out_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F]; + out_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F]; + out_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F]; + } + for (int i = 0; i < mod_table[size % 3]; i++) + out_data[out_size - 2 - i] = '='; + out_data[out_size - 1] = '\0'; + return out_data; +} + +void *base64_decode(const char *data, uint32_t *out_size) { + if (decoding_table[0] == 0) + build_decoding_table(); + uint32_t size = strlen(data); + if (size % 4 != 0) return NULL; + + *out_size = size / 4 * 3; + if (data[size - 1] == '=') (*out_size)--; + if (data[size - 2] == '=') (*out_size)--; + + uint8_t *decoded_data = malloc(*out_size); + if (decoded_data == NULL) return NULL; + + for (int i = 0, j = 0; i < size;) { + uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; + uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; + uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; + uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]]; + + uint32_t triple = (sextet_a << 3 * 6) + + (sextet_b << 2 * 6) + + (sextet_c << 1 * 6) + + (sextet_d << 0 * 6); + + if (j < *out_size) decoded_data[j++] = (triple >> 2 * 8) & 0xFF; + if (j < *out_size) decoded_data[j++] = (triple >> 1 * 8) & 0xFF; + if (j < *out_size) decoded_data[j++] = (triple >> 0 * 8) & 0xFF; + } + return decoded_data; +} diff --git a/base64.h b/base64.h new file mode 100644 index 0000000..3fbcc06 --- /dev/null +++ b/base64.h @@ -0,0 +1,27 @@ +#ifndef __BASE64_H +#define __BASE64_H + +#include + +/* + * Public API + */ +// Encode data as URL-safe Base64. +// Parameters: +// - data - data to encode +// - size - size of data to encode +// Returns: +// - pointer to resulting \0-terminated string (you must free() it) +// - NULL on out-of-memory +char *base64_encode(const void *data, uint32_t size); + +// Decode data from URL-safe Base64. +// Parameters: +// - data - data to decode (must have \0) +// - out_size - size of decoded data +// Returns: +// - pointer to decoded data (you must free() it) +// - NULL on out-of-memory +void *base64_decode(const char *data, uint32_t *out_size); + +#endif diff --git a/build.sh b/build.sh index 736c83a..097bd42 100755 --- a/build.sh +++ b/build.sh @@ -10,4 +10,4 @@ mkdir build # build echo "[I] Building ipoim..." -gcc *.c $(curl-config --cflags) $(curl-config --libs) -I. -o build/ipoim +gcc *.c mediums/*.c $(curl-config --cflags) $(curl-config --libs) -I. -o build/ipoim diff --git a/connection.c b/connection.c index 4623c2a..3314bfd 100644 --- a/connection.c +++ b/connection.c @@ -92,6 +92,7 @@ static void _free_conn(int index) { c->id ); } + pm_close(c->id); close(c->fd); rb_free(c->send_buf); free(c); diff --git a/main.c b/main.c index 6aef0b1..c2f254d 100644 --- a/main.c +++ b/main.c @@ -14,6 +14,8 @@ #include "event_loop.h" #include "server.h" #include "utils.h" +#include "priv_medium.h" +#include "medium_list.h" /* * Data @@ -165,6 +167,22 @@ static void server_deinit() { server_close(); } +// Setup the medium based on extension choice. +static bool medium_setup() { + const char *ext = cli_arg_get("E"); + int i = 0; + for (;;) { + if (strcmp(ext, MEDIUM_LIST[i])) { + i += 2; + continue; + } + ((void (*)())MEDIUM_LIST[i + 1])(); + return true; + } + fprintf(stderr, "[!] Extension '%s' is not supported\n", ext); + return false; +} + /* * Callbacks and main */ @@ -200,6 +218,9 @@ int main(int argc, char **argv) { print_usage_text(); return 1; } + if (!medium_setup) { + return 1; + } if (!loop_init(on_fd_event)) { return 1; } @@ -221,6 +242,7 @@ int main(int argc, char **argv) { return 1; } } + pm_init(); // Loop while (_to_work) { if (!loop_wait()) { @@ -230,6 +252,7 @@ int main(int argc, char **argv) { fprintf(stderr, "--- loop ---\n"); } // Termination + pm_deinit(); if (_is_server) { server_close(); } diff --git a/medium.c b/medium.c new file mode 100644 index 0000000..2f1026a --- /dev/null +++ b/medium.c @@ -0,0 +1,41 @@ +#include "medium.h" + +#include "event_loop.h" +#include "priv_medium.h" + +/* + * Public API + */ +void medium_set_callbacks( + cbmed_on_init_t on_init, + cbmed_on_deinit_t on_deinit, + cbmed_on_timer_t on_timer, + cbmed_on_fd_event_t on_fd_event, + cbmed_on_send_data_t on_send_data +) { + pm_on_init = on_init; + pm_on_deinit = on_deinit; + pm_on_timer = on_timer; + pm_on_fd_event = on_fd_event; + pm_on_send_data = on_send_data; +} + +void medium_epoll_ctl(int op, int fd, struct epoll_event *ev) { + loop_ctl(op, fd, ev); +} + +void medium_on_recv_data(const void *data, int32_t size) { + +} + +void medium_set_ready_to_send(bool state) { + +} + +void medium_set_max_send_size(int32_t size) { + +} + +void medium_start_timer(uint32_t id, int32_t ms) { + +} diff --git a/medium.h b/medium.h new file mode 100644 index 0000000..ba25bd8 --- /dev/null +++ b/medium.h @@ -0,0 +1,57 @@ +#ifndef __MEDIUM_H +#define __MEDIUM_H + +#include +#include + +#include + +/* + * Type definitions + */ +typedef bool (*cbmed_on_init_t)(); +typedef void (*cbmed_on_deinit_t)(); +typedef void (*cbmed_on_timer_t)(uint32_t id); +typedef void (*cbmed_on_fd_event_t)(int fd, uint32_t events); +typedef int32_t (*cbmed_on_send_data_t)(const void *data, int32_t size); + +/* + * Public API + */ +// Set callbacks to use to utilize medium. +void medium_set_callbacks( + cbmed_on_init_t on_init, + cbmed_on_deinit_t on_deinit, + cbmed_on_timer_t on_timer, + cbmed_on_fd_event_t on_fd_event, + cbmed_on_send_data_t on_send_data +); + +// Modify epoll. +// Remarks: +// - see `man epoll_ctl` +void medium_epoll_ctl(int op, int fd, struct epoll_event *ev); + +// Use this when you have received data from medium. +// Parameters: +// - data - data you received +// - size - size of data +void medium_on_recv_data(const void *data, int32_t size); + +// Call when you become ready/not ready to send data. +// Parameters: +// - state - true = ready; false = not ready +void medium_set_ready_to_send(bool state); + +// Set max size of data you are ready to accept for sending. +// Parameters: +// - size - size of data +void medium_set_max_send_size(int32_t size); + +// Start timer. +// Parameters: +// - id - timer ID +// - ms - milliseconds to wait +void medium_start_timer(uint32_t id, int32_t ms); + +#endif diff --git a/medium_list.h b/medium_list.h new file mode 100644 index 0000000..1816637 --- /dev/null +++ b/medium_list.h @@ -0,0 +1,13 @@ +#ifndef __MEDIUM_LIST_H +#define __MEDIUM_LIST_H + +#include + +#include "mediums/medium_pipe.h" + +static const void *MEDIUM_LIST[] = { + "pipe", medium_pipe_setup_callbacks, + NULL +}; + +#endif diff --git a/mediums/medium_pipe.c b/mediums/medium_pipe.c new file mode 100644 index 0000000..db53166 --- /dev/null +++ b/mediums/medium_pipe.c @@ -0,0 +1,40 @@ +#include "medium_pipe.h" + +#include "base64.h" +#include "medium.h" +#include "utils.h" + +/* + * Private API + */ + + +/* + * Callbacks + */ +static bool cbmed_on_init() { + return true; +} + +static void cbmed_on_deinit() { + +} + +static void cbmed_on_timer(uint32_t id) { + +} + +static void cbmed_on_fd_event(int fd, uint32_t events) { + +} + +static int32_t cbmed_on_send_data(const void *data, int32_t size) { + +} + +/* + * Public API + */ +void medium_pipe_setup_callbacks() { + +} diff --git a/mediums/medium_pipe.h b/mediums/medium_pipe.h new file mode 100644 index 0000000..e5db6f9 --- /dev/null +++ b/mediums/medium_pipe.h @@ -0,0 +1,9 @@ +#ifndef __MEDIUM_PIPE_H +#define __MEDIUM_PIPE_H + +/* + * Public API + */ +void medium_pipe_setup_callbacks(); + +#endif diff --git a/priv_medium.c b/priv_medium.c new file mode 100644 index 0000000..469ca1d --- /dev/null +++ b/priv_medium.c @@ -0,0 +1,58 @@ +#include "priv_medium.h" + +#include +#include + +#include "ring_buffer.h" + + +/* + * Macros + */ +#define SEND_BUF_SIZE (5 * 1024 * 1024) + +/* + * Private data + */ +static rb_handle_t send_buf = NULL; + +/* + * Public data + */ +cbmed_on_init_t pm_on_init = NULL; +cbmed_on_deinit_t pm_on_deinit = NULL; +cbmed_on_timer_t pm_on_timer = NULL; +cbmed_on_fd_event_t pm_on_fd_event = NULL; +cbmed_on_send_data_t pm_on_send_data = NULL; + +/* + * Private API + */ +static void _send_data(const void *data, uint32_t size) { + +} + +/* + * Public API + */ +bool pm_init() { + send_buf = rb_allocate(SEND_BUF_SIZE); + pm_on_init(); +} + +void pm_deinit() { + pm_on_deinit(); + rb_free(send_buf); +} + +void pm_send(uint32_t id, const void *data, uint32_t size) { + +} + +void pm_connect(uint32_t id) { + +} + +void pm_close(uint32_t id) { + +} diff --git a/priv_medium.h b/priv_medium.h new file mode 100644 index 0000000..331a7a0 --- /dev/null +++ b/priv_medium.h @@ -0,0 +1,48 @@ +#ifndef __PRIV_MEDIUM_H +#define __PRIV_MEDIUM_H + +#include +#include + +#include "medium.h" + +/* + * Public data + */ +extern cbmed_on_init_t pm_on_init; +extern cbmed_on_deinit_t pm_on_deinit; +extern cbmed_on_timer_t pm_on_timer; +extern cbmed_on_fd_event_t pm_on_fd_event; +extern cbmed_on_send_data_t pm_on_send_data; + +/* + * Public API + */ +// Initialize medium. +// Returns: +// - true on success +// Remarks: +// - you must call medium__setup_callbacks() before this +bool pm_init(); + +// Deinitialize medium. +void pm_deinit(); + +// Transmit data. +// Parameters: +// - id - connection ID +// - data - data to send (copied) +// - size - size of data +void pm_send(uint32_t id, const void *data, uint32_t size); + +// Send PT_CONNECT. +// Parameters: +// - id - connection ID +void pm_connect(uint32_t id); + +// Send PT_CLOSE. +// Parameters: +// - id - connection ID +void pm_close(uint32_t id); + +#endif diff --git a/server.c b/server.c index 3b7facb..8564596 100644 --- a/server.c +++ b/server.c @@ -10,6 +10,7 @@ #include #include +#include "priv_medium.h" #include "connection.h" #include "utils.h" @@ -39,8 +40,7 @@ bool _accept() { // no returning false, because it would terminate the app } else { - const char* data = "Test data lalalala"; - connection_send(id, data, strlen(data)); + pm_connect(id); } return true; }