Changes in dcc.c [0cb71a6:9d4352c]
Legend:
- Unmodified
- Added
- Removed
-
dcc.c
r0cb71a6 r9d4352c 61 61 unsigned int receivedchunks=0, receiveddata=0; 62 62 63 staticvoid dcc_finish( file_transfer_t *file );64 staticvoid dcc_close( file_transfer_t *file );63 void dcc_finish( file_transfer_t *file ); 64 void dcc_close( file_transfer_t *file ); 65 65 gboolean 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 ); 66 int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr ); 68 67 gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond); 69 68 gboolean dccs_recv_write_request( file_transfer_t *ft ); … … 71 70 gboolean dcc_abort( dcc_file_transfer_t *df, char *reason, ... ); 72 71 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 ) 72 dcc_file_transfer_t *dcc_alloc_transfer( const char *file_name, size_t file_size, struct im_connection *ic ) 112 73 { 113 74 file_transfer_t *file = g_new0( file_transfer_t, 1 ); … … 117 78 file->file_name = g_strdup( file_name ); 118 79 file->local_id = local_transfer_id++; 119 df->ic = ic;80 file->ic = df->ic = ic; 120 81 df->ft = file; 121 82 … … 124 85 125 86 /* 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 )87 file_transfer_t *dccs_send_start( struct im_connection *ic, irc_user_t *iu, const char *file_name, size_t file_size ) 127 88 { 128 89 file_transfer_t *file; 129 90 dcc_file_transfer_t *df; 91 irc_t *irc = (irc_t *) ic->bee->ui_data; 130 92 struct sockaddr_storage saddr; 131 93 char *errmsg; … … 150 112 file->status = FT_STATUS_LISTENING; 151 113 152 if( !dccs_send_request( df, user_nick, &saddr ) )114 if( !dccs_send_request( df, iu, &saddr ) ) 153 115 return NULL; 154 116 155 117 /* 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 ); 159 121 160 122 df->progress_timeout = b_timeout_add( DCC_MAX_STALL * 1000, dcc_progress, df ); … … 163 125 "Accept the file transfer if you'd like the file. If you don't, " 164 126 "issue the 'transfers reject' command.", 165 user_nick, file_name, file_size / 1024 );127 iu->nick, file_name, file_size / 1024 ); 166 128 167 129 return file; … … 216 178 217 179 /* 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 )180 int dccs_send_request( struct dcc_file_transfer *df, irc_user_t *iu, struct sockaddr_storage *saddr ) 219 181 { 220 182 char ipaddr[INET6_ADDRSTRLEN]; … … 250 212 df->ft->file_name, ipaddr, port, df->ft->file_size ); 251 213 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 ); 254 215 255 216 g_free( cmd ); … … 267 228 file_transfer_t *file = df->ft; 268 229 269 if( ( cond & B_EV_IO_READ ) &&230 if( ( cond & GAIM_INPUT_READ ) && 270 231 ( file->status & FT_STATUS_LISTENING ) ) 271 232 { … … 287 248 288 249 /* 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 ); 290 251 291 252 return FALSE; 292 253 } 293 254 294 if( cond & B_EV_IO_READ )255 if( cond & GAIM_INPUT_READ ) 295 256 { 296 257 int ret; … … 364 325 365 326 /* 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 ); 367 328 ft->write_request = dccs_recv_write_request; 368 329 … … 377 338 file_transfer_t *ft = df->ft; 378 339 379 if( ( cond & B_EV_IO_WRITE ) &&340 if( ( cond & GAIM_INPUT_WRITE ) && 380 341 ( ft->status & FT_STATUS_CONNECTING ) ) 381 342 { 382 343 ft->status = FT_STATUS_TRANSFERRING; 383 344 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 ); 385 346 386 347 df->watch_out = 0; … … 388 349 } 389 350 390 if( cond & B_EV_IO_READ )351 if( cond & GAIM_INPUT_READ ) 391 352 { 392 353 int ret, done; … … 445 406 return dcc_abort( df, "BUG: write_request() called while watching" ); 446 407 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 ); 448 409 449 410 return TRUE; … … 488 449 489 450 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 ); 491 452 492 453 return TRUE; … … 496 457 * Cleans up after a transfer. 497 458 */ 498 staticvoid dcc_close( file_transfer_t *file )459 void dcc_close( file_transfer_t *file ) 499 460 { 500 461 dcc_file_transfer_t *df = file->priv; 462 irc_t *irc = (irc_t *) df->ic->bee->ui_data; 501 463 502 464 if( file->free ) … … 514 476 b_event_remove( df->progress_timeout ); 515 477 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 ); 517 479 518 480 g_free( df ); … … 542 504 * 543 505 */ 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; 506 file_transfer_t *dcc_request( struct im_connection *ic, char* const* ctcp ) 507 { 508 irc_t *irc = (irc_t *) ic->bee->ui_data; 553 509 file_transfer_t *ft; 554 510 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 { 573 518 char *filename, *host, *port; 574 size_t filesize;575 519 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' ) 579 526 { 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] ) ) }; 594 528 host = inet_ntoa( ipaddr ); 595 529 } else 596 530 { 597 531 /* Contains non-numbers, hopefully an IPV6 address */ 598 host = input + pmatch[7].rm_so;532 host = ctcp[3]; 599 533 } 600 534 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] ); 606 537 607 538 memset( &hints, 0, sizeof ( struct addrinfo ) ); … … 611 542 if ( ( gret = getaddrinfo( host, port, &hints, &rp ) ) ) 612 543 { 613 g_free( input );614 544 imcb_log( ic, "DCC: getaddrinfo() failed with %s " 615 545 "when parsing incoming 'DCC SEND': " … … 625 555 626 556 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 ); 630 559 631 560 return ft; 632 561 } 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" ); 635 564 636 565 return NULL;
Note: See TracChangeset
for help on using the changeset viewer.