Index: dcc.c
===================================================================
--- dcc.c	(revision 8a90001ab2cde971abc64b8d5e4174dc4c4b0ae2)
+++ dcc.c	(revision 4ac647dbcef152bebde7209f7c9cbbf8a5e0fc37)
@@ -114,4 +114,15 @@
 }
 
+/* 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 )
 {
@@ -154,4 +165,8 @@
 
 	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). ", user_nick, file_name, file_size/1024 );
+
+	imcb_log( ic, "Accept the file transfer if you'd like the file. If you don't, issue the 'transfers reject' command.");
 
 	return file;
@@ -411,5 +426,6 @@
 	
 		if( file->bytes_transferred >= file->file_size ) {
-			dcc_finish( file );
+			if( df->proto_finished )
+				dcc_finish( file );
 			return FALSE;
 		}
@@ -493,4 +509,7 @@
 			return dcc_abort( df, "Remote end closed connection" );
 
+		if( !ft->write( df->ft, ft->buffer, ret ) )
+			return FALSE;
+
 		df->bytes_sent += ret;
 
@@ -509,11 +528,14 @@
 		}
 		
-		if( !ft->write( df->ft, ft->buffer, ret ) )
-			return FALSE;
+		if( df->bytes_sent == ret )
+			ft->started = time( NULL );
 
 		if( done )
 		{
-			closesocket( fd );
-			dcc_finish( ft );
+			if( df->watch_out )
+				b_event_remove( df->watch_out );
+
+			if( df->proto_finished )
+				dcc_finish( ft );
 
 			df->watch_in = 0;
@@ -572,4 +594,7 @@
 		return dcc_abort( df, "send() sent %d instead of %d", ret, data_len );
 
+	if( df->bytes_sent == 0 )
+		file->started = time( NULL );
+
 	df->bytes_sent += ret;
 
@@ -610,4 +635,7 @@
 void dcc_finish( file_transfer_t *file )
 {
+	dcc_file_transfer_t *df = file->priv;
+	time_t diff = time( NULL ) - file->started ? : 1;
+
 	file->status |= FT_STATUS_FINISHED;
 	
@@ -615,4 +643,5 @@
 		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 );
 }
Index: dcc.h
===================================================================
--- dcc.h	(revision 8a90001ab2cde971abc64b8d5e4174dc4c4b0ae2)
+++ dcc.h	(revision 4ac647dbcef152bebde7209f7c9cbbf8a5e0fc37)
@@ -83,4 +83,8 @@
 	struct sockaddr_storage saddr;
 
+	/* set to true if the protocol has finished 
+	 * (i.e. called imcb_file_finished)
+	 */
+	int proto_finished;
 } dcc_file_transfer_t;
 
Index: protocols/ft.h
===================================================================
--- protocols/ft.h	(revision 8a90001ab2cde971abc64b8d5e4174dc4c4b0ae2)
+++ protocols/ft.h	(revision 4ac647dbcef152bebde7209f7c9cbbf8a5e0fc37)
@@ -171,3 +171,5 @@
 
 gboolean imcb_file_recv_start( file_transfer_t *ft );
+
+void imcb_file_finished( file_transfer_t *file );
 #endif
Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision 8a90001ab2cde971abc64b8d5e4174dc4c4b0ae2)
+++ protocols/jabber/jabber.c	(revision 4ac647dbcef152bebde7209f7c9cbbf8a5e0fc37)
@@ -245,4 +245,16 @@
 	struct jabber_data *jd = ic->proto_data;
 	
+	while( jd->filetransfers )
+		imcb_file_canceled( ( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" );
+
+	while( jd->streamhosts )
+	{
+		jabber_streamhost_t *sh = jd->streamhosts->data;
+		jd->streamhosts = g_slist_remove( jd->streamhosts, sh );
+		g_free( sh->jid );
+		g_free( sh->host );
+		g_free( sh );
+	}
+
 	if( jd->fd >= 0 )
 		jabber_end_stream( ic );
Index: protocols/jabber/s5bytestream.c
===================================================================
--- protocols/jabber/s5bytestream.c	(revision 8a90001ab2cde971abc64b8d5e4174dc4c4b0ae2)
+++ protocols/jabber/s5bytestream.c	(revision 4ac647dbcef152bebde7209f7c9cbbf8a5e0fc37)
@@ -643,8 +643,8 @@
 		return jabber_bs_abort( bt, "Remote end closed connection" );
 	
-	if( tf->bytesread == 0 )
-		tf->ft->started = time( NULL );
-
 	tf->bytesread += ret;
+
+	if( tf->bytesread >= tf->ft->file_size )
+		imcb_file_finished( tf->ft );
 
 	tf->ft->write( tf->ft, tf->ft->buffer, ret );	
@@ -701,7 +701,4 @@
 	ASSERTSOCKOP( ret = send( tf->fd, buffer, len, 0 ), "Sending" );
 
-	if( tf->byteswritten == 0 )
-		tf->ft->started = time( NULL );
-
 	tf->byteswritten += ret;
 	
@@ -710,5 +707,8 @@
 		return jabber_bs_abort( bt, "send() sent %d instead of %d (send buffer too big!)", ret, len );
 
-	bt->tf->watch_out = b_input_add( tf->fd, GAIM_INPUT_WRITE, jabber_bs_send_can_write, bt );
+	if( tf->byteswritten >= ft->file_size )
+		imcb_file_finished( ft );
+	else
+		bt->tf->watch_out = b_input_add( tf->fd, GAIM_INPUT_WRITE, jabber_bs_send_can_write, bt );
 		
 	return TRUE;
Index: protocols/jabber/si.c
===================================================================
--- protocols/jabber/si.c	(revision 8a90001ab2cde971abc64b8d5e4174dc4c4b0ae2)
+++ protocols/jabber/si.c	(revision 4ac647dbcef152bebde7209f7c9cbbf8a5e0fc37)
@@ -54,13 +54,4 @@
 }
 
-/* file_transfer finished() callback */
-void jabber_si_finished( file_transfer_t *ft )
-{
-	struct jabber_transfer *tf = ft->data;
-	time_t diff = time( NULL ) - ft->started ? : 1;
-
-	imcb_log( tf->ic, "File %s transferred successfully at %d kb/s!" , ft->file_name, (int) ( ft->bytes_transferred / 1024 / diff ) );
-}
-
 /* file_transfer canceled() callback */
 void jabber_si_canceled( file_transfer_t *ft, char *reason )
@@ -177,5 +168,4 @@
 	tf->ft->data = tf;
 	tf->ft->free = jabber_si_free_transfer;
-	tf->ft->finished = jabber_si_finished;
 	tf->bud = bud;
 	ft->write = jabber_bs_send_write;
@@ -302,8 +292,4 @@
 	/* Request is fine. */
 
-	imcb_log( ic, "File transfer request from %s for %s (%zd kb). ", xt_find_attr( node, "from" ), name, size/1024 );
-
-	imcb_log( ic, "Accept the file transfer if you'd like the file. If you don't, issue the 'transfers reject' command.");
-
 	tf = g_new0( struct jabber_transfer, 1 );
 
@@ -318,5 +304,4 @@
 	tf->ft->accept = jabber_si_answer_request;
 	tf->ft->free = jabber_si_free_transfer;
-	tf->ft->finished = jabber_si_finished;
 	tf->ft->canceled = jabber_si_canceled;
 
