diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | conf.c | 28 | ||||
| -rw-r--r-- | conf.h | 4 | ||||
| -rw-r--r-- | dcc.c | 79 | ||||
| -rw-r--r-- | lib/Makefile | 2 | ||||
| -rw-r--r-- | protocols/jabber/s5bytestream.c | 87 | ||||
| -rw-r--r-- | protocols/msn/invitation.c | 70 | 
7 files changed, 69 insertions, 203 deletions
| @@ -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) @@ -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 ); @@ -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[] ); @@ -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 ); | 
