Changeset 8822d23


Ignore:
Timestamp:
2010-05-17T23:23:20Z (9 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
5d1b3a95
Parents:
553767c
Message:

This receives files but is very fragile if anything unusual happens (like a
cancellation/timeout/etc).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/purple/ft.c

    r553767c r8822d23  
    3838        PurpleXfer *xfer;
    3939        file_transfer_t *ft;
    40         gint ready_timer;
    41         char *buf;
    42         int buf_len;
     40        int fd;
     41        char *fn;
     42        gboolean ui_wants_data;
    4343};
    4444
     
    4747struct im_connection *purple_ic_by_pa( PurpleAccount *pa );
    4848
     49gboolean try_write_to_ui( gpointer data, gint fd, b_input_condition cond )
     50{
     51        struct file_transfer *ft = data;
     52        struct prpl_xfer_data *px = ft->data;
     53        struct stat fs;
     54        off_t tx_bytes;
     55       
     56        fprintf( stderr, "write_to_ui\n" );
     57       
     58        /* If we don't have the file opened yet, there's no data so wait. */
     59        if( px->fd < 0 || !px->ui_wants_data )
     60                return FALSE;
     61       
     62        tx_bytes = lseek( px->fd, 0, SEEK_CUR );
     63        fstat( px->fd, &fs );
     64       
     65        fprintf( stderr, "write_to_ui %zd %zd %zd\n", fs.st_size, tx_bytes, px->xfer->size );
     66       
     67        if( fs.st_size > tx_bytes )
     68        {
     69                char buf[1024];
     70                size_t n = MIN( fs.st_size - tx_bytes, sizeof( buf ) );
     71               
     72                if( read( px->fd, buf, n ) == n && ft->write( ft, buf, n ) )
     73                {
     74                        fprintf( stderr, "Wrote %zd bytes\n", n );
     75                        px->ui_wants_data = FALSE;
     76                }
     77                else
     78                {
     79                        purple_xfer_cancel_local( px->xfer );
     80                        imcb_file_canceled( ft, "Read error" );
     81                }
     82        }
     83       
     84        if( lseek( px->fd, 0, SEEK_CUR ) == px->xfer->size )
     85        {
     86                purple_xfer_end( px->xfer );
     87                imcb_file_finished( ft );
     88        }
     89       
     90        return FALSE;
     91}
     92
     93/* UI calls this when its buffer is empty and wants more data to send to the user. */
    4994static gboolean prpl_xfer_write_request( struct file_transfer *ft )
    5095{
     96        struct prpl_xfer_data *px = ft->data;
     97       
     98        fprintf( stderr, "wrq\n" );
     99       
     100        px->ui_wants_data = TRUE;
     101        try_write_to_ui( ft, 0, 0 );
     102       
    51103        return FALSE;
    52104}
     
    54106static gboolean prpl_xfer_write( struct file_transfer *ft, char *buffer, unsigned int len )
    55107{
    56         struct prpl_xfer_data *px = ft->data;
    57        
    58108        return FALSE;
    59109}
     
    78128        if( purple_xfer_get_type( xfer ) == PURPLE_XFER_RECEIVE )
    79129        {
    80                 /* This should suppress the stupid file dialog. */
    81                 purple_xfer_set_local_filename( xfer, "/tmp/wtf123" );
     130                struct prpl_xfer_data *px = g_new0( struct prpl_xfer_data, 1 );
     131               
     132                xfer->ui_data = px;
     133                px->xfer = xfer;
     134                px->fn = mktemp( g_strdup( "/tmp/bitlbee-purple-ft.XXXXXX" ) );
     135                px->fd = -1;
     136               
     137                purple_xfer_set_local_filename( xfer, px->fn );
    82138               
    83139                /* Sadly the xfer struct is still empty ATM so come back after
     
    90146                struct prpl_xfer_data *px = g_new0( struct prpl_xfer_data, 1 );
    91147               
     148                px->fd = -1;
    92149                px->ft = next_ft;
    93150                px->ft->data = px;
     
    107164        PurpleXfer *xfer = data;
    108165        struct im_connection *ic = purple_ic_by_pa( xfer->account );
    109         struct prpl_xfer_data *px = g_new0( struct prpl_xfer_data, 1 );
     166        struct prpl_xfer_data *px = xfer->ui_data;
    110167        PurpleBuddy *buddy;
    111168        const char *who;
     
    118175        px->ft = imcb_file_send_start( ic, (char*) who, xfer->filename, xfer->size );
    119176        px->ft->data = px;
    120         px->xfer = data;
    121         px->xfer->ui_data = px;
    122177       
    123178        px->ft->accept = prpl_xfer_accept;
     
    128183}
    129184
     185static void prplcb_xfer_destroy( PurpleXfer *xfer )
     186{
     187        struct prpl_xfer_data *px = xfer->ui_data;
     188       
     189        g_free( px->fn );
     190        if( px->fd >= 0 )
     191                close( px->fd );
     192        g_free( px );
     193}
     194
    130195static void prplcb_xfer_progress( PurpleXfer *xfer, double percent )
    131196{
    132         fprintf( stderr, "prplcb_xfer_dbg 0x%p %f\n", xfer, percent );
     197        struct prpl_xfer_data *px = xfer->ui_data;
     198       
     199        fprintf( stderr, "prplcb_xfer_progress 0x%p %f\n", xfer, percent );
     200       
     201        if( px->fd == -1 && percent > 0 )
     202        {
     203                /* Weeeeeeeee, we're getting data! That means the file exists
     204                   by now so open it and start sending to the UI. */
     205                px->fd = open( px->fn, O_RDONLY );
     206               
     207                /* Unlink it now, because we don't need it after this. */
     208                //unlink( px->fn );
     209        }
     210       
     211        if( percent < 1 )
     212                try_write_to_ui( px->ft, 0, 0 );
     213        else
     214                b_timeout_add( 0, try_write_to_ui, px->ft );
     215}
     216
     217static void prplcb_xfer_cancel_remote( PurpleXfer *xfer )
     218{
     219        struct prpl_xfer_data *px = xfer->ui_data;
     220       
     221        imcb_file_canceled( px->ft, "Canceled by remote end" );
    133222}
    134223
     
    141230{
    142231        prplcb_xfer_new,
    143         prplcb_xfer_dbg,
     232        prplcb_xfer_destroy,
    144233        prplcb_xfer_dbg,
    145234        prplcb_xfer_progress,
    146235        prplcb_xfer_dbg,
    147         prplcb_xfer_dbg,
     236        prplcb_xfer_cancel_remote,
    148237        NULL,
    149238        NULL,
     
    151240};
    152241
    153 static gboolean prplcb_xfer_send_cb( gpointer data, gint fd, b_input_condition cond );
    154 
    155242void purple_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *handle )
    156243{
Note: See TracChangeset for help on using the changeset viewer.