/*****************************************************************************
 *
 * $Id$
 * Purpose ...............: Fidonet mailer 
 *
 *****************************************************************************
 * Copyright (C) 1997-2002
 *   
 * Michiel Broek		FIDO:	2:280/2802
 * Beekmansbos 10
 * 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 "../config.h"
#include "libs.h"
#include "memwatch.h"
#include "structs.h"
#include "users.h"
#include "records.h"
#include "clcomm.h"
#include "common.h"
#include "dbnode.h"



static FILE *pktfp=NULL;
static faddr pktroute = 
{
	NULL,0,0,0,0,NULL
};



FILE *openpkt(FILE *pkt, faddr *addr, char flavor)
{
	off_t		pos;
	struct flock	fl;
	struct stat	st;
	char		*Name;
	struct tm	*ptm;
	time_t		t;
	int		i;
	faddr		*bestaka;
	unsigned char	buffer[0x3a];
	char		str[9];

	if (pkt == NULL) {
		if (pktfp) {
			Syslog('P', "packet opened, check address");
			if (metric(addr,&pktroute) == 0) {
				if ((CFG.maxpktsize == 0L) ||
				    ((fstat(fileno(pktfp),&st) == 0) &&
				     (st.st_size < CFG.maxpktsize))) {
					Syslog('P', "return existing fp");
					return pktfp;
				}
				Syslog('P', "packet too big, open new");
				closepkt();
			} else {
				Syslog('P', "address changed, closing fp");
				closepkt();
			}
		}

		Syslog('P', "open new packet file");
		pktroute.zone   = addr->zone;
		pktroute.net    = addr->net;
		pktroute.node   = addr->node;
		pktroute.point  = addr->point;
		pktroute.domain = xstrcpy(addr->domain);
		pktroute.name   = NULL;
		Name = pktname(addr,flavor);
		mkdirs(Name, 0770);

		if ((pktfp = fopen(Name, "r+")) == NULL)
			pktfp = fopen(Name,"w");
		if (pktfp == NULL) {
			WriteError("$Unable to open packet %s",MBSE_SS(Name));
			return NULL;
		}

		fl.l_type   = F_WRLCK;
		fl.l_whence = 0;
		fl.l_start  = 0L;
		fl.l_len    = 0L;
		if (fcntl(fileno(pktfp), F_SETLKW, &fl) < 0) {
			WriteError("$Unable to lock packet %s", MBSE_SS(Name));
			fclose(pktfp);
			return NULL;
		}

		pkt = pktfp;
		pos = fseek(pkt, -2L, SEEK_END);
	}

	pos = ftell(pkt);
	if (pos <= 0L) {
		Syslog('P', "creating new .pkt");

		memset(&buffer, 0, sizeof(buffer));
		t = time(NULL);
		ptm = localtime(&t);
		if (ptm->tm_sec > 59)
			ptm->tm_sec = 59;

		bestaka = bestaka_s(addr);
		buffer[0x00] = (bestaka->node & 0x00ff);
		buffer[0x01] = (bestaka->node & 0xff00) >> 8;
		buffer[0x02] = (addr->node & 0x00ff);
		buffer[0x03] = (addr->node & 0xff00) >> 8;
		buffer[0x04] = ((ptm->tm_year + 1900) & 0x00ff);
		buffer[0x05] = ((ptm->tm_year + 1900) & 0xff00) >> 8;
		buffer[0x06] = ptm->tm_mon;
		buffer[0x08] = ptm->tm_mday;
		buffer[0x0a] = ptm->tm_hour;
		buffer[0x0c] = ptm->tm_min;
		buffer[0x0e] = ptm->tm_sec;
		buffer[0x12] = 2;
		buffer[0x14] = (bestaka->net & 0x00ff);
		buffer[0x15] = (bestaka->net & 0xff00) >> 8;
		buffer[0x16] = (addr->net & 0x00ff);
		buffer[0x17] = (addr->net & 0xff00) >> 8;
		buffer[0x18] = 0xfe;

		memset(&str, 0, 8);
		if (noderecord(addr) && strlen(nodes.Epasswd))
			sprintf(str, "%s", nodes.Epasswd);
		for (i = 0; i < 8; i++)
			buffer[0x1a + i] = str[i];

		buffer[0x22] = (bestaka->zone & 0x00ff);
		buffer[0x23] = (bestaka->zone & 0xff00) >> 8;
		buffer[0x24] = (addr->zone & 0x00ff);
		buffer[0x25] = (addr->zone & 0xff00) >> 8;
		buffer[0x29] = 1;
		buffer[0x2c] = 1;
		buffer[0x2e] = buffer[0x22];
		buffer[0x2f] = buffer[0x23];
		buffer[0x30] = buffer[0x24];
		buffer[0x31] = buffer[0x25];
		buffer[0x32] = (bestaka->point & 0x00ff);
		buffer[0x33] = (bestaka->point & 0xff00) >> 8;
		buffer[0x34] = (addr->point & 0x00ff);
		buffer[0x35] = (addr->point & 0xff00) >> 8;
		buffer[0x36] = 'm';
		buffer[0x37] = 'b';
		buffer[0x38] = 's';
		buffer[0x39] = 'e';

		fseek(pkt, 0L, SEEK_SET);
		fwrite(buffer, 1, 0x3a, pkt);
	}

	return pkt;
}



void closepkt(void)
{
	unsigned char	buffer[2];

	Syslog('P', "closepkt entered");
	memset(&buffer, 0, sizeof(buffer));

	if (pktfp) {
		fwrite(buffer, 1, 2, pktfp);
		fclose(pktfp);	/* close also discards lock */
	}
	pktfp = NULL;
	if (pktroute.domain) 
		free(pktroute.domain);
}