diff --git a/cthreads.c b/cthreads.c index cd370b2..8edd97c 100644 --- a/cthreads.c +++ b/cthreads.c @@ -6,8 +6,8 @@ typedef struct { } _thr_internal_t; #ifdef _WIN32 -#define VC_EXTRALEAN -#include +#include "win32_slim.h" +#include // == THREAD =========================================== diff --git a/cthreads.h b/cthreads.h index dbe5675..dbab431 100644 --- a/cthreads.h +++ b/cthreads.h @@ -37,6 +37,31 @@ bool mtxLock(cmutex_t ctx); bool mtxTryLock(cmutex_t ctx); bool mtxUnlock(cmutex_t ctx); +#ifdef __cplusplus +// small c++ class to make mutexes easier to use +struct lock_t { + inline lock_t(cmutex_t mutex) + : mutex(mutex) { + if (mtxValid(mutex)) { + mtxLock(mutex); + } + } + + inline ~lock_t() { + unlock(); + } + + inline void unlock() { + if (mtxValid(mutex)) { + mtxUnlock(mutex); + } + mutex = 0; + } + + cmutex_t mutex; +}; +#endif + #ifdef __cplusplus } // extern "C" #endif \ No newline at end of file diff --git a/dir.c b/dir.c index e2e8316..d1790d3 100644 --- a/dir.c +++ b/dir.c @@ -2,8 +2,7 @@ #include "tracelog.h" #ifdef _WIN32 -#define VC_EXTRALEAN -#include +#include "win32_slim.h" #include #include @@ -107,10 +106,10 @@ dir_entry_t *dirNext(dir_t ctx) { // taken from https://sites.uclouvain.be/SystInfo/usr/include/dirent.h.html // hopefully shouldn't be needed #ifndef DT_DIR -#define DT_DIR 4 + #define DT_DIR 4 #endif #ifndef DT_REG -#define DT_REG 8 + #define DT_REG 8 #endif typedef struct { @@ -134,7 +133,7 @@ void dirClose(dir_t ctx) { bool dirValid(dir_t ctx) { _dir_internal_t *dir = (_dir_internal_t*)ctx; - return dir->handle != NULL; + return dir->dir != NULL; } dir_entry_t *dirNext(dir_t ctx) { diff --git a/dirwatch.c b/dirwatch.c index d8392cf..93660a1 100644 --- a/dirwatch.c +++ b/dirwatch.c @@ -1,12 +1,12 @@ #include "dirwatch.h" #include +#include #include #include "tracelog.h" #ifdef _WIN32 -#define VC_EXTRALEAN -#include +#include "win32_slim.h" #include "str.h" typedef struct { @@ -177,8 +177,6 @@ void stopWatchDir(dirwatch_t *ctx, bool immediately) { #else #include -#include -#include // malloc #include // read #include #include diff --git a/file.c b/file.c index 4c97989..3a7cdd5 100644 --- a/file.c +++ b/file.c @@ -3,8 +3,8 @@ #include "tracelog.h" #ifdef _WIN32 -#define VC_EXTRALEAN -#include +#include "win32_slim.h" +#include static DWORD _toWin32Access(int mode) { if(mode & FILE_READ) return GENERIC_READ; @@ -209,7 +209,7 @@ fread_buf_t fileReadWholeFP(file_t *ctx) { str_t fileReadWholeText(const char *fname) { file_t fp = fileOpen(fname, FILE_READ); if(!fileIsValid(&fp)) { - err("couldn't open file %s -> %d", fname); + err("couldn't open file %s", fname); return strInit(); } str_t contents = fileReadWholeFPText(&fp); diff --git a/fs.c b/fs.c index 05225f2..5f6c075 100644 --- a/fs.c +++ b/fs.c @@ -8,8 +8,7 @@ #include "tracelog.h" #ifdef _WIN32 -#define VC_EXTRALEAN -#include +#include "win32_slim.h" #include diff --git a/http.c b/http.c index bebbd0d..a4809ce 100644 --- a/http.c +++ b/http.c @@ -85,7 +85,7 @@ void reqSetField(http_request_t *ctx, const char *key, const char *value) { } void reqSetUri(http_request_t *ctx, const char *uri) { - if(uri == NULL) return; + if (uri == NULL) return; size_t len = strlen(uri); if(uri[0] != '/') { len += 1; @@ -139,9 +139,7 @@ str_t reqString(http_request_t *ctx) { // == HTTP RESPONSE =========================================================== http_response_t resInit() { - http_response_t res; - memset(&res, 0, sizeof(res)); - return res; + return (http_response_t) {0}; } void resFree(http_response_t *ctx) { @@ -150,7 +148,7 @@ void resFree(http_response_t *ctx) { free(ctx->fields.buf[i].value); } field_vecFree(&ctx->fields); - free(ctx->body); + strFree(&ctx->body); memset(ctx, 0, sizeof(http_response_t)); } @@ -195,8 +193,8 @@ void resParse(http_response_t *ctx, const char *data) { const char *tran_encoding = resGetField(ctx, "transfer-encoding"); if(tran_encoding == NULL || stricmp(tran_encoding, "chunked") != 0) { strview_t body = istrGetviewLen(&in, 0, SIZE_MAX); - free(ctx->body); - ctx->body = strvCopy(body).buf; + strFree(&ctx->body); + ctx->body = strvCopy(body); } else { fatal("chunked encoding not implemented yet"); @@ -233,14 +231,13 @@ void resParseFields(http_response_t *ctx, str_istream_t *in) { // == HTTP CLIENT ============================================================= http_client_t hcliInit() { - http_client_t client; - memset(&client, 0, sizeof(client)); - client.port = 80; - return client; + return (http_client_t) { + .port = 80, + }; } void hcliFree(http_client_t *ctx) { - free(ctx->host_name); + strFree(&ctx->host_name); memset(ctx, 0, sizeof(http_client_t)); } @@ -248,7 +245,7 @@ void hcliSetHost(http_client_t *ctx, const char *hostname) { strview_t hostview = strvInit(hostname); // if the hostname starts with http:// (case insensitive) if(strvICompare(strvSubstr(hostview, 0, 7), strvInit("http://")) == 0) { - ctx->host_name = strvCopy(strvSubstr(hostview, 7, SIZE_MAX)).buf; + ctx->host_name = strvCopy(strvSubstr(hostview, 7, SIZE_MAX)); } else if(strvICompare(strvSubstr(hostview, 0, 8), strvInit("https://")) == 0) { err("HTTPS protocol not yet supported"); @@ -256,13 +253,16 @@ void hcliSetHost(http_client_t *ctx, const char *hostname) { } else { // undefined protocol, use HTTP - ctx->host_name = strvCopy(hostview).buf; + ctx->host_name = strvCopy(hostview); } } http_response_t hcliSendRequest(http_client_t *ctx, http_request_t *req) { + if (strBack(&ctx->host_name) == '/') { + strPop(&ctx->host_name); + } if(!reqHasField(req, "Host")) { - reqSetField(req, "Host", ctx->host_name); + reqSetField(req, "Host", ctx->host_name.buf); } if(!reqHasField(req, "Content-Length")) { if(req->body) { @@ -297,7 +297,7 @@ http_response_t hcliSendRequest(http_client_t *ctx, http_request_t *req) { goto error; } - if(skConnect(ctx->socket, ctx->host_name, ctx->port)) { + if(skConnect(ctx->socket, ctx->host_name.buf, ctx->port)) { req_str = reqString(req); if(req_str.len == 0) { err("couldn't get string from request"); @@ -328,6 +328,9 @@ http_response_t hcliSendRequest(http_client_t *ctx, http_request_t *req) { resParse(&res, received.buf); } + else { + err("Couldn't connect to host %s -> %s", ctx->host_name, skGetErrorString()); + } if(!skClose(ctx->socket)) { err("Couldn't close socket"); diff --git a/http.h b/http.h index 540510b..7c70deb 100644 --- a/http.h +++ b/http.h @@ -97,7 +97,7 @@ typedef struct { int status_code; field_vec_t fields; http_version_t version; - char *body; + str_t body; } http_response_t; http_response_t resInit(void); @@ -112,7 +112,7 @@ void resParseFields(http_response_t *ctx, str_istream_t *in); // == HTTP CLIENT ============================================================= typedef struct { - char *host_name; + str_t host_name; uint16_t port; socket_t socket; } http_client_t; diff --git a/os.c b/os.c index 095d513..64506d3 100644 --- a/os.c +++ b/os.c @@ -7,6 +7,8 @@ #ifdef _WIN32 #define _BUFSZ 128 +#include + // modified from netbsd source http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/pkgtools/libnbcompat/files/getdelim.c?only_with_tag=MAIN ssize_t getdelim(char **buf, size_t *bufsz, int delimiter, FILE *fp) { char *ptr, *eptr; @@ -64,4 +66,30 @@ ssize_t getdelim(char **buf, size_t *bufsz, int delimiter, FILE *fp) { ssize_t getline(char **line_ptr, size_t *n, FILE *stream) { return getdelim(line_ptr, n, '\n', stream); } + +str_t getUserName() { + char buf[UNLEN + 1]; + DWORD sz = sizeof(buf); + BOOL res = GetUserNameA(buf, &sz); + if(!res) { + return strInit(); + } + return strInitBuf(buf, sz); +} + +#else + +#include +#include +#include + +str_t getUserName() { + char buf[255]; + int res = getlogin_r(buf, sizeof(buf)); + if(res) { + return strInit(); + } + return strInitStr(buf); +} + #endif \ No newline at end of file diff --git a/os.h b/os.h index 3c94cb5..ddbbd11 100644 --- a/os.h +++ b/os.h @@ -6,21 +6,26 @@ extern "C" { #include #include +#include "str.h" #ifdef _WIN32 #include - #include // SSIZE_T + #include "win32_slim.h" typedef SSIZE_T ssize_t; ssize_t getdelim(char **buf, size_t *bufsz, int delimiter, FILE *fp); ssize_t getline(char **line_ptr, size_t *n, FILE *stream); #define stricmp _stricmp #else #define stricmp strcasecmp - #define _GNU_SOURCE + #ifndef _GNU_SOURCE + #define _GNU_SOURCE + #endif #include #include // ssize_t #endif +str_t getUserName(); + #ifdef __cplusplus } // extern "C" #endif \ No newline at end of file diff --git a/socket.c b/socket.c index c89bedd..91ebf2c 100644 --- a/socket.c +++ b/socket.c @@ -9,8 +9,6 @@ static int initialize_count = 0; #endif #if SOCK_WINDOWS -#include - static bool _win_skInit(); static bool _win_skCleanup(); static int _win_skGetError(); @@ -113,7 +111,7 @@ bool skBind(socket_t sock, const char *ip, uint16_t port) { return skBindPro(sock, (sk_addr_t *) &addr, sizeof(addr)); } -bool skBindPro(socket_t sock, const sk_addr_t *name, socket_len_t namelen) { +bool skBindPro(socket_t sock, const sk_addr_t *name, sk_len_t namelen) { return bind(sock, name, namelen) != SOCKET_ERROR; } @@ -127,11 +125,11 @@ bool skListenPro(socket_t sock, int backlog) { socket_t skAccept(socket_t sock) { sk_addrin_t addr; - socket_len_t addr_size = (socket_len_t)sizeof(addr); + sk_len_t addr_size = (sk_len_t)sizeof(addr); return skAcceptPro(sock, (sk_addr_t *) &addr, &addr_size); } -socket_t skAcceptPro(socket_t sock, sk_addr_t *addr, socket_len_t *addrlen) { +socket_t skAcceptPro(socket_t sock, sk_addr_t *addr, sk_len_t *addrlen) { return accept(sock, addr, addrlen); } @@ -152,40 +150,40 @@ bool skConnect(socket_t sock, const char *server, unsigned short server_port) { return skConnectPro(sock, (sk_addr_t *) &addr, sizeof(addr)); } -bool skConnectPro(socket_t sock, const sk_addr_t *name, socket_len_t namelen) { +bool skConnectPro(socket_t sock, const sk_addr_t *name, sk_len_t namelen) { return connect(sock, name, namelen) != SOCKET_ERROR; } -int skSend(socket_t sock, const char *buf, int len) { +int skSend(socket_t sock, const void *buf, int len) { return skSendPro(sock, buf, len, 0); } -int skSendPro(socket_t sock, const char *buf, int len, int flags) { +int skSendPro(socket_t sock, const void *buf, int len, int flags) { return send(sock, buf, len, flags); } -int skSendTo(socket_t sock, const char *buf, int len, const sk_addrin_t *to) { +int skSendTo(socket_t sock, const void *buf, int len, const sk_addrin_t *to) { return skSendToPro(sock, buf, len, 0, (sk_addr_t*) to, sizeof(sk_addrin_t)); } -int skSendToPro(socket_t sock, const char *buf, int len, int flags, const sk_addr_t *to, int tolen) { +int skSendToPro(socket_t sock, const void *buf, int len, int flags, const sk_addr_t *to, int tolen) { return sendto(sock, buf, len, flags, to, tolen); } -int skReceive(socket_t sock, char *buf, int len) { +int skReceive(socket_t sock, void *buf, int len) { return skReceivePro(sock, buf, len, 0); } -int skReceivePro(socket_t sock, char *buf, int len, int flags) { +int skReceivePro(socket_t sock, void *buf, int len, int flags) { return recv(sock, buf, len, flags); } -int skReceiveFrom(socket_t sock, char *buf, int len, sk_addrin_t *from) { - socket_len_t fromlen = sizeof(sk_addr_t); +int skReceiveFrom(socket_t sock, void *buf, int len, sk_addrin_t *from) { + sk_len_t fromlen = sizeof(sk_addr_t); return skReceiveFromPro(sock, buf, len, 0, (sk_addr_t*)from, &fromlen); } -int skReceiveFromPro(socket_t sock, char *buf, int len, int flags, sk_addr_t *from, socket_len_t *fromlen) { +int skReceiveFromPro(socket_t sock, void *buf, int len, int flags, sk_addr_t *from, sk_len_t *fromlen) { return recvfrom(sock, buf, len, flags, from, fromlen); } diff --git a/socket.h b/socket.h index 52a345f..f446070 100644 --- a/socket.h +++ b/socket.h @@ -15,15 +15,17 @@ extern "C" { #if SOCK_WINDOWS #pragma warning(disable:4996) // _WINSOCK_DEPRECATED_NO_WARNINGS + #include "win32_slim.h" #include + #include typedef SOCKET socket_t; - typedef int socket_len_t; + typedef int sk_len_t; #elif SOCK_POSIX #include #include #include typedef int socket_t; - typedef uint32_t socket_len_t; + typedef uint32_t sk_len_t; #define INVALID_SOCKET (-1) #define SOCKET_ERROR (-1) #endif @@ -61,7 +63,7 @@ bool skClose(socket_t sock); // Associate a local address with a socket bool skBind(socket_t sock, const char *ip, uint16_t port); // Associate a local address with a socket -bool skBindPro(socket_t sock, const sk_addr_t *name, socket_len_t namelen); +bool skBindPro(socket_t sock, const sk_addr_t *name, sk_len_t namelen); // Place a socket in a state in which it is listening for an incoming connection bool skListen(socket_t sock); @@ -71,29 +73,29 @@ bool skListenPro(socket_t sock, int backlog); // Permits an incoming connection attempt on a socket socket_t skAccept(socket_t sock); // Permits an incoming connection attempt on a socket -socket_t skAcceptPro(socket_t sock, sk_addr_t *addr, socket_len_t *addrlen); +socket_t skAcceptPro(socket_t sock, sk_addr_t *addr, sk_len_t *addrlen); // Connects to a server (e.g. "127.0.0.1" or "google.com") with a port(e.g. 1234), returns true on success bool skConnect(socket_t sock, const char *server, unsigned short server_port); // Connects to a server, returns true on success -bool skConnectPro(socket_t sock, const sk_addr_t *name, socket_len_t namelen); +bool skConnectPro(socket_t sock, const sk_addr_t *name, sk_len_t namelen); // Sends data on a socket, returns true on success -int skSend(socket_t sock, const char *buf, int len); +int skSend(socket_t sock, const void *buf, int len); // Sends data on a socket, returns true on success -int skSendPro(socket_t sock, const char *buf, int len, int flags); +int skSendPro(socket_t sock, const void *buf, int len, int flags); // Sends data to a specific destination -int skSendTo(socket_t sock, const char *buf, int len, const sk_addrin_t *to); +int skSendTo(socket_t sock, const void *buf, int len, const sk_addrin_t *to); // Sends data to a specific destination -int skSendToPro(socket_t sock, const char *buf, int len, int flags, const sk_addr_t *to, int tolen); +int skSendToPro(socket_t sock, const void *buf, int len, int flags, const sk_addr_t *to, int tolen); // Receives data from a socket, returns byte count on success, 0 on connection close or -1 on error -int skReceive(socket_t sock, char *buf, int len); +int skReceive(socket_t sock, void *buf, int len); // Receives data from a socket, returns byte count on success, 0 on connection close or -1 on error -int skReceivePro(socket_t sock, char *buf, int len, int flags); +int skReceivePro(socket_t sock, void *buf, int len, int flags); // Receives a datagram and stores the source address. -int skReceiveFrom(socket_t sock, char *buf, int len, sk_addrin_t *from); +int skReceiveFrom(socket_t sock, void *buf, int len, sk_addrin_t *from); // Receives a datagram and stores the source address. -int skReceiveFromPro(socket_t sock, char *buf, int len, int flags, sk_addr_t *from, socket_len_t *fromlen); +int skReceiveFromPro(socket_t sock, void *buf, int len, int flags, sk_addr_t *from, sk_len_t *fromlen); // Checks that a opened socket is valid, returns true on success bool skIsValid(socket_t sock); diff --git a/str.c b/str.c index 87383ee..86edc89 100644 --- a/str.c +++ b/str.c @@ -10,8 +10,7 @@ #include "tracelog.h" #ifdef _WIN32 -#define VC_EXTRALEAN -#include +#include "win32_slim.h" #else #include #endif diff --git a/str.h b/str.h index 1950b72..e2db604 100644 --- a/str.h +++ b/str.h @@ -2,6 +2,7 @@ #ifdef __cplusplus extern "C" { +#include #endif #include @@ -9,13 +10,17 @@ extern "C" { #include #include #include -// #include "strview.h" #define STRV_NOT_FOUND SIZE_MAX -typedef struct { +typedef struct str_t { char *buf; size_t len; +#ifdef __cplusplus + inline operator std::string() const { + return std::string(buf, len); + } +#endif } str_t; typedef struct { diff --git a/tracelog.c b/tracelog.c index 156adac..f93a367 100644 --- a/tracelog.c +++ b/tracelog.c @@ -14,8 +14,7 @@ #define TLOG_NO_COLOURS #endif - #define VC_EXTRALEAN - #include + #include "win32_slim.h" #else #error "can't use TLOG_VS if not on windows" #endif diff --git a/win32_slim.h b/win32_slim.h new file mode 100644 index 0000000..7e80944 --- /dev/null +++ b/win32_slim.h @@ -0,0 +1,57 @@ +#pragma once + +#ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN +#endif + +#ifndef WIN32_EXTRA_LEAN + #define WIN32_EXTRA_LEAN +#endif + +#define NOIME +#define NOWINRES +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINMESSAGES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define OEMRESOURCE +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NOCTLMGR +#define NODRAWTEXT +#define NOGDI +#define NOUSER +#define NOMB +#define NOMEMMGR +#define NOMETAFILE +#define NOMINMAX +#define NOMSG +#define NOOPENFILE +#define NOSCROLL +#define NOSERVICE +#define NOSOUND +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOIME +#define NOPROXYSTUB +#define NOIMAGE +#define NO +#define NOTAPE +#define ANSI_ONLY + +#include \ No newline at end of file