#include <stdlib.h>
#include <string.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/dlg.h>

#include <dlg/Msg.h>

#include <pragmas/dlg.h>

/// Old Area Def
/*
** Old message area (file area) definition
**
 *********************************************/

struct Old_Area
{
  char   Name[34];
  SHORT  AADef;
  long   Capacity;        // --> SHORT
  long   Number;          // --> SHORT
  char   Flag;
  SHORT  UpperLimit;
  unsigned char llevel;   /* lowest level that can gain access             */
  unsigned char ulevel;   /* highest level that can gain access            */
  char   path[8];         /* used only in file areas (alternate file path) */
  char   processor[12];   /* batchfile used to process the text            */
  char   origin[75];      /* custom origin line for this area              */
  unsigned char uwrite;   /* highest level that can write                  */
  unsigned char lwrite;   /* lowest level that can write                   */
  unsigned char ukill;    /* highest level that can kill                   */
  unsigned char lkill;    /* lowest level that can kill                    */
  unsigned char uforward; /* highest level that can forward                */
  unsigned char lforward; /* lowest level that can forward                 */
  unsigned char ucopy;    /* highest level that can copy                   */
  unsigned char lcopy;    /* lowest level that can copy                    */
  unsigned char uedit;    /* highest level that can edit                   */
  unsigned char ledit;    /* lowest level that can edit                    */
  unsigned char usysop;   /* highest level that can have sysop access      */
  unsigned char lsysop;   /* lowest level that can have sysop access       */
  char          forceset; /* not used                                      */
  unsigned char loadcharset; /* not used                                   */
  unsigned char savecharset; /* alternate character set for this area      */
  char unused[33];           /* not used                                   */
};
//-


static char version[]="$VER: ConvertSIGs 1.3 © 1997-1998 by DLG Development ("__AMIGADATE__")";

BPTR  sout;
BPTR  fh =  NULL;

struct   Library    *DLGBase  =  NULL;

struct   Old_Area   *OA       =  NULL;
struct   Msg_Area   *NA       =  NULL;

void  ShutDown(int, char *);
void  Usage(void);
void _CXBRK(void);

/// Main
int main(int argc, char **argv)
{
   char *iname;

   long  NumAreas = 0;

   ULONG fsize = 0;
   long  i = 0;

   struct   Old_Area *OldArea;
   struct   Msg_Area *NewArea;
   struct   SearchCookie *sc;

   sout = Output();

   DLGBase = OpenLibrary("dlg.library",2L);

   if(!DLGBase) ShutDown(10,"Could not open dlg.library!");

   AFPrintf(NULL,sout,"\nFile Sigs....\n\n");

/// Search for file sigs
   sc = SearchStart("DLGConfig:Sigs","*.file");

   if(sc)
   {
      while(iname = SearchNext(sc))
      {
         char fname[256];
         char bname[256];

         if(!Stricmp(iname,"SIGS.file"))  continue;

         ASPrintf(NULL,fname,"DLGConfig:Sigs/%s",iname);
         AFPrintf(NULL,sout,"%s  -->  ",fname);

         ASPrintf(NULL,bname,"%sbak",fname);
         AFPrintf(NULL,sout,"%s\n",fname);

         Copy(fname,bname);

         if(-1 == FileSize(fname,&fsize))
         {
            AFPrintf(NULL,sout,"Could not find %s!",fname);
            continue;
         }

///      If SIG contains no areas, create a new file with 0 bytes
         if(fsize == 0)
         {
            fh = Open(fname,MODE_NEWFILE);
            Close(fh);
            fh = NULL;
            continue;
         }
//-

         if(fsize % sizeof(struct Old_Area))
         {
            AFPrintf(NULL,sout,"SIG structure corrupt or already converted\n");
            continue;
         }

         NumAreas = fsize / sizeof(struct Old_Area);

         AFPrintf(NULL,sout,"\tContains %ld areas\n",NumAreas);

         OA = calloc(NumAreas,sizeof(struct Old_Area));

         if(!OA)
         {
            AFPrintf(NULL,sout,"\tError: not converted\n");
            continue;
         }

         NA = calloc(NumAreas,sizeof(struct Msg_Area));

         if(!NA)
         {
            AFPrintf(NULL,sout,"\tError: not converted\n");
            free(OA);
            OA = NULL;
            continue;
         }


         fh = Open(fname,MODE_OLDFILE);

         if(!fh)
         {
            AFPrintf(NULL,sout,"\tError: not converted\n");
            free(OA);
            free(NA);
            OA = NULL;
            NA = NULL;
            continue;
         }

         i = Read(fh,OA,fsize);
         Close(fh);
         fh = NULL;

         if(i != fsize)
         {
            AFPrintf(NULL,sout,"\tError: not converted\n");
            free(OA);
            free(NA);
            OA = NULL;
            NA = NULL;
            continue;
         }

         AFPrintf(NULL,sout,"\t%ld Areas to convert.\n",NumAreas);

///   Convert file area definitions
         for(i = 0; i < NumAreas; i++)
         {
            Chk_Abort();
            OldArea = OA + i;
            NewArea = NA + i;
            AFPrintf(NULL,sout,"\t[%4.4ld] [%4.4ld] %-34.34s\r",i,OldArea->Number,OldArea->Name);

            strcpy(NewArea->Name,OldArea->Name);

            NewArea->UpperLimit = OldArea->UpperLimit;

            memcpy(NewArea->path,OldArea->path,8);
            memcpy(NewArea->processor,OldArea->processor,12);

            strcpy(NewArea->origin,OldArea->origin);

            NewArea->Number = (SHORT)OldArea->Number;

            NewArea->llevel = OldArea->llevel;
            NewArea->ulevel = OldArea->ulevel;
            NewArea->lwrite     = OldArea->lwrite;
            NewArea->uwrite     = OldArea->uwrite;
            NewArea->lcopy     = OldArea->lcopy;
            NewArea->ucopy     = OldArea->ucopy;
            NewArea->lkill    = OldArea->lkill;
            NewArea->ukill    = OldArea->ukill;
            NewArea->lforward   = OldArea->lforward;
            NewArea->uforward   = OldArea->uforward;
            NewArea->ledit   = OldArea->ledit;
            NewArea->uedit   = OldArea->uedit;
            NewArea->lsysop  = OldArea->lsysop;
            NewArea->usysop  = OldArea->usysop;

            NewArea->Capacity = (SHORT)OldArea->Capacity;

            NewArea->Flag = OldArea->Flag;

            NewArea->forceset = OldArea->forceset;
            NewArea->loadcharset = OldArea->loadcharset;
            NewArea->savecharset = OldArea->savecharset;
         }

         free(OA);
         OA = NULL;

         AFPrintf(NULL,sout,"\n");
//-

///   Write out new definition

         AFPrintf(NULL,sout,"\tWriting new SIG def\n");

         fh = Open(fname,MODE_NEWFILE);

         if(!fh)
         {
            AFPrintf(NULL,sout,"\tCould not create new area index");
            free(NA);
            NA = NULL;
            continue;
         }

         Write(fh,NA,(NumAreas * sizeof(struct Msg_Area)));
         Close(fh);
         fh = NULL;
//-

         free(NA);
         NA = NULL;

         AFPrintf(NULL,sout,"\tDone!\n\n");
      }

      SearchEnd(sc);
   }
//-

   if(sc) sc = NULL;

   AFPrintf(NULL,sout,"\nMessage SIGs ... \n\n");

/// Search for message sigs
   sc = SearchStart("DLGConfig:Sigs","*.msg");

   if(sc)
   {
      while(iname = SearchNext(sc))
      {
         char fname[256];
         char bname[256];

         if(!Stricmp(iname,"SIGS.msg"))  continue;

         ASPrintf(NULL,fname,"DLGConfig:Sigs/%s",iname);
         AFPrintf(NULL,sout,"%s  -->  ",fname);

         ASPrintf(NULL,bname,"%sbak",fname);
         AFPrintf(NULL,sout,"%s\n",fname);

         Copy(fname,bname);

         if(-1 == FileSize(fname,&fsize))
         {
            AFPrintf(NULL,sout,"Could not find %s!",fname);
            continue;
         }

///      If SIG contains no areas, create a new file with 0 bytes
         if(fsize == 0)
         {
            fh = Open(fname,MODE_NEWFILE);
            Close(fh);
            fh = NULL;
            continue;
         }
//-

         if(fsize % sizeof(struct Old_Area))
         {
            AFPrintf(NULL,sout,"SIG structure corrupt or already converted\n");
            continue;
         }

         NumAreas = fsize / sizeof(struct Old_Area);

         AFPrintf(NULL,sout,"\tContains %ld areas\n",NumAreas);

         OA = calloc(NumAreas,sizeof(struct Old_Area));

         if(!OA)
         {
            AFPrintf(NULL,sout,"\tError: not converted\n");
            continue;
         }

         NA = calloc(NumAreas,sizeof(struct Msg_Area));

         if(!NA)
         {
            AFPrintf(NULL,sout,"\tError: not converted\n");
            free(OA);
            OA = NULL;
            continue;
         }


         fh = Open(fname,MODE_OLDFILE);

         if(!fh)
         {
            AFPrintf(NULL,sout,"\tError: not converted\n");
            free(OA);
            free(NA);
            OA = NULL;
            NA = NULL;
            continue;
         }

         i = Read(fh,OA,fsize);
         Close(fh);
         fh = NULL;

         if(i != fsize)
         {
            AFPrintf(NULL,sout,"\tError: not converted\n");
            free(OA);
            free(NA);
            OA = NULL;
            NA = NULL;
            continue;
         }

         AFPrintf(NULL,sout,"\t%ld Areas to convert.\n",NumAreas);

///   Convert file area definitions
         for(i = 0; i < NumAreas; i++)
         {
            Chk_Abort();
            OldArea = OA + i;
            NewArea = NA + i;
            AFPrintf(NULL,sout,"\t[%4.4ld] [%4.4ld] %-34.34s\r",i,OldArea->Number,OldArea->Name);

            strcpy(NewArea->Name,OldArea->Name);

            NewArea->UpperLimit = OldArea->UpperLimit;

            memcpy(NewArea->path,OldArea->path,8);
            memcpy(NewArea->processor,OldArea->processor,12);

            strcpy(NewArea->origin,OldArea->origin);

            NewArea->Number = (SHORT)OldArea->Number;

            NewArea->llevel = OldArea->llevel;
            NewArea->ulevel = OldArea->ulevel;
            NewArea->lwrite     = OldArea->lwrite;
            NewArea->uwrite     = OldArea->uwrite;
            NewArea->lcopy     = OldArea->lcopy;
            NewArea->ucopy     = OldArea->ucopy;
            NewArea->lkill    = OldArea->lkill;
            NewArea->ukill    = OldArea->ukill;
            NewArea->lforward   = OldArea->lforward;
            NewArea->uforward   = OldArea->uforward;
            NewArea->ledit   = OldArea->ledit;
            NewArea->uedit   = OldArea->uedit;
            NewArea->lsysop  = OldArea->lsysop;
            NewArea->usysop  = OldArea->usysop;

            NewArea->Capacity = (SHORT)OldArea->Capacity;

            NewArea->Flag = OldArea->Flag;

            NewArea->forceset = OldArea->forceset;
            NewArea->loadcharset = OldArea->loadcharset;
            NewArea->savecharset = OldArea->savecharset;
         }

         free(OA);
         OA = NULL;

         AFPrintf(NULL,sout,"\n");
//-

///   Write out new definition

         AFPrintf(NULL,sout,"\tWriting new SIG def\n");

         fh = Open(fname,MODE_NEWFILE);

         if(!fh)
         {
            AFPrintf(NULL,sout,"\tCould not create new area index");
            free(NA);
            NA = NULL;
            continue;
         }

         Write(fh,NA,(NumAreas * sizeof(struct Msg_Area)));
         Close(fh);
         fh = NULL;
//-

         free(NA);
         NA = NULL;

         AFPrintf(NULL,sout,"\tDone!\n\n");
      }

      SearchEnd(sc);
   }
//-

   ShutDown(0,NULL);
}
//-

/// ShutDown
void ShutDown(int Error, char *ErrStr)
{
   if(OA)      free(OA);
   if(NA)      free(NA);

   if(fh)      Close(fh);

   if(DLGBase) CloseLibrary(DLGBase);

   if(Error)
   {
      FPuts(sout,ErrStr);
      FPuts(sout,"\n\n");
   }

   exit(Error);
}
//-

/// _CXBRK
void _CXBRK()
{
   ShutDown(5,"Control-C Detected");
}
//-



