--- libircclient-1.2.orig/Makefile.am
+++ libircclient-1.2/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = src examples
--- libircclient-1.2.orig/configure.in
+++ libircclient-1.2/configure.in
@@ -2,10 +2,13 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.52)
-AC_INIT(libircclient, 1.2, tim@krasnogorsk.ru)
+AC_INIT(src/libircclient.c)
+AM_INIT_AUTOMAKE(libircclient, 1.2)
 AC_CONFIG_SRCDIR([include/libircclient.h])
 AC_CONFIG_HEADER([include/config.h])
 
+LT_INIT
+
 # Check for command-line
 AC_ARG_ENABLE(enable_debug,
 	[  --enable-debug         compile with debug information (no)])
@@ -16,8 +19,6 @@
 # Checks for programs.
 AC_PROG_CXX
 AC_PROG_CC
-AC_CHECK_TOOL(AR, ar, :)
-AC_PROG_RANLIB
 
 # Checks for header files.
 AC_HEADER_STDC
@@ -50,5 +51,5 @@
 AC_SUBST(CFLAGS)
 AC_SUBST(LIBS)
 AC_SUBST(PREFIX)
-AC_CONFIG_FILES([examples/Makefile src/Makefile])
+AC_CONFIG_FILES([Makefile src/Makefile examples/Makefile examples/ircmud/Makefile])
 AC_OUTPUT
--- libircclient-1.2.orig/src/sockets.c
+++ libircclient-1.2/src/sockets.c
@@ -59,7 +59,7 @@
 
 static int socket_create (int domain, int type, socket_t * sock)
 {
-	*sock = socket (PF_INET, SOCK_STREAM, 0);
+	*sock = socket (domain, SOCK_STREAM, 0);
 	return IS_SOCKET_ERROR(*sock) ? 1 : 0;
 }
 
--- libircclient-1.2.orig/src/dcc.c
+++ libircclient-1.2/src/dcc.c
@@ -519,20 +519,19 @@
 	if ( libirc_mutex_init (&dcc->mutex_outbuf) )
 		goto cleanup_exit_error;
 
-	if ( socket_create (PF_INET, SOCK_STREAM, &dcc->sock) )
+	if ( socket_create (session->local_addr.ss_family, SOCK_STREAM, &dcc->sock) )
 		goto cleanup_exit_error;
 
 	if ( !ip )
 	{
-		struct sockaddr_in saddr;
+		struct sockaddr_storage saddr;
 		unsigned long arg = 1;
 
 		setsockopt (dcc->sock, SOL_SOCKET, SO_REUSEADDR, (char*)&arg, sizeof(arg));
 
 		memset (&saddr, 0, sizeof(saddr));
-		saddr.sin_family = AF_INET;
-		memcpy (&saddr.sin_addr, &session->local_addr, sizeof(session->local_addr));
-        saddr.sin_port = htons (0);
+		memcpy (&saddr, &session->local_addr, sizeof(session->local_addr));
+		((struct sockaddr_in *)&saddr)->sin_port = htons (0);
 
 		if ( bind (dcc->sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0 )
 			goto cleanup_exit_error;
--- libircclient-1.2.orig/src/libircclient.c
+++ libircclient-1.2/src/libircclient.c
@@ -91,6 +91,14 @@
 	free (session);
 }
 
+void irc_set_local_addr (irc_session_t * session, const char * local_addr)
+{
+	struct addrinfo hints = { 0 };
+
+	if (getaddrinfo(local_addr, NULL, &hints, &session->local_addrs) != 0) {
+		session->local_addrs = NULL;
+	}
+}
 
 int irc_connect (irc_session_t * session,
 			const char * server, 
@@ -100,7 +108,11 @@
 			const char * username,
 			const char * realname)
 {
-	struct sockaddr_in saddr;
+	struct addrinfo *addrs;
+	struct addrinfo *iter = NULL;
+	struct addrinfo *liter = NULL;
+	struct addrinfo hints = { 0 };
+	char sport[6];
 
 	// Check and copy all the specified fields
 	if ( !server || !nick )
@@ -127,48 +139,52 @@
 	session->nick = strdup (nick);
 	session->server = strdup (server);
 
-	memset (&saddr, 0, sizeof(saddr));
-	saddr.sin_family = AF_INET;
-	saddr.sin_port = htons (port);
-	saddr.sin_addr.s_addr = inet_addr (server);
+	snprintf(sport, 6, "%hd", port);
 
-    if ( saddr.sin_addr.s_addr == INADDR_NONE )
-    {
-		struct hostent *hp;
-#if defined HAVE_GETHOSTBYNAME_R
-		int tmp_errno;
-		struct hostent tmp_hostent;
-		char buf[2048];
-
-      	if ( gethostbyname_r (server, &tmp_hostent, buf, sizeof(buf), &hp, &tmp_errno) )
-      		hp = 0;
-#else
-      	hp = gethostbyname (server);
-#endif
-		if ( !hp )
-		{
-			session->lasterror = LIBIRC_ERR_RESOLV;
-			return 1;
-		}
+	if ( getaddrinfo(server, sport, &hints, &addrs) != 0 )
+	{
+		session->lasterror = LIBIRC_ERR_RESOLV;
+		return 1;
+	}
 
-		memcpy (&saddr.sin_addr, hp->h_addr, (size_t) hp->h_length);
-    }
+	if ( session->local_addrs )
+	{
+		for (liter = session->local_addrs; liter; liter = liter->ai_next) {
+			for (iter = addrs; iter; iter = iter->ai_next) {
+				if (iter->ai_family == liter->ai_family)
+					break;
+			}
+			if (iter) break;
+		}
+	}
+	if ( iter == NULL ) {
+		iter = addrs;
+		liter = NULL;
+	}
 
     // create the IRC server socket
-	if ( socket_create (PF_INET, SOCK_STREAM, &session->sock)
+	if ( socket_create (iter->ai_family, SOCK_STREAM, &session->sock)
 	|| socket_make_nonblocking (&session->sock) )
 	{
+		freeaddrinfo(addrs);
 		session->lasterror = LIBIRC_ERR_SOCKET;
 		return 1;
 	}
 
+	if ( liter )
+	{
+		bind (session->sock, (struct sockaddr *)liter->ai_addr, liter->ai_addrlen);
+	}
+
     // and connect to the IRC server
-    if ( socket_connect (&session->sock, (struct sockaddr *) &saddr, sizeof(saddr)) )
+    if ( socket_connect (&session->sock, (struct sockaddr *) iter->ai_addr, iter->ai_addrlen) )
     {
+	    freeaddrinfo(addrs);
     	session->lasterror = LIBIRC_ERR_CONNECT;
 		return 1;
     }
 
+    freeaddrinfo(addrs);
     session->state = LIBIRC_STATE_CONNECTING;
     session->motd_received = 0; // reset in case of reconnect
 	return 0;
@@ -192,20 +208,16 @@
 
 	while ( irc_is_connected(session) )
 	{
-		struct timeval tv;
 		fd_set in_set, out_set;
 		int maxfd = 0;
 
-		tv.tv_usec = 250000;
-		tv.tv_sec = 0;
-
 		// Init sets
 		FD_ZERO (&in_set);
 		FD_ZERO (&out_set);
 
 		irc_add_select_descriptors (session, &in_set, &out_set, &maxfd);
 
-		if ( select (maxfd + 1, &in_set, &out_set, 0, &tv) < 0 )
+		if ( select (maxfd + 1, &in_set, &out_set, 0, NULL) < 0 )
 		{
 			if ( socket_error() == EINTR )
 				continue;
@@ -567,7 +579,7 @@
 	{
 		// Now we have to determine whether the socket is connected 
 		// or the connect is failed
-		struct sockaddr_in saddr, laddr;
+		struct sockaddr_storage saddr, laddr;
 		socklen_t slen = sizeof(saddr);
 		socklen_t llen = sizeof(laddr);
 
@@ -580,12 +592,7 @@
 			return 1;
 		}
 
-		memcpy (&session->local_addr, &laddr.sin_addr, sizeof(session->local_addr));
-
-#if defined (ENABLE_DEBUG)
-		if ( IS_DEBUG_ENABLED(session) )
-			fprintf (stderr, "[DEBUG] Detected local address: %s\n", inet_ntoa(session->local_addr));
-#endif
+		memcpy (&session->local_addr, &laddr, sizeof(laddr));
 
 		session->state = LIBIRC_STATE_CONNECTED;
 
--- libircclient-1.2.orig/include/libircclient.h
+++ libircclient-1.2/include/libircclient.h
@@ -125,9 +125,9 @@
 
 
 #define IN_INCLUDE_LIBIRC_H
-#include "libirc_errors.h"
-#include "libirc_events.h"
-#include "libirc_options.h"
+#include <libirc_errors.h>
+#include <libirc_events.h>
+#include <libirc_options.h>
 
 #if defined (IN_BUILDING_LIBIRC)
 	#include "libirc_session.h"
@@ -182,6 +182,17 @@
  */
 void irc_destroy_session (irc_session_t * session);
 
+/*!
+ * \fn void irc_set_local_addr (irc_session_t * session, const char * local_addr)
+ * \brief Sets the local address for the session.
+ *
+ * \param session A session to set the address for. Must not be NULL.
+ * \param local_addr String representation of the local address. Must not be NULL.
+ *
+ * This function can be used to set the local address to use for an irc session.
+ * Must be called before irc_connect to have effect.
+ */
+void irc_set_local_addr (irc_session_t * session, const char * local_addr);
 
 /*!
  * \fn int irc_connect (irc_session_t * session, const char * server, unsigned short port, const char * server_password, const char * nick, const char * username, const char * realname);
--- libircclient-1.2.orig/include/libirc_session.h
+++ libircclient-1.2/include/libirc_session.h
@@ -54,7 +54,8 @@
 	char		  * username;
 	char		  *	nick;
 
-	struct in_addr	local_addr;
+	struct addrinfo	*local_addrs;
+	struct sockaddr_storage	local_addr;
 	irc_dcc_t		dcc_last_id;
 	irc_dcc_session_t * dcc_sessions;
 	port_mutex_t	mutex_dcc;
--- libircclient-1.2.orig/examples/Makefile.am
+++ libircclient-1.2/examples/Makefile.am
@@ -0,0 +1,14 @@
+SUBDIRS = ircmud
+
+bin_PROGRAMS = censor colors ircftp irctest spammer
+
+AM_CFLAGS = -Wall -I../include
+LIBS = -L../src -lircclient
+
+spammer_LDFLAGS = -pthread
+
+censor_SOURCES = censor.cpp
+colors_SOURCES = colors.cpp
+ircftp_SOURCES = ircftp.cpp
+irctest_SOURCES = irctest.c
+spammer_SOURCES = spammer.c
--- libircclient-1.2.orig/examples/colors.cpp
+++ libircclient-1.2/examples/colors.cpp
@@ -107,9 +107,9 @@
 	irc_ctx_t ctx;
 	irc_session_t * s;
 
-	if ( argc != 4 )
+	if ( argc != 5 )
 	{
-		printf ("Usage: %s <server> <nick> <channel>\n", argv[0]);
+		printf ("Usage: %s <server> <nick> <channel> <local>\n", argv[0]);
 		return 1;
 	}
 
@@ -128,6 +128,8 @@
 		return 1;
 	}
 
+	irc_set_local_addr (s, argv[4]);
+
 	ctx.channel = argv[3];
     ctx.nick = argv[2];
 
--- libircclient-1.2.orig/examples/ircmud/Makefile.am
+++ libircclient-1.2/examples/ircmud/Makefile.am
@@ -0,0 +1,7 @@
+bin_PROGRAMS = mudirconnector
+
+AM_CFLAGS = -D_REENTRANT -g -Wall -I../../include
+mudirconnector_LDFLAGS = -pthread
+mudirconnector_LDADD = -L../../src -lircclient
+
+mudirconnector_SOURCES = config.cpp log.cpp ircmud.cpp main.cpp
--- libircclient-1.2.orig/examples/ircmud/ircmud.cpp
+++ libircclient-1.2/examples/ircmud/ircmud.cpp
@@ -3,6 +3,7 @@
  */
 
 #include "global.h"
+#include <errno.h>
 
 
 static void * process_connection (void * arg)
--- libircclient-1.2.orig/examples/ircmud/global.h
+++ libircclient-1.2/examples/ircmud/global.h
@@ -27,7 +27,7 @@
 
 #include <pthread.h>
 
-#include <libircclient.h>
+#include "libircclient.h"
 
 #include "config.h"
 #include "log.h"
--- libircclient-1.2.orig/examples/ircmud/main.cpp
+++ libircclient-1.2/examples/ircmud/main.cpp
@@ -1,5 +1,7 @@
 
 #include "global.h"
+#include <errno.h>
+#include <cstdlib>
 
 
 CConfig	gCfg;
@@ -93,15 +95,12 @@
 	}
 
 	// Cleanup
-	std::map<std::string, CIrcMud*>::iterator conn, conn_next;
+	std::map<std::string, irc_dcc_t>::iterator conn, conn_next;
 
     for ( conn = gConnectionMap.begin(); conn != gConnectionMap.end(); conn++ )
 	{
-		if ( !conn->second->IsAlive() )
-		{
-			delete conn->second;
-			conn = gConnectionMap.erase(conn);
-		}
+		irc_dcc_destroy(session, conn->second);
+		gConnectionMap.erase(conn);
 	}
 }
 
@@ -175,7 +174,7 @@
 	callbacks.event_notice = event_notice;
 	callbacks.event_numeric = event_numeric;
 
-	callbacks.event_ctcp_req = irc_event_ctcp_internal;
+//	callbacks.event_ctcp_req = irc_event_ctcp_internal;
 //	callbacks.event_dcc_chat_req = irc_event_dcc_chat;
 
 	irc_session_t * s = irc_create_session (&callbacks);
@@ -194,7 +193,7 @@
 	catch (std::string errmsg)
 	{
 		std::cerr << "Error: " << errmsg;
-		exit (1);
+		std::exit (1);
 	}
 
 	irc_option_set (s, LIBIRC_OPTION_STRIPNICKS);
--- libircclient-1.2.orig/examples/ircmud/config.cpp
+++ libircclient-1.2/examples/ircmud/config.cpp
@@ -1,3 +1,4 @@
+#include <cstdlib>
 #include "global.h"
 
 
@@ -9,7 +10,7 @@
 	if ( (sep = addr.find_last_of(": ")) != std::string::npos )
 	{
 		std::string port = addr.substr(sep+1);
-		default_port = atoi (port.c_str());
+		default_port = std::atoi (port.c_str());
 		addr.erase (sep);
 
 		if ( default_port <= 0 )
