/* Post Office Protocol (POP3) Client -- RFC1225
 * Copyright 1992 William Allen Simpson
 *	partly based on a NNTP client design by Anders Klemets, SM0RGV
 *      and POP2 Client by Mike Stockett, WA7DYX, et alia.
 */
#include "global.h"
#ifdef POP3CLIENT
#include <time.h>
#include "timer.h"
#include "proc.h"
#include "netuser.h"
#include "files.h"
#include "mailcli.h"
#include "mailutil.h"
#include "smtp.h"
#include "md5.h"
#if defined(LZW)
#include "lzw.h"
extern int poplzw;
#endif
#ifdef MSDOS
#include "hardware.h"
#endif
 

#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: pop3cli.c,v 1.15 1997/09/07 21:18:28 root Exp $";
#endif

void
pop3_job(unused,v1,p2)
int unused OPTIONAL;
void *v1;
void *p2 OPTIONAL;
{
struct mailservers *np = v1;
struct sockaddr_in fsocket;
char buf[TLINELEN];
char const *cp;
char *cp2;
FILE *wfp = NULLFILE;
time_t t;
int s = -1;
int bytes;
int messages;
int i;
#if defined(LZW)
int lzwmode, lzwbits;
#endif

	if (!np || !np->hostname || mailbusy (np))
		return;

	if ((fsocket.sin_addr.s_addr = resolve (np->hostname)) == 0L) {
		/* No IP address found */
		if (Mailtrace >= 1)
			log (-1, "POP3 can't resolve host '%s'", np->hostname);
		start_detached_timer (&np->timer);
		return;
	}

	fsocket.sin_family = AF_INET;
	fsocket.sin_port = IPPORT_POP3;

	s = socket (AF_INET, SOCK_STREAM, 0);
	(void) sockmode (s, SOCK_ASCII);

	if (connect (s, (char *)&fsocket, SOCKSIZE) == -1) {
		cp = sockerr (s);
		if (Mailtrace >= 2)
			log (s, "POP3 Connect failed: %s", (cp != NULLCHAR) ? cp : "" );
		goto quit;
	}

	log (s, "POP3 Connected to mailhost %s", np->hostname);

	/* Eat the banner */
	if (mailresponse (s, buf, "banner") == -1 || buf[0] == '-')
		goto quit;

	if ((cp = strchr (buf, '<')) != NULLCHAR && (cp2 = strchr (cp, '>')) != NULLCHAR) {
		MD5_CTX mdContext;
		char response[128], *rp;
		unsigned char *dp, *ep;

		*++cp2 = '\0';
		strncpy (response, cp, sizeof (response));
		strcat (response, np->password);
		MD5Init (&mdContext);
		MD5Update (&mdContext, (unsigned char *) response, strlen (response));
		MD5Final (&mdContext);
		dp = mdContext.digest;
		ep = dp + sizeof (mdContext.digest);
		for (rp = response; dp < ep; rp += 2)
			(void) sprintf (rp, "%02x", *dp++ & 0xff);
		*rp = '\0';

		usprintf (s, "APOP %s %s\n", np->username, response);
		if (mailresponse (s, buf, "APOP") == -1 || buf[0] == '-')
			goto quit;
	} else {

		usprintf(s,"USER %s\n", np->username);
		if (mailresponse (s, buf, "USER") == -1 || buf[0] == '-')
			goto quit;

		usprintf (s, "PASS %s\n", np->password);
		if (mailresponse (s, buf, "PASS") == -1 || buf[0] == '-')
			goto quit;
	}

	usputs (s, "STAT\n");
	if (mailresponse (s, buf, "STAT") == -1 || buf[0] == '-')
		goto quit;

	rip(buf);
	if (Mailtrace >= 1)
		log (s, "POP3 status %s", buf);
	sscanf (buf, "+OK %d %d", &messages, &bytes);

#if defined(LZW)
	if (poplzw && messages) {
		usprintf (s, "XLZW %d %d\n", Lzwbits, Lzwmode);
		if (mailresponse(s, buf, "XLZW") == 0 && buf[0] != '-') {
			lzwmode = lzwbits = 0;
			sscanf (buf, "+OK lzw %d %d", &lzwbits, &lzwmode);
			if (lzwmode != Lzwmode || lzwbits != Lzwbits) {
				lzwmode = LZWCOMPACT;
				lzwbits = LZWBITS;
			}
			lzwinit (s,lzwbits,lzwmode);
		}
	}
#endif

	for (i = 0; i++ < messages; ) {
		if ((wfp = tmpfile()) == NULLFILE) {
			if (Mailtrace >= 1)
				log (s, "POP3 Cannot create tmp file");
			goto quit;
		}

		usprintf (s, "RETR %d\n", i);
		if (mailresponse (s, buf, "RETR") == -1 )
			goto quit;
		if (buf[0] == '-')
			continue;

		(void) time (&t);
		fprintf (wfp, "From POP3@%s %s", np->hostname, ctime (&t));

		if (recvmail (s, buf, TLINELEN, wfp, Mailtrace) == -1)
			goto quit;

		if (copymail (buf, TLINELEN, wfp, np->mailbox) == -1)
			goto quit;
		(void) fclose (wfp);

		usprintf (s,"DELE %d\n", i);
		if (mailresponse (s, buf, "DELE" ) == -1 || buf[0] == '-')
			goto quit;
	}

	usputs (s,"QUIT\n");
	(void) mailresponse (s, buf, "QUIT");

	if (messages && Mailtrace) {
		if (Mailquiet == 0)
			tcmdprintf ("\007");
		tcmdprintf ("%u message%sarrived for %s from mailhost %s\n",
			messages, (messages == 1) ? " " : "s ", np->mailbox, np->hostname);
		smtptick (NULL);     /* wake SMTP to send that mail */
	}

quit:
	log (s,"POP3 daemon exiting");
	close_s (s);

	if (wfp != NULLFILE)		/*lint !e644 */
		(void) fclose (wfp);
	start_detached_timer (&np->timer);
}


#endif	/* POP3CLIENT */
