// --------------------------------------------------------------------------
// Citadel: NetDC15.CPP
//
// DragCit 1.5 Networking

#include "ctdl.h"
#pragma hdrstop

#include "room.h"
#include "net.h"
#include "filecmd.h"
#include "aplic.h"
#include "cwindows.h"
#include "filerdwr.h"

// --------------------------------------------------------------------------
// Contents
//
// dc15network()	During network master code


// --------------------------------------------------------------------------
// Static Data

static void sendRequest(const protocols *theProt);
static void reciveRequest(const protocols *theProt);
static void makeSendFile(void);
static void sendFiles(const protocols *theProt);
static void receiveFiles(const protocols *theProt);


// --------------------------------------------------------------------------
// dc15network(): During network master code.

Bool dc15network(Bool master)
	{
	char line[100], line2[100];
	label here, there;
	FILE *file;
	int i, rms;
	time_t t, t2=0;
	Bool	done = FALSE;

	TI()netFailed = FALSE;

	const protocols *theProt = GetProtocolByKey(TI()node->GetProtocol(),
			TRUE);

	if (!theProt)
		{
		doccr();
		cPrintf(getnetmsg(177));
		doCR();
		return (FALSE);
		}

	if (!SerialPort.HaveCarrier())
		{
		return (FALSE);
		}

	sprintf(line, sbs, cfg.temppath, mesgTmp);
	unlink(line);

	sprintf(line, getnetmsg(123), cfg.temppath);
	unlink(line);

	sprintf(line, getnetmsg(124), cfg.temppath);
	unlink(line);

	sprintf(line, getnetmsg(125), cfg.temppath);
	unlink(line);

	if ((file = fopen(line, FO_AB)) == NULL)
		{
		perror(getnetmsg(25));
		return (FALSE);
		}

	for (i = get_first_room(here, there), rms = 0; i;
			i = get_next_room(here, there), rms++)
		{
		PutStr(file, there);
		}

	PutStr(file, ns);
	fclose(file);

	if (master)
		{
		sendRequest(theProt);
		if (!SerialPort.HaveCarrier())
			{
			return (FALSE);
			}

		reciveRequest(theProt);
		}
	else
		{
		reciveRequest(theProt);
		if (!SerialPort.HaveCarrier())
			{
			return (FALSE);
			}

		sendRequest(theProt);
		}

	if (!SerialPort.HaveCarrier() || TI()netFailed)
		{
		return (FALSE);
		}

	if (master)
		{
		// clear the buffer
		while (SerialPort.HaveCarrier() && TI()SerialPort.IsInputReady())
			{
			TI()SerialPort.Input();
			}
		}

	makeSendFile();

	if (!SerialPort.HaveCarrier() || TI()netFailed)
		{
		return (FALSE);
		}

	// wait for them to get their shit together
	cPrintf(getnetmsg(11));

	TI()SerialPort.Output('X');
	t2 = 0;
	t = time(NULL);
	while (SerialPort.HaveCarrier() && !done)
		{
		if (time(NULL) > (t + (TI()node->GetFetchTimeout() * 60)))
			{
			CITWINDOW *w = ScreenSaver.IsOn() ? NULL :
					CitWindowsMsg(NULL, getmsg(713), getmsg(1648));

			Hangup();
			TI()netFailed = TRUE;

			if (w)
				{
				destroyCitWindow(w, FALSE);
				}
			}

		KBReady();

		if (TI()SerialPort.IsInputReady())
			{
			i = TI()SerialPort.Input();
			if (i == 'X' || TI()node->GetNetworkType() != NET_DCIT16)
				{
				done = TRUE;
				}
			else
				{
				DebugOut(pctc, i);
				}

			}

		// wake them up! (every second)
		if (time(NULL) != t2)
			{
			TI()SerialPort.Output('X');
			t2 = time(NULL);
			}
		}

	// wake them up!
	for (i = 0; i < 10; i++)
		{
		TI()SerialPort.Output('X');
		}

	doccr();

	if (!SerialPort.HaveCarrier() || TI()netFailed)
		{
		return (FALSE);
		}

	if (master)
		{
		receiveFiles(theProt);
		if (!SerialPort.HaveCarrier() || TI()netFailed)
			{
			return (FALSE);
			}

		sendFiles(theProt);
		}
	else
		{
		sendFiles(theProt);
		if (!SerialPort.HaveCarrier() || TI()netFailed)
			{
			return (FALSE);
			}

		receiveFiles(theProt);
		}

	if (TI()netFailed)
		{
		return (FALSE);
		}

	cPrintf(getnetmsg(84));
	doccr();

	CITWINDOW *w = ScreenSaver.IsOn() ? NULL :
			CitWindowsMsg(NULL, getmsg(1643));

	Hangup();

	if (w)
		{
		destroyCitWindow(w, FALSE);
		}

	setio();	// hmmm

	cPrintf(getnetmsg(85), cfg.Lmsg_nym);
	doccr();

	sformat(line, TI()node->GetExtractPacket(), getmsg(48), roomdataIn);
	apsystem(line, TRUE);

	changedir(cfg.temppath);
	unlink(roomdataIn);

	for (i = 0; i < rms; i++)
		{
		sprintf(line, getnetmsg(126), i);
		sprintf(line2, getnetmsg(127), i);
		rename(line, line2);
		}

	sprintf(line, sbs, cfg.temppath, mesgTmp);
	sprintf(line2, getnetmsg(123), cfg.temppath);
	rename(line, line2);

	return (TRUE);
	}


// --------------------------------------------------------------------------
// sendRequest(): Send the room request file.

static void sendRequest(const protocols *theProt)
	{
	cPrintf(getnetmsg(86));
	doccr();

	wxsnd(cfg.temppath, roomreqOut, theProt, 0);

	unlink(roomreqOut);
	}


// --------------------------------------------------------------------------
// reciveRequest(): Recive the room request file.

static void reciveRequest(const protocols *theProt)
	{
	cPrintf(getnetmsg(87));
	doccr();

	wxrcv(cfg.temppath, roomreqIn, theProt);

	if (!filexists(roomreqIn))
		{
		CITWINDOW *w = ScreenSaver.IsOn() ? NULL :
				CitWindowsMsg(NULL, getmsg(713), getmsg(1646));

		Hangup();
		TI()netFailed = TRUE;

		if (w)
			{
			destroyCitWindow(w, FALSE);
			}
		}
	}


// --------------------------------------------------------------------------
// makeSendFile(): Make the file to send to remote.

static void makeSendFile(void)
	{
	char line[100], line2[100];
	label troo;
	label fn;
	FILE *file;
	int i = 0, rm;
	int crcounter = 0;

	if ((file = fopen(roomreqIn, FO_RB)) == NULL)
		{
		perror(getnetmsg(90));
		return; // ok
		}

	doccr();
	cPrintf(getnetmsg(2));
	doccr();

	GetStr(file, troo, LABELSIZE);

	while (*troo && !feof(file))
		{
		rm = RoomExists(troo);
		if (rm == CERROR)
			{
			rm = IdExists(troo, TRUE);
			}

		if (rm != CERROR)
			{
			if (TI()CurrentUser->CanAccessRoom(rm))
				{
				sprintf(fn, getnetmsg(126), i);
				cPrintf(getnetmsg(128), deansi(troo));
				if (!((crcounter+1) % 3))
					{
					doccr();
					}
				crcounter++;
				NewRoom(rm, fn, NULL);
				}
			else
				{
				doccr();
				cPrintf(getnetmsg(111), deansi(troo));
				doccr();
				amPrintf(getnetmsg(4), troo, bn);
				TI()netError = TRUE;
				}
			}
		else
			{
			doccr();
			cPrintf(getnetmsg(97), deansi(troo));
			doccr();
			amPrintf(getnetmsg(6), troo, bn);
			TI()netError = TRUE;
			}

		i++;
		GetStr(file, troo, LABELSIZE);
		}

	doccr();
	fclose(file);
	unlink(roomreqIn);

	cPrintf(getnetmsg(98));
	doccr();
	sprintf(line, sbs, cfg.transpath, TI()node->GetMailFileName());
	sprintf(line2, sbs, cfg.temppath, mesgTmp);
	if ((file = fopen(line2, FO_WB)) != NULL)
		{
		fclose(file);
		}
	copyfile(line, line2);

	cPrintf(getnetmsg(99), cfg.Lmsg_nym);
	doccr();

	// Zip them up
	sprintf(line2, getnetmsg(113), mesgTmp, roomStar);
	sformat(line, TI()node->GetCreatePacket(), getmsg(49), roomdataOut,
			line2);
	apsystem(line, TRUE);

	// Remove them.
	changedir(cfg.temppath);
	ambigUnlink(roomStar, FALSE);
	unlink(mesgTmp);
	}


// --------------------------------------------------------------------------
// sendFiles(): Send the data files.

static void sendFiles(const protocols *theProt)
	{
	cPrintf(getnetmsg(100));
	doccr();

	wxsnd(cfg.temppath, roomdataOut, theProt, 0);

	unlink(roomdataOut);
	}


// --------------------------------------------------------------------------
// receiveFiles(): Recive the data files.

static void receiveFiles(const protocols *theProt)
	{
	cPrintf(getnetmsg(101));
	doccr();

	wxrcv(cfg.temppath, roomdataIn, theProt);

	if (!filexists(roomdataIn))
		{
		CITWINDOW *w = ScreenSaver.IsOn() ? NULL :
				CitWindowsMsg(NULL, getmsg(713), getmsg(1647));

		Hangup();
		TI()netFailed = TRUE;

		if (w)
			{
			destroyCitWindow(w, FALSE);
			}
		}
	}
