aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-05-19 01:57:58 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-05-19 01:57:58 +0100
commite7dc02a89d846d27b63719a5093c2e2a295fc232 (patch)
tree86058fd1959cd29ccd32274357b796641df0f932
parent31fc06fbb48b6217186ca441eb9b95add5f783ce (diff)
Similar hacky code to send files. This indirect sending stuff sucks badly
for numerous reasons. Maybe libpurple 2.7.0 is less crappy and will eventually allow (working) direct ft's again. This somewhat works, but filename info is lost with some protocols.
-rw-r--r--protocols/purple/ft.c113
1 files changed, 93 insertions, 20 deletions
diff --git a/protocols/purple/ft.c b/protocols/purple/ft.c
index 8cfa60dd..ab637a94 100644
--- a/protocols/purple/ft.c
+++ b/protocols/purple/ft.c
@@ -37,8 +37,9 @@ struct prpl_xfer_data
{
PurpleXfer *xfer;
file_transfer_t *ft;
+ struct im_connection *ic;
int fd;
- char *fn;
+ char *fn, *orig_fn, *handle;
gboolean ui_wants_data;
};
@@ -82,20 +83,16 @@ static void prplcb_xfer_new( PurpleXfer *xfer )
}
else
{
- /*
- struct prpl_xfer_data *px = g_new0( struct prpl_xfer_data, 1 );
+ struct file_transfer *ft = next_ft;
+ struct prpl_xfer_data *px = ft->data;
- px->fd = -1;
- px->ft = next_ft;
- px->ft->data = px;
+ xfer->ui_data = px;
px->xfer = xfer;
- px->xfer->ui_data = px;
- purple_xfer_set_filename( xfer, px->ft->file_name );
- purple_xfer_set_size( xfer, px->ft->file_size );
+ purple_xfer_set_filename( xfer, px->orig_fn );
+ purple_xfer_set_local_filename( xfer, px->fn );
next_ft = NULL;
- */
}
}
@@ -179,6 +176,8 @@ static void prplcb_xfer_destroy( PurpleXfer *xfer )
struct prpl_xfer_data *px = xfer->ui_data;
g_free( px->fn );
+ g_free( px->orig_fn );
+ g_free( px->handle );
if( px->fd >= 0 )
close( px->fd );
g_free( px );
@@ -188,6 +187,20 @@ static void prplcb_xfer_progress( PurpleXfer *xfer, double percent )
{
struct prpl_xfer_data *px = xfer->ui_data;
+ if( px == NULL )
+ return;
+
+ if( purple_xfer_get_type( xfer ) == PURPLE_XFER_SEND )
+ {
+ if( *px->fn )
+ {
+ //unlink( px->fn );
+ *px->fn = '\0';
+ }
+
+ return;
+ }
+
if( px->fd == -1 && percent > 0 )
{
/* Weeeeeeeee, we're getting data! That means the file exists
@@ -215,6 +228,16 @@ static void prplcb_xfer_cancel_remote( PurpleXfer *xfer )
imcb_file_canceled( px->ft, "Canceled by remote end" );
}
+static void prplcb_xfer_add( PurpleXfer *xfer )
+{
+ if( purple_xfer_get_type( xfer ) == PURPLE_XFER_SEND )
+ {
+ struct prpl_xfer_data *px = xfer->ui_data;
+
+ purple_xfer_set_filename( xfer, px->orig_fn );
+ }
+}
+
static void prplcb_xfer_dbg( PurpleXfer *xfer )
{
fprintf( stderr, "prplcb_xfer_dbg 0x%p\n", xfer );
@@ -222,27 +245,77 @@ static void prplcb_xfer_dbg( PurpleXfer *xfer )
/* Sending files (UI->IM): */
-static gboolean prpl_xfer_write( struct file_transfer *ft, char *buffer, unsigned int len )
+static gboolean prpl_xfer_write( struct file_transfer *ft, char *buffer, unsigned int len );
+static gboolean purple_transfer_request_cb( gpointer data, gint fd, b_input_condition cond );
+
+void purple_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *handle )
{
- return FALSE;
+ struct prpl_xfer_data *px = g_new0( struct prpl_xfer_data, 1 );
+
+ ft->data = px;
+ px->ft = ft;
+ px->fn = g_strdup( "/tmp/bitlbee-purple-ft.XXXXXX" );
+ px->fd = mkstemp( px->fn );
+
+ px->ic = ic;
+ px->handle = g_strdup( handle );
+ px->orig_fn = g_strdup( ft->file_name );
+
+ imcb_log( ic, "Due to libpurple limitations, the file has to be cached locally before proceeding with the actual file transfer. Please wait..." );
+
+ b_timeout_add( 0, purple_transfer_request_cb, ft );
}
-void purple_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *handle )
+static void purple_transfer_forward( struct file_transfer *ft )
{
- PurpleAccount *pa = ic->proto_data;
- struct prpl_xfer_data *px;
+ struct prpl_xfer_data *px = ft->data;
+ PurpleAccount *pa = px->ic->proto_data;
/* xfer_new() will pick up this variable. It's a hack but we're not
multi-threaded anyway. */
next_ft = ft;
- serv_send_file( purple_account_get_connection( pa ), handle, ft->file_name );
+ serv_send_file( purple_account_get_connection( pa ), px->handle, px->fn );
+}
+
+static gboolean purple_transfer_request_cb( gpointer data, gint fd, b_input_condition cond )
+{
+ file_transfer_t *ft = data;
+
+ if( ft->write == NULL )
+ {
+ ft->write = prpl_xfer_write;
+ imcb_file_recv_start( ft );
+ }
- ft->write = prpl_xfer_write;
+ ft->write_request( ft );
- px = ft->data;
- imcb_file_recv_start( ft );
+ return FALSE;
}
+static gboolean prpl_xfer_write( struct file_transfer *ft, char *buffer, unsigned int len )
+{
+ struct prpl_xfer_data *px = ft->data;
+
+ if( write( px->fd, buffer, len ) != len )
+ {
+ imcb_file_canceled( ft, "Error while writing temporary file" );
+ return FALSE;
+ }
+
+ if( lseek( px->fd, 0, SEEK_CUR ) >= ft->file_size )
+ {
+ close( px->fd );
+ px->fd = -1;
+
+ purple_transfer_forward( ft );
+ imcb_file_finished( ft );
+ px->ft = NULL;
+ }
+ else
+ b_timeout_add( 0, purple_transfer_request_cb, ft );
+
+ return TRUE;
+}
@@ -250,7 +323,7 @@ PurpleXferUiOps bee_xfer_uiops =
{
prplcb_xfer_new,
prplcb_xfer_destroy,
- prplcb_xfer_dbg,
+ prplcb_xfer_add,
prplcb_xfer_progress,
prplcb_xfer_dbg,
prplcb_xfer_cancel_remote,