[OE-core] [PATCH 9/9] oe-git-proxy*: Remove previous git proxy solutions

Darren Hart dvhart at linux.intel.com
Tue Feb 5 22:52:51 UTC 2013


The new oe-git-proxy.sh should address all git proxying needs, remove
the previous scripts.

V2: Separate the removal of the old scripts into their own patch

Signed-off-by: Darren Hart <dvhart at linux.intel.com>
---
 scripts/oe-git-proxy-command       |   10 -
 scripts/oe-git-proxy-socks-command |   23 -
 scripts/oe-git-proxy-socks.c       | 2982 ------------------------------------
 3 files changed, 0 insertions(+), 3015 deletions(-)
 delete mode 100755 scripts/oe-git-proxy-command
 delete mode 100755 scripts/oe-git-proxy-socks-command
 delete mode 100755 scripts/oe-git-proxy-socks.c

diff --git a/scripts/oe-git-proxy-command b/scripts/oe-git-proxy-command
deleted file mode 100755
index d31f85a..0000000
--- a/scripts/oe-git-proxy-command
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /bin/bash
-
-(echo "CONNECT $1:$2 HTTP/1.0"; 
- echo; 
- cat ) | nc $GIT_PROXY_HOST $GIT_PROXY_PORT | 
-  
-(read a; 
- read a; 
- read a; 
- cat )
\ No newline at end of file
diff --git a/scripts/oe-git-proxy-socks-command b/scripts/oe-git-proxy-socks-command
deleted file mode 100755
index 8acffb5..0000000
--- a/scripts/oe-git-proxy-socks-command
+++ /dev/null
@@ -1,23 +0,0 @@
-#! /bin/bash
-SCRIPTDIR=`dirname $0`
-# Check oe-git-proxy-socks exists
-PROXYSOCKS=`which oe-git-proxy-socks 2> /dev/null`
-if [ -z "$PROXYSOCKS" -a -e "$SCRIPTDIR/oe-git-proxy-socks.c" ]; then
-	# If not try and build it
-	gcc $SCRIPTDIR/oe-git-proxy-socks.c -o $SCRIPTDIR/oe-git-proxy-socks
-fi
-PROXYSOCKS=`which oe-git-proxy-socks 2> /dev/null`
-if [ ! -x "$PROXYSOCKS" ]; then
-	# If that fails, we can see if netcat (nc) is available
-	NETCAT=`which nc 2> /dev/null`
-	if [ ! -x "$NETCAT" ]; then
-		# If that fails, explain to the user
-		echo "Unable to find oe-git-proxy-socks. This is usually created with the command"
-		echo "'gcc scripts/oe-git-proxy-socks.c -o scripts/oe-git-proxy-socks' which we tried"
-		echo "but it doesn't seem to have worked. Please compile the binary manually."
-		echo "Alternativly, install nc (netcat) on this machine."
-		exit 1
-	fi
-	exec $NETCAT -x $GIT_PROXY_HOST:$GIT_PROXY_PORT "$@"
-fi
-oe-git-proxy-socks -S $GIT_PROXY_HOST:$GIT_PROXY_PORT $@
diff --git a/scripts/oe-git-proxy-socks.c b/scripts/oe-git-proxy-socks.c
deleted file mode 100755
index f574711..0000000
--- a/scripts/oe-git-proxy-socks.c
+++ /dev/null
@@ -1,2982 +0,0 @@
-/***********************************************************************
- * connect.c -- Make socket connection using SOCKS4/5 and HTTP tunnel.
- *
- * Copyright (c) 2000-2006 Shun-ichi Goto
- * Copyright (c) 2002, J. Grant (English Corrections)
- *
- * 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.
- *
- * ---------------------------------------------------------
- * PROJECT:  My Test Program
- * AUTHOR:   Shun-ichi GOTO <gotoh at taiyo.co.jp>
- * CREATE:   Wed Jun 21, 2000
- * REVISION: $Revision: 100 $
- * ---------------------------------------------------------
- *
- * Getting Source
- * ==============
- *
- *   Recent version of 'connect.c' is available from
- *     http://www.taiyo.co.jp/~gotoh/ssh/connect.c
- *
- *   Related tool, ssh-askpass.exe (alternative ssh-askpass on UNIX)
- *   is available:
- *     http://www.taiyo.co.jp/~gotoh/ssh/ssh-askpass.exe.gz
- *
- *   See more detail:
- *     http://www.taiyo.co.jp/~gotoh/ssh/connect.html
- *
- * How To Compile
- * ==============
- *
- *  On UNIX environment:
- *      $ gcc connect.c -o connect
- *
- *  On SOLARIS:
- *      $ gcc -o connect -lresolv -lsocket -lnsl connect.c
- *
- *  on Win32 environment:
- *      $ cl connect.c wsock32.lib advapi32.lib
- *    or
- *      $ bcc32 connect.c wsock32.lib advapi32.lib
- *    or
- *      $ gcc connect.c -o connect
- *
- *  on Mac OS X environment:
- *      $ gcc connect.c -o connect -lresolv
- *    or
- *      $ gcc connect.c -o connect -DBIND_8_COMPAT=1
- *
- * How To Use
- * ==========
- *
- *   You can specify proxy method in an environment variable or in a
- *   command line option.
- *
- *   usage:  connect [-dnhst45] [-R resolve] [-p local-port] [-w sec]
- *                   [-H [user@]proxy-server[:port]]
- *                   [-S [user@]socks-server[:port]]
- *                   [-T proxy-server[:port]]
- *                   [-c telnet proxy command]
- *                   host port
- *
- *   "host" and "port" is for the target hostname and port-number to
- *   connect to.
- *
- *   The -H option specifys a hostname and port number of the http proxy
- *   server to relay. If port is omitted, 80 is used. You can specify this
- *   value in the environment variable HTTP_PROXY and pass the -h option
- *   to use it.
- *
- *   The -S option specifys the hostname and port number of the SOCKS
- *   server to relay.  Like -H, port number can be omitted and the default
- *   is 1080. You can also specify this value pair in the environment
- *   variable SOCKS5_SERVER and give the -s option to use it.
- *
- *   The '-4' and the '-5' options are for specifying SOCKS relaying and
- *   indicates protocol version to use. It is valid only when used with
- *   '-s' or '-S'. Default is '-5' (protocol version 5)
- *
- *   The '-R' option is for specifying method to resolve the
- *   hostname. Three keywords ("local", "remote", "both") or dot-notation
- *   IP address are acceptable.  The keyword "both" means, "Try local
- *   first, then remote". If a dot-notation IP address is specified, use
- *   this host as nameserver. The default is "remote" for SOCKS5 or
- *   "local" for others. On SOCKS4 protocol, remote resolving method
- *   ("remote" and "both") requires protocol 4a supported server.
- *
- *   The '-p' option will forward a local TCP port instead of using the
- *   standard input and output.
- *
- *   The '-P' option is same to '-p' except keep remote session. The
- *   program repeats waiting the port with holding remote session without
- *   disconnecting. To disconnect the remote session, send EOF to stdin or
- *   kill the program.
- *
- *   The '-w' option specifys timeout seconds for making connection with
- *   TARGET host.
- *
- *   The '-d' option is used for debug. If you fail to connect, use this
- *   and check request to and response from server.
- *
- *   You can omit the "port" argument when program name is special format
- *   containing port number itself. For example,
- *     $ ln -s connect connect-25
- *   means this connect-25 command is spcifying port number 25 already
- *   so you need not 2nd argument (and ignored if specified).
- *
- *   To use proxy, this example is for SOCKS5 connection to connect to
- *   'host' at port 25 via SOCKS5 server on 'firewall' host.
- *     $ connect -S firewall  host 25
- *   or
- *     $ SOCKS5_SERVER=firewall; export SOCKS5_SERVER
- *     $ connect -s host 25
- *
- *   For a HTTP-PROXY connection:
- *     $ connect -H proxy-server:8080  host 25
- *   or
- *     $ HTTP_PROXY=proxy-server:8080; export HTTP_PROXY
- *     $ connect -h host 25
- *   To forward a local port, for example to use ssh:
- *     $ connect -p 5550 -H proxy-server:8080  host 22
- *    ($ ssh -l user -p 5550 localhost )
- *
- * TIPS
- * ====
- *
- *   Connect.c doesn't have any configuration to specify the SOCKS server.
- *   If you are a mobile user, this limitation might bother you.  However,
- *   You can compile connect.c and link with other standard SOCKS library
- *   like the NEC SOCKS5 library or Dante. This means connect.c is
- *   socksified and uses a configration file like to other SOCKSified
- *   network commands and you can switch configuration file any time
- *   (ex. when ppp startup) that brings you switching of SOCKS server for
- *   connect.c in same way with other commands. For this case, you can
- *   write ~/.ssh/config like this:
- *
- *     ProxyCommand connect -n %h %p
- *
- * SOCKS5 authentication
- * =====================
- *
- *   Only USER/PASS authentication is supported.
- *
- * Proxy authentication
- * ====================
- *
- *   Only BASIC scheme is supported.
- *
- * Authentication informations
- * ===========================
- *
- *   User name for authentication is specifed by an environment variable
- *   or system login name.  And password is specified from environment
- *   variable or external program (specified in $SSH_ASKPASS) or tty.
- *
- *   Following environment variable is used for specifying user name.
- *     SOCKS: $SOCKS5_USER, $LOGNAME, $USER
- *     HTTP Proxy: $HTTP_PROXY_USER, $LOGNAME, $USER
- *
- * ssh-askpass support
- * ===================
-  *
- *   You can use ssh-askpass (came from OpenSSH or else) to specify
- *   password on graphical environment (X-Window or MS Windows). To use
- *   this, set program name to environment variable SSH_ASKPASS. On UNIX,
- *   X-Window must be required, so $DISPLAY environment variable is also
- *   needed.  On Win32 environment, $DISPLAY is not mentioned.
- *
- * Related Informations
- * ====================
- *
- *   SOCKS5 -- RFC 1928, RFC 1929, RFC 1961
- *             NEC SOCKS Reference Implementation is available from:
- *               http://www.socks.nec.com
- *             DeleGate version 5 or earlier can be SOCKS4 server,
- *             and version 6 can be SOCKS5 and SOCKS4 server.
- *             and version 7.7.0 or later can be SOCKS5 and SOCKS4a server.
- *               http://www.delegate.org/delegate/
- *
- *   HTTP-Proxy --
- *             Many http proxy servers supports this, but https should
- *             be allowed as configuration on your host.
- *             For example on DeleGate, you should add "https" to the
- *             "REMITTABLE" parameter to allow HTTP-Proxy like this:
- *               delegated -Pxxxx ...... REMITTABLE="+,https" ...
- *
- *  Hypertext Transfer Protocol -- HTTP/1.1  -- RFC 2616
- *  HTTP Authentication: Basic and Digest Access Authentication -- RFC 2617
- *             For proxy authentication, refer these documents.
- *
- ***********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#ifdef __CYGWIN32__
-#undef _WIN32
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#include <winsock.h>
-#include <sys/stat.h>
-#include <io.h>
-#include <conio.h>
-#else /* !_WIN32 */
-#include <unistd.h>
-#include <pwd.h>
-#include <termios.h>
-#include <sys/time.h>
-#ifndef __hpux
-#include <sys/select.h>
-#endif /* __hpux */
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#if !defined(_WIN32) && !defined(__CYGWIN32__)
-#define WITH_RESOLVER 1
-#include <arpa/nameser.h>
-#include <resolv.h>
-#else  /* not ( not _WIN32 && not __CYGWIN32__) */
-#undef WITH_RESOLVER
-#endif /* not ( not _WIN32 && not __CYGWIN32__) */
-#endif /* !_WIN32 */
-
-#ifdef _WIN32
-#define ECONNRESET WSAECONNRESET
-#endif /* _WI32 */
-
-
-
-#ifndef LINT
-static char *vcid = "$Id: connect.c 100 2007-07-03 10:48:26Z gotoh $";
-#endif
-
-/* Microsoft Visual C/C++ has _snprintf() and _vsnprintf() */
-#ifdef _MSC_VER
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#endif
-
-/* consider Borland C */
-#ifdef __BORLANDC__
-#define _kbhit kbhit
-#define _setmode setmode
-#endif
-
-/* help message.
-   Win32 environment does not support -R option (vc and cygwin)
-   Win32 native compilers does not support -w option, yet (vc)
-*/
-static char *usage = "usage: %s [-dnhst45] [-p local-port]"
-#ifdef _WIN32
-#ifdef __CYGWIN32__
-"[-w timeout] \n"                               /* cygwin cannot -R */
-#else  /* not __CYGWIN32__ */
-" \n"                                           /* VC cannot -w nor -R  */
-#endif /* not __CYGWIN32__ */
-#else  /* not _WIN32 */
-/* help message for UNIX */
-"[-R resolve] [-w timeout] \n"
-#endif /* not _WIN32 */
-"          [-H proxy-server[:port]] [-S [user@]socks-server[:port]] \n"
-"          [-T proxy-server[:port]]\n"
-"          [-c telnet-proxy-command]\n"
-"          host port\n";
-
-/* name of this program */
-char *progname = NULL;
-char *progdesc = "connect --- simple relaying command via proxy.";
-char *rcs_revstr = "$Revision: 100 $";
-char *revstr = NULL;
-int major_version = 1;
-int minor_version = 0;
-
-/* set of character for strspn() */
-const char *digits    = "0123456789";
-const char *dotdigits = "0123456789.";
-
-/* options */
-int f_debug = 0;
-
-/* report flag to hide secure information */
-int f_report = 1;
-
-int connect_timeout = 0;
-
-/* local input type */
-#define LOCAL_STDIO     0
-#define LOCAL_SOCKET    1
-char *local_type_names[] = { "stdio", "socket" };
-int   local_type = LOCAL_STDIO;
-u_short local_port = 0;                         /* option 'p' */
-int f_hold_session = 0;                         /* option 'P' */
-
-char *telnet_command = "telnet %h %p";
-
-/* utiity types, pair holder of number and string */
-typedef struct {
-    int num;
-    const char *str;
-} LOOKUP_ITEM;
-
-/* relay method, server and port */
-#define METHOD_UNDECIDED 0
-#define METHOD_DIRECT    1
-#define METHOD_SOCKS     2
-#define METHOD_HTTP      3
-#define METHOD_TELNET    4
-char *method_names[] = { "UNDECIDED", "DIRECT", "SOCKS", "HTTP", "TELNET" };
-
-int   relay_method = METHOD_UNDECIDED;          /* relaying method */
-char *relay_host = NULL;                        /* hostname of relay server */
-u_short relay_port = 0;                         /* port of relay server */
-char *relay_user = NULL;                        /* user name for auth */
-
-/* destination target host and port */
-char *dest_host = NULL;
-struct sockaddr_in dest_addr;
-u_short dest_port = 0;
-
-/* informations for SOCKS */
-#define SOCKS5_REP_SUCCEEDED    0x00    /* succeeded */
-#define SOCKS5_REP_FAIL         0x01    /* general SOCKS serer failure */
-#define SOCKS5_REP_NALLOWED     0x02    /* connection not allowed by ruleset */
-#define SOCKS5_REP_NUNREACH     0x03    /* Network unreachable */
-#define SOCKS5_REP_HUNREACH     0x04    /* Host unreachable */
-#define SOCKS5_REP_REFUSED      0x05    /* connection refused */
-#define SOCKS5_REP_EXPIRED      0x06    /* TTL expired */
-#define SOCKS5_REP_CNOTSUP      0x07    /* Command not supported */
-#define SOCKS5_REP_ANOTSUP      0x08    /* Address not supported */
-#define SOCKS5_REP_INVADDR      0x09    /* Inalid address */
-
-LOOKUP_ITEM socks5_rep_names[] = {
-    { SOCKS5_REP_SUCCEEDED, "succeeded"},
-    { SOCKS5_REP_FAIL,      "general SOCKS server failure"},
-    { SOCKS5_REP_NALLOWED,  "connection not allowed by ruleset"},
-    { SOCKS5_REP_NUNREACH,  "Network unreachable"},
-    { SOCKS5_REP_HUNREACH,  "Host unreachable"},
-    { SOCKS5_REP_REFUSED,   "connection refused"},
-    { SOCKS5_REP_EXPIRED,   "TTL expired"},
-    { SOCKS5_REP_CNOTSUP,   "Command not supported"},
-    { SOCKS5_REP_ANOTSUP,   "Address not supported"},
-    { SOCKS5_REP_INVADDR,   "Invalid address"},
-    { -1, NULL }
-};
-
-/* SOCKS5 authentication methods */
-#define SOCKS5_AUTH_REJECT      0xFF    /* No acceptable auth method */
-#define SOCKS5_AUTH_NOAUTH      0x00    /* without authentication */
-#define SOCKS5_AUTH_GSSAPI      0x01    /* GSSAPI */
-#define SOCKS5_AUTH_USERPASS    0x02    /* User/Password */
-#define SOCKS5_AUTH_CHAP        0x03    /* Challenge-Handshake Auth Proto. */
-#define SOCKS5_AUTH_EAP         0x05    /* Extensible Authentication Proto. */
-#define SOCKS5_AUTH_MAF         0x08    /* Multi-Authentication Framework */
-
-#define SOCKS4_REP_SUCCEEDED    90      /* rquest granted (succeeded) */
-#define SOCKS4_REP_REJECTED     91      /* request rejected or failed */
-#define SOCKS4_REP_IDENT_FAIL   92      /* cannot connect identd */
-#define SOCKS4_REP_USERID       93      /* user id not matched */
-
-LOOKUP_ITEM socks4_rep_names[] = {
-    { SOCKS4_REP_SUCCEEDED,  "request granted (succeeded)"},
-    { SOCKS4_REP_REJECTED,   "request rejected or failed"},
-    { SOCKS4_REP_IDENT_FAIL, "cannot connect identd"},
-    { SOCKS4_REP_USERID,     "user id not matched"},
-    { -1, NULL }
-};
-
-#define RESOLVE_UNKNOWN 0
-#define RESOLVE_LOCAL   1
-#define RESOLVE_REMOTE  2
-#define RESOLVE_BOTH    3
-char *resolve_names[] = { "UNKNOWN", "LOCAL", "REMOTE", "BOTH" };
-
-int socks_version = 5;                          /* SOCKS protocol version */
-int socks_resolve = RESOLVE_UNKNOWN;
-struct sockaddr_in socks_ns;
-char *socks5_auth = NULL;
-
-/* Environment variable names */
-#define ENV_SOCKS_SERVER  "SOCKS_SERVER"        /* SOCKS server */
-#define ENV_SOCKS5_SERVER "SOCKS5_SERVER"
-#define ENV_SOCKS4_SERVER "SOCKS4_SERVER"
-
-#define ENV_SOCKS_RESOLVE  "SOCKS_RESOLVE"      /* resolve method */
-#define ENV_SOCKS5_RESOLVE "SOCKS5_RESOLVE"
-#define ENV_SOCKS4_RESOLVE "SOCKS4_RESOLVE"
-
-#define ENV_SOCKS5_USER     "SOCKS5_USER"       /* auth user for SOCKS5 */
-#define ENV_SOCKS4_USER     "SOCKS4_USER"       /* auth user for SOCKS4 */
-#define ENV_SOCKS_USER      "SOCKS_USER"        /* auth user for SOCKS */
-#define ENV_SOCKS5_PASSWD   "SOCKS5_PASSWD"     /* auth password for SOCKS5 */
-#define ENV_SOCKS5_PASSWORD "SOCKS5_PASSWORD"   /* old style */
-
-#define ENV_HTTP_PROXY          "HTTP_PROXY"    /* common env var */
-#define ENV_HTTP_PROXY_USER     "HTTP_PROXY_USER" /* auth user */
-#define ENV_HTTP_PROXY_PASSWORD "HTTP_PROXY_PASSWORD" /* auth password */
-
-#define ENV_TELNET_PROXY          "TELNET_PROXY"    /* common env var */
-
-#define ENV_CONNECT_USER     "CONNECT_USER"     /* default auth user name */
-#define ENV_CONNECT_PASSWORD "CONNECT_PASSWORD" /* default auth password */
-
-#define ENV_SOCKS_DIRECT   "SOCKS_DIRECT"       /* addr-list for non-proxy */
-#define ENV_SOCKS5_DIRECT  "SOCKS5_DIRECT"
-#define ENV_SOCKS4_DIRECT  "SOCKS4_DIRECT"
-#define ENV_HTTP_DIRECT    "HTTP_DIRECT"
-#define ENV_CONNECT_DIRECT "CONNECT_DIRECT"
-
-#define ENV_SOCKS5_AUTH "SOCKS5_AUTH"
-#define ENV_SSH_ASKPASS "SSH_ASKPASS"           /* askpass program */
-
-/* Prefix string of HTTP_PROXY */
-#define HTTP_PROXY_PREFIX "http://"
-#define PROXY_AUTH_NONE 0
-#define PROXY_AUTH_BASIC 1
-#define PROXY_AUTH_DIGEST 2
-int proxy_auth_type = PROXY_AUTH_NONE;
-
-/* reason of end repeating */
-#define REASON_UNK              -2
-#define REASON_ERROR            -1
-#define REASON_CLOSED_BY_LOCAL  0
-#define REASON_CLOSED_BY_REMOTE 1
-
-/* return value of relay start function. */
-#define START_ERROR -1
-#define START_OK     0
-#define START_RETRY  1
-
-/* socket related definitions */
-#ifndef _WIN32
-#define SOCKET int
-#endif
-#ifndef SOCKET_ERROR
-#define SOCKET_ERROR -1
-#endif
-
-#ifdef _WIN32
-#define socket_errno() WSAGetLastError()
-#else /* !_WIN32 */
-#define closesocket close
-#define socket_errno() (errno)
-#endif /* !_WIN32 */
-
-#ifdef _WIN32
-#define popen _popen
-#endif /* WIN32 */
-
-/* packet operation macro */
-#define PUT_BYTE(ptr,data) (*(unsigned char*)ptr = data)
-
-/* debug message output */
-void
-debug( const char *fmt, ... )
-{
-    va_list args;
-    if ( f_debug ) {
-        va_start( args, fmt );
-        fprintf(stderr, "DEBUG: ");
-        vfprintf( stderr, fmt, args );
-        va_end( args );
-    }
-}
-
-void
-debug_( const char *fmt, ... )                  /* without prefix */
-{
-    va_list args;
-    if ( f_debug ) {
-        va_start( args, fmt );
-        vfprintf( stderr, fmt, args );
-        va_end( args );
-    }
-}
-
-/* error message output */
-void
-error( const char *fmt, ... )
-{
-    va_list args;
-    va_start( args, fmt );
-    fprintf(stderr, "ERROR: ");
-    vfprintf( stderr, fmt, args );
-    va_end( args );
-}
-
-void
-fatal( const char *fmt, ... )
-{
-    va_list args;
-    va_start( args, fmt );
-    fprintf(stderr, "FATAL: ");
-    vfprintf( stderr, fmt, args );
-    va_end( args );
-    exit (EXIT_FAILURE);
-}
-
-
-void *
-xmalloc (size_t size)
-{
-    void *ret = malloc(size);
-    if (ret == NULL)
-	fatal("Cannot allocate memory: %d bytes.\n", size);
-    return ret;
-}
-
-char *
-downcase( char *str )
-{
-    char *buf = str;
-    while ( *buf ) {
-        if ( isupper(*buf) )
-            *buf += 'a'-'A';
-        buf++;
-    }
-    return str;                                 /* return converted arg */
-}
-
-char *
-expand_host_and_port (const char *fmt, const char *host, int port)
-{
-    const char *src;
-    char *buf, *dst, *ptr;
-    size_t len = strlen(fmt) + strlen(host) + 20;
-    buf = xmalloc (len);
-    dst = buf;
-    src = fmt;
-    
-    while (*src) {
-	if (*src == '%') {
-	    switch (src[1]) {
-	    case 'h':
-		strcpy (dst, host);
-		src += 2;
-		break;
-	    case 'p':
-		snprintf (dst, len, "%d", port);
-		src += 2;
-		break;
-	    default:
-		src ++;
-		break;
-	    }
-	    dst = buf + strlen (buf);
-	} else if (*src == '\\') {
-	    switch (src[1]) {
-	    case 'r':				/* CR */
-		*dst++ = '\r';
-		src += 2;
-		break;
-	    case 'n':				/* LF */
-		*dst++ = '\n';
-		src += 2;
-		break;
-	    case 't':				/* TAB */
-		*dst++ = '\t';
-		src += 2;
-		break;
-	    default:
-		src ++;
-		break;
-	    }
-	} else {
-	    /* usual */
-	    *dst++ = *src++;
-	}
-	*dst = '\0';
-    }
-    assert (strlen(buf) < len);
-    return buf;
-}
-
-
-int
-lookup_resolve( const char *str )
-{
-    char *buf = strdup( str );
-    int ret;
-
-    downcase( buf );
-    if ( strcmp( buf, "both" ) == 0 )
-        ret = RESOLVE_BOTH;
-    else if ( strcmp( buf, "remote" ) == 0 )
-        ret = RESOLVE_REMOTE;
-    else if ( strcmp( buf, "local" ) == 0 )
-        ret = RESOLVE_LOCAL;
-    else if ( strspn(buf, dotdigits) == strlen(buf) ) {
-#ifndef WITH_RESOLVER
-        fatal("Sorry, you can't specify to resolve the hostname with the -R option on Win32 environment.");
-#endif /* not WITH_RESOLVER */
-        ret = RESOLVE_LOCAL;                    /* this case is also 'local' */
-        socks_ns.sin_addr.s_addr = inet_addr(buf);
-        socks_ns.sin_family = AF_INET;
-    }
-    else
-        ret = RESOLVE_UNKNOWN;
-    free(buf);
-    return ret;
-}
-
-char *
-getusername(void)
-{
-#ifdef _WIN32
-    static char buf[1024];
-    DWORD size = sizeof(buf);
-    buf[0] = '\0';
-    GetUserName( buf, &size);
-    return buf;
-#else  /* not _WIN32 */
-    struct passwd *pw = getpwuid(getuid());
-    if ( pw == NULL )
-        fatal("getpwuid() failed for uid: %d\n", getuid());
-    return pw->pw_name;
-#endif /* not _WIN32 */
-}
-
-/* expect
-   check STR is begin with substr with case-ignored comparison.
-   Return 1 if matched, otherwise 0.
-*/
-int
-expect( char *str, char *substr)
-{
-    int len = strlen(substr);
-    while ( 0 < len-- ) {
-        if ( toupper(*str) != toupper(*substr) )
-            return 0;                           /* not matched */
-        str++, substr++;
-    }
-    return 1;                   /* good, matched */
-}
-
-
-/** PARAMETER operation **/
-#define PARAMETER_FILE "/etc/connectrc"
-#define PARAMETER_DOTFILE ".connectrc"
-typedef struct {
-    char* name;
-    char* value;
-} PARAMETER_ITEM;
-PARAMETER_ITEM parameter_table[] = {
-    { ENV_SOCKS_SERVER, NULL },
-    { ENV_SOCKS5_SERVER, NULL },
-    { ENV_SOCKS4_SERVER, NULL },
-    { ENV_SOCKS_RESOLVE, NULL },
-    { ENV_SOCKS5_RESOLVE, NULL },
-    { ENV_SOCKS4_RESOLVE, NULL },
-    { ENV_SOCKS5_USER, NULL },
-    { ENV_SOCKS5_PASSWD, NULL },
-    { ENV_SOCKS5_PASSWORD, NULL },
-    { ENV_HTTP_PROXY, NULL },
-    { ENV_HTTP_PROXY_USER, NULL },
-    { ENV_HTTP_PROXY_PASSWORD, NULL },
-    { ENV_CONNECT_USER, NULL },
-    { ENV_CONNECT_PASSWORD, NULL },
-    { ENV_SSH_ASKPASS, NULL },
-    { ENV_SOCKS5_DIRECT, NULL },
-    { ENV_SOCKS4_DIRECT, NULL },
-    { ENV_SOCKS_DIRECT, NULL },
-    { ENV_HTTP_DIRECT, NULL },
-    { ENV_CONNECT_DIRECT, NULL },
-    { ENV_SOCKS5_AUTH, NULL },
-    { NULL, NULL }
-};
-
-PARAMETER_ITEM*
-find_parameter_item(const char* name)
-{
-    int i;
-    for( i = 0; parameter_table[i].name != NULL; i++ ){
-        if ( strcmp(name, parameter_table[i].name) == 0 )
-            return &parameter_table[i];
-    }
-    return NULL;
-}
-
-void
-read_parameter_file_1(const char* name)
-{
-    FILE* f;
-    int line;
-    char lbuf[1025];
-    f = fopen(name, "r");
-    if( f ){
-        debug("Reading parameter file(%s)\n", name);
-        for ( line = 1; fgets(lbuf, 1024, f); line++ ) {
-            char *p, *q, *param, *value;
-            p = strchr(lbuf, '\n');
-            if ( p == NULL )
-                fatal("%s:%d: buffer overflow\n", name, line);
-            *p = '\0';
-            p = strchr(lbuf, '#');
-            if ( p )
-                *p = '\0';
-            for ( p = lbuf; *p; p++ )
-                if( *p != ' ' && *p != '\t' ) break;
-            if ( *p == '\0' ) continue;
-            param = p;
-            p = strchr(p, '=');
-            if ( p == NULL ) {
-                error("%s:%d: missing equal sign\n", name, line);
-                continue;
-            }
-            for ( q = p - 1; q >= lbuf; q-- )
-                if ( *q != ' ' && *q != '\t' ) break;
-            *++q = '\0';
-            for ( ++p; *p; p++ )
-                if ( *p != ' ' && *p != '\t' ) break;
-            value = p;
-            for ( ; *p; p++ );
-            for ( p--; p >= lbuf; p-- )
-                if ( *p != ' ' && *p != '\t' ) break;
-            *++p = '\0';
-            if ( param && value ) {
-                PARAMETER_ITEM *item;
-                item = find_parameter_item(param);
-                if ( item == NULL ) {
-                    error("%s:%d: unknown parameter `%s'\n", name, line, param);
-                    continue;
-                }
-                item->value = strdup(value);
-                debug("Parameter `%s' is set to `%s'\n", param, value);
-            }
-        }
-    }
-}
-
-void
-read_parameter_file(void)
-{
-#if !defined(_WIN32) || defined(cygwin)
-    char *name;
-    struct passwd *pw;
-#endif
-
-    read_parameter_file_1(PARAMETER_FILE);
-#if !defined(_WIN32) || defined(cygwin)
-    pw = getpwuid(getuid());
-    if ( pw == NULL )
-        fatal("getpwuid() failed for uid: %d\n", getuid());
-    name = xmalloc(strlen(pw->pw_dir) + strlen(PARAMETER_DOTFILE) + 2);
-    strcpy(name, pw->pw_dir);
-    strcat(name, "/" PARAMETER_DOTFILE);
-    read_parameter_file_1(name);
-    free(name);
-#endif /* _WIN32 */
-}
-
-char*
-getparam(const char* name)
-{
-    char *value = getenv(name);
-    if ( value == NULL ){
-        PARAMETER_ITEM *item = find_parameter_item(name);
-        if ( item != NULL )
-            value = item->value;
-    }
-    return value;
-}
-
-
-/** DIRECT connection **/
-#define MAX_DIRECT_ADDR_LIST 256
-
-struct ADDRPAIR {
-    struct in_addr addr;
-    struct in_addr mask;
-    char *name;
-    int negative;
-};
-
-struct ADDRPAIR direct_addr_list[MAX_DIRECT_ADDR_LIST];
-int n_direct_addr_list = 0;
-
-void
-mask_addr (void *addr, void *mask, int addrlen)
-{
-    char *a, *m;
-    a = addr;
-    m = mask;
-    while ( 0 < addrlen-- )
-        *a++ &= *m++;
-}
-
-int
-add_direct_addr (struct in_addr *addr, struct in_addr *mask, int negative)
-{
-    struct in_addr iaddr;
-    char *s;
-    if ( MAX_DIRECT_ADDR_LIST <= n_direct_addr_list ) {
-        error("direct address table is full!\n");
-        return -1;
-    }
-    iaddr = *addr;
-    mask_addr(&iaddr, mask, sizeof(iaddr));
-    s = strdup(inet_ntoa(iaddr));
-    debug("adding direct addr entry: %s%s/%s\n",
-          negative? "!": "", s, inet_ntoa(*mask));
-    free(s);
-    memcpy( &direct_addr_list[n_direct_addr_list].addr,
-            &iaddr, sizeof(iaddr));
-    memcpy( &direct_addr_list[n_direct_addr_list].mask,
-            mask, sizeof(*mask));
-    direct_addr_list[n_direct_addr_list].name = NULL;
-    direct_addr_list[n_direct_addr_list].negative = negative;
-    n_direct_addr_list++;
-    return 0;
-}
-
-
-/* add domain/host name entry to direct name table */
-int
-add_direct_host( const char *name, int negative)
-{
-    if ( MAX_DIRECT_ADDR_LIST <= n_direct_addr_list ) {
-        error("direct address table is full!\n");
-        return -1;
-    }
-    if (*name == '*')
-        name++;
-    if (*name == '.')
-        name++;
-    debug("adding direct name entry: %s%s\n", negative? "!": "", name);
-    direct_addr_list[n_direct_addr_list].name = downcase(strdup(name));
-    direct_addr_list[n_direct_addr_list].negative = negative;
-    n_direct_addr_list++;
-    return 0;
-}
-
-
-int
-parse_addr_pair (const char *str, struct in_addr *addr, struct in_addr *mask)
-{
-    /* NOTE: */
-    /* Assume already be splitted by separator
-       and formatted as folowing:
-       1)  12.34.56.789/255.255.255.0
-       2)  12.34.56.789/24
-       3)  12.34.56.
-       All above generates same addr/mask pair 12.34.56.0 and 255.255.255.0
-    */
-    const char *ptr;
-    u_char *dsta, *dstm;
-    int i, n;
-
-    assert( str != NULL );
-    addr->s_addr = 0;
-    mask->s_addr = 0;
-    ptr = str;
-    dsta = (u_char*)&addr->s_addr;
-    dstm = (u_char*)&mask->s_addr;
-    for (i=0; i<4; i++ ) {
-        if ( *ptr == '\0' )
-            break;              /* case of format #3 */
-        if ( !isdigit(*ptr) )
-            return -1;          /* format error: */
-        *dsta++ = atoi( ptr );
-        *dstm++ = 255;          /* automatic mask for format #3 */
-        while ( isdigit(*ptr) ) /* skip digits */
-            ptr++;
-        if ( *ptr == '.' )
-            ptr++;
-        else
-            break;
-    }
-    /* At this point, *ptr points '/' or EOS ('\0') */
-    if ( *ptr == '\0' )
-        return 0;                       /* complete as format #3 */
-    if ( *ptr != '/' )
-        return -1;                      /* format error */
-    /* Now parse mask for format #1 or #2 */
-    ptr++;
-    mask->s_addr = 0;                   /* clear automatic mask */
-
-    if ( strchr( ptr, '.') ) {
-        /* case of format #1 */
-        dstm = (u_char*)&mask->s_addr;
-        for (i=0; i<4; i++) {
-            if ( !isdigit(*ptr) )
-                return -1;              /* format error: */
-            *dstm++ = atoi(ptr);
-            while ( isdigit(*ptr) )     /* skip digits */
-                ptr++;
-            if ( *ptr == '.' )
-                ptr++;
-            else
-                break;                  /* from for loop */
-        }
-        /* complete as format #1 */
-    } else {
-        /* case of format #2 */
-        if ( !isdigit(*ptr) )
-            return -1;                  /* format error: */
-        n = atoi(ptr);
-        if ( n<0 || 32<n)
-            return -1;                  /* format error */
-        mask->s_addr = (n==0)? 0: htonl(((u_long)0xFFFFFFFF)<<(32-n));
-        /* complete as format #1 */
-    }
-    return 0;
-}
-
-void
-initialize_direct_addr (void)
-{
-    int negative;
-    int n_entries;
-    char *env = NULL, *beg, *next, *envkey = NULL;
-    struct in_addr addr, mask;
-
-    if ( relay_method == METHOD_SOCKS ){
-        if ( socks_version == 5 )
-            envkey = ENV_SOCKS5_DIRECT;
-        else
-            envkey = ENV_SOCKS4_DIRECT;
-        env = getparam(envkey);
-        if ( env == NULL )
-            env = getparam(ENV_SOCKS_DIRECT);
-    } else if ( relay_method == METHOD_HTTP ){
-        env = getparam(ENV_HTTP_DIRECT);
-    }
-
-    if ( env == NULL )
-        env = getparam(ENV_CONNECT_DIRECT);
-
-    if ( env == NULL )
-        return;                 /* no entry */
-    debug("making direct addr list from: '%s'\n", env);
-    env = strdup( env );        /* reallocate to modify */
-    beg = next = env;
-    n_entries = 0;
-    do {
-        if ( MAX_DIRECT_ADDR_LIST <= n_entries ) {
-            error("too many entries in %s", envkey);
-            break;              /* from do loop */
-        }
-        next = strchr( beg, ',');
-        if ( next != NULL )
-            *next++ = '\0';
-        addr.s_addr = 0;
-        mask.s_addr = 0;
-        if (*beg == '!') {
-            negative = 1;
-            beg++;
-        } else
-            negative = 0;
-        if ( !parse_addr_pair( beg, &addr, &mask ) ) {
-            add_direct_addr( &addr, &mask, negative );
-        } else {
-            add_direct_host( beg, negative );
-        }
-        if ( next != NULL )
-            beg = next;
-    } while ( next != NULL );
-
-    free( env );
-    return;
-}
-
-int
-cmp_addr (void *addr1, void *addr2, int addrlen)
-{
-    return memcmp( addr1, addr2, addrlen );
-}
-
-int
-is_direct_address (const struct in_addr addr)
-{
-    int i, neg;
-    struct in_addr iaddr;
-
-    /* Note: assume IPV4 address !! */
-    for (i=0; i<n_direct_addr_list; i++ ) {
-        if (direct_addr_list[i].name != NULL)
-            continue;                           /* it's name entry */
-        neg = direct_addr_list[i].negative;
-        iaddr = addr;
-        mask_addr( &iaddr, &direct_addr_list[i].mask,
-                   sizeof(struct in_addr));
-        if (cmp_addr(&iaddr, &direct_addr_list[i].addr,
-                     sizeof(struct in_addr)) == 0) {
-            char *a, *m;
-            a = strdup(inet_ntoa(direct_addr_list[i].addr));
-            m = strdup(inet_ntoa(direct_addr_list[i].mask));
-            debug("match with: %s/%s%s\n", a, m, neg? " (negative)": "");
-            free(a);
-            free(m);
-            return !neg? 1: 0;
-        }
-    }
-    debug("not matched, addr to be relayed: %s\n", inet_ntoa(addr));
-    return 0;                   /* not direct */
-}
-
-
-/* check s1 is ends with s2.
-   return 1 if exact match or domain part match.
-   return 0 if s1 is shorter than s2 or partial match.
-   For example, 
-    ends_with("bar.com", "bar.com")        => 1 (exact match)
-    ends_with("foo.bar.com", "bar.com")    => 1 (domain match)
-    ends_with("foo.beebar.com", "bar.com") => 0 (partial match)
-    ends_with("bar", "bar.com")            => 0 (shorter)
- */
-domain_match(const char *s1, const char *s2)
-{
-    int len1, len2;
-    const char *tail1, *tail2;
-    len1 = strlen(s1);
-    len2 = strlen(s2);
-    if (len1 < len2 || len1 == 0 || len2 == 0)
-        return 0;                               /* not match */
-    tail1 = s1 + len1;
-    tail2 = s2 + len2;
-    while (0 < len1 && 0 < len2) {
-        if (*--tail1 != *--tail2)
-            break;                              /* not match */
-        len1--, len2--;
-    }
-    if (len2 != 0)
-        return 0;                               /* not match */
-    /* Now exact match, domain match or partial match.
-       Return true if exact or domain match.
-       Or continue checking. */
-    if (tail1 == s1 || tail1[-1] == '.')
-        return 1;                               /* match! */
-    return 0;                                   /* not match */
-}
-
-/* Check given NAME is ends with one of 
-   registered direct name entry.
-   Return 1 if matched, or 0.
-*/
-int
-is_direct_name (const char *name)
-{
-    int len, i;
-    const char *tail;
-    debug("checking %s is for direct?\n", name);
-    name = downcase(strdup(name));
-    len = strlen(name);
-    if (len < 1)
-        return 0;                               /* false */
-    tail = &name[len];
-    for (i=0; i<n_direct_addr_list; i++ ) {
-        int dlen, neg;
-        const char *dname;
-        const char *n, *d;
-        dname = direct_addr_list[i].name;
-        if (dname == NULL)
-            continue;                           /* it's addr/mask entry */
-        neg = direct_addr_list[i].negative;
-        if (domain_match(name, dname)) {
-            debug("match with: %s%s\n", dname, neg? " (negative)": "");
-            if (neg) {
-                return 0;       /* not direct */
-            } else {
-                return 1;       /* direct*/
-            }
-        }
-    }
-    return 0;                                   /* not matched */
-}
-
-/* check to connect to HOST directyly?
-   return 1 if to be direct, 0 for else. */
-int
-check_direct(const char *host)
-{
-    struct in_addr addr;
-    addr.s_addr = inet_addr(host);
-    if (addr.s_addr != INADDR_NONE) {
-        /* case of IP address */
-        if (is_direct_address(addr)) {
-            debug("%s is for direct.\n", host);
-            return 1;                           /* true */
-        }
-    } else {
-        /* case of hostname */
-        if (is_direct_name(host)) {
-            debug("%s is for direct.\n", host);
-            return 1;                           /* true */
-        }
-    }
-    debug("%s is for not direct.\n", host);
-    return 0;                                    /* false */
-}
-
-
-/** TTY operation **/
-
-int intr_flag = 0;
-
-#ifndef _WIN32
-void
-intr_handler(int sig)
-{
-    intr_flag = 1;
-}
-
-void
-tty_change_echo(int fd, int enable)
-{
-    static struct termios ntio, otio;           /* new/old termios */
-    static sigset_t nset, oset;                 /* new/old sigset */
-    static struct sigaction nsa, osa;           /* new/old sigaction */
-    static int disabled = 0;
-
-    if ( disabled && enable ) {
-        /* enable echo */
-        tcsetattr(fd, TCSANOW, &otio);
-        disabled = 0;
-        /* resotore sigaction */
-        sigprocmask(SIG_SETMASK, &oset, NULL);
-        sigaction(SIGINT, &osa, NULL);
-        if ( intr_flag != 0 ) {
-            /* re-generate signal  */
-            kill(getpid(), SIGINT);
-            sigemptyset(&nset);
-            sigsuspend(&nset);
-            intr_flag = 0;
-        }
-    } else if (!disabled && !enable) {
-        /* set SIGINTR handler and break syscall on singal */
-        sigemptyset(&nset);
-        sigaddset(&nset, SIGTSTP);
-        sigprocmask(SIG_BLOCK, &nset, &oset);
-        intr_flag = 0;
-        memset(&nsa, 0, sizeof(nsa));
-        nsa.sa_handler = intr_handler;
-        sigaction(SIGINT, &nsa, &osa);
-        /* disable echo */
-        if (tcgetattr(fd, &otio) == 0 && (otio.c_lflag & ECHO)) {
-            disabled = 1;
-            ntio = otio;
-            ntio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
-            (void) tcsetattr(fd, TCSANOW, &ntio);
-        }
-    }
-
-    return;
-}
-
-#define TTY_NAME "/dev/tty"
-int
-tty_readpass( const char *prompt, char *buf, size_t size )
-{
-    int tty, ret = 0;
-
-    tty = open(TTY_NAME, O_RDWR);
-    if ( tty < 0 ) {
-        error("Unable to open %s\n", TTY_NAME);
-        return -1;                              /* can't open tty */
-    }
-    if ( size <= 0 )
-        return -1;                              /* no room */
-    write(tty, prompt, strlen(prompt));
-    buf[0] = '\0';
-    tty_change_echo(tty, 0);                    /* disable echo */
-    ret = read(tty,buf, size-1);
-    tty_change_echo(tty, 1);                    /* restore */
-    write(tty, "\n", 1);                        /* new line */
-    close(tty);
-    if ( strchr(buf,'\n') == NULL  )
-        return -1;
-    if ( 0 < ret )
-        buf[ret] = '\0';
-    return ret;
-}
-
-#else  /* _WIN32 */
-
-BOOL __stdcall
-w32_intr_handler(DWORD dwCtrlType)
-{
-    if ( dwCtrlType == CTRL_C_EVENT ) {
-        intr_flag = 1;
-        return TRUE;
-    } else {
-        return FALSE;
-    }
-}
-
-#define tty_readpass w32_tty_readpass
-int
-w32_tty_readpass( const char *prompt, char *buf, size_t size )
-{
-    HANDLE in = CreateFile("CONIN$", GENERIC_READ|GENERIC_WRITE,
-                           0, NULL, OPEN_EXISTING, 0, NULL);
-    HANDLE out = CreateFile("CONOUT$", GENERIC_WRITE,
-                            0, NULL, OPEN_EXISTING, 0, NULL);
-    DWORD mode;
-    DWORD ret, bytes;
-
-    if (in == INVALID_HANDLE_VALUE || out == INVALID_HANDLE_VALUE)
-        fatal("Cannot open console. (errno=%d)", GetLastError());
-
-    WriteFile(out, prompt, strlen(prompt), &bytes, 0);
-    SetConsoleCtrlHandler(w32_intr_handler, TRUE ); /* add handler */
-    GetConsoleMode(in, &mode);
-    SetConsoleMode(in, mode&~ENABLE_ECHO_INPUT); /* disable echo */
-    ret = ReadFile(in, buf, size, &bytes, 0);
-    SetConsoleMode(in, mode);                   /* enable echo */
-    SetConsoleCtrlHandler( w32_intr_handler, FALSE ); /* remove handler */
-    if ( intr_flag )
-        GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); /* re-signal */
-    WriteFile(out,"\n", 1, &bytes, 0);
-    CloseHandle(in);
-    CloseHandle(out);
-    return ret;
-}
-
-#endif /* _WIN32 */
-
-/*** User / Password ***/
-
-/* SOCKS5 and HTTP Proxy authentication may requires username and
-   password. We ll give it via environment variable or tty.
-   Username and password for authentication are decided by
-   following rules:
-
-   Username is taken from
-     1) server location spec (i.e. user at host:port)
-     2) environment variables (see tables.1)
-     3) system account name currently logged in.
-
-     Table.1 Order of environment variables for username
-
-        |  SOCKS v5   |  SOCKS v4   |   HTTP proxy    |
-      --+-------------+-------------+-----------------+
-      1 | SOCKS45_USER | SOCKS4_USER | HTTP_PROXY_USER |
-      --+-------------+-------------+                 |
-      2 |        SOCKS_USER         |                 |
-      --+---------------------------+-----------------+
-      3 |              CONNECT_USER                   |
-      --+---------------------------------------------+
-
-   Password is taken from
-     1) by environment variables (see table.2)
-     2) by entering from tty.
-
-     Table.2 Order of environment variables for password
-
-        |    SOCKS v5     |     HTTP proxy      |
-      --+-----------------+---------------------+
-      1 | SOCKS5_PASSWD   |                     |
-      --+-----------------+ HTTP_PROXY_PASSWORD |
-      2 | SOCKS5_PASSWORD |                     |
-      --+-----------------+---------------------+
-      3 |           CONNECT_PASSWORD            |
-      --+---------------------------------------+
-
-      Note: SOCKS5_PASSWD which is added in rev. 1.79
-            to share value with NEC SOCKS implementation.
- */
-
-char *
-determine_relay_user ()
-{
-    char *user = NULL;
-    /* get username from environment variable, or system. */
-    if (relay_method == METHOD_SOCKS) {
-        if (user == NULL && socks_version == 5)
-            user = getparam (ENV_SOCKS5_USER);
-        if (user == NULL && socks_version == 4)
-            user = getparam (ENV_SOCKS4_USER);
-        if (user == NULL)
-            user = getparam (ENV_SOCKS_USER);
-    } else if (relay_method == METHOD_HTTP) {
-        if (user == NULL)
-            user = getparam (ENV_HTTP_PROXY_USER);
-    }
-    if (user == NULL)
-        user = getparam (ENV_CONNECT_USER);
-    /* determine relay user by system call if not yet. */
-    if (user == NULL)
-        user = getusername();
-    return user;
-}
-
-char *
-determine_relay_password ()
-{
-    char *pass = NULL;
-    if (pass == NULL && relay_method == METHOD_HTTP)
-        pass = getparam(ENV_HTTP_PROXY_PASSWORD);
-    if (pass == NULL && relay_method == METHOD_SOCKS)
-        pass = getparam(ENV_SOCKS5_PASSWD);
-    if (pass == NULL && relay_method == METHOD_SOCKS)
-        pass = getparam(ENV_SOCKS5_PASSWORD);
-    if (pass == NULL)
-        pass = getparam(ENV_CONNECT_PASSWORD);
-    return pass;
-}
-
-
-/*** network operations ***/
-
-
-/* set_relay()
-   Determine relay informations:
-   method, host, port, and username.
-   1st arg, METHOD should be METHOD_xxx.
-   2nd arg, SPEC is hostname or hostname:port or user at hostame:port.
-   hostname is domain name or dot notation.
-   If port is omitted, use 80 for METHOD_HTTP method,
-   use 1080 for METHOD_SOCKS method.
-   Username is also able to given by 3rd. format.
-   2nd argument SPEC can be NULL. if NULL, use environment variable.
- */
-int
-set_relay( int method, char *spec )
-{
-    char *buf, *sep, *resolve;
-
-    relay_method = method;
-
-    read_parameter_file();
-    initialize_direct_addr();
-    if (n_direct_addr_list == 0) {
-        debug ("No direct address are specified.\n");
-    } else {
-        debug ("%d direct address entries.\n", n_direct_addr_list);
-    }
-
-    switch ( method ) {
-    case METHOD_DIRECT:
-        return -1;                              /* nothing to do */
-
-    case METHOD_SOCKS:
-        if ( spec == NULL ) {
-            switch ( socks_version ) {
-            case 5:
-                spec = getparam(ENV_SOCKS5_SERVER);
-                break;
-            case 4:
-                spec = getparam(ENV_SOCKS4_SERVER);
-                break;
-            }
-        }
-        if ( spec == NULL )
-            spec = getparam(ENV_SOCKS_SERVER);
-
-        if ( spec == NULL )
-            fatal("Failed to determine SOCKS server.\n");
-        relay_port = 1080;                      /* set default first */
-
-        /* determine resolve method */
-        if ( socks_resolve == RESOLVE_UNKNOWN ) {
-            if ( ((socks_version == 5) &&
-                  ((resolve = getparam(ENV_SOCKS5_RESOLVE)) != NULL)) ||
-                 ((socks_version == 4) &&
-                  ((resolve = getparam(ENV_SOCKS4_RESOLVE)) != NULL)) ||
-                 ((resolve = getparam(ENV_SOCKS_RESOLVE)) != NULL) ) {
-                socks_resolve = lookup_resolve( resolve );
-                if ( socks_resolve == RESOLVE_UNKNOWN )
-                    fatal("Invalid resolve method: %s\n", resolve);
-            } else {
-                /* default */
-                if ( socks_version == 5 )
-                    socks_resolve = RESOLVE_REMOTE;
-                else
-                    socks_resolve = RESOLVE_LOCAL;
-            }
-        }
-        break;
-
-    case METHOD_HTTP:
-        if ( spec == NULL )
-            spec = getparam(ENV_HTTP_PROXY);
-        if ( spec == NULL )
-            fatal("You must specify http proxy server\n");
-        relay_port = 80;                        /* set default first */
-        break;
-    case METHOD_TELNET:
-        if ( spec == NULL )
-            spec = getparam(ENV_TELNET_PROXY);
-        if ( spec == NULL )
-            fatal("You must specify telnet proxy server\n");
-        relay_port = 23;                        /* set default first */
-    }
-
-    if (expect( spec, HTTP_PROXY_PREFIX)) {
-        /* URL format like: "http://server:port/" */
-        /* extract server:port part */
-        buf = strdup( spec + strlen(HTTP_PROXY_PREFIX));
-        buf[strcspn(buf, "/")] = '\0';
-    } else {
-        /* assume spec is aready "server:port" format */
-        buf = strdup( spec );
-    }
-    spec = buf;
-
-    /* check username in spec */
-    sep = strchr( spec, '@' );
-    if ( sep != NULL ) {
-        *sep = '\0';
-        relay_user = strdup( spec );
-        spec = sep +1;
-    }
-    if (relay_user == NULL)
-        relay_user = determine_relay_user();
-
-    /* split out hostname and port number from spec */
-    sep = strchr(spec,':');
-    if ( sep == NULL ) {
-        /* hostname only, port is already set as default */
-        relay_host = strdup( spec );
-    } else {
-        /* hostname and port */
-        relay_port = atoi(sep+1);
-        *sep = '\0';
-        relay_host = strdup( spec );
-    }
-    free(buf);
-    return 0;
-}
-
-
-u_short
-resolve_port( const char *service )
-{
-    int port;
-    if ( service[strspn (service, digits)] == '\0'  ) {
-        /* all digits, port number */
-        port = atoi(service);
-    } else {
-        /* treat as service name */
-        struct servent *ent;
-        ent = getservbyname( service, NULL );
-        if ( ent == NULL ) {
-            debug("Unknown service, '%s'\n", service);
-            port = 0;
-        } else {
-            port = ntohs(ent->s_port);
-            debug("service: %s => %d\n", service, port);
-        }
-    }
-    return (u_short)port;
-}
-
-void
-make_revstr(void)
-{
-    char *ptr;
-    size_t len;
-    ptr = strstr(rcs_revstr, ": ");
-    if (!ptr) {
-        revstr = strdup("unknown");
-        return;
-    }
-    ptr += 2;
-    /* assume subversion's keyword expansion like "Revision: 96". */
-    minor_version = atoi(ptr);
-    revstr = xmalloc(20);
-    snprintf(revstr, 20, "%d.%d", major_version, minor_version);
-}
-
-int
-getarg( int argc, char **argv )
-{
-    int err = 0;
-    char *ptr, *server = (char*)NULL;
-    int method = METHOD_DIRECT;
-
-    progname = *argv;
-    argc--, argv++;
-
-    /* check optinos */
-    while ( (0 < argc) && (**argv == '-') ) {
-        ptr = *argv + 1;
-        while ( *ptr ) {
-            switch ( *ptr ) {
-            case 's':                           /* use SOCKS */
-                method = METHOD_SOCKS;
-                break;
-
-            case 'n':                           /* no proxy */
-                method = METHOD_DIRECT;
-                break;
-
-            case 'h':                           /* use http-proxy */
-                method = METHOD_HTTP;
-                break;
-            case 't':
-                method = METHOD_TELNET;
-                break;
-
-            case 'S':                           /* specify SOCKS server */
-                if ( 1 < argc ) {
-                    argv++, argc--;
-                    method = METHOD_SOCKS;
-                    server = *argv;
-                } else {
-                    error("option '-%c' needs argument.\n", *ptr);
-                    err++;
-                }
-                break;
-
-            case 'H':                           /* specify http-proxy server */
-                if ( 1 < argc ) {
-                    argv++, argc--;
-                    method = METHOD_HTTP;
-                    server = *argv;
-                } else {
-                    error("option '-%c' needs argument.\n", *ptr);
-                    err++;
-                }
-                break;
-            case 'T':                           /* specify telnet proxy server */
-                if ( 1 < argc ) {
-                    argv++, argc--;
-                    method = METHOD_TELNET;
-                    server = *argv;
-                } else {
-                    error("option '-%c' needs argument.\n", *ptr);
-                    err++;
-                }
-                break;
-
-            case 'c':
-                 if (1 < argc) {
-                      argv++, argc--;
-                      telnet_command = *argv;
-                 } else {
-                      error("option '%c' needs argument.\n", *ptr);
-                      err++;
-                 }
-                 break;
-
-            case 'P':
-                f_hold_session = 1;
-                /* without break */
-            case 'p':                          /* specify port to forward */
-                if ( 1 < argc ) {
-                    argv++, argc--;
-                    local_type = LOCAL_SOCKET;
-                    local_port = resolve_port(*argv);
-                } else {
-                    error("option '-%c' needs argument.\n", *ptr);
-                    err++;
-                }
-                break;
-
-#ifndef _WIN32
-            case 'w':
-                if ( 1 < argc ) {
-                    argv++, argc--;
-                    connect_timeout = atoi(*argv);
-                } else {
-                    error("option '-%c' needs argument.\n", *ptr);
-                    err++;
-                }
-                break;
-#endif /* not _WIN32 */
-
-            case '4':
-                socks_version = 4;
-                break;
-
-            case '5':
-                socks_version = 5;
-                break;
-
-            case 'a':
-                if ( 1 < argc ) {
-                    argv++, argc--;
-                    socks5_auth = *argv;
-                } else {
-                    error("option '-%c' needs argument.\n", *ptr);
-                    err++;
-                }
-                break;
-
-            case 'R':                           /* specify resolve method */
-                if ( 1 < argc ) {
-                    argv++, argc--;
-                    socks_resolve = lookup_resolve( *argv );
-                } else {
-                    error("option '-%c' needs argument.\n", *ptr);
-                    err++;
-                }
-                break;
-
-            case 'V':                           /* print version */
-                fprintf(stderr, "%s\nVersion %s\n", progdesc, revstr);
-                exit(0);
-
-            case 'd':                           /* debug mode */
-                f_debug++;
-                break;
-
-            default:
-                error("unknown option '-%c'\n", *ptr);
-                err++;
-            }
-            ptr++;
-        }
-        argc--, argv++;
-    }
-
-    /* check error */
-    if ( 0 < err )
-        goto quit;
-
-    set_relay( method, server );
-
-    /* check destination HOST (MUST) */
-    if ( argc == 0  ) {
-        fprintf(stderr, "%s\nVersion %s\n", progdesc, revstr);
-        fprintf(stderr, usage, progname);
-        exit(0);
-    }
-    dest_host = argv[0];
-    /* decide port or service name from programname or argument */
-    if ( ((ptr=strrchr( progname, '/' )) != NULL) ||
-         ((ptr=strchr( progname, '\\')) != NULL) )
-        ptr++;
-    else
-        ptr = progname;
-    if ( dest_port == 0 ) {
-        /* accept only if -P is not specified. */
-        if ( 1 < argc ) {
-            /* get port number from argument (prior to progname) */
-            /* NOTE: This way is for cvs ext method. */
-            dest_port = resolve_port(argv[1]);
-        } else if ( strncmp( ptr, "connect-", 8) == 0 ) {
-            /* decide port number from program name */
-            char *str = strdup( ptr+8 );
-            str[strcspn( str, "." )] = '\0';
-            dest_port = resolve_port(str);
-            free(str);
-        }
-    }
-    /* check port number */
-    if ( dest_port <= 0 ) {
-        error( "You must specify the destination port correctly.\n");
-        err++;
-        goto quit;
-    }
-    if ( (relay_method != METHOD_DIRECT) && (relay_port <= 0) ) {
-        error("Invalid relay port: %d\n", dest_port);
-        err++;
-        goto quit;
-    }
-
-quit:
-    /* report for debugging */
-    debug("relay_method = %s (%d)\n",
-          method_names[relay_method], relay_method);
-    if ( relay_method != METHOD_DIRECT ) {
-        debug("relay_host=%s\n", relay_host);
-        debug("relay_port=%d\n", relay_port);
-        debug("relay_user=%s\n", relay_user);
-    }
-    if ( relay_method == METHOD_SOCKS ) {
-        debug("socks_version=%d\n", socks_version);
-        debug("socks_resolve=%s (%d)\n",
-              resolve_names[socks_resolve], socks_resolve);
-    }
-    debug("local_type=%s\n", local_type_names[local_type]);
-    if ( local_type == LOCAL_SOCKET ) {
-        debug("local_port=%d\n", local_port);
-        if (f_hold_session)
-            debug ("  with holding remote session.\n");
-    }
-    debug("dest_host=%s\n", dest_host);
-    debug("dest_port=%d\n", dest_port);
-    if ( 0 < err ) {
-        fprintf(stderr, usage, progname);
-        exit(1);
-    }
-    return 0;
-}
-
-#ifndef _WIN32
-/* Time-out feature is not allowed for Win32 native compilers. */
-/* MSVC and Borland C cannot but Cygwin and UNIXes can. */
-
-/* timeout signal hander */
-void
-sig_timeout(void)
-{
-    signal( SIGALRM, SIG_IGN );
-    alarm( 0 );
-    error( "timed out\n" );
-    exit(1);
-}
-
-/* set timeout param = seconds, 0 clears */
-void
-set_timeout(int timeout)
-{
-    /* This feature is allowed for UNIX or cygwin environments, currently */
-    if ( timeout == 0 ) {
-        debug( "clearing timeout\n" );
-        signal( SIGALRM, SIG_IGN );
-        alarm( 0 );
-    } else {
-        debug( "setting timeout: %d seconds\n", timeout );
-        signal(SIGALRM, (void *)sig_timeout);
-        alarm( timeout );
-    }
-}
-#endif
-
-#if !defined(_WIN32) && !defined(__CYGWIN32__)
-void
-switch_ns (struct sockaddr_in *ns)
-{
-    res_init();
-    memcpy (&_res.nsaddr_list[0], ns, sizeof(*ns));
-    _res.nscount = 1;
-    debug("Using nameserver at %s\n", inet_ntoa(ns->sin_addr));
-}
-#endif /* !_WIN32 && !__CYGWIN32__ */
-
-/* TODO: IPv6
-   TODO: fallback if askpass execution failed.
- */
-
-int
-local_resolve (const char *host, struct sockaddr_in *addr)
-{
-    struct hostent *ent;
-    if ( strspn(host, dotdigits) == strlen(host) ) {
-        /* given by IPv4 address */
-        addr->sin_family = AF_INET;
-        addr->sin_addr.s_addr = inet_addr(host);
-    } else {
-        debug("resolving host by name: %s\n", host);
-        ent = gethostbyname (host);
-        if ( ent ) {
-            memcpy (&addr->sin_addr, ent->h_addr, ent->h_length);
-            addr->sin_family = ent->h_addrtype;
-            debug("resolved: %s (%s)\n",
-                  host, inet_ntoa(addr->sin_addr));
-        } else {
-            debug("failed to resolve locally.\n");
-            return -1;                          /* failed */
-        }
-    }
-    return 0;                                   /* good */
-}
-
-int
-open_connection( const char *host, u_short port )
-{
-    SOCKET s;
-    struct sockaddr_in saddr;
-
-    /* resolve address of proxy or direct target */
-    if (local_resolve (host, &saddr) < 0) {
-        error("can't resolve hostname: %s\n", host);
-        return SOCKET_ERROR;
-    }
-    saddr.sin_port = htons(port);
-
-    debug("connecting to %s:%u\n", inet_ntoa(saddr.sin_addr), port);
-    s = socket( AF_INET, SOCK_STREAM, 0 );
-    if ( connect( s, (struct sockaddr *)&saddr, sizeof(saddr))
-         == SOCKET_ERROR) {
-        debug( "connect() failed.\n");
-        return SOCKET_ERROR;
-    }
-    return s;
-}
-
-void
-report_text( char *prefix, char *buf )
-{
-    static char work[1024];
-    char *tmp;
-
-    if ( !f_debug )
-        return;
-    if ( !f_report )
-        return;                                 /* don't report */
-    debug("%s \"", prefix);
-    while ( *buf ) {
-        memset( work, 0, sizeof(work));
-        tmp = work;
-        while ( *buf && ((tmp-work) < (int)sizeof(work)-5) ) {
-            switch ( *buf ) {
-            case '\t': *tmp++ = '\\'; *tmp++ = 't'; break;
-            case '\r': *tmp++ = '\\'; *tmp++ = 'r'; break;
-            case '\n': *tmp++ = '\\'; *tmp++ = 'n'; break;
-            case '\\': *tmp++ = '\\'; *tmp++ = '\\'; break;
-            default:
-                if ( isprint(*buf) ) {
-                    *tmp++ = *buf;
-                } else {
-		    int consumed = tmp - work;
-                    snprintf( tmp, sizeof(work)-consumed,
-			      "\\x%02X", (unsigned char)*buf);
-                    tmp += strlen(tmp);
-                }
-            }
-            buf++;
-            *tmp = '\0';
-        }
-        debug_("%s", work);
-    }
-
-    debug_("\"\n");
-}
-
-
-void
-report_bytes( char *prefix, char *buf, int len )
-{
-    if ( ! f_debug )
-        return;
-    debug( "%s", prefix );
-    while ( 0 < len ) {
-        fprintf( stderr, " %02x", *(unsigned char *)buf);
-        buf++;
-        len--;
-    }
-    fprintf(stderr, "\n");
-    return;
-}
-
-int
-atomic_out( SOCKET s, char *buf, int size )
-{
-    int ret, len;
-
-    assert( buf != NULL );
-    assert( 0<=size );
-    /* do atomic out */
-    ret = 0;
-    while ( 0 < size ) {
-        len = send( s, buf+ret, size, 0 );
-        if ( len == -1 )
-            fatal("atomic_out() failed to send(), %d\n", socket_errno());
-        ret += len;
-        size -= len;
-    }
-    if (!f_report) {
-        debug("atomic_out()  [some bytes]\n");
-        debug(">>> xx xx xx xx ...\n");
-    } else {
-        debug("atomic_out()  [%d bytes]\n", ret);
-        report_bytes(">>>", buf, ret);
-    }
-    return ret;
-}
-
-int
-atomic_in( SOCKET s, char *buf, int size )
-{
-    int ret, len;
-
-    assert( buf != NULL );
-    assert( 0<=size );
-
-    /* do atomic in */
-    ret = 0;
-    while ( 0 < size ) {
-        len = recv( s, buf+ret, size, 0 );
-        if ( len == -1 ) {
-            fatal("atomic_in() failed to recv(), %d\n", socket_errno());
-        } else if ( len == 0 ) {
-            fatal( "Connection closed by peer.\n");
-        }
-        ret += len;
-        size -= len;
-    }
-    if (!f_report) {
-        debug("atomic_in()  [some bytes]\n");
-        debug("<<< xx xx xx xx ...\n");
-    } else {
-        debug("atomic_in() [%d bytes]\n", ret);
-        report_bytes("<<<", buf, ret);
-    }
-    return ret;
-}
-
-int
-line_input( SOCKET s, char *buf, int size )
-{
-    char *dst = buf;
-    if ( size == 0 )
-        return 0;                               /* no error */
-    size--;
-    while ( 0 < size ) {
-        switch ( recv( s, dst, 1, 0) ) {        /* recv one-by-one */
-        case SOCKET_ERROR:
-            error("recv() error\n");
-            return -1;                          /* error */
-        case 0:
-            size = 0;                           /* end of stream */
-            break;
-        default:
-            /* continue reading until last 1 char is EOL? */
-            if ( *dst == '\n' ) {
-                /* finished */
-                size = 0;
-            } else {
-                /* more... */
-                size--;
-            }
-            dst++;
-        }
-    }
-    *dst = '\0';
-    report_text( "<<<", buf);
-    return 0;
-}
-
-/* cut_token()
-   Span token in given string STR until char in DELIM is appeared.
-   Then replace contiguous DELIMS with '\0' for string termination
-   and returns next pointer.
-   If no next token, return NULL.
-*/
-char *
-cut_token( char *str, char *delim)
-{
-    char *ptr = str + strcspn(str, delim);
-    char *end = ptr + strspn(ptr, delim);
-    if ( ptr == str )
-        return NULL;
-    while ( ptr < end )
-        *ptr++ = '\0';
-    return ptr;
-}
-
-const char *
-lookup(int num, LOOKUP_ITEM *items)
-{
-    int i = 0;
-    while (0 <= items[i].num) {
-        if (items[i].num == num)
-            return items[i].str;
-        i++;
-    }
-    return "(unknown)";
-}
-
-/* readpass()
-   password input routine
-   Use ssh-askpass (same mechanism to OpenSSH)
-*/
-char *
-readpass( const char* prompt, ...)
-{
-    static char buf[1000];                      /* XXX, don't be fix length */
-    va_list args;
-    va_start(args, prompt);
-    vsnprintf(buf, sizeof(buf), prompt, args);
-    va_end(args);
-
-    if ( getparam(ENV_SSH_ASKPASS)
-#if !defined(_WIN32) && !defined(__CYGWIN32__)
-         && getenv("DISPLAY")
-#endif /* not _WIN32 && not __CYGWIN32__ */
-        ) {
-        /* use ssh-askpass to get password */
-        FILE *fp;
-        char *askpass = getparam(ENV_SSH_ASKPASS), *cmd;
-	int cmd_size = strlen(askpass) +1 +1 +strlen(buf) +1 +1;
-        cmd = xmalloc(cmd_size);
-        snprintf(cmd, cmd_size, "%s \"%s\"", askpass, buf);
-        fp = popen(cmd, "r");
-        free(cmd);
-        if ( fp == NULL )
-            return NULL;                        /* fail */
-        buf[0] = '\0';
-        if (fgets(buf, sizeof(buf), fp) == NULL)
-            return NULL;                        /* fail */
-        fclose(fp);
-    } else {
-        tty_readpass( buf, buf, sizeof(buf));
-    }
-    buf[strcspn(buf, "\r\n")] = '\0';
-    return buf;
-}
-
-static int
-socks5_do_auth_userpass( int s )
-{
-    unsigned char buf[1024], *ptr;
-    char *pass = NULL;
-    int len;
-
-    /* do User/Password authentication. */
-    /* This feature requires username and password from
-       command line argument or environment variable,
-       or terminal. */
-    if (relay_user == NULL)
-        fatal("cannot determine user name.\n");
-
-    /* get password from environment variable if exists. */
-    if ((pass=determine_relay_password()) == NULL &&
-        (pass=readpass("Enter SOCKS5 password for %s@%s: ",
-                       relay_user, relay_host)) == NULL)
-        fatal("Cannot get password for user: %s\n", relay_user);
-
-    /* make authentication packet */
-    ptr = buf;
-    PUT_BYTE( ptr++, 1 );                       /* subnegotiation ver.: 1 */
-    len = strlen( relay_user );                 /* ULEN and UNAME */
-    PUT_BYTE( ptr++, len );
-    strcpy( ptr, relay_user );
-    ptr += len;
-    len = strlen( pass );                       /* PLEN and PASSWD */
-    PUT_BYTE( ptr++, strlen(pass));
-    strcpy( ptr, pass );
-    ptr += len;
-    memset (pass, 0, strlen(pass));             /* erase password */
-
-    /* send it and get answer */
-    f_report = 0;
-    atomic_out( s, buf, ptr-buf );
-    f_report = 1;
-    atomic_in( s, buf, 2 );
-
-    /* check status */
-    if ( buf[1] == 0 )
-        return 0;                               /* success */
-    else
-        return -1;                              /* fail */
-}
-
-static const char *
-socks5_getauthname( int auth )
-{
-    switch ( auth ) {
-    case SOCKS5_AUTH_REJECT: return "REJECTED";
-    case SOCKS5_AUTH_NOAUTH: return "NO-AUTH";
-    case SOCKS5_AUTH_GSSAPI: return "GSSAPI";
-    case SOCKS5_AUTH_USERPASS: return "USERPASS";
-    case SOCKS5_AUTH_CHAP: return "CHAP";
-    case SOCKS5_AUTH_EAP: return "EAP";
-    case SOCKS5_AUTH_MAF: return "MAF";
-    default: return "(unknown)";
-    }
-}
-
-typedef struct {
-    char* name;
-    unsigned char auth;
-} AUTH_METHOD_ITEM;
-
-AUTH_METHOD_ITEM socks5_auth_table[] = {
-    { "none", SOCKS5_AUTH_NOAUTH },
-    { "gssapi", SOCKS5_AUTH_GSSAPI },
-    { "userpass", SOCKS5_AUTH_USERPASS },
-    { "chap", SOCKS5_AUTH_CHAP },
-    { NULL, -1 },
-};
-
-int
-socks5_auth_parse_1(char *start, char *end){
-    int i, len;
-    for ( ; *start; start++ )
-        if ( *start != ' ' && *start != '\t') break;
-    for ( end--; end >= start; end-- ) {
-        if ( *end != ' ' && *end != '\t'){
-            end++;
-            break;
-        }
-    }
-    len = end - start;
-    for ( i = 0; socks5_auth_table[i].name != NULL; i++ ){
-        if ( strncmp(start, socks5_auth_table[i].name, len) == 0) {
-            return socks5_auth_table[i].auth;
-        }
-    }
-    fatal("Unknown auth method: %s\n", start);
-    return -1;
-}
-
-int
-socks5_auth_parse(char *start, unsigned char *auth_list, int max_auth){
-    char *end;
-    int i = 0;
-    while ( i < max_auth ) {
-        end = strchr(start, ',');
-        if (*start && end) {
-            auth_list[i++] = socks5_auth_parse_1(start, end);
-            start = ++end;
-        } else {
-            break;
-        }
-    }
-    if ( *start && ( i < max_auth ) ){
-        for( end = start; *end; end++ );
-        auth_list[i++] = socks5_auth_parse_1(start, end);
-    } else {
-        fatal("Too much auth method.\n");
-    }
-    return i;
-}
-
-/* begin SOCKS5 relaying
-   And no authentication is supported.
- */
-int
-begin_socks5_relay( SOCKET s )
-{
-    unsigned char buf[256], *ptr, *env = socks5_auth;
-    unsigned char n_auth = 0; unsigned char auth_list[10], auth_method;
-    int len, auth_result, i;
-
-    debug( "begin_socks_relay()\n");
-
-    /* request authentication */
-    ptr = buf;
-    PUT_BYTE( ptr++, 5);                        /* SOCKS version (5) */
-
-    if ( env == NULL )
-        env = getparam(ENV_SOCKS5_AUTH);
-    if ( env == NULL ) {
-        /* add no-auth authentication */
-        auth_list[n_auth++] = SOCKS5_AUTH_NOAUTH;
-        /* add user/pass authentication */
-        auth_list[n_auth++] = SOCKS5_AUTH_USERPASS;
-    } else {
-        n_auth = socks5_auth_parse(env, auth_list, 10);
-    }
-    PUT_BYTE( ptr++, n_auth);                   /* num auth */
-    for (i=0; i<n_auth; i++) {
-        debug("available auth method[%d] = %s (0x%02x)\n",
-              i, socks5_getauthname(auth_list[i]), auth_list[i]);
-        PUT_BYTE( ptr++, auth_list[i]);         /* authentications */
-    }
-    atomic_out( s, buf, ptr-buf );              /* send requst */
-    atomic_in( s, buf, 2 );                     /* recv response */
-    if ( (buf[0] != 5) ||                       /* ver5 response */
-         (buf[1] == 0xFF) ) {                   /* check auth method */
-        error("No auth method accepted.\n");
-        return -1;
-    }
-    auth_method = buf[1];
-
-    debug("auth method: %s\n", socks5_getauthname(auth_method));
-
-    switch ( auth_method ) {
-    case SOCKS5_AUTH_REJECT:
-        error("No acceptable authentication method\n");
-        return -1;                              /* fail */
-
-    case SOCKS5_AUTH_NOAUTH:
-        /* nothing to do */
-        auth_result = 0;
-        break;
-
-    case SOCKS5_AUTH_USERPASS:
-        auth_result = socks5_do_auth_userpass(s);
-        break;
-
-    default:
-        error("Unsupported authentication method: %s\n",
-              socks5_getauthname( auth_method ));
-        return -1;                              /* fail */
-    }
-    if ( auth_result != 0 ) {
-        error("Authentication failed.\n");
-        return -1;
-    }
-    /* request to connect */
-    ptr = buf;
-    PUT_BYTE( ptr++, 5);                        /* SOCKS version (5) */
-    PUT_BYTE( ptr++, 1);                        /* CMD: CONNECT */
-    PUT_BYTE( ptr++, 0);                        /* FLG: 0 */
-    if ( dest_addr.sin_addr.s_addr == 0 ) {
-        /* resolved by SOCKS server */
-        PUT_BYTE( ptr++, 3);                    /* ATYP: DOMAINNAME */
-        len = strlen(dest_host);
-        PUT_BYTE( ptr++, len);                  /* DST.ADDR (len) */
-        memcpy( ptr, dest_host, len );          /* (hostname) */
-        ptr += len;
-    } else {
-        /* resolved localy */
-        PUT_BYTE( ptr++, 1 );                   /* ATYP: IPv4 */
-        memcpy( ptr, &dest_addr.sin_addr.s_addr, sizeof(dest_addr.sin_addr));
-        ptr += sizeof(dest_addr.sin_addr);
-    }
-    PUT_BYTE( ptr++, dest_port>>8);     /* DST.PORT */
-    PUT_BYTE( ptr++, dest_port&0xFF);
-    atomic_out( s, buf, ptr-buf);               /* send request */
-    atomic_in( s, buf, 4 );                     /* recv response */
-    if ( (buf[1] != SOCKS5_REP_SUCCEEDED) ) {   /* check reply code */
-        error("Got error response from SOCKS server: %d (%s).\n",
-              buf[1], lookup(buf[1], socks5_rep_names));
-        return -1;
-    }
-    ptr = buf + 4;
-    switch ( buf[3] ) {                         /* case by ATYP */
-    case 1:                                     /* IP v4 ADDR*/
-        atomic_in( s, ptr, 4+2 );               /* recv IPv4 addr and port */
-        break;
-    case 3:                                     /* DOMAINNAME */
-        atomic_in( s, ptr, 1 );                 /* recv name and port */
-        atomic_in( s, ptr+1, *(unsigned char*)ptr + 2);
-        break;
-    case 4:                                     /* IP v6 ADDR */
-        atomic_in( s, ptr, 16+2 );              /* recv IPv6 addr and port */
-        break;
-    }
-
-    /* Conguraturation, connected via SOCKS5 server! */
-    return 0;
-}
-
-/* begin SOCKS protocol 4 relaying
-   And no authentication is supported.
-
-   There's SOCKS protocol version 4 and 4a. Protocol version
-   4a has capability to resolve hostname by SOCKS server, so
-   we don't need resolving IP address of destination host on
-   local machine.
-
-   Environment variable SOCKS_RESOLVE directs how to resolve
-   IP addess. There's 3 keywords allowed; "local", "remote"
-   and "both" (case insensitive). Keyword "local" means taht
-   target host name is resolved by localhost resolver
-   (usualy with gethostbyname()), "remote" means by remote
-   SOCKS server, "both" means to try resolving by localhost
-   then remote.
-
-   SOCKS4 protocol and authentication of SOCKS5 protocol
-   requires user name on connect request.
-   User name is determined by following method.
-
-   1. If server spec has user at hostname:port format then
-      user part is used for this SOCKS server.
-
-   2. Get user name from environment variable LOGNAME, USER
-      (in this order).
-
-*/
-int
-begin_socks4_relay( SOCKET s )
-{
-    unsigned char buf[256], *ptr;
-
-    debug( "begin_socks_relay()\n");
-
-    /* make connect request packet
-       protocol v4:
-         VN:1, CD:1, PORT:2, ADDR:4, USER:n, NULL:1
-       protocol v4a:
-         VN:1, CD:1, PORT:2, DUMMY:4, USER:n, NULL:1, HOSTNAME:n, NULL:1
-    */
-    ptr = buf;
-    PUT_BYTE( ptr++, 4);                        /* protocol version (4) */
-    PUT_BYTE( ptr++, 1);                        /* CONNECT command */
-    PUT_BYTE( ptr++, dest_port>>8);     /* destination Port */
-    PUT_BYTE( ptr++, dest_port&0xFF);
-    /* destination IP */
-    memcpy(ptr, &dest_addr.sin_addr, sizeof(dest_addr.sin_addr));
-    ptr += sizeof(dest_addr.sin_addr);
-    if ( dest_addr.sin_addr.s_addr == 0 )
-        *(ptr-1) = 1;                           /* fake, protocol 4a */
-    /* username */
-    if (relay_user == NULL)
-        fatal( "Cannot determine user name.\n");
-    strcpy( ptr, relay_user );
-    ptr += strlen( relay_user ) +1;
-    /* destination host name (for protocol 4a) */
-    if ( (socks_version == 4) && (dest_addr.sin_addr.s_addr == 0)) {
-        strcpy( ptr, dest_host );
-        ptr += strlen( dest_host ) +1;
-    }
-    /* send command and get response
-       response is: VN:1, CD:1, PORT:2, ADDR:4 */
-    atomic_out( s, buf, ptr-buf);               /* send request */
-    atomic_in( s, buf, 8 );                     /* recv response */
-    if ( (buf[1] != SOCKS4_REP_SUCCEEDED) ) {   /* check reply code */
-        error("Got error response: %d: '%s'.\n",
-              buf[1], lookup(buf[1], socks4_rep_names));
-        return -1;                              /* failed */
-    }
-
-    /* Conguraturation, connected via SOCKS4 server! */
-    return 0;
-}
-
-int
-sendf(SOCKET s, const char *fmt,...)
-{
-    static char buf[10240];                     /* xxx, enough? */
-
-    va_list args;
-    va_start( args, fmt );
-    vsnprintf( buf, sizeof(buf), fmt, args );
-    va_end( args );
-
-    report_text(">>>", buf);
-    if ( send(s, buf, strlen(buf), 0) == SOCKET_ERROR ) {
-        debug("failed to send http request. errno=%d\n", socket_errno());
-        return -1;
-    }
-    return 0;
-}
-
-const char *base64_table =
-"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-char *
-make_base64_string(const char *str)
-{
-    static char *buf;
-    unsigned char *src;
-    char *dst;
-    int bits, data, src_len, dst_len;
-    /* make base64 string */
-    src_len = strlen(str);
-    dst_len = (src_len+2)/3*4;
-    buf = xmalloc(dst_len+1);
-    bits = data = 0;
-    src = (unsigned char *)str;
-    dst = (unsigned char *)buf;
-    while ( dst_len-- ) {
-        if ( bits < 6 ) {
-            data = (data << 8) | *src;
-            bits += 8;
-            if ( *src != 0 )
-                src++;
-        }
-        *dst++ = base64_table[0x3F & (data >> (bits-6))];
-        bits -= 6;
-    }
-    *dst = '\0';
-    /* fix-up tail padding */
-    switch ( src_len%3 ) {
-    case 1:
-        *--dst = '=';
-    case 2:
-        *--dst = '=';
-    }
-    return buf;
-}
-
-
-int
-basic_auth (SOCKET s)
-{
-    char *userpass;
-    char *cred;
-    const char *user = relay_user;
-    char *pass = NULL;
-    int len, ret;
-
-    /* Get username/password for authentication */
-    if (user == NULL)
-        fatal("Cannot decide username for proxy authentication.");
-    if ((pass = determine_relay_password ()) == NULL &&
-        (pass = readpass("Enter proxy authentication password for %s@%s: ",
-                         relay_user, relay_host)) == NULL)
-        fatal("Cannot decide password for proxy authentication.");
-
-    len = strlen(user)+strlen(pass)+1;
-    userpass = xmalloc(len+1);
-    snprintf(userpass, len+1, "%s:%s", user, pass);
-    memset (pass, 0, strlen(pass));
-    cred = make_base64_string(userpass);
-    memset (userpass, 0, len);
-
-    f_report = 0;                               /* don't report for security */
-    ret = sendf(s, "Proxy-Authorization: Basic %s\r\n", cred);
-    f_report = 1;
-    report_text(">>>", "Proxy-Authorization: Basic xxxxx\r\n");
-
-    memset(cred, 0, strlen(cred));
-    free(cred);
-
-    return ret;
-}
-
-/* begin relaying via HTTP proxy
-   Directs CONNECT method to proxy server to connect to
-   destination host (and port). It may not be allowed on your
-   proxy server.
- */
-int
-begin_http_relay( SOCKET s )
-{
-    char buf[1024];
-    int result;
-    char *auth_what;
-
-    debug("begin_http_relay()\n");
-
-    if (sendf(s,"CONNECT %s:%d HTTP/1.0\r\n", dest_host, dest_port) < 0)
-        return START_ERROR;
-    if (proxy_auth_type == PROXY_AUTH_BASIC && basic_auth (s) < 0)
-        return START_ERROR;
-    if (sendf(s,"\r\n") < 0)
-        return START_ERROR;
-
-    /* get response */
-    if ( line_input(s, buf, sizeof(buf)) < 0 ) {
-        debug("failed to read http response.\n");
-        return START_ERROR;
-    }
-
-    /* check status */
-    if (!strchr(buf, ' ')) {
-	error ("Unexpected http response: '%s'.\n", buf);
-	return START_ERROR;
-    }
-    result = atoi(strchr(buf,' '));
-
-    switch ( result ) {
-    case 200:
-        /* Conguraturation, connected via http proxy server! */
-        debug("connected, start user session.\n");
-        break;
-    case 302:                                   /* redirect */
-        do {
-            if (line_input(s, buf, sizeof(buf)))
-                break;
-            downcase(buf);
-            if (expect(buf, "Location: ")) {
-                relay_host = cut_token(buf, "//");
-                cut_token(buf, "/");
-                relay_port = atoi(cut_token(buf, ":"));
-            }
-        } while (strcmp(buf,"\r\n") != 0);
-        return START_RETRY;
-
-    /* We handle both 401 and 407 codes here: 401 is WWW-Authenticate, which
-     * not strictly the correct response, but some proxies do send this (e.g.
-     * Symantec's Raptor firewall) */
-    case 401:                                   /* WWW-Auth required */
-    case 407:                                   /* Proxy-Auth required */
-        /** NOTE: As easy implementation, we support only BASIC scheme
-            and ignore realm. */
-        /* If proxy_auth_type is PROXY_AUTH_BASIC and get
-         this result code, authentication was failed. */
-        if (proxy_auth_type != PROXY_AUTH_NONE) {
-            error("Authentication failed.\n");
-            return START_ERROR;
-        }
-        auth_what = (result == 401) ? "WWW-Authenticate:" : "Proxy-Authenticate:";
-        do {
-            if ( line_input(s, buf, sizeof(buf)) ) {
-                break;
-            }
-            downcase(buf);
-            if (expect(buf, auth_what)) {
-                /* parse type and realm */
-                char *scheme, *realm;
-                scheme = cut_token(buf, " ");
-                realm = cut_token(scheme, " ");
-                if ( scheme == NULL || realm == NULL ) {
-                    debug("Invalid format of %s field.", auth_what);
-                    return START_ERROR;         /* fail */
-                }
-                /* check supported auth type */
-                if (expect(scheme, "basic")) {
-                    proxy_auth_type = PROXY_AUTH_BASIC;
-                } else {
-                    debug("Unsupported authentication type: %s", scheme);
-                }
-            }
-        } while (strcmp(buf,"\r\n") != 0);
-        if ( proxy_auth_type == PROXY_AUTH_NONE ) {
-            debug("Can't find %s in response header.", auth_what);
-            return START_ERROR;
-        } else {
-            return START_RETRY;
-        }
-
-    default:
-        /* Not allowed */
-        debug("http proxy is not allowed.\n");
-        return START_ERROR;
-    }
-    /* skip to end of response header */
-    do {
-        if ( line_input(s, buf, sizeof(buf) ) ) {
-            debug("Can't skip response headers\n");
-            return START_ERROR;
-        }
-    } while ( strcmp(buf,"\r\n") != 0 );
-
-    return START_OK;
-}
-
-/* begin relaying via TELNET proxy.
-   Sends string specified by telnet_command (-c option) with
-   replacing host name and port number to the socket.  */
-int
-begin_telnet_relay( SOCKET s )
-{
-    char buf[1024];
-    char *cmd;
-    char *good_phrase = "connected to";
-    char *bad_phrase_list[] = {
-	" failed", " refused", " rejected", " closed"
-    };
-    char sep = ' ';
-    int i;
-
-    debug("begin_telnet_relay()\n");
-
-    /* report phrase */
-    debug("good phrase: '%s'\n", good_phrase);
-    debug("bad phrases");
-    sep = ':';
-    for (i=0; i< (sizeof(bad_phrase_list) / sizeof(char*)); i++) {
-	debug_("%c '%s'", sep, bad_phrase_list[i]);
-	sep = ',';
-    }
-    debug_("\n");
-
-    /* make request string with replacing %h by destination hostname
-       and %p by port number, etc. */
-    cmd = expand_host_and_port(telnet_command, dest_host, dest_port);
-    
-    /* Sorry, we send request string now without waiting a prompt. */
-    if (sendf(s, "%s\r\n", cmd) < 0) {
-	free(cmd);
-        return START_ERROR;
-    }
-    free(cmd);
-
-    /* Process answer from proxy until good or bad phrase is detected.  We
-       assume that the good phrase should be appeared only in the final
-       line of proxy responses. Bad keywods in the line causes operation
-       fail. First checks a good phrase, then checks bad phrases.
-       If no match, continue reading line from proxy. */
-    while (!line_input(s, buf, sizeof(buf)) && buf[0] != '\0') {
-	downcase(buf);
-	/* first, check good phrase */
-        if (strstr(buf, good_phrase)) {
-	    debug("good phrase is detected: '%s'\n", good_phrase);
-            return START_OK;
-        }
-	/* then, check bad phrase */
-	for (i=0; i<(sizeof(bad_phrase_list)/sizeof(char*)); i++) {
-	    if (strstr(buf, bad_phrase_list[i]) != NULL) {
-		debug("bad phrase is detected: '%s'\n", bad_phrase_list[i]);
-		return START_ERROR;
-	    }
-        }
-    }
-    debug("error reading from telnet proxy\n");
-
-    return START_ERROR;
-}
-
-
-#ifdef _WIN32
-/* ddatalen()
-   Returns 1 if data is available, otherwise return 0
- */
-int
-stdindatalen (void)
-{
-    DWORD len = 0;
-    struct stat st;
-    fstat( 0, &st );
-    if ( st.st_mode & _S_IFIFO ) {
-        /* in case of PIPE */
-        if ( !PeekNamedPipe( GetStdHandle(STD_INPUT_HANDLE),
-                             NULL, 0, NULL, &len, NULL) ) {
-            if ( GetLastError() == ERROR_BROKEN_PIPE ) {
-                /* PIPE source is closed */
-                /* read() will detects EOF */
-                len = 1;
-            } else {
-                fatal("PeekNamedPipe() failed, errno=%d\n",
-                      GetLastError());
-            }
-        }
-    } else if ( st.st_mode & _S_IFREG ) {
-        /* in case of regular file (redirected) */
-        len = 1;                        /* always data ready */
-    } else if ( _kbhit() ) {
-        /* in case of console */
-        len = 1;
-    }
-    return len;
-}
-#endif /* _WIN32 */
-
-/* relay byte from stdin to socket and fro socket to stdout.
-   returns reason of termination */
-int
-do_repeater( SOCKET local_in, SOCKET local_out, SOCKET remote )
-{
-    /** vars for local input data **/
-    char lbuf[1024];                            /* local input buffer */
-    int lbuf_len;                               /* available data in lbuf */
-    int f_local;                                /* read local input more? */
-    /** vars for remote input data **/
-    char rbuf[1024];                            /* remote input buffer */
-    int rbuf_len;                               /* available data in rbuf */
-    int f_remote;                               /* read remote input more? */
-    int close_reason = REASON_UNK;              /* reason of end repeating */
-    /** other variables **/
-    int nfds, len;
-    fd_set ifds, ofds;
-    struct timeval *tmo;
-#ifdef _WIN32
-    struct timeval win32_tmo;
-#endif /* _WIN32 */
-
-    /* repeater between stdin/out and socket  */
-    nfds = ((local_in<remote)? remote: local_in) +1;
-    f_local = 1;                                /* yes, read from local */
-    f_remote = 1;                               /* yes, read from remote */
-    lbuf_len = 0;
-    rbuf_len = 0;
-
-    while ( f_local || f_remote ) {
-        FD_ZERO(&ifds );
-        FD_ZERO(&ofds );
-        tmo = NULL;
-
-        /** prepare for reading local input **/
-        if ( f_local && (lbuf_len < (int)sizeof(lbuf)) ) {
-#ifdef _WIN32
-            if ( local_type != LOCAL_SOCKET ) {
-                /* select() on Winsock is not accept standard handle.
-                   So use select() with short timeout and checking data
-                   in stdin by another method. */
-                win32_tmo.tv_sec = 0;
-                win32_tmo.tv_usec = 10*1000;    /* 10 ms */
-                tmo = &win32_tmo;
-            } else
-#endif /* !_WIN32 */
-            FD_SET( local_in, &ifds );
-        }
-
-        /** prepare for reading remote input **/
-        if ( f_remote && (rbuf_len < (int)sizeof(rbuf)) ) {
-            FD_SET( remote, &ifds );
-        }
-
-        /* FD_SET( local_out, ofds ); */
-        /* FD_SET( remote, ofds ); */
-
-        if ( select( nfds, &ifds, &ofds, (fd_set*)NULL, tmo ) == -1 ) {
-            /* some error */
-            error( "select() failed, %d\n", socket_errno());
-            return REASON_ERROR;
-        }
-#ifdef _WIN32
-        /* fake ifds if local is stdio handle because
-           select() of Winsock does not accept stdio
-           handle. */
-        if (f_local && (local_type!=LOCAL_SOCKET) && (0<stdindatalen()))
-            FD_SET(0,&ifds);            /* data ready */
-#endif
-
-        /* remote => local */
-        if ( FD_ISSET(remote, &ifds) && (rbuf_len < (int)sizeof(rbuf)) ) {
-            len = recv( remote, rbuf + rbuf_len, sizeof(rbuf)-rbuf_len, 0);
-            if ( len == 0 || (len == -1 && socket_errno() == ECONNRESET)) {
-                debug("connection %s by peer\n",
-                      (len==0)? "closed": "reset");
-                close_reason = REASON_CLOSED_BY_REMOTE;
-                f_remote = 0;                   /* no more read from socket */
-                f_local = 0;
-            } else if ( len == -1 ) {
-                /* error */
-                fatal("recv() failed, %d\n", socket_errno());
-            } else {
-                debug("recv %d bytes\n", len);
-                if ( 1 < f_debug )              /* more verbose */
-                    report_bytes( "<<<", rbuf+rbuf_len, len);
-                rbuf_len += len;
-            }
-        }
-
-        /* local => remote */
-        if ( FD_ISSET(local_in, &ifds) && (lbuf_len < (int)sizeof(lbuf)) ) {
-            if (local_type == LOCAL_SOCKET)
-                len = recv(local_in, lbuf + lbuf_len,
-                           sizeof(lbuf)-lbuf_len, 0);
-            else
-                len = read(local_in, lbuf + lbuf_len, sizeof(lbuf)-lbuf_len);
-            if ( len == 0 ) {
-                /* stdin is EOF */
-                debug("local input is EOF\n");
-                if (!f_hold_session)
-                    shutdown(remote, 1);        /* no-more writing */
-                f_local = 0;
-                close_reason = REASON_CLOSED_BY_LOCAL;
-            } else if ( len == -1 ) {
-                /* error on reading from stdin */
-                if (f_hold_session) {
-                    debug ("failed to read from local\n");
-                    f_local = 0;
-                    close_reason = REASON_CLOSED_BY_LOCAL;
-                } else
-                    fatal("recv() failed, errno = %d\n", errno);
-            } else {
-                /* repeat */
-                lbuf_len += len;
-            }
-        }
-
-        /* flush data in buffer to socket */
-        if ( 0 < lbuf_len ) {
-            len = send(remote, lbuf, lbuf_len, 0);
-            if ( len == -1 ) {
-                fatal("send() failed, %d\n", socket_errno());
-            } else if ( 0 < len ) {
-                if ( 1 < f_debug )              /* more verbose */
-                    report_bytes( ">>>", lbuf, len);
-                /* move data on to top of buffer */
-                debug("sent %d bytes\n", len);
-                lbuf_len -= len;
-                if ( 0 < lbuf_len )
-                    memcpy( lbuf, lbuf+len, lbuf_len );
-                assert( 0 <= lbuf_len );
-            }
-        }
-
-        /* flush data in buffer to local output */
-        if ( 0 < rbuf_len ) {
-            if (local_type == LOCAL_SOCKET)
-                len = send( local_out, rbuf, rbuf_len, 0);
-            else
-                len = write( local_out, rbuf, rbuf_len);
-            if ( len == -1 ) {
-                fatal("output (local) failed, errno=%d\n", errno);
-            }
-            rbuf_len -= len;
-            if ( len < rbuf_len )
-                memcpy( rbuf, rbuf+len, rbuf_len );
-            assert( 0 <= rbuf_len );
-        }
-        if (f_local == 0 && f_hold_session) {
-            debug ("closing local port without disconnecting from remote\n");
-            f_remote = 0;
-            shutdown (local_out, 2);
-            close (local_out);
-            break;
-        }
-    }
-
-    return close_reason;
-}
-
-int
-accept_connection (u_short port)
-{
-    static int sock = -1;
-    int connection;
-    struct sockaddr_in name;
-    struct sockaddr client;
-    int socklen;
-    fd_set ifds;
-    int nfds;
-    int sockopt;
-
-    /* Create the socket. */
-    debug("Creating source port to forward.\n");
-    sock = socket (PF_INET, SOCK_STREAM, 0);
-    if (sock < 0)
-        fatal("socket() failed, errno=%d\n", socket_errno());
-    sockopt = 1;
-    setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
-                (void*)&sockopt, sizeof(sockopt));
-
-    /* Give the socket a name. */
-    name.sin_family = AF_INET;
-    name.sin_port = htons (port);
-    name.sin_addr.s_addr = htonl (INADDR_ANY);
-    if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
-        fatal ("bind() failed, errno=%d\n", socket_errno());
-
-    if (listen( sock, 1) < 0)
-        fatal ("listen() failed, errno=%d\n", socket_errno());
-
-    /* wait for new connection with watching EOF of stdin. */
-    debug ("waiting new connection at port %d (socket=%d)\n", port, sock);
-    nfds = sock + 1;
-    do {
-        int n;
-        struct timeval *ptmo = NULL;
-#ifdef _WIN32
-        struct timeval tmo;
-        tmo.tv_sec = 0;
-        tmo.tv_usec = 100*1000;                 /* On Windows, 100ms timeout */
-        ptmo = &tmo;
-#endif /* _WIN32 */
-        FD_ZERO (&ifds);
-        FD_SET ((SOCKET)sock, &ifds);
-#ifndef _WIN32
-        FD_SET (0, &ifds);                      /* watch stdin */
-#endif
-        n = select (nfds, &ifds, NULL, NULL, ptmo);
-        if (n == -1) {
-            fatal ("select() failed, %d\n", socket_errno());
-            exit (1);
-        }
-#ifdef _WIN32
-        if (0 < stdindatalen()) {
-            FD_SET (0, &ifds);          /* fake */
-            n++;
-        }
-#endif
-        if (0 < n) {
-            if (FD_ISSET(0, &ifds) && (getchar() <= 0)) {
-                /* EOF */
-                debug ("Give-up waiting port because stdin is closed.");
-                exit(0);
-            }
-            if (FD_ISSET(sock, &ifds))
-                break;                          /* socket is stimulated */
-        }
-    } while (1);
-    socklen = sizeof(client);
-    connection = accept( sock, &client, &socklen);
-    if ( connection < 0 )
-        fatal ("accept() failed, errno=%d\n", socket_errno());
-    return connection;
-}
-
-
-
-/** Main of program **/
-int
-main( int argc, char **argv )
-{
-    int ret;
-    int remote;                                 /* socket */
-    int local_in;                               /* Local input */
-    int local_out;                              /* Local output */
-    int reason;
-#ifdef _WIN32
-    WSADATA wsadata;
-    WSAStartup( 0x101, &wsadata);
-#endif /* _WIN32 */
-
-    /* initialization */
-    make_revstr();
-    getarg( argc, argv );
-    debug("Program is $Revision: 100 $\n");
-
-    /* Open local_in and local_out if forwarding a port */
-    if ( local_type == LOCAL_SOCKET ) {
-        /* Relay between local port and destination */
-        local_in = local_out = accept_connection( local_port );
-    } else {
-        /* Relay between stdin/stdout and desteination */
-        local_in = 0;
-        local_out = 1;
-#ifdef _WIN32
-        _setmode(local_in, O_BINARY);
-        _setmode(local_out, O_BINARY);
-#endif
-    }
-
-retry:
-#ifndef _WIN32
-    if (0 < connect_timeout)
-        set_timeout (connect_timeout);
-#endif /* not _WIN32 */
-
-    if (check_direct(dest_host))
-        relay_method = METHOD_DIRECT;
-    /* make connection */
-    if ( relay_method == METHOD_DIRECT ) {
-        remote = open_connection (dest_host, dest_port);
-        if ( remote == SOCKET_ERROR )
-            fatal( "Unable to connect to destination host, errno=%d\n",
-                   socket_errno());
-    } else {
-        remote = open_connection (relay_host, relay_port);
-        if ( remote == SOCKET_ERROR )
-            fatal( "Unable to connect to relay host, errno=%d\n",
-                   socket_errno());
-    }
-
-    /** resolve destination host (SOCKS) **/
-#if !defined(_WIN32) && !defined(__CYGWIN32__)
-    if (socks_ns.sin_addr.s_addr != 0)
-        switch_ns (&socks_ns);
-#endif /* not _WIN32 && not __CYGWIN32__ */
-    if (relay_method == METHOD_SOCKS &&
-        socks_resolve == RESOLVE_LOCAL &&
-        local_resolve (dest_host, &dest_addr) < 0) {
-        fatal("Unknown host: %s", dest_host);
-    }
-
-    /** relay negociation **/
-    switch ( relay_method ) {
-    case METHOD_SOCKS:
-        if ( ((socks_version == 5) && (begin_socks5_relay(remote) < 0)) ||
-             ((socks_version == 4) && (begin_socks4_relay(remote) < 0)) )
-            fatal( "failed to begin relaying via SOCKS.\n");
-        break;
-
-    case METHOD_HTTP:
-        ret = begin_http_relay(remote);
-        switch (ret) {
-        case START_ERROR:
-            close (remote);
-            fatal("failed to begin relaying via HTTP.\n");
-        case START_OK:
-            break;
-        case START_RETRY:
-            /* retry with authentication */
-            close (remote);
-            goto retry;
-        }
-        break;
-    case METHOD_TELNET:
-        if (begin_telnet_relay(remote) < 0)
-             fatal("failed to begin relaying via telnet.\n");
-        break;
-    }
-    debug("connected\n");
-
-#ifndef _WIN32
-    if (0 < connect_timeout)
-        set_timeout (0);
-#endif /* not _WIN32 */
-
-    /* main loop */
-    debug ("start relaying.\n");
-do_repeater:
-    reason = do_repeater(local_in, local_out, remote);
-    debug ("relaying done.\n");
-    if (local_type == LOCAL_SOCKET &&
-        reason == REASON_CLOSED_BY_LOCAL &&
-        f_hold_session) {
-        /* re-wait at local port without closing remote session */
-        debug ("re-waiting at local port %d\n", local_port);
-        local_in = local_out = accept_connection( local_port );
-        debug ("re-start relaying\n");
-        goto do_repeater;
-    }
-    closesocket(remote);
-    if ( local_type == LOCAL_SOCKET)
-        closesocket(local_in);
-#ifdef _WIN32
-    WSACleanup();
-#endif /* _WIN32 */
-    debug ("that's all, bye.\n");
-
-    return 0;
-}
-
-/* ------------------------------------------------------------
-   Local Variables:
-   compile-command: "cc connect.c -o connect"
-   tab-width: 8
-   fill-column: 74
-   comment-column: 48
-   End:
-   ------------------------------------------------------------ */
-
-/*** end of connect.c ***/
-- 
1.7.5.4





More information about the Openembedded-core mailing list