/*****************************************************************************
 *
 * File ..................: tosser/tosspkt.c
 * Purpose ...............: Toss a single *.pkt file
 * Last modification date : 14-Aug-1999
 * memory leaks check ....: 20-Feb-1999
 *
 *****************************************************************************
 * Copyright (C) 1997-1999
 *   
 * Michiel Broek		FIDO:		2:2801/16
 * Beekmansbos 10		Internet:	mbroek@ux123.pttnwb.nl
 * 1971 BV IJmuiden
 * the Netherlands
 *
 * This file is part of MBSE BBS.
 *
 * This BBS is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * MBSE BBS is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with MBSE BBS; see the file COPYING.  If not, write to the Free
 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *****************************************************************************/


#include "../include/libs.h"
#include "../include/structs.h"
#include "../include/records.h"
#include "../common/common.h"
#include "../dbase/dbnode.h"
#include "putil.h"
#include "importmsg.h"
#include "tosspkt.h"



/*
 * External declarations
 */
extern	int	do_quiet;



/*
 * Global variables
 */
int	net_in = 0;			/* Netmails received		    */
int	net_imp = 0;			/* Netmails imported                */
int	net_out = 0;			/* Netmails forwarded		    */
int	net_bad = 0;			/* Bad netmails (tracking errors    */
int	echo_in = 0;			/* Echomail received		    */
int	echo_imp = 0;			/* Echomail imported		    */
int	echo_out = 0;			/* Echomail forwarded		    */
int	echo_bad = 0;			/* Bad echomail			    */
int	echo_dupe = 0;			/* Dupe echomail		    */
char	*toname = NULL;			/* To user			    */
char	*fromname = NULL;		/* From user			    */
char	*subj = NULL;			/* Message subject		    */



static int at_zero = 0;

char *aread(char *, int, FILE *);
char *aread(char *s, int count, FILE *fp)
{
	int i,c,next;

	if (feof(fp)) 
		return(NULL);
	if (s == NULL) 
		return NULL;
	if (at_zero)
	{
		at_zero=0;
		return NULL;
	}

	for (i = 0,next = 1; (i < count-1) && next;)
		switch (c=getc(fp)) {
		case '\n':	break;

		case '\r':	s[i]='\n';
				i++;
				next=0;
				break;

		case 0x8d:	s[i]=' ';
				i++;
				break;

		case '\0':	at_zero=1;
				next=0;
				break;

		default:	s[i]=c;
				i++;
				break;
		}
	s[i]='\0';
	return s;
}



/*
 * Toss one packet.
 *
 *  0  - 
 *  1  - Cannot open packet
 *  2  - Bad packet header
 *  3  - Packet is not for us
 *  4  - Bad password
 */
int TossPkt(char *fn)
{
	int	rc, count = 0, maxrc = 0;
	faddr	from, to;
	FILE	*pkt;

	if (!do_quiet) {
		colour(10, 0);
		printf("Tossing packet %s\n", fn);
	}

	if ((pkt = fopen(fn, "r")) == 0) {
		perror("");
		WriteError("Cannot open %s", fn);
		return 1;
	}

	if (((rc = getheader(&from, &to, pkt, fn)) != 0)) {
		WriteError("%s, aborting",
				(rc == 1)?"wrong header type":
				(rc == 2)?"bad packet header":
				(rc == 3)?"packet is not for us":
				(rc == 4)?"bad password":
				"bad packet");
		return(rc);
	}

	while ((rc = getmessage(pkt, &from, &to)) == 1) {
		count++;
	}
	Syslog('-', "Messages : %d", count);

	maxrc=rc;
	if (!do_quiet)
		printf("\r                                                    \r");

	if (rc)
		Syslog('+', "End, rc=%d", maxrc);

	fclose(pkt);
	return maxrc;
}



/*
 * Process one message from message packet.
 *
 *  0   - no more messages
 *  1   - more messages
 *  2   - bad file
 *  3   - bad message header
 *  4   - unable to open temp file
 *  5   - unexpected end of packet
 *  >10 - import error
 */
int getmessage(FILE *pkt, faddr *p_from, faddr *p_to)
{
	char		buf[2048];
	char		*orig = NULL;
	char		*p, *l, *r;
	int		tmp, rc, maxrc = 0;
	faddr		f, t, *o;
	int		result, flags, cost;
	time_t		mdate = 0L;
	FILE		*fp;
	unsigned char	buffer[0x0e];

	subj = NULL;
	toname = NULL;
	fromname = NULL;
	result = fread(&buffer, 1, sizeof(buffer), pkt);

	switch(tmp = (buffer[0x01] << 8) + buffer[0x00]) {
	case 0:	
		if (result == 2)
			return 0;
		else {
			Syslog('!', "Junk after logical end of packet, skipped");
			return 5;
		}
	case 2:	
		break;

	default:
		Syslog('!', "bad message type: 0x%04x",tmp);
		return 2;
	}

	if (result != 14) {
		Syslog('!', "Unexpected end of packet");
		return 5;
	}

	f.zone   = 0;
	t.zone   = 0;
	f.point  = 0;
	t.point  = 0;
	f.name   = NULL;
	t.name   = NULL;
	f.domain = NULL;
	t.domain = NULL;
	f.node = (buffer[0x03] << 8) + buffer[0x02];
	t.node = (buffer[0x05] << 8) + buffer[0x04];
	f.net  = (buffer[0x07] << 8) + buffer[0x06];
	t.net  = (buffer[0x09] << 8) + buffer[0x08];
	flags  = (buffer[0x0b] << 8) + buffer[0x0a];
	cost   = (buffer[0x0d] << 8) + buffer[0x0c];


	/*
	 * Read the DateTime, toUserName, fromUserName and subject fields
	 * from the packed message. The stringlength is +1 for the right
	 * check. This is different then in ifmail's original code.
	 */
	if (aread(buf, 21, pkt)) {
		mdate = parsefdate(buf, NULL);
		if (aread(buf, sizeof(buf)-1, pkt)) {
			Syslog('!', "date not null-terminated: \"%s\"",buf);
			return 3;
		}
	}

	if (aread(buf, 37, pkt)) {
		t.name = xstrcpy(buf);
		toname = xstrcpy(buf);
		if (aread(buf, sizeof(buf)-1, pkt)) {
			if (*(p=t.name+strlen(t.name)-1) == '\n')
				 *p = '\0';
			Syslog('!', "to name not null-terminated: \"%s\"",buf);
			return 3;
		}
	}

	if (aread(buf, 37, pkt)) {
		f.name = xstrcpy(buf);
		fromname = xstrcpy(buf);
		if (aread(buf, sizeof(buf)-1, pkt)) {
			if (*(p=f.name+strlen(f.name)-1) == '\n') 
				*p = '\0';
			Syslog('!', "from name not null-terminated: \"%s\"",buf);
			return 3;
		}
	}

	if (aread(buf, 73, pkt)) {
		subj = xstrcpy(buf);
		if (aread(buf, sizeof(buf)-1, pkt)) {
			if (*(p=subj+strlen(subj)-1) == '\n') 
				*p = '\0';
			subj = xstrcat(subj,(char *)"\\n");
			subj = xstrcat(subj,buf);
			Syslog('!', "subj not null-terminated: \"%s\"",buf);
			return 3;
		}
	}

	if (feof(pkt) || ferror(pkt)) {
		Syslog('!', "Could not read message header, aborting");
		return 3;
	}

	f.zone = p_from->zone;
	t.zone = p_to->zone;

	if ((fp = tmpfile()) == NULL) {
		WriteError("$unable to open temporary file");
		return 4;
	}

	/*
	 * Read the text from the .pkt file
	 */
	while (aread(buf,sizeof(buf)-1,pkt)) {

		fputs(buf, fp);

		/*
		 * Extract info from Origin line if found.
		 */
		if (!strncmp(buf," * Origin:",10)) {
			p=buf+10;
			while (*p == ' ') p++;
			if ((l=strrchr(p,'(')) && (r=strrchr(p,')')) && (l < r)) {
				*l = '\0';
				*r = '\0';
				l++;
				if ((o = parsefnode(l))) {
					f.point = o->point;
					f.node = o->node;
					f.net = o->net;
					f.zone = o->zone;
					if (o->domain) 
						f.domain=o->domain;
					o->domain=NULL;
					tidy_faddr(o);
				}
			} else
				if (*(l=p+strlen(p)-1) == '\n')
					 *l='\0';
			for (l=p+strlen(p)-1;*l == ' ';l--) 
				*l='\0'; 
			orig = xstrcpy(p);
		}
	}
	
	rc = importmsg(p_from, &f,&t,orig,mdate,flags,cost,fp);
	if (rc) 
		rc+=10;
	if (rc > maxrc) 
		maxrc = rc;

	fclose(fp);

	if(f.name) 
		free(f.name); 
	f.name=NULL;

	if(t.name) 
		free(t.name); 
	t.name=NULL;

	if(f.domain) 
		free(f.domain); 
	f.domain=NULL;

	if(t.domain) 
		free(t.domain); 
	t.domain=NULL;

	if (fromname)
		free(fromname);
	fromname = NULL;

	if (toname)
		free(toname);
	toname = NULL;

	if (subj)
		free(subj);
	subj = NULL;

	if (orig)
		free(orig);
	orig = NULL;

	if (feof(pkt) || ferror(pkt)) {
		WriteError("Unexpected end of packet");
		return 5;
	}
	return 1;
}


