/* -------------------------------------------------------------------- */
/*	OPENFILE.CPP				Citadel 								*/
/* -------------------------------------------------------------------- */
#include "ctdl.h"
#pragma hdrstop

#include "config.h"
#include "resize.h"
#include "datafile.h"
#include "room.h"
#include "roompriv.h"
#include "group.h"
#include "hall.h"

/* -------------------------------------------------------------------- */
/*	openFile()			Special to open a .CIT file 					*/
/*	checkresize()		checks to see if files need to be resized.		*/
/*	autoConvert()		up/downsizes .DAT files 						*/
/*	initfiles() 		initializes files, opens them					*/
/* -------------------------------------------------------------------- */

extern Bool resizeMsg, resizeLog, resizeGrp, resizeRoom, resizeHall;

/* -------------------------------------------------------------------- */
/*	openFile()		Special to open a .DAT file 						*/
/* -------------------------------------------------------------------- */
void openFile(const char *filename, citFILE *fd)
	{
	/* open file */
	if (!citOpen(filename, CO_RPB, fd))
		{
		crashout(getmsg(1121), filename, errno);
		}
	}

/* -------------------------------------------------------------------- */
/*	checkresize()		checks to see if files need to be resized.		*/
/* -------------------------------------------------------------------- */
static void checkresize(void)
	{
	int fh;
	long result;

	/* save old values for later */
	newmessagek = cfg.messagek;
	newmaxrooms = cfg.maxrooms;
	newmaxhalls = cfg.maxhalls;
	newmaxlogtab = cfg.MAXLOGTAB;
	newmaxgroups = cfg.maxgroups;

	/* check message file */
	fh = open(msgFile, O_RDONLY);
	if (fh != -1)
		{
		if ((result = filelength(fh)) == 0)
			{
			close(fh);
			unlink(msgFile);
			}
		else if (result != ((long) cfg.messagek * 1024l))
			{
			resizeMsg = TRUE;
			errorDisp(getcfgmsg(139), msgDat);
			doccr();

			/* set messagek to actual value */
			cfg.messagek = result / 1024l;
			close(fh);
			}
		else
			{
			close(fh);
			}
		}

	/* check log file */
	fh = open(logDat, O_RDONLY);
	if (fh != -1)
		{
		if ((result = filelength(fh)) == 0)
			{
			close(fh);
			unlink(logDat);
			unlink(log2Dat);
			unlink(log3Dat);
			unlink(log4Dat);
			unlink(log5Dat);
			unlink(log6Dat);
			}
		else if (result != ((long) cfg.MAXLOGTAB *
				(long) sizeof (LogDatStructure)) + sizeof(long))
			{
			resizeLog = TRUE;
			errorDisp(getcfgmsg(139), logDat);
			doccr();

			/* set MAXLOGTAB to actual value */
			cfg.MAXLOGTAB = (int) ((result - sizeof(long)) /
					(long) sizeof(LogDatStructure));
			close(fh);
			}
		else
			{
			close(fh);
			}
		}

	/* check group file */
	fh = open(grpDat, O_RDONLY);
	if (fh != -1)
		{
		if ((result = filelength(fh)) == 0)
			{
			close(fh);
			unlink(grpDat);
			}
		else if (result != ((long) cfg.maxgroups * (long) sizeof(GroupEntry)) + sizeof(long))
			{
			resizeGrp = TRUE;
			errorDisp(getcfgmsg(139), grpDat);
			doccr();

			/* set maxgroups to actual value */
			cfg.maxgroups = (int) ((result - sizeof(long)) /
					(long) sizeof(GroupEntry));
			close(fh);
			}
		else
			{
			close(fh);
			}
		}

	/* check room file */
	fh = open(roomDat, O_RDONLY);
	if (fh != -1)
		{
		if ((result = filelength(fh)) == 0)
			{
			close(fh);
			unlink(roomDat);
			}
		else if (result != ((long) cfg.maxrooms * (long) sizeof (aRoom)) + sizeof(long))
			{
			resizeRoom = TRUE;
			errorDisp(getcfgmsg(139), roomDat);
			doccr();

			/* set maxrooms to actual value */
			cfg.maxrooms = (int) ((result - sizeof(long)) /
					(long) sizeof(aRoom));
			close(fh);
			}
		else
			{
			close(fh);
			}
		}

	/* check hall file */
	fh = open(hallDat, O_RDONLY);
	if (fh != -1)
		{
		if ((result = filelength(fh)) == 0)
			{
			close(fh);
			unlink(hallDat);
			unlink(hall2Dat);
			}
		else if (result != (long) cfg.maxhalls * (long) sizeof(HallEntry1) +
				sizeof(long))
			{
			resizeHall = TRUE;
			errorDisp(getcfgmsg(139), hallDat);
			doccr();

			/* set maxhalls to actual value */
			cfg.maxhalls = (int) ((result - sizeof(long)) /
					(long) sizeof(HallEntry1));
			close(fh);
			}
		else
			{
			close(fh);
			}
		}

	if (resizeMsg || resizeLog || resizeRoom || resizeGrp || resizeHall)
		{
		doccr();
		pause(200);
		}
	}

/* -------------------------------------------------------------------- */
/*	autoConvert()		up/downsizes .DAT files 						*/
/* -------------------------------------------------------------------- */
static void autoConvert(const char *fname, long size)
	{
	FILE *fl;
	long l;

	if ((fl = fopen(fname, FO_RPB)) != NULL)
		{
		fread(&l, sizeof(l), 1, fl);

		if (l != size)
			{
			FILE *fl2;
			const char *tmp = getcfgmsg(137);

			if ((fl2 = fopen(tmp, FO_WPB)) != NULL)
				{
				char *buf;
				int bufsize = (int) max(l, size);

				buf = new char[bufsize];

				if (buf)
					{
					int cnt = 0;

					fwrite(&size, sizeof(size), 1, fl2);

					while (!feof(fl))
						{
						memset(buf, 0, bufsize);

						if (fread(buf, 1, (int) l, fl) == l)
							{
							cPrintf(br);
							cPrintf(getcfgmsg(138), fname, ltoac(++cnt));

							fwrite(buf, 1, (int) size, fl2);
							}
						}

					doccr();
					doccr();
					delete [] buf;
					}
				else
					{
					crashout(getmsg(188), getcfgmsg(203));
					}

				fclose(fl2);
				fclose(fl);

				unlink(fname);
				rename(tmp, fname);
				unlink(tmp);

				return; // avoid the fclose down there
				}
			else
				{
				crashout(getmsg(8), tmp);
				}
			}

		fclose(fl);
		}
	}

/* -------------------------------------------------------------------- */
/*	initfiles() 		initializes files, opens them					*/
/* -------------------------------------------------------------------- */
Bool initfiles(void)
	{
	citFILE aFile;

	changedir(cfg.homepath);

	if (cfg.msgpath[(strlen(cfg.msgpath) - 1)] == '\\')
		{
		cfg.msgpath[(strlen(cfg.msgpath) - 1)] = 0;
		}

	sprintf(msgFile, sbs, cfg.msgpath, msgDat);

	autoConvert(grpDat, sizeof(GroupEntry));
	autoConvert(logDat, sizeof(LogDatStructure));
	autoConvert(hallDat, sizeof(HallEntry1));
	autoConvert(roomDat, sizeof(aRoom));

	checkresize();

	/* check group file */
	if (!citOpen(grpDat, CO_RPB, &aFile))
		{
		errorDisp(getcfgmsg(140), grpDat);
		doccr();
		errorDisp(getcfgmsg(141));
		doccr();
		doccr();
		grpZap = TRUE;
		}
	else
		{
		citClose(&aFile);
		}

	/* check hall file */
	if (!citOpen(hallDat, CO_RPB, &aFile))
		{
		errorDisp(getcfgmsg(140), hallDat);
		doccr();
		errorDisp(getcfgmsg(141));
		doccr();
		doccr();
		hallZap = TRUE;
		}
	else
		{
		citClose(&aFile);
		}

	/* check room pos file */
	if (!citOpen(roomposDat, CO_RPB, &aFile))
		{
		errorDisp(getcfgmsg(140), roomposDat);
		doccr();
		errorDisp(getcfgmsg(141));
		doccr();
		doccr();
		roomposZap = TRUE;
		}
	else
		{
		citClose(&aFile);
		}

	/* open log file */
	if (!citOpen(logDat, CO_RPB, &aFile))
		{
		errorDisp(getcfgmsg(140), logDat);
		doccr();
		errorDisp(getcfgmsg(141));
		doccr();
		logZap = TRUE;
		}
	else
		{
		citClose(&aFile);
		}

	/* open log2 file */
	if (!citOpen(log2Dat, CO_RPB, &aFile))
		{
		errorDisp(getcfgmsg(140), log2Dat);
		doccr();
		errorDisp(getcfgmsg(141));
		doccr();
		log2Zap = TRUE;
		}
	else
		{
		citClose(&aFile);
		}

	/* open log3 file */
	if (!citOpen(log3Dat, CO_RPB, &aFile))
		{
		errorDisp(getcfgmsg(140), log3Dat);
		doccr();
		errorDisp(getcfgmsg(141));
		doccr();
		log3Zap = TRUE;
		}
	else
		{
		citClose(&aFile);
		}

	/* open log4 file */
	if (!citOpen(log4Dat, CO_RPB, &aFile))
		{
		errorDisp(getcfgmsg(140), log4Dat);
		doccr();
		errorDisp(getcfgmsg(141));
		doccr();
		log4Zap = TRUE;
		}
	else
		{
		citClose(&aFile);
		}

	/* open log5 file */
	if (!citOpen(log5Dat, CO_RPB, &aFile))
		{
		errorDisp(getcfgmsg(140), log5Dat);
		doccr();
		errorDisp(getcfgmsg(141));
		doccr();
		log5Zap = TRUE;
		}
	else
		{
		citClose(&aFile);
		}

	/* open log6 file */
	if (!citOpen(log6Dat, CO_RPB, &aFile))
		{
		errorDisp(getcfgmsg(140), log6Dat);
		doccr();
		errorDisp(getcfgmsg(141));
		doccr();
		log6Zap = TRUE;
		}
	else
		{
		citClose(&aFile);
		}


	if (logZap || log2Zap || log3Zap || log4Zap || log5Zap || log6Zap)
		{
		doccr();
		}

	/* open message file */
	if ((msgfl = bufferedOpen(msgFile)) == NULL)
		{
		errorDisp(getcfgmsg(140), msgDat);
		doccr();

		if ((msgfl = bufferedCreate(msgFile)) == NULL)
			{
			illegal(getmsg(8), msgDat);
			winRet (FALSE);
			}

		errorDisp(getcfgmsg(141));
		doccr();
		doccr();
		msgZap = TRUE;
		}

	/* open room file */
	if (!citOpen(roomDat, CO_RPB, &roomfl))
		{
		errorDisp(getcfgmsg(140), roomDat);
		doccr();

		if (!citOpen(roomDat, CO_WPB, &roomfl))
			{
			illegal(getmsg(8), roomDat);
			winRet (FALSE);
			}

		errorDisp(getcfgmsg(141));
		doccr();
		doccr();
		roomZap = TRUE;
		}

	citWinCloseTmp(&roomfl);
	bufferedWinCloseTmp(msgfl);

	return (TRUE);
	}
