From c50ed2b2335b320138a718fc3a3e1bac4864f8d3 Mon Sep 17 00:00:00 2001 From: Mid <> Date: Mon, 6 Jan 2025 11:10:48 +0200 Subject: [PATCH] Attempt windows support (doesn't work) --- Makefile | 8 +- cb64.h | 227 ------------------------------------------------------- main2.c | 69 +++++++++++++---- 3 files changed, 61 insertions(+), 243 deletions(-) delete mode 100644 cb64.h diff --git a/Makefile b/Makefile index c184a7e..821df8f 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,12 @@ EMSCR := $(shell command -v emcmake 2> /dev/null) LLVM_AR := $(shell command -v llvm-ar 2> /dev/null) +SYS := $(shell $(CC) -dumpmachine) + +ifneq (,$(findstring mingw,$(SYS))) +wsrALDFLAGS := -lws2_32 +endif + emscr: ifndef EMSCR $(error "Emscripten is not in PATH.") @@ -27,7 +33,7 @@ FFmpeg/libswscale/libswscale.a: emscr llvm-ar d FFmpeg/libavcodec/libavcodec.a reverse.o wsrA: main2.c - cc -s -O3 -D_GNU_SOURCE -o wsrA main2.c picohttpparser.c + $(CC) -s -O3 -D_GNU_SOURCE -D_WIN32_WINNT=0x600 -o wsrA main2.c picohttpparser.c base64.c $(wsrALDFLAGS) support.js: emscr ogg/libogg.a vorbis/lib/libvorbis.a FFmpeg/libswscale/libswscale.a emcc -o support -fPIC -flto -IFFmpeg -Iogg/include -Ivorbis/include -LFFmpeg/libavcodec -l:libavcodec.a -LFFmpeg/libswscale -l:libswscale.a -LFFmpeg/libavutil -l:libavutil.a -Lvorbis/lib -l:libvorbis.a -Logg -l:libogg.a support.c -pthread -msimd128 -O3 -sMAYBE_WASM2JS -sUSE_PTHREADS=1 -sEXPORT_ALL=1 -sMAIN_MODULE=1 -sTOTAL_MEMORY=128MB diff --git a/cb64.h b/cb64.h deleted file mode 100644 index 54b48c6..0000000 --- a/cb64.h +++ /dev/null @@ -1,227 +0,0 @@ -#ifndef HEADER_CB64_H -#define HEADER_CB64_H - -#include -#include -#include -#include - -#define TRUE 1 -#define FALSE 0 - -#define B64_TABLE_SIZE 64 - -#define B64_ENCODE_OK 0 -#define B64_ENCODE_FAIL -1 -#define B64_DECODE_OK 0 -#define B64_DECODE_FAIL -1 - -struct base64_table_dict -{ - char key; - uint8_t val; -} b64_dict_t; - -static struct base64_table_dict dict[B64_TABLE_SIZE]; - -static const uint8_t BASE_64_TABLE[B64_TABLE_SIZE] = { - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, - 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, - 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, - 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F -}; - -static const uint8_t PADDING = 0x3D; -static const uint8_t SIX_BIT_MASK = 0x3F; // 63 // 111111 -static const uint8_t EIGHT_BIT_MASK = 0xFF; // 255 // 11111111 - -static void init_b64_table_dict() -{ - for (int i = 0; i < B64_TABLE_SIZE; i++) - { - b64_dict_t.key = BASE_64_TABLE[i]; - b64_dict_t.val = i; - dict[i] = b64_dict_t; - } -} - -static struct base64_table_dict base64_table_dict_find(char key) -{ - for (int i = 0; i < B64_TABLE_SIZE; i++) - { - if (dict[i].key == key) - return dict[i]; - } - return b64_dict_t; -} - -static uint64_t size_char_ptr(const unsigned char* arr) -{ - uint64_t size = 0; - - while(*arr) - { - size++; - arr++; - } - - return size; -} - -int encode_b64(const unsigned char* src, size_t src_size, - unsigned char** dst, size_t* dst_size) -{ - if (src_size == 0) - src_size = size_char_ptr(src); - - uint32_t _dst_size = 4 * ((src_size + 2) / 3); - - // caller should call free() - unsigned char* _dst = (unsigned char*) malloc(sizeof(*_dst) * _dst_size + 3); - if (_dst == NULL) - return B64_ENCODE_FAIL; - - FILE* f = fmemopen((void*)src, src_size, "r"); - FILE* base64_res_f = fmemopen((void*)_dst, sizeof(*_dst) * _dst_size + 3, "w"); - - unsigned char buffer[4]; - uint32_t size_out = 0; - uint32_t total_read = 0; - - while(TRUE) - { - // read data per 3 bytes to buffer - size_t r = fread(buffer, 1, 3, f); - - // check if the entire buffer has been read - if (r <= 0 || total_read == src_size) - break; - - total_read += r; - - // terminate the buffer with '\0' - buffer[r] = '\0'; - - uint32_t segment_count = 0; - uint32_t dec = 0; - for (int i = 0; i < r; i++) - { - // if (buffer[i] == '\0') - // continue; - - uint32_t l_shift = 16 - segment_count * 8; - uint32_t s = (uint32_t) buffer[i]; - dec |= s << l_shift; - segment_count = segment_count + 1; - } - - for (int i = 0; i < segment_count+1; i++) - { - uint32_t r_shift = 18 - i * 6; - uint8_t idx_b = (uint8_t) (dec >> r_shift) & SIX_BIT_MASK; - - uint8_t c_b64 = BASE_64_TABLE[idx_b]; - - fputc(c_b64, base64_res_f); - size_out = size_out + 1; - } - if (segment_count == 2) - { - fputc(PADDING, base64_res_f); - size_out = size_out + 2; - } - if (segment_count == 1) - { - fputc(PADDING, base64_res_f); - fputc(PADDING, base64_res_f); - size_out = size_out + 3; - } - - } - // terminate the buffer with '\0' - _dst[size_out] = '\0'; - *dst = _dst; - *dst_size = size_out; - - fclose(f); - fclose(base64_res_f); - - return B64_ENCODE_OK; -} - -int decode_b64(const unsigned char* src, size_t src_size, - unsigned char** dst, size_t* dst_size) -{ - init_b64_table_dict(); - if (src_size == 0) - src_size = size_char_ptr(src); - - uint32_t _dst_size = src_size / 4 * 3; - - // caller should call free() - unsigned char* _dst = (unsigned char*) malloc(sizeof(*_dst) * _dst_size + 1); - if (_dst == NULL) - return B64_DECODE_FAIL; - - FILE* base64_in_f = fmemopen((void*)src, src_size, "r"); - FILE* text_f = fmemopen((void*)_dst, sizeof(*_dst) * _dst_size + 1, "w"); - - unsigned char buffer[5]; - uint32_t size_out = 0; - uint32_t total_read = 0; - - while (TRUE) - { - // read data per 4 bytes to buffer - size_t r = fread(buffer, 1, 4, base64_in_f); - - // check if the entire buffer has been read - if (r <= 0 || total_read == src_size) - break; - - total_read += r; - - // terminate the buffer with '\0' - buffer[r] = '\0'; - - uint32_t segment_count = 0; - uint32_t dec = 0; - for (int i = 0; i < 4; i++) - { - if (buffer[i] == '\0' || buffer[i] == PADDING) - continue; - - struct base64_table_dict b64_idx_dict = base64_table_dict_find(buffer[i]); - uint32_t l_shift = 18 - segment_count * 6; - uint32_t b64_idx = (uint32_t) b64_idx_dict.val; - dec |= b64_idx << l_shift; - segment_count = segment_count + 1; - } - - for (int i = 0; i < segment_count-1; i++) - { - uint32_t r_shift = 16 - i * 8; - uint8_t c_b255 = (uint8_t) (dec >> r_shift) & EIGHT_BIT_MASK; - - fputc(c_b255, text_f); - size_out = size_out + 1; - } - - } - - // terminate the buffer with '\0' - _dst[size_out] = '\0'; - *dst = _dst; - *dst_size = size_out; - - fclose(base64_in_f); - fclose(text_f); - - return B64_DECODE_OK; -} - -#endif diff --git a/main2.c b/main2.c index ad637d0..98ec389 100644 --- a/main2.c +++ b/main2.c @@ -1,3 +1,8 @@ +#ifdef _WIN32 +#include +#include +#include"wepoll.c" +#else #include #include #include @@ -5,6 +10,7 @@ #include #include #include +#endif #include #include @@ -14,13 +20,31 @@ #include #include"picohttpparser.h" +#include"base64.h" #include"teeny-sha1.c" -#include"cb64.h" - -#define EPOLL_EVS 2048 +#ifdef _WIN32 +typedef HANDLE EPoll; +typedef int Socket; +void *memmem(const void *haystack, size_t haystack_len, const void * const needle, const size_t needle_len) { + if(haystack == NULL) return NULL; + if(haystack_len == 0) return NULL; + if(needle == NULL) return NULL; + if(needle_len == 0) return NULL; + + for(const char *h = haystack; haystack_len >= needle_len; ++h, --haystack_len) { + if(!memcmp(h, needle, needle_len)) { + return (void*) h; + } + } + + return NULL; +} +#else typedef int EPoll; typedef int Socket; +#define closesocket close +#endif typedef enum ClientType { UNKNOWN, @@ -193,7 +217,6 @@ static void stream_step(const uint8_t *newbuf, size_t newsz) { } static void receive_ws(Client *cli) { - } static int handle(Client *cli) { @@ -238,7 +261,9 @@ static int handle(Client *cli) { char sha1hex[41]; sha1digest(sha1bin, sha1hex, acceptbuf, acceptbufsz); - encode_b64(sha1bin, sizeof(sha1bin), &wsAccept, &wsAcceptLen); + wsAcceptLen = BASE64_ENCODE_OUT_SIZE(sizeof(sha1bin)); + wsAccept = malloc(wsAcceptLen); + base64_encode(sha1bin, sizeof(sha1bin), wsAccept); } } @@ -266,11 +291,12 @@ static int handle(Client *cli) { transmit(cli, buf, bufnum); + printf("New WS client\n"); + if(Stream.state == STREAMING && Stream.mkvHeader) { + printf("Sending header\n"); ws_send(cli, Stream.mkvHeader, Stream.mkvHeaderSz); } - - printf("New WS client\n"); } consume(cli, pret); @@ -393,9 +419,6 @@ static bool get_arg_bool(const char *key) { int main(int argc, char **argv) { Argc = argc, Argv = argv; - ServSock = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0); - EP = epoll_create1(0); - const char *streamkey = get_arg("key", NULL); if(!streamkey) { puts("Missing stream key parameter key=..."); @@ -406,13 +429,23 @@ int main(int argc, char **argv) { strcat(ValidStreamPath, "/push/"); strcat(ValidStreamPath, streamkey); + #ifdef _WIN32 + WSAStartup(MAKEWORD(2, 2), &(WSADATA) {}); + + ServSock = socket(AF_INET6, SOCK_STREAM, 0); + ioctlsocket(ServSock, FIONBIO, &(u_long) {1}); + #else + ServSock = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0); + #endif + EP = epoll_create1(0); + + assert(ServSock != -1); + if(get_arg_bool("reuseaddr")) { setsockopt(ServSock, SOL_SOCKET, SO_REUSEADDR, &(int) {1}, sizeof(int)); } setsockopt(ServSock, IPPROTO_IPV6, IPV6_V6ONLY, &(int) {0}, sizeof(int)); - assert(ServSock != -1); - struct addrinfo *res = NULL; assert(getaddrinfo(NULL, get_arg("port", "25404"), &(struct addrinfo) {.ai_flags = AI_PASSIVE, .ai_family = AF_INET6}, &res) == 0); @@ -428,8 +461,10 @@ int main(int argc, char **argv) { #define BUFSZ 8192 char buf[BUFSZ]; + #define EPOLL_EVS 2048 struct epoll_event events[EPOLL_EVS]; int nfds = epoll_wait(EP, events, EPOLL_EVS, -1); + for(int i = 0; i < nfds; i++) { if(events[i].data.fd == ServSock) { struct sockaddr_storage addr; @@ -437,10 +472,14 @@ int main(int argc, char **argv) { Socket clisock = accept(ServSock, (struct sockaddr*) &addr, &addrlen); + #ifdef _WIN32 + ioctlsocket(clisock, FIONBIO, &(u_long) {1}); + #else if(fcntl(clisock, F_SETFL, fcntl(clisock, F_GETFL, 0) | O_NONBLOCK) == -1) { - close(clisock); + closesocket(clisock); continue; } + #endif Client *cli = calloc(1, sizeof(*cli)); cli->fd = clisock; @@ -460,7 +499,7 @@ int main(int argc, char **argv) { while(1) { ssize_t readcount = recv(cli->fd, buf, sizeof(buf), 0); - if(readcount < 0) { + if(readcount <= 0) { if(errno != EAGAIN && errno != EWOULDBLOCK) { forceclose = true; } @@ -484,7 +523,7 @@ int main(int argc, char **argv) { if(forceclose || (events[i].events & (EPOLLRDHUP | EPOLLHUP))) { epoll_ctl(EP, EPOLL_CTL_DEL, cli->fd, NULL); - close(cli->fd); + closesocket(cli->fd); rem_cli(cli);