[tor-commits] [torsocks/master] Move source code to old source directory

dgoulet at torproject.org dgoulet at torproject.org
Fri Apr 4 22:40:25 UTC 2014


commit 36194ee1b1a6b979fcf7df49a1347d7b53130645
Author: David Goulet <dgoulet at ev0ke.net>
Date:   Sun Jun 2 12:58:25 2013 -0400

    Move source code to old source directory
    
    Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
 src.old/Makefile.am       |   18 +
 src.old/common.c          |  224 +++++++++
 src.old/common.h          |  104 +++++
 src.old/darwin_warts.c    |   59 +++
 src.old/dead_pool.c       |  805 ++++++++++++++++++++++++++++++++
 src.old/dead_pool.h       |   67 +++
 src.old/expansion_table.h |  125 +++++
 src.old/parser.c          |  872 +++++++++++++++++++++++++++++++++++
 src.old/parser.h          |   69 +++
 src.old/socks.c           |  633 ++++++++++++++++++++++++++
 src.old/socks.h           |  116 +++++
 src.old/torsocks.c        | 1108 +++++++++++++++++++++++++++++++++++++++++++++
 src.old/torsocks.in       |  167 +++++++
 src.old/usewithtor.in     |  113 +++++
 src/common.c              |  224 ---------
 src/common.h              |  104 -----
 src/darwin_warts.c        |   59 ---
 src/dead_pool.c           |  805 --------------------------------
 src/dead_pool.h           |   67 ---
 src/expansion_table.h     |  125 -----
 src/parser.c              |  872 -----------------------------------
 src/parser.h              |   69 ---
 src/socks.c               |  633 --------------------------
 src/socks.h               |  116 -----
 src/torsocks.c            | 1108 ---------------------------------------------
 src/torsocks.in           |  167 -------
 src/usewithtor.in         |  113 -----
 27 files changed, 4480 insertions(+), 4462 deletions(-)

diff --git a/src.old/Makefile.am b/src.old/Makefile.am
new file mode 100644
index 0000000..e3a01c9
--- /dev/null
+++ b/src.old/Makefile.am
@@ -0,0 +1,18 @@
+# Makefile used by configure to create real Makefile
+
+libdir = @libdir@/torsocks
+
+# Install invocation scripts
+bin_SCRIPTS = torsocks usewithtor
+INSTALL_SCRIPT = $(install_sh) -c -m 755
+
+libtorsocks_la_LDFLAGS= $(TORSOCKSLDFLAGS)
+# Install main library to $(prefix)/lib/tor (must match torsocks.in)
+lib_LTLIBRARIES = libtorsocks.la
+libtorsocks_la_SOURCES = torsocks.c common.c parser.c dead_pool.c darwin_warts.c socks.c\
+				common.h  dead_pool.h  expansion_table.h  parser.h  socks.h
+
+DISTCLEANFILES=parser.lo dead_pool.lo common.lo libtorsocks.lo torsocks.lo darwin_warts.lo socks.lo\
+			   config.cache config.log config.h Makefile \
+			   aclocal.m4 config.status usewithtor torsocks \
+			   autom4te.cache .libs .deps 
diff --git a/src.old/common.c b/src.old/common.c
new file mode 100644
index 0000000..8fe3303
--- /dev/null
+++ b/src.old/common.c
@@ -0,0 +1,224 @@
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
+ *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                         *
+ * Some code taken from Tor:                                               *
+ * Copyright (c) 2003, Roger Dingledine                                    *
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.              *
+ * Copyright (c) 2007-2008, The Tor Project, Inc.                          *
+ *                                                                         *
+ ***************************************************************************/
+/* 
+
+    commmon.c    - Common routines for the torsocks package 
+
+*/
+
+#include <config.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#include "common.h"
+
+/* Globals */
+int loglevel = MSGERR;    /* The default logging level is to only log
+                             error messages */
+char logfilename[256];    /* Name of file to which log messages should
+                             be redirected */
+FILE *logfile = NULL;     /* File to which messages should be logged */
+int logstamp = 0;         /* Timestamp (and pid stamp) messages */
+
+
+/**
+ * Read a 16-bit value beginning at <b>cp</b>.  Equivalent to
+ * *(uint16_t*)(cp), but will not cause segfaults on platforms that forbid
+ * unaligned memory access.
+ */
+uint16_t
+get_uint16(const char *cp)
+{
+    uint16_t v;
+    memcpy(&v,cp,2);
+    return v;
+}
+/**
+ * Read a 32-bit value beginning at <b>cp</b>.  Equivalent to
+ * *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid
+ * unaligned memory access.
+ */
+uint32_t
+get_uint32(const char *cp)
+{
+    uint32_t v;
+    memcpy(&v,cp,4);
+    return v;
+}
+/**
+ * Set a 16-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
+ * *(uint16_t)(cp) = v, but will not cause segfaults on platforms that forbid
+ * unaligned memory access. */
+void
+set_uint16(char *cp, uint16_t v)
+{
+    memcpy(cp,&v,2);
+}
+/**
+ * Set a 32-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
+ * *(uint32_t)(cp) = v, but will not cause segfaults on platforms that forbid
+ * unaligned memory access. */
+void
+set_uint32(char *cp, uint32_t v)
+{
+    memcpy(cp,&v,4);
+}
+
+unsigned int resolve_ip(char *host, int showmsg, int allownames) {
+    struct hostent *new;
+    unsigned int    hostaddr;
+    struct in_addr *ip;
+
+    if ((hostaddr = inet_addr(host)) == (unsigned int) -1) {
+        /* We couldn't convert it as a numerical ip so */
+        /* try it as a dns name                        */
+        if (allownames) {
+            #ifdef HAVE_GETHOSTBYNAME
+            if ((new = gethostbyname(host)) == (struct hostent *) 0) {
+            #endif
+                return(0);
+            #ifdef HAVE_GETHOSTBYNAME
+            } else {
+                ip = ((struct in_addr *) * new->h_addr_list);
+                hostaddr = ip -> s_addr;
+                if (showmsg)
+                    printf("Connecting to %s...\n", inet_ntoa(*ip));
+            }
+            #endif
+        } else
+            return(0);
+    }
+
+    return (hostaddr);
+}
+
+/* Set logging options, the options are as follows:             */
+/*  level - This sets the logging threshold, messages with      */
+/*          a higher level (i.e lower importance) will not be   */
+/*          output. For example, if the threshold is set to     */
+/*          MSGWARN a call to log a message of level MSGDEBUG   */
+/*          would be ignored. This can be set to -1 to disable  */
+/*          messages entirely                                   */
+/*  filename - This is a filename to which the messages should  */
+/*             be logged instead of to standard error           */
+/*  timestamp - This indicates that messages should be prefixed */
+/*              with timestamps (and the process id)            */
+void set_log_options(int level, char *filename, int timestamp) {
+
+   loglevel = level;
+   if (loglevel < MSGERR)
+      loglevel = MSGNONE;
+
+   if (filename) {
+      strncpy(logfilename, filename, sizeof(logfilename));
+      logfilename[sizeof(logfilename) - 1] = '\0';
+   }
+
+   logstamp = timestamp;
+}
+
+/* Count the bits in a netmask.  This is a little bit buggy; it assumes 
+   all the zeroes are on the right... */
+
+int count_netmask_bits(uint32_t mask)
+{
+    int i;
+    int nbits = 0;
+
+    for(i=0; i<32; i++) {
+        if((mask >> i) & 1) {
+            nbits++;
+        } 
+    }
+    mask = ~mask;
+    mask = ntohl(mask);
+    if(mask & (mask+1)) {
+        return -1;  /* Noncontiguous */
+    }
+    return nbits;
+}
+
+void show_msg(int level, const char *fmt, ...) {
+    va_list ap;
+    int saveerr;
+    extern char *torsocks_progname;
+    char timestring[20];
+    time_t timestamp;
+
+    if ((loglevel == MSGNONE) || (level > loglevel))
+        return;
+
+    if (!logfile) {
+        if (logfilename[0]) {
+          logfile = fopen(logfilename, "a");
+          if (logfile == NULL) {
+              logfile = stderr;
+              show_msg(MSGERR, "Could not open log file, %s, %s\n", 
+                      logfilename, strerror(errno));
+          }
+        } else
+          logfile = stderr;
+    }
+
+    if (logstamp) {
+        timestamp = time(NULL);
+        strftime(timestring, sizeof(timestring),  "%H:%M:%S", 
+                localtime(&timestamp));
+        fprintf(logfile, "%s ", timestring);
+    }
+
+    fputs(torsocks_progname, logfile);
+
+    if (logstamp) {
+        fprintf(logfile, "(%d)", getpid());
+    }
+
+    fputs(": ", logfile);
+
+    va_start(ap, fmt);
+
+    /* Save errno */
+    saveerr = errno;
+
+    vfprintf(logfile, fmt, ap);
+
+    fflush(logfile);
+
+    errno = saveerr;
+
+    va_end(ap);
+}
+
diff --git a/src.old/common.h b/src.old/common.h
new file mode 100644
index 0000000..f84a2f7
--- /dev/null
+++ b/src.old/common.h
@@ -0,0 +1,104 @@
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
+ *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+/* Common functions provided in common.c */
+/* GCC has several useful attributes. */
+#include <sys/types.h>
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define ATTR_NORETURN __attribute__((noreturn))
+#define ATTR_PURE __attribute__((pure))
+#define ATTR_CONST __attribute__((const))
+#define ATTR_MALLOC __attribute__((malloc))
+#define ATTR_NORETURN __attribute__((noreturn))
+#define ATTR_NONNULL(x) __attribute__((nonnull x))
+/** Macro: Evaluates to <b>exp</b> and hints the compiler that the value
+ * of <b>exp</b> will probably be true. */
+#define PREDICT_LIKELY(exp) __builtin_expect((exp), 1)
+/** Macro: Evaluates to <b>exp</b> and hints the compiler that the value
+ * of <b>exp</b> will probably be false. */
+#define PREDICT_UNLIKELY(exp) __builtin_expect((exp), 0)
+#else
+#define ATTR_NORETURN
+#define ATTR_PURE
+#define ATTR_CONST
+#define ATTR_MALLOC
+#define ATTR_NORETURN
+#define ATTR_NONNULL(x)
+#define PREDICT_LIKELY(exp) (exp)
+#define PREDICT_UNLIKELY(exp) (exp)
+#endif
+
+/** Try to find the symbol that is either m or __m.
+ * If one of them exists, in that order, then save its address in r,
+ * otherwise we want to print a message at log level l stating that
+ * we could not find it.
+ */
+#define torsocks_find_library(m,l,r) \
+  do { \
+    char * dl_error_msg = ""; \
+    char * dl_error_msg2 = ""; \
+    dlerror(); \
+    if ((r = dlsym(RTLD_NEXT, m)) == NULL) { \
+      dl_error_msg = dlerror(); \
+      if (dl_error_msg != NULL) { \
+        dl_error_msg = strdup(dl_error_msg); \
+      } \
+      if ((r = dlsym(RTLD_NEXT, "__" m)) == NULL) { \
+        dl_error_msg2 = dlerror(); \
+        show_msg(l, "WARNING: The symbol %s() was not found in any shared " \
+          "library with the reported error: %s!\n" \
+          "  Also, we failed to find the symbol %s() with the reported error:" \
+          " %s\n", m, (dl_error_msg ? dl_error_msg : "Not Found"), \
+          "__"m, (dl_error_msg2 ? dl_error_msg2 : "Not Found")); \
+      } \
+      if (dl_error_msg) \
+        free(dl_error_msg); \
+    } \
+  } while (0)
+
+uint16_t get_uint16(const char *cp) ATTR_PURE ATTR_NONNULL((1));
+uint32_t get_uint32(const char *cp) ATTR_PURE ATTR_NONNULL((1));
+void set_uint16(char *cp, uint16_t v) ATTR_NONNULL((1));
+void set_uint32(char *cp, uint32_t v) ATTR_NONNULL((1));
+
+int is_internal_IP(uint32_t ip, int for_listening) ATTR_PURE;
+int parse_addr_port(int severity, const char *addrport, char **address,
+                    uint32_t *addr, uint16_t *port_out);
+
+void set_log_options(int, char *, int);
+void show_msg(int level, const char *, ...);
+int count_netmask_bits(uint32_t mask);
+unsigned int resolve_ip(char *, int, int);
+
+#define MSGNONE   -1
+#define MSGERR    0
+#define MSGWARN   1
+#define MSGTEST  2
+#define MSGNOTICE 3
+#define MSGDEBUG  3
+
+/* Required by some BSDs */
+#ifndef  MAP_ANONYMOUS
+#ifdef MAP_ANON
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+#endif
diff --git a/src.old/darwin_warts.c b/src.old/darwin_warts.c
new file mode 100644
index 0000000..65bdd04
--- /dev/null
+++ b/src.old/darwin_warts.c
@@ -0,0 +1,59 @@
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (C) 2010 Alex Rosenberg <alex at ohmantics.net>                *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+/* Mac OS X 10.6 forces any function named "select" to be named "_select$1050"
+ * in the output to the assembler. We need to patch select as well, so this
+ * isolated code exists without tripping over the Darwin header that causes the
+ * probkem.
+ */
+
+#if defined(__APPLE__) || defined(__darwin__)
+
+#include <AvailabilityMacros.h>
+
+#if defined(MAC_OS_X_VERSION_10_6)
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <errno.h>
+#include "common.h"
+
+#define SELECT_SIGNATURE int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout
+#define SELECT_ARGNAMES n, readfds, writefds, exceptfds, timeout
+
+/* forward declare opaque structures instead of bringing in real Darwin decls. */
+typedef struct fd_set fd_set;
+struct timeval;
+
+int (*realselect)(SELECT_SIGNATURE);
+int torsocks_select_guts(SELECT_SIGNATURE, int (*original_select)(SELECT_SIGNATURE));
+
+int select(SELECT_SIGNATURE) {
+  if (!realselect) {
+    torsocks_find_library("select", MSGERR, realselect);
+  }
+  return torsocks_select_guts(SELECT_ARGNAMES, realselect);
+}
+
+#endif /* 10.6 */
+#endif /* darwin */
diff --git a/src.old/dead_pool.c b/src.old/dead_pool.c
new file mode 100644
index 0000000..13e5740
--- /dev/null
+++ b/src.old/dead_pool.c
@@ -0,0 +1,805 @@
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (C) 2005 Total Information Security Ltd.                    *
+ *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include "common.h"
+#include "dead_pool.h"
+
+int store_pool_entry(dead_pool *pool, char *hostname, struct in_addr *addr);
+void get_next_dead_address(dead_pool *pool, uint32_t *result);
+
+static int
+do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
+           uint32_t *result_addr, const void *addr,
+           int version, int reverse, char **result_hostname);
+
+/* Compares the last strlen(s2) characters of s1 with s2.  Returns as for
+   strcasecmp. */
+static int 
+strcasecmpend(const char *s1, const char *s2)
+{
+   size_t n1 = strlen(s1), n2 = strlen(s2);
+   if (n2>n1) /* then they can't be the same; figure out which is bigger */
+       return strcasecmp(s1,s2);
+   else
+       return strncasecmp(s1+(n1-n2), s2, n2);
+}
+
+dead_pool *
+init_pool(unsigned int pool_size, struct in_addr deadrange_base, 
+    struct in_addr deadrange_mask, char *sockshost, uint16_t socksport)
+{
+    unsigned int i, deadrange_size, deadrange_width;
+    int deadrange_bits;
+    struct in_addr socks_server;
+    dead_pool *newpool = NULL;
+
+    /* Count bits in netmask and determine deadrange width. */
+    deadrange_bits = count_netmask_bits(deadrange_mask.s_addr);
+    if(deadrange_bits == -1) {
+        show_msg(MSGERR, "init_pool: invalid netmask for deadrange\n");
+        return NULL;
+    } 
+    deadrange_width = 32 - deadrange_bits;
+
+    show_msg(MSGDEBUG, "deadrange width is %d bits\n", deadrange_width);
+
+    /* Now work out how many IPs are available in the deadrange and check
+       that this number makes sense.  If the deadpool is bigger than the 
+       deadrange we shrink the pool. */
+
+    for(i=0, deadrange_size = 1; i < deadrange_width; i++) {
+        deadrange_size *= 2;
+    }
+
+    if(deadrange_size < pool_size) {
+        show_msg(MSGWARN, "tordns cache size was %d, but deadrange size is %d: "
+                 "shrinking pool size to %d entries\n", pool_size, 
+                 deadrange_size, deadrange_size);
+        pool_size = deadrange_size;
+    }
+    if(pool_size < 1) {
+        show_msg(MSGERR, "tordns cache size is 0, disabling tordns\n");
+        return NULL;
+    }
+
+    /* Allocate space for the dead_pool structure */
+    newpool = (dead_pool *) mmap(0, sizeof(dead_pool), 
+                   PROT_READ | PROT_WRITE, 
+                   MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
+    if(!newpool) {
+        show_msg(MSGERR, "init_pool: unable to mmap deadpool "
+                 "(tried to map %d bytes)\n", sizeof(dead_pool));
+        return NULL;
+    }
+
+    show_msg(MSGDEBUG, "init_pool: sockshost %s \n", sockshost);
+
+    /* Initialize the dead_pool structure */
+#ifdef HAVE_INET_ATON
+    inet_aton(sockshost, &socks_server);
+#elif defined(HAVE_INET_ADDR)
+    socks_server.s_addr = inet_addr(sockshost);
+#endif
+    newpool->sockshost = ntohl(socks_server.s_addr);
+    newpool->socksport = socksport;
+    newpool->deadrange_base = ntohl(deadrange_base.s_addr);
+    newpool->deadrange_mask = ntohl(deadrange_mask.s_addr);
+    newpool->deadrange_size = deadrange_size;
+    newpool->write_pos = 0;
+    newpool->dead_pos = 0;
+    newpool->n_entries = pool_size;
+
+    /* Allocate space for the entries */
+    newpool->entries = (pool_ent *) mmap(0, newpool->n_entries * sizeof(pool_ent), 
+                            PROT_READ | PROT_WRITE, 
+                            MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
+    if(!newpool->entries) {
+        munmap((void *)newpool, sizeof(dead_pool));
+        show_msg(MSGERR, "init_pool: unable to mmap deadpool entries "
+                 "(tried to map %d bytes)\n", 
+                 newpool->n_entries * sizeof(pool_ent)); 
+        return NULL;
+    }
+
+    /* Initialize the entries */
+    for(i=0; i < newpool->n_entries; i++) {
+        newpool->entries[i].ip = -1;
+        newpool->entries[i].name[0] = '\0';
+    }
+
+    return newpool;
+}
+
+int
+is_dead_address(dead_pool *pool, uint32_t addr) 
+{
+    uint32_t haddr = ntohl(addr);
+    if(pool == NULL) {
+        return 0;
+    }
+    return (pool->deadrange_base == (haddr & pool->deadrange_mask));
+}
+
+void
+get_next_dead_address(dead_pool *pool, uint32_t *result)
+{
+    *result = htonl(pool->deadrange_base + pool->dead_pos++);
+    if(pool->dead_pos >= pool->deadrange_size) {
+        pool->dead_pos = 0;
+    }
+}
+
+int
+store_pool_entry(dead_pool *pool, char *hostname, struct in_addr *addr)
+{
+  int position = pool->write_pos;
+  int oldpos;
+  int rc;
+  uint32_t intaddr;
+  char *result_hostname;
+
+  show_msg(MSGDEBUG, "store_pool_entry: storing '%s'\n", hostname);
+  show_msg(MSGDEBUG, "store_pool_entry: write pos is: %d\n", pool->write_pos);
+
+  /* Check to see if name already exists in pool */
+  oldpos = search_pool_for_name(pool, hostname);
+  if(oldpos != -1){
+      show_msg(MSGDEBUG, "store_pool_entry: not storing (entry exists)\n");
+      addr->s_addr = pool->entries[oldpos].ip;
+      return oldpos;
+  }
+
+  /* If this is a .onion host, then we return a bogus ip from our deadpool, 
+     otherwise we try to resolve it and store the 'real' IP */
+  if(strcasecmpend(hostname, ".onion") == 0) {
+      get_next_dead_address(pool, &pool->entries[position].ip);
+  } else {
+      rc = do_resolve(hostname, pool->sockshost, pool->socksport, &intaddr, 0,
+                  4 /*SOCKS5*/, 0 /*Reverse*/, &result_hostname);
+
+      if(rc != 0) {
+          show_msg(MSGWARN, "failed to resolve: %s\n", hostname);
+          return -1;
+      } 
+      if(is_dead_address(pool, intaddr)) {
+          show_msg(MSGERR, "resolved %s -> %d (deadpool address) IGNORED\n");
+          return -1;
+      }
+      pool->entries[position].ip = intaddr;
+  }
+
+  strncpy(pool->entries[position].name, hostname, 255);
+  pool->entries[position].name[255] = '\0';
+  pool->write_pos++;
+  if(pool->write_pos >= pool->n_entries) {
+      pool->write_pos = 0;
+  }
+  addr->s_addr = pool->entries[position].ip;
+
+  show_msg(MSGDEBUG, "store_pool_entry: stored entry in slot '%d'\n", position);
+
+  return position;
+}
+
+int 
+search_pool_for_name(dead_pool *pool, const char *name) 
+{
+  unsigned int i;
+  for(i=0; i < pool->n_entries; i++){
+    if(strcmp(name, pool->entries[i].name) == 0){
+      return i;
+    }
+  }
+  return -1;
+}
+
+char *
+get_pool_entry(dead_pool *pool, struct in_addr *addr)
+{
+  unsigned int i;
+  uint32_t intaddr = addr->s_addr;
+
+  if(pool == NULL) {
+      return NULL;
+  }
+
+  show_msg(MSGDEBUG, "get_pool_entry: searching for: %s\n", inet_ntoa(*addr));
+  for(i=0; i<pool->n_entries; i++) {
+    if(intaddr == pool->entries[i].ip) {
+        show_msg(MSGDEBUG, "get_pool_entry: found: %s\n", pool->entries[i].name);
+        return pool->entries[i].name;
+    }
+  }
+  show_msg(MSGDEBUG, "get_pool_entry: address not found\n");
+
+  return NULL;
+}
+
+static int
+build_socks4a_resolve_request(char **out,
+                              const char *username,
+                              const char *hostname)
+{
+  size_t len;
+  uint16_t port = htons(0);  /* port: 0. */
+  uint32_t addr = htonl(0x00000001u); /* addr: 0.0.0.1 */
+
+  len = 8 + strlen(username) + 1 + strlen(hostname) + 1;
+  *out = malloc(len);
+  (*out)[0] = 4;      /* SOCKS version 4 */
+  (*out)[1] = '\xF0'; /* Command: resolve. */
+
+  memcpy((*out)+2, &port, sizeof(port));
+  memcpy((*out)+4, &addr, sizeof(addr));
+  strcpy((*out)+8, username);
+  strcpy((*out)+8+strlen(username)+1, hostname);
+
+  return len;
+}
+
+static int
+build_socks5_resolve_ptr_request(char **out, const void *_addr)
+{
+  size_t len;
+  const struct in_addr *addr=_addr;
+
+  len = 12;
+  *out = malloc(len);
+  (*out)[0] = 5;      /* SOCKS version 5 */
+  (*out)[1] = '\xF1'; /* Command: reverse resolve.
+                         see doc/socks-extensions.txt*/
+  (*out)[2] = '\x00'; /* RSV */
+  (*out)[3] = '\x01'; /* ATYP: IP V4 address: X'01' */
+
+  set_uint32((*out)+4, addr->s_addr);/*IP*/
+  set_uint16((*out)+4+4, 0); /* port */
+
+  return len;
+}
+
+#define RESPONSE_LEN 8
+#define SOCKS5_LEN 4
+#define METHODRESPONSE_LEN 2
+
+static int
+parse_socks4a_resolve_response(const char *response, size_t len,
+                               uint32_t *addr_out)
+{
+  uint8_t status;
+  uint16_t port;
+
+  if (len < RESPONSE_LEN) {
+    show_msg(MSGWARN,"Truncated socks response.\n"); 
+    return -1;
+  }
+  if (((uint8_t)response[0])!=0) { /* version: 0 */
+    show_msg(MSGWARN,"Nonzero version in socks response: bad format.\n");
+    return -1;
+  }
+  status = (uint8_t)response[1];
+
+  memcpy(&port, response+2, sizeof(port));
+  if (port!=0) { /* port: 0 */
+    show_msg(MSGWARN,"Nonzero port in socks response: bad format.\n"); 
+    return -1;
+  }
+  if (status != 90) {
+    show_msg(MSGWARN,"Bad status: socks request failed.\n"); 
+    return -1;
+  }
+
+  memcpy(addr_out, response+4, sizeof(*addr_out));
+
+  return 0;
+}
+
+static int
+parse_socks5_resolve_ptr_response(int s,const char *response, size_t len,
+                               uint32_t *result_addr, char ***result_hostname)
+{
+    char reply_buf[4];
+    int r;
+
+    len=0;
+    while (len < SOCKS5_LEN) {
+      r = recv(s, reply_buf+len, SOCKS5_LEN-len, 0);
+      if (r==0) {
+        show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n"); 
+        return -1;
+      }
+      if (r<0) {
+        show_msg(MSGWARN, "do_resolve: error reading SOCKS5 response\n"); 
+        return -1;
+      }
+      len += r;
+    }
+
+    if (reply_buf[0] != 5) {
+      show_msg(MSGWARN, "Bad SOCKS5 reply version.");
+      return -1;
+    }
+    if (reply_buf[1] != 0) {
+      show_msg(MSGWARN,"Got status response '%u': SOCKS5 request failed.",
+               (unsigned)reply_buf[1]);
+      return -1;
+    }
+    if (reply_buf[3] == 1) {
+      /* IPv4 address */
+      len=0;
+      while (len < SOCKS5_LEN) {
+        r = recv(s, reply_buf+len, SOCKS5_LEN-len, 0);
+        if (r==0) {
+          show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n"); 
+          return -1;
+        }
+        if (r<0) {
+          show_msg(MSGWARN, "do_resolve: error reading address in SOCKS5 response\n"); 
+          return -1;
+        }
+        len += r;
+      }
+      *result_addr = ntohl(get_uint32(reply_buf));
+    } else if (reply_buf[3] == 3) {
+      size_t result_len;
+      len=0;
+      while (len < 1) {
+        r = recv(s, reply_buf+len, 1-len, 0);
+        if (r==0) {
+          show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n"); 
+          return -1;
+        }
+        if (r<0) {
+          show_msg(MSGWARN, "do_resolve: error reading address length in SOCKS5 response\n"); 
+          return -1;
+        }
+        len += r;
+      }
+      result_len = *(uint8_t*)(reply_buf);
+      **result_hostname = malloc(result_len+1);
+      len=0;
+      while (len < (int) result_len) {
+        r = recv(s, **result_hostname+len, result_len-len, 0);
+        if (r==0) {
+          show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n"); 
+          return -1;
+        }
+        if (r<0) {
+          show_msg(MSGWARN, "do_resolve: error reading hostname in SOCKS5 response\n");
+          return -1;
+        }
+        len += r;
+      }
+
+      (**result_hostname)[result_len] = '\0';
+    }
+
+  return 0;
+}
+
+static int
+do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
+           uint32_t *result_addr, const void *addr,
+           int version, int reverse, char **result_hostname)
+{
+  int s;
+  struct sockaddr_in socksaddr;
+  char *req, *cp=NULL;
+  int r, len, hslen;
+  char response_buf[RESPONSE_LEN];
+  const char *handshake="\x05\x01\x00";
+
+  show_msg(MSGDEBUG, "do_resolve: resolving %s\n", hostname);
+
+  /* Create SOCKS connection */
+  s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (s<0) {
+    show_msg(MSGWARN, "do_resolve: problem creating socket\n"); 
+    return -1;
+  }
+
+  /* Connect to SOCKS server */
+  memset(&socksaddr, 0, sizeof(socksaddr));
+  socksaddr.sin_family = AF_INET;
+  socksaddr.sin_port = htons(socksport);
+  socksaddr.sin_addr.s_addr = htonl(sockshost);
+  if (realconnect(s, (struct sockaddr*)&socksaddr, sizeof(socksaddr))) {
+    show_msg(MSGWARN, "do_resolve: error connecting to SOCKS server\n");
+    realclose(s);
+    return -1;
+  }
+
+  /* If a SOCKS5 connection, perform handshake */
+  if (version == 5) {
+    char method_buf[2];
+    hslen=3;
+    while (hslen) {
+      r = send(s, handshake, hslen, 0);
+      if (r<0) {
+        show_msg(MSGWARN, "do_resolve: error sending SOCKS5 method list.\n");
+        realclose(s);
+        return -1;
+      }
+      hslen -= r;
+      handshake += r;
+    }
+
+    len = 0;
+    while (len < METHODRESPONSE_LEN) {
+      r = recv(s, method_buf+len, METHODRESPONSE_LEN-len, 0);
+      if (r==0) {
+        show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS response\n");
+        realclose(s);
+        return -1;
+      }
+      if (r<0) {
+        show_msg(MSGWARN, "do_resolve: error reading SOCKS response\n");
+        realclose(s);
+        return -1;
+      }
+      len += r;
+    }
+
+    if (method_buf[0] != '\x05') {
+      show_msg(MSGWARN, "Unrecognized socks version: %u",
+              (unsigned)method_buf[0]);
+      realclose(s);
+      return -1;
+    }
+    if (method_buf[1] != '\x00') {
+      show_msg(MSGWARN, "Unrecognized socks authentication method: %u",
+              (unsigned)method_buf[1]);
+      realclose(s);
+      return -1;
+    }
+  }
+
+  /* Create SOCKS request */
+  if (reverse) {
+    if ((len = build_socks5_resolve_ptr_request(&req, addr))<0) {
+      show_msg(MSGWARN, "do_resolve: error generating reverse SOCKS request\n");
+      realclose(s);
+      return -1;
+    }
+  }else{
+    if ((len = build_socks4a_resolve_request(&req, "", hostname))<0) {
+      show_msg(MSGWARN, "do_resolve: error generating SOCKS request\n");
+      realclose(s);
+      return -1;
+    }
+  }
+
+  /* Send SOCKS request */
+  cp = req;
+  while (len) {
+    r = send(s, cp, len, 0);
+    if (r<0) {
+      show_msg(MSGWARN, "do_resolve: error sending SOCKS request\n"); 
+      free(req);
+      realclose(s);
+      return -1;
+    }
+    len -= r;
+    cp += r;
+  }
+  free(req);
+
+  /* Handle SOCKS Response */
+  if (reverse) {
+    if (parse_socks5_resolve_ptr_response(s, response_buf, RESPONSE_LEN,
+                                          result_addr, &result_hostname) < 0){
+      show_msg(MSGWARN, "do_resolve: error parsing SOCKS response\n");
+      realclose(s);
+      return -1;
+    }
+  }else{
+    /* Process SOCKS response */
+    len = 0;
+    while (len < RESPONSE_LEN) {
+      r = recv(s, response_buf+len, RESPONSE_LEN-len, 0);
+      if (r==0) {
+        show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS response\n");
+        realclose(s);
+        return -1;
+      }
+      if (r<0) {
+        show_msg(MSGWARN, "do_resolve: error reading SOCKS response\n");
+        realclose(s);
+        return -1;
+      }
+      len += r;
+    }
+    realclose(s);
+
+    /* Parse SOCKS response */
+    if (parse_socks4a_resolve_response(response_buf, RESPONSE_LEN, result_addr) < 0){
+      show_msg(MSGWARN, "do_resolve: error parsing SOCKS response\n");
+      return -1;
+    }
+  }
+
+
+  show_msg(MSGDEBUG, "do_resolve: success\n");
+
+  return 0;
+}
+
+struct hostent *
+our_gethostbyaddr(dead_pool *pool, const void *_addr, socklen_t len, int type)
+{
+  const struct in_addr *addr=_addr;
+  static struct hostent he;
+  uint32_t intaddr=0;
+  char *result_hostname=NULL;
+  int rc=0;
+  static char *addrs[2];
+  static char *aliases[2];
+
+  rc = do_resolve("", pool->sockshost, pool->socksport, &intaddr, addr,
+                  5 /*SOCKS5*/, 1 /*Reverse*/, &result_hostname);
+
+
+  if(rc != 0) {
+      show_msg(MSGWARN, "failed to reverse resolve: %s\n",
+               inet_ntoa(*((struct in_addr *)addr)));
+      result_hostname=NULL;
+      addrs[0] = NULL;
+      addrs[1] = NULL;
+  }else{
+      addrs[0] = (char *)addr;
+      addrs[1] = NULL;
+  }
+
+  if (result_hostname)
+    he.h_name = result_hostname;
+  else
+    he.h_name = inet_ntoa(*((struct in_addr *)addr));
+
+  aliases[0] = NULL;
+  aliases[1] = NULL;
+
+  he.h_aliases = aliases;
+  he.h_length    = len;
+  he.h_addrtype  = type;
+  he.h_addr_list = addrs;
+
+  if (result_hostname)
+      show_msg(MSGTEST, "our_gethostbyaddr: resolved '%s' to: '%s'\n",
+              inet_ntoa(*((struct in_addr *)he.h_addr)), result_hostname);
+
+  return &he;
+
+}
+
+struct hostent *
+our_gethostbyname(dead_pool *pool, const char *name)
+{
+  int pos;
+  static struct in_addr addr;
+  static struct hostent he;
+  static char *addrs[2];
+
+  show_msg(MSGTEST, "our_gethostbyname: '%s' requested\n", name);
+
+  pos = store_pool_entry(pool,(char *) name, &addr);
+  if(pos == -1) {
+      h_errno = HOST_NOT_FOUND;
+      return NULL;
+  }
+
+  addrs[0] = (char *)&addr;
+  addrs[1] = NULL;
+
+  he.h_name      = pool->entries[pos].name;
+  he.h_aliases   = NULL;
+  he.h_length    = 4;
+  he.h_addrtype  = AF_INET;
+  he.h_addr_list = addrs;
+
+  show_msg(MSGDEBUG, "our_gethostbyname: resolved '%s' to: '%s'\n", 
+           name, inet_ntoa(*((struct in_addr *)he.h_addr)));
+
+  return &he;
+}
+
+static struct hostent *
+alloc_hostent(int af)
+{
+    struct hostent *he = NULL;
+    char **addr_list = NULL;
+    void *addr = NULL;
+    char **aliases = NULL;
+
+    if(af != AF_INET && af != AF_INET6) {
+        return NULL;
+    }
+
+    /* Since the memory we allocate here will be free'd by freehostent and
+       that function is opaque to us, it's likely that we'll leak a little 
+       bit of memory here. */
+
+    he = malloc(sizeof(struct hostent));
+    addr_list = malloc(2 * sizeof(char *));
+    if(af == AF_INET6) {
+        addr = malloc(sizeof(struct in6_addr));
+    } else {
+        addr = malloc(sizeof(struct in_addr));
+    }
+    aliases = malloc(sizeof(char *));
+
+    if(he == NULL || addr_list == NULL || addr == NULL || aliases == NULL) {
+        if(he)
+            free(he);
+        if(addr_list)
+            free(addr_list);
+        if(addr)
+            free(addr);
+        if(aliases)
+            free(aliases);
+    }
+
+    he->h_name = NULL;
+    he->h_addr_list = addr_list;
+    he->h_addr_list[0] = addr;
+    he->h_addr_list[1] = NULL;
+    he->h_aliases = aliases;
+    he->h_aliases[0] = NULL;
+    he->h_length = af == AF_INET ? 4 : 16;
+    he->h_addrtype = af;
+
+    return he;
+}
+
+/* On Linux, there's no freehostent() anymore; we might as well implement
+   this ourselves. */
+
+static void
+free_hostent(struct hostent *he)
+{
+    int i;
+    if(he->h_name) {
+        free(he->h_name);
+    }
+    if(he->h_aliases) {
+        for(i=0; he->h_aliases[i] != NULL; i++) {
+            free(he->h_aliases[i]);
+        }
+        free(he->h_aliases);
+    }
+    if(he->h_addr_list) {
+        free(he->h_addr_list);
+    }
+    free(he);
+}
+
+int
+our_getaddrinfo(dead_pool *pool, const char *node, const char *service, 
+                void *hints, void *res)
+{
+    int pos;
+    struct in_addr addr;
+    char *ipstr;
+    int ret;
+
+    /* If "node" looks like a dotted-decimal ip address, then just call 
+       the real getaddrinfo; otherwise we'll need to get an address from 
+       our pool. */
+
+    /* TODO: work out what to do with AF_INET6 requests */
+
+#ifdef HAVE_INET_ATON
+    if(node && inet_aton(node, &addr) == 0 && memcmp(node,"*",1)) {
+#elif defined(HAVE_INET_ADDR)
+    /* If we're stuck with inet_addr, then getaddrinfo() won't work 
+       properly with 255.255.255.255 (= -1).  There's not much we can
+       do about this */
+    in_addr_t is_valid;
+    is_valid = inet_addr(node);
+    if(is_valid == -1) {
+#endif
+        pos = store_pool_entry(pool, (char *) node, &addr);
+        if(pos == -1) {
+            return EAI_NONAME;
+        } else {
+            ipstr = strdup(inet_ntoa(addr));
+            ret = realgetaddrinfo(ipstr, service, hints, res);
+            free(ipstr);
+        }
+    } else {
+        ret = realgetaddrinfo(node, service, hints, res);
+    }
+
+    show_msg(MSGTEST, "our_getaddrinfo: '%s' requested\n", service);
+    return ret;
+}
+
+struct hostent *
+our_getipnodebyname(dead_pool *pool, const char *name, int af, int flags, 
+                    int *error_num)
+{
+    int pos;
+    struct hostent *he = NULL;
+    int want_4in6 = 0;
+    char addr_convert_buf[80];
+    struct in_addr pool_addr;
+
+    if(af == AF_INET6) {
+        /* Caller has requested an AF_INET6 address, and is not prepared to
+           accept IPv4-mapped IPV6 addresses. There's nothing we can do to
+           service their request. */
+#ifdef OPENBSD
+        /* OpenBSD doesn't support the AI_V4MAPPED flag, so just return. */
+        return NULL;
+#else
+        if((flags & AI_V4MAPPED) == 0) {
+            show_msg(MSGWARN, "getipnodebyname: asked for V6 addresses only, "
+                     "but torsocks can't handle that\n");
+            *error_num = NO_RECOVERY;
+            return NULL;
+        } else {
+            want_4in6 = 1;
+        }
+#endif
+    }
+
+    pos = store_pool_entry(pool, (char *)name, &pool_addr);
+    if(pos == -1) {
+        *error_num = HOST_NOT_FOUND;
+        return NULL;
+    }
+
+    he = alloc_hostent(af);
+    if(he == NULL) {
+        show_msg(MSGERR, "getipnodebyname: failed to allocate hostent\n");
+        *error_num = NO_RECOVERY;
+        return NULL;
+    }
+
+    if(want_4in6) {
+        /* Convert the ipv4 address in *addr to an IPv4 in IPv6 mapped 
+           address. TODO: inet_ntoa() is thread-safe on Solaris but might
+           not be on other platforms. */
+        strcpy(addr_convert_buf, "::FFFF:");
+        strcpy(addr_convert_buf+7, inet_ntoa(pool_addr));
+        if(inet_pton(AF_INET6, addr_convert_buf, he->h_addr_list[0]) != 1) {
+            show_msg(MSGERR, "getipnodebyname: inet_pton() failed!\n");
+            free_hostent(he);
+            *error_num = NO_RECOVERY;
+            return NULL;
+        }
+    } else {
+        ((struct in_addr *) he->h_addr_list[0])->s_addr = pool_addr.s_addr;
+    }
+    he->h_name = strdup(name);
+
+    return he;
+}
+
+
diff --git a/src.old/dead_pool.h b/src.old/dead_pool.h
new file mode 100644
index 0000000..d6e3e10
--- /dev/null
+++ b/src.old/dead_pool.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (C) 2005 Total Information Security Ltd.                    *
+ *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef _DEAD_POOL_H
+#define _DEAD_POOL_H
+
+#include <config.h>
+
+extern int (*realconnect)(CONNECT_SIGNATURE);
+extern int (*realclose)(CLOSE_SIGNATURE);
+extern int (*realgetaddrinfo)(GETADDRINFO_SIGNATURE);
+
+struct struct_pool_ent {
+  unsigned int ip;
+  char name[256];
+};
+
+typedef struct struct_pool_ent pool_ent;
+
+struct struct_dead_pool {
+  pool_ent *entries;            /* Points to array of pool entries */
+  unsigned int n_entries;       /* Number of entries in the deadpool */
+  unsigned int deadrange_base;  /* Deadrange start IP in host byte order */
+  unsigned int deadrange_mask;  /* Deadrange netmask in host byte order */
+  unsigned int deadrange_size;  /* Number of IPs in the deadrange */
+  unsigned int write_pos;       /* Next position to use in the pool array */
+  unsigned int dead_pos;        /* Next 'unused' deadpool IP */
+  uint32_t sockshost;     
+  uint16_t socksport;
+  char pad[2];
+};
+
+typedef struct struct_dead_pool dead_pool;
+
+dead_pool *init_pool(unsigned int deadpool_size, struct in_addr deadrange_base, 
+    struct in_addr deadrange_mask, char *sockshost, uint16_t socksport);
+int is_dead_address(dead_pool *pool, uint32_t addr);
+char *get_pool_entry(dead_pool *pool, struct in_addr *addr);
+int search_pool_for_name(dead_pool *pool, const char *name);
+struct hostent *our_gethostbyname(dead_pool *pool, const char *name);
+struct hostent *our_gethostbyaddr(dead_pool *pool, const void *addr,
+                                  socklen_t len, int type);
+int our_getaddrinfo(dead_pool *pool, const char *node, const char *service, 
+    void *hints, void *res);
+struct hostent *our_getipnodebyname(dead_pool *pool, const char *name, 
+    int af, int flags, int *error_num);
+
+#endif /* _DEAD_POOL_H */
+
diff --git a/src.old/expansion_table.h b/src.old/expansion_table.h
new file mode 100644
index 0000000..14fabe1
--- /dev/null
+++ b/src.old/expansion_table.h
@@ -0,0 +1,125 @@
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (C) 2010 Alex Rosenberg <alex at ohmantics.net>                *
+ *   Copyright (C) 2011 Robert Hogan <robert at roberthogan.net>              *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#undef FUNC
+#undef FUNCD
+#undef FUND32
+#undef FUNCD64
+
+#ifdef SUPPORT_RES_API
+#define RES_FUNC    FUNC
+#define RES_FUNCD   FUNCD
+#define RES_FUNCD32 FUNCD32
+#define RES_FUNCD64 FUNCD64
+#else
+#define RES_FUNC    EMPTY_FUNC
+#define RES_FUNCD   EMPTY_FUNC
+#define RES_FUNCD32 EMPTY_FUNC
+#define RES_FUNCD64 EMPTY_FUNC
+#endif /* SUPPORT_RES_API */
+
+#define DNS_FUNC    FUNC
+#define DNS_FUNCD   FUNCD
+#define DNS_FUNCD32 FUNCD32
+#define DNS_FUNCD64 FUNCD64
+
+#define EMPTY_FUNC(e,r,s,n,b,m)
+
+#if defined(__APPLE__) || defined(__darwin__)
+#ifndef DARWIN_EXPANSION
+#define DARWIN_EXPANSION                  PATCH_TABLE_EXPANSION
+#endif /* DARWIN_EXPANSION */
+#define FUNCD(e,r,s,n,b,m)                DARWIN_EXPANSION(e,r,s,n,b,m)
+#if (__LP64__)
+#define FUNCD32(e,r,s,n,b,m)              EMPTY_FUNC(e,r,s,n,b,m)
+#define FUNCD64(e,r,s,n,b,m)              DARWIN_EXPANSION(e,r,s,n,b,m)
+/* This tests if we're building with 10.6 or later headers, not
+   if we're running on 10.6. We'd rather do the latter. */
+#ifdef MAC_OS_X_VERSION_10_6
+#define FUNCD64_106(e,r,s,n,b,m)          DARWIN_EXPANSION(e,r,s,n,b,m)
+#else
+#define FUNCD64_106(e,r,s,n,b,m)          EMPTY_FUNC(e,r,s,n,b,m)
+#endif /* MAC_OS_X_VERSION_10_6 */
+#else
+#define FUNCD32(e,r,s,n,b,m)              DARWIN_EXPANSION(e,r,s,n,b,m)
+#define FUNCD64(e,r,s,n,b,m)              EMPTY_FUNC(e,r,s,n,b,m)
+#define FUNCD64_106(e,r,s,n,b,m)          EMPTY_FUNC(e,r,s,n,b,m)
+#endif /* (__LP64__) */
+#else
+#define FUNCD(e,r,s,n,b,m)                EMPTY_FUNC(e,r,s,n,b,m)
+#define FUNCD32(e,r,s,n,b,m)              EMPTY_FUNC(e,r,s,n,b,m)
+#define FUNCD64(e,r,s,n,b,m)              EMPTY_FUNC(e,r,s,n,b,m)
+#define FUNCD64_106(e,r,s,n,b,m)          EMPTY_FUNC(e,r,s,n,b,m)
+#endif /* defined(__APPLE__) || defined(__darwin__) */
+#define FUNC(e,r,s,n,b,m)                 PATCH_TABLE_EXPANSION(e,r,s,n,b,m)
+
+/*           dlsym   return type         SIG/ARGS            C name                         base name            asm name    */
+/* res_init takes void, so we do that one manually. */
+/*RES_FUNC  (ERR,    int,                RES_INIT_,          res_init,                      res_init,            "res_init") */
+RES_FUNC    (ERR,    int,                RES_QUERY_,         res_query,                     res_query,           "res_query")
+RES_FUNC    (ERR,    int,                RES_SEARCH_,        res_search,                    res_search,          "res_search")
+RES_FUNC    (ERR,    int,                RES_SEND_,          res_send,                      res_send,            "res_send")
+RES_FUNC    (ERR,    int,                RES_QUERYDOMAIN_,   res_querydomain,               res_querydomain,     "res_querydomain")
+
+DNS_FUNC    (ERR,    struct hostent *,   GETHOSTBYNAME_,     gethostbyname,                 gethostbyname,       "gethostbyname")
+DNS_FUNC    (ERR,    struct hostent *,   GETHOSTBYADDR_,     gethostbyaddr,                 gethostbyaddr,       "gethostbyaddr")
+DNS_FUNC    (ERR,    int,                GETADDRINFO_,       getaddrinfo,                   getaddrinfo,         "getaddrinfo")
+/* getipnodebyname is deprecated so do not report an error if it is not available.*/
+DNS_FUNC    (WARN,    struct hostent *,  GETIPNODEBYNAME_,   getipnodebyname,               getipnodebyname,     "getipnodebyname")
+
+DNS_FUNC    (ERR,    ssize_t,            SENDTO_,            sendto,                        sendto,              "sendto")
+DNS_FUNCD32 (ERR,    ssize_t,            SENDTO_,            sendto_unix2003,               sendto,              "sendto$UNIX2003")
+DNS_FUNCD32 (ERR,    ssize_t,            SENDTO_,            sendto_nocancel_unix2003,      sendto,              "sendto$NOCANCEL$UNIX2003")
+DNS_FUNCD64 (ERR,    ssize_t,            SENDTO_,            sendto_nocancel,               sendto,              "sendto$NOCANCEL")
+
+DNS_FUNC    (ERR,    ssize_t,            SENDMSG_,           sendmsg,                       sendmsg,             "sendmsg")
+DNS_FUNCD32 (ERR,    ssize_t,            SENDMSG_,           sendmsg_unix2003,              sendmsg,             "sendmsg$UNIX2003")
+DNS_FUNCD32 (ERR,    ssize_t,            SENDMSG_,           sendmsg_nocancel_unix2003,     sendmsg,             "sendmsg$NOCANCEL$UNIX2003")
+DNS_FUNCD64 (ERR,    ssize_t,            SENDMSG_,           sendmsg_nocancel,              sendmsg,             "sendmsg$NOCANCEL")
+
+FUNC        (ERR,    int,                CONNECT_,           connect,                       connect,             "connect")
+FUNCD32     (ERR,    int,                CONNECT_,           connect_unix2003,              connect,             "connect$UNIX2003")
+FUNCD32     (ERR,    int,                CONNECT_,           connect_nocancel_unix2003,     connect,             "connect$NOCANCEL$UNIX2003")
+FUNCD64     (ERR,    int,                CONNECT_,           connect_nocancel,              connect,             "connect$NOCANCEL")
+
+#if !(defined(__APPLE__) || defined(__darwin__) && defined(MAX_OS_X_VERSION_10_6))
+/* see darwin_warts.c */
+FUNC        (ERR,    int,                SELECT_,            select,                        select,              "select")
+#endif
+FUNCD       (ERR,    int,                SELECT_,            select_darwinextsn,            select,              "select$DARWIN_EXTSN")
+FUNCD       (ERR,    int,                SELECT_,            select_darwinextsn_nocancel,   select,              "select$DARWIN_EXTSN$NOCANCEL")
+FUNCD32     (ERR,    int,                SELECT_,            select_unix2003,               select,              "select$UNIX2003")
+FUNCD32     (ERR,    int,                SELECT_,            select_nocancel_unix2003,      select,              "select$NOCANCEL$UNIX2003")
+FUNCD64     (ERR,    int,                SELECT_,            select_nocancel,               select,              "select$NOCANCEL")
+FUNCD64_106 (ERR,    int,                SELECT_,            select_1050,                   select,              "select$1050")
+
+FUNC        (ERR,    int,                POLL_,              poll,                          poll,                "poll")
+FUNCD32     (ERR,    int,                POLL_,              poll_unix2003,                 poll,                "poll$UNIX2003")
+FUNCD32     (ERR,    int,                POLL_,              poll_nocancel_unix2003,        poll,                "poll$NOCANCEL$UNIX2003")
+FUNCD64     (ERR,    int,                POLL_,              poll_nocancel,                 poll,                "poll$NOCANCEL")
+
+FUNC        (ERR,    int,                CLOSE_,             close,                         close,               "close")
+FUNCD32     (ERR,    int,                CLOSE_,             close_unix2003,                close,               "close$UNIX2003")
+FUNCD32     (ERR,    int,                CLOSE_,             close_nocancel_unix2003,       close,               "close$NOCANCEL$UNIX2003")
+FUNCD64     (ERR,    int,                CLOSE_,             close_nocancel,                close,               "close$NOCANCEL")
+
+FUNC        (ERR,    int,                GETPEERNAME_,       getpeername,                   getpeername,         "getpeername")
+FUNCD32     (ERR,    int,                GETPEERNAME_,       getpeername_unix2003,          getpeername,         "getpeername$UNIX2003")
diff --git a/src.old/parser.c b/src.old/parser.c
new file mode 100644
index 0000000..8f24be6
--- /dev/null
+++ b/src.old/parser.c
@@ -0,0 +1,872 @@
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
+ *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+/*
+
+   parser.c    - Parsing routines for torsocks.conf
+
+*/
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <config.h>
+
+#include "common.h"
+#include "parser.h"
+
+/* Global configuration variables */
+#define MAXLINE         BUFSIZ             /* Max length of conf line  */
+static struct serverent *currentcontext = NULL;
+
+static int handle_line(struct parsedfile *, char *, int);
+static int check_server(struct serverent *);
+static int tokenize(char *, int, char *[]);
+static int handle_path(struct parsedfile *, int, int, char *[]);
+static int handle_endpath(struct parsedfile *, int, int);
+static int handle_reaches(int, char *);
+static int handle_server(struct parsedfile *, int, char *);
+static int handle_type(struct parsedfile *config, int, char *);
+static int handle_port(struct parsedfile *config, int, char *);
+static int handle_local(struct parsedfile *, int, const char *);
+static int handle_tordns_enabled(struct parsedfile *, int, char *);
+static int handle_tordns_deadpool_range(struct parsedfile *, int, const char *);
+static int handle_tordns_cache_size(struct parsedfile *, char *);
+static int handle_defuser(struct parsedfile *, int, char *);
+static int handle_defpass(struct parsedfile *, int, char *);
+static int make_netent(char *value, struct netent **ent);
+
+int read_config (char *filename, struct parsedfile *config) {
+    FILE *conf;
+    char line[MAXLINE];
+    int rc = 0;
+    int lineno = 1;
+    struct serverent *server;
+
+   /* Clear out the structure */
+   memset(config, 0x0, sizeof(*config));
+
+   /* Initialization */
+   currentcontext = &(config->defaultserver);
+
+   /* Tordns defaults */
+   config->tordns_cache_size = 256;
+   config->tordns_enabled = 1;
+
+
+    /* If a filename wasn't provided, use the default */
+    if (filename == NULL) {
+        strncpy(line, CONF_FILE, sizeof(line) - 1);
+        /* Insure null termination */
+        line[sizeof(line) - 1] = (char) 0;
+        filename = line;
+        show_msg(MSGDEBUG, "Configuration file not provided by TORSOCKS_CONF_FILE "
+                "environment variable, attempting to use defaults in %s.\n", filename);
+    }
+
+    /* If there is no configuration file use reasonable defaults for Tor */
+    if ((conf = fopen(filename, "r")) == NULL) {
+        show_msg(MSGERR, "Could not open socks configuration file "
+                "(%s) errno (%d), assuming sensible defaults for Tor.\n", filename, errno);
+        memset(&(config->defaultserver), 0x0, sizeof(config->defaultserver));
+        check_server(&(config->defaultserver));
+        handle_local(config, 0, "127.0.0.0/255.0.0.0");
+        handle_local(config, 0, "10.0.0.0/255.0.0.0");
+        handle_local(config, 0, "192.168.0.0/255.255.0.0");
+        handle_local(config, 0, "172.16.0.0/255.240.0.0");
+        handle_local(config, 0, "169.254.0.0/255.255.0.0");
+        rc = 1; /* Severe errors reading configuration */
+    } else {
+        memset(&(config->defaultserver), 0x0, sizeof(config->defaultserver));
+
+        while (NULL != fgets(line, MAXLINE, conf)) {
+            /* This line _SHOULD_ end in \n so we  */
+            /* just chop off the \n and hand it on */
+            if (strlen(line) > 0)
+                line[strlen(line) - 1] = '\0';
+            handle_line(config, line, lineno);
+            lineno++;
+        }
+        fclose(conf);
+
+        /* Always add the 127.0.0.1/255.0.0.0 subnet to local */
+        handle_local(config, 0, "127.0.0.0/255.0.0.0");
+        /* We always consider this local, because many users' dsl
+          routers act as their DNS. */
+        handle_local(config, 0, "10.0.0.0/255.0.0.0");
+        handle_local(config, 0, "192.168.0.0/255.255.0.0");
+        handle_local(config, 0, "172.16.0.0/255.240.0.0");
+        handle_local(config, 0, "169.254.0.0/255.255.0.0");
+        handle_local(config, 0, "192.168.0.0/255.255.0.0");
+
+        /* Check default server */
+        check_server(&(config->defaultserver));
+        server = (config->paths);
+        while (server != NULL) {
+            check_server(server);
+            server = server->next;
+        }
+    }
+
+    /* Initialize tordns deadpool_range if not supplied */
+    if(config->tordns_deadpool_range == NULL) {
+        handle_tordns_deadpool_range(config, 0, "127.0.69.0/255.255.255.0");
+    }
+
+    return(rc);
+}
+
+/* Check server entries (and establish defaults) */
+static int check_server(struct serverent *server) {
+
+    /* Default to the default Tor Socks port */
+    if (server->port == 0) {
+        server->port = 9050;
+    }
+
+    /* Default to a presumably local installation of Tor */
+    if (server->address == NULL) {
+        server->address = strdup("127.0.0.1");
+    }
+
+    /* Default to SOCKS V4 */
+    if (server->type == 0) {
+        server->type = 4;
+    }
+
+    return(0);
+}
+
+
+
+static int handle_line(struct parsedfile *config, char *line, int lineno) {
+    char *words[10];
+    static char savedline[MAXLINE];
+    int   nowords = 0, i;
+
+    /* Save the input string */
+    strncpy(savedline, line, MAXLINE - 1);
+    savedline[MAXLINE - 1] = (char) 0;
+    /* Tokenize the input string */
+    nowords = tokenize(line, 10, words);
+
+    /* Set the spare slots to an empty string to simplify */
+    /* processing                                         */
+    for (i = nowords; i < 10; i++)
+        words[i] = NULL;
+
+    if (nowords > 0) {
+        /* Now this can either be a "path" block starter or */
+        /* ender, otherwise it has to be a pair (<name> =   */
+        /* <value>)                                         */
+        if (!strcmp(words[0], "path")) {
+            handle_path(config, lineno, nowords, words);
+        } else if (!strcmp(words[0], "}")) {
+            handle_endpath(config, lineno, nowords);
+        } else {
+            /* Has to be a pair */
+            if ((nowords != 3) || (strcmp(words[1], "="))) {
+                show_msg(MSGERR, "Malformed configuration pair "
+                       "on line %d in configuration "
+                       "file, \"%s\"\n", lineno, savedline);
+            } else if (!strcmp(words[0], "reaches")) {
+                handle_reaches(lineno, words[2]);
+            } else if (!strcmp(words[0], "server")) {
+                handle_server(config, lineno, words[2]);
+            } else if (!strcmp(words[0], "server_port")) {
+                handle_port(config, lineno, words[2]);
+            } else if (!strcmp(words[0], "server_type")) {
+                handle_type(config, lineno, words[2]);
+            } else if (!strcmp(words[0], "default_user")) {
+                handle_defuser(config, lineno, words[2]);
+            } else if (!strcmp(words[0], "default_pass")) {
+                handle_defpass(config, lineno, words[2]);
+            } else if (!strcmp(words[0], "local")) {
+                handle_local(config, lineno, words[2]);
+            } else if (!strcmp(words[0], "tordns_enable")) {
+                handle_tordns_enabled(config, lineno, words[2]);
+            } else if (!strcmp(words[0], "tordns_deadpool_range")) {
+                handle_tordns_deadpool_range(config, lineno, words[2]);
+            } else if (!strcmp(words[0], "tordns_cache_size")) {
+                handle_tordns_cache_size(config, words[2]);
+            } else {
+                show_msg(MSGERR, "Invalid pair type (%s) specified "
+                       "on line %d in configuration file, "
+                       "\"%s\"\n", words[0], lineno,
+                       savedline);
+            }
+        }
+    }
+
+    return(0);
+}
+
+/* This routines breaks up input lines into tokens  */
+/* and places these tokens into the array specified */
+/* by tokens                                        */
+static int tokenize(char *line, int arrsize, char *tokens[]) {
+    int tokenno = -1;
+    int finished = 0;
+
+    /* Whitespace is ignored before and after tokens     */
+    while ((tokenno < (arrsize - 1)) &&
+          (line = line + strspn(line, " \t")) &&
+           (*line != (char) 0) &&
+           (!finished)) {
+        tokenno++;
+        tokens[tokenno] = line;
+        line = line + strcspn(line, " \t");
+        *line = (char) 0;
+        line++;
+
+        /* We ignore everything after a # */
+        if (*tokens[tokenno] == '#') {
+            finished = 1;
+            tokenno--;
+        }
+    }
+
+    return(tokenno + 1);
+}
+
+static int handle_path(struct parsedfile *config, int lineno, int nowords, char *words[]) {
+    struct serverent *newserver;
+
+    if ((nowords != 2) || (strcmp(words[1], "{"))) {
+        show_msg(MSGERR, "Badly formed path open statement on line %d "
+               "in configuration file (should look like "
+               "\"path {\")\n", lineno);
+    } else if (currentcontext != &(config->defaultserver)) {
+        /* You cannot nest path statements so check that */
+        /* the current context is defaultserver          */
+        show_msg(MSGERR, "Path statements cannot be nested on line %d "
+               "in configuration file\n", lineno);
+    } else {
+        /* Open up a new serverent, put it on the list   */
+        /* then set the current context                  */
+        if ((newserver = malloc(sizeof(*newserver))) == NULL)
+            exit(-1);
+
+        /* Initialize the structure */
+        show_msg(MSGDEBUG, "New server structure from line %d in configuration file going "
+                           "to 0x%08x\n", lineno, newserver);
+        memset(newserver, 0x0, sizeof(*newserver));
+        newserver->next = config->paths;
+        newserver->lineno = lineno;
+        config->paths = newserver;
+        currentcontext = newserver;
+    }
+
+    return(0);
+}
+
+static int handle_endpath(struct parsedfile *config, int lineno, int nowords) {
+
+    if (nowords != 1) {
+        show_msg(MSGERR, "Badly formed path close statement on line "
+               "%d in configuration file (should look like "
+               "\"}\")\n", lineno);
+    } else {
+        currentcontext = &(config->defaultserver);
+    }
+
+    /* We could perform some checking on the validty of data in */
+    /* the completed path here, but thats what verifyconf is    */
+    /* designed to do, no point in weighing down libtorsocks      */
+
+    return(0);
+}
+
+static int handle_reaches(int lineno, char *value) {
+    int rc;
+    struct netent *ent;
+
+    rc = make_netent(value, &ent);
+    switch(rc) {
+        case 1:
+            show_msg(MSGERR, "Local network specification (%s) is not validly "
+                   "constructed in reach statement on line "
+                   "%d in configuration "
+                   "file\n", value, lineno);
+            return(0);
+            break;
+        case 2:
+            show_msg(MSGERR, "IP in reach statement "
+                   "network specification (%s) is not valid on line "
+                   "%d in configuration file\n", value, lineno);
+            return(0);
+            break;
+        case 3:
+            show_msg(MSGERR, "SUBNET in reach statement "
+                   "network specification (%s) is not valid on "
+                   "line %d in configuration file\n", value,
+                   lineno);
+            return(0);
+            break;
+        case 4:
+            show_msg(MSGERR, "IP (%s) & ", inet_ntoa(ent->localip));
+            show_msg(MSGERR, "SUBNET (%s) != IP on line %d in "
+                   "configuration file, ignored\n",
+                   inet_ntoa(ent->localnet), lineno);
+            return(0);
+         break;
+        case 5:
+            show_msg(MSGERR, "Start port in reach statement "
+                    "network specification (%s) is not valid on line "
+                    "%d in configuration file\n", value, lineno);
+            return(0);
+            break;
+        case 6:
+            show_msg(MSGERR, "End port in reach statement "
+                    "network specification (%s) is not valid on line "
+                    "%d in configuration file\n", value, lineno);
+            return(0);
+            break;
+        case 7:
+            show_msg(MSGERR, "End port in reach statement "
+                    "network specification (%s) is less than the start "
+                    "port on line %d in configuration file\n", value, 
+                    lineno);
+            return(0);
+            break;
+    }
+
+    /* The entry is valid so add it to linked list */
+    ent -> next = currentcontext -> reachnets;
+    currentcontext -> reachnets = ent;
+
+    return(0);
+}
+
+static int handle_server(struct parsedfile *config, int lineno, char *value) {
+    char *ip;
+
+    ip = strsplit(NULL, &value, " ");
+
+    /* We don't verify this ip/hostname at this stage, */
+    /* its resolved immediately before use in torsocks.c */
+    if (currentcontext->address == NULL)
+        currentcontext->address = strdup(ip);
+    else {
+        if (currentcontext == &(config->defaultserver))
+            show_msg(MSGERR, "Only one default SOCKS server "
+                   "may be specified at line %d in "
+                   "configuration file\n", lineno);
+        else
+            show_msg(MSGERR, "Only one SOCKS server may be specified "
+                   "per path on line %d in configuration "
+                   "file. (Path begins on line %d)\n",
+                   lineno, currentcontext->lineno);
+    }
+
+    return(0);
+}
+
+static int handle_port(struct parsedfile *config, int lineno, char *value) {
+
+    if (currentcontext->port != 0) {
+        if (currentcontext == &(config->defaultserver))
+            show_msg(MSGERR, "Server port may only be specified "
+                   "once for default server, at line %d "
+                   "in configuration file\n", lineno);
+        else
+            show_msg(MSGERR, "Server port may only be specified "
+                   "once per path on line %d in configuration "
+                   "file. (Path begins on line %d)\n",
+                   lineno, currentcontext->lineno);
+    } else {
+        errno = 0;
+        currentcontext->port = (unsigned short int)
+                  (strtol(value, (char **)NULL, 10));
+        if ((errno != 0) || (currentcontext->port == 0)) {
+            show_msg(MSGERR, "Invalid server port number "
+                   "specified in configuration file "
+                   "(%s) on line %d\n", value, lineno);
+            currentcontext->port = 0;
+        }
+    }
+
+    return(0);
+}
+
+static int handle_defuser(struct parsedfile *config, int lineno, char *value) {
+
+    if (currentcontext->defuser != NULL) {
+        if (currentcontext == &(config->defaultserver))
+            show_msg(MSGERR, "Default username may only be specified "
+                   "once for default server, at line %d "
+                   "in configuration file\n", lineno);
+        else
+            show_msg(MSGERR, "Default username may only be specified "
+                   "once per path on line %d in configuration "
+                   "file. (Path begins on line %d)\n",
+                   lineno, currentcontext->lineno);
+    } else {
+        currentcontext->defuser = strdup(value);
+    }
+
+    return(0);
+}
+
+static int handle_defpass(struct parsedfile *config, int lineno, char *value) {
+
+    if (currentcontext->defpass != NULL) {
+        if (currentcontext == &(config->defaultserver))
+            show_msg(MSGERR, "Default password may only be specified "
+                   "once for default server, at line %d "
+                   "in configuration file\n", lineno);
+        else
+            show_msg(MSGERR, "Default password may only be specified "
+                   "once per path on line %d in configuration "
+                   "file. (Path begins on line %d)\n",
+                   lineno, currentcontext->lineno);
+    } else {
+        currentcontext->defpass = strdup(value);
+    }
+
+    return(0);
+}
+
+static int handle_type(struct parsedfile *config, int lineno, char *value) {
+
+    if (currentcontext->type != 0) {
+        if (currentcontext == &(config->defaultserver))
+            show_msg(MSGERR, "Server type may only be specified "
+                   "once for default server, at line %d "
+                   "in configuration file\n", lineno);
+        else
+            show_msg(MSGERR, "Server type may only be specified "
+                   "once per path on line %d in configuration "
+                   "file. (Path begins on line %d)\n",
+                   lineno, currentcontext->lineno);
+    } else {
+        errno = 0;
+        currentcontext->type = (int) strtol(value, (char **)NULL, 10);
+        if ((errno != 0) || (currentcontext->type == 0) ||
+            ((currentcontext->type != 4) && (currentcontext->type != 5))) {
+            show_msg(MSGERR, "Invalid server type (%s) "
+                   "specified in configuration file "
+                   "on line %d, only 4 or 5 may be "
+                   "specified\n", value, lineno);
+            currentcontext->type = 0;
+        }
+    }
+
+    return(0);
+}
+
+static int handle_flag(char *value) 
+{
+    if(!strcasecmp(value, "true") || !strcasecmp(value, "yes")  
+                                  || !strcmp(value, "1")) {
+        return 1;
+    } else if (!strcasecmp(value, "false") || !strcasecmp(value, "no") 
+                                           || !strcmp(value, "0")) {
+        return 0;
+    } else {
+        return -1;
+    }
+}
+
+static int handle_tordns_enabled(struct parsedfile *config, int lineno,
+                           char *value)
+{
+    int val = handle_flag(value);
+    if(val == -1) {
+        show_msg(MSGERR, "Invalid value %s supplied for tordns_enabled at "
+                 "line %d in config file, IGNORED\n", value, lineno);
+    } else {
+        config->tordns_enabled = val;
+    }
+    return 0;
+}
+
+static int handle_tordns_cache_size(struct parsedfile *config,
+                           char *value)
+{
+    char *endptr;
+    long size = strtol(value, &endptr, 10);
+    if(*endptr != '\0') {
+        show_msg(MSGERR, "Error parsing integer value for "
+                 "tordns_cache_size (%s), using default %d\n", 
+                 value, config->tordns_cache_size);
+    } else if(size < 128) {
+        show_msg(MSGERR, "The value supplied for tordns_cache_size (%d) "
+                 "is too small (<128), using default %d\n", size, 
+                 config->tordns_cache_size);
+    } else if(size > 4096) {
+        show_msg(MSGERR, "The value supplied for tordns_cache_range (%d) "
+                 "is too large (>4096), using default %d\n", size, 
+                 config->tordns_cache_size);
+    } else {
+        config->tordns_cache_size = size;
+    }
+    return 0;
+}
+
+static int handle_tordns_deadpool_range(struct parsedfile *config, int lineno, 
+                           const char *value)
+{
+    int rc;
+    struct netent *ent;
+
+    if (config->tordns_deadpool_range != NULL) {
+        show_msg(MSGERR, "Only one 'deadpool' entry permitted, found a "
+               "second at line %d in configuration file.\n");
+        return(0);
+    }
+
+    if (currentcontext != &(config->defaultserver)) {
+        show_msg(MSGERR, "Deadpool cannot be specified in path "
+               "block at line %d in configuration file. "
+               "(Path block started at line %d)\n",
+               lineno, currentcontext->lineno);
+        return(0);
+    }
+
+    rc = make_netent((char *)value, &ent);
+    /* This is copied from handle_local and should probably be folded into
+       a generic whinge() function or something */
+    switch(rc) {
+        case 1:
+            show_msg(MSGERR, "The deadpool specification (%s) is not validly "
+                   "constructed on line %d in configuration "
+                   "file\n", value, lineno);
+            return(0);
+            break;
+        case 2:
+            show_msg(MSGERR, "IP for deadpool "
+                   "network specification (%s) is not valid on line "
+                   "%d in configuration file\n", value, lineno);
+            return(0);
+            break;
+        case 3:
+            show_msg(MSGERR, "SUBNET for " 
+                   "deadpool network specification (%s) is not valid on "
+                   "line %d in configuration file\n", value, 
+                   lineno);
+            return(0);
+            break;
+        case 4:
+            show_msg(MSGERR, "IP (%s) & ", inet_ntoa(ent->localip));
+            show_msg(MSGERR, "SUBNET (%s) != IP on line %d in "
+                   "configuration file, ignored\n",
+                   inet_ntoa(ent->localnet), lineno);
+            return(0);
+        case 5:
+        case 6:
+        case 7:
+            show_msg(MSGERR, "Port specification is invalid and "
+                   "not allowed in deadpool specification "
+               "(%s) on line %d in configuration file\n",
+                   value, lineno);
+            return(0);
+         break;
+    }
+    if (ent->startport || ent->endport) {
+        show_msg(MSGERR, "Port specification is "
+           "not allowed in deadpool specification "
+           "(%s) on line %d in configuration file\n",
+           value, lineno);
+        return(0);
+    }
+
+    config->tordns_deadpool_range = ent;
+    return 0;
+}
+
+static int handle_local(struct parsedfile *config, int lineno, const char *value) {
+    int rc;
+    struct netent *ent;
+
+    if (currentcontext != &(config->defaultserver)) {
+        show_msg(MSGERR, "Local networks cannot be specified in path "
+               "block at line %d in configuration file. "
+               "(Path block started at line %d)\n",
+               lineno, currentcontext->lineno);
+        return(0);
+    }
+
+    rc = make_netent((char *)value, &ent);
+    switch(rc) {
+        case 1:
+            show_msg(MSGERR, "Local network specification (%s) is not validly "
+                   "constructed on line %d in configuration "
+                   "file\n", value, lineno);
+            return(0);
+            break;
+        case 2:
+            show_msg(MSGERR, "IP for local "
+                   "network specification (%s) is not valid on line "
+                   "%d in configuration file\n", value, lineno);
+            return(0);
+            break;
+        case 3:
+            show_msg(MSGERR, "SUBNET for "
+                   "local network specification (%s) is not valid on "
+                   "line %d in configuration file\n", value,
+                   lineno);
+            return(0);
+            break;
+        case 4:
+            show_msg(MSGERR, "IP (%s) & ", inet_ntoa(ent->localip));
+            show_msg(MSGERR, "SUBNET (%s) != IP on line %d in "
+                   "configuration file, ignored\n",
+                   inet_ntoa(ent->localnet), lineno);
+            return(0);
+        case 5:
+        case 6:
+        case 7:
+            show_msg(MSGERR, "Port specification is invalid and "
+                   "not allowed in local network specification "
+               "(%s) on line %d in configuration file\n",
+                   value, lineno);
+            return(0);
+         break;
+    }
+
+    if (ent->startport || ent->endport) {
+        show_msg(MSGERR, "Port specification is "
+              "not allowed in local network specification "
+              "(%s) on line %d in configuration file\n",
+              value, lineno);
+        return(0);
+    }
+
+    /* The entry is valid so add it to linked list */
+    ent -> next = config->localnets;
+    (config->localnets) = ent;
+
+    return(0);
+}
+
+/* Construct a netent given a string like                             */
+/* "198.126.0.1[:portno[-portno]]/255.255.255.0"                      */
+int make_netent(char *value, struct netent **ent) {
+    char *ip;
+    char *subnet;
+    char *startport = NULL;
+    char *endport = NULL;
+    char *badchar;
+    char separator;
+    static char buf[200];
+    char *split;
+
+   /* Get a copy of the string so we can modify it */
+    strncpy(buf, value, sizeof(buf) - 1);
+    buf[sizeof(buf) - 1] = (char) 0;
+    split = buf;
+
+   /* Now rip it up */
+   ip = strsplit(&separator, &split, "/:");
+   if (separator == ':') {
+      /* We have a start port */
+      startport = strsplit(&separator, &split, "-/");
+      if (separator == '-') 
+         /* We have an end port */
+         endport = strsplit(&separator, &split, "/");
+   }
+   subnet = strsplit(NULL, &split, " \n");
+
+   if ((ip == NULL) || (subnet == NULL)) {
+      /* Network specification not validly constructed */
+      return(1);
+   }
+
+   /* Allocate the new entry */
+   if ((*ent = (struct netent *) malloc(sizeof(struct netent)))
+      == NULL) {
+      /* If we couldn't malloc some storage, leave */
+      exit(1);
+   }
+
+   show_msg(MSGDEBUG, "New network entry for %s going to 0x%08x\n", ip, *ent);
+
+   if (!startport)
+      (*ent)->startport = 0;
+   if (!endport)
+      (*ent)->endport = 0;
+
+#ifdef HAVE_INET_ADDR
+   if (((*ent)->localip.s_addr = inet_addr(ip)) == -1) {
+#elif defined(HAVE_INET_ATON)
+   if (!(inet_aton(ip, &((*ent)->localip)))) {
+#endif
+      /* Badly constructed IP */
+      free(*ent);
+      return(2);
+   }
+#ifdef HAVE_INET_ADDR
+   else if (((*ent)->localnet.s_addr = inet_addr(subnet)) == -1) {
+#elif defined(HAVE_INET_ATON)
+   else if (!(inet_aton(subnet, &((*ent)->localnet)))) {
+#endif
+      /* Badly constructed subnet */
+      free(*ent);
+      return(3);
+   } else if (((*ent)->localip.s_addr &
+          (*ent)->localnet.s_addr) != 
+                   (*ent)->localip.s_addr) {
+      /* Subnet and Ip != Ip */
+      free(*ent);
+      return(4);
+   } else if (startport && 
+              (!((*ent)->startport = strtol(startport, &badchar, 10)) || 
+               (*badchar != 0) || ((*ent)->startport > 65535))) {
+      /* Bad start port */
+      free(*ent);
+      return(5);
+   } else if (endport && 
+              (!((*ent)->endport = strtol(endport, &badchar, 10)) || 
+               (*badchar != 0) || ((*ent)->endport > 65535))) {
+      /* Bad end port */
+      free(*ent);
+      return(6);
+   } else if (((*ent)->startport > (*ent)->endport) && !(startport && !endport)) {
+      /* End port is less than start port */
+      free(*ent);
+      return(7);
+   }
+
+   if (startport && !endport)
+      (*ent)->endport = (*ent)->startport;
+
+    return(0);
+}
+
+int is_local(struct parsedfile *config, struct in_addr *testip) {
+    struct netent *ent;
+    char buf[16];
+    inet_ntop(AF_INET, testip, buf, sizeof(buf));
+    show_msg(MSGDEBUG, "checking if address: %s is local"
+                        "\n",
+                        buf);
+
+    for (ent = (config->localnets); ent != NULL; ent = ent -> next) {
+        inet_ntop(AF_INET, &ent->localnet, buf, sizeof(buf));
+        show_msg(MSGDEBUG, "localnet addr: %s"
+                            "\n",
+                            buf);
+        inet_ntop(AF_INET, &ent->localip, buf, sizeof(buf));
+        show_msg(MSGDEBUG, "localip addr: %s"
+                            "\n",
+                            buf);
+        show_msg(MSGDEBUG, "result testip->s_addr & ent->localnet.s_addr : %i"
+                            "\n",
+                            testip->s_addr & ent->localnet.s_addr);
+        show_msg(MSGDEBUG, "result ent->localip.s_addr & ent->localnet.s_addr : %i"
+                            "\n",
+                            ent->localip.s_addr & ent->localnet.s_addr);
+        show_msg(MSGDEBUG, "result ent->localip.s_addr : %i"
+                            "\n",
+                            ent->localip.s_addr);
+        if ((testip->s_addr & ent->localnet.s_addr) ==
+            (ent->localip.s_addr & ent->localnet.s_addr))  {
+            show_msg(MSGDEBUG, "address: %s is local"
+                                "\n",
+                                buf);
+            return(0);
+        }
+    }
+
+    inet_ntop(AF_INET, testip, buf, sizeof(buf));
+    show_msg(MSGDEBUG, "address: %s is not local"
+                        "\n",
+                        buf);
+    return(1);
+}
+
+/* Find the appropriate server to reach an ip */
+int pick_server(struct parsedfile *config, struct serverent **ent, 
+                struct in_addr *ip, unsigned int port) {
+    struct netent *net;
+   char ipbuf[64];
+
+   show_msg(MSGDEBUG, "Picking appropriate server for %s\n", inet_ntoa(*ip));
+    *ent = (config->paths);
+    while (*ent != NULL) {
+        /* Go through all the servers looking for one */
+        /* with a path to this network                */
+        show_msg(MSGDEBUG, "Checking SOCKS server %s\n", 
+                ((*ent)->address ? (*ent)->address : "(No Address)"));
+        net = (*ent)->reachnets;
+        while (net != NULL) {
+         strcpy(ipbuf, inet_ntoa(net->localip));
+         show_msg(MSGDEBUG, "Server can reach %s/%s\n", 
+                  ipbuf, inet_ntoa(net->localnet));
+            if (((ip->s_addr & net->localnet.s_addr) ==
+                (net->localip.s_addr & net->localnet.s_addr)) &&
+                (!net->startport || 
+                ((net->startport <= port) && (net->endport >= port))))  
+            {
+                show_msg(MSGDEBUG, "This server can reach target\n");
+                    /* Found the net, return */
+                    return(0);
+            }
+            net = net->next;
+        }
+        (*ent) = (*ent)->next;
+    }
+
+    *ent = &(config->defaultserver);
+
+    return(0);
+}
+
+/* This function is very much like strsep, it looks in a string for */
+/* a character from a list of characters, when it finds one it      */
+/* replaces it with a \0 and returns the start of the string        */
+/* (basically spitting out tokens with arbitrary separators). If no */
+/* match is found the remainder of the string is returned and       */
+/* the start pointer is set to be NULL. The difference between      */
+/* standard strsep and this function is that this one will          */
+/* set *separator to the character separator found if it isn't null */
+char *strsplit(char *separator, char **text, const char *search) {
+   unsigned int len;
+   char *ret;
+
+   ret = *text;
+
+    if (*text == NULL) {
+      if (separator)
+         *separator = '\0';
+      return(NULL);
+    } else {
+      len = strcspn(*text, search);
+      if (len == strlen(*text)) {
+         if (separator)
+            *separator = '\0';
+         *text = NULL;
+      } else {
+         *text = *text + len;
+         if (separator)
+            *separator = **text;
+         **text = '\0';
+         *text = *text + 1;
+      }
+    }
+
+   return(ret);
+}
diff --git a/src.old/parser.h b/src.old/parser.h
new file mode 100644
index 0000000..91e6d04
--- /dev/null
+++ b/src.old/parser.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
+ *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+/* parser.h - Structures, functions and global variables for the
+   torsocks parsing routines                                       */
+
+#ifndef _PARSER_H
+
+#define _PARSER_H 1
+
+/* Structure definitions */
+
+/* Structure representing one server specified in the config */
+struct serverent {
+    int lineno;               /* Line number in conf file this path started on */
+    char *address;            /* Address/hostname of server */
+    int port;                 /* Port number of server */
+    int type;                 /* Type of server (4/5) */
+    char *defuser;            /* Default username for this socks server */
+    char *defpass;            /* Default password for this socks server */
+    struct netent *reachnets; /* Linked list of nets from this server */
+    struct serverent *next;   /* Pointer to next server entry */
+};
+
+/* Structure representing a network */
+struct netent {
+   struct in_addr localip;    /* Base IP of the network */
+   struct in_addr localnet;   /* Mask for the network */
+   unsigned long startport;   /* Range of ports for the */
+   unsigned long endport;     /* network                */
+   struct netent *next;       /* Pointer to next network entry */
+};
+
+/* Structure representing a complete parsed file */
+struct parsedfile {
+   struct netent *localnets;
+   struct serverent defaultserver;
+   struct serverent *paths;
+   int tordns_enabled;
+   int tordns_failopen;
+   unsigned int tordns_cache_size;
+   struct netent *tordns_deadpool_range;
+};
+
+/* Functions provided by parser module */
+int read_config(char *, struct parsedfile *);
+int is_local(struct parsedfile *, struct in_addr *);
+int pick_server(struct parsedfile *, struct serverent **, struct in_addr *, unsigned int port);
+char *strsplit(char *separator, char **text, const char *search);
+
+#endif
diff --git a/src.old/socks.c b/src.old/socks.c
new file mode 100644
index 0000000..8497728
--- /dev/null
+++ b/src.old/socks.c
@@ -0,0 +1,633 @@
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
+ *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+/* PreProcessor Defines */
+#include <config.h>
+
+/*Defining _NONSTD_SOURCE causes library and kernel calls to behave as closely
+to Mac OS X 10.3's library and kernel calls as possible.*/
+#if defined(__APPLE__) || defined(__darwin__)
+/*
+From 'man compat' in OSX:
+64-BIT COMPILATION
+     When compiling for 64-bit architectures, the __LP64__ macro will be defined to 1, and UNIX conformance
+     is always on (the _DARWIN_FEATURE_UNIX_CONFORMANCE macro will also be defined to the SUS conformance
+     level).  Defining _NONSTD_SOURCE will cause a compilation error.
+*/
+#if !defined(__LP64__)
+#define _NONSTD_SOURCE 1
+#endif
+#include <sys/socket.h>
+#endif
+
+
+#ifdef USE_GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+/* Header Files */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <string.h>
+#include <strings.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <pwd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdarg.h>
+#if !defined(__APPLE__) && !defined(__darwin__)
+#include <sys/socket.h>
+#endif
+#include <resolv.h>
+
+#include "common.h"
+#include "dead_pool.h"
+#include "parser.h"
+#include "socks.h"
+
+static int connect_server(struct connreq *conn);
+static int send_socks_request(struct connreq *conn);
+static int send_socksv4_request(struct connreq *conn);
+static int send_socksv5_method(struct connreq *conn);
+static int send_socksv5_connect(struct connreq *conn);
+static int send_buffer(struct connreq *conn);
+static int recv_buffer(struct connreq *conn);
+static int read_socksv5_method(struct connreq *conn);
+static int read_socksv4_req(struct connreq *conn);
+static int read_socksv5_connect(struct connreq *conn);
+static int read_socksv5_auth(struct connreq *conn);
+static int send_socksv4a_request(struct connreq *conn, const char *onion_host);
+
+
+dead_pool *pool = NULL;
+struct connreq *requests = NULL;
+
+struct connreq *new_socks_request(int sockid, struct sockaddr_in *connaddr,
+                                         struct sockaddr_in *serveraddr,
+                                         struct serverent *path)
+{
+    struct connreq *newconn;
+
+    if ((newconn = malloc(sizeof(*newconn))) == NULL) {
+        /* Could not malloc, we're stuffed */
+        show_msg(MSGERR, "Could not allocate memory for new socks request\n");
+        return(NULL);
+    }
+
+    /* Add this connection to be proxied to the list */
+    memset(newconn, 0x0, sizeof(*newconn));
+    newconn->sockid = sockid;
+    newconn->state = UNSTARTED;
+    newconn->path = path;
+    memcpy(&(newconn->connaddr), connaddr, sizeof(newconn->connaddr));
+    memcpy(&(newconn->serveraddr), serveraddr, sizeof(newconn->serveraddr));
+    newconn->next = requests;
+    requests = newconn;
+
+    return(newconn);
+}
+
+void kill_socks_request(struct connreq *conn)
+{
+    struct connreq *connnode;
+
+    if (requests == conn)
+        requests = conn->next;
+    else {
+        for (connnode = requests; connnode != NULL; connnode = connnode->next) {
+            if (connnode->next == conn) {
+                connnode->next = conn->next;
+                break;
+            }
+        }
+    }
+
+    free(conn);
+}
+
+struct connreq *find_socks_request(int sockid, int includefinished)
+{
+    struct connreq *connnode;
+
+    for (connnode = requests; connnode != NULL; connnode = connnode->next) {
+        if (connnode->sockid == sockid) {
+            if (((connnode->state == FAILED) || (connnode->state == DONE)) &&
+                !includefinished)
+                break;
+            else
+                return(connnode);
+        }
+    }
+
+    return(NULL);
+}
+
+int handle_request(struct connreq *conn)
+{
+    int rc = 0;
+    int i = 0;
+
+    show_msg(MSGDEBUG, "Beginning handle loop for socket %d\n", conn->sockid);
+
+    while ((rc == 0) &&
+            (conn->state != FAILED) &&
+            (conn->state != DONE) &&
+            (i++ < 20)) {
+        show_msg(MSGDEBUG, "In request handle loop for socket %d, "
+                           "current state of request is %d\n", conn->sockid,
+                           conn->state);
+        switch(conn->state) {
+          case UNSTARTED:
+          case CONNECTING:
+              rc = connect_server(conn);
+              break;
+          case CONNECTED:
+              rc = send_socks_request(conn);
+              break;
+          case SENDING:
+              rc = send_buffer(conn);
+              break;
+          case RECEIVING:
+              rc = recv_buffer(conn);
+              break;
+          case SENTV4REQ:
+              show_msg(MSGDEBUG, "Receiving reply to SOCKS V4 connect request\n");
+              conn->datalen = sizeof(struct sockrep);
+              conn->datadone = 0;
+              conn->state = RECEIVING;
+              conn->nextstate = GOTV4REQ;
+              break;
+          case GOTV4REQ:
+              rc = read_socksv4_req(conn);
+              break;
+          case SENTV5METHOD:
+              show_msg(MSGDEBUG, "Receiving reply to SOCKS V5 method negotiation\n");
+              conn->datalen = 2;
+              conn->datadone = 0;
+              conn->state = RECEIVING;
+              conn->nextstate = GOTV5METHOD;
+              break;
+          case GOTV5METHOD:
+              rc = read_socksv5_method(conn);
+              break;
+          case SENTV5AUTH:
+              show_msg(MSGDEBUG, "Receiving reply to SOCKS V5 authentication negotiation\n");
+              conn->datalen = 2;
+              conn->datadone = 0;
+              conn->state = RECEIVING;
+              conn->nextstate = GOTV5AUTH;
+              break;
+          case GOTV5AUTH:
+              rc = read_socksv5_auth(conn);
+              break;
+          case SENTV5CONNECT:
+              show_msg(MSGDEBUG, "Receiving reply to SOCKS V5 connect request\n");
+              conn->datalen = 10;
+              conn->datadone = 0;
+              conn->state = RECEIVING;
+              conn->nextstate = GOTV5CONNECT;
+              break;
+          case GOTV5CONNECT:
+              rc = read_socksv5_connect(conn);
+              break;
+        }
+        conn->err = errno;
+    }
+
+    if (i == 20)
+        show_msg(MSGERR, "Ooops, state loop while handling request %d\n",
+                conn->sockid);
+
+    show_msg(MSGDEBUG, "Handle loop completed for socket %d in state %d, "
+                       "returning %d\n", conn->sockid, conn->state, rc);
+    return(rc);
+}
+
+static int connect_server(struct connreq *conn)
+{
+    int rc;
+
+    /* Connect this socket to the socks server */
+    show_msg(MSGDEBUG, "Connecting to %s port %d\n",
+             inet_ntoa(conn->serveraddr.sin_addr), ntohs(conn->serveraddr.sin_port));
+
+    rc = realconnect(conn->sockid, (CONNECT_SOCKARG) &(conn->serveraddr),
+                     sizeof(conn->serveraddr));
+
+    show_msg(MSGDEBUG, "Connect returned %d, errno is %d\n", rc, errno);
+    if (rc && errno == EISCONN) {
+        rc = 0;
+        show_msg(MSGDEBUG, "Socket %d already connected to SOCKS server\n", conn->sockid);
+        conn->state = CONNECTED;
+    } else if (rc) {
+        if (errno != EINPROGRESS) {
+            show_msg(MSGERR, "Error %d attempting to connect to SOCKS "
+                             "server (%s)\n", errno, strerror(errno));
+            conn->state = FAILED;
+        } else {
+            show_msg(MSGDEBUG, "Connection in progress\n");
+            conn->state = CONNECTING;
+        }
+    } else {
+        show_msg(MSGDEBUG, "Socket %d connected to SOCKS server\n", conn->sockid);
+        conn->state = CONNECTED;
+    }
+
+    return((rc ? errno : 0));
+}
+
+static int send_socks_request(struct connreq *conn)
+{
+    int rc = 0;
+
+    if (conn->path->type == 4) {
+        char *name = get_pool_entry(pool, &(conn->connaddr.sin_addr));
+        if(name != NULL)
+            rc = send_socksv4a_request(conn,name);
+        else
+            rc = send_socksv4_request(conn);
+    } else
+        rc = send_socksv5_method(conn);
+    return(rc);
+}
+
+static int send_socksv4a_request(struct connreq *conn,const char *onion_host)
+{
+    struct passwd *user;
+    struct sockreq *thisreq;
+    int endOfUser;
+    /* Determine the current username */
+    user = getpwuid(getuid());
+
+    thisreq = (struct sockreq *) conn->buffer;
+    endOfUser=sizeof(struct sockreq) +
+    (user == NULL ? 0 : strlen(user->pw_name)) + 1;
+
+    /* Check the buffer has enough space for the request  */
+    /* and the user name                                  */
+    conn->datalen = endOfUser+
+                    (onion_host == NULL ? 0 : strlen(onion_host)) + 1;
+    if (sizeof(conn->buffer) < conn->datalen) {
+        show_msg(MSGERR, "The SOCKS username is too long");
+        conn->state = FAILED;
+        return(ECONNREFUSED);
+    }
+
+    /* Create the request */
+    thisreq->version = 4;
+    thisreq->command = 1;
+    thisreq->dstport = conn->connaddr.sin_port;
+    thisreq->dstip   = htonl(1);
+
+    /* Copy the username */
+    strcpy((char *) thisreq + sizeof(struct sockreq),
+          (user == NULL ? "" : user->pw_name));
+
+    /* Copy the onion host */
+    strcpy((char *) thisreq + endOfUser,
+          (onion_host == NULL ? "" : onion_host));
+
+    conn->datadone = 0;
+    conn->state = SENDING;
+    conn->nextstate = SENTV4REQ;
+
+    return(0);
+}
+
+static int send_socksv4_request(struct connreq *conn)
+{
+    struct passwd *user;
+    struct sockreq *thisreq;
+
+    /* Determine the current username */
+    user = getpwuid(getuid());
+
+    thisreq = (struct sockreq *) conn->buffer;
+
+    /* Check the buffer has enough space for the request  */
+    /* and the user name                                  */
+    conn->datalen = sizeof(struct sockreq) +
+                    (user == NULL ? 0 : strlen(user->pw_name)) + 1;
+    if (sizeof(conn->buffer) < conn->datalen) {
+        show_msg(MSGERR, "The SOCKS username is too long");
+        conn->state = FAILED;
+        return(ECONNREFUSED);
+    }
+
+    /* Create the request */
+    thisreq->version = 4;
+    thisreq->command = 1;
+    thisreq->dstport = conn->connaddr.sin_port;
+    thisreq->dstip   = conn->connaddr.sin_addr.s_addr;
+
+    /* Copy the username */
+    strcpy((char *) thisreq + sizeof(struct sockreq),
+            (user == NULL ? "" : user->pw_name));
+
+    conn->datadone = 0;
+    conn->state = SENDING;
+    conn->nextstate = SENTV4REQ;
+
+    return(0);
+}
+
+static int send_socksv5_method(struct connreq *conn)
+{
+    char verstring[] = { 0x05,    /* Version 5 SOCKS */
+                          0x02,    /* No. Methods     */
+                          0x00,    /* Null Auth       */
+                          0x02 };  /* User/Pass Auth  */
+
+    show_msg(MSGDEBUG, "Constructing V5 method negotiation\n");
+    conn->state = SENDING;
+    conn->nextstate = SENTV5METHOD;
+    memcpy(conn->buffer, verstring, sizeof(verstring));
+    conn->datalen = sizeof(verstring);
+    conn->datadone = 0;
+
+    return(0);
+}
+
+static int send_socksv5_connect(struct connreq *conn)
+{
+    int namelen = 0;
+    char *name = NULL;
+    char constring[] = { 0x05,    /* Version 5 SOCKS */
+                          0x01,    /* Connect request */
+                          0x00,    /* Reserved        */
+                          0x01 };  /* IP Version 4    */
+
+    show_msg(MSGDEBUG, "Constructing V5 connect request\n");
+    conn->datadone = 0;
+    conn->state = SENDING;
+    conn->nextstate = SENTV5CONNECT;
+    memcpy(conn->buffer, constring, sizeof(constring));
+    conn->datalen = sizeof(constring);
+
+    show_msg(MSGDEBUG, "send_socksv5_connect: looking for: %s\n",
+              inet_ntoa(conn->connaddr.sin_addr));
+
+    name = get_pool_entry(pool, &(conn->connaddr.sin_addr));
+    if(name != NULL) {
+        namelen = strlen(name);
+        if(namelen > 255)  /* "Can't happen" */
+            name = NULL;
+    }
+    if(name != NULL) {
+        show_msg(MSGDEBUG, "send_socksv5_connect: found it!\n");
+        /* Substitute the domain name from the pool into the SOCKS request. */
+        conn->buffer[3] = 0x03;  /* Change the ATYP field */
+        conn->buffer[4] = namelen;  /* Length of name */
+        conn->datalen++;
+        memcpy(&conn->buffer[conn->datalen], name, namelen);
+        conn->datalen += namelen;
+    } else {
+        show_msg(MSGDEBUG, "send_socksv5_connect: ip address not found\n");
+        /* Use the raw IP address */
+        memcpy(&conn->buffer[conn->datalen], &(conn->connaddr.sin_addr.s_addr),
+                sizeof(conn->connaddr.sin_addr.s_addr));
+        conn->datalen += sizeof(conn->connaddr.sin_addr.s_addr);
+    }
+    memcpy(&conn->buffer[conn->datalen], &(conn->connaddr.sin_port),
+          sizeof(conn->connaddr.sin_port));
+    conn->datalen += sizeof(conn->connaddr.sin_port);
+
+    return(0);
+}
+
+static int send_buffer(struct connreq *conn)
+{
+    int rc = 0;
+
+    show_msg(MSGDEBUG, "Writing to server (sending %d bytes)\n", conn->datalen);
+    while ((rc == 0) && (conn->datadone != conn->datalen)) {
+        rc = send(conn->sockid, conn->buffer + conn->datadone,
+                  conn->datalen - conn->datadone, 0);
+        if (rc > 0) {
+            conn->datadone += rc;
+            rc = 0;
+        } else {
+            if (errno != EWOULDBLOCK)
+                show_msg(MSGDEBUG, "Write failed, %s\n", strerror(errno));
+            rc = errno;
+        }
+    }
+
+    if (conn->datadone == conn->datalen)
+        conn->state = conn->nextstate;
+
+    show_msg(MSGDEBUG, "Sent %d bytes of %d bytes in buffer, return code is %d\n",
+              conn->datadone, conn->datalen, rc);
+    return(rc);
+}
+
+static int recv_buffer(struct connreq *conn)
+{
+    int rc = 0;
+
+    show_msg(MSGDEBUG, "Reading from server (expecting %d bytes)\n", conn->datalen);
+    while ((rc == 0) && (conn->datadone != conn->datalen)) {
+          rc = recv(conn->sockid, conn->buffer + conn->datadone,
+                    conn->datalen - conn->datadone, 0);
+          if (rc > 0) {
+              conn->datadone += rc;
+              rc = 0;
+          } else if (rc == 0) {
+              show_msg(MSGDEBUG, "Peer has shutdown but we only read %d of %d bytes.\n",
+                  conn->datadone, conn->datalen);
+              rc = ENOTCONN; /* ENOTCONN seems like the most fitting error message */
+          } else {
+              if (errno != EWOULDBLOCK)
+                  show_msg(MSGDEBUG, "Read failed, %s\n", strerror(errno));
+              rc = errno;
+          }
+    }
+
+    if (conn->datadone == conn->datalen)
+        conn->state = conn->nextstate;
+
+    show_msg(MSGDEBUG, "Received %d bytes of %d bytes expected, return code is %d\n",
+             conn->datadone, conn->datalen, rc);
+    return(rc);
+}
+
+static int read_socksv5_method(struct connreq *conn)
+{
+    struct passwd *nixuser;
+    char *uname, *upass;
+
+    /* See if we offered an acceptable method */
+    if (conn->buffer[1] == '\xff') {
+        show_msg(MSGERR, "SOCKS V5 server refused authentication methods\n");
+        conn->state = FAILED;
+        return(ECONNREFUSED);
+    }
+
+    /* If the socks server chose username/password authentication */
+    /* (method 2) then do that                                    */
+    if ((unsigned short int) conn->buffer[1] == 2) {
+        show_msg(MSGDEBUG, "SOCKS V5 server chose username/password authentication\n");
+
+        /* Determine the current *nix username */
+        nixuser = getpwuid(getuid());
+
+        if (((uname = conn->path->defuser) == NULL) &&
+          ((uname = getenv("TORSOCKS_USERNAME")) == NULL) &&
+            ((uname = (nixuser == NULL ? NULL : nixuser->pw_name)) == NULL)) {
+            show_msg(MSGERR, "Could not get SOCKS username from "
+                    "local passwd file, torsocks.conf "
+                    "or $TORSOCKS_USERNAME to authenticate "
+                    "with");
+            conn->state = FAILED;
+            return(ECONNREFUSED);
+        }
+
+        if (((upass = getenv("TORSOCKS_PASSWORD")) == NULL) &&
+          ((upass = conn->path->defpass) == NULL)) {
+            show_msg(MSGERR, "Need a password in torsocks.conf or "
+                    "$TORSOCKS_PASSWORD to authenticate with");
+            conn->state = FAILED;
+            return(ECONNREFUSED);
+        }
+
+        /* Check that the username / pass specified will */
+        /* fit into the buffer                */
+        if ((3 + strlen(uname) + strlen(upass)) >= sizeof(conn->buffer)) {
+            show_msg(MSGERR, "The supplied socks username or "
+                    "password is too long");
+            conn->state = FAILED;
+            return(ECONNREFUSED);
+        }
+
+        conn->datalen = 0;
+        conn->buffer[conn->datalen] = '\x01';
+        conn->datalen++;
+        conn->buffer[conn->datalen] = (int8_t) strlen(uname);
+        conn->datalen++;
+        memcpy(&(conn->buffer[conn->datalen]), uname, strlen(uname));
+        conn->datalen = conn->datalen + strlen(uname);
+        conn->buffer[conn->datalen] = (int8_t) strlen(upass);
+        conn->datalen++;
+        memcpy(&(conn->buffer[conn->datalen]), upass, strlen(upass));
+        conn->datalen = conn->datalen + strlen(upass);
+
+        conn->state = SENDING;
+        conn->nextstate = SENTV5AUTH;
+        conn->datadone = 0;
+    } else
+        return(send_socksv5_connect(conn));
+
+    return(0);
+}
+
+static int read_socksv5_auth(struct connreq *conn)
+{
+
+    if (conn->buffer[1] != '\x00') {
+        show_msg(MSGERR, "SOCKS authentication failed, check username and password\n");
+        conn->state = FAILED;
+        return(ECONNREFUSED);
+    }
+
+    /* Ok, we authenticated ok, send the connection request */
+    return(send_socksv5_connect(conn));
+}
+
+static int read_socksv5_connect(struct connreq *conn)
+{
+
+    /* See if the connection succeeded */
+    if (conn->buffer[1] != '\x00') {
+        show_msg(MSGERR, "SOCKS V5 connect failed: ");
+        conn->state = FAILED;
+        switch ((int8_t) conn->buffer[1]) {
+            case 1:
+                show_msg(MSGERR, "General SOCKS server failure\n");
+                return(ECONNABORTED);
+            case 2:
+                show_msg(MSGERR, "Connection denied by rule\n");
+                return(ECONNABORTED);
+            case 3:
+                show_msg(MSGERR, "Network unreachable\n");
+                return(ENETUNREACH);
+            case 4:
+                show_msg(MSGERR, "Host unreachable\n");
+                return(EHOSTUNREACH);
+            case 5:
+                show_msg(MSGERR, "Connection refused\n");
+                return(ECONNREFUSED);
+            case 6:
+                show_msg(MSGERR, "TTL Expired\n");
+                return(ETIMEDOUT);
+            case 7:
+                show_msg(MSGERR, "Command not supported\n");
+                return(ECONNABORTED);
+            case 8:
+                show_msg(MSGERR, "Address type not supported\n");
+                return(ECONNABORTED);
+            default:
+                show_msg(MSGERR, "Unknown error\n");
+                return(ECONNABORTED);
+        }
+    }
+    conn->state = DONE;
+
+    return(0);
+}
+
+static int read_socksv4_req(struct connreq *conn)
+{
+    struct sockrep *thisrep;
+
+    thisrep = (struct sockrep *) conn->buffer;
+
+    if (thisrep->result != 90) {
+        show_msg(MSGERR, "SOCKS V4 connect rejected:\n");
+        conn->state = FAILED;
+        switch(thisrep->result) {
+          case 91:
+              show_msg(MSGERR, "SOCKS server refused connection\n");
+              return(ECONNREFUSED);
+          case 92:
+              show_msg(MSGERR, "SOCKS server refused connection "
+                    "because of failed connect to identd "
+                    "on this machine\n");
+              return(ECONNREFUSED);
+          case 93:
+              show_msg(MSGERR, "SOCKS server refused connection "
+                    "because identd and this library "
+                    "reported different user-ids\n");
+              return(ECONNREFUSED);
+          default:
+              show_msg(MSGERR, "Unknown reason\n");
+              return(ECONNREFUSED);
+        }
+    }
+    conn->state = DONE;
+
+    return(0);
+}
diff --git a/src.old/socks.h b/src.old/socks.h
new file mode 100644
index 0000000..6dd497f
--- /dev/null
+++ b/src.old/socks.h
@@ -0,0 +1,116 @@
+/***************************************************************************
+ *                                                                         *
+ *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
+ *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+/* socks.h - Structures used by torsocks to form SOCKS requests */
+
+#ifndef _SOCKS_H
+
+#define _SOCKS_H 1
+
+#include "parser.h"
+#include "dead_pool.h"
+
+/* Structure representing a socks connection request */
+struct sockreq {
+   int8_t version;
+   int8_t command;
+   int16_t dstport;
+   int32_t dstip;
+   /* A null terminated username goes here */
+};
+
+/* Structure representing a socks connection request response */
+struct sockrep {
+   int8_t version;
+   int8_t result;
+   int16_t ignore1;
+   int32_t ignore2;
+};
+
+/* Structure representing a socket which we are currently proxying */
+struct connreq {
+   /* Information about the socket and target */
+   int sockid;
+   struct sockaddr_in connaddr;
+   struct sockaddr_in serveraddr;
+
+   /* Pointer to the config entry for the socks server */
+   struct serverent *path;
+
+   /* Current state of this proxied socket */
+   int state;
+
+   /* Next state to go to when the send or receive is finished */
+   int nextstate;
+
+   /* When connections fail but an error number cannot be reported
+    * because the socket is non blocking we keep the connreq struct until
+    * the status is queried with connect() again, we then return
+    * this value */
+   int err;
+
+   /* Events that were set for this socket upon call to select() or
+    * poll() */
+   int selectevents;
+
+   /* Buffer for sending and receiving on the socket */
+   unsigned int datalen;
+   unsigned int datadone;
+   char buffer[2048];
+
+   struct connreq *next;
+};
+
+/* Connection statuses */
+#define UNSTARTED 0
+#define CONNECTING 1
+#define CONNECTED 2
+#define SENDING 3
+#define RECEIVING 4
+#define SENTV4REQ 5
+#define GOTV4REQ 6
+#define SENTV5METHOD 7
+#define GOTV5METHOD 8
+#define SENTV5AUTH 9
+#define GOTV5AUTH 10
+#define SENTV5CONNECT 11
+#define GOTV5CONNECT 12
+#define DONE 13
+#define FAILED 14
+
+/* Flags to indicate what events a socket was select()ed for */
+#define READ (1<<0)
+#define WRITE (1<<1)
+#define EXCEPT (1<<2)
+#define READWRITE (READ|WRITE)
+#define READWRITEEXCEPT (READ|WRITE|EXCEPT)
+
+/* Global Declarations */
+extern dead_pool *pool;
+extern struct connreq *requests;
+
+struct connreq *new_socks_request(int sockid, struct sockaddr_in *connaddr,
+                                         struct sockaddr_in *serveraddr,
+                                         struct serverent *path);
+void kill_socks_request(struct connreq *conn);
+struct connreq *find_socks_request(int sockid, int includefailed);
+int handle_request(struct connreq *conn);
+
+#endif
diff --git a/src.old/torsocks.c b/src.old/torsocks.c
new file mode 100644
index 0000000..597c107
--- /dev/null
+++ b/src.old/torsocks.c
@@ -0,0 +1,1108 @@
+/***************************************************************************
+ *                                                                         *
+ *                                                                         *
+ *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
+ *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+/* PreProcessor Defines */
+#include <config.h>
+
+/*Defining _NONSTD_SOURCE causes library and kernel calls to behave as closely
+to Mac OS X 10.3's library and kernel calls as possible.*/
+#if defined(__APPLE__) || defined(__darwin__)
+/*
+From 'man compat' in OSX:
+64-BIT COMPILATION
+     When compiling for 64-bit architectures, the __LP64__ macro will be defined to 1, and UNIX conformance
+     is always on (the _DARWIN_FEATURE_UNIX_CONFORMANCE macro will also be defined to the SUS conformance
+     level).  Defining _NONSTD_SOURCE will cause a compilation error.
+*/
+#if !defined(__LP64__)
+#define _NONSTD_SOURCE 1
+#endif
+#include <sys/socket.h>
+#endif
+
+
+#ifdef USE_GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+/* Global configuration variables */
+const char *torsocks_progname = "libtorsocks";         /* Name used in err msgs    */
+
+/* Header Files */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <string.h>
+#include <strings.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <pwd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdarg.h>
+#if !defined(__APPLE__) && !defined(__darwin__)
+#include <sys/socket.h>
+#endif
+#include <resolv.h>
+
+#include "common.h"
+#include "dead_pool.h"
+#include "parser.h"
+#include "socks.h"
+
+/* Some function names are macroized on Darwin. Allow those names
+   to expand accordingly. */
+#define EXPAND_GUTS(x) torsocks_##x##_guts
+#define EXPAND_GUTS_NAME(x) EXPAND_GUTS(x)
+
+/* Function prototypes for original functions that we patch */
+#ifdef SUPPORT_RES_API
+int (*realres_init)(void);
+#endif
+#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r (*real##n)(s##SIGNATURE);
+#include "expansion_table.h"
+#undef PATCH_TABLE_EXPANSION
+#undef DARWIN_EXPANSION
+
+static struct parsedfile config;
+static int suid = 0;
+static char *conffile = NULL;
+
+/* Exported Function Prototypes */
+void __attribute__ ((constructor)) torsocks_init(void);
+
+/* Function prototypes for our patches */
+#ifdef SUPPORT_RES_API
+int res_init(void);
+#endif
+
+#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r n(s##SIGNATURE);
+#define DARWIN_EXPANSION(e,r,s,n,b,m)      r n(s##SIGNATURE) __asm("_" m);
+#include "expansion_table.h"
+#undef PATCH_TABLE_EXPANSION
+#undef DARWIN_EXPANSION
+
+/* Private Function Prototypes */
+/* no torsocks_res_init_guts */
+#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r torsocks_##b##_guts(s##SIGNATURE, r (*original_##b)(s##SIGNATURE));
+#include "expansion_table.h"
+#undef PATCH_TABLE_EXPANSION
+
+static int get_config();
+static int get_environment();
+static int deadpool_init(void);
+
+static pthread_mutex_t torsocks_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void torsocks_init(void)
+{
+    pthread_mutex_lock(&torsocks_init_mutex);
+
+    show_msg(MSGDEBUG, "In torsocks_init \n");
+
+    get_environment();
+    get_config();
+
+#ifdef USE_OLD_DLSYM
+    void *lib;
+#endif
+
+    /* We could do all our initialization here, but to be honest */
+    /* most programs that are run won't use our services, so     */
+    /* we do our general initialization on first call            */
+
+    /* Determine the logging level */
+    suid = (getuid() != geteuid());
+
+    dlerror();
+#ifndef USE_OLD_DLSYM
+    #ifdef SUPPORT_RES_API
+      torsocks_find_library("res_init", MSGERR, realres_init);
+    #endif
+    #define PATCH_TABLE_EXPANSION(e,r,s,n,b,m)  torsocks_find_library(m, MSG##e, real##n);
+    #include "expansion_table.h"
+    #undef PATCH_TABLE_EXPANSION
+#else
+    lib = dlopen(LIBCONNECT, RTLD_LAZY);
+    realconnect = dlsym(lib, "connect");
+    realselect = dlsym(lib, "select");
+    realpoll = dlsym(lib, "poll");
+    realgethostbyname = dlsym(lib, "gethostbyname");
+    realgethostbyaddr = dlsym(lib, "gethostbyaddr");
+    realgetaddrinfo = dlsym(lib, "getaddrinfo");
+    realgetipnodebyname = dlsym(lib, "getipnodebyname");
+    realsendto = dlsym(lib, "sendto");
+    realsendmsg = dlsym(lib, "sendmsg");
+    dlclose(lib);
+    lib = dlopen(LIBC, RTLD_LAZY);
+    realclose = dlsym(lib, "close");
+    dlclose(lib);
+    #ifdef SUPPORT_RES_API
+    lib = dlopen(LIBRESOLV, RTLD_LAZY);
+    realres_init = dlsym(lib, "res_init");
+    realresquery = dlsym(lib, "res_query");
+    realressend = dlsym(lib, "res_send");
+    realresquerydomain = dlsym(lib, "res_querydomain");
+    realressearch = dlsym(lib, "res_search");
+    dlclose(lib);
+    #endif
+#endif
+    /* Unfortunately, we can't do this lazily because otherwise our mmap'd
+       area won't be shared across fork()s. */
+    if (!deadpool_init()) {
+        show_msg(MSGERR, "Fatal error: exiting\n");
+        exit(1);
+    }
+
+    pthread_mutex_unlock(&torsocks_init_mutex);
+
+    show_msg(MSGDEBUG, "Exit torsocks_init \n");
+}
+
+static int get_environment()
+{
+    static int done = 0;
+    int loglevel = MSGERR;
+    char *logfile = NULL;
+    char *env;
+
+    if (done)
+        return(0);
+
+   /* Determine the logging level */
+    if ((env = getenv("TORSOCKS_DEBUG")))
+        loglevel = atoi(env);
+    if (((env = getenv("TORSOCKS_DEBUG_FILE"))) && !suid)
+        logfile = env;
+    set_log_options(loglevel, logfile, (loglevel == MSGTEST) ? 0 : 1);
+
+    done = 1;
+
+    return(0);
+}
+
+static int get_config ()
+{
+    static int done = 0;
+
+    if (done)
+        return(0);
+
+    /* Determine the location of the config file */
+#ifdef ALLOW_ENV_CONFIG
+    if (!suid)
+        conffile = getenv("TORSOCKS_CONF_FILE");
+#endif
+
+    /* Read in the config file */
+    read_config(conffile, &config);
+    if (config.paths)
+        show_msg(MSGDEBUG, "First lineno for first path is %d\n", config.paths->lineno);
+
+    done = 1;
+
+    return(0);
+}
+
+/* Patch trampoline functions */
+/* no torsocks_res_init_guts */
+#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) \
+   r n(s##SIGNATURE) { \
+     if (!real##n) { \
+       torsocks_find_library(m, MSG##e, real##n);\
+     } \
+     return torsocks_##b##_guts(s##ARGNAMES, real##n); \
+   }
+#include "expansion_table.h"
+#undef PATCH_TABLE_EXPANSION
+
+int torsocks_connect_guts(CONNECT_SIGNATURE, int (*original_connect)(CONNECT_SIGNATURE))
+{
+    struct sockaddr_in *connaddr;
+    struct sockaddr_in peer_address;
+    struct sockaddr_in server_address;
+    int gotvalidserver = 0, rc;
+    socklen_t namelen = sizeof(peer_address);
+    int sock_type = -1;
+    socklen_t sock_type_len = sizeof(sock_type);
+    int res = -1;
+    struct serverent *path;
+    struct connreq *newconn;
+
+    /* If the real connect doesn't exist, we're stuffed */
+    if (original_connect == NULL) {
+        show_msg(MSGERR, "Unresolved symbol: connect\n");
+        return(-1);
+    }
+
+    show_msg(MSGTEST, "Got connection request\n");
+
+    connaddr = (struct sockaddr_in *) __addr;
+
+    /* Get the type of the socket */
+    getsockopt(__fd, SOL_SOCKET, SO_TYPE,
+            (void *) &sock_type, &sock_type_len);
+
+    show_msg(MSGDEBUG, "sin_family: %i\n", connaddr->sin_family);
+
+    show_msg(MSGDEBUG, "sockopt: %i \n", sock_type);
+
+    /* If the address is local refuse it. We do this because it could
+       be a TCP DNS request to a local DNS server.*/
+    if (!(is_local(&config, &(connaddr->sin_addr))) &&
+        !is_dead_address(pool, connaddr->sin_addr.s_addr)) {
+        char buf[16];
+        inet_ntop(AF_INET, &(connaddr->sin_addr), buf, sizeof(buf));
+        show_msg(MSGERR, "connect: Connection is to a local address (%s), may be a "
+                         "TCP DNS request to a local DNS server so have to reject to be safe. "
+                         "Please report a bug to http://code.google.com/p/torsocks/issues/entry if "
+                         "this is preventing a program from working properly with torsocks.\n", buf);
+        return -1;
+    }
+
+    /* If this is an INET6, we'll refuse it. */
+    if ((connaddr->sin_family == AF_INET6)) {
+       show_msg(MSGERR, "connect: Connection is IPv6: rejecting.\n");
+       errno = EAFNOSUPPORT;
+       return -1;
+    }
+
+    /* If this isn't an INET socket we can't  */
+    /* handle it, just call the real connect now        */
+    if ((connaddr->sin_family != AF_INET)) {
+        show_msg(MSGDEBUG, "connect: Connection isn't IPv4, ignoring\n");
+        return(original_connect(__fd, __addr, __len));
+    }
+
+    /* If this a UDP socket  */
+    /* then we refuse it, since it is probably a DNS request      */
+    if ((sock_type != SOCK_STREAM)) {
+        show_msg(MSGERR, "connect: Connection is a UDP or ICMP stream, may be a "
+                           "DNS request or other form of leak: rejecting.\n");
+        return -1;
+    }
+
+    /* If we haven't initialized yet, do it now */
+    get_config();
+
+    /* Are we already handling this connect? */
+    if ((newconn = find_socks_request(__fd, 1))) {
+        if (memcmp(&newconn->connaddr, connaddr, sizeof(*connaddr))) {
+            /* Ok, they're calling connect on a socket that is in our
+             * queue but this connect() isn't to the same destination,
+             * they're obviously not trying to check the status of
+             * they're non blocking connect, they must have close()d
+             * the other socket and created a new one which happens
+             * to have the same fd as a request we haven't had the chance
+             * to delete yet, so we delete it here. */
+            show_msg(MSGDEBUG, "Call to connect received on old "
+                                "torsocks request for socket %d but to "
+                                "new destination, deleting old request\n",
+                      newconn->sockid);
+            kill_socks_request(newconn);
+        } else {
+            /* Ok, this call to connect() is to check the status of
+             * a current non blocking connect(). */
+            if (newconn->state == FAILED) {
+                show_msg(MSGDEBUG, "Call to connect received on failed "
+                                  "request %d, returning %d\n",
+                        newconn->sockid, newconn->err);
+                errno = newconn->err;
+                rc = -1;
+            } else if (newconn->state == DONE) {
+                show_msg(MSGERR, "Call to connect received on completed "
+                                "request %d\n",
+                        newconn->sockid, newconn->err);
+                rc = 0;
+            } else {
+                show_msg(MSGDEBUG, "Call to connect received on current request %d\n",
+                        newconn->sockid);
+                rc = handle_request(newconn);
+                errno = rc;
+            }
+            if ((newconn->state == FAILED) || (newconn->state == DONE))
+                kill_socks_request(newconn);
+            return((rc ? -1 : 0));
+        }
+    }
+
+    /* If the socket is already connected, just call connect  */
+    /* and get its standard reply                             */
+    if (!getpeername(__fd, (struct sockaddr *) &peer_address, &namelen)) {
+        show_msg(MSGDEBUG, "Socket is already connected, defering to "
+                          "real connect\n");
+        return(original_connect(__fd, __addr, __len));
+    }
+
+    show_msg(MSGDEBUG, "Got connection request for socket %d to "
+                        "%s\n", __fd, inet_ntoa(connaddr->sin_addr));
+
+    /* Ok, so its not local, we need a path to the net */
+    pick_server(&config, &path, &(connaddr->sin_addr), ntohs(connaddr->sin_port));
+
+    show_msg(MSGDEBUG, "Picked server %s for connection\n",
+              (path->address ? path->address : "(Not Provided)"));
+    if (path->address == NULL) {
+        if (path == &(config.defaultserver))
+            show_msg(MSGERR, "Connection needs to be made "
+                              "via default server but "
+                              "the default server has not "
+                              "been specified\n");
+        else
+            show_msg(MSGERR, "Connection needs to be made "
+                              "via path specified at line "
+                              "%d in configuration file but "
+                              "the server has not been "
+                              "specified for this path\n",
+                              path->lineno);
+    } else if ((res = resolve_ip(path->address, 0, 0)) == -1) {
+        show_msg(MSGERR, "The SOCKS server (%s) listed in the configuration "
+                        "file which needs to be used for this connection "
+                        "is invalid\n", path->address);
+    } else {
+        /* Construct the addr for the socks server */
+        server_address.sin_family = AF_INET; /* host byte order */
+        server_address.sin_addr.s_addr = res;
+        server_address.sin_port = htons(path->port);
+        bzero(&(server_address.sin_zero), 8);
+
+        /* Complain if this server isn't on a localnet */
+        if (is_local(&config, &server_address.sin_addr)) {
+            show_msg(MSGERR, "SOCKS server %s (%s) is not on a local subnet!\n",
+                     path->address, inet_ntoa(server_address.sin_addr));
+        } else
+            gotvalidserver = 1;
+    }
+
+    /* If we haven't found a valid server we return connection refused */
+    if (!gotvalidserver ||
+        !(newconn = new_socks_request(__fd, connaddr, &server_address, path))) {
+        errno = ECONNREFUSED;
+        return(-1);
+    } else {
+        /* Now we call the main function to handle the connect. */
+        rc = handle_request(newconn);
+        /* If the request completed immediately it mustn't have been
+        * a non blocking socket, in this case we don't need to know
+        * about this socket anymore. */
+        if ((newconn->state == FAILED) || (newconn->state == DONE))
+            kill_socks_request(newconn);
+        errno = rc;
+        /* We may get either of these if there are no bytes to read from 
+           the non-blocking connection in handle_request(). Since we are 
+           wrapping connect() here we can't return EWOULDBLOCK/EAGAIN
+           so override it with something the client will accept.*/
+        if (errno == EWOULDBLOCK || errno == EAGAIN)
+            errno = EINPROGRESS;
+        return((rc ? -1 : 0));
+    }
+}
+
+int torsocks_select_guts(SELECT_SIGNATURE, int (*original_select)(SELECT_SIGNATURE))
+{
+    int nevents = 0;
+    int rc = 0;
+    int setevents = 0;
+    int monitoring = 0;
+    struct connreq *conn, *nextconn;
+    fd_set mywritefds, myreadfds, myexceptfds;
+
+    /* If we're not currently managing any requests we can just
+     * leave here */
+    if (!requests) {
+        show_msg(MSGDEBUG, "No requests waiting, calling real select\n");
+        return(original_select(n, readfds, writefds, exceptfds, timeout));
+    }
+
+    show_msg(MSGTEST, "Intercepted call to select\n");
+    show_msg(MSGDEBUG, "Intercepted call to select with %d fds, "
+              "0x%08x 0x%08x 0x%08x, timeout %08x\n", n,
+              readfds, writefds, exceptfds, timeout);
+
+    for (conn = requests; conn != NULL; conn = conn->next) {
+        if ((conn->state == FAILED) || (conn->state == DONE))
+            continue;
+        conn->selectevents = 0;
+        show_msg(MSGDEBUG, "Checking requests for socks enabled socket %d\n",
+                 conn->sockid);
+        conn->selectevents |= (writefds ? (FD_ISSET(conn->sockid, writefds) ? WRITE : 0) : 0);
+        conn->selectevents |= (readfds ? (FD_ISSET(conn->sockid, readfds) ? READ : 0) : 0);
+        conn->selectevents |= (exceptfds ? (FD_ISSET(conn->sockid, exceptfds) ? EXCEPT : 0) : 0);
+        if (conn->selectevents) {
+            show_msg(MSGDEBUG, "Socket %d was set for events\n", conn->sockid);
+            monitoring = 1;
+        }
+    }
+
+    if (!monitoring)
+        return(original_select(n, readfds, writefds, exceptfds, timeout));
+
+    /* This is our select loop. In it we repeatedly call select(). We
+      * pass select the same fdsets as provided by the caller except we
+      * modify the fdsets for the sockets we're managing to get events
+      * we're interested in (while negotiating with the socks server). When
+      * events we're interested in happen we go off and process the result
+      * ourselves, without returning the events to the caller. The loop
+      * ends when an event which isn't one we need to handle occurs or
+      * the select times out */
+    do {
+        /* Copy the clients fd events, we'll change them as we wish */
+        if (readfds)
+            memcpy(&myreadfds, readfds, sizeof(myreadfds));
+        else
+            FD_ZERO(&myreadfds);
+        if (writefds)
+            memcpy(&mywritefds, writefds, sizeof(mywritefds));
+        else
+            FD_ZERO(&mywritefds);
+        if (exceptfds)
+            memcpy(&myexceptfds, exceptfds, sizeof(myexceptfds));
+        else
+            FD_ZERO(&myexceptfds);
+
+        /* Now enable our sockets for the events WE want to hear about */
+        for (conn = requests; conn != NULL; conn = conn->next) {
+            if ((conn->state == FAILED) || (conn->state == DONE) ||
+                (conn->selectevents == 0))
+                continue;
+            /* We always want to know about socket exceptions */
+            FD_SET(conn->sockid, &myexceptfds);
+            /* If we're waiting for a connect or to be able to send
+              * on a socket we want to get write events */
+            if ((conn->state == SENDING) || (conn->state == CONNECTING))
+                FD_SET(conn->sockid,&mywritefds);
+            else
+                FD_CLR(conn->sockid,&mywritefds);
+            /* If we're waiting to receive data we want to get
+              * read events */
+            if (conn->state == RECEIVING)
+                FD_SET(conn->sockid,&myreadfds);
+            else
+                FD_CLR(conn->sockid,&myreadfds);
+        }
+
+        nevents = original_select(n, &myreadfds, &mywritefds, &myexceptfds, timeout);
+        /* If there were no events we must have timed out or had an error */
+        if (nevents <= 0)
+            break;
+
+        /* Loop through all the sockets we're monitoring and see if
+        * any of them have had events */
+        for (conn = requests; conn != NULL; conn = nextconn) {
+            nextconn = conn->next;
+            if ((conn->state == FAILED) || (conn->state == DONE))
+                continue;
+            show_msg(MSGDEBUG, "Checking socket %d for events\n", conn->sockid);
+            /* Clear all the events on the socket (if any), we'll reset
+              * any that are necessary later. */
+            setevents = 0;
+            if (FD_ISSET(conn->sockid, &mywritefds))  {
+                nevents--;
+                setevents |= WRITE;
+                show_msg(MSGDEBUG, "Socket had write event\n");
+                FD_CLR(conn->sockid, &mywritefds);
+            }
+            if (FD_ISSET(conn->sockid, &myreadfds))  {
+                nevents--;
+                setevents |= READ;
+                show_msg(MSGDEBUG, "Socket had write event\n");
+                FD_CLR(conn->sockid, &myreadfds);
+            }
+            if (FD_ISSET(conn->sockid, &myexceptfds))  {
+                nevents--;
+                setevents |= EXCEPT;
+                show_msg(MSGDEBUG, "Socket had except event\n");
+                FD_CLR(conn->sockid, &myexceptfds);
+            }
+
+            if (!setevents) {
+                show_msg(MSGDEBUG, "No events on socket %d\n", conn->sockid);
+                continue;
+            }
+
+            if (setevents & EXCEPT)
+                conn->state = FAILED;
+            else
+                rc = handle_request(conn);
+
+            /* If the connection hasn't failed or completed there is nothing
+              * to report to the client */
+            if ((conn->state != FAILED) &&
+                (conn->state != DONE))
+                continue;
+
+            /* Ok, the connection is completed, for good or for bad. We now
+              * hand back the relevant events to the caller. We don't delete the
+              * connection though since the caller should call connect() to
+              * check the status, we delete it then */
+
+            if (conn->state == FAILED) {
+                /* Damn, the connection failed. Whatever the events the socket
+                * was selected for we flag */
+                if (conn->selectevents & EXCEPT) {
+                    FD_SET(conn->sockid, &myexceptfds);
+                    nevents++;
+                }
+                if (conn->selectevents & READ) {
+                    FD_SET(conn->sockid, &myreadfds);
+                    nevents++;
+                }
+                if (conn->selectevents & WRITE) {
+                    FD_SET(conn->sockid, &mywritefds);
+                    nevents++;
+                }
+                /* We should use setsockopt to set the SO_ERROR errno for this
+                * socket, but this isn't allowed for some silly reason which
+                * leaves us a bit hamstrung.
+                * We don't delete the request so that hopefully we can
+                * return the error on the socket if they call connect() on it */
+            } else {
+                /* The connection is done,  if the client selected for
+                * writing we can go ahead and signal that now (since the socket must
+                * be ready for writing), otherwise we'll just let the select loop
+                * come around again (since we can't flag it for read, we don't know
+                * if there is any data to be read and can't be bothered checking) */
+                if (conn->selectevents & WRITE) {
+                    FD_SET(conn->sockid, &mywritefds);
+                    nevents++;
+                }
+            }
+        }
+    } while (nevents == 0);
+
+    show_msg(MSGDEBUG, "Finished intercepting select(), %d events\n", nevents);
+
+    /* Now copy our event blocks back to the client blocks */
+    if (readfds)
+        memcpy(readfds, &myreadfds, sizeof(myreadfds));
+    if (writefds)
+        memcpy(writefds, &mywritefds, sizeof(mywritefds));
+    if (exceptfds)
+        memcpy(exceptfds, &myexceptfds, sizeof(myexceptfds));
+
+    return(nevents);
+}
+
+int torsocks_poll_guts(POLL_SIGNATURE, int (*original_poll)(POLL_SIGNATURE))
+{
+    int nevents = 0;
+    int rc = 0;
+    unsigned int i;
+    int setevents = 0;
+    int monitoring = 0;
+    struct connreq *conn, *nextconn;
+
+    /* If we're not currently managing any requests we can just
+      * leave here */
+    if (!requests)
+        return(original_poll(ufds, nfds, timeout));
+
+    show_msg(MSGTEST, "Intercepted call to poll\n");
+    show_msg(MSGDEBUG, "Intercepted call to poll with %d fds, "
+              "0x%08x timeout %d\n", nfds, ufds, timeout);
+
+    for (conn = requests; conn != NULL; conn = conn->next)
+        conn->selectevents = 0;
+
+    /* Record what events on our sockets the caller was interested
+      * in */
+    for (i = 0; i < nfds; i++) {
+        if (!(conn = find_socks_request(ufds[i].fd, 0)))
+            continue;
+        show_msg(MSGDEBUG, "Have event checks for socks enabled socket %d\n",
+                conn->sockid);
+        conn->selectevents = ufds[i].events;
+        monitoring = 1;
+    }
+
+    if (!monitoring)
+        return(original_poll(ufds, nfds, timeout));
+
+    /* This is our poll loop. In it we repeatedly call poll(). We
+      * pass select the same event list as provided by the caller except we
+      * modify the events for the sockets we're managing to get events
+      * we're interested in (while negotiating with the socks server). When
+      * events we're interested in happen we go off and process the result
+      * ourselves, without returning the events to the caller. The loop
+      * ends when an event which isn't one we need to handle occurs or
+      * the poll times out */
+    do {
+        /* Enable our sockets for the events WE want to hear about */
+        for (i = 0; i < nfds; i++) {
+            if (!(conn = find_socks_request(ufds[i].fd, 0)))
+                continue;
+
+            /* We always want to know about socket exceptions but they're
+              * always returned (i.e they don't need to be in the list of
+              * wanted events to be returned by the kernel */
+            ufds[i].events = 0;
+
+            /* If we're waiting for a connect or to be able to send
+              * on a socket we want to get write events */
+            if ((conn->state == SENDING) || (conn->state == CONNECTING))
+                ufds[i].events |= POLLOUT;
+            /* If we're waiting to receive data we want to get
+              * read events */
+            if (conn->state == RECEIVING)
+                ufds[i].events |= POLLIN;
+        }
+
+        nevents = original_poll(ufds, nfds, timeout);
+        /* If there were no events we must have timed out or had an error */
+        if (nevents <= 0)
+            break;
+
+        /* Loop through all the sockets we're monitoring and see if
+        * any of them have had events */
+        for (conn = requests; conn != NULL; conn = nextconn) {
+            nextconn = conn->next;
+            if ((conn->state == FAILED) || (conn->state == DONE))
+                continue;
+
+            /* Find the socket in the poll list */
+            for (i = 0; ((i < nfds) && (ufds[i].fd != conn->sockid)); i++)
+                /* Empty Loop */;
+            if (i == nfds)
+                continue;
+
+            show_msg(MSGDEBUG, "Checking socket %d for events\n", conn->sockid);
+
+            if (!ufds[i].revents) {
+                show_msg(MSGDEBUG, "No events on socket\n");
+                continue;
+            }
+
+            /* Clear any read or write events on the socket, we'll reset
+              * any that are necessary later. */
+            setevents = ufds[i].revents;
+            if (setevents & POLLIN) {
+                show_msg(MSGDEBUG, "Socket had read event\n");
+                ufds[i].revents &= ~POLLIN;
+                nevents--;
+            }
+            if (setevents & POLLOUT) {
+                show_msg(MSGDEBUG, "Socket had write event\n");
+                ufds[i].revents &= ~POLLOUT;
+                nevents--;
+            }
+            if (setevents & (POLLERR | POLLNVAL | POLLHUP))
+                show_msg(MSGDEBUG, "Socket had error event\n");
+
+            /* Now handle this event */
+            if (setevents & (POLLERR | POLLNVAL | POLLHUP)) {
+                conn->state = FAILED;
+            } else {
+                rc = handle_request(conn);
+            }
+            /* If the connection hasn't failed or completed there is nothing
+              * to report to the client */
+            if ((conn->state != FAILED) &&
+                (conn->state != DONE))
+                continue;
+
+            /* Ok, the connection is completed, for good or for bad. We now
+             * hand back the relevant events to the caller. We don't delete the
+             * connection though since the caller should call connect() to
+             * check the status, we delete it then */
+
+            if (conn->state == FAILED) {
+                /* Damn, the connection failed. Just copy back the error events
+                 * from the poll call, error events are always valid even if not
+                 * requested by the client */
+                /* We should use setsockopt to set the SO_ERROR errno for this
+                 * socket, but this isn't allowed for some silly reason which
+                 * leaves us a bit hamstrung.
+                 * We don't delete the request so that hopefully we can
+                 * return the error on the socket if they call connect() on it */
+            } else {
+                /* The connection is done,  if the client polled for
+                 * writing we can go ahead and signal that now (since the socket must
+                 * be ready for writing), otherwise we'll just let the select loop
+                 * come around again (since we can't flag it for read, we don't know
+                 * if there is any data to be read and can't be bothered checking) */
+                if (conn->selectevents & POLLOUT) {
+                  setevents |= POLLOUT;
+                  nevents++;
+                }
+            }
+        }
+    } while (nevents == 0);
+
+    show_msg(MSGDEBUG, "Finished intercepting poll(), %d events\n", nevents);
+
+    /* Now restore the events polled in each of the blocks */
+    for (i = 0; i < nfds; i++) {
+        if (!(conn = find_socks_request(ufds[i].fd, 1)))
+            continue;
+        ufds[i].events = conn->selectevents;
+    }
+
+    return(nevents);
+}
+
+int torsocks_close_guts(CLOSE_SIGNATURE, int (*original_close)(CLOSE_SIGNATURE))
+{
+    int rc;
+    struct connreq *conn;
+
+    /* If we're not currently managing any requests we can just
+      * leave here */
+    if (!requests) {
+        show_msg(MSGDEBUG, "No requests waiting, calling real close\n");
+        return(original_close(fd));
+    }
+
+    if (original_close == NULL) {
+        show_msg(MSGERR, "Unresolved symbol: close\n");
+        return(-1);
+    }
+
+    show_msg(MSGTEST, "Got call to close()\n");
+    show_msg(MSGDEBUG, "Call to close(%d)\n", fd);
+
+    rc = original_close(fd);
+
+    /* If we have this fd in our request handling list we
+    * remove it now */
+    if ((conn = find_socks_request(fd, 1))) {
+        show_msg(MSGDEBUG, "Call to close() received on file descriptor "
+                            "%d which is a connection request of status %d\n",
+                 conn->sockid, conn->state);
+        kill_socks_request(conn);
+    }
+
+    return(rc);
+}
+
+/* If we are not done setting up the connection yet, return
+ * -1 and ENOTCONN, otherwise call getpeername
+ *
+ * This is necessary since some applications, when using non-blocking connect,
+ * (like ircII) use getpeername() to find out if they are connected already.
+ *
+ * This results in races sometimes, where the client sends data to the socket
+ * before we are done with the socks connection setup.  Another solution would
+ * be to intercept send().
+ * 
+ * This could be extended to actually set the peername to the peer the
+ * client application has requested, but not for now.
+ *
+ * PP, Sat, 27 Mar 2004 11:30:23 +0100
+ */
+
+int torsocks_getpeername_guts(GETPEERNAME_SIGNATURE,
+                            int (*original_getpeername)(GETPEERNAME_SIGNATURE))
+{
+    struct connreq *conn;
+    int rc;
+
+    if (original_getpeername == NULL) {
+        show_msg(MSGERR, "Unresolved symbol: getpeername\n");
+        return(-1);
+    }
+
+    show_msg(MSGTEST, "Intercepted call to getpeername\n");
+    show_msg(MSGDEBUG, "Call to getpeername for fd %d\n", __fd);
+
+
+    rc = original_getpeername(__fd, __name, __namelen);
+    if (rc == -1)
+        return rc;
+
+    /* Are we handling this connect? */
+    if ((conn = find_socks_request(__fd, 1))) {
+        /* While we are at it, we might was well try to do something useful */
+        handle_request(conn);
+
+        if (conn->state != DONE) {
+            errno = ENOTCONN;
+            return(-1);
+        }
+    }
+    return rc;
+}
+
+#ifdef SUPPORT_RES_API
+int res_init(void)
+{
+    int rc;
+
+    if (!realres_init) {
+      torsocks_find_library("res_init", MSGERR, realres_init);
+    }
+
+    show_msg(MSGTEST, "Got res_init request\n");
+
+    if (realres_init == NULL) {
+        show_msg(MSGERR, "Unresolved symbol: res_init\n");
+        return(-1);
+    }
+    /* Call normal res_init */
+    rc = realres_init();
+
+    /* Force using TCP protocol for DNS queries */
+    _res.options |= RES_USEVC;
+    return(rc);
+}
+
+int EXPAND_GUTS_NAME(res_query)(RES_QUERY_SIGNATURE, int (*original_res_query)(RES_QUERY_SIGNATURE))
+{
+    int rc;
+
+    if (!original_res_query) {
+      torsocks_find_library("res_query", MSGERR, original_res_query);
+    }
+
+    show_msg(MSGTEST, "Got res_query request\n");
+
+    if (original_res_query == NULL) {
+        show_msg(MSGERR, "Unresolved symbol: res_query\n");
+        return(-1);
+    }
+
+    /* Ensure we force using TCP for DNS queries by calling res_init
+       above if it has not already been called.*/
+    if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
+        res_init();
+
+    /* Call normal res_query */
+    rc = original_res_query(dname, class, type, answer, anslen);
+
+    return(rc);
+}
+
+int EXPAND_GUTS_NAME(res_querydomain)(RES_QUERYDOMAIN_SIGNATURE, int (*original_res_querydomain)(RES_QUERYDOMAIN_SIGNATURE))
+{
+    int rc;
+
+    if (!original_res_querydomain) {
+      torsocks_find_library("res_querydomain", MSGERR, original_res_querydomain);
+    }
+
+    show_msg(MSGDEBUG, "Got res_querydomain request\n");
+
+    if (original_res_querydomain == NULL) {
+        show_msg(MSGERR, "Unresolved symbol: res_querydomain\n");
+        return(-1);
+    }
+
+    /* Ensure we force using TCP for DNS queries by calling res_init
+       above if it has not already been called.*/
+    if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
+        res_init();
+
+    /* Call normal res_querydomain */
+    rc = original_res_querydomain(name, domain, class, type, answer, anslen);
+
+    return(rc);
+}
+
+int EXPAND_GUTS_NAME(res_search)(RES_SEARCH_SIGNATURE, int (*original_res_search)(RES_SEARCH_SIGNATURE))
+{
+    int rc;
+
+    if (!original_res_search) {
+      torsocks_find_library("res_search", MSGERR, original_res_search);
+    }
+
+    show_msg(MSGTEST, "Got res_search request\n");
+
+    if (original_res_search == NULL) {
+        show_msg(MSGERR, "Unresolved symbol: res_search\n");
+        return(-1);
+    }
+
+    /* Ensure we force using TCP for DNS queries by calling res_init
+       above if it has not already been called.*/
+    if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
+        res_init();
+
+    /* Call normal res_search */
+    rc = original_res_search(dname, class, type, answer, anslen);
+
+    return(rc);
+}
+
+int EXPAND_GUTS_NAME(res_send)(RES_SEND_SIGNATURE, int (*original_res_send)(RES_SEND_SIGNATURE))
+{
+    int rc;
+
+    if (!original_res_send) {
+      torsocks_find_library("res_send", MSGERR, original_res_send);
+    }
+
+    show_msg(MSGTEST, "Got res_send request\n");
+
+    if (original_res_send == NULL) {
+        show_msg(MSGERR, "Unresolved symbol: res_send\n");
+        return(-1);
+    }
+
+    /* Ensure we force using TCP for DNS queries by calling res_init
+       above if it has not already been called.*/
+    if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
+        res_init();
+
+    /* Call normal res_send */
+    rc = original_res_send(msg, msglen, answer, anslen);
+
+    return(rc);
+}
+#endif
+
+static int deadpool_init(void)
+{
+    if (pool)
+        return 1;
+
+    if (!config.tordns_enabled) {
+        show_msg(MSGERR, "Tor DNS is disabled. Check your configuration.\n");
+        return 0;
+    }
+
+    get_environment();
+    get_config();
+    pool = init_pool(config.tordns_cache_size,
+                     config.tordns_deadpool_range->localip,
+                     config.tordns_deadpool_range->localnet,
+                     config.defaultserver.address,
+                     config.defaultserver.port);
+
+    if (!pool) {
+        show_msg(MSGERR, "Could not initialize reserved addresses for "
+                         ".onion addresses. Torsocks will not work properly.\n");
+        return 0;
+    }
+    return 1;
+}
+
+struct hostent *torsocks_gethostbyname_guts(GETHOSTBYNAME_SIGNATURE, struct hostent *(*original_gethostbyname)(GETHOSTBYNAME_SIGNATURE))
+{
+    if (pool)
+        return our_gethostbyname(pool, name);
+    return original_gethostbyname(name);
+}
+
+struct hostent *torsocks_gethostbyaddr_guts(GETHOSTBYADDR_SIGNATURE, struct hostent *(*original_gethostbyaddr)(GETHOSTBYADDR_SIGNATURE))
+{
+    if (pool)
+        return our_gethostbyaddr(pool, addr, len, type);
+    return original_gethostbyaddr(addr, len, type);
+}
+
+int torsocks_getaddrinfo_guts(GETADDRINFO_SIGNATURE, int (*original_getaddrinfo)(GETADDRINFO_SIGNATURE))
+{
+    if (pool)
+        return our_getaddrinfo(pool, node, service, hints, res);
+    return original_getaddrinfo(node, service, hints, res);
+}
+
+struct hostent *torsocks_getipnodebyname_guts(GETIPNODEBYNAME_SIGNATURE, struct hostent *(*original_getipnodebyname)(GETIPNODEBYNAME_SIGNATURE))
+{
+    if (pool)
+        return our_getipnodebyname(pool, name, af, flags, error_num);
+    return original_getipnodebyname(name, af, flags, error_num);
+}
+
+ssize_t torsocks_sendto_guts(SENDTO_SIGNATURE, ssize_t (*original_sendto)(SENDTO_SIGNATURE))
+{
+    int sock_type = -1;
+    unsigned int sock_type_len = sizeof(sock_type);
+    struct sockaddr_in *connaddr;
+
+    /* If the real sendto doesn't exist, we're stuffed */
+    if (original_sendto == NULL) {
+        show_msg(MSGERR, "Unresolved symbol: sendto\n");
+        return(-1);
+    }
+
+    show_msg(MSGTEST, "Got sendto request\n");
+
+    /* Get the type of the socket */
+    getsockopt(s, SOL_SOCKET, SO_TYPE,
+               (void *) &sock_type, &sock_type_len);
+
+    show_msg(MSGDEBUG, "sockopt: %i\n",  sock_type);
+
+    /* If this a UDP socket then we refuse it, since it is probably a DNS
+       request */
+    if ((sock_type != SOCK_STREAM)) {
+        show_msg(MSGERR, "sendto: Connection is a UDP or ICMP stream, may be a "
+                           "DNS request or other form of leak: rejecting.\n");
+        return -1;
+    }
+
+    connaddr = (struct sockaddr_in *) to;
+
+    /* If there is no address in 'to', sendto will only work if we
+       already allowed the socket to connect(), so we let it through.
+       Likewise if the socket is not an Internet connection. */
+    if (connaddr && (connaddr->sin_family != AF_INET)) {
+        show_msg(MSGDEBUG, "Connection isn't an Internet socket ignoring\n");
+    }
+
+    return (ssize_t) original_sendto(s, buf, len, flags, to, tolen);
+}
+
+ssize_t torsocks_sendmsg_guts(SENDMSG_SIGNATURE, ssize_t (*original_sendmsg)(SENDMSG_SIGNATURE))
+{
+    int sock_type = -1;
+    unsigned int sock_type_len = sizeof(sock_type);
+    struct sockaddr_in *connaddr;
+
+    /* If the real sendmsg doesn't exist, we're stuffed */
+    if (original_sendmsg == NULL) {
+        show_msg(MSGERR, "Unresolved symbol: sendmsg\n");
+        return(-1);
+    }
+
+    show_msg(MSGTEST, "Got sendmsg request\n");
+
+    /* Get the type of the socket */
+    getsockopt(s, SOL_SOCKET, SO_TYPE,
+               (void *) &sock_type, &sock_type_len);
+
+    show_msg(MSGDEBUG, "sockopt: %i\n",  sock_type);
+
+    if ((sock_type != SOCK_STREAM)) {
+        show_msg(MSGERR, "sendmsg: Connection is a UDP or ICMP stream, may be a "
+                          "DNS request or other form of leak: rejecting.\n");
+        return -1;
+    }
+
+    connaddr = (struct sockaddr_in *) msg->msg_name;
+
+    /* If there is no address in msg_name, sendmsg will only work if we
+       already allowed the socket to connect(), so we let it through.
+       Likewise if the socket is not an Internet connection. */
+    if (connaddr && (connaddr->sin_family != AF_INET)) {
+        show_msg(MSGDEBUG, "Connection isn't an Internet socket\n");
+    }
+
+    return (ssize_t) original_sendmsg(s, msg, flags);
+}
+
diff --git a/src.old/torsocks.in b/src.old/torsocks.in
new file mode 100755
index 0000000..4eaed8f
--- /dev/null
+++ b/src.old/torsocks.in
@@ -0,0 +1,167 @@
+#!/bin/sh
+# ***************************************************************************
+# *                                                                         *
+# *                                                                         *
+# *   Copyright (C) 2008 by Robert Hogan                                    *
+# *   robert at roberthogan.net                                                *
+# *   Copyright (C) 2012 by Jacob Appelbaum <jacob at torproject.org>          *
+# *                                                                         *
+# *   This program is free software; you can redistribute it and/or modify  *
+# *   it under the terms of the GNU General Public License as published by  *
+# *   the Free Software Foundation; either version 2 of the License, or     *
+# *   (at your option) any later version.                                   *
+# *                                                                         *
+# *   This program is distributed in the hope that it will be useful,       *
+# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+# *   GNU General Public License for more details.                          *
+# *                                                                         *
+# *   You should have received a copy of the GNU General Public License     *
+# *   along with this program; if not, write to the                         *
+# *   Free Software Foundation, Inc.,                                       *
+#*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+# ***************************************************************************
+# *                                                                         *
+# *   This is a modified version of a source file from the Tor project.     *
+# *   Original copyright information follows:                               *
+# ***************************************************************************
+# Wrapper script for use of the torsocks(8) transparent socksification library
+#
+# There are three forms of usage for this script:
+#
+# @prefix@/bin/torsocks program [program arguments...]
+#
+# This form sets the users @LDPRELOAD@ environment variable so that torsocks(8)
+# will be loaded to socksify the application then executes the specified 
+# program (with the provided arguments). The following simple example might 
+# be used to telnet to www.foo.org via a torsocks.conf(5) configured socks server:
+#
+# @prefix@/bin/torsocks telnet www.foo.org
+#
+# The second form allows for torsocks(8) to be switched on and off for a
+# session (that is, it adds and removes torsocks from the @LDPRELOAD@ environment
+# variable). This form must be _sourced_ into the user's existing session
+# (and will only work with bourne shell users):
+#
+# . @prefix@/bin/torsocks on
+# telnet www.foo.org 
+# . @prefix@/bin/torsocks off
+# 
+# Or
+# 
+# source @prefix@/bin/torsocks on
+# telnet www.foo.org
+# source @prefix@/bin/torsocks off
+#
+# The third form creates a new shell with @LDPRELOAD@ set and is achieved
+# simply by running the script with no arguments 
+# 
+# @prefix@/bin/torsocks
+#
+# When finished the user can simply terminate the shell with 'exit'
+# 
+# This script is originally from the debian torsocks package by
+# Tamas Szerb <toma at rulez.org>
+# Modified by Robert Hogan <robert at roberthogan.net> April 16th 2006
+
+not_found () {
+    echo "ERROR: $1 cannot be found in PATH." >&2
+    exit 1
+}
+
+set_id () {
+    echo "ERROR: $1 is set${2}id. torsocks will not work on a set${2}id executable." >&2
+    exit 1
+}
+
+if [ $# = 0 ] ; then
+   echo "$0: insufficient arguments"
+   exit
+fi
+
+LIBDIR="@prefix@/lib/torsocks"
+LIB_NAME="libtorsocks"
+SHLIB_EXT="@SHLIB_EXT@"
+SHLIB="${LIBDIR}/${LIB_NAME}.${SHLIB_EXT}"
+
+# Check for libtorsocks and if set the 64bit variant
+if [ ! -f $SHLIB ]; then
+   LIBDIR="@prefix@/lib64/torsocks"
+   SHLIB="${LIBDIR}/${LIB_NAME}.${SHLIB_EXT}"
+fi
+
+# Ensure libtorsocks exists,
+if [ ! -f $SHLIB ]; then
+   echo "$0: $SHLIB does not exist! Try re-installing torsocks."
+   exit
+fi
+
+case "$1" in
+  on)
+    if [ -z "$@LDPRELOAD@" ]
+      then
+        export @LDPRELOAD@="${SHLIB}"
+      else
+        echo $@LDPRELOAD@ | grep -q "${SHLIB}" || \
+        export @LDPRELOAD@="${SHLIB} $@LDPRELOAD@"
+    fi
+    # FIXME: This env variable is only meaningful on Mac OSX, so it would be better
+    #        not to set it at all on other platforms.
+    export DYLD_FORCE_FLAT_NAMESPACE=1
+  ;;
+  off)
+    #replace '/' with '\/' in @prefix@
+    # escprefix=`echo '@prefix@' |sed 's/\\//\\\\\//g'`
+    # export @LDPRELOAD@=`echo -n $@LDPRELOAD@ | sed "s/$escprefix\/lib\/torsocks\/libtorsocks.so \?//"`
+    export @LDPRELOAD@=`echo -n $@LDPRELOAD@ | sed "s#@prefix@/lib/torsocks/libtorsocks\. at SHLIB_EXT@ *##"`
+    if [ -z "$@LDPRELOAD@" ]
+      then
+        unset @LDPRELOAD@
+        # FIXME: This env variable is only meaningful on Mac OSX, so it would be better
+        #        not to set it at all on other platforms.
+        unset DYLD_FORCE_FLAT_NAMESPACE=1
+    fi
+  ;;
+  show|sh)
+    echo "@LDPRELOAD@=\"$@LDPRELOAD@\""
+  ;;
+  -h|-?)
+      echo "$0: Please see torsocks(1) or read comment at top of $0"
+   ;;
+  --shell)
+    if [ -z "$@LDPRELOAD@" ]
+    then
+      export @LDPRELOAD@="${SHLIB}"
+    else
+      echo $@LDPRELOAD@ | grep -q "${SHLIB}" || \
+      export @LDPRELOAD@="${SHLIB} $@LDPRELOAD@"
+    fi
+    export DYLD_FORCE_FLAT_NAMESPACE=1
+    echo "torsocks: new torified shell coming right up..."
+    ${SHELL:-/bin/sh}
+  ;;
+  *)
+    if [ -z "$@LDPRELOAD@" ]
+    then
+      export @LDPRELOAD@="${SHLIB}"
+    else
+      echo $@LDPRELOAD@ | grep -q "${SHLIB}" || \
+      export @LDPRELOAD@="${SHLIB} $@LDPRELOAD@"
+    fi
+    export DYLD_FORCE_FLAT_NAMESPACE=1
+
+    if [ $# -gt 0 ]
+    then
+      if ! which "$1" >/dev/null 2>&1; then
+          not_found $1
+      elif [ -u `which "$1"` ]; then
+          set_id $1 u
+      elif [ -g `which "$1"` ]; then
+          set_id $1 g
+      fi
+      exec "$@"
+    fi
+  ;;
+esac
+
+#EOF
diff --git a/src.old/usewithtor.in b/src.old/usewithtor.in
new file mode 100644
index 0000000..e606760
--- /dev/null
+++ b/src.old/usewithtor.in
@@ -0,0 +1,113 @@
+#! /bin/sh
+# ***************************************************************************
+# *                                                                         *
+# *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
+# *                                                                         *
+# *   This program is free software; you can redistribute it and/or modify  *
+# *   it under the terms of the GNU General Public License as published by  *
+# *   the Free Software Foundation; either version 2 of the License, or     *
+# *   (at your option) any later version.                                   *
+# *                                                                         *
+# *   This program is distributed in the hope that it will be useful,       *
+# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+# *   GNU General Public License for more details.                          *
+# *                                                                         *
+# *   You should have received a copy of the GNU General Public License     *
+# *   along with this program; if not, write to the                         *
+# *   Free Software Foundation, Inc.,                                       *
+#*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+# ***************************************************************************
+# *                                                                         *
+# *   This is a modified version of a source file from the Tor project.     *
+# *   Original copyright notice from tsocks source file follows:            *
+# ***************************************************************************
+
+# Wrapper script for use of the tsocks(8) transparent socksification library
+# See the tsocks(1) and torify(1) manpages.
+
+# Copyright (c) 2004, 2006 Peter Palfrader
+# Modified by Jacob Appelbaum <jacob at appelbaum.net> April 16th 2006
+# Modified by Marcus Griep <marcus at griep.us> June 16 2009
+# May be distributed under the same terms as Tor itself
+
+
+# Define and ensure we have tsocks
+# XXX: what if we don't have which?
+TORSOCKS="`which torsocks`"
+PROG=
+VERBOSE=
+
+usage () {
+	echo "Usage: $0 [-hv] <command> [<options>...]"
+}
+
+not_found () {
+	echo "ERROR: $1 cannot be found in PATH." >&2
+	exit 1
+}
+
+set_id () {
+	echo "ERROR: $1 is set${2}id. usewithtor will not work on a set${2}id executable." >&2
+	exit 1
+}
+
+# Check for any argument list
+if [ "$#" = 0 ]; then
+	usage >&2
+	exit 1
+fi
+
+while [ "$1" ]; do
+	case "$1" in
+		-h|--h*)
+			usage
+			exit 0
+			;;
+		-v|--v*)
+			VERBOSE=YesPlease
+			shift
+			;;
+		*)
+			break;
+	esac
+done
+
+if ! which "$1" >/dev/null 2>&1; then
+	not_found $1
+elif [ -u `which "$1"` ]; then
+	set_id $1 u
+elif [ -g `which "$1"` ]; then
+	set_id $1 g
+fi
+
+if [ -x "$TORSOCKS" ]; then
+	PROG=torsocks
+else
+	echo "$0: Unable to find torsocks in PATH." >&2
+	echo "    Perhaps you haven't installed it?" >&2
+	exit 1
+fi
+
+if [ "$VERBOSE" ]; then
+	echo "We're armed with the following torsocks: $TORSOCKS"
+	echo "We're attempting to use $PROG for all tor action."
+fi
+
+if [ "$PROG" = "torsocks" ]; then
+	# Define our torsocks config file
+	TORSOCKS_CONF_FILE="@CONFDIR@/torsocks.conf"
+	export TORSOCKS_CONF_FILE
+
+	# Check that we've got a torsocks config file
+	if [ -r "$TORSOCKS_CONF_FILE" ]; 	then
+		exec torsocks "$@"
+	else
+		echo "$0: Missing torsocks configuration file \"$TORSOCKS_CONF_FILE\" - torsocks will use defaults sensible for Tor." >&2
+		exec torsocks "$@"
+	fi
+fi
+
+# We should have hit an exec. If we get here, we didn't exec
+echo "$0: failed to exec $PROG $@" >&2
+exit 1
diff --git a/src/common.c b/src/common.c
deleted file mode 100644
index 8fe3303..0000000
--- a/src/common.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
- *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                         *
- * Some code taken from Tor:                                               *
- * Copyright (c) 2003, Roger Dingledine                                    *
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.              *
- * Copyright (c) 2007-2008, The Tor Project, Inc.                          *
- *                                                                         *
- ***************************************************************************/
-/* 
-
-    commmon.c    - Common routines for the torsocks package 
-
-*/
-
-#include <config.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-
-#include "common.h"
-
-/* Globals */
-int loglevel = MSGERR;    /* The default logging level is to only log
-                             error messages */
-char logfilename[256];    /* Name of file to which log messages should
-                             be redirected */
-FILE *logfile = NULL;     /* File to which messages should be logged */
-int logstamp = 0;         /* Timestamp (and pid stamp) messages */
-
-
-/**
- * Read a 16-bit value beginning at <b>cp</b>.  Equivalent to
- * *(uint16_t*)(cp), but will not cause segfaults on platforms that forbid
- * unaligned memory access.
- */
-uint16_t
-get_uint16(const char *cp)
-{
-    uint16_t v;
-    memcpy(&v,cp,2);
-    return v;
-}
-/**
- * Read a 32-bit value beginning at <b>cp</b>.  Equivalent to
- * *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid
- * unaligned memory access.
- */
-uint32_t
-get_uint32(const char *cp)
-{
-    uint32_t v;
-    memcpy(&v,cp,4);
-    return v;
-}
-/**
- * Set a 16-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
- * *(uint16_t)(cp) = v, but will not cause segfaults on platforms that forbid
- * unaligned memory access. */
-void
-set_uint16(char *cp, uint16_t v)
-{
-    memcpy(cp,&v,2);
-}
-/**
- * Set a 32-bit value beginning at <b>cp</b> to <b>v</b>. Equivalent to
- * *(uint32_t)(cp) = v, but will not cause segfaults on platforms that forbid
- * unaligned memory access. */
-void
-set_uint32(char *cp, uint32_t v)
-{
-    memcpy(cp,&v,4);
-}
-
-unsigned int resolve_ip(char *host, int showmsg, int allownames) {
-    struct hostent *new;
-    unsigned int    hostaddr;
-    struct in_addr *ip;
-
-    if ((hostaddr = inet_addr(host)) == (unsigned int) -1) {
-        /* We couldn't convert it as a numerical ip so */
-        /* try it as a dns name                        */
-        if (allownames) {
-            #ifdef HAVE_GETHOSTBYNAME
-            if ((new = gethostbyname(host)) == (struct hostent *) 0) {
-            #endif
-                return(0);
-            #ifdef HAVE_GETHOSTBYNAME
-            } else {
-                ip = ((struct in_addr *) * new->h_addr_list);
-                hostaddr = ip -> s_addr;
-                if (showmsg)
-                    printf("Connecting to %s...\n", inet_ntoa(*ip));
-            }
-            #endif
-        } else
-            return(0);
-    }
-
-    return (hostaddr);
-}
-
-/* Set logging options, the options are as follows:             */
-/*  level - This sets the logging threshold, messages with      */
-/*          a higher level (i.e lower importance) will not be   */
-/*          output. For example, if the threshold is set to     */
-/*          MSGWARN a call to log a message of level MSGDEBUG   */
-/*          would be ignored. This can be set to -1 to disable  */
-/*          messages entirely                                   */
-/*  filename - This is a filename to which the messages should  */
-/*             be logged instead of to standard error           */
-/*  timestamp - This indicates that messages should be prefixed */
-/*              with timestamps (and the process id)            */
-void set_log_options(int level, char *filename, int timestamp) {
-
-   loglevel = level;
-   if (loglevel < MSGERR)
-      loglevel = MSGNONE;
-
-   if (filename) {
-      strncpy(logfilename, filename, sizeof(logfilename));
-      logfilename[sizeof(logfilename) - 1] = '\0';
-   }
-
-   logstamp = timestamp;
-}
-
-/* Count the bits in a netmask.  This is a little bit buggy; it assumes 
-   all the zeroes are on the right... */
-
-int count_netmask_bits(uint32_t mask)
-{
-    int i;
-    int nbits = 0;
-
-    for(i=0; i<32; i++) {
-        if((mask >> i) & 1) {
-            nbits++;
-        } 
-    }
-    mask = ~mask;
-    mask = ntohl(mask);
-    if(mask & (mask+1)) {
-        return -1;  /* Noncontiguous */
-    }
-    return nbits;
-}
-
-void show_msg(int level, const char *fmt, ...) {
-    va_list ap;
-    int saveerr;
-    extern char *torsocks_progname;
-    char timestring[20];
-    time_t timestamp;
-
-    if ((loglevel == MSGNONE) || (level > loglevel))
-        return;
-
-    if (!logfile) {
-        if (logfilename[0]) {
-          logfile = fopen(logfilename, "a");
-          if (logfile == NULL) {
-              logfile = stderr;
-              show_msg(MSGERR, "Could not open log file, %s, %s\n", 
-                      logfilename, strerror(errno));
-          }
-        } else
-          logfile = stderr;
-    }
-
-    if (logstamp) {
-        timestamp = time(NULL);
-        strftime(timestring, sizeof(timestring),  "%H:%M:%S", 
-                localtime(&timestamp));
-        fprintf(logfile, "%s ", timestring);
-    }
-
-    fputs(torsocks_progname, logfile);
-
-    if (logstamp) {
-        fprintf(logfile, "(%d)", getpid());
-    }
-
-    fputs(": ", logfile);
-
-    va_start(ap, fmt);
-
-    /* Save errno */
-    saveerr = errno;
-
-    vfprintf(logfile, fmt, ap);
-
-    fflush(logfile);
-
-    errno = saveerr;
-
-    va_end(ap);
-}
-
diff --git a/src/common.h b/src/common.h
deleted file mode 100644
index f84a2f7..0000000
--- a/src/common.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
- *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-
-/* Common functions provided in common.c */
-/* GCC has several useful attributes. */
-#include <sys/types.h>
-
-#if defined(__GNUC__) && __GNUC__ >= 3
-#define ATTR_NORETURN __attribute__((noreturn))
-#define ATTR_PURE __attribute__((pure))
-#define ATTR_CONST __attribute__((const))
-#define ATTR_MALLOC __attribute__((malloc))
-#define ATTR_NORETURN __attribute__((noreturn))
-#define ATTR_NONNULL(x) __attribute__((nonnull x))
-/** Macro: Evaluates to <b>exp</b> and hints the compiler that the value
- * of <b>exp</b> will probably be true. */
-#define PREDICT_LIKELY(exp) __builtin_expect((exp), 1)
-/** Macro: Evaluates to <b>exp</b> and hints the compiler that the value
- * of <b>exp</b> will probably be false. */
-#define PREDICT_UNLIKELY(exp) __builtin_expect((exp), 0)
-#else
-#define ATTR_NORETURN
-#define ATTR_PURE
-#define ATTR_CONST
-#define ATTR_MALLOC
-#define ATTR_NORETURN
-#define ATTR_NONNULL(x)
-#define PREDICT_LIKELY(exp) (exp)
-#define PREDICT_UNLIKELY(exp) (exp)
-#endif
-
-/** Try to find the symbol that is either m or __m.
- * If one of them exists, in that order, then save its address in r,
- * otherwise we want to print a message at log level l stating that
- * we could not find it.
- */
-#define torsocks_find_library(m,l,r) \
-  do { \
-    char * dl_error_msg = ""; \
-    char * dl_error_msg2 = ""; \
-    dlerror(); \
-    if ((r = dlsym(RTLD_NEXT, m)) == NULL) { \
-      dl_error_msg = dlerror(); \
-      if (dl_error_msg != NULL) { \
-        dl_error_msg = strdup(dl_error_msg); \
-      } \
-      if ((r = dlsym(RTLD_NEXT, "__" m)) == NULL) { \
-        dl_error_msg2 = dlerror(); \
-        show_msg(l, "WARNING: The symbol %s() was not found in any shared " \
-          "library with the reported error: %s!\n" \
-          "  Also, we failed to find the symbol %s() with the reported error:" \
-          " %s\n", m, (dl_error_msg ? dl_error_msg : "Not Found"), \
-          "__"m, (dl_error_msg2 ? dl_error_msg2 : "Not Found")); \
-      } \
-      if (dl_error_msg) \
-        free(dl_error_msg); \
-    } \
-  } while (0)
-
-uint16_t get_uint16(const char *cp) ATTR_PURE ATTR_NONNULL((1));
-uint32_t get_uint32(const char *cp) ATTR_PURE ATTR_NONNULL((1));
-void set_uint16(char *cp, uint16_t v) ATTR_NONNULL((1));
-void set_uint32(char *cp, uint32_t v) ATTR_NONNULL((1));
-
-int is_internal_IP(uint32_t ip, int for_listening) ATTR_PURE;
-int parse_addr_port(int severity, const char *addrport, char **address,
-                    uint32_t *addr, uint16_t *port_out);
-
-void set_log_options(int, char *, int);
-void show_msg(int level, const char *, ...);
-int count_netmask_bits(uint32_t mask);
-unsigned int resolve_ip(char *, int, int);
-
-#define MSGNONE   -1
-#define MSGERR    0
-#define MSGWARN   1
-#define MSGTEST  2
-#define MSGNOTICE 3
-#define MSGDEBUG  3
-
-/* Required by some BSDs */
-#ifndef  MAP_ANONYMOUS
-#ifdef MAP_ANON
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-#endif
diff --git a/src/darwin_warts.c b/src/darwin_warts.c
deleted file mode 100644
index 65bdd04..0000000
--- a/src/darwin_warts.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   Copyright (C) 2010 Alex Rosenberg <alex at ohmantics.net>                *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-
-/* Mac OS X 10.6 forces any function named "select" to be named "_select$1050"
- * in the output to the assembler. We need to patch select as well, so this
- * isolated code exists without tripping over the Darwin header that causes the
- * probkem.
- */
-
-#if defined(__APPLE__) || defined(__darwin__)
-
-#include <AvailabilityMacros.h>
-
-#if defined(MAC_OS_X_VERSION_10_6)
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <dlfcn.h>
-#include <string.h>
-#include <errno.h>
-#include "common.h"
-
-#define SELECT_SIGNATURE int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout
-#define SELECT_ARGNAMES n, readfds, writefds, exceptfds, timeout
-
-/* forward declare opaque structures instead of bringing in real Darwin decls. */
-typedef struct fd_set fd_set;
-struct timeval;
-
-int (*realselect)(SELECT_SIGNATURE);
-int torsocks_select_guts(SELECT_SIGNATURE, int (*original_select)(SELECT_SIGNATURE));
-
-int select(SELECT_SIGNATURE) {
-  if (!realselect) {
-    torsocks_find_library("select", MSGERR, realselect);
-  }
-  return torsocks_select_guts(SELECT_ARGNAMES, realselect);
-}
-
-#endif /* 10.6 */
-#endif /* darwin */
diff --git a/src/dead_pool.c b/src/dead_pool.c
deleted file mode 100644
index 13e5740..0000000
--- a/src/dead_pool.c
+++ /dev/null
@@ -1,805 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   Copyright (C) 2005 Total Information Security Ltd.                    *
- *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-
-#include <stdio.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-
-#include "common.h"
-#include "dead_pool.h"
-
-int store_pool_entry(dead_pool *pool, char *hostname, struct in_addr *addr);
-void get_next_dead_address(dead_pool *pool, uint32_t *result);
-
-static int
-do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
-           uint32_t *result_addr, const void *addr,
-           int version, int reverse, char **result_hostname);
-
-/* Compares the last strlen(s2) characters of s1 with s2.  Returns as for
-   strcasecmp. */
-static int 
-strcasecmpend(const char *s1, const char *s2)
-{
-   size_t n1 = strlen(s1), n2 = strlen(s2);
-   if (n2>n1) /* then they can't be the same; figure out which is bigger */
-       return strcasecmp(s1,s2);
-   else
-       return strncasecmp(s1+(n1-n2), s2, n2);
-}
-
-dead_pool *
-init_pool(unsigned int pool_size, struct in_addr deadrange_base, 
-    struct in_addr deadrange_mask, char *sockshost, uint16_t socksport)
-{
-    unsigned int i, deadrange_size, deadrange_width;
-    int deadrange_bits;
-    struct in_addr socks_server;
-    dead_pool *newpool = NULL;
-
-    /* Count bits in netmask and determine deadrange width. */
-    deadrange_bits = count_netmask_bits(deadrange_mask.s_addr);
-    if(deadrange_bits == -1) {
-        show_msg(MSGERR, "init_pool: invalid netmask for deadrange\n");
-        return NULL;
-    } 
-    deadrange_width = 32 - deadrange_bits;
-
-    show_msg(MSGDEBUG, "deadrange width is %d bits\n", deadrange_width);
-
-    /* Now work out how many IPs are available in the deadrange and check
-       that this number makes sense.  If the deadpool is bigger than the 
-       deadrange we shrink the pool. */
-
-    for(i=0, deadrange_size = 1; i < deadrange_width; i++) {
-        deadrange_size *= 2;
-    }
-
-    if(deadrange_size < pool_size) {
-        show_msg(MSGWARN, "tordns cache size was %d, but deadrange size is %d: "
-                 "shrinking pool size to %d entries\n", pool_size, 
-                 deadrange_size, deadrange_size);
-        pool_size = deadrange_size;
-    }
-    if(pool_size < 1) {
-        show_msg(MSGERR, "tordns cache size is 0, disabling tordns\n");
-        return NULL;
-    }
-
-    /* Allocate space for the dead_pool structure */
-    newpool = (dead_pool *) mmap(0, sizeof(dead_pool), 
-                   PROT_READ | PROT_WRITE, 
-                   MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
-    if(!newpool) {
-        show_msg(MSGERR, "init_pool: unable to mmap deadpool "
-                 "(tried to map %d bytes)\n", sizeof(dead_pool));
-        return NULL;
-    }
-
-    show_msg(MSGDEBUG, "init_pool: sockshost %s \n", sockshost);
-
-    /* Initialize the dead_pool structure */
-#ifdef HAVE_INET_ATON
-    inet_aton(sockshost, &socks_server);
-#elif defined(HAVE_INET_ADDR)
-    socks_server.s_addr = inet_addr(sockshost);
-#endif
-    newpool->sockshost = ntohl(socks_server.s_addr);
-    newpool->socksport = socksport;
-    newpool->deadrange_base = ntohl(deadrange_base.s_addr);
-    newpool->deadrange_mask = ntohl(deadrange_mask.s_addr);
-    newpool->deadrange_size = deadrange_size;
-    newpool->write_pos = 0;
-    newpool->dead_pos = 0;
-    newpool->n_entries = pool_size;
-
-    /* Allocate space for the entries */
-    newpool->entries = (pool_ent *) mmap(0, newpool->n_entries * sizeof(pool_ent), 
-                            PROT_READ | PROT_WRITE, 
-                            MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
-    if(!newpool->entries) {
-        munmap((void *)newpool, sizeof(dead_pool));
-        show_msg(MSGERR, "init_pool: unable to mmap deadpool entries "
-                 "(tried to map %d bytes)\n", 
-                 newpool->n_entries * sizeof(pool_ent)); 
-        return NULL;
-    }
-
-    /* Initialize the entries */
-    for(i=0; i < newpool->n_entries; i++) {
-        newpool->entries[i].ip = -1;
-        newpool->entries[i].name[0] = '\0';
-    }
-
-    return newpool;
-}
-
-int
-is_dead_address(dead_pool *pool, uint32_t addr) 
-{
-    uint32_t haddr = ntohl(addr);
-    if(pool == NULL) {
-        return 0;
-    }
-    return (pool->deadrange_base == (haddr & pool->deadrange_mask));
-}
-
-void
-get_next_dead_address(dead_pool *pool, uint32_t *result)
-{
-    *result = htonl(pool->deadrange_base + pool->dead_pos++);
-    if(pool->dead_pos >= pool->deadrange_size) {
-        pool->dead_pos = 0;
-    }
-}
-
-int
-store_pool_entry(dead_pool *pool, char *hostname, struct in_addr *addr)
-{
-  int position = pool->write_pos;
-  int oldpos;
-  int rc;
-  uint32_t intaddr;
-  char *result_hostname;
-
-  show_msg(MSGDEBUG, "store_pool_entry: storing '%s'\n", hostname);
-  show_msg(MSGDEBUG, "store_pool_entry: write pos is: %d\n", pool->write_pos);
-
-  /* Check to see if name already exists in pool */
-  oldpos = search_pool_for_name(pool, hostname);
-  if(oldpos != -1){
-      show_msg(MSGDEBUG, "store_pool_entry: not storing (entry exists)\n");
-      addr->s_addr = pool->entries[oldpos].ip;
-      return oldpos;
-  }
-
-  /* If this is a .onion host, then we return a bogus ip from our deadpool, 
-     otherwise we try to resolve it and store the 'real' IP */
-  if(strcasecmpend(hostname, ".onion") == 0) {
-      get_next_dead_address(pool, &pool->entries[position].ip);
-  } else {
-      rc = do_resolve(hostname, pool->sockshost, pool->socksport, &intaddr, 0,
-                  4 /*SOCKS5*/, 0 /*Reverse*/, &result_hostname);
-
-      if(rc != 0) {
-          show_msg(MSGWARN, "failed to resolve: %s\n", hostname);
-          return -1;
-      } 
-      if(is_dead_address(pool, intaddr)) {
-          show_msg(MSGERR, "resolved %s -> %d (deadpool address) IGNORED\n");
-          return -1;
-      }
-      pool->entries[position].ip = intaddr;
-  }
-
-  strncpy(pool->entries[position].name, hostname, 255);
-  pool->entries[position].name[255] = '\0';
-  pool->write_pos++;
-  if(pool->write_pos >= pool->n_entries) {
-      pool->write_pos = 0;
-  }
-  addr->s_addr = pool->entries[position].ip;
-
-  show_msg(MSGDEBUG, "store_pool_entry: stored entry in slot '%d'\n", position);
-
-  return position;
-}
-
-int 
-search_pool_for_name(dead_pool *pool, const char *name) 
-{
-  unsigned int i;
-  for(i=0; i < pool->n_entries; i++){
-    if(strcmp(name, pool->entries[i].name) == 0){
-      return i;
-    }
-  }
-  return -1;
-}
-
-char *
-get_pool_entry(dead_pool *pool, struct in_addr *addr)
-{
-  unsigned int i;
-  uint32_t intaddr = addr->s_addr;
-
-  if(pool == NULL) {
-      return NULL;
-  }
-
-  show_msg(MSGDEBUG, "get_pool_entry: searching for: %s\n", inet_ntoa(*addr));
-  for(i=0; i<pool->n_entries; i++) {
-    if(intaddr == pool->entries[i].ip) {
-        show_msg(MSGDEBUG, "get_pool_entry: found: %s\n", pool->entries[i].name);
-        return pool->entries[i].name;
-    }
-  }
-  show_msg(MSGDEBUG, "get_pool_entry: address not found\n");
-
-  return NULL;
-}
-
-static int
-build_socks4a_resolve_request(char **out,
-                              const char *username,
-                              const char *hostname)
-{
-  size_t len;
-  uint16_t port = htons(0);  /* port: 0. */
-  uint32_t addr = htonl(0x00000001u); /* addr: 0.0.0.1 */
-
-  len = 8 + strlen(username) + 1 + strlen(hostname) + 1;
-  *out = malloc(len);
-  (*out)[0] = 4;      /* SOCKS version 4 */
-  (*out)[1] = '\xF0'; /* Command: resolve. */
-
-  memcpy((*out)+2, &port, sizeof(port));
-  memcpy((*out)+4, &addr, sizeof(addr));
-  strcpy((*out)+8, username);
-  strcpy((*out)+8+strlen(username)+1, hostname);
-
-  return len;
-}
-
-static int
-build_socks5_resolve_ptr_request(char **out, const void *_addr)
-{
-  size_t len;
-  const struct in_addr *addr=_addr;
-
-  len = 12;
-  *out = malloc(len);
-  (*out)[0] = 5;      /* SOCKS version 5 */
-  (*out)[1] = '\xF1'; /* Command: reverse resolve.
-                         see doc/socks-extensions.txt*/
-  (*out)[2] = '\x00'; /* RSV */
-  (*out)[3] = '\x01'; /* ATYP: IP V4 address: X'01' */
-
-  set_uint32((*out)+4, addr->s_addr);/*IP*/
-  set_uint16((*out)+4+4, 0); /* port */
-
-  return len;
-}
-
-#define RESPONSE_LEN 8
-#define SOCKS5_LEN 4
-#define METHODRESPONSE_LEN 2
-
-static int
-parse_socks4a_resolve_response(const char *response, size_t len,
-                               uint32_t *addr_out)
-{
-  uint8_t status;
-  uint16_t port;
-
-  if (len < RESPONSE_LEN) {
-    show_msg(MSGWARN,"Truncated socks response.\n"); 
-    return -1;
-  }
-  if (((uint8_t)response[0])!=0) { /* version: 0 */
-    show_msg(MSGWARN,"Nonzero version in socks response: bad format.\n");
-    return -1;
-  }
-  status = (uint8_t)response[1];
-
-  memcpy(&port, response+2, sizeof(port));
-  if (port!=0) { /* port: 0 */
-    show_msg(MSGWARN,"Nonzero port in socks response: bad format.\n"); 
-    return -1;
-  }
-  if (status != 90) {
-    show_msg(MSGWARN,"Bad status: socks request failed.\n"); 
-    return -1;
-  }
-
-  memcpy(addr_out, response+4, sizeof(*addr_out));
-
-  return 0;
-}
-
-static int
-parse_socks5_resolve_ptr_response(int s,const char *response, size_t len,
-                               uint32_t *result_addr, char ***result_hostname)
-{
-    char reply_buf[4];
-    int r;
-
-    len=0;
-    while (len < SOCKS5_LEN) {
-      r = recv(s, reply_buf+len, SOCKS5_LEN-len, 0);
-      if (r==0) {
-        show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n"); 
-        return -1;
-      }
-      if (r<0) {
-        show_msg(MSGWARN, "do_resolve: error reading SOCKS5 response\n"); 
-        return -1;
-      }
-      len += r;
-    }
-
-    if (reply_buf[0] != 5) {
-      show_msg(MSGWARN, "Bad SOCKS5 reply version.");
-      return -1;
-    }
-    if (reply_buf[1] != 0) {
-      show_msg(MSGWARN,"Got status response '%u': SOCKS5 request failed.",
-               (unsigned)reply_buf[1]);
-      return -1;
-    }
-    if (reply_buf[3] == 1) {
-      /* IPv4 address */
-      len=0;
-      while (len < SOCKS5_LEN) {
-        r = recv(s, reply_buf+len, SOCKS5_LEN-len, 0);
-        if (r==0) {
-          show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n"); 
-          return -1;
-        }
-        if (r<0) {
-          show_msg(MSGWARN, "do_resolve: error reading address in SOCKS5 response\n"); 
-          return -1;
-        }
-        len += r;
-      }
-      *result_addr = ntohl(get_uint32(reply_buf));
-    } else if (reply_buf[3] == 3) {
-      size_t result_len;
-      len=0;
-      while (len < 1) {
-        r = recv(s, reply_buf+len, 1-len, 0);
-        if (r==0) {
-          show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n"); 
-          return -1;
-        }
-        if (r<0) {
-          show_msg(MSGWARN, "do_resolve: error reading address length in SOCKS5 response\n"); 
-          return -1;
-        }
-        len += r;
-      }
-      result_len = *(uint8_t*)(reply_buf);
-      **result_hostname = malloc(result_len+1);
-      len=0;
-      while (len < (int) result_len) {
-        r = recv(s, **result_hostname+len, result_len-len, 0);
-        if (r==0) {
-          show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS5 response\n"); 
-          return -1;
-        }
-        if (r<0) {
-          show_msg(MSGWARN, "do_resolve: error reading hostname in SOCKS5 response\n");
-          return -1;
-        }
-        len += r;
-      }
-
-      (**result_hostname)[result_len] = '\0';
-    }
-
-  return 0;
-}
-
-static int
-do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport,
-           uint32_t *result_addr, const void *addr,
-           int version, int reverse, char **result_hostname)
-{
-  int s;
-  struct sockaddr_in socksaddr;
-  char *req, *cp=NULL;
-  int r, len, hslen;
-  char response_buf[RESPONSE_LEN];
-  const char *handshake="\x05\x01\x00";
-
-  show_msg(MSGDEBUG, "do_resolve: resolving %s\n", hostname);
-
-  /* Create SOCKS connection */
-  s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-  if (s<0) {
-    show_msg(MSGWARN, "do_resolve: problem creating socket\n"); 
-    return -1;
-  }
-
-  /* Connect to SOCKS server */
-  memset(&socksaddr, 0, sizeof(socksaddr));
-  socksaddr.sin_family = AF_INET;
-  socksaddr.sin_port = htons(socksport);
-  socksaddr.sin_addr.s_addr = htonl(sockshost);
-  if (realconnect(s, (struct sockaddr*)&socksaddr, sizeof(socksaddr))) {
-    show_msg(MSGWARN, "do_resolve: error connecting to SOCKS server\n");
-    realclose(s);
-    return -1;
-  }
-
-  /* If a SOCKS5 connection, perform handshake */
-  if (version == 5) {
-    char method_buf[2];
-    hslen=3;
-    while (hslen) {
-      r = send(s, handshake, hslen, 0);
-      if (r<0) {
-        show_msg(MSGWARN, "do_resolve: error sending SOCKS5 method list.\n");
-        realclose(s);
-        return -1;
-      }
-      hslen -= r;
-      handshake += r;
-    }
-
-    len = 0;
-    while (len < METHODRESPONSE_LEN) {
-      r = recv(s, method_buf+len, METHODRESPONSE_LEN-len, 0);
-      if (r==0) {
-        show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS response\n");
-        realclose(s);
-        return -1;
-      }
-      if (r<0) {
-        show_msg(MSGWARN, "do_resolve: error reading SOCKS response\n");
-        realclose(s);
-        return -1;
-      }
-      len += r;
-    }
-
-    if (method_buf[0] != '\x05') {
-      show_msg(MSGWARN, "Unrecognized socks version: %u",
-              (unsigned)method_buf[0]);
-      realclose(s);
-      return -1;
-    }
-    if (method_buf[1] != '\x00') {
-      show_msg(MSGWARN, "Unrecognized socks authentication method: %u",
-              (unsigned)method_buf[1]);
-      realclose(s);
-      return -1;
-    }
-  }
-
-  /* Create SOCKS request */
-  if (reverse) {
-    if ((len = build_socks5_resolve_ptr_request(&req, addr))<0) {
-      show_msg(MSGWARN, "do_resolve: error generating reverse SOCKS request\n");
-      realclose(s);
-      return -1;
-    }
-  }else{
-    if ((len = build_socks4a_resolve_request(&req, "", hostname))<0) {
-      show_msg(MSGWARN, "do_resolve: error generating SOCKS request\n");
-      realclose(s);
-      return -1;
-    }
-  }
-
-  /* Send SOCKS request */
-  cp = req;
-  while (len) {
-    r = send(s, cp, len, 0);
-    if (r<0) {
-      show_msg(MSGWARN, "do_resolve: error sending SOCKS request\n"); 
-      free(req);
-      realclose(s);
-      return -1;
-    }
-    len -= r;
-    cp += r;
-  }
-  free(req);
-
-  /* Handle SOCKS Response */
-  if (reverse) {
-    if (parse_socks5_resolve_ptr_response(s, response_buf, RESPONSE_LEN,
-                                          result_addr, &result_hostname) < 0){
-      show_msg(MSGWARN, "do_resolve: error parsing SOCKS response\n");
-      realclose(s);
-      return -1;
-    }
-  }else{
-    /* Process SOCKS response */
-    len = 0;
-    while (len < RESPONSE_LEN) {
-      r = recv(s, response_buf+len, RESPONSE_LEN-len, 0);
-      if (r==0) {
-        show_msg(MSGWARN, "do_resolve: EOF while reading SOCKS response\n");
-        realclose(s);
-        return -1;
-      }
-      if (r<0) {
-        show_msg(MSGWARN, "do_resolve: error reading SOCKS response\n");
-        realclose(s);
-        return -1;
-      }
-      len += r;
-    }
-    realclose(s);
-
-    /* Parse SOCKS response */
-    if (parse_socks4a_resolve_response(response_buf, RESPONSE_LEN, result_addr) < 0){
-      show_msg(MSGWARN, "do_resolve: error parsing SOCKS response\n");
-      return -1;
-    }
-  }
-
-
-  show_msg(MSGDEBUG, "do_resolve: success\n");
-
-  return 0;
-}
-
-struct hostent *
-our_gethostbyaddr(dead_pool *pool, const void *_addr, socklen_t len, int type)
-{
-  const struct in_addr *addr=_addr;
-  static struct hostent he;
-  uint32_t intaddr=0;
-  char *result_hostname=NULL;
-  int rc=0;
-  static char *addrs[2];
-  static char *aliases[2];
-
-  rc = do_resolve("", pool->sockshost, pool->socksport, &intaddr, addr,
-                  5 /*SOCKS5*/, 1 /*Reverse*/, &result_hostname);
-
-
-  if(rc != 0) {
-      show_msg(MSGWARN, "failed to reverse resolve: %s\n",
-               inet_ntoa(*((struct in_addr *)addr)));
-      result_hostname=NULL;
-      addrs[0] = NULL;
-      addrs[1] = NULL;
-  }else{
-      addrs[0] = (char *)addr;
-      addrs[1] = NULL;
-  }
-
-  if (result_hostname)
-    he.h_name = result_hostname;
-  else
-    he.h_name = inet_ntoa(*((struct in_addr *)addr));
-
-  aliases[0] = NULL;
-  aliases[1] = NULL;
-
-  he.h_aliases = aliases;
-  he.h_length    = len;
-  he.h_addrtype  = type;
-  he.h_addr_list = addrs;
-
-  if (result_hostname)
-      show_msg(MSGTEST, "our_gethostbyaddr: resolved '%s' to: '%s'\n",
-              inet_ntoa(*((struct in_addr *)he.h_addr)), result_hostname);
-
-  return &he;
-
-}
-
-struct hostent *
-our_gethostbyname(dead_pool *pool, const char *name)
-{
-  int pos;
-  static struct in_addr addr;
-  static struct hostent he;
-  static char *addrs[2];
-
-  show_msg(MSGTEST, "our_gethostbyname: '%s' requested\n", name);
-
-  pos = store_pool_entry(pool,(char *) name, &addr);
-  if(pos == -1) {
-      h_errno = HOST_NOT_FOUND;
-      return NULL;
-  }
-
-  addrs[0] = (char *)&addr;
-  addrs[1] = NULL;
-
-  he.h_name      = pool->entries[pos].name;
-  he.h_aliases   = NULL;
-  he.h_length    = 4;
-  he.h_addrtype  = AF_INET;
-  he.h_addr_list = addrs;
-
-  show_msg(MSGDEBUG, "our_gethostbyname: resolved '%s' to: '%s'\n", 
-           name, inet_ntoa(*((struct in_addr *)he.h_addr)));
-
-  return &he;
-}
-
-static struct hostent *
-alloc_hostent(int af)
-{
-    struct hostent *he = NULL;
-    char **addr_list = NULL;
-    void *addr = NULL;
-    char **aliases = NULL;
-
-    if(af != AF_INET && af != AF_INET6) {
-        return NULL;
-    }
-
-    /* Since the memory we allocate here will be free'd by freehostent and
-       that function is opaque to us, it's likely that we'll leak a little 
-       bit of memory here. */
-
-    he = malloc(sizeof(struct hostent));
-    addr_list = malloc(2 * sizeof(char *));
-    if(af == AF_INET6) {
-        addr = malloc(sizeof(struct in6_addr));
-    } else {
-        addr = malloc(sizeof(struct in_addr));
-    }
-    aliases = malloc(sizeof(char *));
-
-    if(he == NULL || addr_list == NULL || addr == NULL || aliases == NULL) {
-        if(he)
-            free(he);
-        if(addr_list)
-            free(addr_list);
-        if(addr)
-            free(addr);
-        if(aliases)
-            free(aliases);
-    }
-
-    he->h_name = NULL;
-    he->h_addr_list = addr_list;
-    he->h_addr_list[0] = addr;
-    he->h_addr_list[1] = NULL;
-    he->h_aliases = aliases;
-    he->h_aliases[0] = NULL;
-    he->h_length = af == AF_INET ? 4 : 16;
-    he->h_addrtype = af;
-
-    return he;
-}
-
-/* On Linux, there's no freehostent() anymore; we might as well implement
-   this ourselves. */
-
-static void
-free_hostent(struct hostent *he)
-{
-    int i;
-    if(he->h_name) {
-        free(he->h_name);
-    }
-    if(he->h_aliases) {
-        for(i=0; he->h_aliases[i] != NULL; i++) {
-            free(he->h_aliases[i]);
-        }
-        free(he->h_aliases);
-    }
-    if(he->h_addr_list) {
-        free(he->h_addr_list);
-    }
-    free(he);
-}
-
-int
-our_getaddrinfo(dead_pool *pool, const char *node, const char *service, 
-                void *hints, void *res)
-{
-    int pos;
-    struct in_addr addr;
-    char *ipstr;
-    int ret;
-
-    /* If "node" looks like a dotted-decimal ip address, then just call 
-       the real getaddrinfo; otherwise we'll need to get an address from 
-       our pool. */
-
-    /* TODO: work out what to do with AF_INET6 requests */
-
-#ifdef HAVE_INET_ATON
-    if(node && inet_aton(node, &addr) == 0 && memcmp(node,"*",1)) {
-#elif defined(HAVE_INET_ADDR)
-    /* If we're stuck with inet_addr, then getaddrinfo() won't work 
-       properly with 255.255.255.255 (= -1).  There's not much we can
-       do about this */
-    in_addr_t is_valid;
-    is_valid = inet_addr(node);
-    if(is_valid == -1) {
-#endif
-        pos = store_pool_entry(pool, (char *) node, &addr);
-        if(pos == -1) {
-            return EAI_NONAME;
-        } else {
-            ipstr = strdup(inet_ntoa(addr));
-            ret = realgetaddrinfo(ipstr, service, hints, res);
-            free(ipstr);
-        }
-    } else {
-        ret = realgetaddrinfo(node, service, hints, res);
-    }
-
-    show_msg(MSGTEST, "our_getaddrinfo: '%s' requested\n", service);
-    return ret;
-}
-
-struct hostent *
-our_getipnodebyname(dead_pool *pool, const char *name, int af, int flags, 
-                    int *error_num)
-{
-    int pos;
-    struct hostent *he = NULL;
-    int want_4in6 = 0;
-    char addr_convert_buf[80];
-    struct in_addr pool_addr;
-
-    if(af == AF_INET6) {
-        /* Caller has requested an AF_INET6 address, and is not prepared to
-           accept IPv4-mapped IPV6 addresses. There's nothing we can do to
-           service their request. */
-#ifdef OPENBSD
-        /* OpenBSD doesn't support the AI_V4MAPPED flag, so just return. */
-        return NULL;
-#else
-        if((flags & AI_V4MAPPED) == 0) {
-            show_msg(MSGWARN, "getipnodebyname: asked for V6 addresses only, "
-                     "but torsocks can't handle that\n");
-            *error_num = NO_RECOVERY;
-            return NULL;
-        } else {
-            want_4in6 = 1;
-        }
-#endif
-    }
-
-    pos = store_pool_entry(pool, (char *)name, &pool_addr);
-    if(pos == -1) {
-        *error_num = HOST_NOT_FOUND;
-        return NULL;
-    }
-
-    he = alloc_hostent(af);
-    if(he == NULL) {
-        show_msg(MSGERR, "getipnodebyname: failed to allocate hostent\n");
-        *error_num = NO_RECOVERY;
-        return NULL;
-    }
-
-    if(want_4in6) {
-        /* Convert the ipv4 address in *addr to an IPv4 in IPv6 mapped 
-           address. TODO: inet_ntoa() is thread-safe on Solaris but might
-           not be on other platforms. */
-        strcpy(addr_convert_buf, "::FFFF:");
-        strcpy(addr_convert_buf+7, inet_ntoa(pool_addr));
-        if(inet_pton(AF_INET6, addr_convert_buf, he->h_addr_list[0]) != 1) {
-            show_msg(MSGERR, "getipnodebyname: inet_pton() failed!\n");
-            free_hostent(he);
-            *error_num = NO_RECOVERY;
-            return NULL;
-        }
-    } else {
-        ((struct in_addr *) he->h_addr_list[0])->s_addr = pool_addr.s_addr;
-    }
-    he->h_name = strdup(name);
-
-    return he;
-}
-
-
diff --git a/src/dead_pool.h b/src/dead_pool.h
deleted file mode 100644
index d6e3e10..0000000
--- a/src/dead_pool.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   Copyright (C) 2005 Total Information Security Ltd.                    *
- *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-
-#ifndef _DEAD_POOL_H
-#define _DEAD_POOL_H
-
-#include <config.h>
-
-extern int (*realconnect)(CONNECT_SIGNATURE);
-extern int (*realclose)(CLOSE_SIGNATURE);
-extern int (*realgetaddrinfo)(GETADDRINFO_SIGNATURE);
-
-struct struct_pool_ent {
-  unsigned int ip;
-  char name[256];
-};
-
-typedef struct struct_pool_ent pool_ent;
-
-struct struct_dead_pool {
-  pool_ent *entries;            /* Points to array of pool entries */
-  unsigned int n_entries;       /* Number of entries in the deadpool */
-  unsigned int deadrange_base;  /* Deadrange start IP in host byte order */
-  unsigned int deadrange_mask;  /* Deadrange netmask in host byte order */
-  unsigned int deadrange_size;  /* Number of IPs in the deadrange */
-  unsigned int write_pos;       /* Next position to use in the pool array */
-  unsigned int dead_pos;        /* Next 'unused' deadpool IP */
-  uint32_t sockshost;     
-  uint16_t socksport;
-  char pad[2];
-};
-
-typedef struct struct_dead_pool dead_pool;
-
-dead_pool *init_pool(unsigned int deadpool_size, struct in_addr deadrange_base, 
-    struct in_addr deadrange_mask, char *sockshost, uint16_t socksport);
-int is_dead_address(dead_pool *pool, uint32_t addr);
-char *get_pool_entry(dead_pool *pool, struct in_addr *addr);
-int search_pool_for_name(dead_pool *pool, const char *name);
-struct hostent *our_gethostbyname(dead_pool *pool, const char *name);
-struct hostent *our_gethostbyaddr(dead_pool *pool, const void *addr,
-                                  socklen_t len, int type);
-int our_getaddrinfo(dead_pool *pool, const char *node, const char *service, 
-    void *hints, void *res);
-struct hostent *our_getipnodebyname(dead_pool *pool, const char *name, 
-    int af, int flags, int *error_num);
-
-#endif /* _DEAD_POOL_H */
-
diff --git a/src/expansion_table.h b/src/expansion_table.h
deleted file mode 100644
index 14fabe1..0000000
--- a/src/expansion_table.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   Copyright (C) 2010 Alex Rosenberg <alex at ohmantics.net>                *
- *   Copyright (C) 2011 Robert Hogan <robert at roberthogan.net>              *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-
-#undef FUNC
-#undef FUNCD
-#undef FUND32
-#undef FUNCD64
-
-#ifdef SUPPORT_RES_API
-#define RES_FUNC    FUNC
-#define RES_FUNCD   FUNCD
-#define RES_FUNCD32 FUNCD32
-#define RES_FUNCD64 FUNCD64
-#else
-#define RES_FUNC    EMPTY_FUNC
-#define RES_FUNCD   EMPTY_FUNC
-#define RES_FUNCD32 EMPTY_FUNC
-#define RES_FUNCD64 EMPTY_FUNC
-#endif /* SUPPORT_RES_API */
-
-#define DNS_FUNC    FUNC
-#define DNS_FUNCD   FUNCD
-#define DNS_FUNCD32 FUNCD32
-#define DNS_FUNCD64 FUNCD64
-
-#define EMPTY_FUNC(e,r,s,n,b,m)
-
-#if defined(__APPLE__) || defined(__darwin__)
-#ifndef DARWIN_EXPANSION
-#define DARWIN_EXPANSION                  PATCH_TABLE_EXPANSION
-#endif /* DARWIN_EXPANSION */
-#define FUNCD(e,r,s,n,b,m)                DARWIN_EXPANSION(e,r,s,n,b,m)
-#if (__LP64__)
-#define FUNCD32(e,r,s,n,b,m)              EMPTY_FUNC(e,r,s,n,b,m)
-#define FUNCD64(e,r,s,n,b,m)              DARWIN_EXPANSION(e,r,s,n,b,m)
-/* This tests if we're building with 10.6 or later headers, not
-   if we're running on 10.6. We'd rather do the latter. */
-#ifdef MAC_OS_X_VERSION_10_6
-#define FUNCD64_106(e,r,s,n,b,m)          DARWIN_EXPANSION(e,r,s,n,b,m)
-#else
-#define FUNCD64_106(e,r,s,n,b,m)          EMPTY_FUNC(e,r,s,n,b,m)
-#endif /* MAC_OS_X_VERSION_10_6 */
-#else
-#define FUNCD32(e,r,s,n,b,m)              DARWIN_EXPANSION(e,r,s,n,b,m)
-#define FUNCD64(e,r,s,n,b,m)              EMPTY_FUNC(e,r,s,n,b,m)
-#define FUNCD64_106(e,r,s,n,b,m)          EMPTY_FUNC(e,r,s,n,b,m)
-#endif /* (__LP64__) */
-#else
-#define FUNCD(e,r,s,n,b,m)                EMPTY_FUNC(e,r,s,n,b,m)
-#define FUNCD32(e,r,s,n,b,m)              EMPTY_FUNC(e,r,s,n,b,m)
-#define FUNCD64(e,r,s,n,b,m)              EMPTY_FUNC(e,r,s,n,b,m)
-#define FUNCD64_106(e,r,s,n,b,m)          EMPTY_FUNC(e,r,s,n,b,m)
-#endif /* defined(__APPLE__) || defined(__darwin__) */
-#define FUNC(e,r,s,n,b,m)                 PATCH_TABLE_EXPANSION(e,r,s,n,b,m)
-
-/*           dlsym   return type         SIG/ARGS            C name                         base name            asm name    */
-/* res_init takes void, so we do that one manually. */
-/*RES_FUNC  (ERR,    int,                RES_INIT_,          res_init,                      res_init,            "res_init") */
-RES_FUNC    (ERR,    int,                RES_QUERY_,         res_query,                     res_query,           "res_query")
-RES_FUNC    (ERR,    int,                RES_SEARCH_,        res_search,                    res_search,          "res_search")
-RES_FUNC    (ERR,    int,                RES_SEND_,          res_send,                      res_send,            "res_send")
-RES_FUNC    (ERR,    int,                RES_QUERYDOMAIN_,   res_querydomain,               res_querydomain,     "res_querydomain")
-
-DNS_FUNC    (ERR,    struct hostent *,   GETHOSTBYNAME_,     gethostbyname,                 gethostbyname,       "gethostbyname")
-DNS_FUNC    (ERR,    struct hostent *,   GETHOSTBYADDR_,     gethostbyaddr,                 gethostbyaddr,       "gethostbyaddr")
-DNS_FUNC    (ERR,    int,                GETADDRINFO_,       getaddrinfo,                   getaddrinfo,         "getaddrinfo")
-/* getipnodebyname is deprecated so do not report an error if it is not available.*/
-DNS_FUNC    (WARN,    struct hostent *,  GETIPNODEBYNAME_,   getipnodebyname,               getipnodebyname,     "getipnodebyname")
-
-DNS_FUNC    (ERR,    ssize_t,            SENDTO_,            sendto,                        sendto,              "sendto")
-DNS_FUNCD32 (ERR,    ssize_t,            SENDTO_,            sendto_unix2003,               sendto,              "sendto$UNIX2003")
-DNS_FUNCD32 (ERR,    ssize_t,            SENDTO_,            sendto_nocancel_unix2003,      sendto,              "sendto$NOCANCEL$UNIX2003")
-DNS_FUNCD64 (ERR,    ssize_t,            SENDTO_,            sendto_nocancel,               sendto,              "sendto$NOCANCEL")
-
-DNS_FUNC    (ERR,    ssize_t,            SENDMSG_,           sendmsg,                       sendmsg,             "sendmsg")
-DNS_FUNCD32 (ERR,    ssize_t,            SENDMSG_,           sendmsg_unix2003,              sendmsg,             "sendmsg$UNIX2003")
-DNS_FUNCD32 (ERR,    ssize_t,            SENDMSG_,           sendmsg_nocancel_unix2003,     sendmsg,             "sendmsg$NOCANCEL$UNIX2003")
-DNS_FUNCD64 (ERR,    ssize_t,            SENDMSG_,           sendmsg_nocancel,              sendmsg,             "sendmsg$NOCANCEL")
-
-FUNC        (ERR,    int,                CONNECT_,           connect,                       connect,             "connect")
-FUNCD32     (ERR,    int,                CONNECT_,           connect_unix2003,              connect,             "connect$UNIX2003")
-FUNCD32     (ERR,    int,                CONNECT_,           connect_nocancel_unix2003,     connect,             "connect$NOCANCEL$UNIX2003")
-FUNCD64     (ERR,    int,                CONNECT_,           connect_nocancel,              connect,             "connect$NOCANCEL")
-
-#if !(defined(__APPLE__) || defined(__darwin__) && defined(MAX_OS_X_VERSION_10_6))
-/* see darwin_warts.c */
-FUNC        (ERR,    int,                SELECT_,            select,                        select,              "select")
-#endif
-FUNCD       (ERR,    int,                SELECT_,            select_darwinextsn,            select,              "select$DARWIN_EXTSN")
-FUNCD       (ERR,    int,                SELECT_,            select_darwinextsn_nocancel,   select,              "select$DARWIN_EXTSN$NOCANCEL")
-FUNCD32     (ERR,    int,                SELECT_,            select_unix2003,               select,              "select$UNIX2003")
-FUNCD32     (ERR,    int,                SELECT_,            select_nocancel_unix2003,      select,              "select$NOCANCEL$UNIX2003")
-FUNCD64     (ERR,    int,                SELECT_,            select_nocancel,               select,              "select$NOCANCEL")
-FUNCD64_106 (ERR,    int,                SELECT_,            select_1050,                   select,              "select$1050")
-
-FUNC        (ERR,    int,                POLL_,              poll,                          poll,                "poll")
-FUNCD32     (ERR,    int,                POLL_,              poll_unix2003,                 poll,                "poll$UNIX2003")
-FUNCD32     (ERR,    int,                POLL_,              poll_nocancel_unix2003,        poll,                "poll$NOCANCEL$UNIX2003")
-FUNCD64     (ERR,    int,                POLL_,              poll_nocancel,                 poll,                "poll$NOCANCEL")
-
-FUNC        (ERR,    int,                CLOSE_,             close,                         close,               "close")
-FUNCD32     (ERR,    int,                CLOSE_,             close_unix2003,                close,               "close$UNIX2003")
-FUNCD32     (ERR,    int,                CLOSE_,             close_nocancel_unix2003,       close,               "close$NOCANCEL$UNIX2003")
-FUNCD64     (ERR,    int,                CLOSE_,             close_nocancel,                close,               "close$NOCANCEL")
-
-FUNC        (ERR,    int,                GETPEERNAME_,       getpeername,                   getpeername,         "getpeername")
-FUNCD32     (ERR,    int,                GETPEERNAME_,       getpeername_unix2003,          getpeername,         "getpeername$UNIX2003")
diff --git a/src/parser.c b/src/parser.c
deleted file mode 100644
index 8f24be6..0000000
--- a/src/parser.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
- *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-/*
-
-   parser.c    - Parsing routines for torsocks.conf
-
-*/
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <config.h>
-
-#include "common.h"
-#include "parser.h"
-
-/* Global configuration variables */
-#define MAXLINE         BUFSIZ             /* Max length of conf line  */
-static struct serverent *currentcontext = NULL;
-
-static int handle_line(struct parsedfile *, char *, int);
-static int check_server(struct serverent *);
-static int tokenize(char *, int, char *[]);
-static int handle_path(struct parsedfile *, int, int, char *[]);
-static int handle_endpath(struct parsedfile *, int, int);
-static int handle_reaches(int, char *);
-static int handle_server(struct parsedfile *, int, char *);
-static int handle_type(struct parsedfile *config, int, char *);
-static int handle_port(struct parsedfile *config, int, char *);
-static int handle_local(struct parsedfile *, int, const char *);
-static int handle_tordns_enabled(struct parsedfile *, int, char *);
-static int handle_tordns_deadpool_range(struct parsedfile *, int, const char *);
-static int handle_tordns_cache_size(struct parsedfile *, char *);
-static int handle_defuser(struct parsedfile *, int, char *);
-static int handle_defpass(struct parsedfile *, int, char *);
-static int make_netent(char *value, struct netent **ent);
-
-int read_config (char *filename, struct parsedfile *config) {
-    FILE *conf;
-    char line[MAXLINE];
-    int rc = 0;
-    int lineno = 1;
-    struct serverent *server;
-
-   /* Clear out the structure */
-   memset(config, 0x0, sizeof(*config));
-
-   /* Initialization */
-   currentcontext = &(config->defaultserver);
-
-   /* Tordns defaults */
-   config->tordns_cache_size = 256;
-   config->tordns_enabled = 1;
-
-
-    /* If a filename wasn't provided, use the default */
-    if (filename == NULL) {
-        strncpy(line, CONF_FILE, sizeof(line) - 1);
-        /* Insure null termination */
-        line[sizeof(line) - 1] = (char) 0;
-        filename = line;
-        show_msg(MSGDEBUG, "Configuration file not provided by TORSOCKS_CONF_FILE "
-                "environment variable, attempting to use defaults in %s.\n", filename);
-    }
-
-    /* If there is no configuration file use reasonable defaults for Tor */
-    if ((conf = fopen(filename, "r")) == NULL) {
-        show_msg(MSGERR, "Could not open socks configuration file "
-                "(%s) errno (%d), assuming sensible defaults for Tor.\n", filename, errno);
-        memset(&(config->defaultserver), 0x0, sizeof(config->defaultserver));
-        check_server(&(config->defaultserver));
-        handle_local(config, 0, "127.0.0.0/255.0.0.0");
-        handle_local(config, 0, "10.0.0.0/255.0.0.0");
-        handle_local(config, 0, "192.168.0.0/255.255.0.0");
-        handle_local(config, 0, "172.16.0.0/255.240.0.0");
-        handle_local(config, 0, "169.254.0.0/255.255.0.0");
-        rc = 1; /* Severe errors reading configuration */
-    } else {
-        memset(&(config->defaultserver), 0x0, sizeof(config->defaultserver));
-
-        while (NULL != fgets(line, MAXLINE, conf)) {
-            /* This line _SHOULD_ end in \n so we  */
-            /* just chop off the \n and hand it on */
-            if (strlen(line) > 0)
-                line[strlen(line) - 1] = '\0';
-            handle_line(config, line, lineno);
-            lineno++;
-        }
-        fclose(conf);
-
-        /* Always add the 127.0.0.1/255.0.0.0 subnet to local */
-        handle_local(config, 0, "127.0.0.0/255.0.0.0");
-        /* We always consider this local, because many users' dsl
-          routers act as their DNS. */
-        handle_local(config, 0, "10.0.0.0/255.0.0.0");
-        handle_local(config, 0, "192.168.0.0/255.255.0.0");
-        handle_local(config, 0, "172.16.0.0/255.240.0.0");
-        handle_local(config, 0, "169.254.0.0/255.255.0.0");
-        handle_local(config, 0, "192.168.0.0/255.255.0.0");
-
-        /* Check default server */
-        check_server(&(config->defaultserver));
-        server = (config->paths);
-        while (server != NULL) {
-            check_server(server);
-            server = server->next;
-        }
-    }
-
-    /* Initialize tordns deadpool_range if not supplied */
-    if(config->tordns_deadpool_range == NULL) {
-        handle_tordns_deadpool_range(config, 0, "127.0.69.0/255.255.255.0");
-    }
-
-    return(rc);
-}
-
-/* Check server entries (and establish defaults) */
-static int check_server(struct serverent *server) {
-
-    /* Default to the default Tor Socks port */
-    if (server->port == 0) {
-        server->port = 9050;
-    }
-
-    /* Default to a presumably local installation of Tor */
-    if (server->address == NULL) {
-        server->address = strdup("127.0.0.1");
-    }
-
-    /* Default to SOCKS V4 */
-    if (server->type == 0) {
-        server->type = 4;
-    }
-
-    return(0);
-}
-
-
-
-static int handle_line(struct parsedfile *config, char *line, int lineno) {
-    char *words[10];
-    static char savedline[MAXLINE];
-    int   nowords = 0, i;
-
-    /* Save the input string */
-    strncpy(savedline, line, MAXLINE - 1);
-    savedline[MAXLINE - 1] = (char) 0;
-    /* Tokenize the input string */
-    nowords = tokenize(line, 10, words);
-
-    /* Set the spare slots to an empty string to simplify */
-    /* processing                                         */
-    for (i = nowords; i < 10; i++)
-        words[i] = NULL;
-
-    if (nowords > 0) {
-        /* Now this can either be a "path" block starter or */
-        /* ender, otherwise it has to be a pair (<name> =   */
-        /* <value>)                                         */
-        if (!strcmp(words[0], "path")) {
-            handle_path(config, lineno, nowords, words);
-        } else if (!strcmp(words[0], "}")) {
-            handle_endpath(config, lineno, nowords);
-        } else {
-            /* Has to be a pair */
-            if ((nowords != 3) || (strcmp(words[1], "="))) {
-                show_msg(MSGERR, "Malformed configuration pair "
-                       "on line %d in configuration "
-                       "file, \"%s\"\n", lineno, savedline);
-            } else if (!strcmp(words[0], "reaches")) {
-                handle_reaches(lineno, words[2]);
-            } else if (!strcmp(words[0], "server")) {
-                handle_server(config, lineno, words[2]);
-            } else if (!strcmp(words[0], "server_port")) {
-                handle_port(config, lineno, words[2]);
-            } else if (!strcmp(words[0], "server_type")) {
-                handle_type(config, lineno, words[2]);
-            } else if (!strcmp(words[0], "default_user")) {
-                handle_defuser(config, lineno, words[2]);
-            } else if (!strcmp(words[0], "default_pass")) {
-                handle_defpass(config, lineno, words[2]);
-            } else if (!strcmp(words[0], "local")) {
-                handle_local(config, lineno, words[2]);
-            } else if (!strcmp(words[0], "tordns_enable")) {
-                handle_tordns_enabled(config, lineno, words[2]);
-            } else if (!strcmp(words[0], "tordns_deadpool_range")) {
-                handle_tordns_deadpool_range(config, lineno, words[2]);
-            } else if (!strcmp(words[0], "tordns_cache_size")) {
-                handle_tordns_cache_size(config, words[2]);
-            } else {
-                show_msg(MSGERR, "Invalid pair type (%s) specified "
-                       "on line %d in configuration file, "
-                       "\"%s\"\n", words[0], lineno,
-                       savedline);
-            }
-        }
-    }
-
-    return(0);
-}
-
-/* This routines breaks up input lines into tokens  */
-/* and places these tokens into the array specified */
-/* by tokens                                        */
-static int tokenize(char *line, int arrsize, char *tokens[]) {
-    int tokenno = -1;
-    int finished = 0;
-
-    /* Whitespace is ignored before and after tokens     */
-    while ((tokenno < (arrsize - 1)) &&
-          (line = line + strspn(line, " \t")) &&
-           (*line != (char) 0) &&
-           (!finished)) {
-        tokenno++;
-        tokens[tokenno] = line;
-        line = line + strcspn(line, " \t");
-        *line = (char) 0;
-        line++;
-
-        /* We ignore everything after a # */
-        if (*tokens[tokenno] == '#') {
-            finished = 1;
-            tokenno--;
-        }
-    }
-
-    return(tokenno + 1);
-}
-
-static int handle_path(struct parsedfile *config, int lineno, int nowords, char *words[]) {
-    struct serverent *newserver;
-
-    if ((nowords != 2) || (strcmp(words[1], "{"))) {
-        show_msg(MSGERR, "Badly formed path open statement on line %d "
-               "in configuration file (should look like "
-               "\"path {\")\n", lineno);
-    } else if (currentcontext != &(config->defaultserver)) {
-        /* You cannot nest path statements so check that */
-        /* the current context is defaultserver          */
-        show_msg(MSGERR, "Path statements cannot be nested on line %d "
-               "in configuration file\n", lineno);
-    } else {
-        /* Open up a new serverent, put it on the list   */
-        /* then set the current context                  */
-        if ((newserver = malloc(sizeof(*newserver))) == NULL)
-            exit(-1);
-
-        /* Initialize the structure */
-        show_msg(MSGDEBUG, "New server structure from line %d in configuration file going "
-                           "to 0x%08x\n", lineno, newserver);
-        memset(newserver, 0x0, sizeof(*newserver));
-        newserver->next = config->paths;
-        newserver->lineno = lineno;
-        config->paths = newserver;
-        currentcontext = newserver;
-    }
-
-    return(0);
-}
-
-static int handle_endpath(struct parsedfile *config, int lineno, int nowords) {
-
-    if (nowords != 1) {
-        show_msg(MSGERR, "Badly formed path close statement on line "
-               "%d in configuration file (should look like "
-               "\"}\")\n", lineno);
-    } else {
-        currentcontext = &(config->defaultserver);
-    }
-
-    /* We could perform some checking on the validty of data in */
-    /* the completed path here, but thats what verifyconf is    */
-    /* designed to do, no point in weighing down libtorsocks      */
-
-    return(0);
-}
-
-static int handle_reaches(int lineno, char *value) {
-    int rc;
-    struct netent *ent;
-
-    rc = make_netent(value, &ent);
-    switch(rc) {
-        case 1:
-            show_msg(MSGERR, "Local network specification (%s) is not validly "
-                   "constructed in reach statement on line "
-                   "%d in configuration "
-                   "file\n", value, lineno);
-            return(0);
-            break;
-        case 2:
-            show_msg(MSGERR, "IP in reach statement "
-                   "network specification (%s) is not valid on line "
-                   "%d in configuration file\n", value, lineno);
-            return(0);
-            break;
-        case 3:
-            show_msg(MSGERR, "SUBNET in reach statement "
-                   "network specification (%s) is not valid on "
-                   "line %d in configuration file\n", value,
-                   lineno);
-            return(0);
-            break;
-        case 4:
-            show_msg(MSGERR, "IP (%s) & ", inet_ntoa(ent->localip));
-            show_msg(MSGERR, "SUBNET (%s) != IP on line %d in "
-                   "configuration file, ignored\n",
-                   inet_ntoa(ent->localnet), lineno);
-            return(0);
-         break;
-        case 5:
-            show_msg(MSGERR, "Start port in reach statement "
-                    "network specification (%s) is not valid on line "
-                    "%d in configuration file\n", value, lineno);
-            return(0);
-            break;
-        case 6:
-            show_msg(MSGERR, "End port in reach statement "
-                    "network specification (%s) is not valid on line "
-                    "%d in configuration file\n", value, lineno);
-            return(0);
-            break;
-        case 7:
-            show_msg(MSGERR, "End port in reach statement "
-                    "network specification (%s) is less than the start "
-                    "port on line %d in configuration file\n", value, 
-                    lineno);
-            return(0);
-            break;
-    }
-
-    /* The entry is valid so add it to linked list */
-    ent -> next = currentcontext -> reachnets;
-    currentcontext -> reachnets = ent;
-
-    return(0);
-}
-
-static int handle_server(struct parsedfile *config, int lineno, char *value) {
-    char *ip;
-
-    ip = strsplit(NULL, &value, " ");
-
-    /* We don't verify this ip/hostname at this stage, */
-    /* its resolved immediately before use in torsocks.c */
-    if (currentcontext->address == NULL)
-        currentcontext->address = strdup(ip);
-    else {
-        if (currentcontext == &(config->defaultserver))
-            show_msg(MSGERR, "Only one default SOCKS server "
-                   "may be specified at line %d in "
-                   "configuration file\n", lineno);
-        else
-            show_msg(MSGERR, "Only one SOCKS server may be specified "
-                   "per path on line %d in configuration "
-                   "file. (Path begins on line %d)\n",
-                   lineno, currentcontext->lineno);
-    }
-
-    return(0);
-}
-
-static int handle_port(struct parsedfile *config, int lineno, char *value) {
-
-    if (currentcontext->port != 0) {
-        if (currentcontext == &(config->defaultserver))
-            show_msg(MSGERR, "Server port may only be specified "
-                   "once for default server, at line %d "
-                   "in configuration file\n", lineno);
-        else
-            show_msg(MSGERR, "Server port may only be specified "
-                   "once per path on line %d in configuration "
-                   "file. (Path begins on line %d)\n",
-                   lineno, currentcontext->lineno);
-    } else {
-        errno = 0;
-        currentcontext->port = (unsigned short int)
-                  (strtol(value, (char **)NULL, 10));
-        if ((errno != 0) || (currentcontext->port == 0)) {
-            show_msg(MSGERR, "Invalid server port number "
-                   "specified in configuration file "
-                   "(%s) on line %d\n", value, lineno);
-            currentcontext->port = 0;
-        }
-    }
-
-    return(0);
-}
-
-static int handle_defuser(struct parsedfile *config, int lineno, char *value) {
-
-    if (currentcontext->defuser != NULL) {
-        if (currentcontext == &(config->defaultserver))
-            show_msg(MSGERR, "Default username may only be specified "
-                   "once for default server, at line %d "
-                   "in configuration file\n", lineno);
-        else
-            show_msg(MSGERR, "Default username may only be specified "
-                   "once per path on line %d in configuration "
-                   "file. (Path begins on line %d)\n",
-                   lineno, currentcontext->lineno);
-    } else {
-        currentcontext->defuser = strdup(value);
-    }
-
-    return(0);
-}
-
-static int handle_defpass(struct parsedfile *config, int lineno, char *value) {
-
-    if (currentcontext->defpass != NULL) {
-        if (currentcontext == &(config->defaultserver))
-            show_msg(MSGERR, "Default password may only be specified "
-                   "once for default server, at line %d "
-                   "in configuration file\n", lineno);
-        else
-            show_msg(MSGERR, "Default password may only be specified "
-                   "once per path on line %d in configuration "
-                   "file. (Path begins on line %d)\n",
-                   lineno, currentcontext->lineno);
-    } else {
-        currentcontext->defpass = strdup(value);
-    }
-
-    return(0);
-}
-
-static int handle_type(struct parsedfile *config, int lineno, char *value) {
-
-    if (currentcontext->type != 0) {
-        if (currentcontext == &(config->defaultserver))
-            show_msg(MSGERR, "Server type may only be specified "
-                   "once for default server, at line %d "
-                   "in configuration file\n", lineno);
-        else
-            show_msg(MSGERR, "Server type may only be specified "
-                   "once per path on line %d in configuration "
-                   "file. (Path begins on line %d)\n",
-                   lineno, currentcontext->lineno);
-    } else {
-        errno = 0;
-        currentcontext->type = (int) strtol(value, (char **)NULL, 10);
-        if ((errno != 0) || (currentcontext->type == 0) ||
-            ((currentcontext->type != 4) && (currentcontext->type != 5))) {
-            show_msg(MSGERR, "Invalid server type (%s) "
-                   "specified in configuration file "
-                   "on line %d, only 4 or 5 may be "
-                   "specified\n", value, lineno);
-            currentcontext->type = 0;
-        }
-    }
-
-    return(0);
-}
-
-static int handle_flag(char *value) 
-{
-    if(!strcasecmp(value, "true") || !strcasecmp(value, "yes")  
-                                  || !strcmp(value, "1")) {
-        return 1;
-    } else if (!strcasecmp(value, "false") || !strcasecmp(value, "no") 
-                                           || !strcmp(value, "0")) {
-        return 0;
-    } else {
-        return -1;
-    }
-}
-
-static int handle_tordns_enabled(struct parsedfile *config, int lineno,
-                           char *value)
-{
-    int val = handle_flag(value);
-    if(val == -1) {
-        show_msg(MSGERR, "Invalid value %s supplied for tordns_enabled at "
-                 "line %d in config file, IGNORED\n", value, lineno);
-    } else {
-        config->tordns_enabled = val;
-    }
-    return 0;
-}
-
-static int handle_tordns_cache_size(struct parsedfile *config,
-                           char *value)
-{
-    char *endptr;
-    long size = strtol(value, &endptr, 10);
-    if(*endptr != '\0') {
-        show_msg(MSGERR, "Error parsing integer value for "
-                 "tordns_cache_size (%s), using default %d\n", 
-                 value, config->tordns_cache_size);
-    } else if(size < 128) {
-        show_msg(MSGERR, "The value supplied for tordns_cache_size (%d) "
-                 "is too small (<128), using default %d\n", size, 
-                 config->tordns_cache_size);
-    } else if(size > 4096) {
-        show_msg(MSGERR, "The value supplied for tordns_cache_range (%d) "
-                 "is too large (>4096), using default %d\n", size, 
-                 config->tordns_cache_size);
-    } else {
-        config->tordns_cache_size = size;
-    }
-    return 0;
-}
-
-static int handle_tordns_deadpool_range(struct parsedfile *config, int lineno, 
-                           const char *value)
-{
-    int rc;
-    struct netent *ent;
-
-    if (config->tordns_deadpool_range != NULL) {
-        show_msg(MSGERR, "Only one 'deadpool' entry permitted, found a "
-               "second at line %d in configuration file.\n");
-        return(0);
-    }
-
-    if (currentcontext != &(config->defaultserver)) {
-        show_msg(MSGERR, "Deadpool cannot be specified in path "
-               "block at line %d in configuration file. "
-               "(Path block started at line %d)\n",
-               lineno, currentcontext->lineno);
-        return(0);
-    }
-
-    rc = make_netent((char *)value, &ent);
-    /* This is copied from handle_local and should probably be folded into
-       a generic whinge() function or something */
-    switch(rc) {
-        case 1:
-            show_msg(MSGERR, "The deadpool specification (%s) is not validly "
-                   "constructed on line %d in configuration "
-                   "file\n", value, lineno);
-            return(0);
-            break;
-        case 2:
-            show_msg(MSGERR, "IP for deadpool "
-                   "network specification (%s) is not valid on line "
-                   "%d in configuration file\n", value, lineno);
-            return(0);
-            break;
-        case 3:
-            show_msg(MSGERR, "SUBNET for " 
-                   "deadpool network specification (%s) is not valid on "
-                   "line %d in configuration file\n", value, 
-                   lineno);
-            return(0);
-            break;
-        case 4:
-            show_msg(MSGERR, "IP (%s) & ", inet_ntoa(ent->localip));
-            show_msg(MSGERR, "SUBNET (%s) != IP on line %d in "
-                   "configuration file, ignored\n",
-                   inet_ntoa(ent->localnet), lineno);
-            return(0);
-        case 5:
-        case 6:
-        case 7:
-            show_msg(MSGERR, "Port specification is invalid and "
-                   "not allowed in deadpool specification "
-               "(%s) on line %d in configuration file\n",
-                   value, lineno);
-            return(0);
-         break;
-    }
-    if (ent->startport || ent->endport) {
-        show_msg(MSGERR, "Port specification is "
-           "not allowed in deadpool specification "
-           "(%s) on line %d in configuration file\n",
-           value, lineno);
-        return(0);
-    }
-
-    config->tordns_deadpool_range = ent;
-    return 0;
-}
-
-static int handle_local(struct parsedfile *config, int lineno, const char *value) {
-    int rc;
-    struct netent *ent;
-
-    if (currentcontext != &(config->defaultserver)) {
-        show_msg(MSGERR, "Local networks cannot be specified in path "
-               "block at line %d in configuration file. "
-               "(Path block started at line %d)\n",
-               lineno, currentcontext->lineno);
-        return(0);
-    }
-
-    rc = make_netent((char *)value, &ent);
-    switch(rc) {
-        case 1:
-            show_msg(MSGERR, "Local network specification (%s) is not validly "
-                   "constructed on line %d in configuration "
-                   "file\n", value, lineno);
-            return(0);
-            break;
-        case 2:
-            show_msg(MSGERR, "IP for local "
-                   "network specification (%s) is not valid on line "
-                   "%d in configuration file\n", value, lineno);
-            return(0);
-            break;
-        case 3:
-            show_msg(MSGERR, "SUBNET for "
-                   "local network specification (%s) is not valid on "
-                   "line %d in configuration file\n", value,
-                   lineno);
-            return(0);
-            break;
-        case 4:
-            show_msg(MSGERR, "IP (%s) & ", inet_ntoa(ent->localip));
-            show_msg(MSGERR, "SUBNET (%s) != IP on line %d in "
-                   "configuration file, ignored\n",
-                   inet_ntoa(ent->localnet), lineno);
-            return(0);
-        case 5:
-        case 6:
-        case 7:
-            show_msg(MSGERR, "Port specification is invalid and "
-                   "not allowed in local network specification "
-               "(%s) on line %d in configuration file\n",
-                   value, lineno);
-            return(0);
-         break;
-    }
-
-    if (ent->startport || ent->endport) {
-        show_msg(MSGERR, "Port specification is "
-              "not allowed in local network specification "
-              "(%s) on line %d in configuration file\n",
-              value, lineno);
-        return(0);
-    }
-
-    /* The entry is valid so add it to linked list */
-    ent -> next = config->localnets;
-    (config->localnets) = ent;
-
-    return(0);
-}
-
-/* Construct a netent given a string like                             */
-/* "198.126.0.1[:portno[-portno]]/255.255.255.0"                      */
-int make_netent(char *value, struct netent **ent) {
-    char *ip;
-    char *subnet;
-    char *startport = NULL;
-    char *endport = NULL;
-    char *badchar;
-    char separator;
-    static char buf[200];
-    char *split;
-
-   /* Get a copy of the string so we can modify it */
-    strncpy(buf, value, sizeof(buf) - 1);
-    buf[sizeof(buf) - 1] = (char) 0;
-    split = buf;
-
-   /* Now rip it up */
-   ip = strsplit(&separator, &split, "/:");
-   if (separator == ':') {
-      /* We have a start port */
-      startport = strsplit(&separator, &split, "-/");
-      if (separator == '-') 
-         /* We have an end port */
-         endport = strsplit(&separator, &split, "/");
-   }
-   subnet = strsplit(NULL, &split, " \n");
-
-   if ((ip == NULL) || (subnet == NULL)) {
-      /* Network specification not validly constructed */
-      return(1);
-   }
-
-   /* Allocate the new entry */
-   if ((*ent = (struct netent *) malloc(sizeof(struct netent)))
-      == NULL) {
-      /* If we couldn't malloc some storage, leave */
-      exit(1);
-   }
-
-   show_msg(MSGDEBUG, "New network entry for %s going to 0x%08x\n", ip, *ent);
-
-   if (!startport)
-      (*ent)->startport = 0;
-   if (!endport)
-      (*ent)->endport = 0;
-
-#ifdef HAVE_INET_ADDR
-   if (((*ent)->localip.s_addr = inet_addr(ip)) == -1) {
-#elif defined(HAVE_INET_ATON)
-   if (!(inet_aton(ip, &((*ent)->localip)))) {
-#endif
-      /* Badly constructed IP */
-      free(*ent);
-      return(2);
-   }
-#ifdef HAVE_INET_ADDR
-   else if (((*ent)->localnet.s_addr = inet_addr(subnet)) == -1) {
-#elif defined(HAVE_INET_ATON)
-   else if (!(inet_aton(subnet, &((*ent)->localnet)))) {
-#endif
-      /* Badly constructed subnet */
-      free(*ent);
-      return(3);
-   } else if (((*ent)->localip.s_addr &
-          (*ent)->localnet.s_addr) != 
-                   (*ent)->localip.s_addr) {
-      /* Subnet and Ip != Ip */
-      free(*ent);
-      return(4);
-   } else if (startport && 
-              (!((*ent)->startport = strtol(startport, &badchar, 10)) || 
-               (*badchar != 0) || ((*ent)->startport > 65535))) {
-      /* Bad start port */
-      free(*ent);
-      return(5);
-   } else if (endport && 
-              (!((*ent)->endport = strtol(endport, &badchar, 10)) || 
-               (*badchar != 0) || ((*ent)->endport > 65535))) {
-      /* Bad end port */
-      free(*ent);
-      return(6);
-   } else if (((*ent)->startport > (*ent)->endport) && !(startport && !endport)) {
-      /* End port is less than start port */
-      free(*ent);
-      return(7);
-   }
-
-   if (startport && !endport)
-      (*ent)->endport = (*ent)->startport;
-
-    return(0);
-}
-
-int is_local(struct parsedfile *config, struct in_addr *testip) {
-    struct netent *ent;
-    char buf[16];
-    inet_ntop(AF_INET, testip, buf, sizeof(buf));
-    show_msg(MSGDEBUG, "checking if address: %s is local"
-                        "\n",
-                        buf);
-
-    for (ent = (config->localnets); ent != NULL; ent = ent -> next) {
-        inet_ntop(AF_INET, &ent->localnet, buf, sizeof(buf));
-        show_msg(MSGDEBUG, "localnet addr: %s"
-                            "\n",
-                            buf);
-        inet_ntop(AF_INET, &ent->localip, buf, sizeof(buf));
-        show_msg(MSGDEBUG, "localip addr: %s"
-                            "\n",
-                            buf);
-        show_msg(MSGDEBUG, "result testip->s_addr & ent->localnet.s_addr : %i"
-                            "\n",
-                            testip->s_addr & ent->localnet.s_addr);
-        show_msg(MSGDEBUG, "result ent->localip.s_addr & ent->localnet.s_addr : %i"
-                            "\n",
-                            ent->localip.s_addr & ent->localnet.s_addr);
-        show_msg(MSGDEBUG, "result ent->localip.s_addr : %i"
-                            "\n",
-                            ent->localip.s_addr);
-        if ((testip->s_addr & ent->localnet.s_addr) ==
-            (ent->localip.s_addr & ent->localnet.s_addr))  {
-            show_msg(MSGDEBUG, "address: %s is local"
-                                "\n",
-                                buf);
-            return(0);
-        }
-    }
-
-    inet_ntop(AF_INET, testip, buf, sizeof(buf));
-    show_msg(MSGDEBUG, "address: %s is not local"
-                        "\n",
-                        buf);
-    return(1);
-}
-
-/* Find the appropriate server to reach an ip */
-int pick_server(struct parsedfile *config, struct serverent **ent, 
-                struct in_addr *ip, unsigned int port) {
-    struct netent *net;
-   char ipbuf[64];
-
-   show_msg(MSGDEBUG, "Picking appropriate server for %s\n", inet_ntoa(*ip));
-    *ent = (config->paths);
-    while (*ent != NULL) {
-        /* Go through all the servers looking for one */
-        /* with a path to this network                */
-        show_msg(MSGDEBUG, "Checking SOCKS server %s\n", 
-                ((*ent)->address ? (*ent)->address : "(No Address)"));
-        net = (*ent)->reachnets;
-        while (net != NULL) {
-         strcpy(ipbuf, inet_ntoa(net->localip));
-         show_msg(MSGDEBUG, "Server can reach %s/%s\n", 
-                  ipbuf, inet_ntoa(net->localnet));
-            if (((ip->s_addr & net->localnet.s_addr) ==
-                (net->localip.s_addr & net->localnet.s_addr)) &&
-                (!net->startport || 
-                ((net->startport <= port) && (net->endport >= port))))  
-            {
-                show_msg(MSGDEBUG, "This server can reach target\n");
-                    /* Found the net, return */
-                    return(0);
-            }
-            net = net->next;
-        }
-        (*ent) = (*ent)->next;
-    }
-
-    *ent = &(config->defaultserver);
-
-    return(0);
-}
-
-/* This function is very much like strsep, it looks in a string for */
-/* a character from a list of characters, when it finds one it      */
-/* replaces it with a \0 and returns the start of the string        */
-/* (basically spitting out tokens with arbitrary separators). If no */
-/* match is found the remainder of the string is returned and       */
-/* the start pointer is set to be NULL. The difference between      */
-/* standard strsep and this function is that this one will          */
-/* set *separator to the character separator found if it isn't null */
-char *strsplit(char *separator, char **text, const char *search) {
-   unsigned int len;
-   char *ret;
-
-   ret = *text;
-
-    if (*text == NULL) {
-      if (separator)
-         *separator = '\0';
-      return(NULL);
-    } else {
-      len = strcspn(*text, search);
-      if (len == strlen(*text)) {
-         if (separator)
-            *separator = '\0';
-         *text = NULL;
-      } else {
-         *text = *text + len;
-         if (separator)
-            *separator = **text;
-         **text = '\0';
-         *text = *text + 1;
-      }
-    }
-
-   return(ret);
-}
diff --git a/src/parser.h b/src/parser.h
deleted file mode 100644
index 91e6d04..0000000
--- a/src/parser.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
- *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-
-/* parser.h - Structures, functions and global variables for the
-   torsocks parsing routines                                       */
-
-#ifndef _PARSER_H
-
-#define _PARSER_H 1
-
-/* Structure definitions */
-
-/* Structure representing one server specified in the config */
-struct serverent {
-    int lineno;               /* Line number in conf file this path started on */
-    char *address;            /* Address/hostname of server */
-    int port;                 /* Port number of server */
-    int type;                 /* Type of server (4/5) */
-    char *defuser;            /* Default username for this socks server */
-    char *defpass;            /* Default password for this socks server */
-    struct netent *reachnets; /* Linked list of nets from this server */
-    struct serverent *next;   /* Pointer to next server entry */
-};
-
-/* Structure representing a network */
-struct netent {
-   struct in_addr localip;    /* Base IP of the network */
-   struct in_addr localnet;   /* Mask for the network */
-   unsigned long startport;   /* Range of ports for the */
-   unsigned long endport;     /* network                */
-   struct netent *next;       /* Pointer to next network entry */
-};
-
-/* Structure representing a complete parsed file */
-struct parsedfile {
-   struct netent *localnets;
-   struct serverent defaultserver;
-   struct serverent *paths;
-   int tordns_enabled;
-   int tordns_failopen;
-   unsigned int tordns_cache_size;
-   struct netent *tordns_deadpool_range;
-};
-
-/* Functions provided by parser module */
-int read_config(char *, struct parsedfile *);
-int is_local(struct parsedfile *, struct in_addr *);
-int pick_server(struct parsedfile *, struct serverent **, struct in_addr *, unsigned int port);
-char *strsplit(char *separator, char **text, const char *search);
-
-#endif
diff --git a/src/socks.c b/src/socks.c
deleted file mode 100644
index 8497728..0000000
--- a/src/socks.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
- *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-/* PreProcessor Defines */
-#include <config.h>
-
-/*Defining _NONSTD_SOURCE causes library and kernel calls to behave as closely
-to Mac OS X 10.3's library and kernel calls as possible.*/
-#if defined(__APPLE__) || defined(__darwin__)
-/*
-From 'man compat' in OSX:
-64-BIT COMPILATION
-     When compiling for 64-bit architectures, the __LP64__ macro will be defined to 1, and UNIX conformance
-     is always on (the _DARWIN_FEATURE_UNIX_CONFORMANCE macro will also be defined to the SUS conformance
-     level).  Defining _NONSTD_SOURCE will cause a compilation error.
-*/
-#if !defined(__LP64__)
-#define _NONSTD_SOURCE 1
-#endif
-#include <sys/socket.h>
-#endif
-
-
-#ifdef USE_GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-/* Header Files */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <sys/types.h>
-#include <string.h>
-#include <strings.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/poll.h>
-#include <sys/time.h>
-#include <pwd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <stdarg.h>
-#if !defined(__APPLE__) && !defined(__darwin__)
-#include <sys/socket.h>
-#endif
-#include <resolv.h>
-
-#include "common.h"
-#include "dead_pool.h"
-#include "parser.h"
-#include "socks.h"
-
-static int connect_server(struct connreq *conn);
-static int send_socks_request(struct connreq *conn);
-static int send_socksv4_request(struct connreq *conn);
-static int send_socksv5_method(struct connreq *conn);
-static int send_socksv5_connect(struct connreq *conn);
-static int send_buffer(struct connreq *conn);
-static int recv_buffer(struct connreq *conn);
-static int read_socksv5_method(struct connreq *conn);
-static int read_socksv4_req(struct connreq *conn);
-static int read_socksv5_connect(struct connreq *conn);
-static int read_socksv5_auth(struct connreq *conn);
-static int send_socksv4a_request(struct connreq *conn, const char *onion_host);
-
-
-dead_pool *pool = NULL;
-struct connreq *requests = NULL;
-
-struct connreq *new_socks_request(int sockid, struct sockaddr_in *connaddr,
-                                         struct sockaddr_in *serveraddr,
-                                         struct serverent *path)
-{
-    struct connreq *newconn;
-
-    if ((newconn = malloc(sizeof(*newconn))) == NULL) {
-        /* Could not malloc, we're stuffed */
-        show_msg(MSGERR, "Could not allocate memory for new socks request\n");
-        return(NULL);
-    }
-
-    /* Add this connection to be proxied to the list */
-    memset(newconn, 0x0, sizeof(*newconn));
-    newconn->sockid = sockid;
-    newconn->state = UNSTARTED;
-    newconn->path = path;
-    memcpy(&(newconn->connaddr), connaddr, sizeof(newconn->connaddr));
-    memcpy(&(newconn->serveraddr), serveraddr, sizeof(newconn->serveraddr));
-    newconn->next = requests;
-    requests = newconn;
-
-    return(newconn);
-}
-
-void kill_socks_request(struct connreq *conn)
-{
-    struct connreq *connnode;
-
-    if (requests == conn)
-        requests = conn->next;
-    else {
-        for (connnode = requests; connnode != NULL; connnode = connnode->next) {
-            if (connnode->next == conn) {
-                connnode->next = conn->next;
-                break;
-            }
-        }
-    }
-
-    free(conn);
-}
-
-struct connreq *find_socks_request(int sockid, int includefinished)
-{
-    struct connreq *connnode;
-
-    for (connnode = requests; connnode != NULL; connnode = connnode->next) {
-        if (connnode->sockid == sockid) {
-            if (((connnode->state == FAILED) || (connnode->state == DONE)) &&
-                !includefinished)
-                break;
-            else
-                return(connnode);
-        }
-    }
-
-    return(NULL);
-}
-
-int handle_request(struct connreq *conn)
-{
-    int rc = 0;
-    int i = 0;
-
-    show_msg(MSGDEBUG, "Beginning handle loop for socket %d\n", conn->sockid);
-
-    while ((rc == 0) &&
-            (conn->state != FAILED) &&
-            (conn->state != DONE) &&
-            (i++ < 20)) {
-        show_msg(MSGDEBUG, "In request handle loop for socket %d, "
-                           "current state of request is %d\n", conn->sockid,
-                           conn->state);
-        switch(conn->state) {
-          case UNSTARTED:
-          case CONNECTING:
-              rc = connect_server(conn);
-              break;
-          case CONNECTED:
-              rc = send_socks_request(conn);
-              break;
-          case SENDING:
-              rc = send_buffer(conn);
-              break;
-          case RECEIVING:
-              rc = recv_buffer(conn);
-              break;
-          case SENTV4REQ:
-              show_msg(MSGDEBUG, "Receiving reply to SOCKS V4 connect request\n");
-              conn->datalen = sizeof(struct sockrep);
-              conn->datadone = 0;
-              conn->state = RECEIVING;
-              conn->nextstate = GOTV4REQ;
-              break;
-          case GOTV4REQ:
-              rc = read_socksv4_req(conn);
-              break;
-          case SENTV5METHOD:
-              show_msg(MSGDEBUG, "Receiving reply to SOCKS V5 method negotiation\n");
-              conn->datalen = 2;
-              conn->datadone = 0;
-              conn->state = RECEIVING;
-              conn->nextstate = GOTV5METHOD;
-              break;
-          case GOTV5METHOD:
-              rc = read_socksv5_method(conn);
-              break;
-          case SENTV5AUTH:
-              show_msg(MSGDEBUG, "Receiving reply to SOCKS V5 authentication negotiation\n");
-              conn->datalen = 2;
-              conn->datadone = 0;
-              conn->state = RECEIVING;
-              conn->nextstate = GOTV5AUTH;
-              break;
-          case GOTV5AUTH:
-              rc = read_socksv5_auth(conn);
-              break;
-          case SENTV5CONNECT:
-              show_msg(MSGDEBUG, "Receiving reply to SOCKS V5 connect request\n");
-              conn->datalen = 10;
-              conn->datadone = 0;
-              conn->state = RECEIVING;
-              conn->nextstate = GOTV5CONNECT;
-              break;
-          case GOTV5CONNECT:
-              rc = read_socksv5_connect(conn);
-              break;
-        }
-        conn->err = errno;
-    }
-
-    if (i == 20)
-        show_msg(MSGERR, "Ooops, state loop while handling request %d\n",
-                conn->sockid);
-
-    show_msg(MSGDEBUG, "Handle loop completed for socket %d in state %d, "
-                       "returning %d\n", conn->sockid, conn->state, rc);
-    return(rc);
-}
-
-static int connect_server(struct connreq *conn)
-{
-    int rc;
-
-    /* Connect this socket to the socks server */
-    show_msg(MSGDEBUG, "Connecting to %s port %d\n",
-             inet_ntoa(conn->serveraddr.sin_addr), ntohs(conn->serveraddr.sin_port));
-
-    rc = realconnect(conn->sockid, (CONNECT_SOCKARG) &(conn->serveraddr),
-                     sizeof(conn->serveraddr));
-
-    show_msg(MSGDEBUG, "Connect returned %d, errno is %d\n", rc, errno);
-    if (rc && errno == EISCONN) {
-        rc = 0;
-        show_msg(MSGDEBUG, "Socket %d already connected to SOCKS server\n", conn->sockid);
-        conn->state = CONNECTED;
-    } else if (rc) {
-        if (errno != EINPROGRESS) {
-            show_msg(MSGERR, "Error %d attempting to connect to SOCKS "
-                             "server (%s)\n", errno, strerror(errno));
-            conn->state = FAILED;
-        } else {
-            show_msg(MSGDEBUG, "Connection in progress\n");
-            conn->state = CONNECTING;
-        }
-    } else {
-        show_msg(MSGDEBUG, "Socket %d connected to SOCKS server\n", conn->sockid);
-        conn->state = CONNECTED;
-    }
-
-    return((rc ? errno : 0));
-}
-
-static int send_socks_request(struct connreq *conn)
-{
-    int rc = 0;
-
-    if (conn->path->type == 4) {
-        char *name = get_pool_entry(pool, &(conn->connaddr.sin_addr));
-        if(name != NULL)
-            rc = send_socksv4a_request(conn,name);
-        else
-            rc = send_socksv4_request(conn);
-    } else
-        rc = send_socksv5_method(conn);
-    return(rc);
-}
-
-static int send_socksv4a_request(struct connreq *conn,const char *onion_host)
-{
-    struct passwd *user;
-    struct sockreq *thisreq;
-    int endOfUser;
-    /* Determine the current username */
-    user = getpwuid(getuid());
-
-    thisreq = (struct sockreq *) conn->buffer;
-    endOfUser=sizeof(struct sockreq) +
-    (user == NULL ? 0 : strlen(user->pw_name)) + 1;
-
-    /* Check the buffer has enough space for the request  */
-    /* and the user name                                  */
-    conn->datalen = endOfUser+
-                    (onion_host == NULL ? 0 : strlen(onion_host)) + 1;
-    if (sizeof(conn->buffer) < conn->datalen) {
-        show_msg(MSGERR, "The SOCKS username is too long");
-        conn->state = FAILED;
-        return(ECONNREFUSED);
-    }
-
-    /* Create the request */
-    thisreq->version = 4;
-    thisreq->command = 1;
-    thisreq->dstport = conn->connaddr.sin_port;
-    thisreq->dstip   = htonl(1);
-
-    /* Copy the username */
-    strcpy((char *) thisreq + sizeof(struct sockreq),
-          (user == NULL ? "" : user->pw_name));
-
-    /* Copy the onion host */
-    strcpy((char *) thisreq + endOfUser,
-          (onion_host == NULL ? "" : onion_host));
-
-    conn->datadone = 0;
-    conn->state = SENDING;
-    conn->nextstate = SENTV4REQ;
-
-    return(0);
-}
-
-static int send_socksv4_request(struct connreq *conn)
-{
-    struct passwd *user;
-    struct sockreq *thisreq;
-
-    /* Determine the current username */
-    user = getpwuid(getuid());
-
-    thisreq = (struct sockreq *) conn->buffer;
-
-    /* Check the buffer has enough space for the request  */
-    /* and the user name                                  */
-    conn->datalen = sizeof(struct sockreq) +
-                    (user == NULL ? 0 : strlen(user->pw_name)) + 1;
-    if (sizeof(conn->buffer) < conn->datalen) {
-        show_msg(MSGERR, "The SOCKS username is too long");
-        conn->state = FAILED;
-        return(ECONNREFUSED);
-    }
-
-    /* Create the request */
-    thisreq->version = 4;
-    thisreq->command = 1;
-    thisreq->dstport = conn->connaddr.sin_port;
-    thisreq->dstip   = conn->connaddr.sin_addr.s_addr;
-
-    /* Copy the username */
-    strcpy((char *) thisreq + sizeof(struct sockreq),
-            (user == NULL ? "" : user->pw_name));
-
-    conn->datadone = 0;
-    conn->state = SENDING;
-    conn->nextstate = SENTV4REQ;
-
-    return(0);
-}
-
-static int send_socksv5_method(struct connreq *conn)
-{
-    char verstring[] = { 0x05,    /* Version 5 SOCKS */
-                          0x02,    /* No. Methods     */
-                          0x00,    /* Null Auth       */
-                          0x02 };  /* User/Pass Auth  */
-
-    show_msg(MSGDEBUG, "Constructing V5 method negotiation\n");
-    conn->state = SENDING;
-    conn->nextstate = SENTV5METHOD;
-    memcpy(conn->buffer, verstring, sizeof(verstring));
-    conn->datalen = sizeof(verstring);
-    conn->datadone = 0;
-
-    return(0);
-}
-
-static int send_socksv5_connect(struct connreq *conn)
-{
-    int namelen = 0;
-    char *name = NULL;
-    char constring[] = { 0x05,    /* Version 5 SOCKS */
-                          0x01,    /* Connect request */
-                          0x00,    /* Reserved        */
-                          0x01 };  /* IP Version 4    */
-
-    show_msg(MSGDEBUG, "Constructing V5 connect request\n");
-    conn->datadone = 0;
-    conn->state = SENDING;
-    conn->nextstate = SENTV5CONNECT;
-    memcpy(conn->buffer, constring, sizeof(constring));
-    conn->datalen = sizeof(constring);
-
-    show_msg(MSGDEBUG, "send_socksv5_connect: looking for: %s\n",
-              inet_ntoa(conn->connaddr.sin_addr));
-
-    name = get_pool_entry(pool, &(conn->connaddr.sin_addr));
-    if(name != NULL) {
-        namelen = strlen(name);
-        if(namelen > 255)  /* "Can't happen" */
-            name = NULL;
-    }
-    if(name != NULL) {
-        show_msg(MSGDEBUG, "send_socksv5_connect: found it!\n");
-        /* Substitute the domain name from the pool into the SOCKS request. */
-        conn->buffer[3] = 0x03;  /* Change the ATYP field */
-        conn->buffer[4] = namelen;  /* Length of name */
-        conn->datalen++;
-        memcpy(&conn->buffer[conn->datalen], name, namelen);
-        conn->datalen += namelen;
-    } else {
-        show_msg(MSGDEBUG, "send_socksv5_connect: ip address not found\n");
-        /* Use the raw IP address */
-        memcpy(&conn->buffer[conn->datalen], &(conn->connaddr.sin_addr.s_addr),
-                sizeof(conn->connaddr.sin_addr.s_addr));
-        conn->datalen += sizeof(conn->connaddr.sin_addr.s_addr);
-    }
-    memcpy(&conn->buffer[conn->datalen], &(conn->connaddr.sin_port),
-          sizeof(conn->connaddr.sin_port));
-    conn->datalen += sizeof(conn->connaddr.sin_port);
-
-    return(0);
-}
-
-static int send_buffer(struct connreq *conn)
-{
-    int rc = 0;
-
-    show_msg(MSGDEBUG, "Writing to server (sending %d bytes)\n", conn->datalen);
-    while ((rc == 0) && (conn->datadone != conn->datalen)) {
-        rc = send(conn->sockid, conn->buffer + conn->datadone,
-                  conn->datalen - conn->datadone, 0);
-        if (rc > 0) {
-            conn->datadone += rc;
-            rc = 0;
-        } else {
-            if (errno != EWOULDBLOCK)
-                show_msg(MSGDEBUG, "Write failed, %s\n", strerror(errno));
-            rc = errno;
-        }
-    }
-
-    if (conn->datadone == conn->datalen)
-        conn->state = conn->nextstate;
-
-    show_msg(MSGDEBUG, "Sent %d bytes of %d bytes in buffer, return code is %d\n",
-              conn->datadone, conn->datalen, rc);
-    return(rc);
-}
-
-static int recv_buffer(struct connreq *conn)
-{
-    int rc = 0;
-
-    show_msg(MSGDEBUG, "Reading from server (expecting %d bytes)\n", conn->datalen);
-    while ((rc == 0) && (conn->datadone != conn->datalen)) {
-          rc = recv(conn->sockid, conn->buffer + conn->datadone,
-                    conn->datalen - conn->datadone, 0);
-          if (rc > 0) {
-              conn->datadone += rc;
-              rc = 0;
-          } else if (rc == 0) {
-              show_msg(MSGDEBUG, "Peer has shutdown but we only read %d of %d bytes.\n",
-                  conn->datadone, conn->datalen);
-              rc = ENOTCONN; /* ENOTCONN seems like the most fitting error message */
-          } else {
-              if (errno != EWOULDBLOCK)
-                  show_msg(MSGDEBUG, "Read failed, %s\n", strerror(errno));
-              rc = errno;
-          }
-    }
-
-    if (conn->datadone == conn->datalen)
-        conn->state = conn->nextstate;
-
-    show_msg(MSGDEBUG, "Received %d bytes of %d bytes expected, return code is %d\n",
-             conn->datadone, conn->datalen, rc);
-    return(rc);
-}
-
-static int read_socksv5_method(struct connreq *conn)
-{
-    struct passwd *nixuser;
-    char *uname, *upass;
-
-    /* See if we offered an acceptable method */
-    if (conn->buffer[1] == '\xff') {
-        show_msg(MSGERR, "SOCKS V5 server refused authentication methods\n");
-        conn->state = FAILED;
-        return(ECONNREFUSED);
-    }
-
-    /* If the socks server chose username/password authentication */
-    /* (method 2) then do that                                    */
-    if ((unsigned short int) conn->buffer[1] == 2) {
-        show_msg(MSGDEBUG, "SOCKS V5 server chose username/password authentication\n");
-
-        /* Determine the current *nix username */
-        nixuser = getpwuid(getuid());
-
-        if (((uname = conn->path->defuser) == NULL) &&
-          ((uname = getenv("TORSOCKS_USERNAME")) == NULL) &&
-            ((uname = (nixuser == NULL ? NULL : nixuser->pw_name)) == NULL)) {
-            show_msg(MSGERR, "Could not get SOCKS username from "
-                    "local passwd file, torsocks.conf "
-                    "or $TORSOCKS_USERNAME to authenticate "
-                    "with");
-            conn->state = FAILED;
-            return(ECONNREFUSED);
-        }
-
-        if (((upass = getenv("TORSOCKS_PASSWORD")) == NULL) &&
-          ((upass = conn->path->defpass) == NULL)) {
-            show_msg(MSGERR, "Need a password in torsocks.conf or "
-                    "$TORSOCKS_PASSWORD to authenticate with");
-            conn->state = FAILED;
-            return(ECONNREFUSED);
-        }
-
-        /* Check that the username / pass specified will */
-        /* fit into the buffer                */
-        if ((3 + strlen(uname) + strlen(upass)) >= sizeof(conn->buffer)) {
-            show_msg(MSGERR, "The supplied socks username or "
-                    "password is too long");
-            conn->state = FAILED;
-            return(ECONNREFUSED);
-        }
-
-        conn->datalen = 0;
-        conn->buffer[conn->datalen] = '\x01';
-        conn->datalen++;
-        conn->buffer[conn->datalen] = (int8_t) strlen(uname);
-        conn->datalen++;
-        memcpy(&(conn->buffer[conn->datalen]), uname, strlen(uname));
-        conn->datalen = conn->datalen + strlen(uname);
-        conn->buffer[conn->datalen] = (int8_t) strlen(upass);
-        conn->datalen++;
-        memcpy(&(conn->buffer[conn->datalen]), upass, strlen(upass));
-        conn->datalen = conn->datalen + strlen(upass);
-
-        conn->state = SENDING;
-        conn->nextstate = SENTV5AUTH;
-        conn->datadone = 0;
-    } else
-        return(send_socksv5_connect(conn));
-
-    return(0);
-}
-
-static int read_socksv5_auth(struct connreq *conn)
-{
-
-    if (conn->buffer[1] != '\x00') {
-        show_msg(MSGERR, "SOCKS authentication failed, check username and password\n");
-        conn->state = FAILED;
-        return(ECONNREFUSED);
-    }
-
-    /* Ok, we authenticated ok, send the connection request */
-    return(send_socksv5_connect(conn));
-}
-
-static int read_socksv5_connect(struct connreq *conn)
-{
-
-    /* See if the connection succeeded */
-    if (conn->buffer[1] != '\x00') {
-        show_msg(MSGERR, "SOCKS V5 connect failed: ");
-        conn->state = FAILED;
-        switch ((int8_t) conn->buffer[1]) {
-            case 1:
-                show_msg(MSGERR, "General SOCKS server failure\n");
-                return(ECONNABORTED);
-            case 2:
-                show_msg(MSGERR, "Connection denied by rule\n");
-                return(ECONNABORTED);
-            case 3:
-                show_msg(MSGERR, "Network unreachable\n");
-                return(ENETUNREACH);
-            case 4:
-                show_msg(MSGERR, "Host unreachable\n");
-                return(EHOSTUNREACH);
-            case 5:
-                show_msg(MSGERR, "Connection refused\n");
-                return(ECONNREFUSED);
-            case 6:
-                show_msg(MSGERR, "TTL Expired\n");
-                return(ETIMEDOUT);
-            case 7:
-                show_msg(MSGERR, "Command not supported\n");
-                return(ECONNABORTED);
-            case 8:
-                show_msg(MSGERR, "Address type not supported\n");
-                return(ECONNABORTED);
-            default:
-                show_msg(MSGERR, "Unknown error\n");
-                return(ECONNABORTED);
-        }
-    }
-    conn->state = DONE;
-
-    return(0);
-}
-
-static int read_socksv4_req(struct connreq *conn)
-{
-    struct sockrep *thisrep;
-
-    thisrep = (struct sockrep *) conn->buffer;
-
-    if (thisrep->result != 90) {
-        show_msg(MSGERR, "SOCKS V4 connect rejected:\n");
-        conn->state = FAILED;
-        switch(thisrep->result) {
-          case 91:
-              show_msg(MSGERR, "SOCKS server refused connection\n");
-              return(ECONNREFUSED);
-          case 92:
-              show_msg(MSGERR, "SOCKS server refused connection "
-                    "because of failed connect to identd "
-                    "on this machine\n");
-              return(ECONNREFUSED);
-          case 93:
-              show_msg(MSGERR, "SOCKS server refused connection "
-                    "because identd and this library "
-                    "reported different user-ids\n");
-              return(ECONNREFUSED);
-          default:
-              show_msg(MSGERR, "Unknown reason\n");
-              return(ECONNREFUSED);
-        }
-    }
-    conn->state = DONE;
-
-    return(0);
-}
diff --git a/src/socks.h b/src/socks.h
deleted file mode 100644
index 6dd497f..0000000
--- a/src/socks.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
- *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-/* socks.h - Structures used by torsocks to form SOCKS requests */
-
-#ifndef _SOCKS_H
-
-#define _SOCKS_H 1
-
-#include "parser.h"
-#include "dead_pool.h"
-
-/* Structure representing a socks connection request */
-struct sockreq {
-   int8_t version;
-   int8_t command;
-   int16_t dstport;
-   int32_t dstip;
-   /* A null terminated username goes here */
-};
-
-/* Structure representing a socks connection request response */
-struct sockrep {
-   int8_t version;
-   int8_t result;
-   int16_t ignore1;
-   int32_t ignore2;
-};
-
-/* Structure representing a socket which we are currently proxying */
-struct connreq {
-   /* Information about the socket and target */
-   int sockid;
-   struct sockaddr_in connaddr;
-   struct sockaddr_in serveraddr;
-
-   /* Pointer to the config entry for the socks server */
-   struct serverent *path;
-
-   /* Current state of this proxied socket */
-   int state;
-
-   /* Next state to go to when the send or receive is finished */
-   int nextstate;
-
-   /* When connections fail but an error number cannot be reported
-    * because the socket is non blocking we keep the connreq struct until
-    * the status is queried with connect() again, we then return
-    * this value */
-   int err;
-
-   /* Events that were set for this socket upon call to select() or
-    * poll() */
-   int selectevents;
-
-   /* Buffer for sending and receiving on the socket */
-   unsigned int datalen;
-   unsigned int datadone;
-   char buffer[2048];
-
-   struct connreq *next;
-};
-
-/* Connection statuses */
-#define UNSTARTED 0
-#define CONNECTING 1
-#define CONNECTED 2
-#define SENDING 3
-#define RECEIVING 4
-#define SENTV4REQ 5
-#define GOTV4REQ 6
-#define SENTV5METHOD 7
-#define GOTV5METHOD 8
-#define SENTV5AUTH 9
-#define GOTV5AUTH 10
-#define SENTV5CONNECT 11
-#define GOTV5CONNECT 12
-#define DONE 13
-#define FAILED 14
-
-/* Flags to indicate what events a socket was select()ed for */
-#define READ (1<<0)
-#define WRITE (1<<1)
-#define EXCEPT (1<<2)
-#define READWRITE (READ|WRITE)
-#define READWRITEEXCEPT (READ|WRITE|EXCEPT)
-
-/* Global Declarations */
-extern dead_pool *pool;
-extern struct connreq *requests;
-
-struct connreq *new_socks_request(int sockid, struct sockaddr_in *connaddr,
-                                         struct sockaddr_in *serveraddr,
-                                         struct serverent *path);
-void kill_socks_request(struct connreq *conn);
-struct connreq *find_socks_request(int sockid, int includefailed);
-int handle_request(struct connreq *conn);
-
-#endif
diff --git a/src/torsocks.c b/src/torsocks.c
deleted file mode 100644
index 597c107..0000000
--- a/src/torsocks.c
+++ /dev/null
@@ -1,1108 +0,0 @@
-/***************************************************************************
- *                                                                         *
- *                                                                         *
- *   Copyright (C) 2000-2008 Shaun Clowes <delius at progsoc.org>             *
- *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-
-/* PreProcessor Defines */
-#include <config.h>
-
-/*Defining _NONSTD_SOURCE causes library and kernel calls to behave as closely
-to Mac OS X 10.3's library and kernel calls as possible.*/
-#if defined(__APPLE__) || defined(__darwin__)
-/*
-From 'man compat' in OSX:
-64-BIT COMPILATION
-     When compiling for 64-bit architectures, the __LP64__ macro will be defined to 1, and UNIX conformance
-     is always on (the _DARWIN_FEATURE_UNIX_CONFORMANCE macro will also be defined to the SUS conformance
-     level).  Defining _NONSTD_SOURCE will cause a compilation error.
-*/
-#if !defined(__LP64__)
-#define _NONSTD_SOURCE 1
-#endif
-#include <sys/socket.h>
-#endif
-
-
-#ifdef USE_GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-/* Global configuration variables */
-const char *torsocks_progname = "libtorsocks";         /* Name used in err msgs    */
-
-/* Header Files */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <dlfcn.h>
-#include <sys/types.h>
-#include <string.h>
-#include <strings.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/poll.h>
-#include <sys/time.h>
-#include <pwd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <stdarg.h>
-#if !defined(__APPLE__) && !defined(__darwin__)
-#include <sys/socket.h>
-#endif
-#include <resolv.h>
-
-#include "common.h"
-#include "dead_pool.h"
-#include "parser.h"
-#include "socks.h"
-
-/* Some function names are macroized on Darwin. Allow those names
-   to expand accordingly. */
-#define EXPAND_GUTS(x) torsocks_##x##_guts
-#define EXPAND_GUTS_NAME(x) EXPAND_GUTS(x)
-
-/* Function prototypes for original functions that we patch */
-#ifdef SUPPORT_RES_API
-int (*realres_init)(void);
-#endif
-#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r (*real##n)(s##SIGNATURE);
-#include "expansion_table.h"
-#undef PATCH_TABLE_EXPANSION
-#undef DARWIN_EXPANSION
-
-static struct parsedfile config;
-static int suid = 0;
-static char *conffile = NULL;
-
-/* Exported Function Prototypes */
-void __attribute__ ((constructor)) torsocks_init(void);
-
-/* Function prototypes for our patches */
-#ifdef SUPPORT_RES_API
-int res_init(void);
-#endif
-
-#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r n(s##SIGNATURE);
-#define DARWIN_EXPANSION(e,r,s,n,b,m)      r n(s##SIGNATURE) __asm("_" m);
-#include "expansion_table.h"
-#undef PATCH_TABLE_EXPANSION
-#undef DARWIN_EXPANSION
-
-/* Private Function Prototypes */
-/* no torsocks_res_init_guts */
-#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) r torsocks_##b##_guts(s##SIGNATURE, r (*original_##b)(s##SIGNATURE));
-#include "expansion_table.h"
-#undef PATCH_TABLE_EXPANSION
-
-static int get_config();
-static int get_environment();
-static int deadpool_init(void);
-
-static pthread_mutex_t torsocks_init_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-void torsocks_init(void)
-{
-    pthread_mutex_lock(&torsocks_init_mutex);
-
-    show_msg(MSGDEBUG, "In torsocks_init \n");
-
-    get_environment();
-    get_config();
-
-#ifdef USE_OLD_DLSYM
-    void *lib;
-#endif
-
-    /* We could do all our initialization here, but to be honest */
-    /* most programs that are run won't use our services, so     */
-    /* we do our general initialization on first call            */
-
-    /* Determine the logging level */
-    suid = (getuid() != geteuid());
-
-    dlerror();
-#ifndef USE_OLD_DLSYM
-    #ifdef SUPPORT_RES_API
-      torsocks_find_library("res_init", MSGERR, realres_init);
-    #endif
-    #define PATCH_TABLE_EXPANSION(e,r,s,n,b,m)  torsocks_find_library(m, MSG##e, real##n);
-    #include "expansion_table.h"
-    #undef PATCH_TABLE_EXPANSION
-#else
-    lib = dlopen(LIBCONNECT, RTLD_LAZY);
-    realconnect = dlsym(lib, "connect");
-    realselect = dlsym(lib, "select");
-    realpoll = dlsym(lib, "poll");
-    realgethostbyname = dlsym(lib, "gethostbyname");
-    realgethostbyaddr = dlsym(lib, "gethostbyaddr");
-    realgetaddrinfo = dlsym(lib, "getaddrinfo");
-    realgetipnodebyname = dlsym(lib, "getipnodebyname");
-    realsendto = dlsym(lib, "sendto");
-    realsendmsg = dlsym(lib, "sendmsg");
-    dlclose(lib);
-    lib = dlopen(LIBC, RTLD_LAZY);
-    realclose = dlsym(lib, "close");
-    dlclose(lib);
-    #ifdef SUPPORT_RES_API
-    lib = dlopen(LIBRESOLV, RTLD_LAZY);
-    realres_init = dlsym(lib, "res_init");
-    realresquery = dlsym(lib, "res_query");
-    realressend = dlsym(lib, "res_send");
-    realresquerydomain = dlsym(lib, "res_querydomain");
-    realressearch = dlsym(lib, "res_search");
-    dlclose(lib);
-    #endif
-#endif
-    /* Unfortunately, we can't do this lazily because otherwise our mmap'd
-       area won't be shared across fork()s. */
-    if (!deadpool_init()) {
-        show_msg(MSGERR, "Fatal error: exiting\n");
-        exit(1);
-    }
-
-    pthread_mutex_unlock(&torsocks_init_mutex);
-
-    show_msg(MSGDEBUG, "Exit torsocks_init \n");
-}
-
-static int get_environment()
-{
-    static int done = 0;
-    int loglevel = MSGERR;
-    char *logfile = NULL;
-    char *env;
-
-    if (done)
-        return(0);
-
-   /* Determine the logging level */
-    if ((env = getenv("TORSOCKS_DEBUG")))
-        loglevel = atoi(env);
-    if (((env = getenv("TORSOCKS_DEBUG_FILE"))) && !suid)
-        logfile = env;
-    set_log_options(loglevel, logfile, (loglevel == MSGTEST) ? 0 : 1);
-
-    done = 1;
-
-    return(0);
-}
-
-static int get_config ()
-{
-    static int done = 0;
-
-    if (done)
-        return(0);
-
-    /* Determine the location of the config file */
-#ifdef ALLOW_ENV_CONFIG
-    if (!suid)
-        conffile = getenv("TORSOCKS_CONF_FILE");
-#endif
-
-    /* Read in the config file */
-    read_config(conffile, &config);
-    if (config.paths)
-        show_msg(MSGDEBUG, "First lineno for first path is %d\n", config.paths->lineno);
-
-    done = 1;
-
-    return(0);
-}
-
-/* Patch trampoline functions */
-/* no torsocks_res_init_guts */
-#define PATCH_TABLE_EXPANSION(e,r,s,n,b,m) \
-   r n(s##SIGNATURE) { \
-     if (!real##n) { \
-       torsocks_find_library(m, MSG##e, real##n);\
-     } \
-     return torsocks_##b##_guts(s##ARGNAMES, real##n); \
-   }
-#include "expansion_table.h"
-#undef PATCH_TABLE_EXPANSION
-
-int torsocks_connect_guts(CONNECT_SIGNATURE, int (*original_connect)(CONNECT_SIGNATURE))
-{
-    struct sockaddr_in *connaddr;
-    struct sockaddr_in peer_address;
-    struct sockaddr_in server_address;
-    int gotvalidserver = 0, rc;
-    socklen_t namelen = sizeof(peer_address);
-    int sock_type = -1;
-    socklen_t sock_type_len = sizeof(sock_type);
-    int res = -1;
-    struct serverent *path;
-    struct connreq *newconn;
-
-    /* If the real connect doesn't exist, we're stuffed */
-    if (original_connect == NULL) {
-        show_msg(MSGERR, "Unresolved symbol: connect\n");
-        return(-1);
-    }
-
-    show_msg(MSGTEST, "Got connection request\n");
-
-    connaddr = (struct sockaddr_in *) __addr;
-
-    /* Get the type of the socket */
-    getsockopt(__fd, SOL_SOCKET, SO_TYPE,
-            (void *) &sock_type, &sock_type_len);
-
-    show_msg(MSGDEBUG, "sin_family: %i\n", connaddr->sin_family);
-
-    show_msg(MSGDEBUG, "sockopt: %i \n", sock_type);
-
-    /* If the address is local refuse it. We do this because it could
-       be a TCP DNS request to a local DNS server.*/
-    if (!(is_local(&config, &(connaddr->sin_addr))) &&
-        !is_dead_address(pool, connaddr->sin_addr.s_addr)) {
-        char buf[16];
-        inet_ntop(AF_INET, &(connaddr->sin_addr), buf, sizeof(buf));
-        show_msg(MSGERR, "connect: Connection is to a local address (%s), may be a "
-                         "TCP DNS request to a local DNS server so have to reject to be safe. "
-                         "Please report a bug to http://code.google.com/p/torsocks/issues/entry if "
-                         "this is preventing a program from working properly with torsocks.\n", buf);
-        return -1;
-    }
-
-    /* If this is an INET6, we'll refuse it. */
-    if ((connaddr->sin_family == AF_INET6)) {
-       show_msg(MSGERR, "connect: Connection is IPv6: rejecting.\n");
-       errno = EAFNOSUPPORT;
-       return -1;
-    }
-
-    /* If this isn't an INET socket we can't  */
-    /* handle it, just call the real connect now        */
-    if ((connaddr->sin_family != AF_INET)) {
-        show_msg(MSGDEBUG, "connect: Connection isn't IPv4, ignoring\n");
-        return(original_connect(__fd, __addr, __len));
-    }
-
-    /* If this a UDP socket  */
-    /* then we refuse it, since it is probably a DNS request      */
-    if ((sock_type != SOCK_STREAM)) {
-        show_msg(MSGERR, "connect: Connection is a UDP or ICMP stream, may be a "
-                           "DNS request or other form of leak: rejecting.\n");
-        return -1;
-    }
-
-    /* If we haven't initialized yet, do it now */
-    get_config();
-
-    /* Are we already handling this connect? */
-    if ((newconn = find_socks_request(__fd, 1))) {
-        if (memcmp(&newconn->connaddr, connaddr, sizeof(*connaddr))) {
-            /* Ok, they're calling connect on a socket that is in our
-             * queue but this connect() isn't to the same destination,
-             * they're obviously not trying to check the status of
-             * they're non blocking connect, they must have close()d
-             * the other socket and created a new one which happens
-             * to have the same fd as a request we haven't had the chance
-             * to delete yet, so we delete it here. */
-            show_msg(MSGDEBUG, "Call to connect received on old "
-                                "torsocks request for socket %d but to "
-                                "new destination, deleting old request\n",
-                      newconn->sockid);
-            kill_socks_request(newconn);
-        } else {
-            /* Ok, this call to connect() is to check the status of
-             * a current non blocking connect(). */
-            if (newconn->state == FAILED) {
-                show_msg(MSGDEBUG, "Call to connect received on failed "
-                                  "request %d, returning %d\n",
-                        newconn->sockid, newconn->err);
-                errno = newconn->err;
-                rc = -1;
-            } else if (newconn->state == DONE) {
-                show_msg(MSGERR, "Call to connect received on completed "
-                                "request %d\n",
-                        newconn->sockid, newconn->err);
-                rc = 0;
-            } else {
-                show_msg(MSGDEBUG, "Call to connect received on current request %d\n",
-                        newconn->sockid);
-                rc = handle_request(newconn);
-                errno = rc;
-            }
-            if ((newconn->state == FAILED) || (newconn->state == DONE))
-                kill_socks_request(newconn);
-            return((rc ? -1 : 0));
-        }
-    }
-
-    /* If the socket is already connected, just call connect  */
-    /* and get its standard reply                             */
-    if (!getpeername(__fd, (struct sockaddr *) &peer_address, &namelen)) {
-        show_msg(MSGDEBUG, "Socket is already connected, defering to "
-                          "real connect\n");
-        return(original_connect(__fd, __addr, __len));
-    }
-
-    show_msg(MSGDEBUG, "Got connection request for socket %d to "
-                        "%s\n", __fd, inet_ntoa(connaddr->sin_addr));
-
-    /* Ok, so its not local, we need a path to the net */
-    pick_server(&config, &path, &(connaddr->sin_addr), ntohs(connaddr->sin_port));
-
-    show_msg(MSGDEBUG, "Picked server %s for connection\n",
-              (path->address ? path->address : "(Not Provided)"));
-    if (path->address == NULL) {
-        if (path == &(config.defaultserver))
-            show_msg(MSGERR, "Connection needs to be made "
-                              "via default server but "
-                              "the default server has not "
-                              "been specified\n");
-        else
-            show_msg(MSGERR, "Connection needs to be made "
-                              "via path specified at line "
-                              "%d in configuration file but "
-                              "the server has not been "
-                              "specified for this path\n",
-                              path->lineno);
-    } else if ((res = resolve_ip(path->address, 0, 0)) == -1) {
-        show_msg(MSGERR, "The SOCKS server (%s) listed in the configuration "
-                        "file which needs to be used for this connection "
-                        "is invalid\n", path->address);
-    } else {
-        /* Construct the addr for the socks server */
-        server_address.sin_family = AF_INET; /* host byte order */
-        server_address.sin_addr.s_addr = res;
-        server_address.sin_port = htons(path->port);
-        bzero(&(server_address.sin_zero), 8);
-
-        /* Complain if this server isn't on a localnet */
-        if (is_local(&config, &server_address.sin_addr)) {
-            show_msg(MSGERR, "SOCKS server %s (%s) is not on a local subnet!\n",
-                     path->address, inet_ntoa(server_address.sin_addr));
-        } else
-            gotvalidserver = 1;
-    }
-
-    /* If we haven't found a valid server we return connection refused */
-    if (!gotvalidserver ||
-        !(newconn = new_socks_request(__fd, connaddr, &server_address, path))) {
-        errno = ECONNREFUSED;
-        return(-1);
-    } else {
-        /* Now we call the main function to handle the connect. */
-        rc = handle_request(newconn);
-        /* If the request completed immediately it mustn't have been
-        * a non blocking socket, in this case we don't need to know
-        * about this socket anymore. */
-        if ((newconn->state == FAILED) || (newconn->state == DONE))
-            kill_socks_request(newconn);
-        errno = rc;
-        /* We may get either of these if there are no bytes to read from 
-           the non-blocking connection in handle_request(). Since we are 
-           wrapping connect() here we can't return EWOULDBLOCK/EAGAIN
-           so override it with something the client will accept.*/
-        if (errno == EWOULDBLOCK || errno == EAGAIN)
-            errno = EINPROGRESS;
-        return((rc ? -1 : 0));
-    }
-}
-
-int torsocks_select_guts(SELECT_SIGNATURE, int (*original_select)(SELECT_SIGNATURE))
-{
-    int nevents = 0;
-    int rc = 0;
-    int setevents = 0;
-    int monitoring = 0;
-    struct connreq *conn, *nextconn;
-    fd_set mywritefds, myreadfds, myexceptfds;
-
-    /* If we're not currently managing any requests we can just
-     * leave here */
-    if (!requests) {
-        show_msg(MSGDEBUG, "No requests waiting, calling real select\n");
-        return(original_select(n, readfds, writefds, exceptfds, timeout));
-    }
-
-    show_msg(MSGTEST, "Intercepted call to select\n");
-    show_msg(MSGDEBUG, "Intercepted call to select with %d fds, "
-              "0x%08x 0x%08x 0x%08x, timeout %08x\n", n,
-              readfds, writefds, exceptfds, timeout);
-
-    for (conn = requests; conn != NULL; conn = conn->next) {
-        if ((conn->state == FAILED) || (conn->state == DONE))
-            continue;
-        conn->selectevents = 0;
-        show_msg(MSGDEBUG, "Checking requests for socks enabled socket %d\n",
-                 conn->sockid);
-        conn->selectevents |= (writefds ? (FD_ISSET(conn->sockid, writefds) ? WRITE : 0) : 0);
-        conn->selectevents |= (readfds ? (FD_ISSET(conn->sockid, readfds) ? READ : 0) : 0);
-        conn->selectevents |= (exceptfds ? (FD_ISSET(conn->sockid, exceptfds) ? EXCEPT : 0) : 0);
-        if (conn->selectevents) {
-            show_msg(MSGDEBUG, "Socket %d was set for events\n", conn->sockid);
-            monitoring = 1;
-        }
-    }
-
-    if (!monitoring)
-        return(original_select(n, readfds, writefds, exceptfds, timeout));
-
-    /* This is our select loop. In it we repeatedly call select(). We
-      * pass select the same fdsets as provided by the caller except we
-      * modify the fdsets for the sockets we're managing to get events
-      * we're interested in (while negotiating with the socks server). When
-      * events we're interested in happen we go off and process the result
-      * ourselves, without returning the events to the caller. The loop
-      * ends when an event which isn't one we need to handle occurs or
-      * the select times out */
-    do {
-        /* Copy the clients fd events, we'll change them as we wish */
-        if (readfds)
-            memcpy(&myreadfds, readfds, sizeof(myreadfds));
-        else
-            FD_ZERO(&myreadfds);
-        if (writefds)
-            memcpy(&mywritefds, writefds, sizeof(mywritefds));
-        else
-            FD_ZERO(&mywritefds);
-        if (exceptfds)
-            memcpy(&myexceptfds, exceptfds, sizeof(myexceptfds));
-        else
-            FD_ZERO(&myexceptfds);
-
-        /* Now enable our sockets for the events WE want to hear about */
-        for (conn = requests; conn != NULL; conn = conn->next) {
-            if ((conn->state == FAILED) || (conn->state == DONE) ||
-                (conn->selectevents == 0))
-                continue;
-            /* We always want to know about socket exceptions */
-            FD_SET(conn->sockid, &myexceptfds);
-            /* If we're waiting for a connect or to be able to send
-              * on a socket we want to get write events */
-            if ((conn->state == SENDING) || (conn->state == CONNECTING))
-                FD_SET(conn->sockid,&mywritefds);
-            else
-                FD_CLR(conn->sockid,&mywritefds);
-            /* If we're waiting to receive data we want to get
-              * read events */
-            if (conn->state == RECEIVING)
-                FD_SET(conn->sockid,&myreadfds);
-            else
-                FD_CLR(conn->sockid,&myreadfds);
-        }
-
-        nevents = original_select(n, &myreadfds, &mywritefds, &myexceptfds, timeout);
-        /* If there were no events we must have timed out or had an error */
-        if (nevents <= 0)
-            break;
-
-        /* Loop through all the sockets we're monitoring and see if
-        * any of them have had events */
-        for (conn = requests; conn != NULL; conn = nextconn) {
-            nextconn = conn->next;
-            if ((conn->state == FAILED) || (conn->state == DONE))
-                continue;
-            show_msg(MSGDEBUG, "Checking socket %d for events\n", conn->sockid);
-            /* Clear all the events on the socket (if any), we'll reset
-              * any that are necessary later. */
-            setevents = 0;
-            if (FD_ISSET(conn->sockid, &mywritefds))  {
-                nevents--;
-                setevents |= WRITE;
-                show_msg(MSGDEBUG, "Socket had write event\n");
-                FD_CLR(conn->sockid, &mywritefds);
-            }
-            if (FD_ISSET(conn->sockid, &myreadfds))  {
-                nevents--;
-                setevents |= READ;
-                show_msg(MSGDEBUG, "Socket had write event\n");
-                FD_CLR(conn->sockid, &myreadfds);
-            }
-            if (FD_ISSET(conn->sockid, &myexceptfds))  {
-                nevents--;
-                setevents |= EXCEPT;
-                show_msg(MSGDEBUG, "Socket had except event\n");
-                FD_CLR(conn->sockid, &myexceptfds);
-            }
-
-            if (!setevents) {
-                show_msg(MSGDEBUG, "No events on socket %d\n", conn->sockid);
-                continue;
-            }
-
-            if (setevents & EXCEPT)
-                conn->state = FAILED;
-            else
-                rc = handle_request(conn);
-
-            /* If the connection hasn't failed or completed there is nothing
-              * to report to the client */
-            if ((conn->state != FAILED) &&
-                (conn->state != DONE))
-                continue;
-
-            /* Ok, the connection is completed, for good or for bad. We now
-              * hand back the relevant events to the caller. We don't delete the
-              * connection though since the caller should call connect() to
-              * check the status, we delete it then */
-
-            if (conn->state == FAILED) {
-                /* Damn, the connection failed. Whatever the events the socket
-                * was selected for we flag */
-                if (conn->selectevents & EXCEPT) {
-                    FD_SET(conn->sockid, &myexceptfds);
-                    nevents++;
-                }
-                if (conn->selectevents & READ) {
-                    FD_SET(conn->sockid, &myreadfds);
-                    nevents++;
-                }
-                if (conn->selectevents & WRITE) {
-                    FD_SET(conn->sockid, &mywritefds);
-                    nevents++;
-                }
-                /* We should use setsockopt to set the SO_ERROR errno for this
-                * socket, but this isn't allowed for some silly reason which
-                * leaves us a bit hamstrung.
-                * We don't delete the request so that hopefully we can
-                * return the error on the socket if they call connect() on it */
-            } else {
-                /* The connection is done,  if the client selected for
-                * writing we can go ahead and signal that now (since the socket must
-                * be ready for writing), otherwise we'll just let the select loop
-                * come around again (since we can't flag it for read, we don't know
-                * if there is any data to be read and can't be bothered checking) */
-                if (conn->selectevents & WRITE) {
-                    FD_SET(conn->sockid, &mywritefds);
-                    nevents++;
-                }
-            }
-        }
-    } while (nevents == 0);
-
-    show_msg(MSGDEBUG, "Finished intercepting select(), %d events\n", nevents);
-
-    /* Now copy our event blocks back to the client blocks */
-    if (readfds)
-        memcpy(readfds, &myreadfds, sizeof(myreadfds));
-    if (writefds)
-        memcpy(writefds, &mywritefds, sizeof(mywritefds));
-    if (exceptfds)
-        memcpy(exceptfds, &myexceptfds, sizeof(myexceptfds));
-
-    return(nevents);
-}
-
-int torsocks_poll_guts(POLL_SIGNATURE, int (*original_poll)(POLL_SIGNATURE))
-{
-    int nevents = 0;
-    int rc = 0;
-    unsigned int i;
-    int setevents = 0;
-    int monitoring = 0;
-    struct connreq *conn, *nextconn;
-
-    /* If we're not currently managing any requests we can just
-      * leave here */
-    if (!requests)
-        return(original_poll(ufds, nfds, timeout));
-
-    show_msg(MSGTEST, "Intercepted call to poll\n");
-    show_msg(MSGDEBUG, "Intercepted call to poll with %d fds, "
-              "0x%08x timeout %d\n", nfds, ufds, timeout);
-
-    for (conn = requests; conn != NULL; conn = conn->next)
-        conn->selectevents = 0;
-
-    /* Record what events on our sockets the caller was interested
-      * in */
-    for (i = 0; i < nfds; i++) {
-        if (!(conn = find_socks_request(ufds[i].fd, 0)))
-            continue;
-        show_msg(MSGDEBUG, "Have event checks for socks enabled socket %d\n",
-                conn->sockid);
-        conn->selectevents = ufds[i].events;
-        monitoring = 1;
-    }
-
-    if (!monitoring)
-        return(original_poll(ufds, nfds, timeout));
-
-    /* This is our poll loop. In it we repeatedly call poll(). We
-      * pass select the same event list as provided by the caller except we
-      * modify the events for the sockets we're managing to get events
-      * we're interested in (while negotiating with the socks server). When
-      * events we're interested in happen we go off and process the result
-      * ourselves, without returning the events to the caller. The loop
-      * ends when an event which isn't one we need to handle occurs or
-      * the poll times out */
-    do {
-        /* Enable our sockets for the events WE want to hear about */
-        for (i = 0; i < nfds; i++) {
-            if (!(conn = find_socks_request(ufds[i].fd, 0)))
-                continue;
-
-            /* We always want to know about socket exceptions but they're
-              * always returned (i.e they don't need to be in the list of
-              * wanted events to be returned by the kernel */
-            ufds[i].events = 0;
-
-            /* If we're waiting for a connect or to be able to send
-              * on a socket we want to get write events */
-            if ((conn->state == SENDING) || (conn->state == CONNECTING))
-                ufds[i].events |= POLLOUT;
-            /* If we're waiting to receive data we want to get
-              * read events */
-            if (conn->state == RECEIVING)
-                ufds[i].events |= POLLIN;
-        }
-
-        nevents = original_poll(ufds, nfds, timeout);
-        /* If there were no events we must have timed out or had an error */
-        if (nevents <= 0)
-            break;
-
-        /* Loop through all the sockets we're monitoring and see if
-        * any of them have had events */
-        for (conn = requests; conn != NULL; conn = nextconn) {
-            nextconn = conn->next;
-            if ((conn->state == FAILED) || (conn->state == DONE))
-                continue;
-
-            /* Find the socket in the poll list */
-            for (i = 0; ((i < nfds) && (ufds[i].fd != conn->sockid)); i++)
-                /* Empty Loop */;
-            if (i == nfds)
-                continue;
-
-            show_msg(MSGDEBUG, "Checking socket %d for events\n", conn->sockid);
-
-            if (!ufds[i].revents) {
-                show_msg(MSGDEBUG, "No events on socket\n");
-                continue;
-            }
-
-            /* Clear any read or write events on the socket, we'll reset
-              * any that are necessary later. */
-            setevents = ufds[i].revents;
-            if (setevents & POLLIN) {
-                show_msg(MSGDEBUG, "Socket had read event\n");
-                ufds[i].revents &= ~POLLIN;
-                nevents--;
-            }
-            if (setevents & POLLOUT) {
-                show_msg(MSGDEBUG, "Socket had write event\n");
-                ufds[i].revents &= ~POLLOUT;
-                nevents--;
-            }
-            if (setevents & (POLLERR | POLLNVAL | POLLHUP))
-                show_msg(MSGDEBUG, "Socket had error event\n");
-
-            /* Now handle this event */
-            if (setevents & (POLLERR | POLLNVAL | POLLHUP)) {
-                conn->state = FAILED;
-            } else {
-                rc = handle_request(conn);
-            }
-            /* If the connection hasn't failed or completed there is nothing
-              * to report to the client */
-            if ((conn->state != FAILED) &&
-                (conn->state != DONE))
-                continue;
-
-            /* Ok, the connection is completed, for good or for bad. We now
-             * hand back the relevant events to the caller. We don't delete the
-             * connection though since the caller should call connect() to
-             * check the status, we delete it then */
-
-            if (conn->state == FAILED) {
-                /* Damn, the connection failed. Just copy back the error events
-                 * from the poll call, error events are always valid even if not
-                 * requested by the client */
-                /* We should use setsockopt to set the SO_ERROR errno for this
-                 * socket, but this isn't allowed for some silly reason which
-                 * leaves us a bit hamstrung.
-                 * We don't delete the request so that hopefully we can
-                 * return the error on the socket if they call connect() on it */
-            } else {
-                /* The connection is done,  if the client polled for
-                 * writing we can go ahead and signal that now (since the socket must
-                 * be ready for writing), otherwise we'll just let the select loop
-                 * come around again (since we can't flag it for read, we don't know
-                 * if there is any data to be read and can't be bothered checking) */
-                if (conn->selectevents & POLLOUT) {
-                  setevents |= POLLOUT;
-                  nevents++;
-                }
-            }
-        }
-    } while (nevents == 0);
-
-    show_msg(MSGDEBUG, "Finished intercepting poll(), %d events\n", nevents);
-
-    /* Now restore the events polled in each of the blocks */
-    for (i = 0; i < nfds; i++) {
-        if (!(conn = find_socks_request(ufds[i].fd, 1)))
-            continue;
-        ufds[i].events = conn->selectevents;
-    }
-
-    return(nevents);
-}
-
-int torsocks_close_guts(CLOSE_SIGNATURE, int (*original_close)(CLOSE_SIGNATURE))
-{
-    int rc;
-    struct connreq *conn;
-
-    /* If we're not currently managing any requests we can just
-      * leave here */
-    if (!requests) {
-        show_msg(MSGDEBUG, "No requests waiting, calling real close\n");
-        return(original_close(fd));
-    }
-
-    if (original_close == NULL) {
-        show_msg(MSGERR, "Unresolved symbol: close\n");
-        return(-1);
-    }
-
-    show_msg(MSGTEST, "Got call to close()\n");
-    show_msg(MSGDEBUG, "Call to close(%d)\n", fd);
-
-    rc = original_close(fd);
-
-    /* If we have this fd in our request handling list we
-    * remove it now */
-    if ((conn = find_socks_request(fd, 1))) {
-        show_msg(MSGDEBUG, "Call to close() received on file descriptor "
-                            "%d which is a connection request of status %d\n",
-                 conn->sockid, conn->state);
-        kill_socks_request(conn);
-    }
-
-    return(rc);
-}
-
-/* If we are not done setting up the connection yet, return
- * -1 and ENOTCONN, otherwise call getpeername
- *
- * This is necessary since some applications, when using non-blocking connect,
- * (like ircII) use getpeername() to find out if they are connected already.
- *
- * This results in races sometimes, where the client sends data to the socket
- * before we are done with the socks connection setup.  Another solution would
- * be to intercept send().
- * 
- * This could be extended to actually set the peername to the peer the
- * client application has requested, but not for now.
- *
- * PP, Sat, 27 Mar 2004 11:30:23 +0100
- */
-
-int torsocks_getpeername_guts(GETPEERNAME_SIGNATURE,
-                            int (*original_getpeername)(GETPEERNAME_SIGNATURE))
-{
-    struct connreq *conn;
-    int rc;
-
-    if (original_getpeername == NULL) {
-        show_msg(MSGERR, "Unresolved symbol: getpeername\n");
-        return(-1);
-    }
-
-    show_msg(MSGTEST, "Intercepted call to getpeername\n");
-    show_msg(MSGDEBUG, "Call to getpeername for fd %d\n", __fd);
-
-
-    rc = original_getpeername(__fd, __name, __namelen);
-    if (rc == -1)
-        return rc;
-
-    /* Are we handling this connect? */
-    if ((conn = find_socks_request(__fd, 1))) {
-        /* While we are at it, we might was well try to do something useful */
-        handle_request(conn);
-
-        if (conn->state != DONE) {
-            errno = ENOTCONN;
-            return(-1);
-        }
-    }
-    return rc;
-}
-
-#ifdef SUPPORT_RES_API
-int res_init(void)
-{
-    int rc;
-
-    if (!realres_init) {
-      torsocks_find_library("res_init", MSGERR, realres_init);
-    }
-
-    show_msg(MSGTEST, "Got res_init request\n");
-
-    if (realres_init == NULL) {
-        show_msg(MSGERR, "Unresolved symbol: res_init\n");
-        return(-1);
-    }
-    /* Call normal res_init */
-    rc = realres_init();
-
-    /* Force using TCP protocol for DNS queries */
-    _res.options |= RES_USEVC;
-    return(rc);
-}
-
-int EXPAND_GUTS_NAME(res_query)(RES_QUERY_SIGNATURE, int (*original_res_query)(RES_QUERY_SIGNATURE))
-{
-    int rc;
-
-    if (!original_res_query) {
-      torsocks_find_library("res_query", MSGERR, original_res_query);
-    }
-
-    show_msg(MSGTEST, "Got res_query request\n");
-
-    if (original_res_query == NULL) {
-        show_msg(MSGERR, "Unresolved symbol: res_query\n");
-        return(-1);
-    }
-
-    /* Ensure we force using TCP for DNS queries by calling res_init
-       above if it has not already been called.*/
-    if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
-        res_init();
-
-    /* Call normal res_query */
-    rc = original_res_query(dname, class, type, answer, anslen);
-
-    return(rc);
-}
-
-int EXPAND_GUTS_NAME(res_querydomain)(RES_QUERYDOMAIN_SIGNATURE, int (*original_res_querydomain)(RES_QUERYDOMAIN_SIGNATURE))
-{
-    int rc;
-
-    if (!original_res_querydomain) {
-      torsocks_find_library("res_querydomain", MSGERR, original_res_querydomain);
-    }
-
-    show_msg(MSGDEBUG, "Got res_querydomain request\n");
-
-    if (original_res_querydomain == NULL) {
-        show_msg(MSGERR, "Unresolved symbol: res_querydomain\n");
-        return(-1);
-    }
-
-    /* Ensure we force using TCP for DNS queries by calling res_init
-       above if it has not already been called.*/
-    if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
-        res_init();
-
-    /* Call normal res_querydomain */
-    rc = original_res_querydomain(name, domain, class, type, answer, anslen);
-
-    return(rc);
-}
-
-int EXPAND_GUTS_NAME(res_search)(RES_SEARCH_SIGNATURE, int (*original_res_search)(RES_SEARCH_SIGNATURE))
-{
-    int rc;
-
-    if (!original_res_search) {
-      torsocks_find_library("res_search", MSGERR, original_res_search);
-    }
-
-    show_msg(MSGTEST, "Got res_search request\n");
-
-    if (original_res_search == NULL) {
-        show_msg(MSGERR, "Unresolved symbol: res_search\n");
-        return(-1);
-    }
-
-    /* Ensure we force using TCP for DNS queries by calling res_init
-       above if it has not already been called.*/
-    if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
-        res_init();
-
-    /* Call normal res_search */
-    rc = original_res_search(dname, class, type, answer, anslen);
-
-    return(rc);
-}
-
-int EXPAND_GUTS_NAME(res_send)(RES_SEND_SIGNATURE, int (*original_res_send)(RES_SEND_SIGNATURE))
-{
-    int rc;
-
-    if (!original_res_send) {
-      torsocks_find_library("res_send", MSGERR, original_res_send);
-    }
-
-    show_msg(MSGTEST, "Got res_send request\n");
-
-    if (original_res_send == NULL) {
-        show_msg(MSGERR, "Unresolved symbol: res_send\n");
-        return(-1);
-    }
-
-    /* Ensure we force using TCP for DNS queries by calling res_init
-       above if it has not already been called.*/
-    if (!(_res.options & RES_INIT) || !(_res.options & RES_USEVC))
-        res_init();
-
-    /* Call normal res_send */
-    rc = original_res_send(msg, msglen, answer, anslen);
-
-    return(rc);
-}
-#endif
-
-static int deadpool_init(void)
-{
-    if (pool)
-        return 1;
-
-    if (!config.tordns_enabled) {
-        show_msg(MSGERR, "Tor DNS is disabled. Check your configuration.\n");
-        return 0;
-    }
-
-    get_environment();
-    get_config();
-    pool = init_pool(config.tordns_cache_size,
-                     config.tordns_deadpool_range->localip,
-                     config.tordns_deadpool_range->localnet,
-                     config.defaultserver.address,
-                     config.defaultserver.port);
-
-    if (!pool) {
-        show_msg(MSGERR, "Could not initialize reserved addresses for "
-                         ".onion addresses. Torsocks will not work properly.\n");
-        return 0;
-    }
-    return 1;
-}
-
-struct hostent *torsocks_gethostbyname_guts(GETHOSTBYNAME_SIGNATURE, struct hostent *(*original_gethostbyname)(GETHOSTBYNAME_SIGNATURE))
-{
-    if (pool)
-        return our_gethostbyname(pool, name);
-    return original_gethostbyname(name);
-}
-
-struct hostent *torsocks_gethostbyaddr_guts(GETHOSTBYADDR_SIGNATURE, struct hostent *(*original_gethostbyaddr)(GETHOSTBYADDR_SIGNATURE))
-{
-    if (pool)
-        return our_gethostbyaddr(pool, addr, len, type);
-    return original_gethostbyaddr(addr, len, type);
-}
-
-int torsocks_getaddrinfo_guts(GETADDRINFO_SIGNATURE, int (*original_getaddrinfo)(GETADDRINFO_SIGNATURE))
-{
-    if (pool)
-        return our_getaddrinfo(pool, node, service, hints, res);
-    return original_getaddrinfo(node, service, hints, res);
-}
-
-struct hostent *torsocks_getipnodebyname_guts(GETIPNODEBYNAME_SIGNATURE, struct hostent *(*original_getipnodebyname)(GETIPNODEBYNAME_SIGNATURE))
-{
-    if (pool)
-        return our_getipnodebyname(pool, name, af, flags, error_num);
-    return original_getipnodebyname(name, af, flags, error_num);
-}
-
-ssize_t torsocks_sendto_guts(SENDTO_SIGNATURE, ssize_t (*original_sendto)(SENDTO_SIGNATURE))
-{
-    int sock_type = -1;
-    unsigned int sock_type_len = sizeof(sock_type);
-    struct sockaddr_in *connaddr;
-
-    /* If the real sendto doesn't exist, we're stuffed */
-    if (original_sendto == NULL) {
-        show_msg(MSGERR, "Unresolved symbol: sendto\n");
-        return(-1);
-    }
-
-    show_msg(MSGTEST, "Got sendto request\n");
-
-    /* Get the type of the socket */
-    getsockopt(s, SOL_SOCKET, SO_TYPE,
-               (void *) &sock_type, &sock_type_len);
-
-    show_msg(MSGDEBUG, "sockopt: %i\n",  sock_type);
-
-    /* If this a UDP socket then we refuse it, since it is probably a DNS
-       request */
-    if ((sock_type != SOCK_STREAM)) {
-        show_msg(MSGERR, "sendto: Connection is a UDP or ICMP stream, may be a "
-                           "DNS request or other form of leak: rejecting.\n");
-        return -1;
-    }
-
-    connaddr = (struct sockaddr_in *) to;
-
-    /* If there is no address in 'to', sendto will only work if we
-       already allowed the socket to connect(), so we let it through.
-       Likewise if the socket is not an Internet connection. */
-    if (connaddr && (connaddr->sin_family != AF_INET)) {
-        show_msg(MSGDEBUG, "Connection isn't an Internet socket ignoring\n");
-    }
-
-    return (ssize_t) original_sendto(s, buf, len, flags, to, tolen);
-}
-
-ssize_t torsocks_sendmsg_guts(SENDMSG_SIGNATURE, ssize_t (*original_sendmsg)(SENDMSG_SIGNATURE))
-{
-    int sock_type = -1;
-    unsigned int sock_type_len = sizeof(sock_type);
-    struct sockaddr_in *connaddr;
-
-    /* If the real sendmsg doesn't exist, we're stuffed */
-    if (original_sendmsg == NULL) {
-        show_msg(MSGERR, "Unresolved symbol: sendmsg\n");
-        return(-1);
-    }
-
-    show_msg(MSGTEST, "Got sendmsg request\n");
-
-    /* Get the type of the socket */
-    getsockopt(s, SOL_SOCKET, SO_TYPE,
-               (void *) &sock_type, &sock_type_len);
-
-    show_msg(MSGDEBUG, "sockopt: %i\n",  sock_type);
-
-    if ((sock_type != SOCK_STREAM)) {
-        show_msg(MSGERR, "sendmsg: Connection is a UDP or ICMP stream, may be a "
-                          "DNS request or other form of leak: rejecting.\n");
-        return -1;
-    }
-
-    connaddr = (struct sockaddr_in *) msg->msg_name;
-
-    /* If there is no address in msg_name, sendmsg will only work if we
-       already allowed the socket to connect(), so we let it through.
-       Likewise if the socket is not an Internet connection. */
-    if (connaddr && (connaddr->sin_family != AF_INET)) {
-        show_msg(MSGDEBUG, "Connection isn't an Internet socket\n");
-    }
-
-    return (ssize_t) original_sendmsg(s, msg, flags);
-}
-
diff --git a/src/torsocks.in b/src/torsocks.in
deleted file mode 100755
index 4eaed8f..0000000
--- a/src/torsocks.in
+++ /dev/null
@@ -1,167 +0,0 @@
-#!/bin/sh
-# ***************************************************************************
-# *                                                                         *
-# *                                                                         *
-# *   Copyright (C) 2008 by Robert Hogan                                    *
-# *   robert at roberthogan.net                                                *
-# *   Copyright (C) 2012 by Jacob Appelbaum <jacob at torproject.org>          *
-# *                                                                         *
-# *   This program is free software; you can redistribute it and/or modify  *
-# *   it under the terms of the GNU General Public License as published by  *
-# *   the Free Software Foundation; either version 2 of the License, or     *
-# *   (at your option) any later version.                                   *
-# *                                                                         *
-# *   This program is distributed in the hope that it will be useful,       *
-# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-# *   GNU General Public License for more details.                          *
-# *                                                                         *
-# *   You should have received a copy of the GNU General Public License     *
-# *   along with this program; if not, write to the                         *
-# *   Free Software Foundation, Inc.,                                       *
-#*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-# ***************************************************************************
-# *                                                                         *
-# *   This is a modified version of a source file from the Tor project.     *
-# *   Original copyright information follows:                               *
-# ***************************************************************************
-# Wrapper script for use of the torsocks(8) transparent socksification library
-#
-# There are three forms of usage for this script:
-#
-# @prefix@/bin/torsocks program [program arguments...]
-#
-# This form sets the users @LDPRELOAD@ environment variable so that torsocks(8)
-# will be loaded to socksify the application then executes the specified 
-# program (with the provided arguments). The following simple example might 
-# be used to telnet to www.foo.org via a torsocks.conf(5) configured socks server:
-#
-# @prefix@/bin/torsocks telnet www.foo.org
-#
-# The second form allows for torsocks(8) to be switched on and off for a
-# session (that is, it adds and removes torsocks from the @LDPRELOAD@ environment
-# variable). This form must be _sourced_ into the user's existing session
-# (and will only work with bourne shell users):
-#
-# . @prefix@/bin/torsocks on
-# telnet www.foo.org 
-# . @prefix@/bin/torsocks off
-# 
-# Or
-# 
-# source @prefix@/bin/torsocks on
-# telnet www.foo.org
-# source @prefix@/bin/torsocks off
-#
-# The third form creates a new shell with @LDPRELOAD@ set and is achieved
-# simply by running the script with no arguments 
-# 
-# @prefix@/bin/torsocks
-#
-# When finished the user can simply terminate the shell with 'exit'
-# 
-# This script is originally from the debian torsocks package by
-# Tamas Szerb <toma at rulez.org>
-# Modified by Robert Hogan <robert at roberthogan.net> April 16th 2006
-
-not_found () {
-    echo "ERROR: $1 cannot be found in PATH." >&2
-    exit 1
-}
-
-set_id () {
-    echo "ERROR: $1 is set${2}id. torsocks will not work on a set${2}id executable." >&2
-    exit 1
-}
-
-if [ $# = 0 ] ; then
-   echo "$0: insufficient arguments"
-   exit
-fi
-
-LIBDIR="@prefix@/lib/torsocks"
-LIB_NAME="libtorsocks"
-SHLIB_EXT="@SHLIB_EXT@"
-SHLIB="${LIBDIR}/${LIB_NAME}.${SHLIB_EXT}"
-
-# Check for libtorsocks and if set the 64bit variant
-if [ ! -f $SHLIB ]; then
-   LIBDIR="@prefix@/lib64/torsocks"
-   SHLIB="${LIBDIR}/${LIB_NAME}.${SHLIB_EXT}"
-fi
-
-# Ensure libtorsocks exists,
-if [ ! -f $SHLIB ]; then
-   echo "$0: $SHLIB does not exist! Try re-installing torsocks."
-   exit
-fi
-
-case "$1" in
-  on)
-    if [ -z "$@LDPRELOAD@" ]
-      then
-        export @LDPRELOAD@="${SHLIB}"
-      else
-        echo $@LDPRELOAD@ | grep -q "${SHLIB}" || \
-        export @LDPRELOAD@="${SHLIB} $@LDPRELOAD@"
-    fi
-    # FIXME: This env variable is only meaningful on Mac OSX, so it would be better
-    #        not to set it at all on other platforms.
-    export DYLD_FORCE_FLAT_NAMESPACE=1
-  ;;
-  off)
-    #replace '/' with '\/' in @prefix@
-    # escprefix=`echo '@prefix@' |sed 's/\\//\\\\\//g'`
-    # export @LDPRELOAD@=`echo -n $@LDPRELOAD@ | sed "s/$escprefix\/lib\/torsocks\/libtorsocks.so \?//"`
-    export @LDPRELOAD@=`echo -n $@LDPRELOAD@ | sed "s#@prefix@/lib/torsocks/libtorsocks\. at SHLIB_EXT@ *##"`
-    if [ -z "$@LDPRELOAD@" ]
-      then
-        unset @LDPRELOAD@
-        # FIXME: This env variable is only meaningful on Mac OSX, so it would be better
-        #        not to set it at all on other platforms.
-        unset DYLD_FORCE_FLAT_NAMESPACE=1
-    fi
-  ;;
-  show|sh)
-    echo "@LDPRELOAD@=\"$@LDPRELOAD@\""
-  ;;
-  -h|-?)
-      echo "$0: Please see torsocks(1) or read comment at top of $0"
-   ;;
-  --shell)
-    if [ -z "$@LDPRELOAD@" ]
-    then
-      export @LDPRELOAD@="${SHLIB}"
-    else
-      echo $@LDPRELOAD@ | grep -q "${SHLIB}" || \
-      export @LDPRELOAD@="${SHLIB} $@LDPRELOAD@"
-    fi
-    export DYLD_FORCE_FLAT_NAMESPACE=1
-    echo "torsocks: new torified shell coming right up..."
-    ${SHELL:-/bin/sh}
-  ;;
-  *)
-    if [ -z "$@LDPRELOAD@" ]
-    then
-      export @LDPRELOAD@="${SHLIB}"
-    else
-      echo $@LDPRELOAD@ | grep -q "${SHLIB}" || \
-      export @LDPRELOAD@="${SHLIB} $@LDPRELOAD@"
-    fi
-    export DYLD_FORCE_FLAT_NAMESPACE=1
-
-    if [ $# -gt 0 ]
-    then
-      if ! which "$1" >/dev/null 2>&1; then
-          not_found $1
-      elif [ -u `which "$1"` ]; then
-          set_id $1 u
-      elif [ -g `which "$1"` ]; then
-          set_id $1 g
-      fi
-      exec "$@"
-    fi
-  ;;
-esac
-
-#EOF
diff --git a/src/usewithtor.in b/src/usewithtor.in
deleted file mode 100644
index e606760..0000000
--- a/src/usewithtor.in
+++ /dev/null
@@ -1,113 +0,0 @@
-#! /bin/sh
-# ***************************************************************************
-# *                                                                         *
-# *   Copyright (C) 2008-2011 Robert Hogan <robert at roberthogan.net>         *
-# *                                                                         *
-# *   This program is free software; you can redistribute it and/or modify  *
-# *   it under the terms of the GNU General Public License as published by  *
-# *   the Free Software Foundation; either version 2 of the License, or     *
-# *   (at your option) any later version.                                   *
-# *                                                                         *
-# *   This program is distributed in the hope that it will be useful,       *
-# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
-# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
-# *   GNU General Public License for more details.                          *
-# *                                                                         *
-# *   You should have received a copy of the GNU General Public License     *
-# *   along with this program; if not, write to the                         *
-# *   Free Software Foundation, Inc.,                                       *
-#*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-# ***************************************************************************
-# *                                                                         *
-# *   This is a modified version of a source file from the Tor project.     *
-# *   Original copyright notice from tsocks source file follows:            *
-# ***************************************************************************
-
-# Wrapper script for use of the tsocks(8) transparent socksification library
-# See the tsocks(1) and torify(1) manpages.
-
-# Copyright (c) 2004, 2006 Peter Palfrader
-# Modified by Jacob Appelbaum <jacob at appelbaum.net> April 16th 2006
-# Modified by Marcus Griep <marcus at griep.us> June 16 2009
-# May be distributed under the same terms as Tor itself
-
-
-# Define and ensure we have tsocks
-# XXX: what if we don't have which?
-TORSOCKS="`which torsocks`"
-PROG=
-VERBOSE=
-
-usage () {
-	echo "Usage: $0 [-hv] <command> [<options>...]"
-}
-
-not_found () {
-	echo "ERROR: $1 cannot be found in PATH." >&2
-	exit 1
-}
-
-set_id () {
-	echo "ERROR: $1 is set${2}id. usewithtor will not work on a set${2}id executable." >&2
-	exit 1
-}
-
-# Check for any argument list
-if [ "$#" = 0 ]; then
-	usage >&2
-	exit 1
-fi
-
-while [ "$1" ]; do
-	case "$1" in
-		-h|--h*)
-			usage
-			exit 0
-			;;
-		-v|--v*)
-			VERBOSE=YesPlease
-			shift
-			;;
-		*)
-			break;
-	esac
-done
-
-if ! which "$1" >/dev/null 2>&1; then
-	not_found $1
-elif [ -u `which "$1"` ]; then
-	set_id $1 u
-elif [ -g `which "$1"` ]; then
-	set_id $1 g
-fi
-
-if [ -x "$TORSOCKS" ]; then
-	PROG=torsocks
-else
-	echo "$0: Unable to find torsocks in PATH." >&2
-	echo "    Perhaps you haven't installed it?" >&2
-	exit 1
-fi
-
-if [ "$VERBOSE" ]; then
-	echo "We're armed with the following torsocks: $TORSOCKS"
-	echo "We're attempting to use $PROG for all tor action."
-fi
-
-if [ "$PROG" = "torsocks" ]; then
-	# Define our torsocks config file
-	TORSOCKS_CONF_FILE="@CONFDIR@/torsocks.conf"
-	export TORSOCKS_CONF_FILE
-
-	# Check that we've got a torsocks config file
-	if [ -r "$TORSOCKS_CONF_FILE" ]; 	then
-		exec torsocks "$@"
-	else
-		echo "$0: Missing torsocks configuration file \"$TORSOCKS_CONF_FILE\" - torsocks will use defaults sensible for Tor." >&2
-		exec torsocks "$@"
-	fi
-fi
-
-# We should have hit an exec. If we get here, we didn't exec
-echo "$0: failed to exec $PROG $@" >&2
-exit 1






More information about the tor-commits mailing list