--- 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 +#include +#include #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 \n", argv[0]); + printf ("Usage: %s \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 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 -#include +#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 +#include CConfig gCfg; @@ -93,15 +95,12 @@ } // Cleanup - std::map::iterator conn, conn_next; + std::map::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 #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 )