Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • dcc.c

    r0cb71a6 r9d4352c  
    6161unsigned int receivedchunks=0, receiveddata=0;
    6262
    63 static void dcc_finish( file_transfer_t *file );
    64 static void dcc_close( file_transfer_t *file );
     63void dcc_finish( file_transfer_t *file );
     64void dcc_close( file_transfer_t *file );
    6565gboolean dccs_send_proto( gpointer data, gint fd, b_input_condition cond );
    66 int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr );
    67 gboolean dccs_recv_start( file_transfer_t *ft );
     66int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr );
    6867gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond);
    6968gboolean dccs_recv_write_request( file_transfer_t *ft );
     
    7170gboolean dcc_abort( dcc_file_transfer_t *df, char *reason, ... );
    7271
    73 /* As defined in ft.h */
    74 file_transfer_t *imcb_file_send_start( struct im_connection *ic, char *handle, char *file_name, size_t file_size )
    75 {
    76         user_t *u = user_findhandle( ic, handle );
    77         /* one could handle this more intelligent like imcb_buddy_msg.
    78          * can't call it directly though cause it does some wrapping.
    79          * Maybe give imcb_buddy_msg a parameter NO_WRAPPING? */
    80         if (!u) return NULL;
    81 
    82         return dccs_send_start( ic, u->nick, file_name, file_size );
    83 };
    84 
    85 /* As defined in ft.h */
    86 void imcb_file_canceled( file_transfer_t *file, char *reason )
    87 {
    88         if( file->canceled )
    89                 file->canceled( file, reason );
    90 
    91         dcc_close( file );
    92 }
    93 
    94 /* As defined in ft.h */
    95 gboolean imcb_file_recv_start( file_transfer_t *ft )
    96 {
    97         return dccs_recv_start( ft );
    98 }
    99 
    100 /* As defined in ft.h */
    101 void imcb_file_finished( file_transfer_t *file )
    102 {
    103         dcc_file_transfer_t *df = file->priv;
    104 
    105         if( file->bytes_transferred >= file->file_size )
    106                 dcc_finish( file );
    107         else
    108                 df->proto_finished = TRUE;
    109 }
    110 
    111 dcc_file_transfer_t *dcc_alloc_transfer( char *file_name, size_t file_size, struct im_connection *ic )
     72dcc_file_transfer_t *dcc_alloc_transfer( const char *file_name, size_t file_size, struct im_connection *ic )
    11273{
    11374        file_transfer_t *file = g_new0( file_transfer_t, 1 );
     
    11778        file->file_name = g_strdup( file_name );
    11879        file->local_id = local_transfer_id++;
    119         df->ic = ic;
     80        file->ic = df->ic = ic;
    12081        df->ft = file;
    12182       
     
    12485
    12586/* This is where the sending magic starts... */
    126 file_transfer_t *dccs_send_start( struct im_connection *ic, char *user_nick, char *file_name, size_t file_size )
     87file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, const char *file_name, size_t file_size )
    12788{
    12889        file_transfer_t *file;
    12990        dcc_file_transfer_t *df;
     91        irc_t *irc = (irc_t *) ic->bee->ui_data;
    13092        struct sockaddr_storage saddr;
    13193        char *errmsg;
     
    150112        file->status = FT_STATUS_LISTENING;
    151113
    152         if( !dccs_send_request( df, user_nick, &saddr ) )
     114        if( !dccs_send_request( df, iu, &saddr ) )
    153115                return NULL;
    154116
    155117        /* watch */
    156         df->watch_in = b_input_add( df->fd, B_EV_IO_READ, dccs_send_proto, df );
    157 
    158         df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, file );
     118        df->watch_in = b_input_add( df->fd, GAIM_INPUT_READ, dccs_send_proto, df );
     119
     120        irc->file_transfers = g_slist_prepend( irc->file_transfers, file );
    159121
    160122        df->progress_timeout = b_timeout_add( DCC_MAX_STALL * 1000, dcc_progress, df );
     
    163125                      "Accept the file transfer if you'd like the file. If you don't, "
    164126                      "issue the 'transfers reject' command.",
    165                       user_nick, file_name, file_size / 1024 );
     127                      iu->nick, file_name, file_size / 1024 );
    166128
    167129        return file;
     
    216178
    217179/* Creates the "DCC SEND" line and sends it to the server */
    218 int dccs_send_request( struct dcc_file_transfer *df, char *user_nick, struct sockaddr_storage *saddr )
     180int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr )
    219181{
    220182        char ipaddr[INET6_ADDRSTRLEN];
     
    250212                                df->ft->file_name, ipaddr, port, df->ft->file_size );
    251213       
    252         if ( !irc_msgfrom( df->ic->irc, user_nick, cmd ) )
    253                 return dcc_abort( df, "Couldn't send `DCC SEND' message to %s.", user_nick );
     214        irc_send_msg_raw( iu, "PRIVMSG", iu->irc->user->nick, cmd );
    254215
    255216        g_free( cmd );
     
    267228        file_transfer_t *file = df->ft;
    268229       
    269         if( ( cond & B_EV_IO_READ ) &&
     230        if( ( cond & GAIM_INPUT_READ ) &&
    270231            ( file->status & FT_STATUS_LISTENING ) )
    271232        {       
     
    287248
    288249                /* reschedule for reading on new fd */
    289                 df->watch_in = b_input_add( fd, B_EV_IO_READ, dccs_send_proto, df );
     250                df->watch_in = b_input_add( fd, GAIM_INPUT_READ, dccs_send_proto, df );
    290251
    291252                return FALSE;
    292253        }
    293254
    294         if( cond & B_EV_IO_READ )
     255        if( cond & GAIM_INPUT_READ )
    295256        {
    296257                int ret;
     
    364325
    365326        /* watch */
    366         df->watch_out = b_input_add( df->fd, B_EV_IO_WRITE, dccs_recv_proto, df );
     327        df->watch_out = b_input_add( df->fd, GAIM_INPUT_WRITE, dccs_recv_proto, df );
    367328        ft->write_request = dccs_recv_write_request;
    368329
     
    377338        file_transfer_t *ft = df->ft;
    378339
    379         if( ( cond & B_EV_IO_WRITE ) &&
     340        if( ( cond & GAIM_INPUT_WRITE ) &&
    380341            ( ft->status & FT_STATUS_CONNECTING ) )
    381342        {
    382343                ft->status = FT_STATUS_TRANSFERRING;
    383344
    384                 //df->watch_in = b_input_add( df->fd, B_EV_IO_READ, dccs_recv_proto, df );
     345                //df->watch_in = b_input_add( df->fd, GAIM_INPUT_READ, dccs_recv_proto, df );
    385346
    386347                df->watch_out = 0;
     
    388349        }
    389350
    390         if( cond & B_EV_IO_READ )
     351        if( cond & GAIM_INPUT_READ )
    391352        {
    392353                int ret, done;
     
    445406                return dcc_abort( df, "BUG: write_request() called while watching" );
    446407
    447         df->watch_in = b_input_add( df->fd, B_EV_IO_READ, dccs_recv_proto, df );
     408        df->watch_in = b_input_add( df->fd, GAIM_INPUT_READ, dccs_recv_proto, df );
    448409
    449410        return TRUE;
     
    488449
    489450        if( df->bytes_sent < df->ft->file_size )
    490                 df->watch_out = b_input_add( df->fd, B_EV_IO_WRITE, dccs_send_can_write, df );
     451                df->watch_out = b_input_add( df->fd, GAIM_INPUT_WRITE, dccs_send_can_write, df );
    491452
    492453        return TRUE;
     
    496457 * Cleans up after a transfer.
    497458 */
    498 static void dcc_close( file_transfer_t *file )
     459void dcc_close( file_transfer_t *file )
    499460{
    500461        dcc_file_transfer_t *df = file->priv;
     462        irc_t *irc = (irc_t *) df->ic->bee->ui_data;
    501463
    502464        if( file->free )
     
    514476                b_event_remove( df->progress_timeout );
    515477       
    516         df->ic->irc->file_transfers = g_slist_remove( df->ic->irc->file_transfers, file );
     478        irc->file_transfers = g_slist_remove( irc->file_transfers, file );
    517479       
    518480        g_free( df );
     
    542504 *
    543505 */
    544 file_transfer_t *dcc_request( struct im_connection *ic, char *line )
    545 {
    546         char *pattern = "SEND"
    547                 " (([^\"][^ ]*)|\"(([^\"]|\\\")*)\")"
    548                 " (([0-9]*)|([^ ]*))"
    549                 " ([0-9]*)"
    550                 " ([0-9]*)\001";
    551         regmatch_t pmatch[10];
    552         regex_t re;
     506file_transfer_t *dcc_request( struct im_connection *ic, char* const* ctcp )
     507{
     508        irc_t *irc = (irc_t *) ic->bee->ui_data;
    553509        file_transfer_t *ft;
    554510        dcc_file_transfer_t *df;
    555         char errbuf[256];
    556         int regerrcode, gret;
    557 
    558         if( ( regerrcode = regcomp( &re, pattern, REG_EXTENDED ) ) ||
    559             ( regerrcode = regexec( &re, line, 10, pmatch, 0 ) ) ) {
    560                 regerror( regerrcode,&re,errbuf,sizeof( errbuf ) );
    561                 imcb_log( ic,
    562                           "DCC: error parsing 'DCC SEND': %s, line: %s",
    563                           errbuf, line );
    564                 return NULL;
    565         }
    566 
    567         if( ( pmatch[1].rm_so > 0 ) &&
    568             ( pmatch[5].rm_so > 0 ) &&
    569             ( pmatch[8].rm_so > 0 ) &&
    570             ( pmatch[9].rm_so > 0 ) )
    571         {
    572                 char *input = g_strdup( line );
     511        int gret;
     512        size_t filesize;
     513       
     514        if( ctcp[5] != NULL &&
     515            sscanf( ctcp[4], "%zd", &filesize ) == 1 && /* Just int. validation. */
     516            sscanf( ctcp[5], "%zd", &filesize ) == 1 )
     517        {
    573518                char *filename, *host, *port;
    574                 size_t filesize;
    575519                struct addrinfo hints, *rp;
    576 
    577                 /* "filename" or filename */
    578                 if ( pmatch[2].rm_so > 0 )
     520               
     521                filename = ctcp[2];
     522               
     523                host = ctcp[3];
     524                while( *host && isdigit( *host ) ) host++; /* Just digits? */
     525                if( *host == '\0' )
    579526                {
    580                         input[pmatch[2].rm_eo] = '\0';
    581                         filename = input + pmatch[2].rm_so;
    582                 } else
    583                 {
    584                         input[pmatch[3].rm_eo] = '\0';
    585                         filename = input + pmatch[3].rm_so;
    586                 }
    587                        
    588                 input[pmatch[5].rm_eo] = '\0';
    589 
    590                 /* number means ipv4, something else means ipv6 */
    591                 if ( pmatch[6].rm_so > 0 )
    592                 {
    593                         struct in_addr ipaddr = { .s_addr = htonl( strtoul( input + pmatch[5].rm_so, NULL, 10 ) ) };
     527                        struct in_addr ipaddr = { .s_addr = htonl( atoll( ctcp[3] ) ) };
    594528                        host = inet_ntoa( ipaddr );
    595529                } else
    596530                {
    597531                        /* Contains non-numbers, hopefully an IPV6 address */
    598                         host = input + pmatch[7].rm_so;
     532                        host = ctcp[3];
    599533                }
    600534
    601                 input[pmatch[8].rm_eo] = '\0';
    602                 input[pmatch[9].rm_eo] = '\0';
    603 
    604                 port = input + pmatch[8].rm_so;
    605                 filesize = atoll( input + pmatch[9].rm_so );
     535                port = ctcp[4];
     536                filesize = atoll( ctcp[5] );
    606537
    607538                memset( &hints, 0, sizeof ( struct addrinfo ) );
     
    611542                if ( ( gret = getaddrinfo( host, port, &hints, &rp ) ) )
    612543                {
    613                         g_free( input );
    614544                        imcb_log( ic, "DCC: getaddrinfo() failed with %s "
    615545                                  "when parsing incoming 'DCC SEND': "
     
    625555
    626556                freeaddrinfo( rp );
    627                 g_free( input );
    628 
    629                 df->ic->irc->file_transfers = g_slist_prepend( df->ic->irc->file_transfers, ft );
     557
     558                irc->file_transfers = g_slist_prepend( irc->file_transfers, ft );
    630559
    631560                return ft;
    632561        }
    633 
    634         imcb_log( ic, "DCC: couldnt parse 'DCC SEND' line: %s", line );
     562        else
     563                imcb_log( ic, "DCC: couldnt parse `DCC SEND' line" );
    635564
    636565        return NULL;
Note: See TracChangeset for help on using the changeset viewer.