aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-03-21 16:06:31 +0000
committerWilmer van der Gaast <wilmer@gaast.net>2010-03-21 16:06:31 +0000
commit767a148faa35c18cdf4da77b5919a2f6e2df868a (patch)
tree43f981453468759d31d7b215d84d750dbe4876ac /lib
parent545d7c058d0604dd6acfa37c68e9867e72f25c2e (diff)
parenta81d679654e36055ce9913cd7541885b41380947 (diff)
Merging in file transfer support. Most important points from my review
are fixed now, time to let it settle in and get people to try it.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile2
-rw-r--r--lib/ftutil.c134
-rw-r--r--lib/ftutil.h40
3 files changed, 175 insertions, 1 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 03fef1ab..3d128b5a 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -9,7 +9,7 @@
-include ../Makefile.settings
# [SH] Program variables
-objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o
+objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o ftutil.o
CFLAGS += -Wall
LFLAGS += -r
diff --git a/lib/ftutil.c b/lib/ftutil.c
new file mode 100644
index 00000000..d59dd4e0
--- /dev/null
+++ b/lib/ftutil.c
@@ -0,0 +1,134 @@
+/***************************************************************************\
+* *
+* BitlBee - An IRC to IM gateway *
+* Utility functions for file transfer *
+* *
+* Copyright 2008 Uli Meis <a.sporto+bee@gmail.com> *
+* *
+* 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., *
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+* *
+\***************************************************************************/
+
+#define BITLBEE_CORE
+#include "bitlbee.h"
+#include <poll.h>
+#include <netinet/tcp.h>
+#include "lib/ftutil.h"
+
+#define ASSERTSOCKOP(op, msg) \
+ if( (op) == -1 ) {\
+ g_snprintf( errmsg, sizeof( errmsg ), msg ": %s", strerror( errno ) ); \
+ return -1; }
+
+/*
+ * Creates a listening socket and returns it in saddr_ptr.
+ */
+int ft_listen( struct sockaddr_storage *saddr_ptr, char *host, char *port, int for_bitlbee_client, char **errptr )
+{
+ int fd, gret, saddrlen;
+ struct addrinfo hints, *rp;
+ socklen_t ssize = sizeof( struct sockaddr_storage );
+ struct sockaddr_storage saddrs, *saddr = &saddrs;
+ static char errmsg[1024];
+ char *ftlisten = global.conf->ft_listen;
+
+ if( errptr )
+ *errptr = errmsg;
+
+ strcpy( port, "0" );
+
+ /* Format is <IP-A>[:<Port-A>];<IP-B>[:<Port-B>] where
+ * A is for connections with the bitlbee client (DCC)
+ * and B is for connections with IM peers.
+ */
+ if( ftlisten )
+ {
+ char *scolon = strchr( ftlisten, ';' );
+ char *colon;
+
+ if( scolon )
+ {
+ if( for_bitlbee_client )
+ {
+ *scolon = '\0';
+ strncpy( host, ftlisten, HOST_NAME_MAX );
+ *scolon = ';';
+ }
+ else
+ {
+ strncpy( host, scolon + 1, HOST_NAME_MAX );
+ }
+ }
+ else
+ {
+ strncpy( host, ftlisten, HOST_NAME_MAX );
+ }
+
+ if( ( colon = strchr( host, ':' ) ) )
+ {
+ *colon = '\0';
+ strncpy( port, colon + 1, 5 );
+ }
+ }
+ else
+ {
+ ASSERTSOCKOP( gethostname( host, HOST_NAME_MAX + 1 ), "gethostname()" );
+ }
+
+ memset( &hints, 0, sizeof( struct addrinfo ) );
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICSERV;
+
+ if ( ( gret = getaddrinfo( host, port, &hints, &rp ) ) != 0 )
+ {
+ sprintf( errmsg, "getaddrinfo() failed: %s", gai_strerror( gret ) );
+ return -1;
+ }
+
+ saddrlen = rp->ai_addrlen;
+
+ memcpy( saddr, rp->ai_addr, saddrlen );
+
+ freeaddrinfo( rp );
+
+ ASSERTSOCKOP( fd = socket( saddr->ss_family, SOCK_STREAM, 0 ), "Opening socket" );
+ ASSERTSOCKOP( bind( fd, ( struct sockaddr *)saddr, saddrlen ), "Binding socket" );
+ ASSERTSOCKOP( listen( fd, 1 ), "Making socket listen" );
+
+ if ( !inet_ntop( saddr->ss_family, saddr->ss_family == AF_INET ?
+ ( void * )&( ( struct sockaddr_in * ) saddr )->sin_addr.s_addr :
+ ( void * )&( ( struct sockaddr_in6 * ) saddr )->sin6_addr.s6_addr,
+ host, HOST_NAME_MAX ) )
+ {
+ strcpy( errmsg, "inet_ntop failed on listening socket" );
+ return -1;
+ }
+
+ ASSERTSOCKOP( getsockname( fd, ( struct sockaddr *)saddr, &ssize ), "Getting socket name" );
+
+ if( saddr->ss_family == AF_INET )
+ g_snprintf( port, 6, "%d", ntohs( ( (struct sockaddr_in *) saddr )->sin_port ) );
+ else
+ g_snprintf( port, 6, "%d", ntohs( ( (struct sockaddr_in6 *) saddr )->sin6_port ) );
+
+ if( saddr_ptr )
+ memcpy( saddr_ptr, saddr, saddrlen );
+
+ /* I hate static-length strings.. */
+ host[HOST_NAME_MAX] = '\0';
+ port[5] = '\0';
+
+ return fd;
+}
diff --git a/lib/ftutil.h b/lib/ftutil.h
new file mode 100644
index 00000000..c4a5b02b
--- /dev/null
+++ b/lib/ftutil.h
@@ -0,0 +1,40 @@
+/***************************************************************************\
+* *
+* BitlBee - An IRC to IM gateway *
+* Utility functions for file transfer *
+* *
+* Copyright 2008 Uli Meis <a.sporto+bee@gmail.com> *
+* *
+* 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., *
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+* *
+\***************************************************************************/
+
+#ifndef AI_NUMERICSERV
+#define AI_NUMERICSERV 0x0400 /* Don't use name resolution. */
+#endif
+
+/* Some ifdefs for ulibc and apparently also BSD (Thanks to Whoopie) */
+#ifndef HOST_NAME_MAX
+#include <sys/param.h>
+#ifdef MAXHOSTNAMELEN
+#define HOST_NAME_MAX MAXHOSTNAMELEN
+#else
+#define HOST_NAME_MAX 255
+#endif
+#endif
+
+/* This function should be used with care. host should be AT LEAST a
+ char[HOST_NAME_MAX+1] and port AT LEAST a char[6]. */
+int ft_listen( struct sockaddr_storage *saddr_ptr, char *host, char *port, int for_bitlbee_client, char **errptr );