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.c307
1 files changed, 149 insertions, 158 deletions
diff --git a/protocols/purple/ft.c b/protocols/purple/ft.c
index c4efc657..28f5d228 100644
--- a/protocols/purple/ft.c
+++ b/protocols/purple/ft.c
@@ -33,8 +33,7 @@
#include <glib.h>
#include <purple.h>
-struct prpl_xfer_data
-{
+struct prpl_xfer_data {
PurpleXfer *xfer;
file_transfer_t *ft;
struct im_connection *ic;
@@ -45,297 +44,289 @@ 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 );
+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);
/* Receiving files (IM->UI): */
-static void prpl_xfer_accept( struct file_transfer *ft )
+static void prpl_xfer_accept(struct file_transfer *ft)
{
struct prpl_xfer_data *px = ft->data;
- purple_xfer_request_accepted( px->xfer, NULL );
- prpl_xfer_write_request( ft );
+
+ purple_xfer_request_accepted(px->xfer, NULL);
+ prpl_xfer_write_request(ft);
}
-static void prpl_xfer_canceled( struct file_transfer *ft, char *reason )
+static void prpl_xfer_canceled(struct file_transfer *ft, char *reason)
{
struct prpl_xfer_data *px = ft->data;
- purple_xfer_request_denied( px->xfer );
+
+ purple_xfer_request_denied(px->xfer);
}
-static void prplcb_xfer_new( PurpleXfer *xfer )
+static void prplcb_xfer_new(PurpleXfer *xfer)
{
- if( purple_xfer_get_type( xfer ) == PURPLE_XFER_RECEIVE )
- {
- struct prpl_xfer_data *px = g_new0( struct prpl_xfer_data, 1 );
-
+ if (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) {
+ struct prpl_xfer_data *px = g_new0(struct prpl_xfer_data, 1);
+
xfer->ui_data = px;
px->xfer = xfer;
- px->fn = mktemp( g_strdup( "/tmp/bitlbee-purple-ft.XXXXXX" ) );
+ px->fn = mktemp(g_strdup("/tmp/bitlbee-purple-ft.XXXXXX"));
px->fd = -1;
- px->ic = purple_ic_by_pa( xfer->account );
-
- purple_xfer_set_local_filename( xfer, px->fn );
-
+ px->ic = purple_ic_by_pa(xfer->account);
+
+ purple_xfer_set_local_filename(xfer, px->fn);
+
/* Sadly the xfer struct is still empty ATM so come back after
the caller is done. */
- b_timeout_add( 0, prplcb_xfer_new_send_cb, xfer );
- }
- else
- {
+ b_timeout_add(0, prplcb_xfer_new_send_cb, xfer);
+ } else {
struct file_transfer *ft = next_ft;
struct prpl_xfer_data *px = ft->data;
-
+
xfer->ui_data = px;
px->xfer = xfer;
-
+
next_ft = NULL;
}
}
-static gboolean prplcb_xfer_new_send_cb( gpointer data, gint fd, b_input_condition cond )
+static gboolean prplcb_xfer_new_send_cb(gpointer data, gint fd, b_input_condition cond)
{
PurpleXfer *xfer = data;
- struct im_connection *ic = purple_ic_by_pa( xfer->account );
+ struct im_connection *ic = purple_ic_by_pa(xfer->account);
struct prpl_xfer_data *px = xfer->ui_data;
PurpleBuddy *buddy;
const char *who;
-
- buddy = purple_find_buddy( xfer->account, xfer->who );
- who = buddy ? purple_buddy_get_name( buddy ) : xfer->who;
-
+
+ buddy = purple_find_buddy(xfer->account, xfer->who);
+ who = buddy ? purple_buddy_get_name(buddy) : xfer->who;
+
/* TODO(wilmer): After spreading some more const goodness in BitlBee,
remove the evil cast below. */
- px->ft = imcb_file_send_start( ic, (char*) who, xfer->filename, xfer->size );
+ px->ft = imcb_file_send_start(ic, (char *) who, xfer->filename, xfer->size);
px->ft->data = px;
-
+
px->ft->accept = prpl_xfer_accept;
px->ft->canceled = prpl_xfer_canceled;
px->ft->write_request = prpl_xfer_write_request;
-
+
return FALSE;
}
-gboolean try_write_to_ui( gpointer data, gint fd, b_input_condition cond )
+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 )
+ 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 )
- {
+ }
+
+ 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 ) )
- {
+ 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( px->ic, ft, "Read error" );
+ } else {
+ purple_xfer_cancel_local(px->xfer);
+ imcb_file_canceled(px->ic, ft, "Read error");
}
}
-
- if( lseek( px->fd, 0, SEEK_CUR ) == px->xfer->size )
- {
+
+ if (lseek(px->fd, 0, SEEK_CUR) == px->xfer->size) {
/*purple_xfer_end( px->xfer );*/
- imcb_file_finished( px->ic, ft );
+ imcb_file_finished(px->ic, 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 )
+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 );
-
+ try_write_to_ui(ft, 0, 0);
+
return FALSE;
}
/* Generic (IM<>UI): */
-static void prplcb_xfer_destroy( PurpleXfer *xfer )
+static void prplcb_xfer_destroy(PurpleXfer *xfer)
{
struct prpl_xfer_data *px = xfer->ui_data;
-
- g_free( px->fn );
- g_free( px->handle );
- if( px->fd >= 0 )
- close( px->fd );
- g_free( px );
+
+ g_free(px->fn);
+ g_free(px->handle);
+ if (px->fd >= 0) {
+ close(px->fd);
+ }
+ g_free(px);
}
-static void prplcb_xfer_progress( PurpleXfer *xfer, double percent )
+static void prplcb_xfer_progress(PurpleXfer *xfer, double percent)
{
struct prpl_xfer_data *px = xfer->ui_data;
-
- if( px == NULL )
+
+ if (px == NULL) {
return;
-
- if( purple_xfer_get_type( xfer ) == PURPLE_XFER_SEND )
- {
- if( *px->fn )
- {
+ }
+
+ if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
+ if (*px->fn) {
char *slash;
-
- unlink( px->fn );
- if( ( slash = strrchr( px->fn, '/' ) ) )
- {
+
+ unlink(px->fn);
+ if ((slash = strrchr(px->fn, '/'))) {
*slash = '\0';
- rmdir( px->fn );
+ rmdir(px->fn);
}
*px->fn = '\0';
}
-
+
return;
}
-
- if( px->fd == -1 && percent > 0 )
- {
+
+ if (px->fd == -1 && percent > 0) {
/* Weeeeeeeee, we're getting data! That means the file exists
by now so open it and start sending to the UI. */
- px->fd = open( px->fn, O_RDONLY );
-
+ 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
+
+ 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 );
+ b_timeout_add(0, try_write_to_ui, px->ft);
+ }
}
-static void prplcb_xfer_cancel_remote( PurpleXfer *xfer )
+static void prplcb_xfer_cancel_remote(PurpleXfer *xfer)
{
struct prpl_xfer_data *px = xfer->ui_data;
-
- if( px->ft )
- imcb_file_canceled( px->ic, px->ft, "Canceled by remote end" );
- else
+
+ if (px->ft) {
+ imcb_file_canceled(px->ic, px->ft, "Canceled by remote end");
+ } else {
/* px->ft == NULL for sends, because of the two stages. :-/ */
- imcb_error( px->ic, "File transfer cancelled by remote end" );
+ imcb_error(px->ic, "File transfer cancelled by remote end");
+ }
}
-static void prplcb_xfer_dbg( PurpleXfer *xfer )
+static void prplcb_xfer_dbg(PurpleXfer *xfer)
{
- fprintf( stderr, "prplcb_xfer_dbg 0x%p\n", xfer );
+ fprintf(stderr, "prplcb_xfer_dbg 0x%p\n", xfer);
}
/* Sending files (UI->IM): */
-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 );
+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 )
+void purple_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *handle)
{
- struct prpl_xfer_data *px = g_new0( struct prpl_xfer_data, 1 );
+ struct prpl_xfer_data *px = g_new0(struct prpl_xfer_data, 1);
char *dir, *basename;
-
+
ft->data = px;
px->ft = ft;
-
- dir = g_strdup( "/tmp/bitlbee-purple-ft.XXXXXX" );
- if( !mkdtemp( dir ) )
- {
- imcb_error( ic, "Could not create temporary file for file transfer" );
- g_free( px );
- g_free( dir );
+
+ dir = g_strdup("/tmp/bitlbee-purple-ft.XXXXXX");
+ if (!mkdtemp(dir)) {
+ imcb_error(ic, "Could not create temporary file for file transfer");
+ g_free(px);
+ g_free(dir);
return;
}
-
- if( ( basename = strrchr( ft->file_name, '/' ) ) )
+
+ if ((basename = strrchr(ft->file_name, '/'))) {
basename++;
- else
+ } else {
basename = ft->file_name;
- px->fn = g_strdup_printf( "%s/%s", dir, basename );
- px->fd = open( px->fn, O_WRONLY | O_CREAT, 0600 );
- g_free( dir );
-
- if( px->fd < 0 )
- {
- imcb_error( ic, "Could not create temporary file for file transfer" );
- g_free( px );
- g_free( px->fn );
+ }
+ px->fn = g_strdup_printf("%s/%s", dir, basename);
+ px->fd = open(px->fn, O_WRONLY | O_CREAT, 0600);
+ g_free(dir);
+
+ if (px->fd < 0) {
+ imcb_error(ic, "Could not create temporary file for file transfer");
+ g_free(px);
+ g_free(px->fn);
return;
}
-
+
px->ic = ic;
- px->handle = g_strdup( handle );
-
- 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 );
+ px->handle = g_strdup(handle);
+
+ 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);
}
-static void purple_transfer_forward( struct file_transfer *ft )
+static void purple_transfer_forward(struct file_transfer *ft)
{
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 ), px->handle, px->fn );
+ 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 )
+static gboolean purple_transfer_request_cb(gpointer data, gint fd, b_input_condition cond)
{
file_transfer_t *ft = data;
struct prpl_xfer_data *px = ft->data;
-
- if( ft->write == NULL )
- {
+
+ if (ft->write == NULL) {
ft->write = prpl_xfer_write;
- imcb_file_recv_start( px->ic, ft );
+ imcb_file_recv_start(px->ic, ft);
}
-
- ft->write_request( ft );
-
+
+ ft->write_request(ft);
+
return FALSE;
}
-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)
{
struct prpl_xfer_data *px = ft->data;
-
- if( write( px->fd, buffer, len ) != len )
- {
- imcb_file_canceled( px->ic, ft, "Error while writing temporary file" );
+
+ if (write(px->fd, buffer, len) != len) {
+ imcb_file_canceled(px->ic, ft, "Error while writing temporary file");
return FALSE;
}
-
- if( lseek( px->fd, 0, SEEK_CUR ) >= ft->file_size )
- {
- close( px->fd );
+
+ if (lseek(px->fd, 0, SEEK_CUR) >= ft->file_size) {
+ close(px->fd);
px->fd = -1;
-
- purple_transfer_forward( ft );
- imcb_file_finished( px->ic, ft );
+
+ purple_transfer_forward(ft);
+ imcb_file_finished(px->ic, ft);
px->ft = NULL;
+ } else {
+ b_timeout_add(0, purple_transfer_request_cb, ft);
}
- else
- b_timeout_add( 0, purple_transfer_request_cb, ft );
-
+
return TRUE;
}