#include <exec/types.h>
#include <exec/exec.h>
#include <functions.h>
#include <stdio.h>
#include <stdlib.h>
#include "dh0:code/code20/defines.h"
struct User U;
struct UserKeys K;
struct User P;
char FileName[200];
char Keys[200];
char temp[200];
char Ktemp[200];
int TLock(char *str);
void sr(char *str);
void end(void);
int GetUN(char *SA);
int strnicmp(char *str1,char *str2,int len);
static struct FileLock      *pdir = NULL;
static struct FileInfoBlock *dir_info = NULL;
struct Commands cfg;
struct ConfList
{
  struct ConfList *Next;
  char image[80];
} *CList=NULL,*CFirst=NULL;
struct PSTR
{
  int s1;
  int s2;
  int ns;
  int ne;
};
#define ACCESS_READ -2
char BBSloc[200];
void free_pdir();
void LookFor(char *Part,int old,int new);
void CheckPartUpload(int old,int new);
void AcpError();
void FreeConf();
struct ConfList *AllocConf();
main(int argc,char *argv[])
{
   int i,j;
   struct PSTR t;
   FILE *fi,*fo,*fo2;
   char image[200];
   char ConfName[200];
   j=0;
   dir_info=(struct FileInfoBlock *)AllocMem((long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR);
   if(dir_info==NULL)
   {
     printf("Can't allocate memory for directory tree searches\n");
     end();
   } 
   if(argc!=2)
   {
     AcpError();
   }
   printf("\n\n");
   printf("SalvUser version 1.2, written by Joseph Hodge\n");
   strcpy(FileName,argv[1]); sr(FileName);
   strupr(FileName);
   if(!strcmp(FileName,"ACP"))
   {
     strcpy(FileName,"s:acp.startup");
     if(!TLock(FileName))
     {
       AcpError();
     }
     strcpy(BBSloc,"");
     fi=fopen(FileName,"r");
       while(fgets(image,90,fi)!=NULL)
       {
         sr(image);
         if(ParseImage(image,&t))
         {
           if(!strnicmp(&image[t.s1],"BBS_LOCATION",12))
           {
             strcpy(BBSloc,&image[t.s2]); continue;
           }
           if(!strnicmp(&image[t.s1],"CONF_LOCAL",10))
           {
              strcpy(ConfName,&image[t.s2+3]);
              if(ConfName[strlen(ConfName)-1]=='/')
                 ConfName[strlen(ConfName)-1]='\0';
              if(TLock(ConfName))
              {
                CList=(struct ConfList *)AllocConf();
                if(CList==NULL)
                {
                  printf("Can't Allocate memory for Conference List\n");
                  FreeConf();
                  end();
                }
                strcpy(CList->image,ConfName);
              }
              continue;
           }
         }
       }
       fclose(fi);
   }
   else
   {
     if(!TLock(FileName))
     {
       printf("Can't locate %s\n",FileName);
       AcpError();
     }
     fi=fopen(FileName,"rb");
     fread((APTR)&cfg,sizeof(struct Commands),1,fi);
     fclose(fi);
     for(i=0;i<9;i++)
     {
        strcpy(ConfName,cfg.ConfLoc[i]);
        if(ConfName[0]!='\0')
        {
          if(ConfName[strlen(ConfName)-1]=='/')
             ConfName[strlen(ConfName)-1]='\0';
          if(TLock(ConfName))
          {
            CList=(struct ConfList *)AllocConf();
            if(CList==NULL)
            {
              printf("Can't Allocate memory for Conference List\n");
              FreeConf();
              end();
            }
            strcpy(CList->image,ConfName);
          }
        }
      }
      strcpy(BBSloc,cfg.BBSLoc);
   }
   if(BBSloc[0]=='\0')
   {
     printf("Can't find BBS Location\n");
     end();
   }
   if(CFirst==NULL)
   {
     printf("Can't find Conference locations\n");
     end();
   }
   sprintf(FileName,"%sUser.Data",BBSloc);
   sprintf(Keys,"%sUser.Keys",BBSloc);
   sr(FileName);
   if(!TLock(FileName))
   {
     printf("Can't locate %s\n",FileName);
     printf("\n\n");
     end();
   } 
   sprintf(temp,"%s.old",FileName);
   if(TLock(temp))
   {
     DeleteFile(temp);
   }
   Rename(FileName,temp);
   if(TLock(Keys))
   {
     sprintf(Ktemp,"%s.old",Keys);
     if(TLock(Ktemp))
     {
       DeleteFile(Ktemp);
     }
     Rename(Keys,Ktemp);
   }
   printf("\n");
   printf("Original file %s has been backed up as %s\n",FileName,temp);
   printf("Original file %s has been backed up as %s\n",Keys,Ktemp);
   printf("\n");
 
   i=0;
   fi=fopen(temp,"rb");
   fo2=fopen(Keys,"ab");
   fo=fopen(FileName,"wb");
   printf("\n");
   while(fread((APTR)&U,sizeof(struct User),1,fi)!=NULL)
   {
      
       if(U.Slot_Number>0)
       { j +=1;
         if(U.Slot_Number!=j)
         {
           CheckPartUpload(U.Slot_Number,j);
         }
         U.Slot_Number=j;
        
       fwrite((APTR)&U,sizeof(struct User),1,fo); 
       printf("[ASalvaging: %3d->%3d >%-35.35s \n",i+1,j,U.Name);
       
       
     strcpy(K.UserName,U.Name);
      K.Number=(long)(U.Slot_Number);
     K.New_User=U.New_User;
     strcpy(K.Pad,"");
     fwrite((APTR)&K,sizeof(struct UserKeys),1,fo2);
     }
  else printf("[APacked   : %3d      >%-35.35s\n",i+1,U.Name);
     i +=1;
   } 
   printf("\n");
   fclose(fi);
   fclose(fo);
   fclose(fo2);
   printf("[31mRemoved[32m %d[31m Inactive Accounts out of[32m %d[31m Accounts[0m\n",i-j,i);
   printf("[31mPacked[33m %5.2f%%[31m of User DataBase[0m\n",(float)(((float)(i-j)/(float)i))*100.00);
   end();
}
void sr(char *str)
{
  register int i;
  i=strlen(str)-1;
  while(i>-1)
  {
    if(*(str+i)<=32) *(str+i)='\0'; else break;
    i--; 
  }
}
int TLock(char *str)
{
  long lock;
  if(lock=Lock(str,ACCESS_READ))
  {
    UnLock(lock); return(1);
  }
  
  return(0);
}

void end(void)
{
  char temp[255];
  free_pdir();
  if(dir_info)
  {
     FreeMem(dir_info,(long)sizeof(struct FileInfoBlock));
  }
  if(CFirst) FreeConf();
printf("Press [return] to continue\n");
gets(temp);
  exit(0);
}
void free_pdir()
{
   if ( pdir )
      {
      UnLock((BPTR)pdir);
      pdir=NULL;
       }
   return;   
}
struct ConfList *AllocConf()
{
  struct ConfList *p;
  
  p=(struct ConfList *)AllocMem(sizeof(struct ConfList),MEMF_PUBLIC|MEMF_CLEAR);
  if(p)
  {
    if(CList)CList->Next=(struct ConfList *)p;
    p->Next=NULL;
    if(!CFirst) CFirst=(struct ConfList *)p;
  }
  return((struct ConfList *)p);
}

void FreeConf()
{
  struct ConfList *p,*t;
  for(p=CFirst;p!=NULL;p=t)
  {
    t=p->Next;
    FreeMem((struct ConfList *)p,sizeof(struct ConfList));
    p=t;
  }
  CFirst=NULL;
  CList=NULL;
}
void AcpError()
   {
      printf("SalvUser version 1.2, written by Joseph Hodge\n");
      printf("compatible with AmiExpress 1.1x+\n");
      printf("Usage: SalvUser <ACP|configpath>\n");
      printf("   ie: SalvUser ACP\n");
      printf("       SalvUser BBS:Config1\n");
      printf("\n");
      end();
   }

void CheckPartUpload(int old,int new)
{
   char key[20];
   char image[200];
   struct ConfList *p;
   sprintf(key,"@%d",old);
   p=CFirst;
   for(p=CFirst;p!=NULL;p=p->Next)
   {
    
      LookFor(p->image,old,new);
   }
}
void LookFor(char *Part,int old,int new)
{
  REGISTER int i=0;
  REGISTER int j=0;
  char ch;
  char image[200];
  char t[200];
  char name[200];
  char p[200];
  char PartUpload[200];
  int breakhard=1;
  sprintf(PartUpload,"%s/PartUpload",Part);
  while(breakhard)
  {
    free_pdir();
    if(!(pdir=(struct FileLock *)Lock(PartUpload,(ULONG)ACCESS_READ)))
    {
      free_pdir();
      return;
    }
    if(!Examine((BPTR)pdir,dir_info))
    { 
      free_pdir();
      return;
    }
    breakhard=0;
    while(ExNext((BPTR)pdir,dir_info))
    {
      strcpy(name,dir_info->fib_FileName);
      if(GetUN(name)==old)
      {
        sprintf(image,"%s/PartUpload/%s",Part,name);
        i=0;
        while(1)
        {
          if(image[i]==NULL) break;
          if(image[i]=='@') {image[i]='\0'; break; }
          i++;
        }
        free_pdir();
        sprintf(t,"%s@%d",image,new);
        sprintf(p,"%s@%d",image,old);
        if(TLock(t)) DeleteFile(t);
        Rename(p,t);
        breakhard=1;
        printf("Renaming %s\n",p);
        printf("         %s\n\n",t);
        break;
      }
        
      
    }
  }
}

int strnicmp(char *str1,char *str2,int len)
{
  register int i;
  strupr(str1);
  strupr(str2);
  i=0;
  while(i<len)
  {
    if(*(str1+i)!=*(str2+i)) return(1);
    i++;
  }
  return(0);
}
int GetUN(char *SA)
{
int x,N;

for(x=0; x<strlen(SA); x++)
	{
	if(SA[x]=='@')
		{
		strcat(SA," ");
		N=(int)atol(SA+x+1);
		SA[x]='\00';
		return(N);
		}
	}
return(0);
}
