aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile2
-rw-r--r--lib/ftutil.c134
-rw-r--r--lib/ftutil.h40
-rw-r--r--lib/misc.c48
-rw-r--r--lib/misc.h2
5 files changed, 225 insertions, 1 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 441634cd..b686f886 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 oauth.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o
+objects = arc.o base64.o $(EVENT_HANDLER) ftutil.o http_client.o ini.o md5.o misc.o oauth.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.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 );
diff --git a/lib/misc.c b/lib/misc.c
index c56b31f3..f324af6e 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -647,3 +647,51 @@ int md5_verify_password( char *password, char *hash )
return ret;
}
+
+char **split_command_parts( char *command )
+{
+ static char *cmd[IRC_MAX_ARGS+1];
+ char *s, q = 0;
+ int k;
+
+ memset( cmd, 0, sizeof( cmd ) );
+ cmd[0] = command;
+ k = 1;
+ for( s = command; *s && k < IRC_MAX_ARGS; s ++ )
+ if( *s == ' ' && !q )
+ {
+ *s = 0;
+ while( *++s == ' ' );
+ if( *s == '"' || *s == '\'' )
+ {
+ q = *s;
+ s ++;
+ }
+ if( *s )
+ {
+ cmd[k++] = s;
+ s --;
+ }
+ else
+ {
+ break;
+ }
+ }
+ else if( *s == '\\' && ( ( !q && s[1] ) || ( q && q == s[1] ) ) )
+ {
+ char *cpy;
+
+ for( cpy = s; *cpy; cpy ++ )
+ cpy[0] = cpy[1];
+ }
+ else if( *s == q )
+ {
+ q = *s = 0;
+ }
+
+ /* Full zero-padding for easier argc checking. */
+ while( k <= IRC_MAX_ARGS )
+ cmd[k++] = NULL;
+
+ return cmd;
+}
diff --git a/lib/misc.h b/lib/misc.h
index 9f2058b6..12a9edff 100644
--- a/lib/misc.h
+++ b/lib/misc.h
@@ -68,4 +68,6 @@ G_MODULE_EXPORT gboolean ssl_sockerr_again( void *ssl );
G_MODULE_EXPORT int md5_verify_password( char *password, char *hash );
+G_MODULE_EXPORT char **split_command_parts( char *command );
+
#endif