/*
**	POP3GET.c
**
**  Simple POP3 Get utility
**
**  Requires "RMail" to be in the path and executable (tested
**  with ASMail only)
**
**  (C) 1995 Oliver Wagner (owagner@lsd.wupper.de),
**  Public Domain
**
**  No warranties.
**
**  To be compiled with SAS/C 6.50.
**
*/

#define __USE_SYSBASE
#include <proto/exec.h>
#include <proto/dos.h>
#include <dos/dostags.h>
#include <dos/stdio.h>
#include <string.h>

#include "rev.h"

#define min __builtin_min

char version[] = { "$VER: Pop3Get " VERTAG };

struct myargs {
	char *host;
	char *port;
	char *user;
	char *pass;
	ULONG nodelete;
} myargs;

long __oslibversion = 37;

//	sprintf() replacement
static UWORD fmtfunc[] = { 0x16c0, 0x4e75 };
static void __stdargs sprintf( char *to, char *fmt, ... )
{
	RawDoFmt( fmt, &fmt + 1, (APTR)fmtfunc, to );
}

static void clnl( char *p )
{
	p = stpbrk( p, "\r\n" );
	if( p )
		*p = 0;
}

char buffer[ 512 ];
BPTR sock; // :-)

// This is the tricky one
static int doxfer( void )
{
	int c;
	int len;
	BPTR f;
	char *tmpname;
	char toline[ 512 ], *top;

	for( c = 1; ; c++ )
	{
		int inheader = TRUE;
		char *p;

		top = toline;
		*top = 0;

		FPrintf( sock, "RETR %ld\n", c );
		if( !FGets( sock, buffer, sizeof( buffer ) ) )
			return( 10 );
		if( strnicmp( buffer, "+OK", 3 ) )
			break;
		len = atoi( &buffer[ 4 ] );
		Printf( "Retrieving mail #%ld, %ld bytes...\n", c, len );

		tmpname = len > 32768 ? "pop3get.tmp" : "T:pop3get.tmp";

		f = Open( tmpname, MODE_NEWFILE );
		if( !f )
		{
			Printf( "*ALERT* Unable to open \"%s\"; IoErr = %ld, exiting...\n", tmpname, IoErr() );
		}
		SetVBuf( f, NULL, BUF_FULL, 8192 );
		for(;;)
		{
			if( !FGets( sock, buffer, sizeof( buffer ) ) )
			{
				Printf( "*ALERT* Receive error during RETR!\n" );
				Close( f );
				DeleteFile( tmpname );
				return( 10 );
			}

			clnl( buffer );
			if( !strcmp( buffer, "." ) )
				break;	// EOM
			FWrite( f, buffer, strlen( buffer ), 1 );
			FPutC( f, '\n' );

			if( !buffer[ 0 ] )
				inheader = FALSE;

			if( inheader )
			{
				if( !strnicmp( buffer, "To:", 3 ) )
				{
					p = strtok( buffer, " ,\t<>" );
					while( p )
					{
						char *p2;
						p2 = strchr( p, '@' );
						if( p2 )
						{
							char *p3 = p;
							while( *p3 != '@' )
								*top++ = *p3++;
							*top++ = ' ';
						}
						else
						{
							p2 = strchr( p, '!' );
							if( p2 )
							{
								strcpy( top, p2 + 1 );
								top = strchr( top, 0 );
								*top++ = ' ';
							}
						}
						p = strtok( NULL, " ,\t" );
					}
				}
			}
		}

		if( top > toline )
			top[ - 1 ] = 0;
		else
			strcpy( toline, "No-To-Found" );

		Close( f );
		Printf( "Msg #%ld to \"%s\", sending...\n", c, toline );
		sprintf( buffer, "RMail <%s %s", tmpname, toline );
		SystemTags( buffer, TAG_DONE );
		DeleteFile( tmpname );

		if( !myargs.nodelete )
		{
			Printf( "Deleting message #%ld...\n", c );
			FPrintf( sock, "DELE %ld\n", c );
			FGets( sock, buffer, sizeof( buffer ) );
		}
	}
	Printf( "finished transaction; got %ld mails total.\n", c - 1 );
	return( c == 1 ? 5 : 0 );
}

void __stdargs __main( char *dummy )
{
	struct RDArgs *rda;
	int rc = 10;

	Printf( "%s written by Oliver Wagner (owagner@lsd.wupper.de)\n", &version[ 6 ] );

	myargs.port = "110";
	rda = ReadArgs( "Host/A,Port/K,Username=USER/A,Password=PASS/A,NoDelete/S", (LONG*)&myargs, NULL );
	if( !rda )
	{
		PrintFault( IoErr(), "Pop3Get" );
		exit( 10 );
	}

	sprintf( buffer, "TCP:%s/%s", myargs.host, myargs.port );
	Printf( "Attempting connection to host \"%s\" on port %s...\n", myargs.host, myargs.port );
	sock = Open( buffer, MODE_NEWFILE );
	if( sock )
	{
		int okcount = 0;

		PutStr( "Connection established, now doing login.\n" );
		FPrintf( sock, "USER %s\nPASS %s\n", myargs.user, myargs.pass );

		// We're looking for the third OK (nifty, eh? :-)
		while( okcount < 3 && FGets( sock, buffer, sizeof( buffer ) ) )
		{
			clnl( buffer );
			Printf( "got: '%s'\n", buffer );
			if( !strnicmp( buffer, "+OK", 3 ) )
				okcount++;
			else if( !strnicmp( buffer, "-ERR", 4 ) )
				break;
		}
		if( okcount == 3 )
		{
			rc = doxfer();
			FPrintf( sock, "QUIT\n" );
		}
	}
	else
		Printf( "Unable to connect, error %ld.\n", IoErr() );
	FreeArgs( rda );
	exit( rc );
}
