aboutsummaryrefslogtreecommitdiffstats
path: root/dcc.c
diff options
context:
space:
mode:
Diffstat (limited to 'dcc.c')
-rw-r--r--dcc.c144
1 files changed, 36 insertions, 108 deletions
diff --git a/dcc.c b/dcc.c
index 1f8ec611..ecce7db4 100644
--- a/dcc.c
+++ b/dcc.c
@@ -60,55 +60,16 @@ unsigned int local_transfer_id=1;
*/
unsigned int receivedchunks=0, receiveddata=0;
-static void dcc_finish( file_transfer_t *file );
-static void dcc_close( file_transfer_t *file );
+void dcc_finish( file_transfer_t *file );
+void dcc_close( file_transfer_t *file );
gboolean dccs_send_proto( gpointer data, gint fd, b_input_condition cond );
-int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr );
-gboolean dccs_recv_start( file_transfer_t *ft );
+int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr );
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 )
-{
- user_t *u = user_findhandle( ic, handle );
- /* one could handle this more intelligent like imcb_buddy_msg.
- * can't call it directly though cause it does some wrapping.
- * Maybe give imcb_buddy_msg a parameter NO_WRAPPING? */
- if (!u) return NULL;
-
- return dccs_send_start( ic, u->nick, file_name, file_size );
-};
-
-/* As defined in ft.h */
-void imcb_file_canceled( file_transfer_t *file, char *reason )
-{
- if( file->canceled )
- file->canceled( file, reason );
-
- dcc_close( file );
-}
-
-/* As defined in ft.h */
-gboolean imcb_file_recv_start( file_transfer_t *ft )
-{
- return dccs_recv_start( ft );
-}
-
-/* As defined in ft.h */
-void imcb_file_finished( file_transfer_t *file )
-{
- dcc_file_transfer_t *df = file->priv;
-
- if( file->bytes_transferred >= file->file_size )
- dcc_finish( file );
- else
- df->proto_finished = TRUE;
-}
-
-dcc_file_transfer_t *dcc_alloc_transfer( char *file_name, size_t file_size, struct im_connection *ic )
+dcc_file_transfer_t *dcc_alloc_transfer( const char *file_name, size_t file_size, struct im_connection *ic )
{
file_transfer_t *file = g_new0( file_transfer_t, 1 );
dcc_file_transfer_t *df = file->priv = g_new0( dcc_file_transfer_t, 1 );
@@ -116,17 +77,18 @@ dcc_file_transfer_t *dcc_alloc_transfer( char *file_name, size_t file_size, stru
file->file_size = file_size;
file->file_name = g_strdup( file_name );
file->local_id = local_transfer_id++;
- df->ic = ic;
+ file->ic = df->ic = ic;
df->ft = file;
return df;
}
/* This is where the sending magic starts... */
-file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick, char *file_name, size_t file_size )
+file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, const char *file_name, size_t file_size )
{
file_transfer_t *file;
dcc_file_transfer_t *df;
+ irc_t *irc = (irc_t *) ic->bee->ui_data;
struct sockaddr_storage saddr;
char *errmsg;
char host[HOST_NAME_MAX];
@@ -149,20 +111,20 @@ file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick, cha
file->status = FT_STATUS_LISTENING;
- if( !dccs_send_request( df, user_nick, &saddr ) )
+ if( !dccs_send_request( df, iu, &saddr ) )
return NULL;
/* watch */
df->watch_in = b_input_add( df->fd, B_EV_IO_READ, dccs_send_proto, df );
- df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, file );
+ irc->file_transfers = g_slist_prepend( irc->file_transfers, file );
df->progress_timeout = b_timeout_add( DCC_MAX_STALL * 1000, dcc_progress, df );
imcb_log( ic, "File transfer request from %s for %s (%zd kb).\n"
"Accept the file transfer if you'd like the file. If you don't, "
"issue the 'transfers reject' command.",
- user_nick, file_name, file_size / 1024 );
+ iu->nick, file_name, file_size / 1024 );
return file;
}
@@ -215,7 +177,7 @@ gboolean dcc_progress( gpointer data, gint fd, b_input_condition cond )
return dcc_abort( df , msg ": %s", strerror( errno ) );
/* Creates the "DCC SEND" line and sends it to the server */
-int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr )
+int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr )
{
char ipaddr[INET6_ADDRSTRLEN];
const void *netaddr;
@@ -249,8 +211,7 @@ int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct soc
cmd = g_strdup_printf( "\001DCC SEND %s %s %u %zu\001",
df->ft->file_name, ipaddr, port, df->ft->file_size );
- if ( !irc_msgfrom( df->ic->irc, user_nick, cmd ) )
- return dcc_abort( df, "Couldn't send `DCC SEND' message to %s.", user_nick );
+ irc_send_msg_raw( iu, "PRIVMSG", iu->irc->user->nick, cmd );
g_free( cmd );
@@ -495,9 +456,10 @@ gboolean dccs_send_write( file_transfer_t *file, char *data, unsigned int data_l
/*
* Cleans up after a transfer.
*/
-static void dcc_close( file_transfer_t *file )
+void dcc_close( file_transfer_t *file )
{
dcc_file_transfer_t *df = file->priv;
+ irc_t *irc = (irc_t *) df->ic->bee->ui_data;
if( file->free )
file->free( file );
@@ -513,7 +475,7 @@ static void dcc_close( file_transfer_t *file )
if( df->progress_timeout )
b_event_remove( df->progress_timeout );
- df->ic->irc->file_transfers = g_slist_remove( df->ic->irc->file_transfers, file );
+ irc->file_transfers = g_slist_remove( irc->file_transfers, file );
g_free( df );
g_free( file->file_name );
@@ -541,68 +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 )
{
- char *pattern = "SEND"
- " (([^\"][^ ]*)|\"(([^\"]|\\\")*)\")"
- " (([0-9]*)|([^ ]*))"
- " ([0-9]*)"
- " ([0-9]*)\001";
- regmatch_t pmatch[10];
- regex_t re;
+ irc_t *irc = (irc_t *) ic->bee->ui_data;
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;
@@ -610,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",
@@ -624,15 +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 );
- df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, ft );
+ 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;
}
-