www.pudn.com > POP3-C.rar > pop3.c
/* * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * http://www.mozilla.org/NPL/. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is the Netscape Messaging Access SDK Version 3.5 code, * released on or about June 15, 1998. * * The Initial Developer of the Original Code is Netscape Communications * Corporation. Portions created by Netscape are Copyright (C) 1998 Netscape * Communications Corporation. All Rights Reserved. * * Contributor(s): ______________________________________. */ /* * Copyright (c) 1997 and 1998 Netscape Communications Corporation * (http://home.netscape.com/misc/trademarks.html) */ /* * pop3.c * Implementation file for POP3 functionality. * @author derekt@netscape.com * @version 1.0 */ #include "nsmail.h" #include "pop3.h" #include "pop3priv.h" #include "nsio.h" #include#include #include /* Initializes and allocates the pop3Client_t structure and sets the sink. */ int pop3_initialize( pop3Client_t ** out_ppPOP3, pop3Sink_t * in_pPOP3Sink ) { pop3Client_i_t * l_pPOP3; /* Parameter validation. */ if ( out_ppPOP3 == NULL || (*out_ppPOP3) != NULL || in_pPOP3Sink == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } /* Create the client */ l_pPOP3 = (pop3Client_i_t*)malloc( sizeof(pop3Client_i_t) ); if ( l_pPOP3 == NULL ) { return NSMAIL_ERR_OUTOFMEMORY; } /* Set the data members of the client. */ l_pPOP3->timeout = -1; l_pPOP3->chunkSize = 1024; l_pPOP3->pop3Sink = in_pPOP3Sink; l_pPOP3->mustProcess = FALSE; l_pPOP3->pCommandList = NULL; l_pPOP3->messageDataSize = 0; l_pPOP3->messageNumber = 0; l_pPOP3->multiLineState = FALSE; memset(&(l_pPOP3->io), 0, sizeof( IO_t ) ); memset(l_pPOP3->commandBuffer, 0, MAX_COMMANDLINE_LENGTH * sizeof( char ) ); memset(l_pPOP3->responseLine, 0, MAX_TEXTLINE_LENGTH * sizeof( char ) ); l_pPOP3->messageData = (char*)malloc( l_pPOP3->chunkSize * sizeof(char) ); if ( l_pPOP3->messageData == NULL ) { return NSMAIL_ERR_OUTOFMEMORY; } *out_ppPOP3 = l_pPOP3; /* * Initialize the IO structure. */ return IO_initialize( (&l_pPOP3->io), l_pPOP3->chunkSize, MAX_BUFFER_LENGTH ); } /* Function used to free the pop3Client_t structure and it's data members. */ void pop3_free( pop3Client_t ** in_ppPOP3 ) { if ( in_ppPOP3 == NULL || *in_ppPOP3 == NULL ) { return; } /* Free the members of the IO structure. */ IO_free( &((*in_ppPOP3)->io) ); /* Remove all the elements from the linked list. */ RemoveAllElements( &((*in_ppPOP3)->pCommandList) ); /* Free the message data buffer. */ if ( (*in_ppPOP3)->messageData != NULL ) { free( (*in_ppPOP3)->messageData ); } /* Free the client. */ free( (*in_ppPOP3) ); *in_ppPOP3 = NULL; } int pop3_connect( pop3Client_t * in_pPOP3, const char * in_server, unsigned short in_port ) { int l_nReturnCode; if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Reset data members. */ in_pPOP3->messageDataSize = 0; in_pPOP3->multiLineState = FALSE; RemoveAllElements( &(in_pPOP3->pCommandList) ); /* Connect to the server. */ if ( in_port == 0 ) { in_port = DEFAULT_POP3_PORT; } /* Connect to the server. */ l_nReturnCode = IO_connect( &(in_pPOP3->io), in_server, in_port ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_CONN ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_delete( pop3Client_t * in_pPOP3, int in_messageNumber ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_write( &(in_pPOP3->io), dele, strlen(dele) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } sprintf( in_pPOP3->commandBuffer, "%d", in_messageNumber ); l_nReturnCode = IO_send( &(in_pPOP3->io), in_pPOP3->commandBuffer, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_DELE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_disconnect( pop3Client_t * in_pPOP3 ) { /* Disconnect from the server. */ return IO_disconnect( &(in_pPOP3->io) ); } int pop3_list( pop3Client_t * in_pPOP3 ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_send( &(in_pPOP3->io), list, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_LIST ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_listA( pop3Client_t * in_pPOP3, int in_messageNumber ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_write( &(in_pPOP3->io), list, strlen(list) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } sprintf( in_pPOP3->commandBuffer, "%d", in_messageNumber ); l_nReturnCode = IO_send( &(in_pPOP3->io), in_pPOP3->commandBuffer, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_LISTA ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_noop( pop3Client_t * in_pPOP3 ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_send( &(in_pPOP3->io), noop, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_NOOP ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_pass( pop3Client_t * in_pPOP3, const char * in_password ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_write( &(in_pPOP3->io), pass, strlen(pass) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } l_nReturnCode = IO_send( &(in_pPOP3->io), in_password, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_PASS ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_quit( pop3Client_t * in_pPOP3 ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_send( &(in_pPOP3->io), quit, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_QUIT ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_reset( pop3Client_t * in_pPOP3 ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_send( &(in_pPOP3->io), rset, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_RSET ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_retrieve( pop3Client_t * in_pPOP3, int in_messageNumber ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_write( &(in_pPOP3->io), retr, strlen(retr) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } sprintf( in_pPOP3->commandBuffer, "%d", in_messageNumber ); l_nReturnCode = IO_send( &(in_pPOP3->io), in_pPOP3->commandBuffer, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_RETR ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->messageNumber = in_messageNumber; in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_sendCommand( pop3Client_t * in_pPOP3, const char * in_command, boolean in_multiLine ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_send( &(in_pPOP3->io), in_command, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ if ( in_multiLine ) { l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_SENDCOMMAND ); } else { l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_SENDCOMMANDA ); } if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_stat( pop3Client_t * in_pPOP3 ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_send( &(in_pPOP3->io), stat, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_STAT ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_top( pop3Client_t * in_pPOP3, int in_messageNumber, int in_lines ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_write( &(in_pPOP3->io), top, strlen(top) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } sprintf( in_pPOP3->commandBuffer, "%d", in_messageNumber ); l_nReturnCode = IO_write( &(in_pPOP3->io), in_pPOP3->commandBuffer, strlen(in_pPOP3->commandBuffer) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } l_nReturnCode = IO_write( &(in_pPOP3->io), space, strlen(space) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } sprintf( in_pPOP3->commandBuffer, "%d", in_lines ); l_nReturnCode = IO_send( &(in_pPOP3->io), in_pPOP3->commandBuffer, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_TOP ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->messageNumber = in_messageNumber; in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_uidList( pop3Client_t * in_pPOP3 ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_send( &(in_pPOP3->io), uidl, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_UIDL ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_uidListA( pop3Client_t * in_pPOP3, int in_messageNumber ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_write( &(in_pPOP3->io), uidl, strlen(uidl) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } sprintf( in_pPOP3->commandBuffer, "%d", in_messageNumber ); l_nReturnCode = IO_send( &(in_pPOP3->io), in_pPOP3->commandBuffer, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_UIDLA ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_user( pop3Client_t * in_pPOP3, const char * in_user ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL || in_user == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_write( &(in_pPOP3->io), user, strlen(user) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } l_nReturnCode = IO_send( &(in_pPOP3->io), in_user, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_USER ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_xAuthList( pop3Client_t * in_pPOP3 ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_send( &(in_pPOP3->io), xauthlist, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_XAUTHLIST ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_xAuthListA( pop3Client_t * in_pPOP3, int in_messageNumber ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_write( &(in_pPOP3->io), xauthlist, strlen(xauthlist) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } sprintf( in_pPOP3->commandBuffer, "%d", in_messageNumber ); l_nReturnCode = IO_send( &(in_pPOP3->io), in_pPOP3->commandBuffer, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_XAUTHLISTA ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_xSender( pop3Client_t * in_pPOP3, int in_messageNumber ) { int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( in_pPOP3->mustProcess ) { return NSMAIL_ERR_MUSTPROCESSRESPONSES; } /* Send the command. */ l_nReturnCode = IO_write( &(in_pPOP3->io), xsender, strlen(xsender) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } sprintf( in_pPOP3->commandBuffer, "%d", in_messageNumber ); l_nReturnCode = IO_send( &(in_pPOP3->io), in_pPOP3->commandBuffer, FALSE ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Store the command type on the pending response list. */ l_nReturnCode = AddElement( &(in_pPOP3->pCommandList), (void*)&POP3Response_XSENDER ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } in_pPOP3->mustProcess = TRUE; return NSMAIL_OK; } int pop3_processResponses( pop3Client_t * in_pPOP3 ) { pop3_ResponseType_t * l_pCurrentResponse; LinkedList_t * l_pCurrentLink; int l_nReturnCode; /* Check for errors. */ if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } /* Make sure that all buffered commands are sent. */ l_nReturnCode = IO_flush( &(in_pPOP3->io) ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Continue to process responses while the list is not empty. */ /* or a timeout occurs. */ while ( in_pPOP3->pCommandList != NULL ) { l_pCurrentResponse = (pop3_ResponseType_t *)in_pPOP3->pCommandList->pData; switch ( (*l_pCurrentResponse) ) { case CONN: l_nReturnCode = parseSingleLine( in_pPOP3, in_pPOP3->pop3Sink->connect ); if ( l_nReturnCode != NSMAIL_OK ) { IO_disconnect( &(in_pPOP3->io) ); } break; case DELE: l_nReturnCode = parseSingleLine( in_pPOP3, in_pPOP3->pop3Sink->dele ); break; case LISTA: l_nReturnCode = parseListA( in_pPOP3 ); break; case LIST: l_nReturnCode = parseList( in_pPOP3 ); break; case NOOP: l_nReturnCode = parseNoop( in_pPOP3 ); break; case PASS: l_nReturnCode = parseSingleLine( in_pPOP3, in_pPOP3->pop3Sink->pass ); break; case QUIT: l_nReturnCode = parseSingleLine( in_pPOP3, in_pPOP3->pop3Sink->quit ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } l_nReturnCode = IO_disconnect( &(in_pPOP3->io) ); break; case RSET: l_nReturnCode = parseSingleLine( in_pPOP3, in_pPOP3->pop3Sink->reset ); break; case RETR: l_nReturnCode = parseRetr( in_pPOP3 ); break; case SENDCOMMANDA: l_nReturnCode = parseSendCommandA( in_pPOP3 ); break; case SENDCOMMAND: l_nReturnCode = parseSendCommand( in_pPOP3 ); break; case STAT: l_nReturnCode = parseStat( in_pPOP3 ); break; case TOP: l_nReturnCode = parseTop( in_pPOP3 ); break; case UIDLA: l_nReturnCode = parseUidlA( in_pPOP3 ); break; case UIDL: l_nReturnCode = parseUidl( in_pPOP3 ); break; case USER: l_nReturnCode = parseSingleLine( in_pPOP3, in_pPOP3->pop3Sink->user ); break; case XAUTHLISTA: l_nReturnCode = parseXAuthListA( in_pPOP3 ); break; case XAUTHLIST: l_nReturnCode = parseXAuthList( in_pPOP3 ); break; case XSENDER: l_nReturnCode = parseXSender( in_pPOP3 ); break; default: l_nReturnCode = NSMAIL_ERR_UNEXPECTED; break; } /* An timeout or an error has occured. */ if ( l_nReturnCode != NSMAIL_OK ) { if ( l_nReturnCode != NSMAIL_ERR_TIMEOUT ) { in_pPOP3->mustProcess = FALSE; } return l_nReturnCode; } /* Move to the next element in the pending response list. */ l_pCurrentLink = in_pPOP3->pCommandList; in_pPOP3->pCommandList = in_pPOP3->pCommandList->next; /* Free the current link in the pending response list. */ free ( l_pCurrentLink ); } in_pPOP3->mustProcess = FALSE; return NSMAIL_OK; } int pop3_setChunkSize( pop3Client_t * in_pPOP3, int in_chunkSize ) { if ( in_pPOP3 == NULL || in_chunkSize <= 0 ) { return NSMAIL_ERR_INVALIDPARAM; } in_pPOP3->chunkSize = in_chunkSize; free ( in_pPOP3->messageData ); in_pPOP3->messageData = (char*)malloc( in_chunkSize * sizeof(char) ); if ( in_pPOP3->messageData == NULL ) { return NSMAIL_ERR_OUTOFMEMORY; } return NSMAIL_OK; } int pop3_setResponseSink( pop3Client_t * in_pPOP3, pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3 == NULL || in_pPOP3Sink == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } in_pPOP3->pop3Sink = in_pPOP3Sink; return NSMAIL_OK; } int pop3_setTimeout( pop3Client_t * in_pPOP3, double in_timeout ) { if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } return IO_setTimeout( &(in_pPOP3->io), in_timeout ); } int pop3_set_option( pop3Client_t * in_pPOP3, int in_option, void * in_pOptionData ) { if ( in_pPOP3 == NULL || in_pOptionData == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } switch ( in_option ) { case NSMAIL_OPT_IO_FN_PTRS: IO_setFunctions( &(in_pPOP3->io), (nsmail_io_fns_t *)in_pOptionData ); return NSMAIL_OK; break; default: return NSMAIL_ERR_UNEXPECTED; break; } } int pop3_get_option( pop3Client_t * in_pPOP3, int in_option, void * in_pOptionData ) { if ( in_pPOP3 == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } switch ( in_option ) { case NSMAIL_OPT_IO_FN_PTRS: IO_getFunctions( &(in_pPOP3->io), (nsmail_io_fns_t *)in_pOptionData ); return NSMAIL_OK; break; default: return NSMAIL_ERR_UNEXPECTED; break; } } static int setStatusInfo( const char * in_responseLine, boolean * out_status ) { if ( in_responseLine == NULL || out_status == NULL ) { return NSMAIL_ERR_INVALIDPARAM; } if ( strlen(in_responseLine) < 3 ) { return NSMAIL_ERR_PARSE; } if ( strncmp( ok, in_responseLine, 3 ) == 0 ) { *out_status = TRUE; } else if ( strncmp( err, in_responseLine, 4 ) == 0 ) { *out_status = FALSE; } else { return NSMAIL_ERR_PARSE; } return NSMAIL_OK; } static int parseSingleLine( pop3Client_t * in_pPOP3, sinkMethod_t in_callback ) { /* Server status */ boolean l_status; /* Read the next line of data from the socket. */ int l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { if ( in_callback != NULL ) { in_callback( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[4]) ); } } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); } return NSMAIL_OK; } static int parseListA( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; char * l_ptr; int l_messageNum; int l_octetCount; /* Read the next line of data from the socket. */ int l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { l_messageNum = atoi( &(in_pPOP3->responseLine[4]) ); if ( l_messageNum == 0 ) { return NSMAIL_ERR_PARSE; } l_ptr = strchr( &(in_pPOP3->responseLine[4]), ' ' ); if ( l_ptr == NULL ) { return NSMAIL_ERR_PARSE; } l_octetCount = atoi( &(l_ptr[1]) ); if ( l_octetCount == 0 ) { return NSMAIL_ERR_PARSE; } pop3Sink_listStart( in_pPOP3->pop3Sink ); pop3Sink_list( in_pPOP3->pop3Sink, l_messageNum, l_octetCount ); pop3Sink_listComplete( in_pPOP3->pop3Sink ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); } return NSMAIL_OK; } static int parseList( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; char * l_ptr; int l_messageNum; int l_octetCount; int l_nReturnCode; if ( in_pPOP3->multiLineState == FALSE ) { /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { pop3Sink_listStart( in_pPOP3->pop3Sink ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); return NSMAIL_OK; } in_pPOP3->multiLineState = TRUE; } /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } while ( '.' != (in_pPOP3->responseLine)[0] || strlen(in_pPOP3->responseLine) != 1 ) { l_messageNum = atoi( in_pPOP3->responseLine ); if ( l_messageNum == 0 ) { return NSMAIL_ERR_PARSE; } l_ptr = strchr( in_pPOP3->responseLine, ' ' ); if ( l_ptr == NULL ) { return NSMAIL_ERR_PARSE; } l_octetCount = atoi( &(l_ptr[1]) ); if ( l_octetCount == 0 ) { return NSMAIL_ERR_PARSE; } /* Invoke the callback. */ pop3Sink_list( in_pPOP3->pop3Sink, l_messageNum, l_octetCount ); /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } } in_pPOP3->multiLineState = FALSE; /* Invoke the callback. */ pop3Sink_listComplete( in_pPOP3->pop3Sink ); return NSMAIL_OK; } static int parseNoop( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; /* Read the next line of data from the socket. */ int l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { pop3Sink_noop( in_pPOP3->pop3Sink ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); } return NSMAIL_OK; } static int parseRetr( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; char * l_responseLine = NULL; unsigned int l_byteCount; unsigned int l_octetCount; unsigned int l_messageLength; int l_nReturnCode; if ( in_pPOP3->multiLineState == FALSE ) { /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { l_octetCount = atoi( &(in_pPOP3->responseLine[4]) ); if ( l_octetCount == 0 ) { /* The server returned just +OK instead of +OK octets. So we will also return 0 for octetcount :-( PY 7/29/98 return NSMAIL_ERR_PARSE; */ } pop3Sink_retrieveStart( in_pPOP3->pop3Sink, in_pPOP3->messageNumber, l_octetCount ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); return NSMAIL_OK; } in_pPOP3->multiLineState = TRUE; } /* Read the next line of data from the socket. */ l_nReturnCode = IO_readDLine( &(in_pPOP3->io), &l_responseLine ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } l_messageLength = strlen( l_responseLine ); /* in_pPOP3->responseLine[l_messageLength++] = '\r'; in_pPOP3->responseLine[l_messageLength++] = '\n'; in_pPOP3->responseLine[l_messageLength] = '\0'; */ while ( ('.' == l_responseLine[0] && l_messageLength == 3) == FALSE ) { l_byteCount = 0; if ( l_responseLine[0] == '.' ) { l_byteCount++; } while ( l_byteCount < strlen(l_responseLine) ) { if ( in_pPOP3->messageDataSize == in_pPOP3->chunkSize - 1 ) { (in_pPOP3->messageData)[in_pPOP3->messageDataSize] = '\0'; /* Invoke the callback. */ pop3Sink_retrieve( in_pPOP3->pop3Sink, in_pPOP3->messageData ); in_pPOP3->messageDataSize = 0; } (in_pPOP3->messageData)[in_pPOP3->messageDataSize++] = l_responseLine[l_byteCount++]; } /* Free the line here */ l_nReturnCode = IO_freeDLine( &l_responseLine ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } l_responseLine = NULL; /* Read the next line of data from the socket. */ l_nReturnCode = IO_readDLine( &(in_pPOP3->io), &l_responseLine ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } l_messageLength = strlen( l_responseLine ); /* in_pPOP3->responseLine[l_messageLength++] = '\r'; in_pPOP3->responseLine[l_messageLength++] = '\n'; in_pPOP3->responseLine[l_messageLength] = '\0'; */ } /* Free the line here */ l_nReturnCode = IO_freeDLine( &l_responseLine ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } l_responseLine = NULL; if ( in_pPOP3->messageDataSize > 0 ) { (in_pPOP3->messageData)[in_pPOP3->messageDataSize] = '\0'; /* Invoke the callback. */ pop3Sink_retrieve( in_pPOP3->pop3Sink, in_pPOP3->messageData ); in_pPOP3->messageDataSize = 0; } in_pPOP3->multiLineState = FALSE; /* Invoke the callback. */ pop3Sink_retrieveComplete( in_pPOP3->pop3Sink ); return NSMAIL_OK; } static int parseSendCommandA( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; /* Read the next line of data from the socket. */ int l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { pop3Sink_sendCommandStart( in_pPOP3->pop3Sink ); pop3Sink_sendCommand( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[4]) ); pop3Sink_sendCommandComplete( in_pPOP3->pop3Sink ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); } return NSMAIL_OK; } static int parseSendCommand( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; int l_nReturnCode; if ( in_pPOP3->multiLineState == FALSE ) { /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { pop3Sink_sendCommandStart( in_pPOP3->pop3Sink ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); return NSMAIL_OK; } in_pPOP3->multiLineState = TRUE; } /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } while ( '.' != (in_pPOP3->responseLine)[0] || strlen(in_pPOP3->responseLine) != 1 ) { /* Invoke the callback. */ pop3Sink_sendCommand( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[4]) ); /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } } in_pPOP3->multiLineState = FALSE; /* Invoke the callback. */ pop3Sink_sendCommandComplete( in_pPOP3->pop3Sink ); return NSMAIL_OK; } static int parseStat( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; char * l_ptr; int l_messageNum; int l_octetCount; /* Read the next line of data from the socket. */ int l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { l_messageNum = atoi( &(in_pPOP3->responseLine[4]) ); if ( ( l_messageNum == 0 ) && ( in_pPOP3->responseLine[4] != '0' ) ) { return NSMAIL_ERR_PARSE; } l_ptr = strchr( &(in_pPOP3->responseLine[4]), ' ' ); if ( l_ptr == NULL ) { return NSMAIL_ERR_PARSE; } l_octetCount = atoi( &(l_ptr[1]) ); if ( ( l_octetCount == 0 ) && ( l_ptr[1] != '0' ) ) { return NSMAIL_ERR_PARSE; } pop3Sink_stat( in_pPOP3->pop3Sink, l_messageNum, l_octetCount ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); } return NSMAIL_OK; } static int parseTop( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; int l_nReturnCode; if ( in_pPOP3->multiLineState == FALSE ) { /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { pop3Sink_topStart( in_pPOP3->pop3Sink, in_pPOP3->messageNumber ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); return NSMAIL_OK; } in_pPOP3->multiLineState = TRUE; } /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } while ( '.' != (in_pPOP3->responseLine)[0] || strlen(in_pPOP3->responseLine) != 1 ) { /* Invoke the callback. */ pop3Sink_top( in_pPOP3->pop3Sink, in_pPOP3->responseLine ); /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } } in_pPOP3->multiLineState = FALSE; /* Invoke the callback. */ pop3Sink_topComplete( in_pPOP3->pop3Sink ); return NSMAIL_OK; } static int parseUidlA( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; char * l_ptr; int l_messageNum; /* Read the next line of data from the socket. */ int l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { l_messageNum = atoi( &(in_pPOP3->responseLine[4]) ); if ( l_messageNum == 0 ) { return NSMAIL_ERR_PARSE; } l_ptr = strchr( &(in_pPOP3->responseLine[4]), ' ' ); if ( l_ptr == NULL ) { return NSMAIL_ERR_PARSE; } pop3Sink_uidListStart( in_pPOP3->pop3Sink ); pop3Sink_uidList( in_pPOP3->pop3Sink, l_messageNum, &(l_ptr[1]) ); pop3Sink_uidListComplete( in_pPOP3->pop3Sink ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); } return NSMAIL_OK; } static int parseUidl( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; char * l_ptr; int l_messageNum; int l_nReturnCode; if ( in_pPOP3->multiLineState == FALSE ) { /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { pop3Sink_uidListStart( in_pPOP3->pop3Sink ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); return NSMAIL_OK; } in_pPOP3->multiLineState = TRUE; } /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } while ( '.' != (in_pPOP3->responseLine)[0] || strlen(in_pPOP3->responseLine) != 1 ) { l_messageNum = atoi( in_pPOP3->responseLine ); if ( l_messageNum == 0 ) { return NSMAIL_ERR_PARSE; } l_ptr = strchr( in_pPOP3->responseLine, ' ' ); if ( l_ptr == NULL ) { return NSMAIL_ERR_PARSE; } /* Invoke the callback. */ pop3Sink_uidList( in_pPOP3->pop3Sink, l_messageNum, &(l_ptr[1]) ); /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } } in_pPOP3->multiLineState = FALSE; /* Invoke the callback. */ pop3Sink_uidListComplete( in_pPOP3->pop3Sink ); return NSMAIL_OK; } static int parseXAuthListA( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; char * l_ptr; char * l_authName = NULL; int l_messageNum; /* Read the next line of data from the socket. */ int l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { l_messageNum = atoi( &(in_pPOP3->responseLine[4]) ); if ( l_messageNum == 0 ) { return NSMAIL_ERR_PARSE; } l_ptr = strchr( &(in_pPOP3->responseLine[4]), ' ' ); if ( l_ptr != NULL ) { l_authName = &(l_ptr[1]); } pop3Sink_xAuthListStart( in_pPOP3->pop3Sink ); pop3Sink_xAuthList( in_pPOP3->pop3Sink, l_messageNum, l_authName ); pop3Sink_xAuthListComplete( in_pPOP3->pop3Sink ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); } return NSMAIL_OK; } static int parseXAuthList( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; char * l_ptr; char * l_authName; int l_messageNum; int l_nReturnCode; if ( in_pPOP3->multiLineState == FALSE ) { /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { pop3Sink_xAuthListStart( in_pPOP3->pop3Sink ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); return NSMAIL_OK; } in_pPOP3->multiLineState = TRUE; } /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } while ( '.' != (in_pPOP3->responseLine)[0] || strlen(in_pPOP3->responseLine) != 1 ) { l_messageNum = atoi( in_pPOP3->responseLine ); if ( l_messageNum == 0 ) { return NSMAIL_ERR_PARSE; } l_ptr = strchr( in_pPOP3->responseLine, ' ' ); if ( l_ptr != NULL ) { l_authName = &(l_ptr[1]); } /* Invoke the callback. */ pop3Sink_xAuthList( in_pPOP3->pop3Sink, l_messageNum, l_authName ); /* Read the next line of data from the socket. */ l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } } in_pPOP3->multiLineState = FALSE; /* Invoke the callback. */ pop3Sink_xAuthListComplete( in_pPOP3->pop3Sink ); return NSMAIL_OK; } static int parseXSender( pop3Client_t * in_pPOP3 ) { /* Server status */ boolean l_status; /* Read the next line of data from the socket. */ int l_nReturnCode = IO_readLine( &(in_pPOP3->io), in_pPOP3->responseLine, MAX_TEXTLINE_LENGTH ); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Parse out the status and the message. */ l_nReturnCode = setStatusInfo(in_pPOP3->responseLine, &l_status); if ( l_nReturnCode != NSMAIL_OK ) { return l_nReturnCode; } /* Invoke the callback. */ if ( l_status ) { pop3Sink_xSender( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[4]) ); } else { pop3Sink_error( in_pPOP3->pop3Sink, &(in_pPOP3->responseLine[5]) ); } return NSMAIL_OK; } static void pop3Sink_error( pop3Sink_t * in_pPOP3Sink, const char * in_response ) { if ( in_pPOP3Sink->error != NULL ) { in_pPOP3Sink->error( in_pPOP3Sink, in_response ); } } static void pop3Sink_listStart( pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3Sink->listStart != NULL ) { in_pPOP3Sink->listStart( in_pPOP3Sink ); } } static void pop3Sink_list( pop3Sink_t * in_pPOP3Sink, int in_messageNumber, int in_octetCount ) { if ( in_pPOP3Sink->list != NULL ) { in_pPOP3Sink->list( in_pPOP3Sink, in_messageNumber, in_octetCount ); } } static void pop3Sink_listComplete( pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3Sink->listComplete != NULL ) { in_pPOP3Sink->listComplete( in_pPOP3Sink ); } } static void pop3Sink_noop( pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3Sink->noop != NULL ) { in_pPOP3Sink->noop( in_pPOP3Sink ); } } static void pop3Sink_retrieveStart( pop3Sink_t * in_pPOP3Sink, int in_messageNumber, int in_octetCount ) { if ( in_pPOP3Sink->retrieveStart != NULL ) { in_pPOP3Sink->retrieveStart( in_pPOP3Sink, in_messageNumber, in_octetCount ); } } static void pop3Sink_retrieve( pop3Sink_t * in_pPOP3Sink, const char * in_response ) { if ( in_pPOP3Sink->retrieve != NULL ) { in_pPOP3Sink->retrieve( in_pPOP3Sink, in_response ); } } static void pop3Sink_retrieveComplete( pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3Sink->retrieveComplete != NULL ) { in_pPOP3Sink->retrieveComplete( in_pPOP3Sink ); } } static void pop3Sink_sendCommandStart( pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3Sink->sendCommandStart != NULL ) { in_pPOP3Sink->sendCommandStart( in_pPOP3Sink ); } } static void pop3Sink_sendCommand( pop3Sink_t * in_pPOP3Sink, const char * in_response ) { if ( in_pPOP3Sink->sendCommand != NULL ) { in_pPOP3Sink->sendCommand( in_pPOP3Sink, in_response ); } } static void pop3Sink_sendCommandComplete( pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3Sink->sendCommandComplete != NULL ) { in_pPOP3Sink->sendCommandComplete( in_pPOP3Sink ); } } static void pop3Sink_stat( pop3Sink_t * in_pPOP3Sink, int in_messageNumber, int in_octetCount ) { if ( in_pPOP3Sink->stat != NULL ) { in_pPOP3Sink->stat( in_pPOP3Sink, in_messageNumber, in_octetCount ); } } static void pop3Sink_topStart( pop3Sink_t * in_pPOP3Sink, int in_messageNumber ) { if ( in_pPOP3Sink->topStart != NULL ) { in_pPOP3Sink->topStart( in_pPOP3Sink, in_messageNumber ); } } static void pop3Sink_top( pop3Sink_t * in_pPOP3Sink, const char * in_response ) { if ( in_pPOP3Sink->top != NULL ) { in_pPOP3Sink->top( in_pPOP3Sink, in_response ); } } static void pop3Sink_topComplete( pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3Sink->topComplete != NULL ) { in_pPOP3Sink->topComplete( in_pPOP3Sink ); } } static void pop3Sink_uidListStart( pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3Sink->uidListStart != NULL ) { in_pPOP3Sink->uidListStart( in_pPOP3Sink ); } } static void pop3Sink_uidList( pop3Sink_t * in_pPOP3Sink, int in_messageNumber, const char * in_response ) { if ( in_pPOP3Sink->uidList != NULL ) { in_pPOP3Sink->uidList( in_pPOP3Sink, in_messageNumber, in_response ); } } static void pop3Sink_uidListComplete( pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3Sink->uidListComplete != NULL ) { in_pPOP3Sink->uidListComplete( in_pPOP3Sink ); } } static void pop3Sink_xAuthListStart( pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3Sink->xAuthListStart != NULL ) { in_pPOP3Sink->xAuthListStart( in_pPOP3Sink ); } } static void pop3Sink_xAuthList( pop3Sink_t * in_pPOP3Sink, int in_messageNumber, const char * in_response ) { if ( in_pPOP3Sink->xAuthList != NULL ) { in_pPOP3Sink->xAuthList( in_pPOP3Sink, in_messageNumber, in_response ); } } static void pop3Sink_xAuthListComplete( pop3Sink_t * in_pPOP3Sink ) { if ( in_pPOP3Sink->xAuthListComplete != NULL ) { in_pPOP3Sink->xAuthListComplete( in_pPOP3Sink ); } } static void pop3Sink_xSender( pop3Sink_t * in_pPOP3Sink, const char * in_response ) { if ( in_pPOP3Sink->xSender != NULL ) { in_pPOP3Sink->xSender( in_pPOP3Sink, in_response ); } } /* Initializes and allocates the pop3Sink_t structure. */ int pop3Sink_initialize( pop3Sink_t ** out_ppPOP3Sink ) { /* Parameter validation. */ if ( out_ppPOP3Sink == NULL || (*out_ppPOP3Sink) != NULL ) { return NSMAIL_ERR_INVALIDPARAM; } /* Create the sink */ (*out_ppPOP3Sink) = (pop3Sink_t*)malloc( sizeof(pop3Sink_t) ); if ( (*out_ppPOP3Sink) == NULL ) { return NSMAIL_ERR_OUTOFMEMORY; } memset( (*out_ppPOP3Sink), 0, sizeof(pop3Sink_t) ); return NSMAIL_OK; } /* Function used to free the pop3Sink_t structure. */ void pop3Sink_free( pop3Sink_t ** in_ppPOP3Sink ) { if ( in_ppPOP3Sink == NULL || *in_ppPOP3Sink == NULL ) { return; } /* Free the client. */ free( *in_ppPOP3Sink ); *in_ppPOP3Sink = NULL; }