diff options
Diffstat (limited to 'dcc.c')
-rw-r--r-- | dcc.c | 508 |
1 files changed, 266 insertions, 242 deletions
@@ -29,62 +29,62 @@ #include <regex.h> #include "lib/ftutil.h" -/* +/* * Since that might be confusing a note on naming: * - * Generic dcc functions start with + * Generic dcc functions start with * - * dcc_ + * dcc_ * * ,methods specific to DCC SEND start with * - * dccs_ + * dccs_ * * . Since we can be on both ends of a DCC SEND, * functions specific to one end are called * - * dccs_send and dccs_recv + * dccs_send and dccs_recv * * ,respectively. */ -/* +/* * used to generate a unique local transfer id the user * can use to reject/cancel transfers */ -unsigned int local_transfer_id=1; +unsigned int local_transfer_id = 1; -/* +/* * just for debugging the nr. of chunks we received from im-protocols and the total data */ -unsigned int receivedchunks=0, receiveddata=0; - -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, 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, ... ); - -dcc_file_transfer_t *dcc_alloc_transfer( const char *file_name, size_t file_size, struct im_connection *ic ) +unsigned int receivedchunks = 0, receiveddata = 0; + +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, 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, ...); + +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 ); - + file_transfer_t *file = g_new0(file_transfer_t, 1); + dcc_file_transfer_t *df = file->priv = g_new0(dcc_file_transfer_t, 1); + file->file_size = file_size; - file->file_name = g_strdup( file_name ); + file->file_name = g_strdup(file_name); file->local_id = local_transfer_id++; 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, irc_user_t *iu, const 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; @@ -94,75 +94,79 @@ file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, cons char host[HOST_NAME_MAX]; char port[6]; - if( file_size > global.conf->ft_max_size ) + if (file_size > global.conf->ft_max_size) { return NULL; - - df = dcc_alloc_transfer( file_name, file_size, ic ); + } + + df = dcc_alloc_transfer(file_name, file_size, ic); file = df->ft; file->write = dccs_send_write; /* listen and request */ - if( ( df->fd = ft_listen( &saddr, host, port, irc->fd, TRUE, &errmsg ) ) == -1 ) - { - dcc_abort( df, "Failed to listen locally, check your ft_listen setting in bitlbee.conf: %s", errmsg ); + if ((df->fd = ft_listen(&saddr, host, port, irc->fd, TRUE, &errmsg)) == -1) { + dcc_abort(df, "Failed to listen locally, check your ft_listen setting in bitlbee.conf: %s", errmsg); return NULL; } file->status = FT_STATUS_LISTENING; - if( !dccs_send_request( df, iu, &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->watch_in = b_input_add(df->fd, B_EV_IO_READ, dccs_send_proto, df); - irc->file_transfers = g_slist_prepend( 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 ); + 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 'transfer reject' command.", - iu->nick, file_name, file_size / 1024 ); + 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 'transfer reject' command.", + iu->nick, file_name, file_size / 1024); return file; } /* Used pretty much everywhere in the code to abort a transfer */ -gboolean dcc_abort( dcc_file_transfer_t *df, char *reason, ... ) +gboolean dcc_abort(dcc_file_transfer_t *df, char *reason, ...) { file_transfer_t *file = df->ft; va_list params; - va_start( params, reason ); - char *msg = g_strdup_vprintf( reason, params ); - va_end( params ); - + + va_start(params, reason); + char *msg = g_strdup_vprintf(reason, params); + va_end(params); + file->status |= FT_STATUS_CANCELED; - - if( file->canceled ) - file->canceled( file, msg ); - imcb_log( df->ic, "File %s: DCC transfer aborted: %s", file->file_name, msg ); + if (file->canceled) { + file->canceled(file, msg); + } + + imcb_log(df->ic, "File %s: DCC transfer aborted: %s", file->file_name, msg); - g_free( msg ); + g_free(msg); - dcc_close( df->ft ); + dcc_close(df->ft); return FALSE; } -gboolean dcc_progress( gpointer data, gint fd, b_input_condition cond ) +gboolean dcc_progress(gpointer data, gint fd, b_input_condition cond) { struct dcc_file_transfer *df = data; - if( df->bytes_sent == df->progress_bytes_last ) - { + if (df->bytes_sent == df->progress_bytes_last) { /* no progress. cancel */ - if( df->bytes_sent == 0 ) - return dcc_abort( df, "Couldn't establish transfer within %d seconds", DCC_MAX_STALL ); - else - return dcc_abort( df, "Transfer stalled for %d seconds at %d kb", DCC_MAX_STALL, df->bytes_sent / 1024 ); + if (df->bytes_sent == 0) { + return dcc_abort(df, "Couldn't establish transfer within %d seconds", DCC_MAX_STALL); + } else { + return dcc_abort(df, "Transfer stalled for %d seconds at %d kb", DCC_MAX_STALL, + df->bytes_sent / 1024); + } } @@ -173,47 +177,45 @@ gboolean dcc_progress( gpointer data, gint fd, b_input_condition cond ) /* used extensively for socket operations */ #define ASSERTSOCKOP(op, msg) \ - if( (op) == -1 ) \ - return dcc_abort( df , msg ": %s", strerror( errno ) ); + if ((op) == -1) { \ + 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, irc_user_t *iu, 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]; + char ipaddr[INET6_ADDRSTRLEN]; const void *netaddr; int port; char *cmd; - if( saddr->ss_family == AF_INET ) - { + if (saddr->ss_family == AF_INET) { struct sockaddr_in *saddr_ipv4 = ( struct sockaddr_in *) saddr; - sprintf( ipaddr, "%d", - ntohl( saddr_ipv4->sin_addr.s_addr ) ); + sprintf(ipaddr, "%d", + ntohl(saddr_ipv4->sin_addr.s_addr)); port = saddr_ipv4->sin_port; - } - else - { + } else { struct sockaddr_in6 *saddr_ipv6 = ( struct sockaddr_in6 *) saddr; netaddr = &saddr_ipv6->sin6_addr.s6_addr; port = saddr_ipv6->sin6_port; - /* + /* * Didn't find docs about this, but it seems that's the way irssi does it */ - if( !inet_ntop( saddr->ss_family, netaddr, ipaddr, sizeof( ipaddr ) ) ) - return dcc_abort( df, "inet_ntop failed: %s", strerror( errno ) ); + if (!inet_ntop(saddr->ss_family, netaddr, ipaddr, sizeof(ipaddr))) { + return dcc_abort(df, "inet_ntop failed: %s", strerror(errno)); + } } - port = ntohs( port ); + port = ntohs(port); + + cmd = g_strdup_printf("\001DCC SEND %s %s %u %zu\001", + df->ft->file_name, ipaddr, port, df->ft->file_size); - cmd = g_strdup_printf( "\001DCC SEND %s %s %u %zu\001", - df->ft->file_name, ipaddr, port, df->ft->file_size ); - - irc_send_msg_raw( iu, "PRIVMSG", iu->irc->user->nick, cmd ); + irc_send_msg_raw(iu, "PRIVMSG", iu->irc->user->nick, cmd); - g_free( cmd ); + g_free(cmd); return TRUE; } @@ -222,124 +224,132 @@ int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sock * After setup, the transfer itself is handled entirely by this function. * There are basically four things to handle: connect, receive, send, and error. */ -gboolean dccs_send_proto( gpointer data, gint fd, b_input_condition cond ) +gboolean dccs_send_proto(gpointer data, gint fd, b_input_condition cond) { dcc_file_transfer_t *df = data; file_transfer_t *file = df->ft; - - if( ( cond & B_EV_IO_READ ) && - ( file->status & FT_STATUS_LISTENING ) ) - { + + if ((cond & B_EV_IO_READ) && + (file->status & FT_STATUS_LISTENING)) { struct sockaddr *clt_addr; - socklen_t ssize = sizeof( clt_addr ); + socklen_t ssize = sizeof(clt_addr); /* Connect */ - ASSERTSOCKOP( df->fd = accept( fd, (struct sockaddr *) &clt_addr, &ssize ), "Accepting connection" ); + ASSERTSOCKOP(df->fd = accept(fd, (struct sockaddr *) &clt_addr, &ssize), "Accepting connection"); - closesocket( fd ); + closesocket(fd); fd = df->fd; file->status = FT_STATUS_TRANSFERRING; - sock_make_nonblocking( fd ); + sock_make_nonblocking(fd); /* IM protocol callback */ - if( file->accept ) - file->accept( file ); + if (file->accept) { + file->accept(file); + } /* reschedule for reading on new fd */ - df->watch_in = b_input_add( fd, B_EV_IO_READ, dccs_send_proto, df ); + df->watch_in = b_input_add(fd, B_EV_IO_READ, dccs_send_proto, df); return FALSE; } - if( cond & B_EV_IO_READ ) - { + if (cond & B_EV_IO_READ) { int ret; - - ASSERTSOCKOP( ret = recv( fd, ( (char*) &df->acked ) + df->acked_len, - sizeof( df->acked ) - df->acked_len, 0 ), "Receiving" ); - if( ret == 0 ) - return dcc_abort( df, "Remote end closed connection" ); - + ASSERTSOCKOP(ret = recv(fd, ((char *) &df->acked) + df->acked_len, + sizeof(df->acked) - df->acked_len, 0), "Receiving"); + + if (ret == 0) { + return dcc_abort(df, "Remote end closed connection"); + } + /* How likely is it that a 32-bit integer gets split accross packet boundaries? Chances are rarely 0 so let's be sure. */ - if( ( df->acked_len = ( df->acked_len + ret ) % 4 ) > 0 ) + if ((df->acked_len = (df->acked_len + ret) % 4) > 0) { return TRUE; + } - df->acked = ntohl( df->acked ); + df->acked = ntohl(df->acked); /* If any of this is actually happening, the receiver should buy a new IRC client */ - if ( df->acked > df->bytes_sent ) - return dcc_abort( df, "Receiver magically received more bytes than sent ( %d > %d ) (BUG at receiver?)", df->acked, df->bytes_sent ); + if (df->acked > df->bytes_sent) { + return dcc_abort(df, + "Receiver magically received more bytes than sent ( %d > %d ) (BUG at receiver?)", df->acked, + df->bytes_sent); + } + + if (df->acked < file->bytes_transferred) { + return dcc_abort(df, "Receiver lost bytes? ( has %d, had %d ) (BUG at receiver?)", df->acked, + file->bytes_transferred); + } - if ( df->acked < file->bytes_transferred ) - return dcc_abort( df, "Receiver lost bytes? ( has %d, had %d ) (BUG at receiver?)", df->acked, file->bytes_transferred ); - file->bytes_transferred = df->acked; - - if( file->bytes_transferred >= file->file_size ) { - if( df->proto_finished ) - dcc_finish( file ); + + if (file->bytes_transferred >= file->file_size) { + if (df->proto_finished) { + dcc_finish(file); + } return FALSE; } - + return TRUE; } return TRUE; } -gboolean dccs_recv_start( file_transfer_t *ft ) +gboolean dccs_recv_start(file_transfer_t *ft) { dcc_file_transfer_t *df = ft->priv; struct sockaddr_storage *saddr = &df->saddr; int fd; - char ipaddr[INET6_ADDRSTRLEN]; - socklen_t sa_len = saddr->ss_family == AF_INET ? - sizeof( struct sockaddr_in ) : sizeof( struct sockaddr_in6 ); - - if( !ft->write ) - return dcc_abort( df, "BUG: protocol didn't register write()" ); - - ASSERTSOCKOP( fd = df->fd = socket( saddr->ss_family, SOCK_STREAM, 0 ), "Opening Socket" ); - - sock_make_nonblocking( fd ); - - if( ( connect( fd, (struct sockaddr *)saddr, sa_len ) == -1 ) && - ( errno != EINPROGRESS ) ) - return dcc_abort( df, "Connecting to %s:%d : %s", - 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, - ipaddr, - sizeof( ipaddr ) ), - ntohs( saddr->ss_family == AF_INET ? - ( ( struct sockaddr_in *) saddr )->sin_port : - ( ( struct sockaddr_in6 *) saddr )->sin6_port ), - strerror( errno ) ); + char ipaddr[INET6_ADDRSTRLEN]; + socklen_t sa_len = saddr->ss_family == AF_INET ? + sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); + + if (!ft->write) { + return dcc_abort(df, "BUG: protocol didn't register write()"); + } + + ASSERTSOCKOP(fd = df->fd = socket(saddr->ss_family, SOCK_STREAM, 0), "Opening Socket"); + + sock_make_nonblocking(fd); + + if ((connect(fd, (struct sockaddr *) saddr, sa_len) == -1) && + (errno != EINPROGRESS)) { + return dcc_abort(df, "Connecting to %s:%d : %s", + 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, + ipaddr, + sizeof(ipaddr)), + ntohs(saddr->ss_family == AF_INET ? + (( struct sockaddr_in *) saddr)->sin_port : + (( struct sockaddr_in6 *) saddr)->sin6_port), + strerror(errno)); + } ft->status = FT_STATUS_CONNECTING; /* watch */ - df->watch_out = b_input_add( df->fd, B_EV_IO_WRITE, dccs_recv_proto, df ); + df->watch_out = b_input_add(df->fd, B_EV_IO_WRITE, dccs_recv_proto, df); ft->write_request = dccs_recv_write_request; - df->progress_timeout = b_timeout_add( DCC_MAX_STALL * 1000, dcc_progress, df ); + df->progress_timeout = b_timeout_add(DCC_MAX_STALL * 1000, dcc_progress, df); return TRUE; } -gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond ) +gboolean dccs_recv_proto(gpointer data, gint fd, b_input_condition cond) { dcc_file_transfer_t *df = data; file_transfer_t *ft = df->ft; - if( ( cond & B_EV_IO_WRITE ) && - ( ft->status & FT_STATUS_CONNECTING ) ) - { + if ((cond & B_EV_IO_WRITE) && + (ft->status & FT_STATUS_CONNECTING)) { ft->status = FT_STATUS_TRANSFERRING; //df->watch_in = b_input_add( df->fd, B_EV_IO_READ, dccs_recv_proto, df ); @@ -348,46 +358,49 @@ gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond ) return FALSE; } - if( cond & B_EV_IO_READ ) - { + if (cond & B_EV_IO_READ) { int ret, done; - ASSERTSOCKOP( ret = recv( fd, ft->buffer, sizeof( ft->buffer ), 0 ), "Receiving" ); + ASSERTSOCKOP(ret = recv(fd, ft->buffer, sizeof(ft->buffer), 0), "Receiving"); - if( ret == 0 ) - return dcc_abort( df, "Remote end closed connection" ); + if (ret == 0) { + return dcc_abort(df, "Remote end closed connection"); + } - if( !ft->write( df->ft, ft->buffer, ret ) ) + if (!ft->write(df->ft, ft->buffer, ret)) { return FALSE; + } df->bytes_sent += ret; done = df->bytes_sent >= ft->file_size; - if( ( ( df->bytes_sent - ft->bytes_transferred ) > DCC_PACKET_SIZE ) || - done ) - { - guint32 ack = htonl( ft->bytes_transferred = df->bytes_sent ); + if (((df->bytes_sent - ft->bytes_transferred) > DCC_PACKET_SIZE) || + done) { + guint32 ack = htonl(ft->bytes_transferred = df->bytes_sent); int ackret; - ASSERTSOCKOP( ackret = send( fd, &ack, 4, 0 ), "Sending DCC ACK" ); - - if ( ackret != 4 ) - return dcc_abort( df, "Error sending DCC ACK, sent %d instead of 4 bytes", ackret ); + ASSERTSOCKOP(ackret = send(fd, &ack, 4, 0), "Sending DCC ACK"); + + if (ackret != 4) { + return dcc_abort(df, "Error sending DCC ACK, sent %d instead of 4 bytes", ackret); + } + } + + if (df->bytes_sent == ret) { + ft->started = time(NULL); } - - if( df->bytes_sent == ret ) - ft->started = time( NULL ); - if( done ) - { - if( df->watch_out ) - b_event_remove( df->watch_out ); + if (done) { + if (df->watch_out) { + b_event_remove(df->watch_out); + } df->watch_in = 0; - if( df->proto_finished ) - dcc_finish( ft ); + if (df->proto_finished) { + dcc_finish(ft); + } return FALSE; } @@ -399,57 +412,64 @@ gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond ) return TRUE; } -gboolean dccs_recv_write_request( file_transfer_t *ft ) +gboolean dccs_recv_write_request(file_transfer_t *ft) { dcc_file_transfer_t *df = ft->priv; - if( df->watch_in ) - return dcc_abort( df, "BUG: write_request() called while watching" ); + if (df->watch_in) { + return dcc_abort(df, "BUG: write_request() called while watching"); + } - df->watch_in = b_input_add( df->fd, B_EV_IO_READ, dccs_recv_proto, df ); + df->watch_in = b_input_add(df->fd, B_EV_IO_READ, dccs_recv_proto, df); return TRUE; } -gboolean dccs_send_can_write( gpointer data, gint fd, b_input_condition cond ) +gboolean dccs_send_can_write(gpointer data, gint fd, b_input_condition cond) { struct dcc_file_transfer *df = data; + df->watch_out = 0; - df->ft->write_request( df->ft ); + df->ft->write_request(df->ft); return FALSE; } -/* +/* * Incoming data. - * + * */ -gboolean dccs_send_write( file_transfer_t *file, char *data, unsigned int data_len ) +gboolean dccs_send_write(file_transfer_t *file, char *data, unsigned int data_len) { dcc_file_transfer_t *df = file->priv; int ret; receivedchunks++; receiveddata += data_len; - if( df->watch_out ) - return dcc_abort( df, "BUG: write() called while watching" ); + if (df->watch_out) { + return dcc_abort(df, "BUG: write() called while watching"); + } - ASSERTSOCKOP( ret = send( df->fd, data, data_len, 0 ), "Sending data" ); + ASSERTSOCKOP(ret = send(df->fd, data, data_len, 0), "Sending data"); - if( ret == 0 ) - return dcc_abort( df, "Remote end closed connection" ); + if (ret == 0) { + return dcc_abort(df, "Remote end closed connection"); + } /* TODO: this should really not be fatal */ - if( ret < data_len ) - return dcc_abort( df, "send() sent %d instead of %d", ret, data_len ); + if (ret < data_len) { + return dcc_abort(df, "send() sent %d instead of %d", ret, data_len); + } - if( df->bytes_sent == 0 ) - file->started = time( NULL ); + if (df->bytes_sent == 0) { + file->started = time(NULL); + } df->bytes_sent += ret; - if( df->bytes_sent < df->ft->file_size ) - df->watch_out = b_input_add( df->fd, B_EV_IO_WRITE, dccs_send_can_write, df ); + if (df->bytes_sent < df->ft->file_size) { + df->watch_out = b_input_add(df->fd, B_EV_IO_WRITE, dccs_send_can_write, df); + } return TRUE; } @@ -457,111 +477,115 @@ gboolean dccs_send_write( file_transfer_t *file, char *data, unsigned int data_l /* * Cleans up after a transfer. */ -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 ); - - closesocket( df->fd ); - - if( df->watch_in ) - b_event_remove( df->watch_in ); - - if( df->watch_out ) - b_event_remove( df->watch_out ); - - if( df->progress_timeout ) - b_event_remove( df->progress_timeout ); - - irc->file_transfers = g_slist_remove( irc->file_transfers, file ); - - g_free( df ); - g_free( file->file_name ); - g_free( file ); + if (file->free) { + file->free(file); + } + + closesocket(df->fd); + + if (df->watch_in) { + b_event_remove(df->watch_in); + } + + if (df->watch_out) { + b_event_remove(df->watch_out); + } + + if (df->progress_timeout) { + b_event_remove(df->progress_timeout); + } + + irc->file_transfers = g_slist_remove(irc->file_transfers, file); + + g_free(df); + g_free(file->file_name); + g_free(file); } -void dcc_finish( file_transfer_t *file ) +void dcc_finish(file_transfer_t *file) { dcc_file_transfer_t *df = file->priv; - time_t diff = time( NULL ) - file->started ? : 1; + time_t diff = time(NULL) - file->started ? : 1; file->status |= FT_STATUS_FINISHED; - - if( file->finished ) - file->finished( file ); - imcb_log( df->ic, "File %s transferred successfully at %d kb/s!" , file->file_name, (int) ( file->bytes_transferred / 1024 / diff ) ); - dcc_close( file ); + if (file->finished) { + file->finished(file); + } + + imcb_log(df->ic, "File %s transferred successfully at %d kb/s!", file->file_name, + (int) (file->bytes_transferred / 1024 / diff)); + dcc_close(file); } -/* +/* * DCC SEND <filename> <IP> <port> <filesize> * * filename can be in "" or not. If it is, " can probably be escaped... * IP can be an unsigned int (IPV4) or something else (IPV6) - * + * */ -file_transfer_t *dcc_request( struct im_connection *ic, char* const* ctcp ) +file_transfer_t *dcc_request(struct im_connection *ic, char* const* ctcp) { irc_t *irc = (irc_t *) ic->bee->ui_data; file_transfer_t *ft; dcc_file_transfer_t *df; int gret; size_t filesize; - - if( ctcp[5] != NULL && - sscanf( ctcp[4], "%zd", &filesize ) == 1 && /* Just int. validation. */ - sscanf( ctcp[5], "%zd", &filesize ) == 1 ) - { + + if (ctcp[5] != NULL && + sscanf(ctcp[4], "%zd", &filesize) == 1 && /* Just int. validation. */ + sscanf(ctcp[5], "%zd", &filesize) == 1) { char *filename, *host, *port; struct addrinfo hints, *rp; - + filename = ctcp[2]; - + host = ctcp[3]; - while( *host && g_ascii_isdigit( *host ) ) host++; /* Just digits? */ - if( *host == '\0' ) - { - struct in_addr ipaddr = { .s_addr = htonl( atoll( ctcp[3] ) ) }; - host = inet_ntoa( ipaddr ); - } else - { + while (*host && g_ascii_isdigit(*host)) { + host++; /* Just digits? */ + } + if (*host == '\0') { + struct in_addr ipaddr = { .s_addr = htonl(atoll(ctcp[3])) }; + host = inet_ntoa(ipaddr); + } else { /* Contains non-numbers, hopefully an IPV6 address */ host = ctcp[3]; } port = ctcp[4]; - filesize = atoll( ctcp[5] ); + filesize = atoll(ctcp[5]); - memset( &hints, 0, sizeof ( struct addrinfo ) ); + memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICSERV; - if ( ( gret = getaddrinfo( host, port, &hints, &rp ) ) ) - { - imcb_log( ic, "DCC: getaddrinfo() failed with %s " - "when parsing incoming 'DCC SEND': " - "host %s, port %s", - gai_strerror( gret ), host, port ); + if ((gret = getaddrinfo(host, port, &hints, &rp))) { + imcb_log(ic, "DCC: getaddrinfo() failed with %s " + "when parsing incoming 'DCC SEND': " + "host %s, port %s", + gai_strerror(gret), host, port); return NULL; } - df = dcc_alloc_transfer( filename, filesize, ic ); + df = dcc_alloc_transfer(filename, filesize, ic); ft = df->ft; ft->sending = TRUE; - memcpy( &df->saddr, rp->ai_addr, rp->ai_addrlen ); + memcpy(&df->saddr, rp->ai_addr, rp->ai_addrlen); - freeaddrinfo( rp ); + freeaddrinfo(rp); - irc->file_transfers = g_slist_prepend( irc->file_transfers, ft ); + irc->file_transfers = g_slist_prepend(irc->file_transfers, ft); return ft; + } else { + imcb_log(ic, "DCC: couldnt parse `DCC SEND' line"); } - else - imcb_log( ic, "DCC: couldnt parse `DCC SEND' line" ); return NULL; } |