/*

  This is a part of the Project Frontier's Source code.

  Copyright (C) 1997-98 Francis Gastellu
                    aka Lone Runner/Aegis

  This program 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
  of the License, or (at your option) any later version.

  This program 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 this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

/*

PCBoard's messages bases (MSGS) functions

*/

#include <stdio.h>
#include <fcntl.h>
#include <share.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <io.h>
#include "..\lang\fortify.h"
#include "..\com\msgs.h"
#include "..\com\mbfieee.h"
#include "..\com\system.h"
#include "..\com\sharing.h"
#include "..\com\pcbdat.h"
#include "..\com\mbfieee.h"

char messageFields[10][19] = {
	"Reference Number: ",
	"            Date: ",
	"            Time: ",
	"              To: ",
	"            From: ",
	"         Subject: ",
	"        Password: ",
	"            Echo: ",
	"Extended headers: ",
    "          Status: "};

char basename[51];
MessageBaseType mbTemp;

void openMessageBase(MessageBaseType *mb)
{
int pass=0;
indextype Index;
MsgHdr Hdr;

reopen:

fnsplit(mb->basename, tmpDrive, tmpDir, tmpFile, NULL);
fnmerge(tmpStr, tmpDrive, tmpDir, tmpFile, ".IDX");

if (!access(tmpStr,0))
	{
	fnsplit(mb->basename, tmpDrive, tmpDir, tmpFile, NULL);
	fnmerge(tmpStr, tmpDrive, tmpDir, tmpFile, ".");
	if (!access(tmpStr,0))
		{
        mb->MsgsFile = fopen_share(tmpStr, "r+b", SH_DENYNO);
		fread(&mb->Header, sizeof(mb->Header), 1, mb->MsgsFile);
		fnsplit(mb->basename, tmpDrive, tmpDir, tmpFile, NULL);
		fnmerge(tmpStr, tmpDrive, tmpDir, tmpFile, ".IDX");
        mb->IndexFile = fopen_share(tmpStr, "r+b", SH_DENYNO);
       	mb->OldIndexFile = NULL;
		fnmerge(tmpStr, tmpDrive, tmpDir, tmpFile, ".NDX");
        if (oldIndexes)
        	{
			if (!access(tmpStr,0))
            	{
    		    mb->OldIndexFile = fopen_share(tmpStr, "r+b", SH_DENYNO);
                }
            else
            	{
                fppe_runtimeError("Creating old index...");
				mb->OldIndexFile = fopen_share(tmpStr, "w+b", SH_DENYNO);
				fclose(mb->OldIndexFile);
	    	    mb->OldIndexFile = fopen_share(tmpStr, "r+b", SH_DENYNO);
                }
            checkSync(mb);
            }
        return;
        }
    }

if (pass)
	{
	fppe_runtimeError("MSGS.openMessageBase: Can't write to disk!");
    return;
    }

fppe_runtimeError("Creating message base...");

pass++;

fnsplit(mb->basename, tmpDrive, tmpDir, tmpFile, NULL);
fnmerge(tmpStr, tmpDrive, tmpDir, tmpFile, ".");

mb->MsgsFile = fopen_share(tmpStr, "w+b", SH_DENYNO);
lockMsgBase(mb);

mb->Header.HiMsg = Long2BsReal(1);
mb->Header.LoMsg = Long2BsReal(1);
mb->Header.NActive = Long2BsReal(0);
mb->Header.NCallers = Long2BsReal(totalUsers);
memset(mb->Header.locked, ' ', 6);
memset(mb->Header.reserved, ' ', 106);

fwrite(&mb->Header, sizeof(mb->Header), 1, mb->MsgsFile);

Hdr.statusFlag=' ';
Hdr.num = Long2BsReal(1);
Hdr.refNum = Long2BsReal(0);
Hdr.nBlocks = 2;
memset(Hdr.date, ' ', 8);
memset(Hdr.time, ' ', 5);
memset(Hdr.to, ' ', 25);
Hdr.replyDate = Long2BsReal(0);
memset(Hdr.replyTime, ' ', 5);
Hdr.replyStatus = ' ';
memset(Hdr.from, ' ', 25);
memset(Hdr.subject, ' ', 25);
memset(Hdr.password, ' ', 12);
Hdr.activeStatus = 'â';
Hdr.echoStatus = ' ';
memset(Hdr.reserved1, 0, 4);
Hdr.reserved2 = 0;
Hdr.extendedHdrFlags = 0;

fwrite(&Hdr, sizeof(MsgHdr), 1, mb->MsgsFile);
memset(&tmpStr, ' ', 128);
fwrite(&tmpStr, 128, 1, mb->MsgsFile);
fclose(mb->MsgsFile);

fnsplit(mb->basename, tmpDrive, tmpDir, tmpFile, NULL);
fnmerge(tmpStr, tmpDrive, tmpDir, tmpFile, ".IDX");
mb->IndexFile = fopen_share(tmpStr, "w+b", SH_DENYNO);

Index.offset = 128;
Index.number = BsReal2Long(1);
memset(Index.receiver, ' ', 25);
memset(Index.sender, ' ', 25);
Index.status = ' ';
Index.date = 0;
memset(Index.reserved, 0, 3);

fwrite(&Index, sizeof(Index), 1,  mb->IndexFile);
fclose(mb->IndexFile);

mb->IndexFile = NULL;
mb->MsgsFile = NULL;
mb->OldIndexFile = NULL;

unlockMsgBase(mb);
goto reopen;
}

// ------------------------------------------------------------------------

void readHeader(MessageBaseType *mb, long number, MsgHdr *msgHeader)
{
indextype Index;
long a;

if (!checkOpenMessageBase(mb))
	return;

a = (number-BsReal2Long(mb->Header.LoMsg))*sizeof(indextype);
fseek(mb->IndexFile,a,SEEK_SET);
fread(&Index,sizeof(indextype), 1, mb->IndexFile);

//if (Index.offset > 0) {
  fseek(mb->MsgsFile,labs(Index.offset),SEEK_SET);
  fread(msgHeader,sizeof(MsgHdr), 1, mb->MsgsFile);
//  }
}

// ------------------------------------------------------------------------

void writeHeader(MessageBaseType *mb, long number, MsgHdr *msgHeader)
{
indextype Index;
long a;

if (!checkOpenMessageBase(mb))
	return;

a = (number-BsReal2Long(mb->Header.LoMsg))*sizeof(indextype);
fseek(mb->IndexFile,a,SEEK_SET);
fread(&Index,sizeof(indextype), 1, mb->IndexFile);


//if (Index.offset > 0) {
  fseek(mb->MsgsFile,labs(Index.offset),SEEK_SET);
  fwrite(msgHeader,sizeof(MsgHdr), 1, mb->MsgsFile);
//  }
}

// ------------------------------------------------------------------------

int checkOpenMessageBase(MessageBaseType *mb)
{
if (mb->MsgsFile == NULL || mb->IndexFile == NULL)
	openMessageBase(mb);
if (mb->MsgsFile == NULL || mb->IndexFile == NULL)
	return 0;
return -1;
}

// ------------------------------------------------------------------------

void lockMsgBase(MessageBaseType *mb)
{
if (mb->MsgsFile == NULL)
	{
//	fppe_runtimeError("MSGS.lockMsgBase: Can't lock!");
	return;
    }
//lock(mb->MsgsFile, 16, 6);
}

// ------------------------------------------------------------------------

void unlockMsgBase(MessageBaseType *mb)
{
if (mb->MsgsFile == NULL)
	{
//	fppe_runtimeError("MSGS.unlockMsgBase: Can't unlock!");
	return;
	}
//unlock(mb->MsgsFile, 16, 6);
}

// ------------------------------------------------------------------------

void insertMessage(int conf, char *filename)
{
MsgHdr Hdr;
indextype Index;
FILE *in;
char *text;
unsigned long HdrPos, filelength;
bsreal bs;
long l;

char *p;
char data[81];

int a,b,c;
int dataSize;

in = fopen_share(filename, "rt", SH_DENYWR);
if (in == NULL)
	return;

getMessageBase(conf, basename);
initMessageBase(&mbTemp, basename);
openMessageBase(&mbTemp);
lockMsgBase(&mbTemp);

fseek(in, 0, SEEK_END);
filelength = ftell(in);
fseek(in, 0, SEEK_SET);

Hdr.statusFlag=' ';
Hdr.num = Long2BsReal(0);
Hdr.refNum = Long2BsReal(0);
Hdr.nBlocks = 1;
memset(Hdr.date, ' ', 8);
memset(Hdr.time, ' ', 5);
memset(Hdr.to, ' ', 25);
Hdr.replyDate = Long2BsReal(0);
memset(Hdr.replyTime, ' ', 5);
Hdr.replyStatus = ' ';
memset(Hdr.from, ' ', 25);
memset(Hdr.subject, ' ', 25);
memset(Hdr.password, ' ', 12);
Hdr.activeStatus = 'á';
Hdr.echoStatus = ' ';
memset(Hdr.reserved1, 0, 4);
Hdr.reserved2 = 0;
Hdr.extendedHdrFlags = 0;



fseek(mbTemp.IndexFile, 0, SEEK_END);

mbTemp.Header.HiMsg = Long2BsReal(ftell(mbTemp.IndexFile) / sizeof(Index) + 1);
mbTemp.Header.NActive = Long2BsReal(BsReal2Long(mbTemp.Header.NActive)+1);
fseek(mbTemp.MsgsFile, 0, SEEK_SET);
fwrite(&mbTemp.Header, sizeof(mbTemp.Header), 1, mbTemp.MsgsFile);
fseek(mbTemp.MsgsFile, 0, SEEK_END);
HdrPos = ftell(mbTemp.MsgsFile);
fwrite(&Hdr, sizeof(Hdr), 1, mbTemp.MsgsFile);

dataSize=0;
while (!feof(in))
	{
	fgets(data, 80, in);
    for (a=0;a<10;a++)
    	{
	    if (!strnicmp(data, messageFields[a], 18))
	    	{
            switch (a+1)
            	{
                case 1: //  "Reference Number: ",
                	Hdr.refNum = Long2BsReal(strtol(&data[18], &p, 10));
                	break;
                case 2: //  "            Date: ",
                    memcpy(Hdr.date, &data[18], 8);
                	break;
                case 3: //  "            Time: ",
                    memcpy(Hdr.time, &data[18], 5);
                	break;
                case 4: // 	"              To: ",
                    memcpy(Hdr.to, &data[18], 25);
                	break;
                case 5: // 	"            From: ",
                    memcpy(Hdr.from, &data[18], 25);
                	break;
                case 6: // 	"         Subject: ",
                    memcpy(Hdr.subject, &data[18], 25);
                	break;
                case 7: // 	"        Password: ",
                    memcpy(Hdr.password, &data[18], 12);
                	break;
                case 8: // 	"            Echo: ",
                    if (data[18] != '\n')
	                    Hdr.echoStatus = data[18];
                	break;
                case 10: //	"          Status: "};
                    if (data[18] != '\n')
	                    Hdr.statusFlag = data[18];
                	break;
                case 9: //	"Extended headers: "};
                    b = strtol(&data[18], &p, 10);
                    for (c=0;c<b;c++)
                    	{
                        fgets(data, 80, in);
                        fwrite("\xFF\x40", 2, 1, mbTemp.MsgsFile);
                        dataSize+=2;

						if (!strncmpi(data,"TO     :", 8)) { Hdr.extendedHdrFlags |= 1; }
						if (!strncmpi(data,"FROM   :", 8)) { Hdr.extendedHdrFlags |= 0x82; }
						if (!strncmpi(data,"SUBJECT:", 8)) { Hdr.extendedHdrFlags |= 4; }
						if (!strncmpi(data,"ATTACH :", 8)) { Hdr.extendedHdrFlags |= 0x10; }
						if (!strncmpi(data,"LIST   :", 8)) { Hdr.extendedHdrFlags |= 8; }
						if (!strncmpi(data,"ACKRR  :", 8)) { Hdr.extendedHdrFlags |= 0x40; }
						if (!strncmpi(data,"ACKNAME:", 8)) { Hdr.extendedHdrFlags |= 2; }

                        fwrite(data, 69, 1, mbTemp.MsgsFile);
                        dataSize+=69;
                        fwrite("\xE3", 1, 1, mbTemp.MsgsFile);
                        dataSize++;
                        }
                	break;
                }
    	    }
        }
	if (!stricmp(data, "Message Body:\n"))
    	break;
    }

/*strnzcpy(tmpStr, Hdr.date, 8);
l = charDateToPPLDate(tmpStr, 0);
PPLDateToCharDate(tmpStr, l, 1);
strncpy(Hdr.date, tmpStr, 8);*/

a = filelength - ftell(in);

text = (char *)malloc(a);
fread(text, a, 1, in);
fclose(in);

for (c=0;c<a;c++)
	if (text[c] == '\n') { text[c] = '\xE3'; a--;}

Hdr.num = mbTemp.Header.HiMsg;
fwrite(text, a, 1, mbTemp.MsgsFile);
dataSize+=a;

b = (((dataSize >> 7)+1) << 7) - dataSize;

for (a=0;a<b;a++)
	fwrite(" ", 1, 1, mbTemp.MsgsFile);

dataSize += b;

Hdr.nBlocks += (dataSize >> 7);

fseek(mbTemp.MsgsFile, HdrPos, SEEK_SET);
fwrite(&Hdr, sizeof(Hdr), 1, mbTemp.MsgsFile);

Index.offset = HdrPos;
Index.number = BsReal2Long(mbTemp.Header.HiMsg);
memcpy(Index.receiver, Hdr.to, 25);
memcpy(Index.sender, Hdr.from, 25);
Index.status = Hdr.statusFlag;
strnzcpy(tmpStr, Hdr.date, 8);
Index.date = charDateToPPLDate(tmpStr,1);
memset(&Index.reserved, 0, 3);

fseek(mbTemp.IndexFile, 0, SEEK_END);
fwrite(&Index, sizeof(Index), 1, mbTemp.IndexFile);

if (oldIndexes)
	{
	fseek(mbTemp.OldIndexFile, (Index.number-BsReal2Long(mbTemp.Header.LoMsg)) * 4, SEEK_SET);
	bs = Long2BsReal(HdrPos/128 + 1);
	fwrite(&bs, 4, 1, mbTemp.OldIndexFile);
    }

unlockMsgBase(&mbTemp);
closeMessageBase(&mbTemp);
free(text);
}

// ------------------------------------------------------------------------

void initMessageBase(MessageBaseType *mb, char *base)
{
mb->MsgsFile = NULL;
mb->IndexFile = NULL;
mb->basename = base;
}

// ------------------------------------------------------------------------

void closeMessageBase(MessageBaseType *mb)
{
fclose(mb->MsgsFile);
fclose(mb->IndexFile);
fclose(mb->OldIndexFile);
}

// ------------------------------------------------------------------------

void retrieveMessage(int conf, long msg, char *filename)
{
MsgHdr Hdr;
FILE *out;
char *text;
long block;
int nx;
long nxm;
int h=0;
int c, a,b;
long l;

getMessageBase(conf, basename);
initMessageBase(&mbTemp, basename);
openMessageBase(&mbTemp);

if (msg > BsReal2Long(mbTemp.Header.HiMsg) || msg < BsReal2Long(mbTemp.Header.LoMsg))
    {
	closeMessageBase(&mbTemp);
	return;
    }


readHeader(&mbTemp, msg, &Hdr);

block=128;

if (!access(filename, 0))
	unlink(filename);
if (Hdr.activeStatus == 226)
	{
	closeMessageBase(&mbTemp);
    return;
    }
if ((out = fopen_share(filename, "w+t", SH_DENYRW)) == NULL)
	{
	closeMessageBase(&mbTemp);
    return;
    }

fprintf(out, "          Status: %c\n"
			 "  Message Number: %ld\n"
			 "Reference Number: %ld\n"
			 "Number of blocks: %d\n",
			 Hdr.statusFlag != 0 ? Hdr.statusFlag : ' ',
             BsReal2Long(Hdr.num),
			 BsReal2Long(Hdr.refNum),
       		 Hdr.nBlocks);
strnzcpy(tmpStr, Hdr.date, 8);
//l = charDateToPPLDate(tmpStr, 1);
//PPLDateToCharDate(tmpStr, l, 0);
fprintf(out, "            Date: %8.8s\n", tmpStr);
strnzcpy(tmpStr, Hdr.time, 5);
fprintf(out, "            Time: %5.5s\n", tmpStr);
strnzcpy(tmpStr, Hdr.to, 25);
fprintf(out, "              To: %25.25s\n", tmpStr);
strnzcpy(tmpStr, Hdr.replyTime, 5);
fprintf(out, "   Time or reply: %5.5s\n", tmpStr);
strnzcpy(tmpStr, Hdr.from, 25);
fprintf(out, "            From: %25.25s\n", tmpStr);
strnzcpy(tmpStr, Hdr.subject, 25);
fprintf(out, "         Subject: %25.25s\n", tmpStr);
strnzcpy(tmpStr, Hdr.password, 12);
fprintf(out, "        Password: %12.12s\n", tmpStr);
fprintf(out, "          Active: %d\n", Hdr.activeStatus);
fprintf(out, "            Echo: %c\n", Hdr.echoStatus != 0 ? Hdr.echoStatus : ' ');
fprintf(out, "       Has reply: %c\n", Hdr.replyStatus != 0 ? Hdr.replyStatus : ' ');
PPLDateToCharDate(tmpStr, BsReal2Long(Hdr.replyDate), 1);
fprintf(out, "   Date of reply: %s\n", BsReal2Long(Hdr.replyDate) == 0 ? "" : tmpStr);

nx=0;
while (block < Hdr.nBlocks * 128)
	{
	fread(&tmpStr, 128, 1, mbTemp.MsgsFile);
    block+=128;
    b = 0;
    if (Hdr.nBlocks * 128 - block < 0)
        b = (block - Hdr.nBlocks * 128);
   	a = 128 - b;
    tmpStr[a] = 0;
	if (*(unsigned int*)(&tmpStr) == 0x40FF)
		{
        nx++;
        if (block == 256)
        	{
			fprintf(out, "Extended headers: ");
		    nxm = ftell(out);
		    fprintf(out, "%-4d\n", nx);
		    }
        fprintf(out,"%69.69s\n", &tmpStr[2]);
        fseek(mbTemp.MsgsFile, -56+b, SEEK_CUR);
        block-=56+b;
        }
    else
    	{
        if (!h)
			{ fprintf(out, "Message Body:\n"); h++; }
		for (c=0;c<a;c++)
			if (tmpStr[c] == '\xE3') { tmpStr[c] = '\n';}
        if (block >= Hdr.nBlocks * 128)
           	rtrim(tmpStr);
        fprintf(out, "%s", tmpStr);
        }
    }

if (nx > 1)
	{
    fseek(out, nxm, SEEK_SET);
    fprintf(out, "%-4d", nx);
    }

fclose(out);
closeMessageBase(&mbTemp);
}

// ------------------------------------------------------------------------

void setRead(int conf, long msg, int reply)
{
MsgHdr Hdr;
struct date d_date;
struct time d_time;
struct time t;

getMessageBase(conf, basename);
initMessageBase(&mbTemp, basename);
openMessageBase(&mbTemp);

if (msg > BsReal2Long(mbTemp.Header.HiMsg) || msg < BsReal2Long(mbTemp.Header.LoMsg))
	return;

readHeader(&mbTemp, msg, &Hdr);

switch (Hdr.statusFlag)
	 {
     case '*': Hdr.statusFlag = '+'; break;
     case ' ': Hdr.statusFlag = '-'; break;
     case '~': Hdr.statusFlag = '`'; break;
     case '%': Hdr.statusFlag = '^'; break;
     case '!': Hdr.statusFlag = '#'; break;
     }

if (reply)
	Hdr.replyStatus = 'R';

gettime(&t);
sprintf(tmpStr, "%02d:%02d", t.ti_hour, t.ti_min);
strncpy(Hdr.replyTime, tmpStr, 5);

getdate(&d_date);
d_time.ti_min=0;
d_time.ti_hour=0;
d_time.ti_hund=0;
d_time.ti_sec=0;
Hdr.replyDate = Long2BsReal(25568 + DosToUnix(&d_date, &d_time) / 86400);

writeHeader(&mbTemp, msg, &Hdr);

closeMessageBase(&mbTemp);
}

// ------------------------------------------------------------------------

void setUnread(int conf, long msg)
{
MsgHdr Hdr;
getMessageBase(conf, basename);
initMessageBase(&mbTemp, basename);
openMessageBase(&mbTemp);

if (msg > BsReal2Long(mbTemp.Header.HiMsg) || msg < BsReal2Long(mbTemp.Header.LoMsg))
	return;

readHeader(&mbTemp, msg, &Hdr);

switch (Hdr.statusFlag)
	 {
     case '+': Hdr.statusFlag = '*'; break;
     case '-': Hdr.statusFlag = ' '; break;
     case '`': Hdr.statusFlag = '~'; break;
     case '^': Hdr.statusFlag = '%'; break;
     case '#': Hdr.statusFlag = '!'; break;
     }

memset(&Hdr.replyTime, 0, 5);
Hdr.replyStatus = ' ';
Hdr.replyDate = 0;

writeHeader(&mbTemp, msg, &Hdr);

closeMessageBase(&mbTemp);
}

void setKillMsgStatus(long conf, long msgNum, int bool)
{
MsgHdr Hdr;
getMessageBase(conf, basename);
initMessageBase(&mbTemp, basename);
openMessageBase(&mbTemp);

if (msgNum > BsReal2Long(mbTemp.Header.HiMsg) || msgNum < BsReal2Long(mbTemp.Header.LoMsg))
	return;

readHeader(&mbTemp, msgNum, &Hdr);
if (bool)
	{
    if (Hdr.activeStatus == (unsigned char)'á')
		mbTemp.Header.NActive = Long2BsReal(BsReal2Long(mbTemp.Header.NActive) - 1);
	Hdr.activeStatus = 'â';
	}
else
	{
    if (Hdr.activeStatus == (unsigned char)'â')
		mbTemp.Header.NActive = Long2BsReal(BsReal2Long(mbTemp.Header.NActive) + 1);
	Hdr.activeStatus = 'á';
	}

setKillHeaderStatus(&mbTemp, msgNum, bool);
writeHeader(&mbTemp, msgNum, &Hdr);
closeMessageBase(&mbTemp);
}

void setKillHeaderStatus(MessageBaseType *mb, long number, int bool)
{
indextype Index;
long a;

if (!checkOpenMessageBase(mb))
	return;

a = (number-BsReal2Long(mb->Header.LoMsg))*sizeof(indextype);
fseek(mb->IndexFile,a,SEEK_SET);
fread(&Index,sizeof(indextype), 1, mb->IndexFile);
if (bool)
	Index.offset = -labs(Index.offset);
else
	Index.offset = labs(Index.offset);
fseek(mb->IndexFile,a,SEEK_SET);
fwrite(&Index,sizeof(indextype), 1, mb->IndexFile);
}

void readMsgBaseHeader(MessageBaseType *mb)
{
if (!checkOpenMessageBase(mb))
	return;

fseek(mb->MsgsFile, 0, SEEK_SET);
fread(&mb->Header, sizeof(mb->Header), 1, mb->MsgsFile);
}

void writeMsgBaseHeader(MessageBaseType *mb)
{
if (!checkOpenMessageBase(mb))
	return;

fseek(mb->MsgsFile, 0, SEEK_SET);
fwrite(&mb->Header, sizeof(mb->Header), 1, mb->MsgsFile);
}

long getNextMsg(int conf, long start, int inc, char *from, char *fromalias, char *to, char *toalias, char *subject, char *text, long fromdate, int seeall)
{
MsgHdr Hdr;
FILE *out;
long block;
long nxm;
int c, a,b;
long msg;
int fromok, took, subjok, textok, dateok;
char *buffer;
int seen;

getMessageBase(conf, basename);
initMessageBase(&mbTemp, basename);
openMessageBase(&mbTemp);

for (msg=start;;msg+=inc)
	{
	fromok=0;
	took=0;
	subjok=0;
	textok=0;

    if (*from==0) fromok=1;
    if (*to==0) took=1;
    if (*subject==0) subjok=1;
    if (*text==0) textok=1;
    if (fromdate==0) dateok=1;
    seen = 0;

    if (msg > BsReal2Long(mbTemp.Header.HiMsg) || msg < BsReal2Long(mbTemp.Header.LoMsg))
        {
	    closeMessageBase(&mbTemp);
	    return 0;
        }

    readHeader(&mbTemp, msg, &Hdr);

    if (seeall || Hdr.statusFlag == ' ' || Hdr.statusFlag == '-') seen=1;

    if (Hdr.activeStatus != 226)
    	{
        if (!took)
        	{
	        sprintf(tmpStr, "%-25s", to);
			if (!strnicmp(Hdr.to, tmpStr, 25)) took = 1;
	        sprintf(tmpStr, "%-25s", toalias);
			if (!strnicmp(Hdr.to, tmpStr, 25)) took = 1;
            }
        if (!seen)
        	{
	        sprintf(tmpStr, "%-25s", user.FullName);
			if (!strnicmp(Hdr.to, tmpStr, 25)) seen = 1;
            }
        if (!seen)
        	{
	        sprintf(tmpStr, "%-25s", userAlias);
			if (!strnicmp(Hdr.to, tmpStr, 25)) seen = 1;
            }
        if (!fromok)
			{
            sprintf(tmpStr, "%-25s", from);
			if (!strnicmp(Hdr.from, tmpStr, 25)) fromok = 1;
	        sprintf(tmpStr, "%-25s", fromalias);
			if (!strnicmp(Hdr.from, tmpStr, 25)) fromok = 1;
            }
        if (!seen)
        	{
	        sprintf(tmpStr, "%-25s", user.FullName);
			if (!strnicmp(Hdr.from, tmpStr, 25)) seen = 1;
            }
        if (!seen)
        	{
	        sprintf(tmpStr, "%-25s", userAlias);
			if (!strnicmp(Hdr.from, tmpStr, 25)) seen = 1;
            }
        if (!subjok)
			{
            sprintf(tmpStr, "%-25s", subject);
			if (!strnicmp(Hdr.subject, tmpStr, 25)) subjok = 1;
            }
        if (!dateok)
        	{
            strnzcpy(tmpStr, Hdr.date, 8);
			if (charDateToPPLDate(tmpStr, 1) >= fromdate) dateok = 1;
            }

            block=128;
            buffer = (char *)calloc(Hdr.nBlocks * 128, 1);

        while (block < Hdr.nBlocks * 128)
	        {
	        fread(&tmpStr, 128, 1, mbTemp.MsgsFile);
            block+=128;
            b = 0;
            if (Hdr.nBlocks * 128 - block < 0)
                b = (block - Hdr.nBlocks * 128);
   	        a = 128 - b;
            tmpStr[a] = 0;
            strcat(buffer, tmpStr);
            }
        if (stristr(buffer, text) != NULL) textok=1;

        // Insert check for extended headers TO, FROM, SUBJECT, LIST

        free(buffer);

        if (seen && dateok && fromok && took && subjok && textok)
		    {
		    closeMessageBase(&mbTemp);
    	    return msg;
            }
        }
	}
}


// ------------------------------------------------------------------------

void checkSync(MessageBaseType *mb)
{
long hi, lo;
long xpctSize, actualSize;
long t=0;
long a;
bsreal b;
MsgHdr msgHeader;
indextype idx;
long _t;

if (mb->OldIndexFile == NULL) return;

hi = BsReal2Long(mb->Header.HiMsg);
lo = BsReal2Long(mb->Header.LoMsg);


xpctSize = (hi - lo + 1) * 4;
fseek(mb->OldIndexFile, 0, SEEK_END);
actualSize = ftell(mb->OldIndexFile);

fseek(mb->IndexFile, 0, SEEK_END);
if (actualSize > xpctSize)
	{
	fseek(mb->OldIndexFile, (ftell(mb->IndexFile)/sizeof(indextype)) * 4, SEEK_SET);
	fread(&b, 4, 1, mb->OldIndexFile);
	t = BsReal2Long(b);
    }

if (t != 0)
	{
    print("@X0CUpdating index...");
    for (a=ftell(mb->IndexFile)/sizeof(indextype)+1;;a++)
    	{
        if (!(a % 512)) print(".");
        fseek(mb->OldIndexFile, (a-1)*4, SEEK_SET);
        fread(&b, 4, 1, mb->OldIndexFile);
        t = BsReal2Long(b);
        if (t == 0) break;
        fseek(mb->MsgsFile, (t-1)*128, SEEK_SET);
		fread(&msgHeader,sizeof(MsgHdr), 1, mb->MsgsFile);
        idx.offset = (t-1) * 128;
        idx.number = a+lo;
        strncpy(idx.sender, msgHeader.from, 25);
        strncpy(idx.receiver, msgHeader.to, 25);
        idx.status = msgHeader.statusFlag;
        strnzcpy(tmpStr, msgHeader.date, 8);
        idx.date = charDateToPPLDate(tmpStr, 1);
        memset(&idx.reserved, 0, 3);
        fwrite(&idx, sizeof(indextype), 1, mb->IndexFile);
        }
    print("\n");
    }

if (actualSize < xpctSize)
	t = 0;
else
	{
	fseek(mb->OldIndexFile, xpctSize-4, SEEK_SET);
	fread(&b, 4, 1, mb->OldIndexFile);
	t = BsReal2Long(b);
    }
if (t == 0)
	{
    print("@X0CUpdating old index..");
    fseek(mb->OldIndexFile, 0, SEEK_SET);
    _t = 4095+lo;
    if (hi > _t) _t = hi;
    for (a=lo;a<=_t;a++)
    	{
        if (!(a % 512)) print(".");
        if (a <= hi)
        	{
	        fseek(mb->IndexFile, a * sizeof(indextype), SEEK_SET);
			fread(&t, 4, 1, mb->IndexFile);
        	b = Long2BsReal(t/128+1);
            }
        else
        	b = Long2BsReal(0);
        fwrite(&b, 4, 1, mb->OldIndexFile);
        }
    print("\n");
    }
}

