#include <exec/exec.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <fcntl.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#define ACS_SYSOP_READ           23
#include "sc:ae/CmodGlue/doorheader.h"
#include "sc:ae/CmodGlue/glue.h"
#define sm sendmessage
#define pm prompt
#define hk hotkey
#define gu getuserstring
#define pu putuserstring
void sr(char *s);
static void CreateFile(char *s);
struct MailHeader {
	char	Status[1];
	long	MsgNumb;
	char	ToName[31],
		FromName[31],
		Subject[31];
	long	MsgDate,
		Recv;
	char Pad;
	};
struct MailStat {
	long	LowestKey,
		HighMsgNum,
		LowestNotDel;
	char Pad[6];
	};

struct MailHeader MH;
struct MailStat MS;
char oldheadername[200],body[4];
char string[150];
char conflocation[200];
char temp[100];
char Name[32];
ULONG HighMsg;
void LastCommand(void);
void end(void);
static BPTR LockMsgBase(void);
int GetMailStatFile(void);
FILE *fi=NULL;
main(int argc,char *argv[])
{
  FILE *fo;
  ULONG msgnumb=0;
  BPTR msglock;
  int Sysop;
  int good;
  if(argc!=2)
  {
    printf("SearchMsg version 2.0,  written by Joseph Hodge\n");
    printf("This is a XIM for /X 2.34+\n");
    printf("\n");
    exit(0);
  }
  Register(argv[1][0]-'0');
 /*  sm("[33m.---------------------------------------------------------.[0m",1);
   sm("[33m| [36mAmi-Express [35mSEARCHMSG [36mVersion 2.0 Written by ByteMaster[33m |[0m",1);
   sm("[33m|         [44m[36m/X[0m[36m Development Team - [33mThe Silent Achievers  [33m    |[0m",1);
   sm("[33m`---------------------------------------------------------'[0m",1);
*/  if(IsAccess(ACS_SYSOP_READ)) Sysop=1; else Sysop=0;
  gu(conflocation,BB_CONFLOCAL);
  gu(Name,DT_NAME); strupr(Name);
  sr(conflocation);
  sprintf(oldheadername,"%sMsgBase/HeaderFile",conflocation);
  sm("",1);
  sm("[32mEnter text string to search for [33m>: [0m",0);
  pm("",string,100);
  if(string[0]=='\0')
  {
    sm("",1); ShutDown(); end();
  }
  hk("[32mSearch Body of text [36m([33my[32m/[33mN[36m) [33m>:[0m",body);
  if(body[0]=='y' || body[0]=='Y')
  {
    sm("[36mYes.[0m",1);
  }
  else sm("[36mNo.[0m",1);

  msglock=LockMsgBase();
  if(msglock==NULL)
  {
    sm("",1);
    sm("[35mError, Cannot gain lock on message base[0m",1);
    sm("",1);
    ShutDown();
    end();
  }
  GetMailStatFile();
  UnLock(msglock);
  sm("",1);
  sprintf(temp,"[32mHigh Message        [33m>: [36m%ld",MS.HighMsgNum-1L);
  sm(temp,1);
  sprintf(temp,"[32mLow  Message        [33m>: [36m%ld",MS.LowestKey);
  sm(temp,1);
            pm("[32mSearch From Message [33m>:[0m ",temp,10);
  HighMsg=atol(temp);
  if(HighMsg>MS.HighMsgNum)
  {
    sm("",1);
    sm("[35mError, Msg Number to search from is too High[0m",1);
    sm("",1);
    ShutDown();
    end();
  }
  if(HighMsg<MS.LowestKey) HighMsg=MS.LowestKey;
  fi=fopen(oldheadername,"r+b");
  if(fi==NULL)
  {
    sm("",1);
    sm("[35mError, Cannot Open HeaderFile[0m",1);
    sm("",1);
    ShutDown();
    end();
  }
  strupr(string);
  if(HighMsg>0L) HighMsg -=1L;
  fseek(fi,(ULONG)sizeof(struct MailHeader)*(HighMsg-MS.LowestKey),0L);
  sm("",1);
  sm("[32mSearching[33m.",0);
  while(fread((APTR)&MH,sizeof(struct MailHeader),1,fi)!=NULL)
  {
     sm("[33m.",0);
     PutInfo(NONEXTMSG,DT_MSGCODE);
     good=0;
     strupr(MH.ToName); strupr(MH.FromName); strupr(MH.Subject);
     sr(MH.ToName); sr(MH.FromName);
     if(strstr(MH.ToName,string) || strstr(MH.FromName,string) || strstr(MH.Subject,string)) good=1;
     if(MH.Status[0]=='D') { good=0; continue; }
     if(strcmp(MH.ToName,Name) && strcmp(MH.FromName,Name) && MH.Status[0]!='P' && !Sysop)
      {  good=0; continue; }
     if(!good && (body[0]=='Y' || body[0]=='y'))
     {
       sprintf(temp,"%sMsgBase/%ld",conflocation,MH.MsgNumb);
       fo=fopen(temp,"r");
       if(fo!=NULL)
       { 
         while(fgets(temp,80,fo)!=NULL)
         {
            strupr(temp); if(strstr(temp,string)) { good=1; break; }
         }
         fclose(fo);
       }
     }
     if(good)
     {
       sm("",1);
       sprintf(temp,"R %ld",MH.MsgNumb);
       pu(temp,PRV_COMMAND);
     }
     if(good)
     {
       if(GetInfo(DT_MSGCODE)) break;
       sm("[32mSearching[33m.",0);
       if(FetchKey()) { sm("",1); sm("[33m****break[0m",1); break; }

     }
   }
  ShutDown();
  end();
}
void sr(char *s)
{
  register int i;
  i=strlen(s)-1;
  while(i>-1)
  {
    if(*(s+i)<=32) *(s+i)='\0'; else break;
    i--;
  }
}
int GetMailStatFile(void)
{
 int fd,stat;
 char string[100];
 strcpy(string,conflocation);
 strcat(string,"MsgBase/MailStats");
 fd=open(string,O_RDONLY);

 if(fd==(-1)) {     /* if The mailstat file doesnt exist creat one */
     fd=open(string,O_CREAT);
     if(fd==(-1)) { 
         return(0);
     }

     MS.LowestNotDel=0;
     MS.LowestKey=1;
     MS.HighMsgNum=1;
     stat=write(fd,(char *)&MS,sizeof(struct MailStat));
 } else
     stat=read(fd,(char *)&MS,sizeof(struct MailStat));

 if(stat!=sizeof(struct MailStat)){
     close(fd); return(0);
 }
 
 close(fd);
 return(0);
}
static BPTR LockMsgBase(void)
{
 BPTR lock;
 UWORD loop=0;
 LONG error;
 char GSTR3[100];
 sprintf(GSTR3,"%sMsgBase/MailLock",conflocation);
 do  {
     if(!(lock=Lock(GSTR3,ACCESS_WRITE))) {
         error=IoErr();
         if(error==205)        CreateFile(GSTR3);
         Delay(120L);
         printf(".");
     }
 } while(!lock&&loop++<30);

 return(lock);
}

void LastCommand(void)
{
  PutInfo(NEXTMSG,DT_MSGCODE);
  pu("",RETURNCOMMAND);
  sm("",1);
}
void end(void)
{
  if(fi) fclose(fi);
  exit(0);
}
static void CreateFile(char *s)
{
 FILE *f;
 
 if(f=fopen(s,"w"))  {
     fprintf(f,"DO NOT DELETE!\n");
     fclose(f);
 }
}