📄 view.cpp
字号:
BOOL bCancel = FALSE;
int nRet, nLen;
char *str;
if( m_bWaitingForTimeout ) // may be a big file
{
KillTimer(ID_MYTIMEOUT);
m_bWaitingForTimeout = FALSE;
}
ASSERT( m_pXferFilePointer==NULL );
ASSERT( m_sIncomingFilePath.GetLength() );
m_pXferFilePointer = fopen( (const char *)m_sIncomingFilePath, "r" );
if( m_pXferFilePointer )
{
fclose( m_pXferFilePointer );
sOut.Format( "File %s\nalready exists.\n\nOverwrite?", m_sIncomingFilePath);
if( AfxMessageBox( sOut, MB_YESNO ) != IDYES )
{
bCancel = TRUE;
}
}
if( bCancel )
{
BurnIncomingData();
}
else if( !bCancel && !m_nRadioASCII )
{
// a binary store to disk
ASSERT( m_sIncomingFilePath.GetLength() );
m_pXferFilePointer = fopen( (const char *)m_sIncomingFilePath, "wb" );
if( m_pXferFilePointer )
{
do
{
nRet = recv( m_sktData, m_szDataBuffer, BUFSIZE, 0 );
if( nRet != SOCKET_ERROR && nRet > 0 )
{
fwrite( (char *)m_szDataBuffer, sizeof( char ), nRet, m_pXferFilePointer );
}
} while( nRet != SOCKET_ERROR && nRet > 0 );
fclose(m_pXferFilePointer);
}
else
{
sOut.Format( "Specifed path\n%s\nis invalid", m_sIncomingFilePath );
AfxMessageBox( sOut );
BurnIncomingData();
}
}
else if( !bCancel && m_nRadioASCII )
{
// an ASCII store to disk
ASSERT( m_sIncomingFilePath.GetLength() );
m_pXferFilePointer = fopen( (const char *)m_sIncomingFilePath, "w" );
if( m_pXferFilePointer )
{
do
{
memset(m_szDataBuffer,0,BUFSIZE+2);
// this memset trick avoids having strtok insert a wild \0 somewhere bad
// it is guaranteed to find a \n (the delimiter in this case) before
// running off into other memory
memset(m_szDataBuffer+BUFSIZE, '\n', 1);
nRet = recv( m_sktData, m_szDataBuffer, BUFSIZE, 0 );
if( nRet != SOCKET_ERROR && nRet > 0 )
{
str=strtok(m_szDataBuffer,"\n");
while( str && *str)
{
char temp[BUFSIZE+1];
strcpy( temp, str);
nLen = strlen(str);
if( nLen > 0 )
{
if( *( str + nLen - 1 ) == 0x0d) // remove the 0x0d aka \r
{
*( str + nLen - 1 ) = 0;
fprintf( m_pXferFilePointer, "%s\n", str );
}
else
{
fprintf( m_pXferFilePointer, "%s", str );
}
}
str=strtok((char *)NULL,"\n");
}
}
} while( nRet != SOCKET_ERROR && nRet > 0 );
fclose(m_pXferFilePointer);
}
else
{
sOut.Format( "Specifed path\n%s\nis invalid", m_sIncomingFilePath );
AfxMessageBox( sOut );
BurnIncomingData();
}
} // end of else if on !bCancel && m_nRadioASCII
// always clean up the same way
m_bFileHasBeenReceived = TRUE;
m_bReceivingFile = FALSE;
TRACE("setting m_bReceivingFile to FALSE\n");
m_pXferFilePointer = NULL;
}
/////////////////////////////////////////////////////////////////////////////
// a helper for failures on DATA socket READ case
void CMiniFTPView::BurnIncomingData(void)
{
int nRet;
do
{
nRet = recv( m_sktData, m_szDataBuffer, BUFSIZE, 0 );
} while( nRet != SOCKET_ERROR && nRet > 0 );
}
/////////////////////////////////////////////////////////////////////////////
void CMiniFTPView::OnConnect()
{
MakeSafeState( TRUE ); // double check that everything is safe
CConnectDlg dlg;
dlg.m_sHost = AfxGetApp()->GetProfileString("Connect", "Host", "");
dlg.m_sName = AfxGetApp()->GetProfileString("Connect", "Name", "");
dlg.m_sPassword = AfxGetApp()->GetProfileString("Connect", "Password", "");
dlg.m_uTimeout = AfxGetApp()->GetProfileInt("Connect", "Timeout", 30);
// run dialog
if( dlg.DoModal() == IDOK)
{
// housecleaning?
if( dlg.m_bClearWindow )
{
GetEditCtrl().SetWindowText("");
}
// make the connection
BeginWaitCursor(); // show hourglass
m_sktControl = ConnectOrBind( FALSE, (const char *)dlg.m_sHost, "21" );
EndWaitCursor(); // kill hourglass
if( SOCKET_ERROR != m_sktControl && INVALID_SOCKET != m_sktControl )
{
WSAAsyncSelect ( m_sktControl, AfxGetMainWnd()->m_hWnd,
WM_WINSOCK_EVENT_FRAME_CONTROL,
FD_WRITE|FD_READ|FD_CLOSE/*|FD_ACCEPT*/);
int nChars=GetWindowTextLength(); // get the index of the last line
if( nChars != 0 )
{
Log("\r\n"); // only do if not the first line in the CEdit
}
CString sOut;
sOut.Format("MiniFTP Status>Control Connection made OK (socket %d)\r\n\r\n",
m_sktControl );
Log(sOut);
// save settings in ini file
AfxGetApp()->WriteProfileString("Connect", "Host", dlg.m_sHost);
AfxGetApp()->WriteProfileString("Connect", "Name", dlg.m_sName);
AfxGetApp()->WriteProfileString("Connect", "Password", dlg.m_sPassword);
AfxGetApp()->WriteProfileInt("Connect", "Timeout", dlg.m_uTimeout);
m_uTimeout = dlg.m_uTimeout; // save for state machine
// need to logon
// form command list
// send name
sOut = "USER ";
sOut += dlg.m_sName;
m_sCommandList.AddTail(sOut);
// send password
sOut = "PASS ";
sOut += dlg.m_sPassword;
m_sCommandList.AddTail(sOut);
// kick off the state machine
// THIS IS WHERE THIS APP REALLY STARTS
ASSERT( !m_bTimerOn );
SetTimer(ID_MYTIMER, REPTIME, NULL);
m_bTimerOn = TRUE;
}
else
{
CString sOut, sMoreout;
sOut.Format("Connection error code %d", m_sktControl);
sMoreout = "";
switch (m_sktControl) // which error?
{
case SOCKET_ERROR:
sMoreout = " (SOCKET_ERROR or INVALID_SOCKET)";
break;
/* case INVALID_SOCKET:
sMoreout = " (INVALID_SOCKET)";
break; */
} // end of switch
sOut += sMoreout;
AfxMessageBox(sOut);
}
} // end of if on domodal
// defeat the final "save document" dialog on app exit
GetDocument()->SetModifiedFlag(FALSE);
}
/////////////////////////////////////////////////////////////////////////////
// use this function to connect to a host on a port
BOOL CMiniFTPView::UserCommand(CString sCommand)
{
BOOL bRet = FALSE;
if( sCommand.GetLength() == 0 )
{
bRet = TRUE;
return bRet;
}
if( m_sktListen != INVALID_SOCKET )
{
closesocket(m_sktListen);
}
m_sktListen = INVALID_SOCKET;
CString sOut;
m_sktListen = ConnectOrBind( TRUE, "0", "0");
if( m_sktListen == INVALID_SOCKET )
{
Log("\r\nMiniFTP Status>Could not form Listen socket");
::MessageBeep(MB_OK);
bRet = TRUE;
return bRet;
}
else
{
WSAAsyncSelect ( m_sktListen, AfxGetMainWnd()->m_hWnd,
WM_WINSOCK_EVENT_FRAME_LISTEN,
/*FD_WRITE|FD_READ|*/FD_CLOSE|FD_ACCEPT);
sOut.Format("\r\nMiniFTP Status>Listen Connection made OK (socket %d)\r\n\r\n",
m_sktListen );
Log(sOut);
// set the socket to listen
listen( m_sktListen, 3 );
// inform remote end about our port that we created.
// get the port name that we got for later transmission in PORT cmd
struct sockaddr_in saCtrlAddr;
int iLength=sizeof(saCtrlAddr);
getsockname(m_sktListen,(struct sockaddr *)&saCtrlAddr,&iLength);
struct sockaddr_in saTmpAddr;
iLength = sizeof (saTmpAddr);
if (getsockname(m_sktControl,(LPSOCKADDR)&saTmpAddr, &iLength)
==SOCKET_ERROR)
{
AfxMessageBox("getsockname problem");
}
char *a,*p;
a = (char *)&saTmpAddr.sin_addr;
p = (char *)&saCtrlAddr.sin_port;
#define UC(b) (((int)b)&0xff)
CString sPort= "PORT ";
sPort.Format( "PORT %d,%d,%d,%d,%d,%d",
UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
UC(p[0]), UC(p[1]) );
// put the PORT command on the meesage list
m_sCommandList.AddTail(sPort);
// what else to add to list ?
CString sTemp = sCommand;
sTemp = sTemp.Left(4);
sTemp.MakeUpper();
if( sTemp == "RETR" || sTemp == "STOR" )
{
if(sTemp == "RETR")
{
m_bReceivingFile = TRUE;
m_bFileHasBeenReceived = FALSE;
sTemp = sCommand;
sTemp = sTemp.Right( sTemp.GetLength() - 5);
sTemp.TrimRight();
sTemp.TrimLeft();
m_sIncomingFilePath = m_sIncomingPath;
m_sIncomingFilePath += "\\";
m_sIncomingFilePath += sTemp;
}
if(sTemp == "STOR")
{
m_bSendingFile = TRUE;
m_bFileHasBeenSent = FALSE;
sTemp = sCommand;
sTemp = sTemp.Right( sTemp.GetLength() - 5);
sTemp.TrimRight();
sTemp.TrimLeft();
m_sStoringFilePath = sTemp; // save it so the event handler can reference
}
sTemp = "TYPE ";
if( m_nRadioASCII )
{
sTemp += "A";
}
else
{
sTemp += "I";
}
m_sCommandList.AddTail(sTemp);
}
// finally put on the list what the user actaully wanted
m_sCommandList.AddTail(sCommand);
// start the state machine
ASSERT( !m_bTimerOn );
SetTimer(ID_MYTIMER, REPTIME, NULL);
m_bTimerOn = TRUE;
return bRet;
} // end of else on m_sktListen
}
/////////////////////////////////////////////////////////////////////////////
// use this function to connect to a host on a port
// return 0 if OK
BOOL CMiniFTPView::DoCommand(CString s)
{
BOOL bRet = FALSE;
if( m_sktControl != INVALID_SOCKET )
{
send( m_sktControl, (const char *)s, s.GetLength(), 0);
CString sTemp;
sTemp = s;
sTemp.MakeUpper();
sTemp = sTemp.Left(4);
if( sTemp == "PASS" )
{
Log( "PASS (hidden)");
}
else
{
Log(s);
}
CString sCRLF = "\r\n";
send( m_sktControl, (const char *)sCRLF, sCRLF.GetLength(), 0);
Log(sCRLF);
}
else
{
bRet = TRUE;
}
return( bRet );
}
/////////////////////////////////////////////////////////////////////////////
// use this function to connect or bind to a host on a port
// pass bBind TRUE to do a bind() i.e. Listen
// pass bBind FALSE to do a connect()
SOCKET CMiniFTPView::ConnectOrBind(BOOL bBind, const char *name, const char *port)
{
SOCKET s = INVALID_SOCKET;
struct sockaddr_in far server;
struct hostent far *hp;
char msg[100];
int portnum = atoi(port);
while( *name != 0 && *name == ' ' )
{
name++;
}
/*if( *name == 0 || portnum == 0)
{
return INVALID_SOCKET;
}*/ // this is not a good test in the Listen/Bind case
if( (name[0] >= '0') && (name[0] <= '9') )
{
memset((char *) &server,0,sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(name);
server.sin_port = htons(portnum);
}
else
{
if ( (hp = (hostent far *) gethostbyname(name)) == NULL)
{
sprintf(msg,"Error: Connecting to %s.", name);
if(AfxMessageBox( msg ) == IDOK)
{
return INVALID_SOCKET;
}
}
memset( (char *) &server, 0, sizeof(server));
memcpy( (char *) &server.sin_addr, hp->h_addr, hp->h_length );
server.sin_family = hp->h_addrtype;
server.sin_port = htons( portnum );
}// end of else
// create socket
if( (s = socket(AF_INET, SOCK_STREAM, 0)) < 1)
{
sprintf( msg,"Error opening stream socket" );
if(AfxMessageBox( msg ) == IDOK)
{
return INVALID_SOCKET;
}
}
if( !bBind ) // do connect to server
{
if (connect( s, (struct sockaddr far *)&server, sizeof(server))< 0 )
{
sprintf( msg,"Cannot connect to %s on port %s",name,port);
if(AfxMessageBox( msg ) == IDOK)
{
return INVALID_SOCKET;
}
}
}
else // do a bind so we listen
{
if (bind(s, (struct sockaddr far *)&server, sizeof(server))< 0)
{
sprintf(msg,"Cannot bind to %s on port %s",name,port);
if(AfxMessageBox( msg ) == IDOK)
{
return INVALID_SOCKET;
}
}
}
setsockopt( s, SOL_SOCKET, SO_LINGER, 0, 0 );
setsockopt( s, SOL_SOCKET, SO_REUSEADDR, 0, 0 );
setsockopt( s, SOL_SOCKET, SO_KEEPALIVE, 0, 0 );
return s;
}
/////////////////////////////////////////////////////////////////////////////
void CMiniFTPView::OnFsettings()
{
CXport dlg;
dlg.m_nRadioASCII = m_nRadioASCII; // was initialized in constructor
dlg.m_sIncomingPath = m_sIncomingPath; // was initialized in constructor
if( dlg.DoModal() == IDOK)
{
// save settings in ini file
AfxGetApp()->WriteProfileInt("Setting", "ASCII", dlg.m_nRadioASCII );
AfxGetApp()->WriteProfileString("Setting", "Name", dlg.m_sIncomingPath);
m_nRadioASCII = dlg.m_nRadioASCII;
m_sIncomingPath = dlg.m_sIncomingPath;
}
}
/////////////////////////////////////////////////////////////////////////////
void CMiniFTPView::OnCloseconn()
{
MakeSafeState(TRUE);
Log("\r\nMiniFTP Status>Connection closed by client\r\n\r\n");
}
/////////////////////////////////////////////////////////////////////////////
void CMiniFTPView::OnClearview()
{
// clear the user input edit box
GetEditCtrl().SetWindowText("");
}
/////////////////////////////////////////////////////////////////////////////
void CMiniFTPView::OnUpdateCloseconn(CCmdUI* pCmdUI)
{
if( m_sktControl != INVALID_SOCKET )
{
pCmdUI->Enable(1 );
}
else
{
pCmdUI->Enable(0);
}
}
////////////////////////////////////////////////////////////////////////////
void CMiniFTPView::OnUpdateConnect(CCmdUI* pCmdUI)
{
if( m_sktControl == INVALID_SOCKET )
{
pCmdUI->Enable(1 );
}
else
{
pCmdUI->Enable(0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -