changeset 622:bb6b07b44800

Network code is being generalized into a th-libs module.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 27 May 2014 07:31:20 +0300
parents 29b8ff5b625b
children 118276b60667
files Makefile.gen main.c network.c network.h ui.h
diffstat 5 files changed, 98 insertions(+), 878 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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 <unistd.h>
 #include <fcntl.h>
 #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("<USER>%s</USER><MESSAGE>%s</MESSAGE>", 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, "</USER>");
+    t = th_conn_buf_strstr(conn, "</USER>");
     if (!t) return 1;
     *t = 0;
 
     // Find end of the message
-    t = nn_conn_buf_strstr(conn, "<MESSAGE>");
+    t = th_conn_buf_strstr(conn, "<MESSAGE>");
     if (!t) return 2;
     msg = conn->ptr;
     
-    t = nn_conn_buf_strstr(conn, "</MESSAGE>");
+    t = th_conn_buf_strstr(conn, "</MESSAGE>");
     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, "</LOGIN_FAILURE>");
-        nn_conn_buf_strstr(conn, "</USER>");
+        th_conn_buf_strstr(conn, "</LOGIN_FAILURE>");
+        th_conn_buf_strstr(conn, "</USER>");
         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, "</LOGIN_SUCCESS>");
-        nn_conn_buf_strstr(conn, "</USER>");
+        th_conn_buf_strstr(conn, "</LOGIN_SUCCESS>");
+        th_conn_buf_strstr(conn, "</USER>");
         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, "</ADD_USER>");
+    s = th_conn_buf_strstr(conn, "</ADD_USER>");
     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, "</DELETE_USER>");
+    s = th_conn_buf_strstr(conn, "</DELETE_USER>");
     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, "</NUMCLIENTS>");
+    th_conn_buf_strstr(conn, "</NUMCLIENTS>");
     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 = "<policy-file-request/>";
-    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");
--- 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 <errno.h>
-
-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("<USER>%s</USER><MESSAGE>%s</MESSAGE>", 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);
-    }
-}
--- 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 <stdio.h>
-#include <unistd.h>
-#include "th_types.h"
-#include "th_string.h"
-
-#ifdef __WIN32
-#define __OBJC_BOOL // A nasty hack
-#include <windows.h>
-#include <winsock.h>
-typedef uint16_t in_port_t;
-typedef uint32_t in_addr_t;
-#else
-#include <sys/select.h>
-#include <sys/socket.h>
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#include <arpa/inet.h>
-#include <netdb.h>
-#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
--- 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;