aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/purple/ft.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/purple/ft.c')
-rw-r--r--protocols/purple/ft.c158
1 files changed, 81 insertions, 77 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,
+};