// --------------------------------------------------------------------------
// Citadel: Net69.CPP
//
// Net 6.9 stuff.

#include "ctdl.h"
#pragma hdrstop

#include "room.h"
#include "tallybuf.h"
#include "auxtab.h"
#include "msg.h"
#include "log.h"
#include "net.h"
#include "moreinfo.h"
#include "filecmd.h"
#include "aplic.h"
#include "cwindows.h"
#include "filerdwr.h"
#include "miscovl.h"
#include "term.h"


// --------------------------------------------------------------------------
// Contents
//
// net69_error()		saves net69 error messages
// net69()


static const char *msg69		= "MSG.69";
static const char *moreinfo69	= "MOREINFO.69";
static const char *sbroomreqPs	= "%s\\ROOMREQ.%s";


// --------------------------------------------------------------------------
// net69_error(): Saves net69 error messages.

void cdecl net69_error(Bool Fetch, Bool errorflag, const char *node,
		const char *fmt, ...)
	{
	char buff[256];
	va_list ap;

	va_start(ap, fmt);
	vsprintf(buff, fmt, ap);
	va_end(ap);

	if (!errorflag)
		{
		amPrintf(getnetmsg(144), Fetch ? getnetmsg(55) : getnetmsg(56),
				node, bn);
		}

	amPrintf(getnetmsg(145), buff, bn);
	}


// --------------------------------------------------------------------------
// net69()

Bool net69(Bool master)
	{
	int i;
	time_t t, t2=0;
	Bool done = FALSE;
	char packetname[20];
	Bool fetchit = FALSE;

	amZap();

	TI()netFailed = FALSE;

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

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

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

	setdefaultTerm(2);

	sprintf(packetname, getnetmsg(146), TI()node->GetAlias(), cfg.alias);

	changedir(cfg.transpath);

	if (TI()node->GetFetch() > -1)
		{
		directoryinfo *files = filldirectory(packetname, 0, OldAndNew, FALSE);

		if (files && files[0].name[0] == 0)
			{
			fetchit = TRUE;
			}

		// free file directory structure
		delete [] files;
		}

	if (fetchit || TI()node->GetFetch() > 0)
		{
		LogEntry5 Log5(cfg.maxrooms);

		Log5.CopyRoomNewPointers(*TI()CurrentUser);

		if (!net69_fetch(fetchit))
			{
			TI()CurrentUser->CopyRoomNewPointers(Log5);
			}
		}

	changedir(cfg.transpath);

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

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

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

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

	TI()SerialPort.Output('X');
	t2 = 0;
	t = time(NULL);
	while (SerialPort.HaveCarrier() && !done)
		{
		if (time(NULL) > (t + (TI()node->GetFetchTimeout() * 60)))
			{
			Hangup();
			TI()netFailed = TRUE;
			}

		KBReady();

		if (TI()SerialPort.IsInputReady())
			{
			i = TI()SerialPort.Input();

			if (i == 'X')
				{
				done = TRUE;
				}
			else
				{
				DebugOut(pctc, i);
				}
			}

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

	if (!SerialPort.HaveCarrier() || TI()netFailed)
		{
		return (FALSE);
		}
	else
		{
		// wake them up!
		for (i = 0; i < 10; i++)
			{
			TI()SerialPort.Output('X');
			}
		}


	doccr();
	doccr();
	cPrintf(getnetmsg(58));
	doccr();

	sprintf(packetname, getnetmsg(72), TI()node->GetAlias());

	if (TI()node->GetNetworkRevisionNumber() > 0)
		{
		// unidirectional transfers.

		if (master)
			{
			wxsnd(cfg.transpath, packetname, theProt,
					(theProt->CheckType == 1) ? 2 : 0);
			wxrcv(cfg.transpath, ns, theProt);
			}
		else
			{
			wxrcv(cfg.transpath, ns, theProt);
			wxsnd(cfg.transpath, packetname, theProt,
					(theProt->CheckType == 1) ? 2 : 0);
			}
		}
	else
		{
		// bidirectional transfer
		wxsnd(cfg.transpath, packetname, theProt,
				(theProt->CheckType == 1) ? 2 : 0);
		}

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

	doccr();
	cPrintf(getnetmsg(59));
	doccr();

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

	Hangup();

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

	setio();

	if (theProt->CheckType == 0)
		{
		ambigUnlink(packetname, FALSE);
		}
	else if (theProt->CheckType == 2)
		{
		RunApplication(theProt->CheckMethod, packetname, TRUE, FALSE);
		}

	net69_incorporate();

	SaveAideMess(NULL);

	return (TRUE);
	}

// This should be replaced with NetLogEntry::MakeNet69RoomRequestFile.
// Until then, these two functions have to be maintained together.
void net69_makeroomrequest(void)
	{
	FILE *roomreqfd;
	char roomreqfilename[80];

	sprintf(roomreqfilename, sbroomreqPs, cfg.temppath, cfg.alias);

	cPrintf(getnetmsg(60), roomreqfilename);
	doccr();

	if ((roomreqfd = fopen(roomreqfilename, FO_WB)) == NULL)
		{
		doccr();
		cPrintf(getmsg(78), roomreqfilename);
		doccr();
		}
	else
		{
		for (r_slot i = 0; i < cfg.maxrooms; i++)
			{
			if (TI()CurrentUser->CanAccessRoom(i) && *GetRoomNetID(i) &&
					!IsNetIDCorrupted(GetRoomNetID(i)))
				{
				net69_PutStr(roomreqfd, GetRoomNetID(i));
				}
			}

		fclose(roomreqfd);
		}
	}

Bool NetLogEntryC::MakeNet69RoomRequestFile(ModemConsoleE ReportTo)
	{
	void cdecl (*wPrintf)(const char *fmt, ...);
	void (*wDoCR)(void);

	switch (ReportTo)
		{
		case MODEM:
			{
			wPrintf = mPrintf;
			wDoCR = doCR;
			break;
			}

		case CONSOLE:
			{
			wPrintf = cPrintf;
			wDoCR = doccr;
			break;
			}

		default:
			{
			wPrintf = noPrintf;
			wDoCR = noDoCR;
			break;
			}
		}

	FILE *roomreqfd;
	char roomreqfilename[80];

	sprintf(roomreqfilename, sbroomreqPs, cfg.temppath, cfg.alias);

	wPrintf(getnetmsg(60), roomreqfilename);
	wDoCR();

	if ((roomreqfd = fopen(roomreqfilename, FO_WB)) == NULL)
		{
		wDoCR();
		wPrintf(getmsg(78), roomreqfilename);
		wDoCR();

		return (FALSE);
		}
	else
		{
		for (r_slot i = 0; i < cfg.maxrooms; i++)
			{
			if (CanAccessRoom(i) && *GetRoomNetID(i) &&
					!IsNetIDCorrupted(GetRoomNetID(i)))
				{
				net69_PutStr(roomreqfd, GetRoomNetID(i));
				}
			}

		fclose(roomreqfd);
		}

	return (TRUE);
	}

void net69_incorporate(void)
	{
	int big_total_new = 0, big_total_expired = 0, big_total_duplicate = 0;

	SetDoWhat(NETWORKING);

	if (!getnode(&TI()node, getnetmsg(61), NOMODCON, TRUE))
		{
		doccr();
		cPrintf(getnetmsg(62));
		doccr();
		return;
		}

	char packetmask[20];
	sprintf(packetmask, getnetmsg(72), cfg.alias);

	changedir(cfg.transpath);

	TI()MRO.Verbose = TRUE;
	TI()MRO.Reverse = FALSE;

	// We need to sort these files by date
	directoryinfo *files = filldirectory(packetmask, 2, OldAndNew, FALSE);

	if (files)
		{
		char fullPathToMsg69[80];
		sprintf(fullPathToMsg69, sbs, cfg.temppath, msg69);

		char fullPathToMoreinfo69[80];
		sprintf(fullPathToMoreinfo69, sbs, cfg.temppath, moreinfo69);

		char fullPathToMesgTmp[80];
		sprintf(fullPathToMesgTmp, sbs, cfg.temppath, mesgTmp);

		char fullPathToFile69[80];
		sprintf(fullPathToFile69, getnetmsg(147), cfg.temppath, cfg.alias);

		Bool errorflag = FALSE;

		for (int i = 0; files[i].name[0]; i++)
			{
			label packetname;
			CopyStringToBuffer(packetname, files[i].name, LABELSIZE);

			doccr();
			cPrintf(getnetmsg(63), packetname);
			doccr();

			char fullPathToPacket[128];
			sprintf(fullPathToPacket, sbs, cfg.transpath, packetname);

			char ExtractCommandLine[256];
			sformat(ExtractCommandLine, TI()node->GetExtractPacket(),
					getnetmsg(48), fullPathToPacket);

			changedir(cfg.temppath);
			apsystem(ExtractCommandLine, TRUE);
			changedir(cfg.temppath);

			if ((cfg.offhook == 1) && !SerialPort.HaveCarrier())
				{
				offhook();
				}

			// If we didn't get a MSG.69, try again, supering it.
			if (!filexists(fullPathToMsg69))
				{
				char *wo = ExtractCommandLine;
				Bool superit = FALSE;

				while (*wo == '!' || *wo == '@' || *wo == '$' ||
						*wo == '?' || *wo == '*')
					{
					if (*wo == '!')
						{
						superit = TRUE;
						}

					wo++;
					}

				if (!superit)
					{
					char ExtractCommandLine2[256];
					ExtractCommandLine2[0] = '!';

					strcpy(ExtractCommandLine2 + 1, ExtractCommandLine);
					apsystem(ExtractCommandLine2, TRUE);
					changedir(cfg.temppath);
					}
				}

			unlink(fullPathToPacket);

			FILE *msgfd;
			if ((msgfd = fopen(fullPathToMsg69, FO_RB)) == NULL)
				{
				doccr();
				cPrintf(getmsg(78), fullPathToMsg69);
				doccr();
				}
			else
				{
				NetLogEntryC IncomingLog;
				label rnode;

				if (!IncomingLog.IsValid())
					{
					doccr();
					cPrintf(getnetmsg(50));
					doccr();

					net69_error(FALSE, errorflag, rnode, getnetmsg(50));
					errorflag = TRUE;
					}

				if (net69_GetStr(msgfd, rnode, LABELSIZE))
					{
					if (!getnode(&TI()node, rnode, NOMODCON, FALSE))
						{
						DebugOut(getmsg(206), rnode);

						getnode(&TI()node, getnetmsg(61), NOMODCON, FALSE);
						TI()node->SetName(rnode); // Not "default" in path
						}

					// If we were able to allocate space for a log buffer,
					// attempt to load node this packet came from so we
					// can control which rooms we accept messages to.
					const Bool ControlAccess = IncomingLog.IsValid() ?
							IncomingLog.LoadByName(rnode) : FALSE;

					doccr();
					cPrintf(getnetmsg(65), cfg.Lmsgs_nym, rnode);
					doccr();
					doccr();
					cPrintf(getnetmsg(66));
					doccr();

					int total_new = 0, total_expired = 0, total_duplicate = 0;
					int total_rooms = 0;

					label netid;
					while (net69_GetStr(msgfd, netid, LABELSIZE))
						{
						KBReady();

						r_slot roomNo = IdExists(netid, TRUE);

						if (roomNo == CERROR)
							{
							if (TI()node->IsAutoRoom() &&
									!IsNetIDCorrupted(netid) &&
									!IsNetIDInNetIDCit(netid))
								{
								if (autoroom(netid))
									{
									if (TI()node->IsVerbose(NCV_ROOMCREATED))
										{
										net69_error(FALSE, errorflag, rnode,
												getnetmsg(107), netid);
										errorflag = TRUE;
										}
									}
								else
									{
									if (TI()node->IsVerbose(NCV_ROOMNOTCREATED))
										{
										net69_error(FALSE, errorflag, rnode,
												getnetmsg(108), netid);
										errorflag = TRUE;
										}
									}
								}
							else
								{
								if (TI()node->IsVerbose(NCV_NETIDNOTFOUND))
									{
									net69_error(FALSE, errorflag, rnode,
											getnetmsg(109), netid);
									errorflag = TRUE;
									}
								}
							roomNo = IdExists(netid, TRUE);
							}

						if (roomNo != CERROR)
							{
							int our_new, our_expired, our_duplicate;

							cPrintf(getnetmsg(131),
									deansi(GetRoomName(roomNo)));

							if (ControlAccess &&
									TI()node->IsVerbose(NCV_NOACCESS) &&
									!IncomingLog.CanAccessRoom(roomNo))
								{
								net69_error(FALSE, errorflag, rnode,
										getnetmsg(117), netid);
								errorflag = TRUE;
								}

							ReadMsgFl(roomNo, NULL, msgfd, NULL, &our_new,
									&our_expired, &our_duplicate,
									ControlAccess ? &IncomingLog : NULL);

							if (our_new)
								{
								cPrintf(getnetmsg(132), our_new);
								}
							else
								{
								cPrintf(getnetmsg(133), our_new);
								}
							cPrintf(getnetmsg(134));

							if (our_expired)
								{
								cPrintf(getnetmsg(132), our_expired);
								}
							else
								{
								cPrintf(getnetmsg(133), our_expired);
								}
							cPrintf(getnetmsg(134));

							if (our_duplicate)
								{
								cPrintf(getnetmsg(132), our_duplicate);
								}
							else
								{
								cPrintf(getnetmsg(133), our_duplicate);
								}

							doccr();

							total_new += our_new;
							total_expired += our_expired;
							total_duplicate += our_duplicate;
							total_rooms++;
							}
						else
							{
							int ch, lastch;

							ch = 1;
							lastch = ch;

							while (!feof(msgfd) &&
									!((ch == 0) && (lastch == 0)))
								{
								lastch = ch;
								ch = fgetc(msgfd);
								}

							cPrintf(getnetmsg(75), deansi(netid));
							doccr();
							}

						StatusLine.Update();
						}

					big_total_new += total_new;
					big_total_expired += total_expired;
					big_total_duplicate += total_duplicate;

					cPrintf(getnetmsg(67));
					doccr();
					cPrintf(getnetmsg(68));

					if (total_rooms)
						{
						cPrintf(getnetmsg(132), total_rooms);
						}
					else
						{
						cPrintf(getnetmsg(133), total_rooms);
						}
					cPrintf(getnetmsg(175));

					if (total_new)
						{
						cPrintf(getnetmsg(132), total_new);
						}
					else
						{
						cPrintf(getnetmsg(133), total_new);
						}
					cPrintf(getnetmsg(134));


					if (total_expired)
						{
						cPrintf(getnetmsg(132), total_expired);
						}
					else
						{
						cPrintf(getnetmsg(133), total_expired);
						}
					cPrintf(getnetmsg(134));

					if (total_duplicate)
						{
						cPrintf(getnetmsg(132), total_duplicate);
						}
					else
						{
						cPrintf(getnetmsg(133), total_duplicate);
						}
					}

				fclose(msgfd);
				unlink(fullPathToMsg69);
				}

			MoreInfo NetInfo;

			if (NetInfo.Open(fullPathToMoreinfo69))
				{
				// read it in...

				NetInfo.Close();
				unlink(fullPathToMoreinfo69);
				}

			if ((msgfd = fopen(fullPathToMesgTmp, FO_RB)) != NULL)
				{
				doccr();
				cPrintf(getnetmsg(69));
				doccr();
				doccr();
				cPrintf(getnetmsg(34));
				doccr();

				int our_new, our_expired, our_duplicate;

				ReadMsgFl(MAILROOM, NULL, msgfd, NULL, &our_new, &our_expired,
						&our_duplicate, NULL);

				label New, Routed, Rejected;
				strcpy(New, ltoac(our_new));
				strcpy(Routed, ltoac(our_expired));
				strcpy(Rejected, ltoac(our_duplicate));

				cPrintf(getnetmsg(70), New,
						our_new == 1 ? cfg.Lmsg_nym : cfg.Lmsgs_nym,
						Routed, Rejected,
						ltoac(our_new + our_expired + our_duplicate));

				fclose(msgfd);

				unlink(fullPathToMesgTmp);
				}

			doccr();

			// Get the alias from the packetname
			char alias[4];
			int j = substr(packetname, getnetmsg(148), FALSE) + 2;
			for (int k = 0; (k < 3) && packetname[j] && (packetname[j] != '.');
					j++, k++)
				{
				alias[k] = packetname[j];
				}
			alias[k] = 0;

			char roomreqfilename[80];
			sprintf(roomreqfilename, sbroomreqPs, cfg.temppath, alias);
			if (filexists(roomreqfilename))
				{
				char RoomReqInTrans[80];
				sprintf(RoomReqInTrans, sbroomreqPs, cfg.transpath, alias);

				doccr();
				cPrintf(getnetmsg(71), roomreqfilename);
				doccr();

				copyfile(roomreqfilename, RoomReqInTrans);
				unlink(roomreqfilename);
				}

			if (filexists(fullPathToFile69))
				{
				doccr();
				cPrintf(getnetmsg(63), fullPathToFile69);
				doccr();

				if (TI()node->IsVerbose(NCV_FILE69IN))
					{
					net69_error(FALSE, errorflag, alias, getnetmsg(110),
							fullPathToFile69);

					errorflag = TRUE;
					}

				if (TI()node->IsVerbose(NCV_FILE69INFULL))
					{
					char PartialCommandLine[256];

					sprintf(PartialCommandLine, getnetmsg(149),
							fullPathToFile69, cfg.temppath, getnetmsg(150));

					ExtractCommandLine[0] = '$';

					sformat(ExtractCommandLine + 1,
							TI()node->GetExtractPacket(), getnetmsg(48),
							PartialCommandLine);
					}
				else
					{
					sformat(ExtractCommandLine, TI()node->GetExtractPacket(),
							getnetmsg(48), fullPathToFile69);
					}

				changedir(cfg.dlpath);
				apsystem(ExtractCommandLine, TRUE);

				unlink(fullPathToFile69);

				if (TI()node->IsVerbose(NCV_FILE69INFULL))
					{
					char TempFileName[128];

					sprintf(TempFileName, sbs, cfg.temppath, getnetmsg(150));

					if (TI()AideMsg)
						{
						FILE *fl;

						if ((fl = fopen(TempFileName, FO_RB)) != NULL)
							{
							char *TextFromFile = new char[MAXTEXT];

							if (TextFromFile)
								{
								GetFileMessage(fl, TextFromFile, MAXTEXT - 1);

								TI()AideMsg->AppendText(TextFromFile);

								delete [] TextFromFile;
								}
							else
								{
								mPrintf(getmsg(188), getnetmsg(151));
								}

							fclose(fl);
							}
						}

					unlink(TempFileName);
					}
				}
			}

		delete [] files;
		}


	// Copy all FILE69.* out of #DLPATH to #TRANSPATH
	changedir(cfg.dlpath);
	files = filldirectory(getnetmsg(152), 0, OldAndNew, FALSE);

	if (files)
		{
		for (int i = 0; files[i].name[0]; i++)
			{
			char fullPathToFile69InTrans[128];

			sprintf(fullPathToFile69InTrans, sbs, cfg.transpath,
					files[i].name);

			doccr();
			cPrintf(getnetmsg(71), files[i].name);
			doccr();

			copyfile(files[i].name, fullPathToFile69InTrans);
			unlink(files[i].name);
			}

		delete [] files;
		}

	TI()MS.Entered = big_total_new;
	TI()expired = big_total_expired;
	TI()duplicate = big_total_duplicate;

	TI()callout = FALSE;

	buildaddress();

	readNetCmdTmp();
	}

Bool net69_fetch(Bool needFull)
	{
	Bool usingroomrequest = FALSE;
	FILE *roomreqfd;
	label netid;
	int roomNo;
	FILE *msgfd;
	int msgsread;
	int crcounter = 0;
	char errorflag = FALSE;

	int oldmread = TI()MS.Read;
	TI()MS.Read = 0;

	SetDoWhat(NETWORKING);

	changedir(cfg.temppath);

	roomtalley();

	if (needFull || TI()node->GetFetch() == 2)
		{
		char fullPathToRoomreq[80];
		sprintf(fullPathToRoomreq, getnetmsg(153), cfg.transpath,
				TI()node->GetAlias());

		if ((roomreqfd = fopen(fullPathToRoomreq, FO_RB)) == NULL)
			{
			DebugOut(getdbmsg(48), TI()node->GetAlias());
			}
		else
			{
			usingroomrequest = TRUE;
			}

		char fullPathToMsg69[80];
		sprintf(fullPathToMsg69, sbs, cfg.temppath, msg69);

		if ((msgfd = fopen(fullPathToMsg69, FO_WB)) == NULL)
			{
			doccr();
			cPrintf(getmsg(78), fullPathToMsg69);
			doccr();

			if (TI()menu69)
				{
				TI()MS.Read = oldmread;
				}

			if (roomreqfd)
				{
				fclose(roomreqfd);
				}

			return (FALSE);
			}

		PutStr(msgfd, cfg.Address);

		doccr();

		cPrintf(getnetmsg(73), cfg.Lmsgs_nym);

		if (usingroomrequest)
			{
			DebugOut(getdbmsg(49), TI()node->GetAlias());
			}

		doccr();
		doccr();

		cPrintf(getnetmsg(76));

		if (usingroomrequest)
			{
			doccr();

			while (net69_GetStr(roomreqfd, netid, LABELSIZE))
				{
				time(&TI()LastActiveTime);	// avoid timeouts with KBReady
				while (KBReady())
					{
					if (ciChar() == ESC)
						{
						fclose(msgfd);
						return (FALSE);
						}
					}

				if ((roomNo = IdExists(netid, TRUE)) != CERROR)
					{
					if (TI()CurrentUser->CanAccessRoom(roomNo))
						{
						if (GetRoomNewMessages(roomNo))
							{
							cPrintf(getnetmsg(139),
									deansi(GetRoomName(roomNo)));

							msgsread = NewRoom(roomNo, NULL, msgfd);

							cPrintf(getnetmsg(140), msgsread);

							if (!((crcounter+1) % 2))
								{
								doccr();
								}
							crcounter++;
							}
						}
					else
						{
						if (TI()node->IsVerbose(NCV_NOACCESS))
							{
							net69_error(TRUE, errorflag, TI()node->GetName(),
									getnetmsg(111), GetRoomName(roomNo));
							errorflag = TRUE;
							}
						}
					}
				else
					{
					cPrintf(getnetmsg(139), deansi(netid));

					if (TI()node->IsAutoRoom() && !IsNetIDCorrupted(netid) &&
						!IsNetIDInNetIDCit(netid))
						{
						if (autoroom(netid))
							{
							cPrintf(getnetmsg(77));
							if (TI()node->IsVerbose(NCV_ROOMCREATED))
								{
								net69_error(TRUE, errorflag, TI()node->GetName(),
										getnetmsg(107), netid);
								errorflag = TRUE;
								}
							}
						else
							{
							cPrintf(getnetmsg(141));
							if (TI()node->IsVerbose(NCV_ROOMNOTCREATED))
								{
								net69_error(TRUE, errorflag, TI()node->GetName(),
										getnetmsg(108), netid);
								errorflag = TRUE;
								}
							}
						}
					else
						{
						cPrintf(getnetmsg(141));
						if (TI()node->IsVerbose(NCV_NETIDNOTFOUND))
							{
							net69_error(TRUE, errorflag, TI()node->GetName(),
									getnetmsg(109), netid);
							errorflag = TRUE;
							}
						}

					if (!((crcounter+1) % 2))
						{
						doccr();
						}

					crcounter++;
					}
				}

			fclose(roomreqfd);
			}
		else
			{
			doccr();

			for (roomNo = 0; roomNo < cfg.maxrooms; roomNo++)
				{
				KBReady();

				if (TI()CurrentUser->CanAccessRoom(roomNo) && GetRoomNetID(roomNo)[0] &&
						!TI()CurrentUser->IsRoomExcluded(roomNo) &&
						GetRoomNewMessages(roomNo))
					{
					cPrintf(getnetmsg(139), deansi(GetRoomName(roomNo)));

					msgsread = NewRoom(roomNo, NULL, msgfd);

					if (msgsread)
						{
						cPrintf(getnetmsg(140), msgsread);
						}
					else
						{
						cPrintf(getnetmsg(156), msgsread);
						}

					if (!((crcounter+1) % 2))
						{
						doccr();
						}
					crcounter++;
					}
				}
			}

		fclose(msgfd);

		doccr();
		doccr();
		cPrintf(getnetmsg(74), ltoac(TI()MS.Read),
				(TI()MS.Read == 1) ? cfg.Lmsg_nym : cfg.Lmsgs_nym);
		doccr();
		doccr();
		}

	char fullPathToMailFile[80];
	sprintf(fullPathToMailFile, sbs, cfg.transpath,
			TI()node->GetMailFileName());

	if (filexists(fullPathToMailFile))
		{
		char fullPathToMesgTmp[80];
		sprintf(fullPathToMesgTmp, sbs, cfg.temppath, mesgTmp);

		cPrintf(getnetmsg(78));
		doccr();
		doccr();

		if (copyfile(fullPathToMailFile, fullPathToMesgTmp))
			{
			unlink(fullPathToMailFile);
			}
		else
			{
			cPrintf(getnetmsg(42));
			doccr();
			doccr();
			}
		}

	TI()CurrentUser->SetPoopcount(TI()CurrentUser->GetPoopcount() + 1);

	char roomreqfilename[20];
	*roomreqfilename = 0;

	if (TI()node->GetRequest() &&
			!(TI()CurrentUser->GetPoopcount() % TI()node->GetRequest()))
		{
		changedir(cfg.temppath);

		net69_makeroomrequest();
		doccr();

		// how's sbroomreqPs + 3 for icky?
		//// it's extremely icky if you give it two parameters!
		sprintf(roomreqfilename, sbroomreqPs + 3, cfg.alias);
		}

	char fullPathToFile69[80];
	sprintf(fullPathToFile69, getnetmsg(157), cfg.transpath,
			TI()node->GetAlias());

	if (filexists(fullPathToFile69))
		{
		cPrintf(getnetmsg(79), fullPathToFile69);
		doccr();
		doccr();
		}
	else
		{
		*fullPathToFile69 = 0;
		}

	cPrintf(getnetmsg(80));
	doccr();
	doccr();

	changedir(cfg.temppath);

	char packetname[20];
	sprintf(packetname, getnetmsg(158), TI()node->GetAlias(), cfg.alias,
			TI()CurrentUser->GetPoopcount() % 1000);

	// Zip them up
	char filesToSend[128];

	if (needFull || TI()node->GetFetch() == 2)
		{
		sprintf(filesToSend, getnetmsg(159), msg69, mesgTmp, roomreqfilename,
				fullPathToFile69);
		}
	else
		{
		sprintf(filesToSend, getnetmsg(160), mesgTmp, roomreqfilename,
				fullPathToFile69);
		}

	char createCommandLine[256];
	sformat(createCommandLine, TI()node->GetCreatePacket(), getnetmsg(49),
			packetname, filesToSend);

	apsystem(createCommandLine, TRUE);
	changedir(cfg.temppath);

	// check to make sure it was really zipped - if you are out of memory,
	// and zip fails, netting becomes hosed.
	if (!filexists(packetname))
		{
		char *wo = createCommandLine;
		int superit = FALSE;

		while (*wo == '!' || *wo == '@' || *wo == '$' || *wo == '?' ||
				*wo == '*')
			{
			if (*wo == '!')
				{
				superit = TRUE;
				}
			wo++;
			}

		if (!superit)
			{
			char createCommandLine2[256];

			*createCommandLine2 = '!';
			strcpy(createCommandLine2 + 1, createCommandLine);

			apsystem(createCommandLine2, TRUE);
			changedir(cfg.temppath);
			}

		if (!filexists(packetname))
			{
			// either we already supershelled, or supershelling failed, too.
			cPrintf(getnetmsg(81));
			doccr();

			char fullPathToMesgTmp[80];
			sprintf(fullPathToMesgTmp, sbs, cfg.temppath, mesgTmp);

			if (filexists(fullPathToMesgTmp))
				{
				cPrintf(getnetmsg(82));
				doccr();
				doccr();

				copyfile(fullPathToMesgTmp, fullPathToMailFile);
				unlink(fullPathToMesgTmp);
				}

			unlink(msg69);
			unlink(roomreqfilename);

			if (TI()menu69)
				{
				TI()MS.Read = oldmread;
				}

			return (FALSE);
			}
		}

	cPrintf(getnetmsg(83), packetname);
	doccr();

	char fullPathToPacketInTrans[80], fullPathToPacketInTemp[80];
	sprintf(fullPathToPacketInTrans, sbs, cfg.transpath, packetname);
	sprintf(fullPathToPacketInTemp, sbs, cfg.temppath, packetname);

	if (copyfile(fullPathToPacketInTemp, fullPathToPacketInTrans))
		{
		changedir(cfg.temppath);
		unlink(mesgTmp);
		unlink(msg69);
		unlink(fullPathToPacketInTemp);
		unlink(roomreqfilename);
		unlink(fullPathToFile69);

		if (TI()menu69)
			{
			TI()MS.Read = oldmread;
			}

		return (TRUE);
		}
	else
		{
		doccr();
		cPrintf(getnetmsg(47));
		doccr();

		char fullPathToMesgTmp[80];
		sprintf(fullPathToMesgTmp, sbs, cfg.temppath, mesgTmp);

		if (filexists(fullPathToMesgTmp))
			{
			doccr();
			cPrintf(getnetmsg(82));
			doccr();

			copyfile(fullPathToMesgTmp, fullPathToMailFile);
			unlink(fullPathToMesgTmp);
			}

		changedir(cfg.temppath);
		unlink(msg69);
		unlink(roomreqfilename);

		if (TI()menu69)
			{
			TI()MS.Read = oldmread;
			}

		return (FALSE);
		}
	}

// NametoId() Converts Room name to network ID
void NametoId(char *string)
	{
	const r_slot slot = RoomExists(string);

	if (slot != CERROR)
		{
		strcpy(string, GetRoomNetID(slot));
		}
	else
		{
		*string = 0;
		}
	}
