diff options
| -rw-r--r-- | protocols/purple/ft.c | 158 | ||||
| -rw-r--r-- | protocols/purple/purple.c | 7 | 
2 files changed, 85 insertions, 80 deletions
| diff --git a/protocols/purple/ft.c b/protocols/purple/ft.c index 57d45beb..8cfa60dd 100644 --- a/protocols/purple/ft.c +++ b/protocols/purple/ft.c @@ -45,69 +45,11 @@ struct prpl_xfer_data  static file_transfer_t *next_ft;  struct im_connection *purple_ic_by_pa( PurpleAccount *pa ); +static gboolean prplcb_xfer_new_send_cb( gpointer data, gint fd, b_input_condition cond ); +static gboolean prpl_xfer_write_request( struct file_transfer *ft ); -gboolean try_write_to_ui( gpointer data, gint fd, b_input_condition cond ) -{ -	struct file_transfer *ft = data; -	struct prpl_xfer_data *px = ft->data; -	struct stat fs; -	off_t tx_bytes; -	 -	fprintf( stderr, "write_to_ui\n" ); -	 -	/* If we don't have the file opened yet, there's no data so wait. */ -	if( px->fd < 0 || !px->ui_wants_data ) -		return FALSE; -	 -	tx_bytes = lseek( px->fd, 0, SEEK_CUR ); -	fstat( px->fd, &fs ); -	 -	fprintf( stderr, "write_to_ui %zd %zd %zd\n", fs.st_size, tx_bytes, px->xfer->size ); -	 -	if( fs.st_size > tx_bytes ) -	{ -		char buf[1024]; -		size_t n = MIN( fs.st_size - tx_bytes, sizeof( buf ) ); -		 -		if( read( px->fd, buf, n ) == n && ft->write( ft, buf, n ) ) -		{ -			fprintf( stderr, "Wrote %zd bytes\n", n ); -			px->ui_wants_data = FALSE; -		} -		else -		{ -			purple_xfer_cancel_local( px->xfer ); -			imcb_file_canceled( ft, "Read error" ); -		} -	} -	 -	if( lseek( px->fd, 0, SEEK_CUR ) == px->xfer->size ) -	{ -		purple_xfer_end( px->xfer ); -		imcb_file_finished( ft ); -	} -	 -	return FALSE; -} - -/* UI calls this when its buffer is empty and wants more data to send to the user. */ -static gboolean prpl_xfer_write_request( struct file_transfer *ft ) -{ -	struct prpl_xfer_data *px = ft->data; -	 -	fprintf( stderr, "wrq\n" ); -	 -	px->ui_wants_data = TRUE; -	try_write_to_ui( ft, 0, 0 ); -	 -	return FALSE; -} - -static gboolean prpl_xfer_write( struct file_transfer *ft, char *buffer, unsigned int len ) -{ -	return FALSE; -} +/* Receiving files (IM->UI): */  static void prpl_xfer_accept( struct file_transfer *ft )  {  	struct prpl_xfer_data *px = ft->data; @@ -121,8 +63,6 @@ static void prpl_xfer_canceled( struct file_transfer *ft, char *reason )  	purple_xfer_request_denied( px->xfer );  } -static gboolean prplcb_xfer_new_send_cb( gpointer data, gint fd, b_input_condition cond ); -  static void prplcb_xfer_new( PurpleXfer *xfer )  {  	if( purple_xfer_get_type( xfer ) == PURPLE_XFER_RECEIVE ) @@ -182,6 +122,58 @@ static gboolean prplcb_xfer_new_send_cb( gpointer data, gint fd, b_input_conditi  	return FALSE;  } +gboolean try_write_to_ui( gpointer data, gint fd, b_input_condition cond ) +{ +	struct file_transfer *ft = data; +	struct prpl_xfer_data *px = ft->data; +	struct stat fs; +	off_t tx_bytes; +	 +	/* If we don't have the file opened yet, there's no data so wait. */ +	if( px->fd < 0 || !px->ui_wants_data ) +		return FALSE; +	 +	tx_bytes = lseek( px->fd, 0, SEEK_CUR ); +	fstat( px->fd, &fs ); +	 +	if( fs.st_size > tx_bytes ) +	{ +		char buf[1024]; +		size_t n = MIN( fs.st_size - tx_bytes, sizeof( buf ) ); +		 +		if( read( px->fd, buf, n ) == n && ft->write( ft, buf, n ) ) +		{ +			px->ui_wants_data = FALSE; +		} +		else +		{ +			purple_xfer_cancel_local( px->xfer ); +			imcb_file_canceled( ft, "Read error" ); +		} +	} +	 +	if( lseek( px->fd, 0, SEEK_CUR ) == px->xfer->size ) +	{ +		purple_xfer_end( px->xfer ); +		imcb_file_finished( ft ); +	} +	 +	return FALSE; +} + +/* UI calls this when its buffer is empty and wants more data to send to the user. */ +static gboolean prpl_xfer_write_request( struct file_transfer *ft ) +{ +	struct prpl_xfer_data *px = ft->data; +	 +	px->ui_wants_data = TRUE; +	try_write_to_ui( ft, 0, 0 ); +	 +	return FALSE; +} + + +/* Generic (IM<>UI): */  static void prplcb_xfer_destroy( PurpleXfer *xfer )  {  	struct prpl_xfer_data *px = xfer->ui_data; @@ -196,8 +188,6 @@ static void prplcb_xfer_progress( PurpleXfer *xfer, double percent )  {  	struct prpl_xfer_data *px = xfer->ui_data; -	fprintf( stderr, "prplcb_xfer_progress 0x%p %f\n", xfer, percent ); -	  	if( px->fd == -1 && percent > 0 )  	{  		/* Weeeeeeeee, we're getting data! That means the file exists @@ -205,12 +195,16 @@ static void prplcb_xfer_progress( PurpleXfer *xfer, double percent )  		px->fd = open( px->fn, O_RDONLY );  		/* Unlink it now, because we don't need it after this. */ -		//unlink( px->fn ); +		unlink( px->fn );  	}  	if( percent < 1 )  		try_write_to_ui( px->ft, 0, 0 );  	else +		/* Another nice problem: If we have the whole file, it only +		   gets closed when we return. Problem: There may still be +		   stuff buffered and not written, we'll only see it after +		   the caller close()s the file. So poll the file after that. */  		b_timeout_add( 0, try_write_to_ui, px->ft );  } @@ -226,18 +220,12 @@ static void prplcb_xfer_dbg( PurpleXfer *xfer )  	fprintf( stderr, "prplcb_xfer_dbg 0x%p\n", xfer );  } -PurpleXferUiOps bee_xfer_uiops = + +/* Sending files (UI->IM): */ +static gboolean prpl_xfer_write( struct file_transfer *ft, char *buffer, unsigned int len )  { -	prplcb_xfer_new, -	prplcb_xfer_destroy, -	prplcb_xfer_dbg, -	prplcb_xfer_progress, -	prplcb_xfer_dbg, -	prplcb_xfer_cancel_remote, -	NULL, -	NULL, -	prplcb_xfer_dbg, -}; +	return FALSE; +}  void purple_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *handle )  { @@ -254,3 +242,19 @@ void purple_transfer_request( struct im_connection *ic, file_transfer_t *ft, cha  	px = ft->data;  	imcb_file_recv_start( ft );  } + + + + +PurpleXferUiOps bee_xfer_uiops = +{ +	prplcb_xfer_new, +	prplcb_xfer_destroy, +	prplcb_xfer_dbg, +	prplcb_xfer_progress, +	prplcb_xfer_dbg, +	prplcb_xfer_cancel_remote, +	NULL, +	NULL, +	prplcb_xfer_dbg, +}; diff --git a/protocols/purple/purple.c b/protocols/purple/purple.c index eb3a4eb5..2507bfc2 100644 --- a/protocols/purple/purple.c +++ b/protocols/purple/purple.c @@ -141,10 +141,11 @@ static void purple_init( account_t *acc )  			{  				PurpleKeyValuePair *kv = io->data;  				opts = g_slist_append( opts, kv->value ); +				/* TODO: kv->value is not a char*, WTF? */  				if( strcmp( kv->value, kv->key ) != 0 ) -					g_string_append_printf( help, "%s (%s), ", kv->value, kv->key ); +					g_string_append_printf( help, "%s (%s), ", (char*) kv->value, kv->key );  				else -					g_string_append_printf( help, "%s, ", kv->value ); +					g_string_append_printf( help, "%s, ", (char*) kv->value );  			}  			g_string_truncate( help, help->len - 2 );  			eval = set_eval_list; @@ -454,7 +455,7 @@ void purple_chat_invite( struct groupchat *gc, char *who, char *message )  	                  who );  } -void purple_chat_leave( struct groupchat *gc, char *who ) +void purple_chat_leave( struct groupchat *gc )  {  	PurpleConversation *pc = gc->data; | 
