#include <exec/exec.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>
struct ConfBase
{
  char Handle[31];
  ULONG NewSinceDate, ConfRead,ConfYM;
  ULONG Bytes_Download,Bytes_Upload;
  ULONG Daily_Bytes_Limit,Daily_Bytes_Dld;
  USHORT Upload,Downloads,RatioType,Ratio,Messages_Posted;
  UWORD Access;
  UWORD Active;
};
struct ConfBase UP;
void sr(char *s);
void GetLowestKey(void);
struct MailHeader {
	char	Status[1];
	long	MsgNumb;
     long ActualMsgNumb;
	char	ToName[31],
		FromName[31],
		Subject[31];
     char ToNet[8],FromNet[8];
	long	MsgDate,
		Recv;
     long threaded;
	char Pad;
	};
struct MailStat {
	long	LowestKey,
		HighMsgNum,
		LowestNotDel;
	char Pad[6];
	};

struct MailHeader MH;
struct MailStat MS;
char oldheadername[200],newheadername[200];
char conflocation[200];
char temp[100];
ULONG lowmsg;
main(int argc,char *argv[])
{
  FILE *fi,*fo;
  ULONG msgnumb=0L;
  ULONG goodtogo=0L;
  printf("\n");
  printf(" .------------------------------------------------------.\n");
  printf(" | Ami-Express LowMsg Version 1.0 Written by ByteMaster |\n");
  printf(" |      /X Development Team - The Silent Achievers      |\n");
  printf(" `------------------------------------------------------'\n");
  printf("\n");

  if(argc<2)
  {
    printf("LowMsg version 1.0,  written by Joseph Hodge\n");
    printf("usage: LowMsg <conf location>\n");
    printf("   ie: LowMsg bbs:confs/\n");
    printf("\n");
    exit(0);
  }
  strcpy(conflocation,argv[1]);
  sr(conflocation);
 GetLowestKey();

  sprintf(oldheadername,"%sMsgBase/HeaderFile",conflocation);
  strcpy(newheadername,oldheadername);
  strcat(oldheadername,".old");
  DeleteFile(oldheadername);
  msgnumb=0;
  if(Rename(newheadername,oldheadername))
  {
     fi=fopen(oldheadername,"rb");
     fo=fopen(newheadername,"wb");
     while(fread((APTR)&MH,sizeof(struct MailHeader),1,fi)!=NULL)
     {
       
       msgnumb++;
       if(!goodtogo)
       {
          if(MH.MsgNumb==msgnumb) 
          {
            printf("MsgBase already set at lowest possible KEY\n");
            fclose(fo);
            fclose(fi);
            DeleteFile(newheadername);
            Rename(oldheadername,newheadername);
            exit(0);
          }
          goodtogo=1L;
       }
       if(MH.Status[0]!='D')
       {
          if(msgnumb!=MH.MsgNumb)
          {
             sprintf(temp,"%sMsgBase/%ld",conflocation,MH.MsgNumb);
             sprintf(oldheadername,"%sMsgBase/%ld",conflocation,msgnumb);
             Rename(temp,oldheadername);
             sprintf(temp,"%sMsgBase/F%ld",conflocation,MH.MsgNumb);
             sprintf(oldheadername,"%sMsgBase/F%ld",conflocation,msgnumb);
             Rename(temp,oldheadername);
             printf("Renumbering msg# %ld to %ld\n",MH.MsgNumb,msgnumb);
          }
       }
       MH.MsgNumb=msgnumb;
       fwrite((APTR)&MH,sizeof(struct MailHeader),1,fo);
     }
     fclose(fi);
     fclose(fo);
     msgnumb++;
     sprintf(oldheadername,"%sMsgBase/mailstats",conflocation);
     fi=fopen(oldheadername,"rb");
     if(fi!=NULL)
     {
       printf("Updating MailStats\n");
       fread((APTR)&MS,sizeof(struct MailStat),1,fi);
       printf("Old HighMsg = %ld\n",MS.HighMsgNum);
       printf("Old LowKey  = %ld\n",MS.LowestKey);
       fclose(fi);
       MS.HighMsgNum=msgnumb;
       goodtogo=MS.LowestKey;
       MS.LowestKey=1;
       MS.LowestNotDel=MS.LowestKey;
       fi=fopen(oldheadername,"wb");
       printf("New HighMsg = %ld\n",MS.HighMsgNum);
       printf("New LowKey  = %ld\n",MS.LowestKey);
       fwrite((APTR)&MS,sizeof(struct MailStat),1,fi);
       fclose(fi);
     }
     printf("Updating User's MsgBase Pointers\n");
     sprintf(temp,"%sConf.DB",conflocation);
     sprintf(oldheadername,"%sConf.DB.old",conflocation);
     DeleteFile(oldheadername);
     Rename(temp,oldheadername);
     fi=fopen(oldheadername,"rb");
     if(fi!=NULL)
     {
       fo=fopen(temp,"wb");
       while(fread((APTR)&UP,sizeof(struct ConfBase),1,fi)!=NULL)
       {
           if(UP.ConfRead<goodtogo) UP.ConfRead=0L;
           else UP.ConfRead=UP.ConfRead-goodtogo;
           if(UP.ConfYM<goodtogo) UP.ConfYM=0L;
           else UP.ConfYM=UP.ConfYM-goodtogo;
           fwrite((APTR)&UP,sizeof(struct ConfBase),1,fo); 
       }
       fclose(fi);
       fclose(fo);
       printf("LowMsg Utility Complete.\n");
     }
  }
  else
  {
    printf("Error, cannot locate msgbase\n");
  }
  exit(0);
}

void GetLowestKey(void)
{
  FILE *fi;
  char image[200];
  
  sprintf(image,"%sMsgBase/MailStats",conflocation);
  fi=fopen(image,"rb");
  if(fi!=NULL)
  {
    fread((APTR)&MS,sizeof(struct MailStat),1,fi);
    fclose(fi);
    if((LONG)MS.HighMsgNum-MS.LowestKey >lowmsg) lowmsg=MS.HighMsgNum-lowmsg;
    else { printf("MsgBase Size meets specification\n"); exit(0); }
    return;
  }
  else { printf("Error, MailStats file inaccessible\n"); exit(0); }
}
void sr(char *s)
{
  register int i;
  i=strlen(s)-1;
  while(i>-1)
  {
    if(*(s+i)<=32) *(s+i)='\0'; else break;
    i--;
  }
}