diff --git a/examples/pool/main.c b/examples/pool/main.c index ad19345..35025d6 100644 --- a/examples/pool/main.c +++ b/examples/pool/main.c @@ -5,7 +5,7 @@ int main(int argc, char *argv[]) { int ret = EXIT_FAILURE; - if(argc != 2){ + if (argc != 2) { printf("usage: %s \n", argv[0]); return ret; } @@ -15,7 +15,7 @@ int main(int argc, char *argv[]) { ctx.debug = true; - if(!lm_ctx_pool_add(&ctx, "test", argv[1])){ + if (!lm_ctx_pool_add(&ctx, "test", argv[1])) { printf("failed to add pool: %s (%d)\n", lm_strerror(), lm_error()); goto end; } diff --git a/include/all.h b/include/all.h index fd083a6..4807a5a 100644 --- a/include/all.h +++ b/include/all.h @@ -1,4 +1,4 @@ -#include "types.h" -#include "pool.h" #include "error.h" #include "libmp.h" +#include "pool.h" +#include "types.h" diff --git a/include/error.h b/include/error.h index 88ef08e..2a136b0 100644 --- a/include/error.h +++ b/include/error.h @@ -2,24 +2,24 @@ typedef enum lm_error { LM_ERR_NoError = 0, - LM_ERR_URLBadChar = 1, + LM_ERR_URLBadChar = 1, LM_ERR_URLBadProtocol = 2, - LM_ERR_URLTooLarge = 3, - LM_ERR_URLHostLarge = 4, - LM_ERR_URLPathLarge = 5, - LM_ERR_URLBadHost = 6, - LM_ERR_URLBadPath = 7, + LM_ERR_URLTooLarge = 3, + LM_ERR_URLHostLarge = 4, + LM_ERR_URLPathLarge = 5, + LM_ERR_URLBadHost = 6, + LM_ERR_URLBadPath = 7, LM_ERR_URLPortUnknown = 8, - LM_ERR_URLBadPort = 9, - LM_ERR_PoolNoSupport = 10, - LM_ERR_URLEnd = 11, + LM_ERR_URLBadPort = 9, + LM_ERR_PoolNoSupport = 10, + LM_ERR_URLEnd = 11, } lm_error_t; typedef struct lm_error_desc { lm_error_t code; - char *desc; + char *desc; } lm_error_desc_t; -void lm_error_set(lm_error_t code); +void lm_error_set(lm_error_t code); lm_error_t lm_error(); -char *lm_strerror(); +char *lm_strerror(); diff --git a/include/mptp.h b/include/mptp.h new file mode 100644 index 0000000..d0a7b52 --- /dev/null +++ b/include/mptp.h @@ -0,0 +1,93 @@ +#pragma once +#include +#include "types.h" + +/* + + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + ##################################### + # FLAGS # + ##################################### + # SIZE # + # # + ##################################### + # DATA # + #...................................# + + [8 bits] FLAGS + --------------------------------------------------------- + 4 bits used for specifying the version + --------------------------------------------------------- + 1 bit used to specify if this is a request or response + + 0- it's a request + 1- it's a response + --------------------------------------------------------- + 2 bits used for request/response codes + + We have 4 types of different requests + 1- PING: checks if the server is avaliable + 2- INFO: gets information about the pool(s) the server is hosting + 3- LIST: requests the package list for certain pool + 4- PULL: requests a certain package from a certain pool + + And 4 types of responses + 1- PONG: response for the ping request + 2- COOL: everything is fine, here's the data you requested + 3- BRUH: cannot access to the data you requested, or version mismatch + 4- WHAT: bad request + --------------------------------------------------------- + 1 bit used to specify if this the last request/response + + 0- no stay connected, im not done responsing/requesting yet + 1- yes, im done, disconnect + --------------------------------------------------------- + + [16 bits] SIZE + --------------------------------------------------------- + All bits used for specifying the DATA size, in bytes + --------------------------------------------------------- + + [...] DATA + --------------------------------------------------------- + Plaintext data used for that specific request/response, + max value for SIZE is 65535, so this section may have + 65535 bytes total + --------------------------------------------------------- + +*/ + +#define MPTP_VERSION_SUPPORTED 0 +#define MPTP_VERSION_MAX 15 // 4 bits +#define MPTP_CODE_MAX 4 // 2 bits + +typedef enum lm_mptp_request{ + MPTP_C2S_PING = 0, + MPTP_C2S_INFO = 1, + MPTP_C2S_LIST = 2, + MPTP_C2S_PULL = 3, +} lm_mptp_request_t; + +typedef enum lm_mptp_response{ + MPTP_S2C_PONG = 0, + MPTP_S2C_COOL = 1, + MPTP_S2C_BRUH = 2, + MPTP_S2C_WHAT = 3, +} lm_mptp_response_t; + +typedef struct lm_mptp { + uint8_t flags; + uint16_t size; + char *data; +} lm_mptp_t; + +void lm_mptp_flags_set(lm_mptp_t *packet, uint8_t version, bool is_request, uint8_t code, bool is_last); +#define MPTP_FLAGS_VERSION(m) (m->flags >> 4) & 15 +#define MPTP_FLAGS_IS_REQUEST(m) ((m->flags >> 3) & 1) == 0 +#define MPTP_FLAGS_TYPE(m) (m->flags >> 1) & 3 +#define MPTP_FLAGS_IS_LAST(m) (m->flags & 1) == 1 + +int lm_mptp_connect(lm_url_t *url); +bool lm_mptp_recv(int socket, lm_mptp_t *packet); +bool lm_mptp_send(int socket, lm_mptp_t *packet); +void lm_mptp_disconnect(int socket); diff --git a/include/pool.h b/include/pool.h index d06de1e..6f8db60 100644 --- a/include/pool.h +++ b/include/pool.h @@ -1,6 +1,6 @@ #pragma once -#include #include "types.h" +#include bool lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url); bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name); diff --git a/include/types.h b/include/types.h index 83e83de..b206941 100644 --- a/include/types.h +++ b/include/types.h @@ -4,17 +4,16 @@ typedef struct lm_pool { struct lm_pool *next; - lm_url_t url; - bool available; - char *name; + lm_url_t url; + bool available; + char *name; } lm_pool_t; typedef struct lm_ctx { lm_pool_t *pools; // pool list - char *root; // root path for package installtion - char *temp; // temp path - char *data; // package database path - bool debug; // is debug output enabled? + char *root; // root path for package installtion + char *temp; // temp path + char *data; // package database path + bool debug; // is debug output enabled? } lm_ctx_t; - diff --git a/include/url.h b/include/url.h index 45d404e..8d954db 100644 --- a/include/url.h +++ b/include/url.h @@ -3,14 +3,14 @@ #include #define URL_PROTOCOL_MAX 20 -#define URL_PATH_MAX 2000 -#define URL_HOST_MAX 260 +#define URL_PATH_MAX 2000 +#define URL_HOST_MAX 260 typedef struct lm_url { uint16_t port; - char protocol[URL_PROTOCOL_MAX+1]; - char *host; - char *path; + char protocol[URL_PROTOCOL_MAX + 1]; + char *host; + char *path; } lm_url_t; bool lm_url_parse(lm_url_t *url, char *str); diff --git a/include/util.h b/include/util.h index fe7b8a2..1a8f045 100644 --- a/include/util.h +++ b/include/util.h @@ -1,7 +1,7 @@ #pragma once -#include -#include #include "types.h" +#include +#include #define _(x) gettext(x) diff --git a/locale/tr/LC_MESSAGES/libmp.po b/locale/tr/LC_MESSAGES/libmp.po index b69aad7..e69e884 100644 --- a/locale/tr/LC_MESSAGES/libmp.po +++ b/locale/tr/LC_MESSAGES/libmp.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-20 03:33+0300\n" +"POT-Creation-Date: 2024-06-20 20:00+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,7 +19,7 @@ msgstr "" #: src/error.c:13 msgid "no error" -msgstr "no error" +msgstr "hata yok" #: src/error.c:14 #, fuzzy @@ -60,7 +60,7 @@ msgstr "URL protocol port number is unknown" #: src/error.c:23 msgid "URL is incomplete" -msgstr "URL is incomplete" +msgstr "URL tamamlanmamış" #: src/error.c:24 msgid "pool does not support the specified protocol" diff --git a/src/error.c b/src/error.c index 13b9ee7..fd95e94 100644 --- a/src/error.c +++ b/src/error.c @@ -4,33 +4,33 @@ lm_error_t error = LM_ERR_NoError; -void lm_error_set(lm_error_t code){ +void lm_error_set(lm_error_t code) { error = code; } -char *lm_strerror(){ +char *lm_strerror() { lm_error_desc_t errors[] = { - {.code=LM_ERR_NoError, .desc=_("no error")}, - {.code=LM_ERR_URLBadChar, .desc=_("URL contains an invalid character")}, - {.code=LM_ERR_URLBadProtocol, .desc=_("URL does not have a valid protocol field")}, - {.code=LM_ERR_URLTooLarge, .desc=_("URL is too large")}, - {.code=LM_ERR_URLHostLarge, .desc=_("URL hostname is too large")}, - {.code=LM_ERR_URLPathLarge, .desc=_("URL path is too large")}, - {.code=LM_ERR_URLBadHost, .desc=_("URL does not have a valid hostname")}, - {.code=LM_ERR_URLBadPath, .desc=_("URL does not have a valid path")}, - {.code=LM_ERR_URLBadPort, .desc=_("URL does not contain a hostname with a valid port number")}, - {.code=LM_ERR_URLPortUnknown, .desc=_("URL protocol port number is unknown")}, - {.code=LM_ERR_URLEnd, .desc=_("URL is incomplete")}, - {.code=LM_ERR_PoolNoSupport, .desc=_("pool does not support the specified protocol")}, + {.code = LM_ERR_NoError, .desc = _("no error") }, + {.code = LM_ERR_URLBadChar, .desc = _("URL contains an invalid character") }, + {.code = LM_ERR_URLBadProtocol, .desc = _("URL does not have a valid protocol field") }, + {.code = LM_ERR_URLTooLarge, .desc = _("URL is too large") }, + {.code = LM_ERR_URLHostLarge, .desc = _("URL hostname is too large") }, + {.code = LM_ERR_URLPathLarge, .desc = _("URL path is too large") }, + {.code = LM_ERR_URLBadHost, .desc = _("URL does not have a valid hostname") }, + {.code = LM_ERR_URLBadPath, .desc = _("URL does not have a valid path") }, + {.code = LM_ERR_URLBadPort, .desc = _("URL does not contain a hostname with a valid port number")}, + {.code = LM_ERR_URLPortUnknown, .desc = _("URL protocol port number is unknown") }, + {.code = LM_ERR_URLEnd, .desc = _("URL is incomplete") }, + {.code = LM_ERR_PoolNoSupport, .desc = _("pool does not support the specified protocol") }, }; - for(int i = 0; i < sizeof(errors)/sizeof(lm_error_desc_t); i++){ - if(errors[i].code == error) + for (int i = 0; i < sizeof(errors) / sizeof(lm_error_desc_t); i++) { + if (errors[i].code == error) return errors[i].desc; } return NULL; } -lm_error_t lm_error(){ +lm_error_t lm_error() { return error; } diff --git a/src/libmp.c b/src/libmp.c index 604b766..d3654d3 100644 --- a/src/libmp.c +++ b/src/libmp.c @@ -24,11 +24,11 @@ #include "../include/libmp.h" #include "../include/pool.h" -#include #include +#include #include -void lm_ctx_init(lm_ctx_t *ctx){ +void lm_ctx_init(lm_ctx_t *ctx) { setlocale(LC_ALL, ""); textdomain("libmp"); @@ -39,7 +39,7 @@ void lm_ctx_init(lm_ctx_t *ctx){ ctx->debug = false; } -void lm_ctx_free(lm_ctx_t *ctx){ +void lm_ctx_free(lm_ctx_t *ctx) { lm_ctx_pool_clear(ctx); return; } diff --git a/src/pool.c b/src/pool.c index 5e7e42c..b8d3a95 100644 --- a/src/pool.c +++ b/src/pool.c @@ -1,22 +1,22 @@ +#include "../include/pool.h" #include "../include/error.h" #include "../include/util.h" -#include "../include/pool.h" #include #include -void lm_pool_free(lm_pool_t *pool){ +void lm_pool_free(lm_pool_t *pool) { lm_url_free(&pool->url); free(pool); } -lm_pool_t *lm_pool_new(char *name, char *url){ +lm_pool_t *lm_pool_new(char *name, char *url) { lm_pool_t *pool = malloc(sizeof(lm_pool_t)); - if(!lm_url_parse(&pool->url, url)){ + if (!lm_url_parse(&pool->url, url)) { free(pool); return NULL; } - if(!eq(pool->url.protocol, "mptp")){ + if (!eq(pool->url.protocol, "mptp")) { lm_error_set(LM_ERR_PoolNoSupport); lm_pool_free(pool); return NULL; @@ -26,22 +26,22 @@ lm_pool_t *lm_pool_new(char *name, char *url){ return pool; } -bool lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url){ +bool lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url) { lm_pool_t *pool = lm_pool_new(name, url); - if(NULL == pool) + if (NULL == pool) return false; pdebug(ctx, __func__, "pool name is %s", pool->name); - pdebug(ctx, __func__, "pool URL is %s://%s%s", pool->url.protocol, pool->url.host, pool->url.path); + pdebug(ctx, __func__, "pool URL is %s://%s:%d%s", pool->url.protocol, pool->url.host, pool->url.port, pool->url.path); - if(NULL == ctx->pools){ + if (NULL == ctx->pools) { ctx->pools = pool; return true; } lm_pool_t *cur = ctx->pools; - while(NULL != cur) { - if(NULL == cur->next){ + while (NULL != cur) { + if (NULL == cur->next) { cur->next = pool; return true; } @@ -51,17 +51,17 @@ bool lm_ctx_pool_add(lm_ctx_t *ctx, char *name, char *url){ return false; } -bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name){ +bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name) { lm_pool_t *cur = ctx->pools, *prev = NULL; - while(NULL != cur) { - if(!eq(cur->name, name)){ + while (NULL != cur) { + if (!eq(cur->name, name)) { cur = cur->next; continue; } - if(NULL == prev){ + if (NULL == prev) { ctx->pools = cur->next; - lm_pool_free(cur); + lm_pool_free(cur); return true; } @@ -73,17 +73,17 @@ bool lm_ctx_pool_del(lm_ctx_t *ctx, char *name){ return false; } -void lm_ctx_pool_clear(lm_ctx_t *ctx){ +void lm_ctx_pool_clear(lm_ctx_t *ctx) { lm_pool_t *cur = ctx->pools, *prev = NULL; - while(NULL != cur) { + while (NULL != cur) { prev = cur; - cur = cur->next; + cur = cur->next; lm_pool_free(prev); } ctx->pools = NULL; } -void lm_ctx_pool_test(lm_ctx_t *ctx){ +void lm_ctx_pool_test(lm_ctx_t *ctx) { return; } diff --git a/src/protocol.c b/src/protocol.c new file mode 100644 index 0000000..e69de29 diff --git a/src/url.c b/src/url.c index ca0b3af..05a2109 100644 --- a/src/url.c +++ b/src/url.c @@ -1,35 +1,34 @@ +#include "../include/url.h" #include "../include/error.h" #include "../include/util.h" -#include "../include/url.h" #include -#include -#include #include +#include -char valid_path[] = "-._~:/?#[]@!$&'()*+,;%="; +char valid_path[] = "-._~:/?#[]@!$&'()*+,;%="; typedef enum lm_state { URL_PROTOCOL_0 = 0, - URL_SPLIT_1 = 1, - URL_HOST_2 = 2, - URL_PATH_3 = 3, + URL_SPLIT_1 = 1, + URL_HOST_2 = 2, + URL_PATH_3 = 3, } lm_state_t; -uint16_t lm_url_default(char *protocol){ - if(eq(protocol, "ftp")) +uint16_t lm_url_default(char *protocol) { + if (eq(protocol, "ftp")) return 21; - else if(eq(protocol, "ftps")) + else if (eq(protocol, "ftps")) return 990; - else if(eq(protocol, "http")) + else if (eq(protocol, "http")) return 80; - else if(eq(protocol, "https")) + else if (eq(protocol, "https")) return 443; - else if(eq(protocol, "mptp")) + else if (eq(protocol, "mptp")) return 5858; return 0; } -bool lm_url_parse(lm_url_t *url, char *str){ +bool lm_url_parse(lm_url_t *url, char *str) { // clear out every variable bzero(url->protocol, sizeof(url->protocol)); url->host = NULL; @@ -38,61 +37,61 @@ bool lm_url_parse(lm_url_t *url, char *str){ // stores the string size size_t strl = 0, index = 0, pos = 0; - + // make sure the URL string size is not too large // extra 4 for "://" and ":" - if((strl = strlen(str)) > URL_PROTOCOL_MAX+URL_PATH_MAX+URL_HOST_MAX+4){ + if ((strl = strlen(str)) > URL_PROTOCOL_MAX + URL_PATH_MAX + URL_HOST_MAX + 4) { lm_error_set(LM_ERR_URLTooLarge); return false; } lm_state_t state = URL_PROTOCOL_0; - char buffer[strl+1]; // temporary buffer - bool ret = false; // return value - - // clear out the temporary buffer - bzero(buffer, strl+1); + char buffer[strl + 1], *save; // temporary buffer, strok_r save pointer + bool ret = false; // return value - while ((buffer[index] = *(str+pos)) != 0) { + // clear out the temporary buffer + bzero(buffer, strl + 1); + + while ((buffer[index] = *(str + pos)) != 0) { switch (state) { case URL_PROTOCOL_0: - if(index > URL_PROTOCOL_MAX){ + if (index > URL_PROTOCOL_MAX) { lm_error_set(LM_ERR_URLBadProtocol); goto end; } - if (!is_letter(buffer[index]) && !is_digit(buffer[index]) && buffer[index] != ':'){ + if (!is_letter(buffer[index]) && !is_digit(buffer[index]) && buffer[index] != ':') { lm_error_set(LM_ERR_URLBadChar); goto end; } - if(buffer[index] != ':') + if (buffer[index] != ':') break; - if(0 == index){ + if (0 == index) { lm_error_set(LM_ERR_URLBadProtocol); goto end; } buffer[index] = 0; - memcpy(url->protocol, buffer, index+1); + memcpy(url->protocol, buffer, index + 1); goto next; case URL_SPLIT_1: - if(index > 1){ + if (index > 1) { lm_error_set(LM_ERR_URLBadProtocol); goto end; } - if (buffer[index] != '/'){ + if (buffer[index] != '/') { lm_error_set(LM_ERR_URLBadChar); goto end; } - if(index != 1) + if (index != 1) break; - if(buffer[index-1] != '/' || buffer[index] != '/'){ + if (buffer[index - 1] != '/' || buffer[index] != '/') { lm_error_set(LM_ERR_URLBadProtocol); goto end; } @@ -100,36 +99,37 @@ bool lm_url_parse(lm_url_t *url, char *str){ goto next; case URL_HOST_2: - if(index > URL_HOST_MAX){ + if (index > URL_HOST_MAX) { lm_error_set(LM_ERR_URLHostLarge); goto end; } - if (!is_letter(buffer[index]) && !is_digit(buffer[index]) && buffer[index] != '.' && buffer[index] != ':' && buffer[index] != '/'){ + if (!is_letter(buffer[index]) && !is_digit(buffer[index]) && buffer[index] != '.' && buffer[index] != ':' && + buffer[index] != '/') { lm_error_set(LM_ERR_URLBadChar); goto end; } - if(buffer[index] != '/') + if (buffer[index] != '/') break; - if(index == 0){ + if (index == 0) { lm_error_set(LM_ERR_URLBadHost); goto end; } buffer[index] = 0; - url->host = malloc((index+1)*sizeof(char)); - memcpy(url->host, buffer, index+1); + url->host = malloc((index + 1) * sizeof(char)); + memcpy(url->host, buffer, index + 1); goto next; case URL_PATH_3: - if(index > URL_PATH_MAX){ + if (index > URL_PATH_MAX) { lm_error_set(LM_ERR_URLPathLarge); goto end; } - if (!is_letter(buffer[index]) && !is_digit(buffer[index]) && !contains(valid_path, buffer[index])){ + if (!is_letter(buffer[index]) && !is_digit(buffer[index]) && !contains(valid_path, buffer[index])) { lm_error_set(LM_ERR_URLBadChar); goto end; } @@ -145,59 +145,82 @@ bool lm_url_parse(lm_url_t *url, char *str){ continue; next: - bzero(buffer, strl+1); + bzero(buffer, strl + 1); state++; index = 0; pos++; } switch (state) { - case URL_HOST_2: - if(index == 0){ - lm_error_set(LM_ERR_URLBadHost); - goto end; - } - - if(index > URL_HOST_MAX){ - lm_error_set(LM_ERR_URLHostLarge); - goto end; - } - - url->host = malloc((index+1)*sizeof(char)); - memcpy(url->host, buffer, index+1); - - url->path = malloc(2*sizeof(char)); - url->path[0] = '/'; - url->path[1] = 0; - break; - - case URL_PATH_3: - url->path = malloc((index+2)*sizeof(char)); - url->path[0] = '/'; - memcpy(url->path+1, buffer, index+1); - break; - - default: - lm_error_set(LM_ERR_URLEnd); + case URL_HOST_2: + if (index == 0) { + lm_error_set(LM_ERR_URLBadHost); goto end; + } + + if (index > URL_HOST_MAX) { + lm_error_set(LM_ERR_URLHostLarge); + goto end; + } + + url->host = malloc((index + 1) * sizeof(char)); + memcpy(url->host, buffer, index + 1); + + url->path = malloc(2 * sizeof(char)); + url->path[0] = '/'; + url->path[1] = 0; + break; + + case URL_PATH_3: + url->path = malloc((index + 2) * sizeof(char)); + url->path[0] = '/'; + memcpy(url->path + 1, buffer, index + 1); + break; + + default: + lm_error_set(LM_ERR_URLEnd); + goto end; } - ret = true; + if (strtok_r(url->host, ":", &save) == NULL) { + lm_error_set(LM_ERR_URLBadHost); + goto end; + } + + char *portc = strtok_r(NULL, ":", &save); + if (NULL == portc) { + url->port = lm_url_default(url->protocol); + if (url->port == 0) { + lm_error_set(LM_ERR_URLPortUnknown); + goto end; + } + ret = true; + goto end; + } + + int port = atoi(portc); + if (port <= 0 || port > UINT16_MAX) { + lm_error_set(LM_ERR_URLBadPort); + goto end; + } + + url->port = port; + ret = true; end: - if(!ret && NULL != url->host) + if (!ret && NULL != url->host) free(url->host); - if(!ret && NULL != url->path) + if (!ret && NULL != url->path) free(url->path); return ret; } -void lm_url_free(lm_url_t *url){ - if(NULL != url->host) +void lm_url_free(lm_url_t *url) { + if (NULL != url->host) free(url->host); - if(NULL != url->path) + if (NULL != url->path) free(url->path); } diff --git a/src/util.c b/src/util.c index 4d92969..be99cd5 100644 --- a/src/util.c +++ b/src/util.c @@ -1,12 +1,12 @@ #include "../include/util.h" #include "../include/types.h" #include +#include #include #include -#include -void pdebug(lm_ctx_t *ctx, const char *func, const char *fmt, ...){ - if(!ctx->debug) +void pdebug(lm_ctx_t *ctx, const char *func, const char *fmt, ...) { + if (!ctx->debug) return; va_list args;