summaryrefslogtreecommitdiffabout
path: root/PumpKINDlg.cpp
Side-by-side diff
Diffstat (limited to 'PumpKINDlg.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--PumpKINDlg.cpp109
1 files changed, 101 insertions, 8 deletions
diff --git a/PumpKINDlg.cpp b/PumpKINDlg.cpp
index b6b8a36..4cb1633 100644
--- a/PumpKINDlg.cpp
+++ b/PumpKINDlg.cpp
@@ -1,22 +1,24 @@
// PumpKINDlg.cpp : implementation file
//
#include "stdafx.h"
#include "PumpKIN.h"
#include "PumpKINDlg.h"
+#include "ACLTargetCombo.h"
#include "PropsServer.h"
#include "PropsNetwork.h"
#include "PropsSounds.h"
+#include "PropsACL.h"
#include "ConfirmRRQDlg.h"
#include "ConfirmWRQDlg.h"
#include "RequestDlg.h"
#include "Resolver.h"
#include "Retrier.h"
#include "Trayer.h"
#include <io.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
@@ -70,24 +72,28 @@ void CAboutDlg::DoDataExchange(CDataExchange* pDX)
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
ON_BN_CLICKED(IDC_KLEVERNET, OnKlevernet)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPumpKINDlg dialog
CPumpKINDlg::CPumpKINDlg(CWnd* pParent /*=NULL*/)
: CDialog(CPumpKINDlg::IDD, pParent)
{
+ m_Listener.m_Daddy = this;
+
+ m_bListen = TRUE;
+
m_ListenPort = 69;
m_bTFTPSubdirs = TRUE;
m_RRQMode = rrqAlwaysConfirm;
m_WRQMode = wrqAlwaysConfirm;
m_TFTPTimeOut = CTimeSpan(0,0,0,30);
m_RetryTimeOut = CTimeSpan(0,0,0,10);
m_LogLength = 100;
m_SpeakPort = 69;
m_PromptTimeOut=30;
m_bShown=TRUE;
m_bExiting=FALSE;
m_BlockSize=1024;
@@ -98,31 +104,41 @@ CPumpKINDlg::CPumpKINDlg(CWnd* pParent /*=NULL*/)
m_bnwRequest="(bang)"; m_bnwSuccess="(done)";
m_bnwAbort="(oops)";
//{{AFX_DATA_INIT(CPumpKINDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_bmpBack.LoadBitmap(IDB_BACKGROUND);
m_bmpBack.GetBitmap(&m_bitmapBack);
m_Retrier = new CRetrier(this);
ASSERT(m_Retrier);
m_Trayer = new CTrayer(this);
ASSERT(m_Trayer);
+ /* Ensure we're backwards compatible */
+ ASSERT(CPumpKINDlg::rrqGiveAll==0);
+ ASSERT(CPumpKINDlg::rrqAlwaysConfirm==1);
+ ASSERT(CPumpKINDlg::rrqDenyAll==2);
+ ASSERT(CPumpKINDlg::wrqTakeAll==0);
+ ASSERT(CPumpKINDlg::wrqConfirmIfExists==1);
+ ASSERT(CPumpKINDlg::wrqAlwaysConfirm==2);
+ ASSERT(CPumpKINDlg::wrqDenyAll==3);
+ /* -- */
LoadSettings();
}
void CPumpKINDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CPumpKINDlg)
+ DDX_Control(pDX, IDC_LISTENING, m_ListenCtl);
DDX_Control(pDX, IDC_ABORT, m_AbortCtl);
DDX_Control(pDX, IDC_OPTIONS, m_OptionsCtl);
DDX_Control(pDX, IDC_LOG, m_Log);
DDX_Control(pDX, IDC_CONNECTIONS, m_List);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CPumpKINDlg, CDialog)
//{{AFX_MSG_MAP(CPumpKINDlg)
ON_WM_SYSCOMMAND()
ON_WM_DESTROY()
ON_WM_PAINT()
@@ -142,24 +158,26 @@ BEGIN_MESSAGE_MAP(CPumpKINDlg, CDialog)
ON_COMMAND(ID_TRAY_SHOWPUMPKINWINDOW, OnTrayShowpumpkinwindow)
ON_COMMAND(ID_TRAY_EXIT, OnTrayExit)
ON_COMMAND(ID_TRAY_ABOUTPUMPKIN, OnTrayAboutpumpkin)
ON_COMMAND(ID_TRAY_FETCHFILE, OnTrayFetchfile)
ON_COMMAND(ID_TRAY_HELP, OnTrayHelp)
ON_COMMAND(ID_TRAY_OPTIONS, OnTrayOptions)
ON_COMMAND(ID_TRAY_SENDFILE, OnTraySendfile)
ON_WM_WINDOWPOSCHANGING()
ON_LBN_SELCHANGE(IDC_LOG, OnSelchangeLog)
ON_COMMAND(ID_TRAY_OPENFILESFOLDER, OnTrayOpenfilesfolder)
ON_WM_DROPFILES()
ON_BN_CLICKED(ID_HELP, OnHelp)
+ ON_BN_CLICKED(IDC_LISTENING, OnListening)
+ ON_COMMAND(ID_TRAY_LISTEN, OnTrayListen)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPumpKINDlg message handlers
BOOL CPumpKINDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
@@ -208,24 +226,26 @@ CRect listrc;
SetupButtons();
CRect rc, drc;
GetWindowRect(rc);
GetDesktopWindow()->GetWindowRect(drc);
SetWindowPos(NULL,drc.right-6-rc.Width(),6,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
if(m_bShown)
ShowWindow(SW_SHOW);
else
ShowWindow(SW_HIDE);
+ m_ListenCtl.SetCheck(m_Listener.m_bListen?1:0);
+
// CG: The following block was added by the ToolTips component.
{
// Create the ToolTip control.
m_tooltip.Create(this);
m_tooltip.Activate(TRUE);
m_tooltip.AddTool(&m_List,IDC_CONNECTIONS);
m_tooltip.AddTool(GetDlgItem(IDC_PUT),IDC_PUT);
m_tooltip.AddTool(GetDlgItem(IDC_GET),IDC_GET);
m_tooltip.AddTool(&m_AbortCtl,IDC_ABORT);
m_tooltip.AddTool(GetDlgItem(IDC_OPTIONS),IDC_OPTIONS);
m_tooltip.AddTool(GetDlgItem(IDC_EXIT),IDC_EXIT);
@@ -315,29 +335,28 @@ void CPumpKINDlg::OnPaint()
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CPumpKINDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
int CPumpKINDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
- m_Listener.m_Daddy=this;
- if(!m_Listener.Create(m_ListenPort,SOCK_DGRAM)){
+ if(!m_Listener.SetListen(m_bListen)) {
+ m_bListen=FALSE;
TRACE0("Failed to create socket\n");
AfxMessageBox(IDS_BOX_CANTBIND,MB_OK|MB_ICONEXCLAMATION);
- return -1;
}
if(!m_Trayer->Create(NULL,"PumpKIN TrayIcon",WS_CHILD,CRect(0,0,0,0),this,0)){
TRACE0("Failed to create trayer\n");
return -1;
}
NOTIFYICONDATA nid;
memset(&nid,0,sizeof(nid));
nid.cbSize=sizeof(nid);
nid.hWnd=m_Trayer->m_hWnd;
nid.uID=IDC_TRAYICON;
@@ -655,35 +674,40 @@ CXferSocket::CXferSocket(CPumpKINDlg *daddy,LPCTSTR fileName,LPCTSTR type,SOCKAD
}
BOOL CRRQSocket::Create(LPCTSTR localFile,LPCTSTR hostName)
{
if(!CAsyncSocket::Create(0,SOCK_DGRAM))
return FALSE;
ASSERT(m_Daddy);
ASSERT(m_Peer.sin_addr.s_addr!=INADDR_NONE || hostName);
m_Daddy->m_Xfers[m_hSocket]=this;
CString lFile = localFile?localFile:m_FileName;
TurnSlashes(lFile,TRUE);
UpdateList();
- if(!localFile){ // Check only if server
+ if(!localFile){ // Check only for incoming requests
if(CheckBadRelativeness(m_FileName)){
Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
return TRUE;
}
- switch(m_Daddy->m_RRQMode){
+ int atar=m_Daddy->m_aclRules.FindTarget(acl_rule::opRRQ,m_Peer.sin_addr.s_addr);
+ if(atar<0)
+ atar = m_Daddy->m_RRQMode;
+ switch(atar){
case CPumpKINDlg::rrqGiveAll:
break;
case CPumpKINDlg::rrqAlwaysConfirm:
if(ConfirmRequest())
break;
+ default:
+ TRACE1("Unexpected access target: %d\n",atar);
case CPumpKINDlg::rrqDenyAll:
Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
return TRUE;
}
}
CString fn = localFile?ApplyRootGently(lFile):ApplyRoot(lFile);
CFileException e;
if(!m_File.Open(fn,CFile::modeRead|CFile::shareDenyWrite,&e)){
if(localFile){
CString tmp;
tmp.Format(IDS_LOG_FAILEDLOCALFILE,fn);
m_Daddy->LogLine(tmp);
@@ -1098,25 +1122,25 @@ void CXferSocket::Destroy(BOOL success)
m_Daddy->KillTimer(m_hSocket);
m_Daddy->m_Xfers.RemoveKey(m_hSocket);
LV_FINDINFO lvf;
memset(&lvf,0,sizeof(lvf));
lvf.flags=LVFI_PARAM;
lvf.lParam=(LPARAM)this;
int i = m_Daddy->m_List.FindItem(&lvf);
if(i>=0)
m_Daddy->m_List.DeleteItem(i);
delete this;
}
-void CPumpKINDlg::LogLine(LPCTSTR str)
+void CPumpKINDlg::LogLineToScreen(LPCTSTR str)
{
ASSERT(m_LogLength);
while(m_Log.GetCount()>m_LogLength && m_Log.GetCount()!=LB_ERR){
CTime *t = (CTime*)m_Log.GetItemData(0);
if(((DWORD)t)!=LB_ERR){
ASSERT(t);
m_LogTimes.RemoveKey(t);
delete t;
}
m_Log.DeleteString(0);
}
int i = m_Log.AddString(str);
@@ -1154,58 +1178,68 @@ CString rv = m_Daddy->m_TFTPRoot;
while((!fn.IsEmpty()) && fn[0]=='\\')
fn=fn.Mid(1);
rv+=fn;
return rv;
}
void CPumpKINDlg::OnOptions()
{
CPropertySheet cps(IDS_TITLE_OPTIONS,this);
CPropsServer server;
CPropsNetwork network;
CPropsSounds sounds;
+CPropsACL acl;
server.m_RRQMode=m_RRQMode;
server.m_TFTPRoot=m_TFTPRoot;
server.m_TFTPSubdirs=m_bTFTPSubdirs;
server.m_WRQMode=m_WRQMode;
server.m_PromptTimeOut=m_PromptTimeOut;
+ server.m_LogFile=m_LogFile;
network.m_ListenPort=m_ListenPort;
network.m_SpeakPort=m_SpeakPort;
network.m_TimeOut=m_TFTPTimeOut.GetTotalSeconds();
network.m_BlockSize=m_BlockSize;
sounds.m_Request = m_bnwRequest;
sounds.m_Success = m_bnwSuccess;
sounds.m_Abort = m_bnwAbort;
+ acl.m_rulist = m_aclRules;
+
cps.AddPage(&server);
cps.AddPage(&network);
cps.AddPage(&sounds);
+ cps.AddPage(&acl);
if(cps.DoModal()==IDOK){
m_RRQMode=server.m_RRQMode;
m_TFTPRoot=server.m_TFTPRoot;
m_bTFTPSubdirs=server.m_TFTPSubdirs;
m_WRQMode=server.m_WRQMode;
m_PromptTimeOut=server.m_PromptTimeOut;
+ m_LogFile=server.m_LogFile;
m_ListenPort=network.m_ListenPort;
m_SpeakPort=network.m_SpeakPort;
m_TFTPTimeOut=CTimeSpan(network.m_TimeOut);
m_BlockSize=network.m_BlockSize;
m_bnwRequest = sounds.m_Request;
m_bnwSuccess = sounds.m_Success;
m_bnwAbort = sounds.m_Abort;
+
+ m_aclRules = acl.m_rulist;
+
+ m_lastlogerr.Empty();
}
}
BOOL CRRQSocket::ConfirmRequest()
{
CConfirmRRQDlg cd(NULL);
cd.m_Daddy=this;
cd.m_File=m_FileName;
cd.m_Host=inet_ntoa(m_Peer.sin_addr);
if(cd.DoModal()==IDOK)
return TRUE;
return FALSE;
@@ -1235,48 +1269,52 @@ CString lf;
}
CString fn = localFile?ApplyRootGently(localFile):ApplyRoot(lf);
if(!localFile){ // This is an incoming request..
if(CheckBadRelativeness(m_FileName)){
Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
return TRUE;
}
BOOL exists;
if(!_access((LPCTSTR)fn,0))
m_Rename=exists=TRUE;
else
m_Rename=exists=FALSE;
- // *** m_WRQMode only if server transfer
- switch(m_Daddy->m_WRQMode){
+ int atar=m_Daddy->m_aclRules.FindTarget(acl_rule::opWRQ,m_Peer.sin_addr.s_addr);
+ if(atar<0)
+ atar=m_Daddy->m_WRQMode;
+ switch(atar){
case CPumpKINDlg::wrqTakeAll:
if(exists){
if(!RenameFile(fn)){
Deny(tftp::errDiskFull,IDS_TFTP_ERROR_FAILEDTORENAME);
return TRUE;
}
}
break;
case CPumpKINDlg::wrqConfirmIfExists:
if(!exists)
break;
case CPumpKINDlg::wrqAlwaysConfirm:
if(exists)
m_bResume=TRUE;
if(ConfirmRequest()){
if(m_Rename){
RenameFile(fn);
if(SaveAs(fn))
break;
}else
break;
}
+ default:
+ TRACE1("Unexpected access target: %d\n",atar);
case CPumpKINDlg::wrqDenyAll:
Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
return TRUE;
}
}
CFileException e;
if(!m_File.Open(
fn,
m_bResume
?(CFile::modeWrite|CFile::shareDenyWrite)
:(CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite),
&e
@@ -1786,66 +1824,72 @@ void CPumpKINDlg::OnTrayOptions()
OnOptions();
}
void CPumpKINDlg::OnTraySendfile()
{
OnPut();
}
void CPumpKINDlg::LoadSettings()
{
CWinApp *app = AfxGetApp();
ASSERT(app);
+ m_bListen=app->GetProfileInt("TFTPSettings","Listen",m_bListen);
m_bnwRequest=app->GetProfileString("BellsNWhistles","Request",m_bnwRequest);
m_bnwSuccess=app->GetProfileString("BellsNWhistles","Success",m_bnwSuccess);
m_bnwAbort=app->GetProfileString("BellsNWhistles","Abort",m_bnwAbort);
m_bTFTPSubdirs=app->GetProfileInt("TFTPSettings","Subdirs",m_bTFTPSubdirs);
m_ListenPort=app->GetProfileInt("TFTPSettings","ListenPort",m_ListenPort);
m_LogLength=app->GetProfileInt("UISettings","LogLength",m_LogLength);
m_PromptTimeOut=app->GetProfileInt("UISettings","PromptTimeout",m_PromptTimeOut);
m_RRQMode=app->GetProfileInt("TFTPSettings","RRQMode",m_RRQMode);
m_SpeakPort=app->GetProfileInt("TFTPSettings","SpeakPort",m_SpeakPort);
m_TFTPRoot=app->GetProfileString("TFTPSettings","TFTPRoot",m_TFTPRoot);
+ m_LogFile=app->GetProfileString("General","LogFile",m_LogFile);
m_TFTPTimeOut=CTimeSpan(app->GetProfileInt("TFTPSettings","TFTPTimeout",m_TFTPTimeOut.GetTotalSeconds()));
m_BlockSize=app->GetProfileInt("TFTPSettings","TFTPBlockSize",m_BlockSize);
m_RetryTimeOut=CTimeSpan(app->GetProfileInt("TFTPSettings","RetryTimeout",m_RetryTimeOut.GetTotalSeconds()));
m_WRQMode=app->GetProfileInt("TFTPSettings","WRQMode",m_WRQMode);
m_bShown=app->GetProfileInt("UISettings","Visble",m_bShown);
if(m_TFTPRoot.IsEmpty()){
DWORD dL = ::GetCurrentDirectory(0,NULL);
VERIFY(::GetCurrentDirectory(dL,m_TFTPRoot.GetBuffer(dL)));
m_TFTPRoot.ReleaseBuffer();
}
::SetCurrentDirectory(m_TFTPRoot);
+ m_aclRules.LoadProfile(app);
}
void CPumpKINDlg::SaveSettings()
{
CWinApp *app = AfxGetApp();
ASSERT(app);
+ app->WriteProfileInt("TFTPSettings","Listen",m_bListen);
app->WriteProfileString("BellsNWhistles","Request",m_bnwRequest);
app->WriteProfileString("BellsNWhistles","Success",m_bnwSuccess);
app->WriteProfileString("BellsNWhistles","Abort",m_bnwAbort);
app->WriteProfileInt("TFTPSettings","Subdirs",m_bTFTPSubdirs);
app->WriteProfileInt("TFTPSettings","ListenPort",m_ListenPort);
app->WriteProfileInt("UISettings","LogLength",m_LogLength);
app->WriteProfileInt("UISettings","PromptTimeout",m_PromptTimeOut);
app->WriteProfileInt("TFTPSettings","RRQMode",m_RRQMode);
app->WriteProfileInt("TFTPSettings","SpeakPort",m_SpeakPort);
app->WriteProfileString("TFTPSettings","TFTPRoot",m_TFTPRoot);
+ app->WriteProfileString("General","LogFile",m_LogFile);
app->WriteProfileInt("TFTPSettings","TFTPTimeout",m_TFTPTimeOut.GetTotalSeconds());
app->WriteProfileInt("TFTPSettings","TFTPBlockSize",m_BlockSize);
app->WriteProfileInt("TFTPSettings","RetryTimeout",m_RetryTimeOut.GetTotalSeconds());
app->WriteProfileInt("TFTPSettings","WRQMode",m_WRQMode);
app->WriteProfileInt("UISettings","Visble",m_bShown);
+ m_aclRules.SaveProfile(app);
}
void CPumpKINDlg::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
CDialog::OnWindowPosChanging(lpwndpos);
if(!m_bExiting){
if(m_bShown){
lpwndpos->flags&=~SWP_HIDEWINDOW;
lpwndpos->flags|=SWP_SHOWWINDOW;
}else{
lpwndpos->flags&=~SWP_SHOWWINDOW;
lpwndpos->flags|=SWP_HIDEWINDOW;
@@ -1975,12 +2019,61 @@ tftp* rv = Allocate(src->length);
void CXferSocket::SetTry(tftp *p)
{
if(m_Retry)
delete m_Retry;
m_Retry=p?tftp::Copy(p):NULL;
}
void CPumpKINDlg::OnHelp()
{
AfxGetApp()->WinHelp(0,HELP_FINDER);
}
+
+BOOL CListenSocket::SetListen(BOOL b) {
+ ASSERT(m_Daddy);
+ if(b==m_bListen)
+ return TRUE;
+ if(b) {
+ if(!Create(m_Daddy->m_ListenPort,SOCK_DGRAM))
+ return FALSE;
+ return m_bListen=TRUE;
+ }else{
+ Close(); m_bListen=FALSE;
+ return TRUE;
+ }
+}
+
+void CPumpKINDlg::OnListening()
+{
+ if(!m_Listener.SetListen(m_ListenCtl.GetCheck()==1)) {
+ TRACE0("Failed to create socket\n");
+ AfxMessageBox(IDS_BOX_CANTBIND,MB_OK|MB_ICONEXCLAMATION);
+ }
+ m_ListenCtl.SetCheck(m_Listener.m_bListen?1:0);
+ m_bListen=m_Listener.m_bListen;
+}
+
+void CPumpKINDlg::OnTrayListen()
+{
+ if(!m_Listener.SetListen(!m_Listener.m_bListen)) {
+ TRACE0("Failed to create socket\n");
+ AfxMessageBox(IDS_BOX_CANTBIND,MB_OK|MB_ICONEXCLAMATION);
+ }
+ m_ListenCtl.SetCheck(m_Listener.m_bListen?1:0);
+ m_bListen=m_Listener.m_bListen;
+}
+
+void CPumpKINDlg::LogLine(LPCTSTR str)
+{
+ LogLineToScreen(str);
+ if(!m_LogFile.IsEmpty()) {
+ if(!Klever::LogRecord((LPCTSTR)m_LogFile,str)) {
+ if(m_lastlogerr!=m_LogFile) {
+ CString tmp;
+ tmp.Format(IDS_LOG_LOGERROR,m_LogFile);
+ LogLineToScreen(tmp);
+ m_lastlogerr=m_LogFile;
+ }
+ }
+ }
+}