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

📄 pop3_client.c

📁 在freescale 的ne64上开发的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *Copyright (c) 2000-2002 Viola Systems Ltd.
 *All rights reserved.
 *
 *Redistribution and use in source and binary forms, with or without
 *modification, are permitted provided that the following conditions
 *are met:
 *
 *1. Redistributions of source code must retain the above copyright
 *notice, this list of conditions and the following disclaimer.
 *
 *2. Redistributions in binary form must reproduce the above copyright
 *notice, this list of conditions and the following disclaimer in the
 *documentation and/or other materials provided with the distribution.
 *
 *3. The end-user documentation included with the redistribution, if
 *any, must include the following acknowledgment:
 *	"This product includes software developed by Viola
 *	Systems (http://www.violasystems.com/)."
 *
 *Alternately, this acknowledgment may appear in the software itself,
 *if and wherever such third-party acknowledgments normally appear.
 *
 *4. The names "OpenTCP" and "Viola Systems" must not be used to
 *endorse or promote products derived from this software without prior
 *written permission. For written permission, please contact
 *opentcp@opentcp.org.
 *
 *5. Products derived from this software may not be called "OpenTCP",
 *nor may "OpenTCP" appear in their name, without prior written
 *permission of the Viola Systems Ltd.
 *
 *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
 *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *IN NO EVENT SHALL VIOLA SYSTEMS LTD. OR ITS CONTRIBUTORS BE LIABLE
 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 *EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *====================================================================
 *
 *OpenTCP is the unified open source TCP/IP stack available on a series
 *of 8/16-bit microcontrollers, please see <http://www.opentcp.org>.
 *
 *For more information on how to network-enable your devices, or how to
 *obtain commercial technical support for OpenTCP, please see
 *<http://www.violasystems.com/>.
 */

/** \file pop3_client.c
 *	\brief OpenTCP POP3 client implementation
 *	\author
 *		\li Jari Lahti (jari.lahti@violasystems.com)
 *	\version 1.0
 *	\date 20.08.2002
 *	\bug
 *	\warning
 *	\todo
 *
 *	OpenTCP implementation of POP3 client that uses TCP api. For interface
 *	functions declarations see /pop3/pop3_client.h.
 */

#include "debug.h"
#include "datatypes.h"
#include "globalvariables.h"
#include "system.h"
#include "timers.h"
#include "tcp_ip.h"
#ifdef POP3_WANTED
#include "pop3_client.h"


UINT8 pop3c_init_done = 0; /**< Defines whether pop3c_init has already been invoked or not */

/**	\brief	Holds information needed by the POP3 client for successful operation.
 *
 *	All of the information that the POP3 client is using for operation
 *	are stored here. See pop3c_struct definition for more
 *	information about the structure fields.
 */
struct pop3c_struct pop3_client;


/* The applications that use TCP must implement following function stubs			*/
/* void application_name_init (void) - call once when processor starts				*/
/* void application_name_run (void) - call periodically on main loop				*/
/* INT32 application_name_eventlistener (INT8, UINT8, UINT32, UINT32)				*/
/* - called by TCP input process to inform arriving data, errors etc				*/


/* POP3 Client application		*/


/** \brief Start E-mail reading procedure
 * 	\author
 *		\li Jari Lahti (jari.lahti@violasystems.com)
 *	\date 11.09.2002
 *	\param ip IP address of POP3 server from which to read the e-mails
 *	\param port Port on the server
 *	\return
 *		\li -1 - Error
 *		\li >0 - Connection procedure started (OK)
 *
 *	This function is called by user when she wants to start E-mail
 *	reading procedure. The function is responsible of establishing
 *	connection to POP3 server. After connection is established the
 *	POP3 client engine starts to make callbacks to user functions
 *	in order to get username information, data etc.
 */
INT8 pop3c_connect (UINT32 ip, UINT16 port){
	/* Do we have socket	*/

	if( pop3_client.sochandle < 0 ) {
		DEBUGOUT("pop3c_connect() called but no socket\r\n");
		return(-1);
	}

	if( pop3_client.state < POP3C_CLOSED ) {
		DEBUGOUT("pop3c_connect() called but uninitialized\r\n");
		return(-1);
	}

	if( pop3_client.state == POP3C_CLOSED )	{
		DEBUGOUT("POP3 Connection request going to be processed\r\n");
		pop3_client.remip = ip;
		pop3_client.remport = port;
		pop3c_changestate(POP3C_OPEN_REQUESTED);
		return(1);
	}

	return(-1);

}

/** \brief Initialize POP3 client
 * 	\author
 *		\li Jari Lahti (jari.lahti@violasystems.com)
 *	\date 12.08.2002
 *
 *	This function should be called once when system starts.
 *	Make sure that system services e.g. timers, TCP are initialized
 *	before initializing applications!
 */
void pop3c_init (void){

	if(pop3c_init_done) {
		DEBUGOUT("POP3 client already initialized\r\n");
		return;
	}


	/* Get timer handle	*/

	pop3_client.tmrhandle = get_timer();

	/* Get TCP Socket	*/

	pop3_client.sochandle = tcp_getsocket(TCP_TYPE_CLIENT, TCP_TOS_NORMAL, TCP_DEF_TOUT, pop3c_eventlistener);

	if( pop3_client.sochandle < 0 )	{
		DEBUGOUT("pop3c_init() uncapable of getting socket\r\n");
		RESET_SYSTEM();
	}

	pop3c_changestate(POP3C_CLOSED);
	pop3_client.remip = 0;
	pop3_client.remport = 0;
	pop3_client.unacked = 0;
	pop3_client.msgtotal = 0;
	pop3_client.curmsgindex = 0;
	pop3_client.curmsgtotlen = 0;
	pop3_client.curmsghlen = 0;
	pop3_client.headerbuf[0] = '\0';
	pop3_client.charsinheaderbuf = 0;
	pop3_client.from[0] = '\0';
	pop3_client.subject[0] = '\0';

	pop3c_init_done = 0x01;				/* We are initialized now	*/

}
/** \brief Get current POP3 client state
 * 	\author
 *		\li Jari Lahti (jari.lahti@violasystems.com)
 *	\date 10.10.2002
 *	\return Current POP3 client state
 *
 *	Invoke this function to get current state of the POP3 client
 *
 */
UINT8 pop3c_getstate (void){
	return(pop3_client.state);

}

/********************************************************************************
Function:		pop3c_eventlistener

Parameters:		INT8 cbhandle - handle to TCP socket where event is coming from
				UINT8 event - type of event
				UINT32 par1 - parameter the meaning of depends on event
				UINT32 par2 - parameter the meaning of depends on event

Return val:		INT32 - depends on event but usually (-1) is error of some
						kind and positive reply means OK

Date:			21.8.2002

Desc:			This function is given to TCP socket as function pointer to be
				used by TCP engine to make callbacks to inform about events
				on TCP e.g. arriving data. Main functionality of this function
				is to parse data from TCP to detect POP3 server reply commands,
				handling out retransmissions and making state changes
*********************************************************************************/


INT32 pop3c_eventlistener (INT8 cbhandle, UINT8 event, UINT32 par1, UINT32 par2)
{
	/* This function is called by TCP stack to inform about events	*/

	UINT8 cmd;
	UINT16 i;
	static UINT16 len;
	static UINT16 match;
	static UINT8  end_detect;
	UINT8 ch;
	UINT8 j;
	UINT8 endbuf[4];

	par2 = 0;
	j = 0;
	len = 0;
	endbuf[0] = 0;

	if( cbhandle != pop3_client.sochandle)		/* Not our handle	*/
		return(-1);

	switch( event ) {

		case TCP_EVENT_CONREQ:

			/* We don't allow incoming connections	*/

			return(-1);

		case TCP_EVENT_ABORT:

			if(pop3_client.state > POP3C_CLOSED) {
				/* Inform application	*/
				pop3c_error();
			}

			pop3c_changestate(POP3C_CLOSED);
			pop3_client.unacked = 0;

			return(1);

			break;

		case TCP_EVENT_CONNECTED:

			if(pop3_client.state == POP3C_CONNECTIONOPEN_SENT) {
				DEBUGOUT("POP3 TCP connection opened\r\n");
				pop3c_changestate(POP3C_CONNECTION_OPENED);
				pop3_client.unacked = 0;
				return(-1);
			}

			break;

		case TCP_EVENT_CLOSE:

			pop3c_changestate(POP3C_CLOSED);
			pop3_client.unacked = 0;
			return(1);

			break;

		case TCP_EVENT_ACK:

			/* Our message is acked	*/

			pop3_client.unacked = 0;

			break;

		case TCP_EVENT_DATA:

			/* Do we have unacked data?	*/

			if(pop3_client.unacked)
				return(-1);

			/* Get reply from server	*/

			if(par1 < 3)					/* Long enough?	*/
				return(-1);

			/* Get command				*/

			NETWORK_RECEIVE_INITIALIZE(received_tcp_packet.buf_index);
			cmd = RECEIVE_NETWORK_B();
			NETWORK_RECEIVE_INITIALIZE(received_tcp_packet.buf_index);

			switch(pop3_client.state) {

				case POP3C_CONNECTION_OPENED:

					if(cmd == POP3C_OK)	{
						DEBUGOUT("POP3 Server is ready\r\n");
						pop3c_changestate(POP3C_SERVER_READY);
						return(1);
					}

					break;

				case POP3C_USERNAME_SENT:

					if(cmd == POP3C_OK)	{
						DEBUGOUT("USER +OK by POP3 server\r\n");
						pop3c_changestate(POP3C_USERNAME_ACKED);
						return(1);
					}

					break;

				case POP3C_PASSWORD_SENT:

					if(cmd == POP3C_OK) {
						DEBUGOUT("PASS +OK by POP3 server\r\n");
						pop3c_changestate(POP3C_PASSWORD_ACKED);
						return(1);
					}

					break;

				case POP3C_STAT_SENT:

					if(cmd == POP3C_OK)	{
						DEBUGOUT("STAT get from POP3 server\r\n");

						/* Parse number of messages	*/

						NETWORK_RECEIVE_INITIALIZE(received_tcp_packet.buf_index);

						pop3_client.msgtotal = 0;
						pop3_client.curmsgindex = 0;
						pop3_client.curmsgtotlen = 0;
						pop3_client.curmsghlen = 0;
						if( pop3c_parsestat() < 0 )	{
							/* Error parsing STAT reply	*/
							/* Inform application		*/
							pop3c_error();
							(void)tcp_abort(pop3_client.sochandle);
							pop3c_changestate(POP3C_CLOSED);
							pop3_client.unacked = 0;
							return(1);
						}

						/* Inform application about the nmbr of messages	*/
						pop3c_messages(pop3_client.msgtotal);

						pop3c_changestate(POP3C_STAT_GET);
						return(1);
					}

					break;

				case POP3C_LIST_SENT:

					if(cmd == POP3C_OK)	{
						DEBUGOUT("LIST get from POP3 server\r\n");

						/* Parse message total len	*/

						NETWORK_RECEIVE_INITIALIZE(received_tcp_packet.buf_index);

						pop3_client.curmsgtotlen = 0;

						if(pop3c_parselist() < 0) {
							/* Error parsing LIST reply	*/
							/* Inform application		*/
							(void)pop3c_error();
							(void)tcp_abort(pop3_client.sochandle);
							pop3c_changestate(POP3C_CLOSED);
							pop3_client.unacked = 0;
							return(1);

						}


						pop3c_changestate(POP3C_LIST_GET);
						return(1);
					}

					break;

				case POP3C_TOP0_SENT:

					if(cmd == POP3C_OK) {
						DEBUGOUT("TOP x 0 get from POP3 server\r\n");

						/* Continue imediately to receive header	*/
						pop3_client.curmsghlen = 0;
						pop3_client.from[0] = '\0';
						pop3_client.subject[0] = '\0';
						match = 0;

						/* Receive untill LF found	*/

						for(i=0; i<(UINT16)par1; i++)
						{
							ch = RECEIVE_NETWORK_B();

							if(ch == '\n')
							{	i++;
								break;
							}
						}

						par1 = i;


						pop3c_changestate(POP3C_RECEIVING_HEADER);
					}else
						break;

				case POP3C_RECEIVING_HEADER:
				case POP3C_RECEIVING_HDR_FROM:
				case POP3C_RECEIVING_HDR_SUBJ:

					pop3_client.curmsghlen += (UINT16)par1;

					if( pop3_client.curmsghlen > (pop3_client.curmsgtotlen + 100) )	{
						/* Somebody tries to fool us	*/
						/* Move to next msg				*/

						pop3c_changestate(POP3C_MESSAGE_RECEIVED);
						break;

					}

					/* We try to find 'from:', or 'subject:'	*/

					NETWORK_RECEIVE_INITIALIZE(received_tcp_packet.buf_index);

					for( i=0; i<(UINT16)par1; i++) {

						ch = RECEIVE_NETWORK_B();

						if( pop3_client.state == POP3C_RECEIVING_HEADER) {

							if( ch == '\r')	{
								pop3_client.charsinheaderbuf = 0;
								continue;
							}

							if( ch == '\n')	{
								pop3_client.charsinheaderbuf = 0;

⌨️ 快捷键说明

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