summaryrefslogtreecommitdiffabout
path: root/PumpKINDlg.cpp
authorMichael Krelin <hacker@klever.net>2006-07-02 22:16:25 (UTC)
committer Michael Krelin <hacker@klever.net>2006-07-02 22:16:25 (UTC)
commit577427e68ef10a4d2b75d28e42b22952ae3bcf23 (patch) (unidiff)
tree24c8fc94ea6524059cab7927ef76639bb1a1a98d /PumpKINDlg.cpp
parent24e693797daef020ece3fa19bb5acce000e37165 (diff)
downloadpumpkin-577427e68ef10a4d2b75d28e42b22952ae3bcf23.zip
pumpkin-577427e68ef10a4d2b75d28e42b22952ae3bcf23.tar.gz
pumpkin-577427e68ef10a4d2b75d28e42b22952ae3bcf23.tar.bz2
Do not close RRQ socket until the last ACK is received.
git-svn-id: http://svn.klever.net/kin/pumpkin/trunk@152 fe716a7a-6dde-0310-88d9-d003556173a8
Diffstat (limited to 'PumpKINDlg.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--PumpKINDlg.cpp70
1 files changed, 37 insertions, 33 deletions
diff --git a/PumpKINDlg.cpp b/PumpKINDlg.cpp
index 070f3e8..2a01918 100644
--- a/PumpKINDlg.cpp
+++ b/PumpKINDlg.cpp
@@ -198,1158 +198,1162 @@ BOOL CPumpKINDlg::OnInitDialog()
198 { 198 {
199 pSysMenu->AppendMenu(MF_SEPARATOR); 199 pSysMenu->AppendMenu(MF_SEPARATOR);
200 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 200 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
201 } 201 }
202 202
203 // Set the icon for this dialog. The framework does this automatically 203 // Set the icon for this dialog. The framework does this automatically
204 // when the application's main window is not a dialog 204 // when the application's main window is not a dialog
205 SetIcon(m_hIcon, TRUE); // Set big icon 205 SetIcon(m_hIcon, TRUE); // Set big icon
206 SetIcon(m_hIcon, FALSE); // Set small icon 206 SetIcon(m_hIcon, FALSE); // Set small icon
207 207
208 VERIFY(m_Retrier->Create(NULL,"PumpKIN-Retrier",WS_CHILD,CRect(0,0,0,0),this,0)); 208 VERIFY(m_Retrier->Create(NULL,"PumpKIN-Retrier",WS_CHILD,CRect(0,0,0,0),this,0));
209 209
210 m_Images.Create(16,16,TRUE,2,1); 210 m_Images.Create(16,16,TRUE,2,1);
211 m_iRRQ = m_Images.Add(AfxGetApp()->LoadIcon(IDI_RRQ)); 211 m_iRRQ = m_Images.Add(AfxGetApp()->LoadIcon(IDI_RRQ));
212 m_iWRQ = m_Images.Add(AfxGetApp()->LoadIcon(IDI_WRQ)); 212 m_iWRQ = m_Images.Add(AfxGetApp()->LoadIcon(IDI_WRQ));
213 ASSERT(m_iRRQ>=0); 213 ASSERT(m_iRRQ>=0);
214 ASSERT(m_iWRQ>=0); 214 ASSERT(m_iWRQ>=0);
215 m_List.SetImageList(&m_Images,LVSIL_NORMAL); 215 m_List.SetImageList(&m_Images,LVSIL_NORMAL);
216 m_List.SetImageList(&m_Images,LVSIL_SMALL); 216 m_List.SetImageList(&m_Images,LVSIL_SMALL);
217 m_List.SetImageList(&m_Images,LVSIL_STATE); 217 m_List.SetImageList(&m_Images,LVSIL_STATE);
218 m_List.SetTextColor(RGB(255,255,0));// Yellow 218 m_List.SetTextColor(RGB(255,255,0));// Yellow
219 m_List.SetTextBkColor(RGB(12,167,0));// Green 219 m_List.SetTextBkColor(RGB(12,167,0));// Green
220 m_List.SetBkColor(RGB(12,167,0));// Green 220 m_List.SetBkColor(RGB(12,167,0));// Green
221CRect listrc; 221CRect listrc;
222 m_List.GetClientRect(&listrc); 222 m_List.GetClientRect(&listrc);
223 m_List.InsertColumn(0,"File",LVCFMT_LEFT,listrc.Width()-((listrc.Width()/7)*3+listrc.Width()*2/7),subitemFile); 223 m_List.InsertColumn(0,"File",LVCFMT_LEFT,listrc.Width()-((listrc.Width()/7)*3+listrc.Width()*2/7),subitemFile);
224 m_List.InsertColumn(1,"type",LVCFMT_CENTER,listrc.Width()/7,subitemType); 224 m_List.InsertColumn(1,"type",LVCFMT_CENTER,listrc.Width()/7,subitemType);
225 m_List.InsertColumn(2,"peer",LVCFMT_LEFT,listrc.Width()*2/7,subitemPeer); 225 m_List.InsertColumn(2,"peer",LVCFMT_LEFT,listrc.Width()*2/7,subitemPeer);
226 m_List.InsertColumn(3,"ACK",LVCFMT_RIGHT,listrc.Width()/7,subitemBytes); 226 m_List.InsertColumn(3,"ACK",LVCFMT_RIGHT,listrc.Width()/7,subitemBytes);
227 m_List.InsertColumn(4,"tsize",LVCFMT_RIGHT,listrc.Width()/7,subitemTSize); 227 m_List.InsertColumn(4,"tsize",LVCFMT_RIGHT,listrc.Width()/7,subitemTSize);
228 228
229 LogLine(IDS_LOG_START); 229 LogLine(IDS_LOG_START);
230 230
231 SetupButtons(); 231 SetupButtons();
232 232
233CRect wrci, wrco; 233CRect wrci, wrco;
234 GetWindowRect(&wrco); 234 GetWindowRect(&wrco);
235 GetClientRect(&wrci); 235 GetClientRect(&wrci);
236CRect brc; 236CRect brc;
237 m_GetCtl.GetWindowRect(&brc); ScreenToClient(&brc); 237 m_GetCtl.GetWindowRect(&brc); ScreenToClient(&brc);
238 m_rightGapButtons = wrci.right-brc.right; 238 m_rightGapButtons = wrci.right-brc.right;
239 m_List.GetWindowRect(&brc); ScreenToClient(&brc); 239 m_List.GetWindowRect(&brc); ScreenToClient(&brc);
240 m_rightGapList = wrci.right-brc.right; 240 m_rightGapList = wrci.right-brc.right;
241 m_ListenCtl.GetWindowRect(&brc); ScreenToClient(&brc); 241 m_ListenCtl.GetWindowRect(&brc); ScreenToClient(&brc);
242 m_bottomGapListen = wrci.bottom-brc.bottom; 242 m_bottomGapListen = wrci.bottom-brc.bottom;
243 m_Log.GetWindowRect(&brc);ScreenToClient(&brc); 243 m_Log.GetWindowRect(&brc);ScreenToClient(&brc);
244 m_bottomGapLog = wrci.bottom-brc.bottom; 244 m_bottomGapLog = wrci.bottom-brc.bottom;
245 m_MinSize.cx = wrco.Width(); m_MinSize.cy=wrco.Height(); 245 m_MinSize.cx = wrco.Width(); m_MinSize.cy=wrco.Height();
246 246
247CRect rc, drc; 247CRect rc, drc;
248 GetWindowRect(rc); 248 GetWindowRect(rc);
249 GetDesktopWindow()->GetWindowRect(drc); 249 GetDesktopWindow()->GetWindowRect(drc);
250 SetWindowPos(NULL,drc.right-6-rc.Width(),6,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER); 250 SetWindowPos(NULL,drc.right-6-rc.Width(),6,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
251 251
252 if(m_bShown) 252 if(m_bShown)
253 ShowWindow(SW_SHOW); 253 ShowWindow(SW_SHOW);
254 else 254 else
255 ShowWindow(SW_HIDE); 255 ShowWindow(SW_HIDE);
256 256
257 m_ListenCtl.SetCheck(m_Listener.m_bListen?1:0); 257 m_ListenCtl.SetCheck(m_Listener.m_bListen?1:0);
258 258
259 // CG: The following block was added by the ToolTips component. 259 // CG: The following block was added by the ToolTips component.
260 { 260 {
261 // Create the ToolTip control. 261 // Create the ToolTip control.
262 m_tooltip.Create(this); 262 m_tooltip.Create(this);
263 m_tooltip.Activate(TRUE); 263 m_tooltip.Activate(TRUE);
264 264
265 m_tooltip.AddTool(&m_List,IDC_CONNECTIONS); 265 m_tooltip.AddTool(&m_List,IDC_CONNECTIONS);
266 m_tooltip.AddTool(GetDlgItem(IDC_PUT),IDC_PUT); 266 m_tooltip.AddTool(GetDlgItem(IDC_PUT),IDC_PUT);
267 m_tooltip.AddTool(GetDlgItem(IDC_GET),IDC_GET); 267 m_tooltip.AddTool(GetDlgItem(IDC_GET),IDC_GET);
268 m_tooltip.AddTool(&m_AbortCtl,IDC_ABORT); 268 m_tooltip.AddTool(&m_AbortCtl,IDC_ABORT);
269 m_tooltip.AddTool(GetDlgItem(IDC_OPTIONS),IDC_OPTIONS); 269 m_tooltip.AddTool(GetDlgItem(IDC_OPTIONS),IDC_OPTIONS);
270 m_tooltip.AddTool(GetDlgItem(IDC_EXIT),IDC_EXIT); 270 m_tooltip.AddTool(GetDlgItem(IDC_EXIT),IDC_EXIT);
271 m_tooltip.AddTool(GetDlgItem(ID_HELP),ID_HELP); 271 m_tooltip.AddTool(GetDlgItem(ID_HELP),ID_HELP);
272 m_tooltip.AddTool(GetDlgItem(IDC_LOG),IDC_LOG); 272 m_tooltip.AddTool(GetDlgItem(IDC_LOG),IDC_LOG);
273 } 273 }
274 return TRUE; // return TRUE unless you set the focus to a control 274 return TRUE; // return TRUE unless you set the focus to a control
275} 275}
276 276
277void CPumpKINDlg::OnSysCommand(UINT nID, LPARAM lParam) 277void CPumpKINDlg::OnSysCommand(UINT nID, LPARAM lParam)
278{ 278{
279 if ((nID & 0xFFF0) == IDM_ABOUTBOX) 279 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
280 { 280 {
281 CAboutDlg dlgAbout; 281 CAboutDlg dlgAbout;
282 dlgAbout.DoModal(); 282 dlgAbout.DoModal();
283 } 283 }
284 else 284 else
285 { 285 {
286 CDialog::OnSysCommand(nID, lParam); 286 CDialog::OnSysCommand(nID, lParam);
287 } 287 }
288} 288}
289 289
290void CPumpKINDlg::OnDestroy() 290void CPumpKINDlg::OnDestroy()
291{ 291{
292 SaveSettings(); 292 SaveSettings();
293 293
294NOTIFYICONDATA nid; 294NOTIFYICONDATA nid;
295 memset(&nid,0,sizeof(nid)); 295 memset(&nid,0,sizeof(nid));
296 nid.cbSize=sizeof(nid); 296 nid.cbSize=sizeof(nid);
297 nid.hWnd=m_Trayer->m_hWnd; 297 nid.hWnd=m_Trayer->m_hWnd;
298 nid.uID=IDC_TRAYICON; 298 nid.uID=IDC_TRAYICON;
299 nid.uFlags=0; 299 nid.uFlags=0;
300 VERIFY(Shell_NotifyIcon(NIM_DELETE,&nid)); 300 VERIFY(Shell_NotifyIcon(NIM_DELETE,&nid));
301 301
302 WinHelp(0L, HELP_QUIT); 302 WinHelp(0L, HELP_QUIT);
303 CDialog::OnDestroy(); 303 CDialog::OnDestroy();
304POSITION p = m_LogTimes.GetStartPosition(); 304POSITION p = m_LogTimes.GetStartPosition();
305 while(p){ 305 while(p){
306 CTime *t,*tt; 306 CTime *t,*tt;
307 m_LogTimes.GetNextAssoc(p,t,tt); 307 m_LogTimes.GetNextAssoc(p,t,tt);
308 ASSERT(t && tt && t==tt); 308 ASSERT(t && tt && t==tt);
309 delete t; 309 delete t;
310 } 310 }
311 // *** Abort and cleanup transfers 311 // *** Abort and cleanup transfers
312 m_LogTimes.RemoveAll(); 312 m_LogTimes.RemoveAll();
313} 313}
314 314
315// If you add a minimize button to your dialog, you will need the code below 315// If you add a minimize button to your dialog, you will need the code below
316// to draw the icon. For MFC applications using the document/view model, 316// to draw the icon. For MFC applications using the document/view model,
317// this is automatically done for you by the framework. 317// this is automatically done for you by the framework.
318 318
319void CPumpKINDlg::OnPaint() 319void CPumpKINDlg::OnPaint()
320{ 320{
321 if (IsIconic()) 321 if (IsIconic())
322 { 322 {
323 CPaintDC dc(this); // device context for painting 323 CPaintDC dc(this); // device context for painting
324 324
325 SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); 325 SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
326 326
327 // Center icon in client rectangle 327 // Center icon in client rectangle
328 int cxIcon = GetSystemMetrics(SM_CXICON); 328 int cxIcon = GetSystemMetrics(SM_CXICON);
329 int cyIcon = GetSystemMetrics(SM_CYICON); 329 int cyIcon = GetSystemMetrics(SM_CYICON);
330 CRect rect; 330 CRect rect;
331 GetClientRect(&rect); 331 GetClientRect(&rect);
332 int x = (rect.Width() - cxIcon + 1) / 2; 332 int x = (rect.Width() - cxIcon + 1) / 2;
333 int y = (rect.Height() - cyIcon + 1) / 2; 333 int y = (rect.Height() - cyIcon + 1) / 2;
334 334
335 // Draw the icon 335 // Draw the icon
336 dc.DrawIcon(x, y, m_hIcon); 336 dc.DrawIcon(x, y, m_hIcon);
337 } 337 }
338 else 338 else
339 { 339 {
340 CPaintDC pDC(this); 340 CPaintDC pDC(this);
341 CDC bmpDC; 341 CDC bmpDC;
342 bmpDC.CreateCompatibleDC(&pDC); 342 bmpDC.CreateCompatibleDC(&pDC);
343 bmpDC.SelectObject(&m_bmpBack); 343 bmpDC.SelectObject(&m_bmpBack);
344 CRect rc; 344 CRect rc;
345 GetClientRect(&rc); 345 GetClientRect(&rc);
346 for(int x=-m_bitmapBack.bmWidth*2/4;x<rc.Width();x+=m_bitmapBack.bmWidth) 346 for(int x=-m_bitmapBack.bmWidth*2/4;x<rc.Width();x+=m_bitmapBack.bmWidth)
347 for(int y=-m_bitmapBack.bmHeight*2/4;y<rc.Height();y+=m_bitmapBack.bmHeight) 347 for(int y=-m_bitmapBack.bmHeight*2/4;y<rc.Height();y+=m_bitmapBack.bmHeight)
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() 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()?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 }else 604 }else
605 if(m_Peer.sin_addr.s_addr==INADDR_NONE){ 605 if(m_Peer.sin_addr.s_addr==INADDR_NONE){
606 m_Peer.sin_addr=sin.sin_addr; 606 m_Peer.sin_addr=sin.sin_addr;
607 m_Peer.sin_port=sin.sin_port; 607 m_Peer.sin_port=sin.sin_port;
608 } 608 }
609BOOL alive = TRUE; 609BOOL alive = TRUE;
610 if(state==stateInit){ 610 if(state==stateInit){
611 state=stateXfer; 611 state=stateXfer;
612 m_Peer.sin_port=sin.sin_port; 612 m_Peer.sin_port=sin.sin_port;
613 UpdateList(); 613 UpdateList();
614 } 614 }
615 if(sin.sin_addr.s_addr!=m_Peer.sin_addr.s_addr || sin.sin_port!=m_Peer.sin_port){ 615 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); 616 m_Daddy->LogLine(IDS_LOG_XFERSOURCETID);
617 // *** Bounce it! 617 // *** Bounce it!
618 }else{ 618 }else{
619 alive = OnTFTP(p); 619 alive = OnTFTP(p);
620 } 620 }
621 delete p; 621 delete p;
622 if(alive){ 622 if(alive){
623 DoSelect(); 623 DoSelect();
624 ResetTimeout(); 624 ResetTimeout();
625 } 625 }
626} 626}
627 627
628void CXferSocket::SetPeer(SOCKADDR_IN *sin) 628void CXferSocket::SetPeer(SOCKADDR_IN *sin)
629{ 629{
630 ASSERT(sin); 630 ASSERT(sin);
631 memmove(&m_Peer,sin,sizeof(m_Peer)); 631 memmove(&m_Peer,sin,sizeof(m_Peer));
632} 632}
633 633
634void CXferSocket::UpdateList() 634void CXferSocket::UpdateList()
635{ 635{
636 ASSERT(m_Daddy); 636 ASSERT(m_Daddy);
637LV_FINDINFO lvf; 637LV_FINDINFO lvf;
638 memset(&lvf,0,sizeof(lvf)); 638 memset(&lvf,0,sizeof(lvf));
639 lvf.flags=LVFI_PARAM; 639 lvf.flags=LVFI_PARAM;
640 lvf.lParam=(LPARAM)this; 640 lvf.lParam=(LPARAM)this;
641int i = m_Daddy->m_List.FindItem(&lvf); 641int i = m_Daddy->m_List.FindItem(&lvf);
642 if(i<0){ 642 if(i<0){
643 ASSERT(IsKindOf(RUNTIME_CLASS(CRRQSocket)) || IsKindOf(RUNTIME_CLASS(CWRQSocket))); 643 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); 644 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)); 645 ASSERT(!(i<0));
646 m_Daddy->m_List.SetItemData(i,(DWORD)this); 646 m_Daddy->m_List.SetItemData(i,(DWORD)this);
647 } 647 }
648 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemFile,m_FileName); 648 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemFile,m_FileName);
649 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemType,m_Type); 649 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)); 650 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemPeer,inet_ntoa(m_Peer.sin_addr));
651CString tmp; 651CString tmp;
652 tmp.Format(IDS_FMT_BYTES,GetACK()); 652 tmp.Format(IDS_FMT_BYTES,GetACK());
653 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemBytes,tmp); 653 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemBytes,tmp);
654 if(m_xferSize>=0){ 654 if(m_xferSize>=0){
655 tmp.Format(IDS_FMT_BYTES,m_xferSize); 655 tmp.Format(IDS_FMT_BYTES,m_xferSize);
656 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemTSize,tmp); 656 m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemTSize,tmp);
657 } 657 }
658} 658}
659 659
660CXferSocket::CXferSocket() 660CXferSocket::CXferSocket()
661 : m_wndResolver(NULL), m_Retry(NULL), m_bRetry(FALSE), 661 : m_wndResolver(NULL), m_Retry(NULL), m_bRetry(FALSE),
662 m_blkSize(512), m_timeOut(30), m_xferSize(-1), 662 m_blkSize(512), m_timeOut(30), m_xferSize(-1),
663 m__blkSize(512), m__timeOut(30) 663 m__blkSize(512), m__timeOut(30)
664{ 664{
665 m_Daddy=NULL; 665 m_Daddy=NULL;
666 m_Peer.sin_addr.s_addr=INADDR_NONE; 666 m_Peer.sin_addr.s_addr=INADDR_NONE;
667 m_Peer.sin_family=AF_INET; 667 m_Peer.sin_family=AF_INET;
668 state=stateNone; 668 state=stateNone;
669} 669}
670 670
671ULONG CXferSocket::GetACK() 671ULONG CXferSocket::GetACK()
672{ 672{
673 return 0; 673 return 0;
674} 674}
675 675
676CXferSocket::CXferSocket(CPumpKINDlg *daddy,LPCTSTR fileName,LPCTSTR type,SOCKADDR_IN* sin) 676CXferSocket::CXferSocket(CPumpKINDlg *daddy,LPCTSTR fileName,LPCTSTR type,SOCKADDR_IN* sin)
677 : m_wndResolver(NULL), m_Retry(NULL), m_bRetry(FALSE), 677 : m_wndResolver(NULL), m_Retry(NULL), m_bRetry(FALSE),
678 m_blkSize(512), m_timeOut(30), m_xferSize(-1), 678 m_blkSize(512), m_timeOut(30), m_xferSize(-1),
679 m__blkSize(512), m__timeOut(30) 679 m__blkSize(512), m__timeOut(30)
680{ 680{
681 m_Peer.sin_family=AF_INET; 681 m_Peer.sin_family=AF_INET;
682 state=stateNone; 682 state=stateNone;
683 ASSERT(daddy); 683 ASSERT(daddy);
684 m_Daddy=daddy; 684 m_Daddy=daddy;
685 m_timeOut=m__timeOut=m_Daddy->m_TFTPTimeOut.GetTotalSeconds(); 685 m_timeOut=m__timeOut=m_Daddy->m_TFTPTimeOut.GetTotalSeconds();
686 if(sin){ 686 if(sin){
687 m_Peer.sin_addr.s_addr=sin->sin_addr.s_addr; 687 m_Peer.sin_addr.s_addr=sin->sin_addr.s_addr;
688 m_Peer.sin_port=sin->sin_port; 688 m_Peer.sin_port=sin->sin_port;
689 }else 689 }else
690 m_Peer.sin_addr.s_addr=INADDR_NONE; 690 m_Peer.sin_addr.s_addr=INADDR_NONE;
691 m_FileName=fileName; 691 m_FileName=fileName;
692 m_Type=type; 692 m_Type=type;
693} 693}
694 694
695BOOL CRRQSocket::Create(LPCTSTR localFile,LPCTSTR hostName) 695BOOL CRRQSocket::Create(LPCTSTR localFile,LPCTSTR hostName)
696{ 696{
697 if(!CAsyncSocket::Create(0,SOCK_DGRAM)) 697 if(!CAsyncSocket::Create(0,SOCK_DGRAM))
698 return FALSE; 698 return FALSE;
699 ASSERT(m_Daddy); 699 ASSERT(m_Daddy);
700 ASSERT(m_Peer.sin_addr.s_addr!=INADDR_NONE || hostName); 700 ASSERT(m_Peer.sin_addr.s_addr!=INADDR_NONE || hostName);
701 m_Daddy->m_Xfers[m_hSocket]=this; 701 m_Daddy->m_Xfers[m_hSocket]=this;
702CString lFile = localFile?localFile:m_FileName; 702CString lFile = localFile?localFile:m_FileName;
703 TurnSlashes(lFile,TRUE); 703 TurnSlashes(lFile,TRUE);
704 UpdateList(); 704 UpdateList();
705 if(!localFile){// Check only for incoming requests 705 if(!localFile){// Check only for incoming requests
706 if(CheckBadRelativeness(m_FileName)){ 706 if(CheckBadRelativeness(m_FileName)){
707 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS); 707 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
708 return TRUE; 708 return TRUE;
709 } 709 }
710 int atar=m_Daddy->m_aclRules.FindTarget(acl_rule::opRRQ,m_Peer.sin_addr.s_addr); 710 int atar=m_Daddy->m_aclRules.FindTarget(acl_rule::opRRQ,m_Peer.sin_addr.s_addr);
711 if(atar<0) 711 if(atar<0)
712 atar = m_Daddy->m_RRQMode; 712 atar = m_Daddy->m_RRQMode;
713 switch(atar){ 713 switch(atar){
714 case CPumpKINDlg::rrqGiveAll: 714 case CPumpKINDlg::rrqGiveAll:
715 break; 715 break;
716 case CPumpKINDlg::rrqAlwaysConfirm: 716 case CPumpKINDlg::rrqAlwaysConfirm:
717 if(ConfirmRequest()) 717 if(ConfirmRequest())
718 break; 718 break;
719 default: 719 default:
720 TRACE1("Unexpected access target: %d\n",atar); 720 TRACE1("Unexpected access target: %d\n",atar);
721 case CPumpKINDlg::rrqDenyAll: 721 case CPumpKINDlg::rrqDenyAll:
722 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS); 722 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
723 return TRUE; 723 return TRUE;
724 } 724 }
725 } 725 }
726CString fn = localFile?ApplyRootGently(lFile):ApplyRoot(lFile); 726CString fn = localFile?ApplyRootGently(lFile):ApplyRoot(lFile);
727CFileException e; 727CFileException e;
728 if(!m_File.Open(fn,CFile::modeRead|CFile::shareDenyWrite,&e)){ 728 if(!m_File.Open(fn,CFile::modeRead|CFile::shareDenyWrite,&e)){
729 if(localFile){ 729 if(localFile){
730 CString tmp; 730 CString tmp;
731 tmp.Format(IDS_LOG_FAILEDLOCALFILE,fn); 731 tmp.Format(IDS_LOG_FAILEDLOCALFILE,fn);
732 m_Daddy->LogLine(tmp); 732 m_Daddy->LogLine(tmp);
733 return FALSE; 733 return FALSE;
734 } 734 }
735 Deny(&e); 735 Deny(&e);
736 return TRUE; 736 return TRUE;
737 } 737 }
738 m_xferSize=m_File.GetLength();// *** HANDLE EXCEPTION 738 m_xferSize=m_File.GetLength();// *** HANDLE EXCEPTION
739 if(hostName){ 739 if(hostName){
740 m_HostName=hostName; 740 m_HostName=hostName;
741 741
742 CString tmp; 742 CString tmp;
743 tmp.Format(IDS_LOG_SENDING,m_FileName,m_HostName); 743 tmp.Format(IDS_LOG_SENDING,m_FileName,m_HostName);
744 m_Daddy->LogLine(tmp); 744 m_Daddy->LogLine(tmp);
745 745
746 CString inAddr = hostName; 746 CString inAddr = hostName;
747 int at = inAddr.Find('@'); 747 int at = inAddr.Find('@');
748 if(at>=0) 748 if(at>=0)
749 inAddr=inAddr.Mid(at+1); 749 inAddr=inAddr.Mid(at+1);
750 if((m_Peer.sin_addr.s_addr=inet_addr((LPCTSTR)inAddr))==INADDR_NONE){ 750 if((m_Peer.sin_addr.s_addr=inet_addr((LPCTSTR)inAddr))==INADDR_NONE){
751 ASSERT(!m_wndResolver); 751 ASSERT(!m_wndResolver);
752 m_wndResolver = new CResolver(this); 752 m_wndResolver = new CResolver(this);
753 ASSERT(m_wndResolver); 753 ASSERT(m_wndResolver);
754 return m_wndResolver->Resolve(); 754 return m_wndResolver->Resolve();
755 } 755 }
756 else 756 else
757 OnHostKnown(); 757 OnHostKnown();
758 }else{ 758 }else{
759 tftp::tftpOptions o; 759 tftp::tftpOptions o;
760 CString v; 760 CString v;
761 if(m_Options.Lookup(tftpoBSize,v)){ 761 if(m_Options.Lookup(tftpoBSize,v)){
762 m__blkSize=atoi(v); 762 m__blkSize=atoi(v);
763 if(m__blkSize){ 763 if(m__blkSize){
764 m_blkSize=m__blkSize; 764 m_blkSize=m__blkSize;
765 v.Format("%u",m_blkSize); 765 v.Format("%u",m_blkSize);
766 o[tftpoBSize]=v; 766 o[tftpoBSize]=v;
767 } 767 }
768 } 768 }
769 if(m_Options.Lookup(tftpoTSize,v)){ 769 if(m_Options.Lookup(tftpoTSize,v)){
770 v.Format("%lu",m_xferSize); 770 v.Format("%lu",m_xferSize);
771 o[tftpoTSize]=v; 771 o[tftpoTSize]=v;
772 } 772 }
773 if(m_Options.Lookup(tftpoTOut,v)){ 773 if(m_Options.Lookup(tftpoTOut,v)){
774 m__timeOut=atoi(v); 774 m__timeOut=atoi(v);
775 if(m__timeOut){ 775 if(m__timeOut){
776 m_timeOut=m__timeOut; 776 m_timeOut=m__timeOut;
777 v.Format("%u",m_timeOut); 777 v.Format("%u",m_timeOut);
778 o[tftpoTOut]=v; 778 o[tftpoTOut]=v;
779 } 779 }
780 } 780 }
781 state = stateXfer; 781 state = stateXfer;
782 m_ACK=0; 782 m_ACK=0;
783 if(o.GetCount()){ 783 if(o.GetCount()){
784 tftp *p = tftp::Allocate(tftp::tftpOACK::tftpSize(&o)); 784 tftp *p = tftp::Allocate(tftp::tftpOACK::tftpSize(&o));
785 ASSERT(p); 785 ASSERT(p);
786 p->SetOpcode(tftp::opOACK); 786 p->SetOpcode(tftp::opOACK);
787 p->data.m_OACK.Set(&o); 787 p->data.m_OACK.Set(&o);
788 PostTFTP(p,TRUE); 788 PostTFTP(p,TRUE);
789 }else 789 }else
790 DoXfer(); 790 DoXfer();
791 } 791 }
792 return TRUE; 792 return TRUE;
793} 793}
794 794
795CRRQSocket::CRRQSocket(CPumpKINDlg *daddy,LPCTSTR fileName,LPCTSTR type,SOCKADDR_IN *sin) 795CRRQSocket::CRRQSocket(CPumpKINDlg *daddy,LPCTSTR fileName,LPCTSTR type,SOCKADDR_IN *sin)
796 : CXferSocket(daddy,fileName,type,sin) 796 : CXferSocket(daddy,fileName,type,sin)
797{ 797{
798 m_ACK=0; 798 m_ACK=0;
799 m_LastSlack=0; 799 m_LastSlack=0;
800} 800}
801 801
802UINT tftp::tftpERROR::tftpSize(LPCTSTR msg) 802UINT tftp::tftpERROR::tftpSize(LPCTSTR msg)
803{ 803{
804 return tftpHdrSize-tftpSlackSize+sizeof(tftp::tftpERROR::tftpErrorCode)+strlen(msg)+1; 804 return tftpHdrSize-tftpSlackSize+sizeof(tftp::tftpERROR::tftpErrorCode)+strlen(msg)+1;
805} 805}
806 806
807tftp* tftp::Allocate(UINT tftpSize) 807tftp* tftp::Allocate(UINT tftpSize)
808{ 808{
809 ASSERT(tftpSize); 809 ASSERT(tftpSize);
810tftp* rv = (tftp*) new BYTE[tftpSlackSize+tftpSize]; 810tftp* rv = (tftp*) new BYTE[tftpSlackSize+tftpSize];
811 ASSERT(rv); 811 ASSERT(rv);
812 rv->length=tftpSize; 812 rv->length=tftpSize;
813 return rv; 813 return rv;
814} 814}
815 815
816void tftp::errSet(UINT code,LPCTSTR msg) 816void tftp::errSet(UINT code,LPCTSTR msg)
817{ 817{
818 ASSERT(this); 818 ASSERT(this);
819 ASSERT(length>=data.m_ERROR.tftpSize(msg)); 819 ASSERT(length>=data.m_ERROR.tftpSize(msg));
820 strcpy((char*)data.m_ERROR.data,msg); 820 strcpy((char*)data.m_ERROR.data,msg);
821 data.m_ERROR.SetCode(code); 821 data.m_ERROR.SetCode(code);
822} 822}
823 823
824void CXferSocket::PostTFTP(tftp* p,BOOL retryable) 824void CXferSocket::PostTFTP(tftp* p,BOOL retryable)
825{ 825{
826 ASSERT(p); 826 ASSERT(p);
827 m_Queue.AddTail(p); 827 m_Queue.AddTail(p);
828 DoSelect(); 828 DoSelect();
829 if(!m_bRetry){ 829 if(!m_bRetry){
830 if(retryable) 830 if(retryable)
831 SetTry(p); 831 SetTry(p);
832 else 832 else
833 SetTry(); 833 SetTry();
834 } 834 }
835 ResetTimeout(); 835 ResetTimeout();
836} 836}
837 837
838void CXferSocket::Deny(UINT errCode,UINT errID) 838void CXferSocket::Deny(UINT errCode,UINT errID)
839{ 839{
840 PostError(errCode,errID); 840 PostError(errCode,errID);
841 state=stateDeny; 841 state=stateDeny;
842} 842}
843 843
844void CRRQSocket::DoXfer() 844void CRRQSocket::DoXfer()
845{ 845{
846tftp *p = tftp::Allocate(tftp::tftpDATA::tftpSize(m_blkSize)); 846tftp *p = tftp::Allocate(tftp::tftpDATA::tftpSize(m_blkSize));
847 ASSERT(p); 847 ASSERT(p);
848 p->SetOpcode(tftp::opDATA); 848 p->SetOpcode(tftp::opDATA);
849 TRY{ 849 TRY{
850 m_File.Seek(m_ACK*m_blkSize,CFile::begin); 850 m_File.Seek(m_ACK*m_blkSize,CFile::begin);
851 int bytes = m_File.Read(p->data.m_DATA.data,m_blkSize); 851 int bytes = m_File.Read(p->data.m_DATA.data,m_blkSize);
852 p->data.m_DATA.SetBlock(m_ACK+1); 852 p->data.m_DATA.SetBlock(m_ACK+1);
853 p->length=p->length-m_blkSize+bytes; 853 p->length=p->length-m_blkSize+bytes;
854 m_LastSlack = m_blkSize-bytes; 854 m_LastSlack = m_blkSize-bytes;
855 PostTFTP(p); 855 PostTFTP(p);
856 if(bytes<m_blkSize){ 856 if(bytes<m_blkSize){
857 state=stateFinish; 857 state=stateClosing; m_ACKtoClose = m_ACK+1;
858 ASSERT(m_Daddy);
859 CString tmp;
860 tmp.Format(IDS_LOG_XFERRRQFINISHED,(LPCTSTR)m_FileName);
861 m_Daddy->LogLine(tmp);
862 } 858 }
863 }CATCH(CFileException,e){ 859 }CATCH(CFileException,e){
864 Deny(e); 860 Deny(e);
865 }END_CATCH 861 }END_CATCH
866} 862}
867 863
868UINT tftp::tftpDATA::tftpSize(UINT blkSize) 864UINT tftp::tftpDATA::tftpSize(UINT blkSize)
869{ 865{
870 return tftpHdrSize-tftpSlackSize+sizeof(tftp::tftpDATA) 866 return tftpHdrSize-tftpSlackSize+sizeof(tftp::tftpDATA)
871 -sizeof(BYTE)+blkSize; 867 -sizeof(BYTE)+blkSize;
872} 868}
873 869
874void CXferSocket::Deny(CFileException* e) 870void CXferSocket::Deny(CFileException* e)
875{ 871{
876 PostError(e); 872 PostError(e);
877 state=stateDeny; 873 state=stateDeny;
878} 874}
879 875
880void CXferSocket::PostError(UINT errCode,UINT errID) 876void CXferSocket::PostError(UINT errCode,UINT errID)
881{ 877{
882CString msg; 878CString msg;
883 msg.LoadString(errID); 879 msg.LoadString(errID);
884 ASSERT(m_Daddy); 880 ASSERT(m_Daddy);
885 /*// *** 881 /*// ***
886CString tmp; 882CString tmp;
887 tmp.Format(IDS_LOG_SENTTFTPERROR,errCode,(LPCTSTR)msg); 883 tmp.Format(IDS_LOG_SENTTFTPERROR,errCode,(LPCTSTR)msg);
888 m_Daddy->LogLine(tmp); 884 m_Daddy->LogLine(tmp);
889 */ 885 */
890tftp* err = tftp::Allocate(tftp::tftpERROR::tftpSize(msg)); 886tftp* err = tftp::Allocate(tftp::tftpERROR::tftpSize(msg));
891err->SetOpcode(tftp::opERROR); 887err->SetOpcode(tftp::opERROR);
892 err->errSet(errCode,msg); 888 err->errSet(errCode,msg);
893 PostTFTP(err); 889 PostTFTP(err);
894} 890}
895 891
896void CXferSocket::PostError(CFileException* e) 892void CXferSocket::PostError(CFileException* e)
897{ 893{
898UINT eCode; 894UINT eCode;
899UINT eMsgID; 895UINT eMsgID;
900 switch(e->m_cause){ 896 switch(e->m_cause){
901 case CFileException::fileNotFound: 897 case CFileException::fileNotFound:
902 eCode=tftp::errNotFound; 898 eCode=tftp::errNotFound;
903 eMsgID=IDS_TFTP_ERROR_NOTFOUND; 899 eMsgID=IDS_TFTP_ERROR_NOTFOUND;
904 break; 900 break;
905 case CFileException::accessDenied: 901 case CFileException::accessDenied:
906 eCode=tftp::errAccessViolation; 902 eCode=tftp::errAccessViolation;
907 eMsgID=IDS_TFTP_ERROR_ACCESS; 903 eMsgID=IDS_TFTP_ERROR_ACCESS;
908 break; 904 break;
909 case CFileException::directoryFull: 905 case CFileException::directoryFull:
910 eCode=tftp::errDiskFull; 906 eCode=tftp::errDiskFull;
911 eMsgID=IDS_TFTP_ERROR_DIRFULL; 907 eMsgID=IDS_TFTP_ERROR_DIRFULL;
912 break; 908 break;
913 case CFileException::sharingViolation: 909 case CFileException::sharingViolation:
914 eCode=tftp::errAccessViolation; 910 eCode=tftp::errAccessViolation;
915 eMsgID=IDS_TFTP_ERROR_SHARING; 911 eMsgID=IDS_TFTP_ERROR_SHARING;
916 break; 912 break;
917 case CFileException::diskFull: 913 case CFileException::diskFull:
918 eCode=tftp::errDiskFull; 914 eCode=tftp::errDiskFull;
919 eMsgID=IDS_TFTP_ERROR_DISKFULL; 915 eMsgID=IDS_TFTP_ERROR_DISKFULL;
920 break; 916 break;
921 default: 917 default:
922 eCode=tftp::errUndefined; 918 eCode=tftp::errUndefined;
923 eMsgID=IDS_TFTP_ERROR_UNDEFINED; 919 eMsgID=IDS_TFTP_ERROR_UNDEFINED;
924 break; 920 break;
925 } 921 }
926 PostError(eCode,eMsgID); 922 PostError(eCode,eMsgID);
927} 923}
928 924
929ULONG CRRQSocket::GetACK(void) 925ULONG CRRQSocket::GetACK(void)
930{ 926{
931 return (m_ACK*m_blkSize)-m_LastSlack; 927 return (m_ACK*m_blkSize)-m_LastSlack;
932} 928}
933 929
934BOOL CRRQSocket::OnTFTP(tftp* p) 930BOOL CRRQSocket::OnTFTP(tftp* p)
935{ 931{
936BOOL rv = TRUE; 932BOOL rv = TRUE;
937 switch(p->Opcode()){ 933 switch(p->Opcode()){
938 case tftp::opOACK: 934 case tftp::opOACK:
939 m_ACK=0; 935 {
940 ASSERT(state!=stateFinish); 936 m_ACK=0;
941 { 937 ASSERT(state!=stateFinish);
942 tftp::tftpOptions o; 938 tftp::tftpOptions o;
943 if(p->GetOptions(&o)){ 939 if(p->GetOptions(&o)){
944 CString v; 940 CString v;
945 if(o.Lookup(tftpoBSize,v)){ 941 if(o.Lookup(tftpoBSize,v)){
946 m_blkSize=atoi(v); 942 m_blkSize=atoi(v);
947 if(!m_blkSize){// *** More sanity checks 943 if(!m_blkSize){// *** More sanity checks
948 Deny(tftp::errOption,IDS_TFTP_ERROR_BSIZE); 944 Deny(tftp::errOption,IDS_TFTP_ERROR_BSIZE);
949 rv = TRUE; 945 rv = TRUE;
950 break; 946 break;
947 }
951 } 948 }
952 } 949 if(o.Lookup(tftpoTOut,v)){
953 if(o.Lookup(tftpoTOut,v)){ 950 m_timeOut=atoi(v);
954 m_timeOut=atoi(v); 951 if(!m_timeOut){// *** More sanity checks
955 if(!m_timeOut){// *** More sanity checks 952 Deny(tftp::errOption,IDS_TFTP_ERROR_TOUT);
956 Deny(tftp::errOption,IDS_TFTP_ERROR_TOUT); 953 rv = TRUE;
957 rv = TRUE; 954 break;
958 break; 955 }
956 }
957 if(o.Lookup(tftpoXResume,v)){
958 m_ACK=atoi(v);
959 } 959 }
960 } 960 }
961 if(o.Lookup(tftpoXResume,v)){ 961 UpdateList();
962 m_ACK=atoi(v); 962 DoXfer();
963 }
964 } 963 }
965 UpdateList();
966 DoXfer();
967 }
968 break; 964 break;
969 case tftp::opACK: 965 case tftp::opACK:
970 m_ACK=p->data.m_ACK.Block(); 966 m_ACK=p->data.m_ACK.Block();
971 if(state!=stateFinish){ 967 if(state==stateClosing && m_ACK==m_ACKtoClose) {
968 state = stateFinish;
969 ASSERT(m_Daddy);
970 CString tmp;
971 tmp.Format(IDS_LOG_XFERRRQFINISHED,(LPCTSTR)m_FileName);
972 m_Daddy->LogLine(tmp);
973 rv = FALSE;
974 DoSelect(TRUE);
975 }else if(state!=stateFinish){
972 UpdateList(); 976 UpdateList();
973 DoXfer(); 977 DoXfer();
974 } 978 }
975 break; 979 break;
976 case tftp::opERROR: 980 case tftp::opERROR:
977 { 981 {
978 ASSERT(m_Daddy); 982 ASSERT(m_Daddy);
979 CString tmp; 983 CString tmp;
980 tmp.Format(IDS_LOG_GOTTFTPERROR,p->data.m_ERROR.Code(),(LPCTSTR)p->errMessage()); 984 tmp.Format(IDS_LOG_GOTTFTPERROR,p->data.m_ERROR.Code(),(LPCTSTR)p->errMessage());
981 m_Daddy->LogLine(tmp); 985 m_Daddy->LogLine(tmp);
982 } 986 }
983 Destroy(FALSE); 987 Destroy(FALSE);
984 rv = FALSE; 988 rv = FALSE;
985 break; 989 break;
986 default: 990 default:
987 { 991 {
988 ASSERT(m_Daddy); 992 ASSERT(m_Daddy);
989 CString tmp; 993 CString tmp;
990 tmp.Format(IDS_LOG_XFEROPCODE,p->Opcode()); 994 tmp.Format(IDS_LOG_XFEROPCODE,p->Opcode());
991 m_Daddy->LogLine(tmp); 995 m_Daddy->LogLine(tmp);
992 // *** Self destruct maybe?? 996 // *** Self destruct maybe??
993 } 997 }
994 break; 998 break;
995 } 999 }
996 return rv; 1000 return rv;
997} 1001}
998 1002
999BOOL CWRQSocket::OnTFTP(tftp* p) 1003BOOL CWRQSocket::OnTFTP(tftp* p)
1000{ 1004{
1001 switch(p->Opcode()){ 1005 switch(p->Opcode()){
1002 case tftp::opOACK: 1006 case tftp::opOACK:
1003 ASSERT(state!=stateFinish); 1007 ASSERT(state!=stateFinish);
1004 { 1008 {
1005 if(m_bResume) 1009 if(m_bResume)
1006 m_ACK=m_File.GetLength()/m_blkSize; 1010 m_ACK=m_File.GetLength()/m_blkSize;
1007 else 1011 else
1008 m_ACK=0; 1012 m_ACK=0;
1009 tftp::tftpOptions o; 1013 tftp::tftpOptions o;
1010 if(p->GetOptions(&o)){ 1014 if(p->GetOptions(&o)){
1011 CString v; 1015 CString v;
1012 if(o.Lookup(tftpoBSize,v)){ 1016 if(o.Lookup(tftpoBSize,v)){
1013 m_blkSize=atoi(v); 1017 m_blkSize=atoi(v);
1014 if(!m_blkSize){// *** More sanity checks 1018 if(!m_blkSize){// *** More sanity checks
1015 Deny(tftp::errOption,IDS_TFTP_ERROR_BSIZE); 1019 Deny(tftp::errOption,IDS_TFTP_ERROR_BSIZE);
1016 return TRUE; 1020 return TRUE;
1017 } 1021 }
1018 } 1022 }
1019 if(o.Lookup(tftpoTOut,v)){ 1023 if(o.Lookup(tftpoTOut,v)){
1020 m_timeOut=atoi(v); 1024 m_timeOut=atoi(v);
1021 if(!m_timeOut){// *** More sanity checks 1025 if(!m_timeOut){// *** More sanity checks
1022 Deny(tftp::errOption,IDS_TFTP_ERROR_TOUT); 1026 Deny(tftp::errOption,IDS_TFTP_ERROR_TOUT);
1023 return TRUE; 1027 return TRUE;
1024 } 1028 }
1025 } 1029 }
1026 if(o.Lookup(tftpoTSize,v)){ 1030 if(o.Lookup(tftpoTSize,v)){
1027 m_xferSize=atoi(v); 1031 m_xferSize=atoi(v);
1028 } 1032 }
1029 } 1033 }
1030 UpdateList(); 1034 UpdateList();
1031 DoXfer(); 1035 DoXfer();
1032 } 1036 }
1033 break; 1037 break;
1034 case tftp::opDATA: 1038 case tftp::opDATA:
1035 { 1039 {
1036 UINTblock = p->data.m_DATA.Block(); 1040 UINTblock = p->data.m_DATA.Block();
1037 TRY{ 1041 TRY{
1038 m_File.Seek((block-1)*m_blkSize,CFile::begin); 1042 m_File.Seek((block-1)*m_blkSize,CFile::begin);
1039 int bytes = p->length-sizeof(p->data.m_DATA.block)-(tftpHdrSize-tftpSlackSize); 1043 int bytes = p->length-sizeof(p->data.m_DATA.block)-(tftpHdrSize-tftpSlackSize);
1040 if(bytes){ 1044 if(bytes){
1041 m_File.Write(p->data.m_DATA.data,bytes); 1045 m_File.Write(p->data.m_DATA.data,bytes);
1042 // *** Move to the other place where we can do it not that often 1046 // *** Move to the other place where we can do it not that often
1043 m_File.SetLength(m_File.GetPosition()); 1047 m_File.SetLength(m_File.GetPosition());
1044 } 1048 }
1045 if(bytes<m_blkSize){ 1049 if(bytes<m_blkSize){
1046 state=stateFinish; 1050 state=stateFinish;
1047 ASSERT(m_Daddy); 1051 ASSERT(m_Daddy);
1048 CString tmp; 1052 CString tmp;
1049 tmp.Format(IDS_LOG_XFERWRQFINISHED,(LPCTSTR)m_FileName); 1053 tmp.Format(IDS_LOG_XFERWRQFINISHED,(LPCTSTR)m_FileName);
1050 m_Daddy->LogLine(tmp); 1054 m_Daddy->LogLine(tmp);
1051 } 1055 }
1052 m_ACK=block; 1056 m_ACK=block;
1053 m_LastSlack=m_blkSize-bytes; 1057 m_LastSlack=m_blkSize-bytes;
1054 UpdateList(); 1058 UpdateList();
1055 DoXfer(); 1059 DoXfer();
1056 }CATCH(CFileException,e){ 1060 }CATCH(CFileException,e){
1057 Deny(e); 1061 Deny(e);
1058 }END_CATCH 1062 }END_CATCH
1059 } 1063 }
1060 break; 1064 break;
1061 case tftp::opERROR: 1065 case tftp::opERROR:
1062 { 1066 {
1063 ASSERT(m_Daddy); 1067 ASSERT(m_Daddy);
1064 CString tmp; 1068 CString tmp;
1065 tmp.Format(IDS_LOG_GOTTFTPERROR,p->data.m_ERROR.Code(),(LPCTSTR)p->errMessage()); 1069 tmp.Format(IDS_LOG_GOTTFTPERROR,p->data.m_ERROR.Code(),(LPCTSTR)p->errMessage());
1066 m_Daddy->LogLine(tmp); 1070 m_Daddy->LogLine(tmp);
1067 } 1071 }
1068 Destroy(FALSE); 1072 Destroy(FALSE);
1069 return FALSE; 1073 return FALSE;
1070 default: 1074 default:
1071 { 1075 {
1072 ASSERT(m_Daddy); 1076 ASSERT(m_Daddy);
1073 CString tmp; 1077 CString tmp;
1074 tmp.Format(IDS_LOG_XFEROPCODE,p->Opcode()); 1078 tmp.Format(IDS_LOG_XFEROPCODE,p->Opcode());
1075 m_Daddy->LogLine(tmp); 1079 m_Daddy->LogLine(tmp);
1076 // *** Self destruct maybe?? 1080 // *** Self destruct maybe??
1077 } 1081 }
1078 break; 1082 break;
1079 } 1083 }
1080 return TRUE; 1084 return TRUE;
1081} 1085}
1082 1086
1083void tftp::SetOpcode(WORD op) 1087void tftp::SetOpcode(WORD op)
1084{ 1088{
1085 opcode = REVERSEBYTES(op); 1089 opcode = REVERSEBYTES(op);
1086} 1090}
1087void tftp::tftpDATA::SetBlock(WORD b) 1091void tftp::tftpDATA::SetBlock(WORD b)
1088{ 1092{
1089 block=REVERSEBYTES(b); 1093 block=REVERSEBYTES(b);
1090} 1094}
1091WORD tftp::tftpDATA::Block() 1095WORD tftp::tftpDATA::Block()
1092{ 1096{
1093 return REVERSEBYTES(block); 1097 return REVERSEBYTES(block);
1094} 1098}
1095WORD tftp::tftpACK::Block() 1099WORD tftp::tftpACK::Block()
1096{ 1100{
1097 return REVERSEBYTES(block); 1101 return REVERSEBYTES(block);
1098} 1102}
1099void tftp::tftpACK::SetBlock(WORD b) 1103void tftp::tftpACK::SetBlock(WORD b)
1100{ 1104{
1101 block = REVERSEBYTES(b); 1105 block = REVERSEBYTES(b);
1102} 1106}
1103WORD tftp::tftpERROR::Code() 1107WORD tftp::tftpERROR::Code()
1104{ 1108{
1105 return REVERSEBYTES(code); 1109 return REVERSEBYTES(code);
1106} 1110}
1107void tftp::tftpERROR::SetCode(WORD c) 1111void tftp::tftpERROR::SetCode(WORD c)
1108{ 1112{
1109 code = REVERSEBYTES(c); 1113 code = REVERSEBYTES(c);
1110} 1114}
1111 1115
1112 1116
1113CString tftp::errMessage() 1117CString tftp::errMessage()
1114{ 1118{
1115CString rv; 1119CString rv;
1116 if(memchr(data.m_ERROR.data,0,length-(tftpHdrSize-tftpSlackSize)-sizeof(data.m_ERROR.code))) 1120 if(memchr(data.m_ERROR.data,0,length-(tftpHdrSize-tftpSlackSize)-sizeof(data.m_ERROR.code)))
1117 rv = (LPCTSTR)data.m_ERROR.data; 1121 rv = (LPCTSTR)data.m_ERROR.data;
1118 return rv; 1122 return rv;
1119} 1123}
1120 1124
1121void CXferSocket::Destroy(BOOL success) 1125void CXferSocket::Destroy(BOOL success)
1122{ 1126{
1123 if(m_wndResolver){ 1127 if(m_wndResolver){
1124 delete m_wndResolver; 1128 delete m_wndResolver;
1125 m_wndResolver=NULL; 1129 m_wndResolver=NULL;
1126 } 1130 }
1127 SetTry(); 1131 SetTry();
1128 m_Daddy->m_bnw.StartSound( 1132 m_Daddy->m_bnw.StartSound(
1129 success 1133 success
1130 ? m_Daddy->m_bnwSuccess 1134 ? m_Daddy->m_bnwSuccess
1131 : m_Daddy->m_bnwAbort 1135 : m_Daddy->m_bnwAbort
1132 ); 1136 );
1133 if(m_File.m_hFile!=CFile::hFileNull){ 1137 if(m_File.m_hFile!=CFile::hFileNull){
1134 TRY{ 1138 TRY{
1135 m_File.Close(); 1139 m_File.Close();
1136 }CATCH(CFileException,e){ 1140 }CATCH(CFileException,e){
1137 TRACE0("Error closing file\n"); 1141 TRACE0("Error closing file\n");
1138 }END_CATCH 1142 }END_CATCH
1139 } 1143 }
1140 ASSERT(m_Daddy); 1144 ASSERT(m_Daddy);
1141 m_Daddy->KillTimer(m_hSocket); 1145 m_Daddy->KillTimer(m_hSocket);
1142 m_Daddy->m_Xfers.RemoveKey(m_hSocket); 1146 m_Daddy->m_Xfers.RemoveKey(m_hSocket);
1143LV_FINDINFO lvf; 1147LV_FINDINFO lvf;
1144 memset(&lvf,0,sizeof(lvf)); 1148 memset(&lvf,0,sizeof(lvf));
1145 lvf.flags=LVFI_PARAM; 1149 lvf.flags=LVFI_PARAM;
1146 lvf.lParam=(LPARAM)this; 1150 lvf.lParam=(LPARAM)this;
1147int i = m_Daddy->m_List.FindItem(&lvf); 1151int i = m_Daddy->m_List.FindItem(&lvf);
1148 if(i>=0) 1152 if(i>=0)
1149 m_Daddy->m_List.DeleteItem(i); 1153 m_Daddy->m_List.DeleteItem(i);
1150 delete this; 1154 delete this;
1151} 1155}
1152 1156
1153void CPumpKINDlg::LogLineToScreen(LPCTSTR str) 1157void CPumpKINDlg::LogLineToScreen(LPCTSTR str)
1154{ 1158{
1155 ASSERT(m_LogLength); 1159 ASSERT(m_LogLength);
1156 while(m_Log.GetCount()>m_LogLength && m_Log.GetCount()!=LB_ERR){ 1160 while(m_Log.GetCount()>m_LogLength && m_Log.GetCount()!=LB_ERR){
1157 CTime *t = (CTime*)m_Log.GetItemData(0); 1161 CTime *t = (CTime*)m_Log.GetItemData(0);
1158 if(((DWORD)t)!=LB_ERR){ 1162 if(((DWORD)t)!=LB_ERR){
1159 ASSERT(t); 1163 ASSERT(t);
1160 m_LogTimes.RemoveKey(t); 1164 m_LogTimes.RemoveKey(t);
1161 delete t; 1165 delete t;
1162 } 1166 }
1163 m_Log.DeleteString(0); 1167 m_Log.DeleteString(0);
1164 } 1168 }
1165int i = m_Log.AddString(str); 1169int i = m_Log.AddString(str);
1166 ASSERT(i!=LB_ERR); 1170 ASSERT(i!=LB_ERR);
1167CTime *t = new CTime(CTime::GetCurrentTime()); 1171CTime *t = new CTime(CTime::GetCurrentTime());
1168 m_Log.SetItemData(i,(DWORD)(m_LogTimes[t]=t)); 1172 m_Log.SetItemData(i,(DWORD)(m_LogTimes[t]=t));
1169 m_Log.SetCurSel(i); 1173 m_Log.SetCurSel(i);
1170} 1174}
1171 1175
1172void CPumpKINDlg::LogLine(UINT msgID) 1176void CPumpKINDlg::LogLine(UINT msgID)
1173{ 1177{
1174CString tmp; 1178CString tmp;
1175 tmp.Format(msgID); 1179 tmp.Format(msgID);
1176 LogLine(tmp); 1180 LogLine(tmp);
1177} 1181}
1178 1182
1179void CXferSocket::TurnSlashes(CString& fn,BOOL bBack) 1183void CXferSocket::TurnSlashes(CString& fn,BOOL bBack)
1180{ 1184{
1181 ints = fn.Find(bBack?'/':'\\'); 1185 ints = fn.Find(bBack?'/':'\\');
1182 while(s>=0){ 1186 while(s>=0){
1183 fn.SetAt(s,bBack?'\\':'/'); 1187 fn.SetAt(s,bBack?'\\':'/');
1184 s = fn.Find(bBack?'/':'\\'); 1188 s = fn.Find(bBack?'/':'\\');
1185 } 1189 }
1186} 1190}
1187 1191
1188CString CXferSocket::ApplyRoot(LPCTSTR fileName) 1192CString CXferSocket::ApplyRoot(LPCTSTR fileName)
1189{ 1193{
1190 ASSERT(m_Daddy); 1194 ASSERT(m_Daddy);
1191CString fn = fileName; 1195CString fn = fileName;
1192CString rv = m_Daddy->m_TFTPRoot; 1196CString rv = m_Daddy->m_TFTPRoot;
1193 if(rv.IsEmpty()) 1197 if(rv.IsEmpty())
1194 rv = "."; 1198 rv = ".";
1195 if(rv[rv.GetLength()-1]!='\\') 1199 if(rv[rv.GetLength()-1]!='\\')
1196 rv+="\\"; 1200 rv+="\\";
1197 while((!fn.IsEmpty()) && fn[0]=='\\') 1201 while((!fn.IsEmpty()) && fn[0]=='\\')
1198 fn=fn.Mid(1); 1202 fn=fn.Mid(1);
1199 rv+=fn; 1203 rv+=fn;
1200 return rv; 1204 return rv;
1201} 1205}
1202 1206
1203void CPumpKINDlg::OnOptions() 1207void CPumpKINDlg::OnOptions()
1204{ 1208{
1205CPropertySheet cps(IDS_TITLE_OPTIONS,this); 1209CPropertySheet cps(IDS_TITLE_OPTIONS,this);
1206CPropsServer server; 1210CPropsServer server;
1207CPropsNetwork network; 1211CPropsNetwork network;
1208CPropsSounds sounds; 1212CPropsSounds sounds;
1209CPropsACL acl; 1213CPropsACL acl;
1210 1214
1211 server.m_RRQMode=m_RRQMode; 1215 server.m_RRQMode=m_RRQMode;
1212 server.m_TFTPRoot=m_TFTPRoot; 1216 server.m_TFTPRoot=m_TFTPRoot;
1213 server.m_TFTPSubdirs=m_bTFTPSubdirs; 1217 server.m_TFTPSubdirs=m_bTFTPSubdirs;
1214 server.m_WRQMode=m_WRQMode; 1218 server.m_WRQMode=m_WRQMode;
1215 server.m_PromptTimeOut=m_PromptTimeOut; 1219 server.m_PromptTimeOut=m_PromptTimeOut;
1216 server.m_LogFile=m_LogFile; 1220 server.m_LogFile=m_LogFile;
1217 1221
1218 network.m_ListenPort=m_ListenPort; 1222 network.m_ListenPort=m_ListenPort;
1219 network.m_SpeakPort=m_SpeakPort; 1223 network.m_SpeakPort=m_SpeakPort;
1220 network.m_TimeOut=m_TFTPTimeOut.GetTotalSeconds(); 1224 network.m_TimeOut=m_TFTPTimeOut.GetTotalSeconds();
1221 network.m_BlockSize=m_BlockSize; 1225 network.m_BlockSize=m_BlockSize;
1222 1226
1223 sounds.m_Request = m_bnwRequest; 1227 sounds.m_Request = m_bnwRequest;
1224 sounds.m_Success = m_bnwSuccess; 1228 sounds.m_Success = m_bnwSuccess;
1225 sounds.m_Abort = m_bnwAbort; 1229 sounds.m_Abort = m_bnwAbort;
1226 1230
1227 acl.m_rulist = m_aclRules; 1231 acl.m_rulist = m_aclRules;
1228 1232
1229 cps.AddPage(&server); 1233 cps.AddPage(&server);
1230 cps.AddPage(&network); 1234 cps.AddPage(&network);
1231 cps.AddPage(&sounds); 1235 cps.AddPage(&sounds);
1232 cps.AddPage(&acl); 1236 cps.AddPage(&acl);
1233 if(cps.DoModal()==IDOK){ 1237 if(cps.DoModal()==IDOK){
1234 m_RRQMode=server.m_RRQMode; 1238 m_RRQMode=server.m_RRQMode;
1235 m_TFTPRoot=server.m_TFTPRoot; 1239 m_TFTPRoot=server.m_TFTPRoot;
1236 m_bTFTPSubdirs=server.m_TFTPSubdirs; 1240 m_bTFTPSubdirs=server.m_TFTPSubdirs;
1237 m_WRQMode=server.m_WRQMode; 1241 m_WRQMode=server.m_WRQMode;
1238 m_PromptTimeOut=server.m_PromptTimeOut; 1242 m_PromptTimeOut=server.m_PromptTimeOut;
1239 m_LogFile=server.m_LogFile; 1243 m_LogFile=server.m_LogFile;
1240 1244
1241 m_ListenPort=network.m_ListenPort; 1245 m_ListenPort=network.m_ListenPort;
1242 m_SpeakPort=network.m_SpeakPort; 1246 m_SpeakPort=network.m_SpeakPort;
1243 m_TFTPTimeOut=CTimeSpan(network.m_TimeOut); 1247 m_TFTPTimeOut=CTimeSpan(network.m_TimeOut);
1244 m_BlockSize=network.m_BlockSize; 1248 m_BlockSize=network.m_BlockSize;
1245 1249
1246 m_bnwRequest = sounds.m_Request; 1250 m_bnwRequest = sounds.m_Request;
1247 m_bnwSuccess = sounds.m_Success; 1251 m_bnwSuccess = sounds.m_Success;
1248 m_bnwAbort = sounds.m_Abort; 1252 m_bnwAbort = sounds.m_Abort;
1249 1253
1250 m_aclRules = acl.m_rulist; 1254 m_aclRules = acl.m_rulist;
1251 1255
1252 m_lastlogerr.Empty(); 1256 m_lastlogerr.Empty();
1253 } 1257 }
1254} 1258}
1255 1259
1256BOOL CRRQSocket::ConfirmRequest() 1260BOOL CRRQSocket::ConfirmRequest()
1257{ 1261{
1258CConfirmRRQDlg cd(NULL); 1262CConfirmRRQDlg cd(NULL);
1259 cd.m_Daddy=this; 1263 cd.m_Daddy=this;
1260 cd.m_File=m_FileName; 1264 cd.m_File=m_FileName;
1261 cd.m_Host=inet_ntoa(m_Peer.sin_addr); 1265 cd.m_Host=inet_ntoa(m_Peer.sin_addr);
1262 if(cd.DoModal()==IDOK) 1266 if(cd.DoModal()==IDOK)
1263 return TRUE; 1267 return TRUE;
1264 return FALSE; 1268 return FALSE;
1265} 1269}
1266 1270
1267CWRQSocket::CWRQSocket(CPumpKINDlg* daddy,LPCTSTR fileName,LPCTSTR type,SOCKADDR_IN *sin) 1271CWRQSocket::CWRQSocket(CPumpKINDlg* daddy,LPCTSTR fileName,LPCTSTR type,SOCKADDR_IN *sin)
1268 : CXferSocket(daddy,fileName,type,sin) 1272 : CXferSocket(daddy,fileName,type,sin)
1269{ 1273{
1270 state=stateNone; 1274 state=stateNone;
1271 m_ACK=0; 1275 m_ACK=0;
1272 m_LastSlack=0; 1276 m_LastSlack=0;
1273 m_bResume=FALSE; 1277 m_bResume=FALSE;
1274} 1278}
1275 1279
1276BOOL CWRQSocket::Create(LPCTSTR localFile,LPCTSTR hostName) 1280BOOL CWRQSocket::Create(LPCTSTR localFile,LPCTSTR hostName)
1277{ 1281{
1278 if(!CAsyncSocket::Create(0,SOCK_DGRAM)) 1282 if(!CAsyncSocket::Create(0,SOCK_DGRAM))
1279 return FALSE; 1283 return FALSE;
1280 ASSERT(m_Daddy); 1284 ASSERT(m_Daddy);
1281 ASSERT(m_Peer.sin_addr.s_addr!=INADDR_NONE || hostName); 1285 ASSERT(m_Peer.sin_addr.s_addr!=INADDR_NONE || hostName);
1282 m_Daddy->m_Xfers[m_hSocket]=this; 1286 m_Daddy->m_Xfers[m_hSocket]=this;
1283 UpdateList(); 1287 UpdateList();
1284CString lf; 1288CString lf;
1285 if(!localFile) { 1289 if(!localFile) {
1286 lf = m_FileName; 1290 lf = m_FileName;
1287 TurnSlashes(lf,TRUE); 1291 TurnSlashes(lf,TRUE);
1288 } 1292 }
1289CString fn = localFile?ApplyRootGently(localFile):ApplyRoot(lf); 1293CString fn = localFile?ApplyRootGently(localFile):ApplyRoot(lf);
1290 if(!localFile){// This is an incoming request.. 1294 if(!localFile){// This is an incoming request..
1291 if(CheckBadRelativeness(m_FileName)){ 1295 if(CheckBadRelativeness(m_FileName)){
1292 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS); 1296 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
1293 return TRUE; 1297 return TRUE;
1294 } 1298 }
1295 BOOL exists; 1299 BOOL exists;
1296 if(!_access((LPCTSTR)fn,0)) 1300 if(!_access((LPCTSTR)fn,0))
1297 m_Rename=exists=TRUE; 1301 m_Rename=exists=TRUE;
1298 else 1302 else
1299 m_Rename=exists=FALSE; 1303 m_Rename=exists=FALSE;
1300 int atar=m_Daddy->m_aclRules.FindTarget(acl_rule::opWRQ,m_Peer.sin_addr.s_addr); 1304 int atar=m_Daddy->m_aclRules.FindTarget(acl_rule::opWRQ,m_Peer.sin_addr.s_addr);
1301 if(atar<0) 1305 if(atar<0)
1302 atar=m_Daddy->m_WRQMode; 1306 atar=m_Daddy->m_WRQMode;
1303 switch(atar){ 1307 switch(atar){
1304 case CPumpKINDlg::wrqTakeAll: 1308 case CPumpKINDlg::wrqTakeAll:
1305 if(exists){ 1309 if(exists){
1306 if(!RenameFile(fn)){ 1310 if(!RenameFile(fn)){
1307 Deny(tftp::errDiskFull,IDS_TFTP_ERROR_FAILEDTORENAME); 1311 Deny(tftp::errDiskFull,IDS_TFTP_ERROR_FAILEDTORENAME);
1308 return TRUE; 1312 return TRUE;
1309 } 1313 }
1310 } 1314 }
1311 break; 1315 break;
1312 case CPumpKINDlg::wrqConfirmIfExists: 1316 case CPumpKINDlg::wrqConfirmIfExists:
1313 if(!exists) 1317 if(!exists)
1314 break; 1318 break;
1315 case CPumpKINDlg::wrqAlwaysConfirm: 1319 case CPumpKINDlg::wrqAlwaysConfirm:
1316 if(exists) 1320 if(exists)
1317 m_bResume=TRUE; 1321 m_bResume=TRUE;
1318 if(ConfirmRequest()){ 1322 if(ConfirmRequest()){
1319 if(m_Rename){ 1323 if(m_Rename){
1320 RenameFile(fn); 1324 RenameFile(fn);
1321 if(SaveAs(fn)) 1325 if(SaveAs(fn))
1322 break; 1326 break;
1323 }else 1327 }else
1324 break; 1328 break;
1325 } 1329 }
1326 default: 1330 default:
1327 TRACE1("Unexpected access target: %d\n",atar); 1331 TRACE1("Unexpected access target: %d\n",atar);
1328 case CPumpKINDlg::wrqDenyAll: 1332 case CPumpKINDlg::wrqDenyAll:
1329 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS); 1333 Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
1330 return TRUE; 1334 return TRUE;
1331 } 1335 }
1332 } 1336 }
1333CFileException e; 1337CFileException e;
1334 if(!m_File.Open( 1338 if(!m_File.Open(
1335 fn, 1339 fn,
1336 m_bResume 1340 m_bResume
1337 ?(CFile::modeWrite|CFile::shareDenyWrite) 1341 ?(CFile::modeWrite|CFile::shareDenyWrite)
1338 :(CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite), 1342 :(CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite),
1339 &e 1343 &e
1340 )){ 1344 )){
1341 if(localFile){// Outgoing request 1345 if(localFile){// Outgoing request
1342 CString tmp; 1346 CString tmp;
1343 tmp.Format(IDS_LOG_FAILEDTOOPEN,fn); 1347 tmp.Format(IDS_LOG_FAILEDTOOPEN,fn);
1344 m_Daddy->LogLine(tmp); 1348 m_Daddy->LogLine(tmp);
1345 return FALSE; 1349 return FALSE;
1346 }else{ 1350 }else{
1347 Deny(&e); 1351 Deny(&e);
1348 return TRUE; 1352 return TRUE;
1349 } 1353 }
1350 } 1354 }
1351 if(hostName){ 1355 if(hostName){
1352 m_HostName=hostName; 1356 m_HostName=hostName;
1353 1357
1354 CString tmp; 1358 CString tmp;
1355 tmp.Format(IDS_LOG_REQUESTING,m_FileName,m_HostName); 1359 tmp.Format(IDS_LOG_REQUESTING,m_FileName,m_HostName);