// --------------------------------------------------------------------------
// Citadel: LogRdWr.CPP
//
// Log entry read/write stuff

#include "ctdl.h"
#pragma hdrstop

#include "log.h"
#include "msg.h"
#include "filerdwr.h"
#include "miscovl.h"


void LogStarter::OpenFile(void)
	{
	assert(this);

	if (!File)
		{
		char FullName[128];
		sprintf(FullName, sbs, cfg.homepath, FileName);

		File = fopen(FullName, FO_RPB);

		if (!File)
			{
			File = fopen(FullName, FO_WPB);
			}
		}
	}

void LogStarter::CloseFile(void)
	{
	assert(this);

	if (File)
		{
		fclose(File);
		File = NULL;
		}
	}

Bool LogEntry::Save(l_index Index) const
	{
	assert(this);
	Bool Good = FALSE;

	VerifyHeap();

	if (LogEntry1::Save(Index) && LogEntry2::Save(Index) &&
			LogEntry3::Save(Index) && LogEntry4::Save(Index) &&
			LogEntry5::Save(Index) && LogEntry6::Save(Index) &&
			LogExtensions::Save(Index, GetName()))
		{
		Good = TRUE;
		}

	VerifyHeap();
	return (Good);
	}

Bool LogEntry::Load(l_index Index)
	{
	assert(this);
	Bool Good = FALSE;

	VerifyHeap();

	if (LogEntry1::Load(Index) && LogEntry2::Load(Index) &&
			LogEntry3::Load(Index) && LogEntry4::Load(Index) &&
			LogEntry5::Load(Index) && LogEntry6::Load(Index) &&
			LogExtensions::Load(Index))
		{
		Good = TRUE;
		}

	VerifyHeap();
	return (Good);
	}

#include "datafile.h"

Bool LogEntry1::Save(l_index Index) const
	{
	assert(this);
	Bool Good = TRUE, WasOpen;
	FILE *fl;

	VerifyHeap();

	if (GetFile())
		{
		fl = GetFile();
		WasOpen = TRUE;
		}
	else
		{
		char file[128];
		sprintf(file, sbs, cfg.homepath, GetFileName());
		fl = fopen(file, FO_RPB);

		if (fl == NULL)
			{
			fl = fopen(file, FO_WPB);
			}

		WasOpen = FALSE;
		}

	if (fl != NULL)
		{
		LogDatStructure LD;
		long s;

		// fill up LD
		memset(&LD, 0, sizeof(LD));

		VerifyHeap();

		strcpy(LD.lbname,				GetName());
		strcpy(LD.lbin, 				GetInitials());
		strcpy(LD.lbpw, 				GetPassword());
		strcpy(LD.surname,				GetSurname());
		strcpy(LD.title,				GetTitle());
		strcpy(LD.realname, 			GetRealName());
		strcpy(LD.phonenum, 			GetPhoneNumber());

		strcpy(LD.forward,				GetForwardAddr());
		strcpy(LD.forward_node, 		GetForwardAddrNode());
		strcpy(LD.forward_region,		GetForwardAddrRegion());

		strcpy(LD.prompt,				GetPromptFormat());
		strcpy(LD.dstamp,				GetDateStamp());
		strcpy(LD.vdstamp,				GetVerboseDateStamp());
		strcpy(LD.signature,			GetSignature());
		strcpy(LD.netPrefix,			GetNetPrefix());
		strcpy(LD.addr1,				GetMailAddr1());
		strcpy(LD.addr2,				GetMailAddr2());
		strcpy(LD.addr3,				GetMailAddr3());
		strcpy(LD.alias,				GetAlias());
		strcpy(LD.locID,				GetLocID());
		strcpy(LD.moreprompt,			GetMorePrompt());
		strcpy(LD.occupation,			GetOccupation());
		strcpy(LD.wherehear,			GetWhereHear());
		strcpy(LD.lastRoom, 			GetLastRoom());
		strcpy(LD.lastHall, 			GetLastHall());
		strcpy(LD.defaultRoom,			GetDefaultRoom());
		strcpy(LD.defaultHall,			GetDefaultHall());

		LD.birthdate =					GetBirthDate();
		LD.firston =					GetFirstOn();
		LD.male =						GetSex();

		LD.lbnulls =					GetNulls();
		LD.lbwidth =					GetWidth();
		LD.linesScreen =				GetLinesPerScreen();

		LD.attributes[ATTR_BOLD] =		GetAttribute(ATTR_BOLD);
		LD.attributes[ATTR_BLINK] = 	GetAttribute(ATTR_BLINK);
		LD.attributes[ATTR_NORMAL] =	GetAttribute(ATTR_NORMAL);
		LD.attributes[ATTR_REVERSE] =	GetAttribute(ATTR_REVERSE);
		LD.attributes[ATTR_UNDERLINE] = GetAttribute(ATTR_UNDERLINE);

		LD.numUserShow =				GetNumUserShow();
		LD.protocol =					GetDefaultProtocol();

		LD.calltime =					GetCallTime();
		LD.callno = 					GetCallNumber();
		LD.totaltime =					GetTotalTime();
		LD.credits =					GetCredits();
		LD.logins = 					GetLogins();
		LD.posted = 					GetPosted();
		LD.read =						GetRead();
		LD.pwChange =					GetPasswordChangeTime();
		LD.callsToday = 				GetCallsToday();
		LD.callLimit =					GetCallLimit();

		LD.lastpointer =				GetLastMessage();

		LD.dl_bytes =					GetDL_Bytes();
		LD.ul_bytes =					GetUL_Bytes();
		LD.dl_num = 					GetDL_Num();
		LD.ul_num = 					GetUL_Num();

		LD.poopcount =					GetPoopcount();

		LD.DUNGEONED =					IsDungeoned();
		LD.FORtOnODE =					IsForwardToNode();
		LD.NEXTHALL =					IsAutoNextHall();
		LD.BORDERS =					IsEnterBorders();
		LD.VERIFIED =					!IsVerified();
		LD.SURNAMLOK =					IsSurnameLocked();
		LD.LOCKHALL =					IsDefaultHallLocked();
		LD.PSYCHO = 					IsPsycho();
		LD.DISPLAYTS =					IsViewTitleSurname();
		LD.SUBJECTS =					IsViewSubjects();
		LD.SIGNATURES = 				IsViewSignatures();
		LD.IBMGRAPH =					IsIBMGraph();
		LD.IBMANSI =					IsIBMANSI();
		LD.IBMCOLOR =					IsIBMColor();
		LD.TWIRLY = 					IsTwirly();
		LD.VERBOSE =					IsAutoVerbose();
		LD.MSGPAUSE =					IsPauseBetweenMessages();
		LD.MINIBIN =					IsMinibin();
		LD.MSGCLS = 					IsClearScreenBetweenMessages();
		LD.ROOMINFO =					IsViewRoomInfoLines();
		LD.HALLTELL =					IsViewHallDescription();
		LD.VERBOSECONT =				IsVerboseContinue();
		LD.VIEWCENSOR = 				IsViewCensoredMessages();
		LD.SEEBORDERS = 				IsViewBorders();
		LD.OUT300 = 					IsOut300();
		LD.LOCKUSIG =					IsUserSignatureLocked();
		LD.HIDEEXCL =					IsHideMessageExclusions();
		LD.NODOWNLOAD = 				!IsDownload();
		LD.NOUPLOAD =					!IsUpload();
		LD.NOCHAT = 					!IsChat();
		LD.PRINTFILE =					IsPrintFile();
		LD.spellCheck = 				GetSpellCheckMode();
		LD.NOMAKEROOM = 				!IsMakeRoom();
		LD.VERBOSELO =					IsVerboseLogOut();
		LD.CONFIRMSAVE =				IsConfirmSave();
		LD.NOCONFABORT =				!IsConfirmAbort();
		LD.CONFIRMNOEO =				IsConfirmNoEO();
		LD.USEPERSONAL =				IsUsePersonalHall();
		LD.YOUAREHERE = 				IsYouAreHere();
		LD.IBMROOM =					IsIBMRoom();
		LD.WIDEROOM =					IsWideRoom();
		LD.MUSIC =						IsMusic();
		LD.CHECKAPS =					IsCheckApostropheS();
		LD.CHECKALLCAP =				IsCheckAllCaps();
		LD.CHECKDIGITS =				IsCheckDigits();
		LD.EXCLUDECRYPT =				IsExcludeEncryptedMessages();
		LD.HIDECOMMAS = 				!IsViewCommas();
		LD.PUNPAUSES =					IsPUnPauses();
		LD.ROMAN =						IsRoman();

		LD.lbflags.L_INUSE =			IsInuse();
		LD.lbflags.UCMASK = 			IsUpperOnly();
		LD.lbflags.LFMASK = 			IsLinefeeds();
		LD.lbflags.EXPERT = 			IsExpert();
		LD.lbflags.AIDE =				IsAide();
		LD.lbflags.TABS =				IsTabs();
		LD.lbflags.OLDTOO = 			IsOldToo();
		LD.lbflags.PROBLEM =			IsProblem();
		LD.lbflags.UNLISTED =			IsUnlisted();
		LD.lbflags.PERMANENT =			IsPermanent();
		LD.lbflags.SYSOP =				IsSysop();
		LD.lbflags.NODE =				IsNode();
		LD.lbflags.NETUSER =			IsNetUser();
		LD.lbflags.NOACCOUNT =			!IsAccounting();
		LD.lbflags.NOMAIL = 			!IsMail();
		LD.lbflags.ROOMTELL =			IsViewRoomDesc();

		LD.LastCalledVersion =			NumericVer;

		VerifyHeap();

		s = (long) Index * (long) sizeof(LD) + sizeof(long);

		fseek(fl, s, SEEK_SET);

		if (fwrite(&LD, sizeof(LD), 1, fl) != 1)
			{
			mPrintf(getmsg(661), GetFileName());
			Good = FALSE;
			}

		if (SameString(GetFileName(), logDat))
			{
			LogTab->UpdateTable(this, Index);
			}

		if (!WasOpen)
			{
			fclose(fl);
			}
		}
	else
		{
		mPrintf(getmsg(78), GetFileName());
		Good = FALSE;
		}

	VerifyHeap();
	return (Good);
	}

Bool LogEntry1::Load(l_index Index)
	{
	assert(this);
	Bool Good = TRUE, WasOpen;
	FILE *fl;

	if (GetFile())
		{
		fl = GetFile();
		WasOpen = TRUE;
		}
	else
		{
		char file[128];
		sprintf(file, sbs, cfg.homepath, GetFileName());
		fl = fopen(file, FO_RB);

		WasOpen = FALSE;
		}

	if (fl != NULL)
		{
		struct LogDatStructure LD;
		long s;

		s = (long) Index * (long) sizeof(LD) + sizeof(long);

		fseek(fl, s, SEEK_SET);

		VerifyHeap();
		if (fread(&LD, sizeof(LD), 1, fl) != 1)
			{
			mPrintf(getmsg(83), GetFileName());
			Good = FALSE;
			}
		VerifyHeap();

		if (!WasOpen)
			{
			fclose(fl);
			}

		if (Good)
			{
			// now, copy it... oh boy
			Clear();

			SetName(LD.lbname);
			SetInitials(LD.lbin);
			SetPassword(LD.lbpw);
			SetSurname(LD.surname);
			SetTitle(LD.title);
			SetRealName(LD.realname);
			SetPhoneNumber(LD.phonenum);

			SetForwardAddr(LD.forward);
			SetForwardAddrNode(LD.forward_node);
			SetForwardAddrRegion(LD.forward_region);

			SetPromptFormat(LD.prompt);
			SetDateStamp(LD.dstamp);
			SetVerboseDateStamp(LD.vdstamp);
			SetSignature(LD.signature);
			SetNetPrefix(LD.netPrefix);
			SetMailAddr1(LD.addr1);
			SetMailAddr2(LD.addr2);
			SetMailAddr3(LD.addr3);
			SetAlias(LD.alias);
			SetLocID(LD.locID);
			SetMorePrompt(LD.moreprompt);
			SetOccupation(LD.occupation);
			SetWhereHear(LD.wherehear);
			SetLastRoom(LD.lastRoom);
			SetLastHall(LD.lastHall);
			SetDefaultRoom(LD.defaultRoom);
			SetDefaultHall(LD.defaultHall);

			SetBirthDate(LD.birthdate);
			SetFirstOn(LD.firston);
			SetSex(LD.male);

			SetNulls(LD.lbnulls);
			SetWidth(LD.lbwidth);
			SetLinesPerScreen(LD.linesScreen);

			SetAttribute(ATTR_BOLD, LD.attributes[ATTR_BOLD]);
			SetAttribute(ATTR_BLINK, LD.attributes[ATTR_BLINK]);
			SetAttribute(ATTR_NORMAL, LD.attributes[ATTR_NORMAL]);
			SetAttribute(ATTR_REVERSE, LD.attributes[ATTR_REVERSE]);
			SetAttribute(ATTR_UNDERLINE, LD.attributes[ATTR_UNDERLINE]);

			SetNumUserShow(LD.numUserShow);
			SetDefaultProtocol(LD.protocol);

			SetCallTime(LD.calltime);
			SetCallNumber(LD.callno);
			SetTotalTime(LD.totaltime);
			SetCredits(LD.credits);
			SetLogins(LD.logins);
			SetPosted(LD.posted);
			SetRead(LD.read);
			SetPasswordChangeTime(LD.pwChange);
			SetCallsToday(LD.callsToday);
			SetCallLimit(LD.callLimit);

			SetLastMessage(LD.lastpointer);

			SetDL_Bytes(LD.dl_bytes);
			SetUL_Bytes(LD.ul_bytes);
			SetDL_Num(LD.dl_num);
			SetUL_Num(LD.ul_num);

			SetPoopcount(LD.poopcount);

			SetDungeoned(LD.DUNGEONED);
			SetForwardToNode(LD.FORtOnODE);
			SetAutoNextHall(LD.NEXTHALL);
			SetEnterBorders(LD.BORDERS);
			SetVerified(!LD.VERIFIED);
			SetSurnameLocked(LD.SURNAMLOK);
			SetDefaultHallLocked(LD.LOCKHALL);
			SetPsycho(LD.PSYCHO);
			SetViewTitleSurname(LD.DISPLAYTS);
			SetViewSubjects(LD.SUBJECTS);
			SetViewSignatures(LD.SIGNATURES);
			SetIBMGraph(LD.IBMGRAPH);
			SetIBMANSI(LD.IBMANSI);
			SetIBMColor(LD.IBMCOLOR);
			SetTwirly(LD.TWIRLY);
			SetAutoVerbose(LD.VERBOSE);
			SetPauseBetweenMessages(LD.MSGPAUSE);
			SetMinibin(LD.MINIBIN);
			SetClearScreenBetweenMessages(LD.MSGCLS);
			SetViewRoomInfoLines(LD.ROOMINFO);
			SetViewHallDescription(LD.HALLTELL);
			SetVerboseContinue(LD.VERBOSECONT);
			SetViewCensoredMessages(LD.VIEWCENSOR);
			SetViewBorders(LD.SEEBORDERS);
			SetOut300(LD.OUT300);
			SetUserSignatureLocked(LD.LOCKUSIG);
			SetHideMessageExclusions(LD.HIDEEXCL);
			SetDownload(!LD.NODOWNLOAD);
			SetUpload(!LD.NOUPLOAD);
			SetChat(!LD.NOCHAT);
			SetPrintFile(LD.PRINTFILE);
			SetSpellCheckMode(LD.spellCheck);
			SetMakeRoom(!LD.NOMAKEROOM);
			SetVerboseLogOut(LD.VERBOSELO);
			SetConfirmSave(LD.CONFIRMSAVE);
			SetConfirmAbort(!LD.NOCONFABORT);
			SetConfirmNoEO(LD.CONFIRMNOEO);
			SetUsePersonalHall(LD.USEPERSONAL);
			SetYouAreHere(LD.YOUAREHERE);
			SetIBMRoom(LD.IBMROOM);
			SetWideRoom(LD.WIDEROOM);
			SetMusic(LD.MUSIC);
			SetCheckApostropheS(LD.CHECKAPS);
			SetCheckAllCaps(LD.CHECKALLCAP);
			SetCheckDigits(LD.CHECKDIGITS);
			SetExcludeEncryptedMessages(LD.EXCLUDECRYPT);
			SetViewCommas(!LD.HIDECOMMAS);
			SetPUnPauses(LD.PUNPAUSES);
			SetRoman(LD.ROMAN);


			SetInuse(LD.lbflags.L_INUSE);
			SetUpperOnly(LD.lbflags.UCMASK);
			SetLinefeeds(LD.lbflags.LFMASK);
			SetExpert(LD.lbflags.EXPERT);
			SetAide(LD.lbflags.AIDE);
			SetTabs(LD.lbflags.TABS);
			SetOldToo(LD.lbflags.OLDTOO);
			SetProblem(LD.lbflags.PROBLEM);
			SetUnlisted(LD.lbflags.UNLISTED);
			SetPermanent(LD.lbflags.PERMANENT);
			SetSysop(LD.lbflags.SYSOP);
			SetNode(LD.lbflags.NODE);
			SetNetUser(LD.lbflags.NETUSER);
			SetAccounting(!LD.lbflags.NOACCOUNT);
			SetMail(!LD.lbflags.NOMAIL);
			SetViewRoomDesc(LD.lbflags.ROOMTELL);

			// MorePrompt started being used in version 65074
			if (LD.LastCalledVersion < 65074l)
				{
				SetMorePrompt(cfg.moreprompt);
				}
			}
		}
	else
		{
		mPrintf(getmsg(78), GetFileName());
		Good = FALSE;
		}

	VerifyHeap();
	return (Good);
	}

Bool LogBitBag::Save(l_index Index) const
	{
	assert(this);
	VerifyHeap();

	Bool Good = TRUE;

	if (IsValid())
		{
		FILE *fl;
		Bool WasOpen;

		if (GetFile())
			{
			fl = GetFile();
			WasOpen = TRUE;
			}
		else
			{
			char file[128];
			sprintf(file, sbs, cfg.homepath, GetFileName());
			fl = fopen(file, FO_RPB);

			if (fl == NULL)
				{
				fl = fopen(file, FO_WPB);
				}

			WasOpen = FALSE;
			}

		if (fl != NULL)
			{
			fseek(fl, (long) Index * (long) GetSize(), SEEK_SET);

			if (fwrite(GetPointer(), 1, GetSize(), fl) != GetSize())
				{
				mPrintf(getmsg(661), GetFileName());
				Good = FALSE;
				}

			if (!WasOpen)
				{
				fclose(fl);
				}
			}
		else
			{
			mPrintf(getmsg(78), GetFileName());
			Good = FALSE;
			}
		}
	else
		{
		Good = FALSE;
		}

	VerifyHeap();
	return (Good);
	}

Bool LogBitBag::Load(l_index Index)
	{
	assert(this);
	VerifyHeap();
	Bool Good = TRUE;

	if (IsValid())
		{
		FILE *fl;
		Bool WasOpen;

		if (GetFile())
			{
			fl = GetFile();
			WasOpen = TRUE;
			}
		else
			{
			char file[128];
			sprintf(file, sbs, cfg.homepath, GetFileName());
			fl = fopen(file, FO_RB);

			WasOpen = FALSE;
			}

		if (fl != NULL)
			{
			fseek(fl, (long) Index * (long) GetSize(), SEEK_SET);

			if (fread(GetNCPointer(), 1, GetSize(), fl) != GetSize())
				{
				mPrintf(getmsg(83), GetFileName());
				Good = FALSE;
				}

			if (!WasOpen)
				{
				fclose(fl);
				}
			}
		else
			{
			mPrintf(getmsg(78), GetFileName());
			Good = FALSE;
			}
		}
	else
		{
		Good = FALSE;
		}

	VerifyHeap();
	return (Good);
	}

Bool LogEntry5::Save(l_index Index) const
	{
	assert(this);
	VerifyHeap();
	Bool Good = TRUE;

	if (IsValid())
		{
		FILE *fl;
		Bool WasOpen;

		if (GetFile())
			{
			fl = GetFile();
			WasOpen = TRUE;
			}
		else
			{
			char file[128];
			sprintf(file, sbs, cfg.homepath, GetFileName());
			fl = fopen(file, FO_RPB);

			if (fl == NULL)
				{
				fl = fopen(file, FO_WPB);
				}

			WasOpen = FALSE;
			}

		if (fl != NULL)
			{
			long s;

			s = (long) Index * (long) sizeof(*NewPointer) * MaxRooms;

			fseek(fl, s, SEEK_SET);

			if (fwrite(NewPointer, sizeof(*NewPointer), MaxRooms, fl) !=
					MaxRooms)
				{
				mPrintf(getmsg(661), GetFileName());
				Good = FALSE;
				}

			if (!WasOpen)
				{
				fclose(fl);
				}
			}
		else
			{
			mPrintf(getmsg(78), GetFileName());
			Good = FALSE;
			}
		}
	else
		{
		Good = FALSE;
		}

	VerifyHeap();
	return (Good);
	}

Bool LogEntry5::Load(l_index Index)
	{
	assert(this);
	VerifyHeap();
	Bool Good = TRUE;

	if (IsValid())
		{
		FILE *fl;
		Bool WasOpen;

		if (GetFile())
			{
			fl = GetFile();
			WasOpen = TRUE;
			}
		else
			{
			char file[128];
			sprintf(file, sbs, cfg.homepath, GetFileName());
			fl = fopen(file, FO_RB);

			WasOpen = FALSE;
			}

		if (fl != NULL)
			{
			long s;

			s = (long) Index * (long) sizeof(*NewPointer) * MaxRooms;

			fseek(fl, s, SEEK_SET);

			if (fread(NewPointer, sizeof(*NewPointer), MaxRooms, fl) !=
					MaxRooms)
				{
				mPrintf(getmsg(83), GetFileName());
				Good = FALSE;
				}

			if (!WasOpen)
				{
				fclose(fl);
				}
			}
		else
			{
			mPrintf(getmsg(78), GetFileName());
			Good = FALSE;
			}
		}
	else
		{
		Good = FALSE;
		}

	VerifyHeap();
	return (Good);
	}

Bool LogExtensions::Save(l_slot Slot, const char *Name) const
	{
	assert(this);
	VerifyHeap();
	Bool Good = TRUE;

	char lbuf[128], wow[128], wow2[256];
	FILE *fd;
	strList *theStr;
	pairedStrings *thePair;

	sprintf(lbuf, getmsg(1519), cfg.logextdir, Slot, FileExtension);

	if ((fd = fopen(lbuf, FO_W)) != NULL)
		{
		if (Name)
			{
			fprintf(fd, getmsg(750), Name, bn, bn, ns);
			}

		Bool Written = FALSE;
		int i;

		for (theStr = le_kuser; theStr;
				theStr = (strList *) getNextLL(theStr))
			{
			if (fprintf(fd, getmsg(1520), logextensions[LE_KUSER],
					mkDblBck(theStr->string, wow), bn) == EOF)
				{
				Good = FALSE;
				}

			Written = TRUE;
			}

		for (theStr = le_knode; theStr;
				theStr = (strList *) getNextLL(theStr))
			{
			if (fprintf(fd, getmsg(1520), logextensions[LE_KNODE],
					mkDblBck(theStr->string, wow), bn) == EOF)
				{
				Good = FALSE;
				}

			Written = TRUE;
			}

		for (theStr = le_ktext; theStr;
				theStr = (strList *) getNextLL(theStr))
			{
			if (fprintf(fd, getmsg(1520), logextensions[LE_KTEXT],
					mkDblBck(theStr->string, wow), bn) == EOF)
				{
				Good = FALSE;
				}

			Written = TRUE;
			}

		for (theStr = le_kreg; theStr;
				theStr = (strList *) getNextLL(theStr))
			{
			if (fprintf(fd, getmsg(1520), logextensions[LE_KREG],
					mkDblBck(theStr->string, wow), bn) == EOF)
				{
				Good = FALSE;
				}

			Written = TRUE;
			}

		for (thePair = le_tuser; thePair;
				thePair = (pairedStrings *) getNextLL(thePair))
			{
			if (fprintf(fd, getmsg(1521), logextensions[LE_TUSER],
					mkDblBck(thePair->string1, wow),
					mkDblBck(thePair->string2, wow2), bn) == EOF)
				{
				Good = FALSE;
				}

			Written = TRUE;
			}

		for (thePair = le_replace; thePair;
				thePair = (pairedStrings *) getNextLL(thePair))
			{
			if (fprintf(fd, getmsg(1521), logextensions[LE_REPLACE],
					mkDblBck(thePair->string1, wow),
					mkDblBck(thePair->string2, wow2), bn) == EOF)
				{
				Good = FALSE;
				}

			Written = TRUE;
			}

		for (theStr = le_dict; theStr;
				theStr = (strList *) getNextLL(theStr))
			{
			if (fprintf(fd, getmsg(1520), logextensions[LE_DICTWORD],
					mkDblBck(theStr->string, wow), bn) == EOF)
				{
				Good = FALSE;
				}

			Written = TRUE;
			}

		for (userDefLE *theDef = le_userdef; theDef;
				theDef = (userDefLE *) getNextLL(theDef))
			{
			if (fprintf(fd, getmsg(1521), logextensions[LE_USERDEF],
					mkDblBck(theDef->Code, wow),
					mkDblBck(theDef->Data, wow2), bn) == EOF)
				{
				Good = FALSE;
				}

			Written = TRUE;
			}

		if (cfg.SaveJB)
			{
			for (i = (jb_start + 1) % cfg.maxjumpback;
					i != (jb_end + 1) % cfg.maxjumpback;
					i = (i + 1) % cfg.maxjumpback)
				{
				if (fprintf(fd, getmsg(1522),
						logextensions[LE_JUMPBACK], jb[i].newpointer,
						(ulong) jb[i].newMsgs, jb[i].hall, jb[i].room,
						jb[i].bypass, bn) == EOF)
					{
					Good = FALSE;
					}

				Written = TRUE;
				}
			}

		if (Msg)
			{
			if (fprintf(fd, getmsg(1523), logextensions[LE_MESSAGE],
					TI()thisRoom, bn) == EOF)
				{
				Good = FALSE;
				}

			Msg->Store(SMC_LESAVE, fd);

			if (fprintf(fd, bn) == EOF)
				{
				Good = FALSE;
				}

			Written = TRUE;
			}

		if (le_Finger)
			{
			if ((fprintf(fd, getmsg(1524), logextensions[LE_FINGER], bn) == EOF) ||
					(fwrite(le_Finger, sizeof(char), strlen(le_Finger) + 1,
					fd) != strlen(le_Finger) +1) || (fprintf(fd, bn) == EOF))
				{
				Good = FALSE;
				}

			Written = TRUE;
			}

		fclose(fd);

		if (!Written)
			{
			unlink(lbuf);
			}
		}
	else
		{
		Good = FALSE;
		}

	VerifyHeap();
	return (Good);
	}

Bool LogExtensions::Load(l_slot Slot)
	{
	Bool Good = TRUE;
	assert(this);
	VerifyHeap();

	char lbuf[128], line[384];
	char *words[256];
	int i;
	FILE *fd;

	Clear();

	compactMemory();

	sprintf(lbuf, getmsg(1519), cfg.logextdir, Slot, FileExtension);

	if ((fd = fopen(lbuf, FO_R)) != NULL)
		{
		while (fgets(line, sizeof(line), fd) != NULL)
			{
			if (line[0] != '#')
				{
				continue;
				}

			parse_it(words, line);

			for (i = 0; i < MAXLOGEXT; i++)
				{
				if (SameString(words[0] + 1, logextensions[i]))
					{
					break;
					}
				}

			switch (i)
				{
				case LE_MESSAGE:
					{
					Msg = new Message;

					if (Msg)
						{
						Msg->ReadAll(RMC_NETWORK, fd);
						MsgRoom = atoi(words[1]);
						}
					else
						{
						mPrintf(getmsg(188), getmsg(286));
						}

					break;
					}

				case LE_KUSER:
					{
					if (!AddKillUser(words[1]))
						{
						mPrintf(getmsg(188), getmsg(286));
						}

					break;
					}

				case LE_KNODE:
					{
					if (!AddKillNode(words[1]))
						{
						mPrintf(getmsg(188), getmsg(286));
						}

					break;
					}

				case LE_KTEXT:
					{
					if (!AddKillText(words[1]))
						{
						mPrintf(getmsg(188), getmsg(286));
						}

					break;
					}

				case LE_KREG:
					{
					if (!AddKillRegion(words[1]))
						{
						mPrintf(getmsg(188), getmsg(286));
						}

					break;
					}

				case LE_TUSER:
					{
					if (!AddTagUser(words[1], words[2]))
						{
						mPrintf(getmsg(188), getmsg(286));
						}

					break;
					}

				case LE_REPLACE:
					{
					if (!AddReplace(words[1], words[2]))
						{
						mPrintf(getmsg(188), getmsg(286));
						}

					break;
					}

				case LE_DICTWORD:
					{
					if (!AddWordToDictionary(words[1]))
						{
						mPrintf(getmsg(188), getmsg(286));
						}

					break;
					}

				case LE_USERDEF:
					{
					if (!SetUserDefined(words[1], words[2]))
						{
						mPrintf(getmsg(188), getmsg(286));
						}

					break;
					}

				case LE_JUMPBACK:
					{
					if (jb_length)
						{
						jb_end = ++jb_end % jb_length;

						if (jb_end == jb_start)
							{
							jb_start++;
							}

						jb[jb_end].newpointer = atol(words[1]);
						jb[jb_end].newMsgs = (m_slot) atol(words[2]);
						jb[jb_end].hall = atoi(words[3]);
						jb[jb_end].room = atoi(words[4]);
						jb[jb_end].bypass = atoi(words[5]);
						}

					break;
					}

				case LE_FINGER:
					{
					char *Buffer = new char[MAXTEXT];

					if (Buffer)
						{
						if (GetStr(fd, Buffer, MAXTEXT - 1))
							{
							SetFinger(Buffer);
							}

						delete [] Buffer;
						}
					else
						{
						mPrintf(getmsg(188), getmsg(71));
						}

					break;
					}

				default:
					{
					mPrintfCR(getmsg(345), words[0]);
					break;
					}
				}
			}

		fclose(fd);
		}

	VerifyHeap();
	return (Good);
	}
