⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mailbox.cpp

📁 一个邮件客户端源代码,包括收发邮件,安排日程等很多内容
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		{
			case 0:
			{
				if( m_intState == MBOX_WF_USER_RESPONSE )
				{
					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;
						
						// skip any extra returns

						while( (i+1) < m_arrayPacket.GetSize() &&
							( '\x0D' == m_arrayPacket[i+1] ||
							  '\x0A' == m_arrayPacket[i+1] ) )
							  i++;

						if( i == m_arrayPacket.GetSize() ) break;

						int intBufferLength = i + 1;

						AppendToLog( "Rcvd: " );
						AppendToLog( CString( (char*) &m_arrayPacket[0], intBufferLength ) );

						ParseString( (char*) &m_arrayPacket[0], intStringLength, intBufferLength );

						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:
		{
			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
			{
				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_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 );
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -