# HG changeset patch # User Matti Hamalainen # Date 1401165080 -10800 # Node ID bb6b07b448001cefee3273e1ea353aaaa49aa67a # Parent 29b8ff5b625bef35cbf60ecb9165fb20665cd970 Network code is being generalized into a th-libs module. diff -r 29b8ff5b625b -r bb6b07b44800 Makefile.gen --- a/Makefile.gen Tue May 27 07:27:14 2014 +0300 +++ b/Makefile.gen Tue May 27 07:31:20 2014 +0300 @@ -15,7 +15,7 @@ # Objects # THLIBS_A=$(OBJPATH)thlibs.a -THLIBS_OBJ=th_util.o th_string.o th_args.o th_ioctx.o th_config.o +THLIBS_OBJ=th_util.o th_string.o th_args.o th_ioctx.o th_config.o th_network.o NNCHAT_OBJ=main.o util.o network.o ui.o NNCHAT_BIN=$(BINPATH)nnchat$(EXEEXT) diff -r 29b8ff5b625b -r bb6b07b44800 main.c --- a/main.c Tue May 27 07:27:14 2014 +0300 +++ b/main.c Tue May 27 07:31:20 2014 +0300 @@ -3,11 +3,11 @@ * Written by Matti 'ccr' Hämäläinen * (C) Copyright 2008-2014 Tecnic Software productions (TNSP) */ -#include "util.h" -#include "network.h" -#include "ui.h" #include "th_args.h" #include "th_config.h" +#include "th_network.h" +#include "util.h" +#include "ui.h" #include #include #ifdef __WIN32 @@ -350,6 +350,42 @@ } +BOOL nn_conn_send_msg(th_conn_t *conn, const char *user, const char *str) +{ + char *msg; + + if (str == NULL) + return FALSE; + + msg = th_strdup_printf("%s%s", user, str); + + if (msg != NULL) + { + BOOL ret = nn_conn_send_buf(conn, msg, strlen(msg) + 1); + th_free(msg); + return ret; + } + else + return FALSE; +} + + +BOOL nn_conn_send_msg_v(th_conn_t *conn, const char *user, const char *fmt, ...) +{ + BOOL res; + char *tmp; + va_list ap; + + va_start(ap, fmt); + tmp = th_strdup_vprintf(fmt, ap); + va_end(ap); + + res = nn_conn_send_msg(conn, user, tmp); + th_free(tmp); + return res; +} + + int printFile(FILE *outFile, const char *fmt) { const char *s = fmt; @@ -530,14 +566,14 @@ } -void nn_network_errfunc(struct _nn_conn_t *conn, const char *msg) +void nn_network_errfunc(struct _th_conn_t *conn, const char *msg) { (void) conn; errorMsg("%s", msg); } -void nn_network_msgfunc(struct _nn_conn_t *conn, const char *msg) +void nn_network_msgfunc(struct _th_conn_t *conn, const char *msg) { (void) conn; printMsgConst(NULL, LOG_STAMP | LOG_WINDOW | LOG_FILE, msg); @@ -573,23 +609,23 @@ } -int nnproto_parse_user(nn_conn_t *conn) +int nnproto_parse_user(th_conn_t *conn) { BOOL isMine, isIgnored = FALSE; char *name, *msg, *t; // Find start of the message name = conn->ptr; - t = nn_conn_buf_strstr(conn, ""); + t = th_conn_buf_strstr(conn, ""); if (!t) return 1; *t = 0; // Find end of the message - t = nn_conn_buf_strstr(conn, ""); + t = th_conn_buf_strstr(conn, ""); if (!t) return 2; msg = conn->ptr; - t = nn_conn_buf_strstr(conn, ""); + t = th_conn_buf_strstr(conn, ""); if (!t) return 3; *t = 0; @@ -715,22 +751,22 @@ } -int nnproto_parse_login(nn_conn_t *conn) +int nnproto_parse_login(th_conn_t *conn) { char tmpStr[256]; str_get_timestamp(tmpStr, sizeof(tmpStr), "%c"); - if (!nn_conn_buf_strcmp(conn, "FAILURE>")) + if (!th_conn_buf_strcmp(conn, "FAILURE>")) { - nn_conn_buf_strstr(conn, ""); - nn_conn_buf_strstr(conn, ""); + th_conn_buf_strstr(conn, ""); + th_conn_buf_strstr(conn, ""); printMsg(NULL, "½1½Login failure½0½ - ½3½%s½0½\n", tmpStr); return -2; } - else if (!nn_conn_buf_strcmp(conn, "SUCCESS>")) + else if (!th_conn_buf_strcmp(conn, "SUCCESS>")) { - nn_conn_buf_strstr(conn, ""); - nn_conn_buf_strstr(conn, ""); + th_conn_buf_strstr(conn, ""); + th_conn_buf_strstr(conn, ""); printMsg(NULL, "½2½Login success½0½ - ½3½%s½0½\n", tmpStr); nn_conn_send_msg(conn, optUserNameEnc, "%2FRequestUserList"); return 0; @@ -740,12 +776,12 @@ } -int nnproto_parse_add_user(nn_conn_t *conn) +int nnproto_parse_add_user(th_conn_t *conn) { char *p, *s, *str = conn->ptr; nn_window_t *win; - s = nn_conn_buf_strstr(conn, ""); + s = th_conn_buf_strstr(conn, ""); if (!s) return 1; *s = 0; @@ -768,12 +804,12 @@ } -int nnproto_parse_delete_user(nn_conn_t *conn) +int nnproto_parse_delete_user(th_conn_t *conn) { char *p, *s, *str = conn->ptr; nn_window_t *win; - s = nn_conn_buf_strstr(conn, ""); + s = th_conn_buf_strstr(conn, ""); if (!s) return 1; *s = 0; @@ -796,14 +832,14 @@ } -int nnproto_parse_num_clients(nn_conn_t *conn) +int nnproto_parse_num_clients(th_conn_t *conn) { - nn_conn_buf_strstr(conn, ""); + th_conn_buf_strstr(conn, ""); return 0; } -int nnproto_parse_boot(nn_conn_t *conn) +int nnproto_parse_boot(th_conn_t *conn) { (void) conn; errorMsg("Booted by server.\n"); @@ -815,7 +851,7 @@ { char *name; size_t len; - int (*handler)(nn_conn_t *); + int (*handler)(th_conn_t *); } nn_protocolcmd_t; @@ -832,7 +868,7 @@ static const int nprotoCmds = sizeof(protoCmds) / sizeof(protoCmds[0]); -int nn_parse_protocol(nn_conn_t *conn) +int nn_parse_protocol(th_conn_t *conn) { static BOOL protoCmdsInit = FALSE; int i; @@ -847,7 +883,7 @@ for (i = 0; i < nprotoCmds; i++) { - if (!nn_conn_buf_strncmp(conn, protoCmds[i].name, protoCmds[i].len)) + if (!th_conn_buf_strncmp(conn, protoCmds[i].name, protoCmds[i].len)) return protoCmds[i].handler(conn); } @@ -905,7 +941,7 @@ } -int nncmd_send_raw(nn_conn_t *conn, char *str) +int nncmd_send_raw(th_conn_t *conn, char *str) { #if 1 char *tmp = nn_encode_str1(str); @@ -920,7 +956,7 @@ } -int nncmd_open_profile(nn_conn_t *conn, char *name) +int nncmd_open_profile(th_conn_t *conn, char *name) { char *enc_name = nn_encode_str1(name); char *uri = th_strdup_printf(SET_PROFILE_PREFIX, name); @@ -936,7 +972,7 @@ } -int nncmd_change_list(nn_conn_t *conn, const char *listname, qlist_t **list, const char *name) +int nncmd_change_list(th_conn_t *conn, const char *listname, qlist_t **list, const char *name) { (void) conn; @@ -979,19 +1015,19 @@ } -int nncmd_ignore(nn_conn_t *conn, char *name) +int nncmd_ignore(th_conn_t *conn, char *name) { return nncmd_change_list(conn, "ignore", &setIgnoreList, name); } -int nncmd_friend(nn_conn_t *conn, char *name) +int nncmd_friend(th_conn_t *conn, char *name) { return nncmd_change_list(conn, "friend", &setFriendList, name); } -int nncmd_set_color(nn_conn_t *conn, char *arg) +int nncmd_set_color(th_conn_t *conn, char *arg) { int val; (void) conn; @@ -1009,7 +1045,7 @@ } -int nncmd_open_query(nn_conn_t *conn, char *name) +int nncmd_open_query(th_conn_t *conn, char *name) { (void) conn; @@ -1042,7 +1078,7 @@ } -int nncmd_close_query(nn_conn_t *conn, char *name) +int nncmd_close_query(th_conn_t *conn, char *name) { (void) conn; @@ -1078,7 +1114,7 @@ } -int nncmd_window_info(nn_conn_t *conn, char *arg) +int nncmd_window_info(th_conn_t *conn, char *arg) { (void) conn; @@ -1103,7 +1139,7 @@ } -int nncmd_list_all_users(nn_conn_t *conn, char *buf) +int nncmd_list_all_users(th_conn_t *conn, char *buf) { (void) buf; @@ -1131,10 +1167,10 @@ size_t len; int color; - if (checkNameList(setFriendList, user->name)) + if (nn_check_name_list(setFriendList, user->name)) color = 11; else - if (checkNameList(setIgnoreList, user->name)) + if (nn_check_name_list(setIgnoreList, user->name)) color = 1; else color = 3; @@ -1158,7 +1194,7 @@ } -int nncmd_names(nn_conn_t *conn, char *arg) +int nncmd_names(th_conn_t *conn, char *arg) { nncmd_namedata_t data; (void) conn; @@ -1180,7 +1216,7 @@ } -int nncmd_save_config(nn_conn_t *conn, char *buf) +int nncmd_save_config(th_conn_t *conn, char *buf) { (void) conn; (void) buf; @@ -1217,7 +1253,7 @@ } -int nncmd_quit(nn_conn_t *conn, char *buf) +int nncmd_quit(th_conn_t *conn, char *buf) { (void) conn; (void) buf; @@ -1240,7 +1276,7 @@ char *name; int flags; size_t len; - int (*handler)(nn_conn_t *, char *buf); + int (*handler)(th_conn_t *, char *buf); } nn_usercmd_t; @@ -1289,7 +1325,7 @@ } -int nn_handle_command(nn_conn_t *conn, char *buf) +int nn_handle_command(th_conn_t *conn, char *buf) { qlist_t *curr; @@ -1398,7 +1434,7 @@ } -int nn_handle_input(nn_conn_t *conn, char *buf, size_t bufLen) +int nn_handle_input(th_conn_t *conn, char *buf, size_t bufLen) { BOOL result; char *tmp; @@ -1936,7 +1972,7 @@ char *tmpStr; int index, updateCount = 0; BOOL argsOK, colorSet = FALSE; - nn_conn_t *conn = NULL; + th_conn_t *conn = NULL; nn_editbuf_t *editBuf = nn_editbuf_new(NN_TMPBUF_SIZE); nn_editstate_t editState; th_cfgitem_t *tmpcfg; @@ -2170,7 +2206,7 @@ } // Create a connection - conn = nn_conn_new(nn_network_errfunc, nn_network_msgfunc); + conn = th_conn_new(nn_network_errfunc, nn_network_msgfunc); if (conn == NULL) { errorMsg("Could not create connection structure.\n"); @@ -2185,8 +2221,8 @@ if (optProxyUserID == NULL) optProxyUserID = "James Bond"; - if (nn_conn_set_proxy(conn, optProxyType, optProxyPort, optProxyServer, optProxyAuthType) != 0 || - nn_conn_set_proxy_auth_user(conn, optProxyUserID, optProxyPassword) != 0) + if (th_conn_set_proxy(conn, optProxyType, optProxyPort, optProxyServer, optProxyAuthType) != 0 || + th_conn_set_proxy_auth_user(conn, optProxyUserID, optProxyPassword) != 0) { errorMsg("Error setting proxy information.\n"); goto err_exit; @@ -2203,21 +2239,21 @@ /* To emulate the official client, we first make a request for * policy file, even though we don't use it for anything... */ - if (nn_conn_open(conn, 843, NULL) != 0) + if (th_conn_open(conn, 843, NULL) != 0) { errorMsg("Policy file request connection setup failed!\n"); goto err_exit; } tmpStr = ""; - if (nn_conn_send_buf(conn, tmpStr, strlen(tmpStr) + 1) == FALSE) + if (th_conn_send_buf(conn, tmpStr, strlen(tmpStr) + 1) == FALSE) { errorMsg("Failed to send policy file request.\n"); goto err_exit; } else { - int cres = nn_conn_pull(conn); + int cres = th_conn_pull(conn); if (cres == 0) { printMsg(currWin, "Probe got: %s\n", conn->buf); @@ -2227,11 +2263,11 @@ printMsg(currWin, "Could not get policy probe.\n"); } } - nn_conn_free(conn); + th_conn_free(conn); #endif // Okay, now do the proper connection ... - if (nn_conn_open(conn, optPort, NULL) != 0) + if (th_conn_open(conn, optPort, NULL) != 0) { errorMsg("Main connection setup failed!\n"); goto err_exit; @@ -2251,25 +2287,25 @@ srandom((int) editState.prevKeepAlive); // Enter mainloop - nn_conn_reset(conn); + th_conn_reset(conn); while (!editState.isError && !appQuitFlag) { int retries = 3, cres; editState.update = FALSE; packet_retry: - cres = nn_conn_pull(conn); + cres = th_conn_pull(conn); if (cres == 0) { while (conn->ptr < conn->in_ptr && *(conn->in_ptr - 1) == 0 && retries > 0 && !editState.isError) { -// nn_conn_dump_buffer(stderr, conn); +// th_conn_dump_buffer(stderr, conn); int result = nn_parse_protocol(conn); if (result == 0) { - nn_conn_buf_skip(conn, 1); + th_conn_buf_skip(conn, 1); } else if (result > 0) @@ -2280,14 +2316,14 @@ // Couldn't handle the message for some reason printMsg(currWin, "Could not handle: %s\n", conn->ptr); - nn_conn_buf_skip(conn, strlen(conn->ptr) + 1); + th_conn_buf_skip(conn, strlen(conn->ptr) + 1); } else editState.isError = TRUE; } } else - if (cres < 0 || !nn_conn_check(conn)) + if (cres < 0 || !th_conn_check(conn)) editState.isError = TRUE; // Handle user input @@ -2353,7 +2389,7 @@ #endif th_free(optUserNameEnc); - nn_conn_free(conn); + th_conn_free(conn); nn_network_close(); THMSG(1, "Connection terminated.\n"); diff -r 29b8ff5b625b -r bb6b07b44800 network.c --- a/network.c Tue May 27 07:27:14 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,686 +0,0 @@ -/* - * NNChat - Custom chat client for NewbieNudes.com chatrooms - * Written by Matti 'ccr' Hämäläinen - * (C) Copyright 2008-2014 Tecnic Software productions (TNSP) - */ -#include "network.h" -#include - -enum -{ - NN_SOCKS5_AUTH_NONE = 0, - NN_SOCKS5_AUTH_USER = 2, -}; - -struct nn_socks4_t -{ - uint8_t version; - uint8_t command; - in_port_t port; - in_addr_t addr; -} __attribute__((__packed__)); - -struct nn_socks4_res_t -{ - uint8_t nb; - uint8_t result; - in_port_t port; - in_addr_t addr; -} __attribute__((__packed__)); - - -static BOOL nn_network_inited = FALSE; - - -static const char *nn_proxy_types[] = -{ - "none", - "SOCKS 4", - "SOCKS 4a", - NULL -}; - - -#ifdef __WIN32 -const char *hstrerror(int err) -{ - static char buf[64]; - snprintf(buf, sizeof(buf), "Error #%d", err); - return buf; -} - - -int nn_get_socket_errno(void) -{ - return WSAGetLastError(); -} - - -const char *nn_get_socket_errstr(int err) -{ - static char buf[64]; - switch (err) - { - case WSAEADDRINUSE: return "Address already in use"; - case WSAECONNABORTED: return "Software caused connection abort"; - case WSAECONNREFUSED: return "Connection refused"; - case WSAECONNRESET: return "Connection reset by peer"; - case WSAEHOSTUNREACH: return "No route to host"; - case WSAENETDOWN: return "Network is down"; - case WSAETIMEDOUT: return "Connection timed out"; - case WSAHOST_NOT_FOUND: return "Host not found"; - case WSAVERNOTSUPPORTED: return "Wrong WinSock DLL version"; - default: - snprintf(buf, sizeof(buf), "Error #%d", err); - return buf; - break; - } -} -#else -int nn_get_socket_errno(void) -{ - return errno; -} - - -const char *nn_get_socket_errstr(int err) -{ - return strerror(err); -} -#endif - - -void nn_conn_err(nn_conn_t *conn, const char *fmt, ...) -{ - if (conn->errfunc != NULL) - { - char *msg; - va_list ap; - va_start(ap, fmt); - msg = th_strdup_vprintf(fmt, ap); - va_end(ap); - - conn->errfunc(conn, msg); - th_free(msg); - } -} - - -static void nn_conn_msg(nn_conn_t *conn, const char *fmt, ...) -{ - if (conn->msgfunc != NULL) - { - char *msg; - va_list ap; - va_start(ap, fmt); - msg = th_strdup_vprintf(fmt, ap); - va_end(ap); - - conn->msgfunc(conn, msg); - th_free(msg); - } -} - - -struct hostent *nn_resolve_host(nn_conn_t *conn, const char *name) -{ - struct hostent *res = gethostbyname(name); - - if (res == NULL) - nn_conn_err(conn, "Could not resolve hostname '%s': %s\n", name, strerror(h_errno)); - else - nn_conn_msg(conn, "True hostname for %s is %s\n", name, res->h_name); - - return res; -} - - -nn_conn_t * nn_conn_new( - void (*errfunc)(nn_conn_t *conn, const char *msg), - void (*msgfunc)(nn_conn_t *conn, const char *msg)) -{ - nn_conn_t *conn = th_malloc0(sizeof(nn_conn_t)); - - if (conn == NULL) - return NULL; - - conn->errfunc = errfunc; - conn->msgfunc = msgfunc; - - return conn; -} - - -static BOOL nn_get_addr(struct in_addr *addr, struct hostent *hst) -{ - if (hst != NULL) - { - *addr = *(struct in_addr *) (hst->h_addr); - return TRUE; - } - else - { - addr->s_addr = 0; - return FALSE; - } -} - - -int nn_conn_set_proxy(nn_conn_t *conn, int type, int port, const char *host, int auth_type) -{ - if (conn == NULL) - return -1; - - conn->proxy.type = type; - conn->proxy.port = port; - conn->proxy.auth_type = auth_type; - - th_free(conn->proxy.host); - conn->proxy.host = th_strdup(host); - - if (host != NULL) - { - conn->proxy.hst = nn_resolve_host(conn, host); - nn_get_addr(&(conn->proxy.addr), conn->proxy.hst); - } - else - return -2; - - return 0; -} - - -int nn_conn_set_proxy_auth_user(nn_conn_t *conn, const char *userid, const char *passwd) -{ - if (conn == NULL) - return -1; - - th_free(conn->proxy.userid); - conn->proxy.userid = th_strdup(userid); - - th_free(conn->proxy.passwd); - conn->proxy.passwd = th_strdup(passwd); - - return 0; -} - - -static int nn_conn_proxy_wait(nn_conn_t *conn) -{ - int status, tries; - - for (status = tries = 1; tries <= 20 && status > 0; tries++) - { -#ifdef __WIN32 - Sleep(50); -#else - usleep(50000); -#endif - nn_conn_reset(conn); - status = nn_conn_pull(conn); - } - - if (status < 0) - nn_conn_err(conn, "Proxy negotiation failed at try %d with network error: %d\n", tries, status); - else - nn_conn_err(conn, "Proxy negotiation timed out.\n"); - - return status; -} - - -static BOOL nn_conn_proxy_send(nn_conn_t *conn, void *buf, size_t bufsiz) -{ - BOOL ret; - nn_conn_reset(conn); - if ((ret = nn_conn_send_buf(conn, buf, bufsiz)) == FALSE) - nn_conn_err(conn, "Error sending SOCKS proxy request.\n"); - th_free(buf); - return ret; -} - - -static int nn_conn_socks4_negotiate(nn_conn_t *conn, const int port, const char *host) -{ - struct nn_socks4_res_t *sockres; - struct nn_socks4_t *socksh; - size_t bufsiz; - uint8_t *ptr, *buf; - - (void) host; - - nn_conn_msg(conn, "Initializing SOCKS 4/a proxy negotiation.\n"); - - bufsiz = sizeof(struct nn_socks4_t) + strlen(conn->proxy.userid) + 1; - if (conn->proxy.type == NN_PROXY_SOCKS4A) - bufsiz += strlen(conn->host) + 1; - - if ((ptr = buf = th_malloc(bufsiz)) == NULL) - { - nn_conn_err(conn, "Could not allocate memory for SOCKS negotiation buffer, %d bytes.\n", bufsiz); - return FALSE; - } - - // Create SOCKS 4 handshake - socksh = (struct nn_socks4_t *) buf; - socksh->version = 4; - socksh->command = NN_PROXY_CMD_CONNECT; - socksh->port = htons(port); - socksh->addr = (conn->proxy.type == NN_PROXY_SOCKS4A) ? htonl(0x00000032) : conn->addr.s_addr; - ptr += sizeof(struct nn_socks4_t); - - strcpy((char *) ptr, conn->proxy.userid); - - if (conn->proxy.type == NN_PROXY_SOCKS4A) - { - ptr += strlen(conn->proxy.userid) + 1; - strcpy((char *)ptr, conn->host); - } - - // Send request - if (!nn_conn_proxy_send(conn, buf, bufsiz)) - return FALSE; - - // Wait for SOCKS server to reply - if (nn_conn_proxy_wait(conn) != 0) - return FALSE; - - sockres = (struct nn_socks4_res_t *) &(conn->buf); - if (sockres->nb != 0) - { - nn_conn_err(conn, "Invalid SOCKS 4 server reply, does not begin with NUL byte (%d).\n", sockres->nb); - return FALSE; - } - if (sockres->result != 0x5a) - { - char *s = NULL; - switch (sockres->result) - { - case 0x5b: s = "Request rejected or failed"; break; - case 0x5c: s = "Request failed because client is not running identd (or not reachable from the server)"; break; - case 0x5d: s = "Request failed because client's identd could not confirm the user ID string in the request"; break; - default: s = "Unknown SOCKS 4 error response"; break; - } - nn_conn_err(conn, "SOCKS 4 setup failed, 0x%02x: %s.\n", sockres->result, s); - return FALSE; - } - - return TRUE; -} - - -int nn_conn_open(nn_conn_t *conn, const int port, const char *host) -{ - struct sockaddr_in dest; - - if (conn == NULL) - return -1; - - conn->port = port; - if (host != NULL) - { - conn->host = th_strdup(host); - conn->hst = nn_resolve_host(conn, host); - } - - nn_get_addr(&(conn->addr), conn->hst); - - // Prepare for connection - dest.sin_family = AF_INET; - - if (conn->proxy.type > NN_PROXY_NONE && conn->proxy.type < NN_PROXY_LAST) - { - // If using a proxy, we connect to the proxy server - dest.sin_port = htons(conn->proxy.port); - dest.sin_addr = conn->proxy.addr; - - nn_conn_msg(conn, "Connecting to %s proxy %s:%d ...\n", - nn_proxy_types[conn->proxy.type], - inet_ntoa(conn->proxy.addr), conn->proxy.port); - } - else - { - dest.sin_port = htons(conn->port); - dest.sin_addr = conn->addr; - - nn_conn_msg(conn, "Connecting to %s:%d ...\n", - inet_ntoa(conn->addr), conn->port); - } - - if ((conn->socket = socket(PF_INET, SOCK_STREAM, 0)) == -1) - { - conn->err = nn_get_socket_errno(); - nn_conn_err(conn, "Could not open socket: %s\n", nn_get_socket_errstr(conn->err)); - goto error; - } - - if (connect(conn->socket, (struct sockaddr *) &dest, sizeof(dest)) == -1) - { - conn->err = nn_get_socket_errno(); - nn_conn_err(conn, "Could not connect: %s\n", nn_get_socket_errstr(conn->err)); - goto error; - } - - FD_ZERO(&(conn->sockfds)); - FD_SET(conn->socket, &(conn->sockfds)); - - // Proxy-specific setup - switch (conn->proxy.type) - { - case NN_PROXY_SOCKS4: - case NN_PROXY_SOCKS4A: - if (!nn_conn_socks4_negotiate(conn, port, host)) - goto error; - nn_conn_msg(conn, "SOCKS 4 connection established!\n"); - break; - } - - nn_conn_reset(conn); - conn->status = NN_CONN_OPEN; - return 0; - -error: - nn_conn_close(conn); - return -2; -} - - -int nn_conn_close(nn_conn_t *conn) -{ - if (conn == NULL) - return -1; - - if (conn->socket >= 0) - { -#ifdef __WIN32 - closesocket(conn->socket); -#else - close(conn->socket); -#endif - conn->socket = -1; - } - - conn->status = NN_CONN_CLOSED; - return 0; -} - - -void nn_conn_free(nn_conn_t *conn) -{ - if (conn != NULL) - { - nn_conn_close(conn); - th_free(conn->host); - th_free(conn->proxy.host); - th_free(conn); - } -} - - -BOOL nn_conn_send_buf(nn_conn_t *conn, const char *buf, const size_t len) -{ - size_t bufLeft = len; - const char *bufPtr = buf; - - while (bufLeft > 0) - { - ssize_t bufSent; - bufSent = send(conn->socket, bufPtr, bufLeft, 0); - if (bufSent < 0) - { - conn->err = nn_get_socket_errno(); - nn_conn_err(conn, "nn_conn_send_buf() failed: %s", nn_get_socket_errstr(conn->err)); - return FALSE; - } - bufLeft -= bufSent; - bufPtr += bufSent; - } - - return TRUE; -} - -void nn_conn_reset(nn_conn_t *conn) -{ - if (conn != NULL) - { - conn->ptr = conn->in_ptr = conn->buf; - conn->got_bytes = conn->total_bytes = 0; - } -} - - -int nn_conn_pull(nn_conn_t *conn) -{ - int result; - struct timeval socktv; - fd_set tmpfds; - - if (conn == NULL) - return -10; - - // Shift the input buffer - if (conn->ptr > conn->buf) - { - size_t left = conn->in_ptr - conn->ptr; - if (left > 0) - { - size_t moved = conn->ptr - conn->buf; - memmove(conn->buf, conn->ptr, left); - conn->ptr = conn->buf; - conn->in_ptr -= moved; - conn->total_bytes -= moved; - } - else - nn_conn_reset(conn); - } - - // Check for incoming data - socktv.tv_sec = 0; - socktv.tv_usec = NN_DELAY_USEC; - tmpfds = conn->sockfds; - - if ((result = select(conn->socket + 1, &tmpfds, NULL, NULL, &socktv)) == -1) - { - int err = nn_get_socket_errno(); - if (err != EINTR) - { - conn->err = err; - nn_conn_err(conn, "Error occured in select(%d, sockfds): %d, %s\n", - socket, conn->err, nn_get_socket_errstr(conn->err)); - return -1; - } - } - else if (FD_ISSET(conn->socket, &tmpfds)) - { - conn->got_bytes = recv(conn->socket, conn->in_ptr, NN_CONNBUF_SIZE - conn->total_bytes, 0); - if (conn->got_bytes < 0) - { - conn->err = nn_get_socket_errno(); - nn_conn_err(conn, "Error in recv: %d, %s\n", conn->err, nn_get_socket_errstr(conn->err)); - return -2; - } - else if (conn->got_bytes == 0) - { - nn_conn_err(conn, "Server closed connection.\n"); - conn->status = NN_CONN_CLOSED; - return -3; - } - else - { - conn->total_bytes += conn->got_bytes; - conn->in_ptr += conn->got_bytes; - return 0; - } - } - - return 1; -} - - -BOOL nn_conn_check(nn_conn_t *conn) -{ - if (conn == NULL) - return FALSE; - - return conn->err == 0 && conn->status == NN_CONN_OPEN; -} - - -BOOL nn_network_init(void) -{ -#ifdef __WIN32 - // Initialize WinSock, if needed - WSADATA wsaData; - int err = WSAStartup(0x0101, &wsaData); - if (err != 0) - { - THERR("Could not initialize WinSock library (err=%d).\n", err); - return FALSE; - } -#endif - - nn_network_inited = TRUE; - return TRUE; -} - - -void nn_network_close(void) -{ - if (nn_network_inited) - { -#ifdef __WIN32 - WSACleanup(); -#endif - } - - nn_network_inited = FALSE; -} - - -BOOL nn_conn_buf_check(nn_conn_t *conn, size_t n) -{ - return conn && (conn->ptr + n <= conn->in_ptr); -} - - -BOOL nn_conn_buf_skip(nn_conn_t *conn, size_t n) -{ - if (nn_conn_buf_check(conn, n)) - { - conn->ptr += n; - return TRUE; - } - else - return FALSE; -} - - -int nn_conn_buf_strncmp(nn_conn_t *conn, const char *str, const size_t n) -{ - int ret; - if (!nn_conn_buf_check(conn, n)) - return -1; - - if ((ret = strncmp(conn->ptr, str, n)) == 0) - { - conn->ptr += n; - return 0; - } - else - return ret; -} - - -int nn_conn_buf_strcmp(nn_conn_t *conn, const char *str) -{ - return nn_conn_buf_strncmp(conn, str, strlen(str)); -} - - -char *nn_conn_buf_strstr(nn_conn_t *conn, const char *str) -{ - char *pos; - size_t n = strlen(str); - - if (nn_conn_buf_check(conn, n) && ((pos = strstr(conn->ptr, str)) != NULL)) - { - conn->ptr = pos + n; - return pos; - } - else - return NULL; -} - - -BOOL nn_conn_send_msg(nn_conn_t *conn, const char *user, const char *str) -{ - char *msg; - - if (str == NULL) - return FALSE; - - msg = th_strdup_printf("%s%s", user, str); - - if (msg != NULL) - { - BOOL ret = nn_conn_send_buf(conn, msg, strlen(msg) + 1); - th_free(msg); - return ret; - } - else - return FALSE; -} - - -BOOL nn_conn_send_msg_v(nn_conn_t *conn, const char *user, const char *fmt, ...) -{ - BOOL res; - char *tmp; - va_list ap; - - va_start(ap, fmt); - tmp = th_strdup_vprintf(fmt, ap); - va_end(ap); - - res = nn_conn_send_msg(conn, user, tmp); - th_free(tmp); - return res; -} - - -void nn_conn_dump_buffer(FILE *f, nn_conn_t *conn) -{ - char *p; - size_t offs, left; - - fprintf(f, - "\n--------------------------------------------------------------\n" - "err=%d, status=%d, got_bytes=%d, total_bytes=%d\n" - "buf=0x%p, in_ptr=0x%04x, ptr=0x%04x\n", - conn->err, conn->status, conn->got_bytes, conn->total_bytes, - conn->buf, conn->in_ptr - conn->buf, conn->ptr - conn->buf); - - // Dump buffer contents as a hexdump - for (offs = 0, left = conn->total_bytes, p = conn->buf; p < conn->in_ptr;) - { - char buf[NN_DUMP_BYTES + 1]; - size_t bufoffs, amount = left < NN_DUMP_BYTES ? left : NN_DUMP_BYTES; - left -= amount; - - // Dump offs | xx xx xx xx | and fill string - fprintf(f, "%04x | ", offs); - for (bufoffs = 0; bufoffs < amount; offs++, bufoffs++, p++) - { - fprintf(f, "%02x ", *p); - buf[bufoffs] = th_isprint(*p) ? *p : '.'; - } - buf[bufoffs] = 0; - - // Add padding - for (; bufoffs < NN_DUMP_BYTES; bufoffs++) - fprintf(f, " "); - - // Print string - fprintf(f, "| %s\n", buf); - } -} diff -r 29b8ff5b625b -r bb6b07b44800 network.h --- a/network.h Tue May 27 07:27:14 2014 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/* - * NNChat - Custom chat client for NewbieNudes.com chatrooms - * Written by Matti 'ccr' Hämäläinen - * (C) Copyright 2008-2014 Tecnic Software productions (TNSP) - */ -#ifndef LIBNNCHAT_H -#define LIBNNCHAT_H - -#include -#include -#include "th_types.h" -#include "th_string.h" - -#ifdef __WIN32 -#define __OBJC_BOOL // A nasty hack -#include -#include -typedef uint16_t in_port_t; -typedef uint32_t in_addr_t; -#else -#include -#include -#ifdef HAVE_NETINET_IN_H -#include -#endif -#include -#include -#endif - - -#define NN_CONNBUF_SIZE (64 * 1024) -#define NN_DELAY_USEC (15 * 1000) -#define NN_DUMP_BYTES 16 - - -enum -{ - NN_CONN_UNINIT = 0, - NN_CONN_PROXY_NEG, - NN_CONN_OPEN, - NN_CONN_CLOSED -}; - -enum -{ - NN_PROXY_NONE = 0, - NN_PROXY_SOCKS4, - NN_PROXY_SOCKS4A, - - NN_PROXY_LAST -}; - -enum -{ - NN_PROXY_AUTH_NONE, - NN_PROXY_AUTH_USER, -}; - -enum -{ - NN_PROXY_CMD_CONNECT = 1, - NN_PROXY_CMD_BIND = 2, - NN_PROXY_CMD_ASSOC_UDP = 3, -}; - - -typedef struct _nn_conn_t -{ - struct - { - char *host; - struct hostent *hst; - int type, auth_type; - int port; - struct in_addr addr; - char *userid, *passwd; - } proxy; - - char *host; - struct hostent *hst; - int port; - - int socket; - struct in_addr addr; - fd_set sockfds; - - void (*errfunc)(struct _nn_conn_t *conn, const char *msg); - void (*msgfunc)(struct _nn_conn_t *conn, const char *msg); - - int err; - int status; - - char buf[NN_CONNBUF_SIZE + 16]; - char *ptr, *in_ptr; - ssize_t got_bytes, total_bytes; -} nn_conn_t; - - -const char *nn_get_errstr(int err); -BOOL nn_network_init(); -void nn_network_close(void); - -struct hostent *nn_resolve_host(nn_conn_t *conn, const char *name); -nn_conn_t * nn_conn_new( - void (*errfunc)(nn_conn_t *conn, const char *msg), - void (*msgfunc)(nn_conn_t *conn, const char *msg)); - -int nn_conn_set_proxy(nn_conn_t *conn, int type, int port, const char *host, int auth_type); -int nn_conn_set_proxy_auth_user(nn_conn_t *conn, const char *userid, const char *passwd); -int nn_conn_open(nn_conn_t *conn, const int port, const char *host); -int nn_conn_close(nn_conn_t *); -void nn_conn_free(nn_conn_t *); -void nn_conn_reset(nn_conn_t *); -int nn_conn_pull(nn_conn_t *); -BOOL nn_conn_send_buf(nn_conn_t *, const char *buf, const size_t len); - -BOOL nn_conn_send_msg(nn_conn_t *, const char *user, const char *str); -BOOL nn_conn_send_msg_v(nn_conn_t *, const char *user, const char *fmt, ...); -BOOL nn_conn_check(nn_conn_t *); - - -BOOL nn_conn_buf_check(nn_conn_t *conn, size_t n); -BOOL nn_conn_buf_skip(nn_conn_t *conn, size_t n); -int nn_conn_buf_strncmp(nn_conn_t *conn, const char *str, const size_t n); -int nn_conn_buf_strcmp(nn_conn_t *conn, const char *str); -char * nn_conn_buf_strstr(nn_conn_t *conn, const char *str); - -void nn_conn_dump_buffer(FILE *f, nn_conn_t *conn); - -#endif diff -r 29b8ff5b625b -r bb6b07b44800 ui.h --- a/ui.h Tue May 27 07:27:14 2014 +0300 +++ b/ui.h Tue May 27 07:31:20 2014 +0300 @@ -57,7 +57,7 @@ { time_t prevKeepAlive; BOOL insertMode, isError, update, mask, done; - nn_conn_t *conn; + th_conn_t *conn; void (*debugMsg)(const char *fmt, ...); } nn_editstate_t;