aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorulim <a.sporto+bee@gmail.com>2008-08-12 01:07:12 +0200
committerulim <a.sporto+bee@gmail.com>2008-08-12 01:07:12 +0200
commita02f34fb047af728f991ced3688c5e804c130878 (patch)
tree7eb7c22889aad7f06d2f22fe4920ff8c4005ece5
parent66be7849ef6b74c39bc8f1dc1d96bc4788eb50a0 (diff)
Added conf entries and lib/ftutil.[ch].
ft_listen = <IP-A>:<Port-A>;<IP-B>:<Port-B> to specify listening addresses for the bitlbee<->client connection and the bitlbee<->IM peer connection, respectively. ft_max_size should be obvious. ft_max_kbps should limit the kilobits per second per transfer (not implemented yet).
-rw-r--r--Makefile2
-rw-r--r--conf.c28
-rw-r--r--conf.h4
-rw-r--r--dcc.c79
-rw-r--r--lib/Makefile2
-rw-r--r--protocols/jabber/s5bytestream.c87
-rw-r--r--protocols/msn/invitation.c70
7 files changed, 69 insertions, 203 deletions
diff --git a/Makefile b/Makefile
index 0c07b91b..2aae8c83 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@
# Program variables
objects = account.o bitlbee.o crypting.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) user.o dcc.o
-headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h user.h lib/events.h lib/http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/nogaim.h protocols/ft.h
+headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h user.h lib/events.h lib/http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/nogaim.h protocols/ft.h lib/ftutil.h
subdirs = lib protocols
ifeq ($(TARGET),i586-mingw32msvc)
diff --git a/conf.c b/conf.c
index 02b1eb98..19fe7020 100644
--- a/conf.c
+++ b/conf.c
@@ -62,7 +62,9 @@ conf_t *conf_load( int argc, char *argv[] )
conf->ping_interval = 180;
conf->ping_timeout = 300;
conf->user = NULL;
- conf->max_filetransfer_size = G_MAXUINT;
+ conf->ft_max_size = SIZE_MAX;
+ conf->ft_max_kbps = G_MAXUINT;
+ conf->ft_listen = NULL;
proxytype = 0;
i = conf_loadini( conf, global.conf_file );
@@ -306,6 +308,30 @@ static int conf_loadini( conf_t *conf, char *file )
g_free( conf->user );
conf->user = g_strdup( ini->value );
}
+ else if( g_strcasecmp( ini->key, "ft_max_size" ) == 0 )
+ {
+ size_t ft_max_size;
+ if( sscanf( ini->value, "%zu", &ft_max_size ) != 1 )
+ {
+ fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
+ return 0;
+ }
+ conf->ft_max_size = ft_max_size;
+ }
+ else if( g_strcasecmp( ini->key, "ft_max_kbps" ) == 0 )
+ {
+ if( sscanf( ini->value, "%d", &i ) != 1 )
+ {
+ fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );
+ return 0;
+ }
+ conf->ft_max_kbps = i;
+ }
+ else if( g_strcasecmp( ini->key, "ft_listen" ) == 0 )
+ {
+ g_free( conf->ft_listen );
+ conf->ft_listen = g_strdup( ini->value );
+ }
else
{
fprintf( stderr, "Error: Unknown setting `%s` in configuration file.\n", ini->key );
diff --git a/conf.h b/conf.h
index 7fcd0ede..b39845ad 100644
--- a/conf.h
+++ b/conf.h
@@ -49,7 +49,9 @@ typedef struct conf
int ping_interval;
int ping_timeout;
char *user;
- size_t max_filetransfer_size;
+ size_t ft_max_size;
+ int ft_max_kbps;
+ char *ft_listen;
} conf_t;
G_GNUC_MALLOC conf_t *conf_load( int argc, char *argv[] );
diff --git a/dcc.c b/dcc.c
index 2bb85ad4..c54e9169 100644
--- a/dcc.c
+++ b/dcc.c
@@ -28,20 +28,7 @@
#include <poll.h>
#include <netinet/tcp.h>
#include <regex.h>
-
-/* Some ifdefs for ulibc (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
-
-#ifndef AI_NUMERICSERV
-#define AI_NUMERICSERV 0x0400 /* Don't use name resolution. */
-#endif
+#include "lib/ftutil.h"
/*
* Since that might be confusing a note on naming:
@@ -79,12 +66,12 @@ int max_packet_size = 0;
static void dcc_finish( file_transfer_t *file );
static void dcc_close( file_transfer_t *file );
gboolean dccs_send_proto( gpointer data, gint fd, b_input_condition cond );
-gboolean dcc_listen( dcc_file_transfer_t *df, struct sockaddr_storage **saddr_ptr );
int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr );
gboolean dccs_recv_start( file_transfer_t *ft );
gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond);
gboolean dccs_recv_write_request( file_transfer_t *ft );
gboolean dcc_progress( gpointer data, gint fd, b_input_condition cond );
+gboolean dcc_abort( dcc_file_transfer_t *df, char *reason, ... );
/* As defined in ft.h */
file_transfer_t *imcb_file_send_start( struct im_connection *ic, char *handle, char *file_name, size_t file_size )
@@ -142,9 +129,12 @@ file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick, cha
{
file_transfer_t *file;
dcc_file_transfer_t *df;
- struct sockaddr_storage *saddr;
+ struct sockaddr_storage saddr;
+ char *errmsg;
+ char host[INET6_ADDRSTRLEN];
+ char port[6];
- if( file_size > global.conf->max_filetransfer_size )
+ if( file_size > global.conf->ft_max_size )
return NULL;
df = dcc_alloc_transfer( file_name, file_size, ic );
@@ -152,11 +142,16 @@ file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick, cha
file->write = dccs_send_write;
/* listen and request */
- if( !dcc_listen( df, &saddr ) ||
- !dccs_send_request( df, user_nick, saddr ) )
+
+ if( ( df->fd = ft_listen( &saddr, host, port, TRUE, &errmsg ) ) == -1 ) {
+ dcc_abort( df, "Failed to listen locally, check your ft_listen setting in bitlbee.conf: %s", errmsg );
return NULL;
+ }
- g_free( saddr );
+ file->status = FT_STATUS_LISTENING;
+
+ if( !dccs_send_request( df, user_nick, &saddr ) )
+ return NULL;
/* watch */
df->watch_in = b_input_add( df->fd, GAIM_INPUT_READ, dccs_send_proto, df );
@@ -262,50 +257,6 @@ int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct soc
}
/*
- * Creates a listening socket and returns it in saddr_ptr.
- */
-gboolean dcc_listen( dcc_file_transfer_t *df, struct sockaddr_storage **saddr_ptr )
-{
- file_transfer_t *file = df->ft;
- struct sockaddr_storage *saddr;
- int fd,gret;
- char hostname[ HOST_NAME_MAX + 1 ];
- struct addrinfo hints, *rp;
- socklen_t ssize = sizeof( struct sockaddr_storage );
-
- /* won't be long till someone asks for this to be configurable :) */
-
- ASSERTSOCKOP( gethostname( hostname, sizeof( hostname ) ), "gethostname()" );
-
- memset( &hints, 0, sizeof( struct addrinfo ) );
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_NUMERICSERV;
-
- if ( ( gret = getaddrinfo( hostname, "0", &hints, &rp ) != 0 ) )
- return dcc_abort( df, "getaddrinfo(): %s", gai_strerror( gret ) );
-
- saddr = g_new( struct sockaddr_storage, 1 );
-
- *saddr_ptr = saddr;
-
- memcpy( saddr, rp->ai_addr, rp->ai_addrlen );
-
- ASSERTSOCKOP( fd = df->fd = socket( saddr->ss_family, SOCK_STREAM, 0 ), "Opening socket" );
-
- ASSERTSOCKOP( bind( fd, ( struct sockaddr *)saddr, rp->ai_addrlen ), "Binding socket" );
-
- freeaddrinfo( rp );
-
- ASSERTSOCKOP( getsockname( fd, ( struct sockaddr *)saddr, &ssize ), "Getting socket name" );
-
- ASSERTSOCKOP( listen( fd, 1 ), "Making socket listen" );
-
- file->status = FT_STATUS_LISTENING;
-
- return TRUE;
-}
-
-/*
* Checks poll(), same for receiving and sending
*/
gboolean dcc_poll( dcc_file_transfer_t *df, int fd, short *revents )
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/protocols/jabber/s5bytestream.c b/protocols/jabber/s5bytestream.c
index 7e4ca2ab..3c5ce503 100644
--- a/protocols/jabber/s5bytestream.c
+++ b/protocols/jabber/s5bytestream.c
@@ -23,22 +23,9 @@
#include "jabber.h"
#include "sha1.h"
+#include "lib/ftutil.h"
#include <poll.h>
-/* Some ifdefs for ulibc (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
-
-#ifndef AI_NUMERICSERV
-#define AI_NUMERICSERV 0x0400 /* Don't use name resolution. */
-#endif
-
struct bs_transfer {
struct jabber_transfer *tf;
@@ -114,7 +101,6 @@ int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, stru
gboolean jabber_bs_send_handshake_abort( struct bs_transfer *bt, char *error );
gboolean jabber_bs_send_request( struct jabber_transfer *tf, GSList *streamhosts );
gboolean jabber_bs_send_handshake( gpointer data, gint fd, b_input_condition cond );
-gboolean jabber_bs_send_listen( struct bs_transfer *bt, struct sockaddr_storage *saddr, char *host, char *port );
static xt_status jabber_bs_send_handle_activate( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
void jabber_bs_send_activate( struct bs_transfer *bt );
@@ -901,7 +887,7 @@ void jabber_si_set_proxies( struct bs_transfer *bt )
struct jabber_transfer *tf = bt->tf;
struct jabber_data *jd = tf->ic->proto_data;
char *proxysetting = g_strdup ( set_getstr( &tf->ic->acc->set, "proxy" ) );
- char *proxy,*next;
+ char *proxy, *next, *errmsg = NULL;
char port[6];
char host[INET6_ADDRSTRLEN];
jabber_streamhost_t *sh, *sh2;
@@ -912,15 +898,21 @@ void jabber_si_set_proxies( struct bs_transfer *bt )
if( ( next = strchr( proxy, ';' ) ) )
*next++ = '\0';
- if( ( strcmp( proxy, "<local>" ) == 0 ) && jabber_bs_send_listen( bt, &tf->saddr, host, port ) ) {
- sh = g_new0( jabber_streamhost_t, 1 );
- sh->jid = g_strdup( tf->ini_jid );
- sh->host = g_strdup( host );
- strcpy( sh->port, port );
- bt->streamhosts = g_slist_append( bt->streamhosts, sh );
+ if( strcmp( proxy, "<local>" ) == 0 ) {
+ if( ( tf->fd = ft_listen( &tf->saddr, host, port, FALSE, &errmsg ) ) != -1 ) {
+ sh = g_new0( jabber_streamhost_t, 1 );
+ sh->jid = g_strdup( tf->ini_jid );
+ sh->host = g_strdup( host );
+ strcpy( sh->port, port );
+ bt->streamhosts = g_slist_append( bt->streamhosts, sh );
- bt->tf->watch_in = b_input_add( tf->fd, GAIM_INPUT_READ, jabber_bs_send_handshake, bt );
- bt->connect_timeout = b_timeout_add( JABBER_BS_LISTEN_TIMEOUT * 1000, jabber_bs_connect_timeout, bt );
+ bt->tf->watch_in = b_input_add( tf->fd, GAIM_INPUT_READ, jabber_bs_send_handshake, bt );
+ bt->connect_timeout = b_timeout_add( JABBER_BS_LISTEN_TIMEOUT * 1000, jabber_bs_connect_timeout, bt );
+ } else {
+ imcb_log( tf->ic, "Transferring file %s: couldn't listen locally(non fatal, check your ft_listen setting in bitlbee.conf): %s",
+ tf->ft->file_name,
+ errmsg );
+ }
} else if( strcmp( proxy, "<auto>" ) == 0 ) {
while ( streamhosts ) {
sh = g_new0( jabber_streamhost_t, 1 );
@@ -1022,53 +1014,6 @@ gboolean jabber_bs_send_handshake_abort(struct bs_transfer *bt, char *error )
}
/*
- * Creates a listening socket and returns it in saddr_ptr.
- */
-gboolean jabber_bs_send_listen( struct bs_transfer *bt, struct sockaddr_storage *saddr, char *host, char *port )
-{
- struct jabber_transfer *tf = bt->tf;
- int fd,gret;
- char hostname[ HOST_NAME_MAX + 1 ];
- struct addrinfo hints, *rp;
- socklen_t ssize = sizeof( struct sockaddr_storage );
-
- /* won't be long till someone asks for this to be configurable :) */
-
- ASSERTSOCKOP( gethostname( hostname, sizeof( hostname ) ), "gethostname()" );
-
- memset( &hints, 0, sizeof( struct addrinfo ) );
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_NUMERICSERV;
-
- if ( ( gret = getaddrinfo( hostname, "0", &hints, &rp ) ) != 0 )
- return jabber_bs_abort( bt, "getaddrinfo() failed: %s", gai_strerror( gret ) );
-
- memcpy( saddr, rp->ai_addr, rp->ai_addrlen );
-
- ASSERTSOCKOP( fd = tf->fd = socket( saddr->ss_family, SOCK_STREAM, 0 ), "Opening socket" );
-
- ASSERTSOCKOP( bind( fd, ( struct sockaddr *)saddr, rp->ai_addrlen ), "Binding socket" );
-
- freeaddrinfo( rp );
-
- 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, INET6_ADDRSTRLEN ) )
- return jabber_bs_abort( bt, "inet_ntop failed on listening socket" );
-
- ASSERTSOCKOP( getsockname( fd, ( struct sockaddr *)saddr, &ssize ), "Getting socket name" );
-
- if( saddr->ss_family == AF_INET )
- sprintf( port, "%d", ntohs( ( ( struct sockaddr_in *) saddr )->sin_port ) );
- else
- sprintf( port, "%d", ntohs( ( ( struct sockaddr_in6 *) saddr )->sin6_port ) );
-
- return TRUE;
-}
-
-/*
* SOCKS5BYTESTREAM protocol for the sender
*/
gboolean jabber_bs_send_handshake( gpointer data, gint fd, b_input_condition cond )
diff --git a/protocols/msn/invitation.c b/protocols/msn/invitation.c
index 021764d2..f44155fa 100644
--- a/protocols/msn/invitation.c
+++ b/protocols/msn/invitation.c
@@ -27,20 +27,7 @@
#include "bitlbee.h"
#include "invitation.h"
#include "msn.h"
-
-/* 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
-
-#ifndef AI_NUMERICSERV
-#define AI_NUMERICSERV 0x0400 /* Don't use name resolution. */
-#endif
+#include "lib/ftutil.h"
#ifdef debug
#undef debug
@@ -78,54 +65,6 @@ gboolean msn_ftp_abort( file_transfer_t *file, char *format, ... )
if( (op) == -1 ) \
return msn_ftp_abort( file , msg ": %s", strerror( errno ) );
-/*
- * Creates a listening socket and returns its address in host, port.
- */
-gboolean msn_ftp_listen( msn_filetransfer_t *msn_file, char *host, char *port )
-{
- file_transfer_t *file = msn_file->dcc;
- int fd,gret;
- char hostname[ HOST_NAME_MAX + 1 ];
- struct addrinfo hints, *rp;
- struct sockaddr_storage saddrst, *saddr = &saddrst;
- socklen_t ssize = sizeof( struct sockaddr_storage );
-
- /* won't be long till someone asks for this to be configurable :) */
-
- ASSERTSOCKOP( gethostname( hostname, sizeof( hostname ) ), "gethostname()" );
-
- memset( &hints, 0, sizeof( struct addrinfo ) );
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_NUMERICSERV;
-
- if ( ( gret = getaddrinfo( hostname, "0", &hints, &rp ) ) != 0 )
- return msn_ftp_abort( file, "getaddrinfo() failed: %s", gai_strerror( gret ) );
-
- memcpy( saddr, rp->ai_addr, rp->ai_addrlen );
-
- ASSERTSOCKOP( fd = msn_file->fd = socket( saddr->ss_family, SOCK_STREAM, 0 ), "Opening socket" );
-
- ASSERTSOCKOP( bind( fd, ( struct sockaddr *)saddr, rp->ai_addrlen ), "Binding socket" );
-
- freeaddrinfo( rp );
-
- 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, INET6_ADDRSTRLEN ) )
- return msn_ftp_abort( file, "inet_ntop failed on listening socket" );
-
- ASSERTSOCKOP( getsockname( fd, ( struct sockaddr *)saddr, &ssize ), "Getting socket name" );
-
- if( saddr->ss_family == AF_INET )
- sprintf( port, "%d", ntohs( ( ( struct sockaddr_in *) saddr )->sin_port ) );
- else
- sprintf( port, "%d", ntohs( ( ( struct sockaddr_in6 *) saddr )->sin6_port ) );
-
- return TRUE;
-}
-
void msn_ftp_invitation_cmd( struct im_connection *ic, char *who, int cookie, char *icmd,
char *trailer )
{
@@ -281,11 +220,14 @@ void msn_invitations_accept( msn_filetransfer_t *msn_file, struct msn_switchboar
unsigned int acookie = time ( NULL );
char host[INET6_ADDRSTRLEN];
char port[6];
+ char *errmsg;
msn_file->auth_cookie = acookie;
- if( !msn_ftp_listen( msn_file, host, port ) )
- return;
+ if( ( msn_file->fd = ft_listen( NULL, host, port, FALSE, &errmsg ) ) == -1 ) {
+ msn_ftp_abort( file, "Failed to listen locally, check your ft_listen setting in bitlbee.conf: %s", errmsg );
+ return;
+ }
msn_file->r_event_id = b_input_add( msn_file->fd, GAIM_INPUT_READ, msn_ftps_connected, file );