Index: dcc.c
===================================================================
--- dcc.c	(revision 17a6ee93f4fbefe8b4356d884fdd95f4e72ce8cc)
+++ dcc.c	(revision 4ed9c8c11adb8d1010ed4bb7b3ff9af962f91237)
@@ -61,8 +61,9 @@
 unsigned int receivedchunks=0, receiveddata=0;
 
-void dcc_finish( file_transfer_t *file );
-void dcc_close( file_transfer_t *file );
+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 );
-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, 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 );
@@ -70,5 +71,43 @@
 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 )
+/* 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 )
 {
 	file_transfer_t *file = g_new0( file_transfer_t, 1 );
@@ -85,9 +124,8 @@
 
 /* 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, char *user_nick, 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;
@@ -112,5 +150,5 @@
 	file->status = FT_STATUS_LISTENING;
 
-	if( !dccs_send_request( df, iu, &saddr ) )
+	if( !dccs_send_request( df, user_nick, &saddr ) )
 		return NULL;
 
@@ -118,5 +156,5 @@
 	df->watch_in = b_input_add( df->fd, GAIM_INPUT_READ, dccs_send_proto, df );
 
-	irc->file_transfers = g_slist_prepend( irc->file_transfers, file );
+	df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, file );
 
 	df->progress_timeout = b_timeout_add( DCC_MAX_STALL * 1000, dcc_progress, df );
@@ -125,5 +163,5 @@
 	              "Accept the file transfer if you'd like the file. If you don't, "
 	              "issue the 'transfers reject' command.",
-	              iu->nick, file_name, file_size / 1024 );
+	              user_nick, file_name, file_size / 1024 );
 
 	return file;
@@ -178,5 +216,5 @@
 
 /* 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, char *user_nick, struct sockaddr_storage *saddr )
 {
 	char ipaddr[INET6_ADDRSTRLEN]; 
@@ -212,5 +250,6 @@
 				df->ft->file_name, ipaddr, port, df->ft->file_size );
 	
-	irc_send_msg_raw( iu, "PRIVMSG", iu->irc->user->nick, cmd );
+	if ( !irc_msgfrom( df->ic->irc, user_nick, cmd ) )
+		return dcc_abort( df, "Couldn't send `DCC SEND' message to %s.", user_nick );
 
 	g_free( cmd );
@@ -457,8 +496,7 @@
  * Cleans up after a transfer.
  */
-void dcc_close( file_transfer_t *file )
+static 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 )
@@ -476,5 +514,5 @@
 		b_event_remove( df->progress_timeout );
 	
-	irc->file_transfers = g_slist_remove( irc->file_transfers, file );
+	df->ic->irc->file_transfers = g_slist_remove( df->ic->irc->file_transfers, file );
 	
 	g_free( df );
@@ -506,5 +544,4 @@
 file_transfer_t *dcc_request( struct im_connection *ic, char *line )
 {
-	irc_t *irc = (irc_t *) ic->bee->ui_data;
 	char *pattern = "SEND"
 		" (([^\"][^ ]*)|\"(([^\"]|\\\")*)\")"
@@ -590,5 +627,5 @@
 		g_free( input );
 
-		irc->file_transfers = g_slist_prepend( irc->file_transfers, ft );
+		df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, ft );
 
 		return ft;
