summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2011-04-27 10:10:00 (UTC)
committer Michael Krelin <hacker@klever.net>2011-04-27 10:10:00 (UTC)
commitd097b824b7fcad001c9581fb2e322bf3e3e5961d (patch) (unidiff)
tree5a1c55e82c4b0ff4acca276b8e1122547530cc0b
parent65981784977659461f08b48f537be9f9f77a2112 (diff)
downloadpumpkin-d097b824b7fcad001c9581fb2e322bf3e3e5961d.zip
pumpkin-d097b824b7fcad001c9581fb2e322bf3e3e5961d.tar.gz
pumpkin-d097b824b7fcad001c9581fb2e322bf3e3e5961d.tar.bz2
fix for misleading error message about unexpected source
along with a double-freeing offense. When I fail to receive packet not only I diagnose this unfortunate development, but also start talking about packet from unexpected source which is kinda weird considering there's no packet at all. Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (more/less context) (ignore whitespace changes)
-rwxr-xr-x[-rw-r--r--]PumpKINDlg.cpp1
1 files changed, 1 insertions, 0 deletions
diff --git a/PumpKINDlg.cpp b/PumpKINDlg.cpp
index f41b69f..3ff1500 100644..100755
--- a/PumpKINDlg.cpp
+++ b/PumpKINDlg.cpp
@@ -348,512 +348,513 @@ void CPumpKINDlg::OnPaint()
348 pDC.BitBlt(x,y,m_bitmapBack.bmWidth,m_bitmapBack.bmHeight,&bmpDC,0,0,SRCCOPY); 348 pDC.BitBlt(x,y,m_bitmapBack.bmWidth,m_bitmapBack.bmHeight,&bmpDC,0,0,SRCCOPY);
349 bmpDC.DeleteDC(); 349 bmpDC.DeleteDC();
350 CDialog::OnPaint(); 350 CDialog::OnPaint();
351 } 351 }
352} 352}
353 353
354// The system calls this to obtain the cursor to display while the user drags 354// The system calls this to obtain the cursor to display while the user drags
355// the minimized window. 355// the minimized window.
356HCURSOR CPumpKINDlg::OnQueryDragIcon() 356HCURSOR CPumpKINDlg::OnQueryDragIcon()
357{ 357{
358 return (HCURSOR) m_hIcon; 358 return (HCURSOR) m_hIcon;
359} 359}
360 360
361int CPumpKINDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 361int CPumpKINDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
362{ 362{
363 if (CDialog::OnCreate(lpCreateStruct) == -1) 363 if (CDialog::OnCreate(lpCreateStruct) == -1)
364 return -1; 364 return -1;
365 365
366 if(!m_Listener.SetListen(m_bListen)) { 366 if(!m_Listener.SetListen(m_bListen)) {
367 m_bListen=FALSE; 367 m_bListen=FALSE;
368 TRACE0("Failed to create socket\n"); 368 TRACE0("Failed to create socket\n");
369 AfxMessageBox(IDS_BOX_CANTBIND,MB_OK|MB_ICONEXCLAMATION); 369 AfxMessageBox(IDS_BOX_CANTBIND,MB_OK|MB_ICONEXCLAMATION);
370 } 370 }
371 371
372 if(!m_Trayer->Create(NULL,"PumpKIN TrayIcon",WS_CHILD,CRect(0,0,0,0),this,0)){ 372 if(!m_Trayer->Create(NULL,"PumpKIN TrayIcon",WS_CHILD,CRect(0,0,0,0),this,0)){
373 TRACE0("Failed to create trayer\n"); 373 TRACE0("Failed to create trayer\n");
374 return -1; 374 return -1;
375 } 375 }
376 376
377NOTIFYICONDATA nid; 377NOTIFYICONDATA nid;
378 memset(&nid,0,sizeof(nid)); 378 memset(&nid,0,sizeof(nid));
379 nid.cbSize=sizeof(nid); 379 nid.cbSize=sizeof(nid);
380 nid.hWnd=m_Trayer->m_hWnd; 380 nid.hWnd=m_Trayer->m_hWnd;
381 nid.uID=IDC_TRAYICON; 381 nid.uID=IDC_TRAYICON;
382 nid.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP; 382 nid.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
383 nid.uCallbackMessage=WM_TRAYICON; 383 nid.uCallbackMessage=WM_TRAYICON;
384 nid.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME); 384 nid.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
385 // *** Load from resource 385 // *** Load from resource
386 strcpy(nid.szTip,"PumpKIN"); 386 strcpy(nid.szTip,"PumpKIN");
387 VERIFY(Shell_NotifyIcon(NIM_ADD,&nid)); 387 VERIFY(Shell_NotifyIcon(NIM_ADD,&nid));
388 388
389 return 0; 389 return 0;
390} 390}
391 391
392void CListenSocket::OnReceive(int nErrorCode) 392void CListenSocket::OnReceive(int nErrorCode)
393{ 393{
394 ASSERT(m_Daddy); 394 ASSERT(m_Daddy);
395 if(nErrorCode){ 395 if(nErrorCode){
396 m_Daddy->LogLine(IDS_LOG_LISTENRECEIVEERROR); 396 m_Daddy->LogLine(IDS_LOG_LISTENRECEIVEERROR);
397 return; 397 return;
398 } 398 }
399DWORD fionread = 0; 399DWORD fionread = 0;
400 VERIFY(IOCtl(FIONREAD,&fionread));// *** Do some checking on the value acquired 400 VERIFY(IOCtl(FIONREAD,&fionread));// *** Do some checking on the value acquired
401tftp *tftpRQ = tftp::Allocate(fionread); 401tftp *tftpRQ = tftp::Allocate(fionread);
402 ASSERT(tftpRQ); 402 ASSERT(tftpRQ);
403SOCKADDR_IN sin; 403SOCKADDR_IN sin;
404 if(!tftpRQ->Receive(this,fionread,&sin)){ 404 if(!tftpRQ->Receive(this,fionread,&sin)){
405 m_Daddy->LogLine(IDS_LOG_LISTENACCEPTERROR); 405 m_Daddy->LogLine(IDS_LOG_LISTENACCEPTERROR);
406 delete tftpRQ; 406 delete tftpRQ;
407 return; 407 return;
408 } 408 }
409 #ifndefNDEBUG 409 #ifndefNDEBUG
410CString tmp; 410CString tmp;
411 tmp.Format("%u - %s - %u\n",tftpRQ->Opcode(),inet_ntoa(sin.sin_addr),sin.sin_port); 411 tmp.Format("%u - %s - %u\n",tftpRQ->Opcode(),inet_ntoa(sin.sin_addr),sin.sin_port);
412 TRACE0(tmp); 412 TRACE0(tmp);
413#endif 413#endif
414POSITION p = m_Daddy->m_Xfers.GetStartPosition(); 414POSITION p = m_Daddy->m_Xfers.GetStartPosition();
415 while(p){ 415 while(p){
416 SOCKET key; 416 SOCKET key;
417 CXferSocket *sock; 417 CXferSocket *sock;
418 m_Daddy->m_Xfers.GetNextAssoc(p,key,sock); 418 m_Daddy->m_Xfers.GetNextAssoc(p,key,sock);
419 ASSERT(sock); 419 ASSERT(sock);
420 if(sock->m_Peer.sin_addr.s_addr==sin.sin_addr.s_addr && sock->m_Peer.sin_port==sin.sin_port){ 420 if(sock->m_Peer.sin_addr.s_addr==sin.sin_addr.s_addr && sock->m_Peer.sin_port==sin.sin_port){
421 TRACE0("Ignoring request which we are already processing\n"); 421 TRACE0("Ignoring request which we are already processing\n");
422 delete tftpRQ; 422 delete tftpRQ;
423 return; 423 return;
424 } 424 }
425 } 425 }
426 switch(tftpRQ->Opcode()){ 426 switch(tftpRQ->Opcode()){
427 case tftp::opRRQ: 427 case tftp::opRRQ:
428 // Read Request 428 // Read Request
429 { 429 {
430 CString tmp; 430 CString tmp;
431 tmp.Format(IDS_LOG_RRQSERVE,tftpRQ->rqFileName(),tftpRQ->rqType(),inet_ntoa(sin.sin_addr)); 431 tmp.Format(IDS_LOG_RRQSERVE,tftpRQ->rqFileName(),tftpRQ->rqType(),inet_ntoa(sin.sin_addr));
432 m_Daddy->LogLine(tmp); 432 m_Daddy->LogLine(tmp);
433 CRRQSocket *s = new CRRQSocket(m_Daddy,tftpRQ->rqFileName(),tftpRQ->rqType(),&sin); 433 CRRQSocket *s = new CRRQSocket(m_Daddy,tftpRQ->rqFileName(),tftpRQ->rqType(),&sin);
434 ASSERT(s); 434 ASSERT(s);
435 tftpRQ->GetOptions(&s->m_Options); 435 tftpRQ->GetOptions(&s->m_Options);
436 if(!s->Create()) 436 if(!s->Create())
437 s->Destroy(FALSE); 437 s->Destroy(FALSE);
438 } 438 }
439 break; 439 break;
440 case tftp::opWRQ: 440 case tftp::opWRQ:
441 // Write Request 441 // Write Request
442 { 442 {
443 CString tmp; 443 CString tmp;
444 tmp.Format(IDS_LOG_WRQSERVE,tftpRQ->rqFileName(),tftpRQ->rqType(),inet_ntoa(sin.sin_addr)); 444 tmp.Format(IDS_LOG_WRQSERVE,tftpRQ->rqFileName(),tftpRQ->rqType(),inet_ntoa(sin.sin_addr));
445 m_Daddy->LogLine(tmp); 445 m_Daddy->LogLine(tmp);
446 CWRQSocket *s = new CWRQSocket(m_Daddy,tftpRQ->rqFileName(),tftpRQ->rqType(),&sin); 446 CWRQSocket *s = new CWRQSocket(m_Daddy,tftpRQ->rqFileName(),tftpRQ->rqType(),&sin);
447 ASSERT(s); 447 ASSERT(s);
448 tftpRQ->GetOptions(&s->m_Options); 448 tftpRQ->GetOptions(&s->m_Options);
449 if(!s->Create(NULL,NULL)) 449 if(!s->Create(NULL,NULL))
450 s->Destroy(FALSE); 450 s->Destroy(FALSE);
451 } 451 }
452 break; 452 break;
453 default: 453 default:
454 m_Daddy->LogLine(IDS_LOG_LISTENOPCODE); 454 m_Daddy->LogLine(IDS_LOG_LISTENOPCODE);
455 delete tftpRQ; 455 delete tftpRQ;
456 return; 456 return;
457 } 457 }
458 delete tftpRQ; 458 delete tftpRQ;
459} 459}
460 460
461BOOL tftp::Receive(CAsyncSocket* socket,UINT maxLength,SOCKADDR_IN *sin) 461BOOL tftp::Receive(CAsyncSocket* socket,UINT maxLength,SOCKADDR_IN *sin)
462{ 462{
463 ASSERT(socket); 463 ASSERT(socket);
464int saddrLen = sizeof(SOCKADDR_IN); 464int saddrLen = sizeof(SOCKADDR_IN);
465 length = sin ? 465 length = sin ?
466 socket->ReceiveFrom(udpBase(),maxLength,(SOCKADDR*)sin,&saddrLen) 466 socket->ReceiveFrom(udpBase(),maxLength,(SOCKADDR*)sin,&saddrLen)
467 : 467 :
468 socket->Receive(udpBase(),maxLength) 468 socket->Receive(udpBase(),maxLength)
469 ; 469 ;
470 if(!length) 470 if(!length)
471 return FALSE; 471 return FALSE;
472 if(length==(tftpLength)SOCKET_ERROR) 472 if(length==(tftpLength)SOCKET_ERROR)
473 return FALSE; 473 return FALSE;
474 return TRUE; 474 return TRUE;
475} 475}
476 476
477UINT tftp::Opcode() 477UINT tftp::Opcode()
478{ 478{
479 return REVERSEBYTES(opcode); 479 return REVERSEBYTES(opcode);
480} 480}
481 481
482CString tftp::rqFileName() 482CString tftp::rqFileName()
483{ 483{
484 ASSERT(length); 484 ASSERT(length);
485 ASSERT(Opcode()==opRRQ || Opcode()==opWRQ); 485 ASSERT(Opcode()==opRRQ || Opcode()==opWRQ);
486CString rv; 486CString rv;
487 if(memchr(&data.m_RQ.data,0,length-sizeof(opcode))) 487 if(memchr(&data.m_RQ.data,0,length-sizeof(opcode)))
488 rv = (LPCTSTR)data.m_RQ.data; 488 rv = (LPCTSTR)data.m_RQ.data;
489 return rv; 489 return rv;
490} 490}
491 491
492CString tftp::rqType() 492CString tftp::rqType()
493{ 493{
494 ASSERT(length); 494 ASSERT(length);
495 ASSERT(Opcode()==opRRQ || Opcode()==opWRQ); 495 ASSERT(Opcode()==opRRQ || Opcode()==opWRQ);
496CString rv; 496CString rv;
497char *tmp = (char*)memchr(&data.m_RQ.data,0,length-sizeof(opcode)); 497char *tmp = (char*)memchr(&data.m_RQ.data,0,length-sizeof(opcode));
498 if(tmp++) 498 if(tmp++)
499 rv = (LPCTSTR)tmp; 499 rv = (LPCTSTR)tmp;
500 return rv; 500 return rv;
501} 501}
502 502
503UINT tftp::GetOptions(tftp::tftpOptions* ops) 503UINT tftp::GetOptions(tftp::tftpOptions* ops)
504{ 504{
505 ASSERT(length); 505 ASSERT(length);
506 ASSERT(Opcode()==opRRQ || Opcode()==opWRQ || Opcode()==opOACK); 506 ASSERT(Opcode()==opRRQ || Opcode()==opWRQ || Opcode()==opOACK);
507 ASSERT(ops); 507 ASSERT(ops);
508tftpOptions& o = *ops; 508tftpOptions& o = *ops;
509LPSTR base = (LPSTR)&data.m_RQ.data; 509LPSTR base = (LPSTR)&data.m_RQ.data;
510UINT basePtr = 0; 510UINT basePtr = 0;
511 if(Opcode()==opRRQ || Opcode()==opWRQ){ 511 if(Opcode()==opRRQ || Opcode()==opWRQ){
512 base = (LPSTR)memchr(&data.m_RQ.data,0,length-sizeof(opcode)); 512 base = (LPSTR)memchr(&data.m_RQ.data,0,length-sizeof(opcode));
513 if(!base) 513 if(!base)
514 return 0; 514 return 0;
515 base++; 515 base++;
516 basePtr = (base-(LPSTR)&data.m_RQ.data); 516 basePtr = (base-(LPSTR)&data.m_RQ.data);
517 base = (LPSTR)memchr(base,0,length-basePtr); 517 base = (LPSTR)memchr(base,0,length-basePtr);
518 if(!base) 518 if(!base)
519 return 0; 519 return 0;
520 base++; 520 base++;
521 basePtr = (base-(LPSTR)&data.m_RQ.data); 521 basePtr = (base-(LPSTR)&data.m_RQ.data);
522 } 522 }
523 ops->RemoveAll(); 523 ops->RemoveAll();
524UINT rv = 0; 524UINT rv = 0;
525 while(basePtr<(length-sizeof(opcode))){ 525 while(basePtr<(length-sizeof(opcode))){
526 CString onam = (LPSTR)&data.m_RQ.data[basePtr]; 526 CString onam = (LPSTR)&data.m_RQ.data[basePtr];
527 basePtr+=onam.GetLength()+1; 527 basePtr+=onam.GetLength()+1;
528 CString oval = (LPSTR)&data.m_RQ.data[basePtr]; 528 CString oval = (LPSTR)&data.m_RQ.data[basePtr];
529 basePtr+=oval.GetLength()+1; 529 basePtr+=oval.GetLength()+1;
530 onam.MakeLower(); 530 onam.MakeLower();
531 o[onam]=oval; 531 o[onam]=oval;
532 rv++; 532 rv++;
533 } 533 }
534 return rv; 534 return rv;
535} 535}
536 536
537tftp::tftp() 537tftp::tftp()
538{ 538{
539 length=0; 539 length=0;
540} 540}
541 541
542 542
543void CXferSocket::OnSend(int nErrorCode) 543void CXferSocket::OnSend(int nErrorCode)
544{ 544{
545 if(nErrorCode){ 545 if(nErrorCode){
546 ASSERT(m_Daddy); 546 ASSERT(m_Daddy);
547 m_Daddy->LogLine(IDS_LOG_XFERSEND); 547 m_Daddy->LogLine(IDS_LOG_XFERSEND);
548 return; 548 return;
549 } 549 }
550 if(!m_Queue.IsEmpty()){ 550 if(!m_Queue.IsEmpty()){
551 tftp *p = m_Queue.GetHead(); 551 tftp *p = m_Queue.GetHead();
552 ASSERT(p); 552 ASSERT(p);
553 m_Queue.RemoveHead(); 553 m_Queue.RemoveHead();
554 if(!p->Send(this,&m_Peer)){ 554 if(!p->Send(this,&m_Peer)){
555 ASSERT(m_Daddy); 555 ASSERT(m_Daddy);
556 m_Daddy->LogLine(IDS_LOG_XFERUDPSEND); 556 m_Daddy->LogLine(IDS_LOG_XFERUDPSEND);
557 } 557 }
558 delete p; 558 delete p;
559 } 559 }
560 DoSelect(); 560 DoSelect();
561 if(m_Queue.IsEmpty()){ 561 if(m_Queue.IsEmpty()){
562 switch(state){ 562 switch(state){
563 case stateDeny: 563 case stateDeny:
564 Destroy(FALSE); 564 Destroy(FALSE);
565 break; 565 break;
566 case stateFinish: 566 case stateFinish:
567 Destroy(TRUE); 567 Destroy(TRUE);
568 break; 568 break;
569 } 569 }
570 } 570 }
571} 571}
572 572
573BOOL tftp::Send(CAsyncSocket *socket,SOCKADDR_IN* saddr) 573BOOL tftp::Send(CAsyncSocket *socket,SOCKADDR_IN* saddr)
574{ 574{
575 ASSERT(socket); 575 ASSERT(socket);
576int rv = socket->SendTo(udpBase(),length,(SOCKADDR*)saddr,sizeof(SOCKADDR_IN)); 576int rv = socket->SendTo(udpBase(),length,(SOCKADDR*)saddr,sizeof(SOCKADDR_IN));
577 if(rv!=length) 577 if(rv!=length)
578 return FALSE; 578 return FALSE;
579 return TRUE; 579 return TRUE;
580} 580}
581 581
582void CXferSocket::DoSelect(BOOL do_select) 582void CXferSocket::DoSelect(BOOL do_select)
583{ 583{
584 if(m_Peer.sin_addr.s_addr!=INADDR_NONE) 584 if(m_Peer.sin_addr.s_addr!=INADDR_NONE)
585 AsyncSelect(FD_CLOSE|FD_READ|((m_Queue.IsEmpty()&&!do_select)?0:FD_WRITE)); 585 AsyncSelect(FD_CLOSE|FD_READ|((m_Queue.IsEmpty()&&!do_select)?0:FD_WRITE));
586} 586}
587 587
588void CXferSocket::OnReceive(int nErrorCode) 588void CXferSocket::OnReceive(int nErrorCode)
589{ 589{
590 if(nErrorCode){ 590 if(nErrorCode){
591 ASSERT(m_Daddy); 591 ASSERT(m_Daddy);
592 m_Daddy->LogLine(IDS_LOG_XFERRECEIVE); 592 m_Daddy->LogLine(IDS_LOG_XFERRECEIVE);
593 return; 593 return;
594 } 594 }
595 ASSERT(m_Daddy); 595 ASSERT(m_Daddy);
596DWORD fionread = 0; 596DWORD fionread = 0;
597 VERIFY(IOCtl(FIONREAD,&fionread)); 597 VERIFY(IOCtl(FIONREAD,&fionread));
598tftp *p = tftp::Allocate(fionread); 598tftp *p = tftp::Allocate(fionread);
599 ASSERT(p); 599 ASSERT(p);
600SOCKADDR_IN sin; 600SOCKADDR_IN sin;
601 if(!p->Receive(this,fionread,&sin)){ 601 if(!p->Receive(this,fionread,&sin)){
602 m_Daddy->LogLine(IDS_LOG_XFERUDPRECEIVE); 602 m_Daddy->LogLine(IDS_LOG_XFERUDPRECEIVE);
603 delete p; 603 delete p;
604 return;
604 }else 605 }else
605 if(m_Peer.sin_addr.s_addr==INADDR_NONE){ 606 if(m_Peer.sin_addr.s_addr==INADDR_NONE){
606 m_Peer.sin_addr=sin.sin_addr; 607 m_Peer.sin_addr=sin.sin_addr;
607 m_Peer.sin_port=sin.sin_port; 608 m_Peer.sin_port=sin.sin_port;
608 } 609 }
609BOOL alive = TRUE; 610BOOL alive = TRUE;
610 if(state==stateInit){ 611 if(state==stateInit){
611 state=stateXfer; 612 state=stateXfer;
612 m_Peer.sin_port=sin.sin_port; 613 m_Peer.sin_port=sin.sin_port;
613 UpdateList(); 614 UpdateList();
614 } 615 }
615 if(sin.sin_addr.s_addr!=m_Peer.sin_addr.s_addr || sin.sin_port!=m_Peer.sin_port){ 616 if(sin.sin_addr.s_addr!=m_Peer.sin_addr.s_addr || sin.sin_port!=m_Peer.sin_port){
616 m_Daddy->LogLine(IDS_LOG_XFERSOURCETID); 617 m_Daddy->LogLine(IDS_LOG_XFERSOURCETID);
617 // *** Bounce it! 618 // *** Bounce it!
618 }else{ 619 }else{
619 alive = OnTFTP(p); 620 alive = OnTFTP(p);
620 } 621 }
621 delete p; 622 delete p;
622 if(alive){ 623 if(alive){
623 DoSelect(); 624 DoSelect();
624 ResetTimeout(); 625 ResetTimeout();
625 } 626 }
626} 627}
627 628
628void CXferSocket::SetPeer(SOCKADDR_IN *sin) 629void CXferSocket::SetPeer(SOCKADDR_IN *sin)
629{ 630{
630 ASSERT(sin); 631 ASSERT(sin);
631 memmove(&m_Peer,sin,sizeof(m_Peer)); 632 memmove(&m_Peer,sin,sizeof(m_Peer));
632} 633}
633 634
634void CXferSocket::UpdateList() 635void CXferSocket::UpdateList()
635{ 636{
636 ASSERT(m_Daddy); 637 ASSERT(m_Daddy);
637LV_FINDINFO lvf; 638LV_FINDINFO lvf;
638 memset(&lvf,0,sizeof(lvf)); 639 memset(&lvf,0,sizeof(lvf));
639 lvf.flags=LVFI_PARAM; 640 lvf.flags=LVFI_PARAM;
640 lvf.lParam=(LPARAM)this; 641 lvf.lParam=(LPARAM)this;
641int i = m_Daddy->m_List.FindItem(&lvf); 642int i = m_Daddy->m_List.FindItem(&lvf);
642 if(i<0){ 643 if(i<0){
643 ASSERT(IsKindOf(RUNTIME_CLASS(CRRQSocket)) || IsKindOf(RUNTIME_CLASS(CWRQSocket))); 644 ASSERT(IsKindOf(RUNTIME_CLASS(CRRQSocket)) || IsKindOf(RUNTIME_CLASS(CWRQSocket)));
644 i=m_Daddy->m_List.InsertItem(0,m_FileName,IsKindOf(RUNTIME_CLASS(CRRQSocket))?m_Daddy->m_iRRQ:m_Daddy->m_iWRQ); 645 i=m_Daddy->m_List.InsertItem(0,m_FileName,IsKindOf(RUNTIME_CLASS(CRRQSocket))?m_Daddy->m_iRRQ:m_Daddy->m_iWRQ);
645 ASSERT(!(i<0)); 646 ASSERT(!(i<0));
646 m_Daddy->m_List.SetItemData(i,(DWORD)this); 647 m_Daddy->m_List.SetItemData(i,(DWORD)this);
647 } 648 }
648 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemFile,m_FileName); 649 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemFile,m_FileName);
649 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemType,m_Type); 650 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemType,m_Type);
650 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemPeer,inet_ntoa(m_Peer.sin_addr)); 651 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemPeer,inet_ntoa(m_Peer.sin_addr));
651CString tmp; 652CString tmp;
652 tmp.Format(IDS_FMT_BYTES,GetACK()); 653 tmp.Format(IDS_FMT_BYTES,GetACK());
653 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemBytes,tmp); 654 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemBytes,tmp);
654 if(m_xferSize>=0){ 655 if(m_xferSize>=0){
655 tmp.Format(IDS_FMT_BYTES,m_xferSize); 656 tmp.Format(IDS_FMT_BYTES,m_xferSize);
656 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemTSize,tmp); 657 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemTSize,tmp);
657 } 658 }
658} 659}
659 660
660CXferSocket::CXferSocket() 661CXferSocket::CXferSocket()
661 : m_wndResolver(NULL), m_Retry(NULL), m_bRetry(FALSE), 662 : m_wndResolver(NULL), m_Retry(NULL), m_bRetry(FALSE),
662 m_blkSize(512), m_timeOut(30), m_xferSize(-1), 663 m_blkSize(512), m_timeOut(30), m_xferSize(-1),
663 m__blkSize(512), m__timeOut(30) 664 m__blkSize(512), m__timeOut(30)
664{ 665{
665 m_Daddy=NULL; 666 m_Daddy=NULL;
666 m_Peer.sin_addr.s_addr=INADDR_NONE; 667 m_Peer.sin_addr.s_addr=INADDR_NONE;
667 m_Peer.sin_family=AF_INET; 668 m_Peer.sin_family=AF_INET;
668 state=stateNone; 669 state=stateNone;
669} 670}
670 671
671ULONG CXferSocket::GetACK() 672ULONG CXferSocket::GetACK()
672{ 673{
673 return 0; 674 return 0;
674} 675}
675 676
676CXferSocket::CXferSocket(CPumpKINDlg *daddy,LPCTSTR fileName,LPCTSTR type,SOCKADDR_IN* sin) 677CXferSocket::CXferSocket(CPumpKINDlg *daddy,LPCTSTR fileName,LPCTSTR type,SOCKADDR_IN* sin)
677 : m_wndResolver(NULL), m_Retry(NULL), m_bRetry(FALSE), 678 : m_wndResolver(NULL), m_Retry(NULL), m_bRetry(FALSE),
678 m_blkSize(512), m_timeOut(30), m_xferSize(-1), 679 m_blkSize(512), m_timeOut(30), m_xferSize(-1),
679 m__blkSize(512), m__timeOut(30) 680 m__blkSize(512), m__timeOut(30)
680{ 681{
681 m_Peer.sin_family=AF_INET; 682 m_Peer.sin_family=AF_INET;
682 state=stateNone; 683 state=stateNone;
683 ASSERT(daddy); 684 ASSERT(daddy);
684 m_Daddy=daddy; 685 m_Daddy=daddy;
685 m_timeOut=m__timeOut=m_Daddy->m_TFTPTimeOut.GetTotalSeconds(); 686 m_timeOut=m__timeOut=m_Daddy->m_TFTPTimeOut.GetTotalSeconds();
686 if(sin){ 687 if(sin){
687 m_Peer.sin_addr.s_addr=sin->sin_addr.s_addr; 688 m_Peer.sin_addr.s_addr=sin->sin_addr.s_addr;
688 m_Peer.sin_port=sin->sin_port; 689 m_Peer.sin_port=sin->sin_port;
689 }else 690 }else
690 m_Peer.sin_addr.s_addr=INADDR_NONE; 691 m_Peer.sin_addr.s_addr=INADDR_NONE;
691 m_FileName=fileName; 692 m_FileName=fileName;
692 m_Type=type; 693 m_Type=type;
693} 694}
694 695
695BOOL CRRQSocket::Create(LPCTSTR localFile,LPCTSTR hostName) 696BOOL CRRQSocket::Create(LPCTSTR localFile,LPCTSTR hostName)
696{ 697{
697 if(!CAsyncSocket::Create(0,SOCK_DGRAM)) 698 if(!CAsyncSocket::Create(0,SOCK_DGRAM))
698 return FALSE; 699 return FALSE;
699 ASSERT(m_Daddy); 700 ASSERT(m_Daddy);
700 ASSERT(m_Peer.sin_addr.s_addr!=INADDR_NONE || hostName); 701 ASSERT(m_Peer.sin_addr.s_addr!=INADDR_NONE || hostName);
701 m_Daddy->m_Xfers[m_hSocket]=this; 702 m_Daddy->m_Xfers[m_hSocket]=this;
702CString lFile = localFile?localFile:m_FileName; 703CString lFile = localFile?localFile:m_FileName;
703 TurnSlashes(lFile,TRUE); 704 TurnSlashes(lFile,TRUE);
704 UpdateList(); 705 UpdateList();
705 if(!localFile){// Check only for incoming requests 706 if(!localFile){// Check only for incoming requests
706 if(CheckBadRelativeness(m_FileName)){ 707 if(CheckBadRelativeness(m_FileName)){
707 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS); 708 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
708 return TRUE; 709 return TRUE;
709 } 710 }
710 int atar=m_Daddy->m_aclRules.FindTarget(acl_rule::opRRQ,m_Peer.sin_addr.s_addr); 711 int atar=m_Daddy->m_aclRules.FindTarget(acl_rule::opRRQ,m_Peer.sin_addr.s_addr);
711 if(atar<0) 712 if(atar<0)
712 atar = m_Daddy->m_RRQMode; 713 atar = m_Daddy->m_RRQMode;
713 switch(atar){ 714 switch(atar){
714 case CPumpKINDlg::rrqGiveAll: 715 case CPumpKINDlg::rrqGiveAll:
715 break; 716 break;
716 case CPumpKINDlg::rrqAlwaysConfirm: 717 case CPumpKINDlg::rrqAlwaysConfirm:
717 if(ConfirmRequest()) 718 if(ConfirmRequest())
718 break; 719 break;
719 default: 720 default:
720 TRACE1("Unexpected access target: %d\n",atar); 721 TRACE1("Unexpected access target: %d\n",atar);
721 case CPumpKINDlg::rrqDenyAll: 722 case CPumpKINDlg::rrqDenyAll:
722 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS); 723 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
723 return TRUE; 724 return TRUE;
724 } 725 }
725 } 726 }
726CString fn = localFile?ApplyRootGently(lFile):ApplyRoot(lFile); 727CString fn = localFile?ApplyRootGently(lFile):ApplyRoot(lFile);
727CFileException e; 728CFileException e;
728 if(!m_File.Open(fn,CFile::modeRead|CFile::shareDenyWrite,&e)){ 729 if(!m_File.Open(fn,CFile::modeRead|CFile::shareDenyWrite,&e)){
729 if(localFile){ 730 if(localFile){
730 CString tmp; 731 CString tmp;
731 tmp.Format(IDS_LOG_FAILEDLOCALFILE,fn); 732 tmp.Format(IDS_LOG_FAILEDLOCALFILE,fn);
732 m_Daddy->LogLine(tmp); 733 m_Daddy->LogLine(tmp);
733 return FALSE; 734 return FALSE;
734 } 735 }
735 Deny(&e); 736 Deny(&e);
736 return TRUE; 737 return TRUE;
737 } 738 }
738 m_xferSize=m_File.GetLength();// *** HANDLE EXCEPTION 739 m_xferSize=m_File.GetLength();// *** HANDLE EXCEPTION
739 if(hostName){ 740 if(hostName){
740 m_HostName=hostName; 741 m_HostName=hostName;
741 742
742 CString tmp; 743 CString tmp;
743 tmp.Format(IDS_LOG_SENDING,m_FileName,m_HostName); 744 tmp.Format(IDS_LOG_SENDING,m_FileName,m_HostName);
744 m_Daddy->LogLine(tmp); 745 m_Daddy->LogLine(tmp);
745 746
746 CString inAddr = hostName; 747 CString inAddr = hostName;
747 int at = inAddr.Find('@'); 748 int at = inAddr.Find('@');
748 if(at>=0) 749 if(at>=0)
749 inAddr=inAddr.Mid(at+1); 750 inAddr=inAddr.Mid(at+1);
750 if((m_Peer.sin_addr.s_addr=inet_addr((LPCTSTR)inAddr))==INADDR_NONE){ 751 if((m_Peer.sin_addr.s_addr=inet_addr((LPCTSTR)inAddr))==INADDR_NONE){
751 ASSERT(!m_wndResolver); 752 ASSERT(!m_wndResolver);
752 m_wndResolver = new CResolver(this); 753 m_wndResolver = new CResolver(this);
753 ASSERT(m_wndResolver); 754 ASSERT(m_wndResolver);
754 return m_wndResolver->Resolve(); 755 return m_wndResolver->Resolve();
755 } 756 }
756 else 757 else
757 OnHostKnown(); 758 OnHostKnown();
758 }else{ 759 }else{
759 tftp::tftpOptions o; 760 tftp::tftpOptions o;
760 CString v; 761 CString v;
761 if(m_Options.Lookup(tftpoBSize,v)){ 762 if(m_Options.Lookup(tftpoBSize,v)){
762 m__blkSize=atoi(v); 763 m__blkSize=atoi(v);
763 if(m__blkSize){ 764 if(m__blkSize){
764 m_blkSize=m__blkSize; 765 m_blkSize=m__blkSize;
765 v.Format("%u",m_blkSize); 766 v.Format("%u",m_blkSize);
766 o[tftpoBSize]=v; 767 o[tftpoBSize]=v;
767 } 768 }
768 } 769 }
769 if(m_Options.Lookup(tftpoTSize,v)){ 770 if(m_Options.Lookup(tftpoTSize,v)){
770 v.Format("%lu",m_xferSize); 771 v.Format("%lu",m_xferSize);
771 o[tftpoTSize]=v; 772 o[tftpoTSize]=v;
772 } 773 }
773 if(m_Options.Lookup(tftpoTOut,v)){ 774 if(m_Options.Lookup(tftpoTOut,v)){
774 m__timeOut=atoi(v); 775 m__timeOut=atoi(v);
775 if(m__timeOut){ 776 if(m__timeOut){
776 m_timeOut=m__timeOut; 777 m_timeOut=m__timeOut;
777 v.Format("%u",m_timeOut); 778 v.Format("%u",m_timeOut);
778 o[tftpoTOut]=v; 779 o[tftpoTOut]=v;
779 } 780 }
780 } 781 }
781 // XXX: see if we can enforce our preference regarding block size here. 782 // XXX: see if we can enforce our preference regarding block size here.
782 if(m_xferSize >= (m_blkSize<<16)) { 783 if(m_xferSize >= (m_blkSize<<16)) {
783 Deny(tftp::errUndefined,IDS_TFTP_ERROR_TOOBIG); 784 Deny(tftp::errUndefined,IDS_TFTP_ERROR_TOOBIG);
784 return TRUE; 785 return TRUE;
785 } 786 }
786 state = stateXfer; 787 state = stateXfer;
787 m_ACK=0; 788 m_ACK=0;
788 if(o.GetCount()){ 789 if(o.GetCount()){
789 tftp *p = tftp::Allocate(tftp::tftpOACK::tftpSize(&o)); 790 tftp *p = tftp::Allocate(tftp::tftpOACK::tftpSize(&o));
790 ASSERT(p); 791 ASSERT(p);
791 p->SetOpcode(tftp::opOACK); 792 p->SetOpcode(tftp::opOACK);
792 p->data.m_OACK.Set(&o); 793 p->data.m_OACK.Set(&o);
793 PostTFTP(p,TRUE); 794 PostTFTP(p,TRUE);
794 }else 795 }else
795 DoXfer(); 796 DoXfer();
796 } 797 }
797 return TRUE; 798 return TRUE;
798} 799}
799 800
800CRRQSocket::CRRQSocket(CPumpKINDlg *daddy,LPCTSTR fileName,LPCTSTR type,SOCKADDR_IN *sin) 801CRRQSocket::CRRQSocket(CPumpKINDlg *daddy,LPCTSTR fileName,LPCTSTR type,SOCKADDR_IN *sin)
801 : CXferSocket(daddy,fileName,type,sin) 802 : CXferSocket(daddy,fileName,type,sin)
802{ 803{
803 m_ACK=0; 804 m_ACK=0;
804 m_LastSlack=0; 805 m_LastSlack=0;
805} 806}
806 807
807UINT tftp::tftpERROR::tftpSize(LPCTSTR msg) 808UINT tftp::tftpERROR::tftpSize(LPCTSTR msg)
808{ 809{
809 return tftpHdrSize-tftpSlackSize+sizeof(tftp::tftpERROR::tftpErrorCode)+strlen(msg)+1; 810 return tftpHdrSize-tftpSlackSize+sizeof(tftp::tftpERROR::tftpErrorCode)+strlen(msg)+1;
810} 811}
811 812
812tftp* tftp::Allocate(UINT tftpSize) 813tftp* tftp::Allocate(UINT tftpSize)
813{ 814{
814 ASSERT(tftpSize); 815 ASSERT(tftpSize);
815tftp* rv = (tftp*) new BYTE[tftpSlackSize+tftpSize]; 816tftp* rv = (tftp*) new BYTE[tftpSlackSize+tftpSize];
816 ASSERT(rv); 817 ASSERT(rv);
817 rv->length=tftpSize; 818 rv->length=tftpSize;
818 return rv; 819 return rv;
819} 820}
820 821
821void tftp::errSet(UINT code,LPCTSTR msg) 822void tftp::errSet(UINT code,LPCTSTR msg)
822{ 823{
823 ASSERT(this); 824 ASSERT(this);
824 ASSERT(length>=data.m_ERROR.tftpSize(msg)); 825 ASSERT(length>=data.m_ERROR.tftpSize(msg));
825 strcpy((char*)data.m_ERROR.data,msg); 826 strcpy((char*)data.m_ERROR.data,msg);
826 data.m_ERROR.SetCode(code); 827 data.m_ERROR.SetCode(code);
827} 828}
828 829
829void CXferSocket::PostTFTP(tftp* p,BOOL retryable) 830void CXferSocket::PostTFTP(tftp* p,BOOL retryable)
830{ 831{
831 ASSERT(p); 832 ASSERT(p);
832 m_Queue.AddTail(p); 833 m_Queue.AddTail(p);
833 DoSelect(); 834 DoSelect();
834 if(!m_bRetry){ 835 if(!m_bRetry){
835 if(retryable) 836 if(retryable)
836 SetTry(p); 837 SetTry(p);
837 else 838 else
838 SetTry(); 839 SetTry();
839 } 840 }
840 ResetTimeout(); 841 ResetTimeout();
841} 842}
842 843
843void CXferSocket::Deny(UINT errCode,UINT errID) 844void CXferSocket::Deny(UINT errCode,UINT errID)
844{ 845{
845 PostError(errCode,errID); 846 PostError(errCode,errID);
846 state=stateDeny; 847 state=stateDeny;
847} 848}
848 849
849void CRRQSocket::DoXfer() 850void CRRQSocket::DoXfer()
850{ 851{
851tftp *p = tftp::Allocate(tftp::tftpDATA::tftpSize(m_blkSize)); 852tftp *p = tftp::Allocate(tftp::tftpDATA::tftpSize(m_blkSize));
852 ASSERT(p); 853 ASSERT(p);
853 p->SetOpcode(tftp::opDATA); 854 p->SetOpcode(tftp::opDATA);
854 TRY{ 855 TRY{
855 m_File.Seek(m_ACK*m_blkSize,CFile::begin); 856 m_File.Seek(m_ACK*m_blkSize,CFile::begin);
856 int bytes = m_File.Read(p->data.m_DATA.data,m_blkSize); 857 int bytes = m_File.Read(p->data.m_DATA.data,m_blkSize);
857 p->data.m_DATA.SetBlock(m_ACK+1); 858 p->data.m_DATA.SetBlock(m_ACK+1);
858 p->length=p->length-m_blkSize+bytes; 859 p->length=p->length-m_blkSize+bytes;
859 m_LastSlack = m_blkSize-bytes; 860 m_LastSlack = m_blkSize-bytes;