diff options
| -rw-r--r-- | dcc.c | 72 | ||||
| -rw-r--r-- | dcc.h | 2 | ||||
| -rw-r--r-- | irc_im.c | 19 | ||||
| -rw-r--r-- | lib/misc.c | 5 | 
4 files changed, 43 insertions, 55 deletions
| @@ -503,69 +503,37 @@ void dcc_finish( file_transfer_t *file )   * IP can be an unsigned int (IPV4) or something else (IPV6)   *    */ -file_transfer_t *dcc_request( struct im_connection *ic, char *line ) +file_transfer_t *dcc_request( struct im_connection *ic, char* const* ctcp )  {  	irc_t *irc = (irc_t *) ic->bee->ui_data; -	char *pattern = "SEND" -		" (([^\"][^ ]*)|\"(([^\"]|\\\")*)\")" -		" (([0-9]*)|([^ ]*))" -		" ([0-9]*)" -		" ([0-9]*)\001"; -	regmatch_t pmatch[10]; -	regex_t re;  	file_transfer_t *ft;  	dcc_file_transfer_t *df; -	char errbuf[256]; -	int regerrcode, gret; - -	if( ( regerrcode = regcomp( &re, pattern, REG_EXTENDED ) ) || -	    ( regerrcode = regexec( &re, line, 10, pmatch, 0 ) ) ) { -		regerror( regerrcode,&re,errbuf,sizeof( errbuf ) ); -		imcb_log( ic,  -			  "DCC: error parsing 'DCC SEND': %s, line: %s",  -			  errbuf, line ); -		return NULL; -	} - -	if( ( pmatch[1].rm_so > 0 ) && -	    ( pmatch[5].rm_so > 0 ) && -	    ( pmatch[8].rm_so > 0 ) && -	    ( pmatch[9].rm_so > 0 ) ) +	int gret; +	size_t filesize; +	 +	if( ctcp[5] != NULL && +	    sscanf( ctcp[4], "%zd", &filesize ) == 1 && /* Just int. validation. */ +	    sscanf( ctcp[5], "%zd", &filesize ) == 1 )  	{ -		char *input = g_strdup( line );  		char *filename, *host, *port; -		size_t filesize;  		struct addrinfo hints, *rp; - -		/* "filename" or filename */ -		if ( pmatch[2].rm_so > 0 ) -		{ -			input[pmatch[2].rm_eo] = '\0'; -			filename = input + pmatch[2].rm_so; -		} else -		{ -			input[pmatch[3].rm_eo] = '\0'; -			filename = input + pmatch[3].rm_so; -		} -			 -		input[pmatch[5].rm_eo] = '\0'; - -		/* number means ipv4, something else means ipv6 */ -		if ( pmatch[6].rm_so > 0 ) +		 +		filename = ctcp[2]; +		 +		host = ctcp[3]; +		while( *host && isdigit( *host ) ) host++; /* Just digits? */ +		if( *host == '\0' )  		{ -			struct in_addr ipaddr = { .s_addr = htonl( strtoul( input + pmatch[5].rm_so, NULL, 10 ) ) }; +			struct in_addr ipaddr = { .s_addr = htonl( atoll( ctcp[3] ) ) };  			host = inet_ntoa( ipaddr );  		} else  		{  			/* Contains non-numbers, hopefully an IPV6 address */ -			host = input + pmatch[7].rm_so; +			host = ctcp[3];  		} -		input[pmatch[8].rm_eo] = '\0'; -		input[pmatch[9].rm_eo] = '\0'; - -		port = input + pmatch[8].rm_so; -		filesize = atoll( input + pmatch[9].rm_so ); +		port = ctcp[4]; +		filesize = atoll( ctcp[5] );  		memset( &hints, 0, sizeof ( struct addrinfo ) );  		hints.ai_socktype = SOCK_STREAM; @@ -573,7 +541,6 @@ file_transfer_t *dcc_request( struct im_connection *ic, char *line )  		if ( ( gret = getaddrinfo( host, port, &hints, &rp ) ) )  		{ -			g_free( input );  			imcb_log( ic, "DCC: getaddrinfo() failed with %s "  				  "when parsing incoming 'DCC SEND': "  				  "host %s, port %s",  @@ -587,14 +554,13 @@ file_transfer_t *dcc_request( struct im_connection *ic, char *line )  		memcpy( &df->saddr, rp->ai_addr, rp->ai_addrlen );  		freeaddrinfo( rp ); -		g_free( input );  		irc->file_transfers = g_slist_prepend( irc->file_transfers, ft );  		return ft;  	} - -	imcb_log( ic, "DCC: couldnt parse 'DCC SEND' line: %s", line ); +	else +		imcb_log( ic, "DCC: couldnt parse `DCC SEND' line" );  	return NULL;  } @@ -97,7 +97,7 @@ typedef struct dcc_file_transfer {  file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, const char *file_name, size_t file_size );  void dcc_canceled( file_transfer_t *file, char *reason );  gboolean dccs_send_write( file_transfer_t *file, char *data, unsigned int data_size ); -file_transfer_t *dcc_request( struct im_connection *ic, char *line ); +file_transfer_t *dcc_request( struct im_connection *ic, char* const* ctcp );  void dcc_finish( file_transfer_t *file );  void dcc_close( file_transfer_t *file );  gboolean dccs_recv_start( file_transfer_t *ft ); @@ -210,6 +210,25 @@ static gboolean bee_irc_user_privmsg( irc_user_t *iu, const char *msg )  		return FALSE;  } +static gboolean bee_irc_user_ctcp( irc_user_t *iu, char *const *ctcp ) +{ +	if( ctcp[1] && g_strcasecmp( ctcp[0], "DCC" ) == 0 +	            && g_strcasecmp( ctcp[1], "SEND" ) == 0 ) +	{ +		if( iu->bu && iu->bu->ic && iu->bu->ic->acc->prpl->transfer_request ) +		{ +			file_transfer_t *ft = dcc_request( iu->bu->ic, ctcp ); +			if ( ft ) +				iu->bu->ic->acc->prpl->transfer_request( iu->bu->ic, ft, iu->bu->handle ); +			 +			return TRUE; +		} +	} +	 +	return FALSE; +} +  static const struct irc_user_funcs irc_user_im_funcs = {  	bee_irc_user_privmsg, +	bee_irc_user_ctcp,  }; @@ -654,7 +654,10 @@ char **split_command_parts( char *command )  		{  			q = *s = 0;  		} -	cmd[k] = NULL; +	 +	/* Full zero-padding for easier argc checking. */ +	while( k <= IRC_MAX_ARGS ) +		cmd[k++] = NULL;  	return cmd;  } | 
