?? mailbox.cpp
字號:
{
m_tServerSupportsAPOP = false;
Check();
}
else
{
SetState( IDP_MBOX_CONNECTION_WAS_LOST );
}
return;
}
case SOCKET_ERROR:
{
DWORD dwLastError = GetLastError();
if( WSAEWOULDBLOCK != dwLastError )
{
if( WSAECONNABORTED == dwLastError ||
WSAECONNRESET == dwLastError )
{
if( m_intState == MBOX_WF_APOP_RESPONSE )
{
m_tServerSupportsAPOP = false;
Check();
}
else
{
SetState( MBOX_CONNECTION_WAS_LOST );
}
}
else
{
TRACE2( "Socket Error #%d; [%s] cannot receive\n", GetLastError(), m_strAlias );
SetState( MBOX_SOCKET_ERROR );
}
}
return;
}
default:
{
// TRACE2( "[+%d bytes]->[%d bytes]\n", nErrorCode, m_arrayPacket.GetSize()+nErrorCode );
ASSERT( nErrorCode <= sizeof( szPacket ) );
m_arrayPacket.SetSize( m_arrayPacket.GetSize() + nErrorCode );
memcpy( &m_arrayPacket[ m_arrayPacket.GetSize() - nErrorCode ], szPacket, nErrorCode );
if( nErrorCode < sizeof( szPacket ) )
{
while( m_arrayPacket.GetSize() )
{
int i = 1;
while( i < m_arrayPacket.GetSize() &&
'\x0D' != m_arrayPacket[i-1] &&
'\x0A' != m_arrayPacket[i] ) ++i;
int intStringLength = i - 1;
if( i == m_arrayPacket.GetSize() ) break;
int intBufferLength = i + 1;
AppendToLog( "Rcvd: " );
CString sLog((char*) &m_arrayPacket[0], intBufferLength );
AppendToLog( sLog );
static int nTraceLog = 0;
if (nTraceLog)
TRACE(sLog);
// skip any extra returns at the beginning
int nSkip = 0;
while (nSkip<intStringLength &&
(m_arrayPacket[nSkip] == 0x0A || m_arrayPacket[nSkip] == 0x0D))
nSkip++;
if (nSkip == intStringLength)
nSkip = 0;
ParseString( (char*) &m_arrayPacket[0] + nSkip, intStringLength-nSkip, intBufferLength-nSkip );
if( m_arrayPacket.GetSize() ) m_arrayPacket.RemoveAt( 0, intBufferLength );
} // while
} // if
if( INVALID_SOCKET == m_hSocket ) return;
} // default
} // switch receive
} // while
}
void CMailbox::ParseString( char *str, int len, int size )
{
char szPacket[ 1024 ];
CString strPacket;
switch( m_intState )
{
case MBOX_CONNECTING:
{
// null-terminate
str[ len ] = 0;
char *stamp_begin = (char*) memchr( str, '<', size );
char *stamp_end = (char*) memchr( str, '>', size );
m_sServerGreeting = CString( str + 3, len - 3 );
m_sServerGreeting.TrimLeft();
m_sServerGreeting.TrimRight();
#if 1
if ( ((m_dwFlags & MBF_NO_APOP) == 0) && m_tServerSupportsAPOP &&
( stamp_begin ) &&
( stamp_end ) &&
( stamp_begin < stamp_end ) )
{
/* APOP command is supported - use secure method */
*(++stamp_end) = 0;
CString sPass = GetPassword();
char *pass = new char[ sPass.GetLength() + 1 ];
strcpy(pass, sPass);
char *string = new char[ strlen( stamp_begin ) + strlen( pass ) + 1 ];
sprintf( string, "%s%s", stamp_begin, pass );
unsigned char digest[16];
MD5String( string, digest );
strPacket.Format( _T("APOP %s "), m_strUser );
strcpy( szPacket, strPacket);
for( int i = 0; i < sizeof( digest ); ++i )
{
char hex[3];
sprintf( hex, "%02x", digest[i] );
strcat( szPacket, hex );
}
strcat( szPacket, "\r\n" );
delete pass;
delete string;
SetState( Send( szPacket, strlen( szPacket ) ) ?
MBOX_WF_APOP_RESPONSE : MBOX_CANNOT_SEND );
}
else
#endif
{
/* APOP command is NOT supported - use plain text method */
strPacket.Format( _T("USER %s\r\n"), m_strUser );
CharToOem( strPacket, szPacket );
SetState( Send( szPacket, strlen( szPacket ) ) ?
MBOX_WF_USER_RESPONSE : MBOX_CANNOT_SEND );
m_tServerSupportsAPOP = false;
}
}
break;
case MBOX_WF_APOP_RESPONSE:
{
m_strLastError.Empty();
if( '-' == *str )
{
// note, this piece is duplicated:
{
/* APOP command is NOT supported - use plain text method */
strPacket.Format( _T("USER %s\r\n"), m_strUser );
CharToOem( strPacket, szPacket );
SetState( Send( szPacket, strlen( szPacket ) ) ?
MBOX_WF_USER_RESPONSE : MBOX_CANNOT_SEND );
m_tServerSupportsAPOP = false;
}
}
else
{
m_tServerSupportsAPOP = true;
SendBurstWriteSenseRequest();
}
}
break;
case MBOX_WF_USER_RESPONSE_SSL:
case MBOX_WF_USER_RESPONSE:
{
if( '-' == *str )
{
if( len > 5 )
{
str[ len ] = 0;
m_strLastError = "error: ";
m_strLastError += str + 5;
m_strLastError.MakeLower();
m_strLastError.Replace( '.', ' ' );
}
SendQuitRequest( MBOX_INVALID_USER );
}
else
{
if (m_intState == MBOX_WF_USER_RESPONSE_SSL)
{
m_intState = MBOX_WF_USER_RESPONSE;
break;
}
CString sPass = GetPassword();
strPacket.Format( _T("PASS %s\r\n"), sPass );
strcpy(szPacket, strPacket);
SetState( Send( szPacket, strlen( szPacket ) ) ?
MBOX_WF_PASS_RESPONSE : MBOX_CANNOT_SEND );
}
}
break;
case MBOX_WF_PASS_RESPONSE:
{
m_strLastError.Empty();
if( '-' == *str )
{
if( len > 5 )
{
str[ len ] = 0;
m_strLastError = "error: ";
m_strLastError += str + 5;
m_strLastError.MakeLower();
m_strLastError.Replace( '.', ' ' );
}
SendQuitRequest( MBOX_INVALID_PASS );
}
else
{
m_tServerSupportsAPOP = false;
SendBurstWriteSenseRequest();
}
}
break;
case MBOX_WF_FIRST_NOOP:
{
CreateWatchDog( 4000 );
SetState( MBOX_WF_SECOND_NOOP );
}
break;
case MBOX_WF_SECOND_NOOP:
{
DestroyWatchDog();
m_tServerSupportsBurstWrites = true;
SendUidlRequest();
}
break;
case MBOX_WF_UIDL_RESPONSE:
{
m_strLastError.Empty();
switch( *str )
{
case '-':
{
m_tServerSupportsUIDL = false;
m_intOrder = 0;
SendTopExRequest();
}
break;
case '.':
{
// brieuc
if (m_dwFlags & MBF_SPEC_TOP)
SendTopFRequest(); // for my FLASH POP server
else
FinishReceivingID();
}
break;
case '+':
{
m_tServerSupportsUIDL = true;
break;
}
default:
{
str[ len ] = 0;
int order = 0;
if( 1 != sscanf( str, "%d", &order ) )
{
SetState( MBOX_SERVER_FAILED );
break;
};
char *id_space = strchr( str, ' ' );
if( id_space == NULL )
{
SetState( MBOX_SERVER_FAILED );
break;
}
OrderAssignedToID( order, id_space + 1 );
}
}
}
break;
case MBOX_WF_TOPEX_RESPONSE:
{
switch( *str )
{
case '-': FinishReceivingID(); break;
case '.': SendTopExRequest(); break;
default:
{
const char msgid[] = "message-id: ";
if( strnicmp( str, msgid, sizeof( msgid )-1 ) ) break;
str[ len ] = 0;
str += sizeof( msgid )-1;
OrderAssignedToID( m_intOrder, str );
}
}
}
break;
case MBOX_WF_TOPF_RESPONSE:
{
switch( *str )
{
case '-':
case '.': FinishReceivingID(); break;
default: { }
}
}
break;
case MBOX_WF_LIST_RESPONSE:
{
switch( *str )
{
case '.':
case '-': SendInitialTopRequest();
case '+': break;
default:
{
str[ len ] = 0;
int order = 0, size = 0;
if( ( 2 != sscanf( str, "%d %d", &order, &size ) ) || !order || !size )
{
SendQuitRequest( MBOX_SERVER_FAILED );
break;
}
for( int i = m_arrayExcerpt.GetSize(); i; --i )
{
// char a[111];
// TRACE( strcat( itoa( m_arrayExcerpt[i-1]->m_intOrder, a, 10 ), "\n" ) );
if( order == m_arrayExcerpt[i-1]->m_intOrder ) break;
}
if( !i )
{
SendQuitRequest( MBOX_SERVER_FAILED );
break;
}
m_arrayExcerpt[--i]->m_intSize = size;
m_arrayExcerpt[i]->Change( COLUMN_SIZE );
}
}
}
break;
case MBOX_WF_TOP_RESPONSE:
{
ASSERT( m_aIndices.GetSize() > 0 );
// BRN
str[ len ] = 0;
if (_tcscmp(str, _T("."))==0)
{
m_arrayExcerpt[ m_aIndices[0] ]->NoMoreTopLines();
m_arrayExcerpt[ m_aIndices[0] ]->m_tmCheckTime = m_tmCheckTime;
m_aIndices.RemoveAt(0);
SendTopRequest();
}
else if (_tcsncmp(str, _T("-ERR"),4)==0)
{
m_aIndices.RemoveAt(0);
SendTopRequest();
}
else if (_tcsncmp(str, _T("+OK"),4)==0)
{
}
else
{
m_arrayExcerpt[ m_aIndices[0] ]->ParseTopLine( str );
}
/* BRN
switch( *str )
{
case '.': m_arrayExcerpt[ m_aIndices[0] ]->NoMoreTopLines();
case '-': m_aIndices.RemoveAt(0);
SendTopRequest();
case '+': break;
default:
{
str[ len ] = 0;
m_arrayExcerpt[ m_aIndices[0] ]->ParseTopLine( str );
}
}
*/
}
break;
case MBOX_WF_RETR_RESPONSE:
{
switch( *str )
{
case '-':
{
SendRetrRequest();
}
break;
case '+':
{
m_arrayExcerpt[ m_aIndices[0] ]->BeginDataDownload();
SetState( MBOX_DOWNLOADING_DATA );
}
break;
default: SetState( MBOX_SERVER_FAILED );
}
}
break;
case MBOX_DOWNLOADING_DATA:
{
BOOL bStopDownload = FALSE;
if( ( *str == '.' ) && ( len == 1 ) )
{
// terminal dot
bStopDownload = TRUE;
}
else
{
if (!m_arrayExcerpt[ m_aIndices[0] ]->WriteBufferToDataFile( str, size ))
bStopDownload = TRUE;
}
if (bStopDownload)
{
m_arrayExcerpt[ m_aIndices[0] ]->EndDataDownload();
m_aIndices.RemoveAt(0);
SetState( MBOX_WF_RETR_RESPONSE );
SendRetrRequest();
}
}
break;
case MBOX_WF_DELE_RESPONSE:
{
switch( *str )
{
case '+': // we know that indices are in descending order,
// so we don't worry about fixing remaining indices in
// array m_aIndices
delete m_arrayExcerpt[ m_aIndices[0] ];
m_arrayExcerpt.RemoveAt( m_aIndices[0] );
case '-': m_aIndices.RemoveAt(0);
Change( COLUMN_MAIL );
SendDeleRequest();
break;
default: SetState( MBOX_SERVER_FAILED );
}
}
}
}
void CMailbox::OrderAssignedToID( int order, const char *str )
{
TCHAR *szID = new TCHAR [ strlen( str ) + 1 ];
OemToChar( str, szID );
// search for this id
for( int i = m_arrayExcerpt.GetSize(); i; --i )
{
if( !m_arrayExcerpt[i-1]->m_strID.Compare( szID ) ||
( m_arrayExcerpt[i-1]->m_intOrder == order ) ) break;
}
if( i && m_arrayExcerpt[i-1]->m_intOrder == 0 ) // excerpt with this id exists
{
m_arrayExcerpt[i-1]->m_intOrder = order;
}
else // create a new one
{
Change( COLUMN_MAIL );
CExcerpt *xrpt = new CExcerpt( this );
xrpt->m_intOrder = order;
xrpt->m_strID = szID;
m_arrayExcerpt.Add( xrpt );
}
delete szID;
}
void CMailbox::FinishReceivingID()
{
int i = m_arrayExcerpt.GetSize();
while( i-- )
{
if( !m_arrayExcerpt[i]->m_intOrder )
{
Change( COLUMN_MAIL );
delete m_arrayExcerpt[i];
m_arrayExcerpt.RemoveAt(i);
}
}
SendListRequest();
}
void CMailbox::SendListRequest()
{
int i = m_arrayExcerpt.GetSize();
while( i-- )
{
if( m_arrayExcerpt[i]->m_intSize == 0 )
{
SetState( Send( "LIST\r\n", 6 ) ?
MBOX_WF_LIST_RESPONSE : MBOX_CANNOT_SEND );
return;
}
}
SendInitialTopRequest();
}
void CMailbox::SendBurstWriteSenseRequest()
{
if( m_tServerSupportsBurstWrites.IsSet() )
{
SendUidlRequest();
}
else
{
SetState( Send( "NOOP\r\nNOOP\r\n", 12 ) ?
MBOX_WF_FIRST_NOOP : MBOX_CANNOT_SEND );
}
}
void CMailbox::SendUidlRequest()
{
for( int i = 0; i < m_arrayExcerpt.GetSize(); ++i )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -