#define   ANSICOL

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <fcntl.h>
#include <stat.h>
#include <exec/types.h>
#include <libraries/dosextens.h>
#include <devices/tpt.h>

#include <dlg/dlg.h>
#include <dlg/user.h>
#include <dlg/msg.h>
#include <dlg/input.h>
#include <dlg/menu.h>
#include <dlg/resman.h>
#include <dlg/log.h>
#include <dlg/file.h>

#include <link/area.h>
#include <link/config.h>
#include <link/io.h>
#include <link/user.h>

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

#include <pragmas/dlg.h>

#include <private/Version.h>
#define  ObjRev "3"
const UBYTE version[]="\0$VER: MsgAreas " BUILDVER "." ObjRev " ©" COPYRIGHT " by Digerati Dreams "__AMIGADATE__;


void  main(int , char **);
int   HandleBuiltIn(UBYTE );
void _CXBRK(void);

BYTE  Add_Area(void);
BYTE  Edit_Area(void);
void  Replace_Area(void);
void _Replace_Area(char *);
void  Delete_Area(long);
BOOL _Delete_Area(long , char *, char *);
void  AA_Flags(struct Msg_Area *);
BYTE  Sort_List(char *);
BYTE  Load_Users(void);
int   cmpnumbers(struct Msg_Area *, struct Msg_Area *);
BOOL  DeleteMsgs(long area);
BOOL  Move_Area(void);
int   CompareWM(struct WaitingMail *, struct WaitingMail *);


#define INSTACK RStruct.Command_Stack[0]
#define STK     RStruct.Command_Stack
#define HOT     UserDat.Hot_Keys


struct Msg_Area    Area;
struct USER_DATA   UserDat;
struct Ram_File    RStruct;
struct UserInfo    ui      = {&UserDat, &RStruct};
struct NameStruct *users;
char               Ext[4];

char               Overlay      =  FALSE;
char               MenuName[13] = "MSGA_Main";
char               exitflag     =  FALSE;

/// Main menu commands
#define NUMENTRIES 7

struct NewShortMenu Menu[NUMENTRIES]=
{
   {"Abort",1},         //  0
   {"MSGA_Add",1},      //  1
   {"MSGA_Delete",1},   //  2
   {"MSGA_Edit",1},     //  3
   {"MSGA_Exit",1},     //  4
   {"MSGA_List",1},     //  5
   {"MSGA_Move",1},     //  6
};

#define  MA 1     // MSGA_Add
#define  MD 2     // MSGA_Delete
#define  ME 3     // MSGA_Edit
#define  MX 4     // MSGA_Exit
#define  ML 5     // MSGA_List
#define  MM 6     // MSGA_Move
//-

BPTR               sout;
struct Library    *DLGBase = NULL;
struct LangStruct *ls;
char             **SA;

/// Main
void main(int argc,char **argv)
{
   char *s;
   char *stack = NULL;

   sout = Output();
   if (!(DLGBase = OpenLibrary(DLGNAME, DLGVERSION)))  exit(5);

   while(--argc > 0)
   {
      s = *++argv;

      if (*s++=='-')
      {
         while(*s)
         {
            switch(toupper(*s))
            {
               case  'O':
                  Overlay=TRUE;
                  break;

               case 'S':
                  if (!--argc)  break;
                  stack = *++argv;
                  break;

               case 'M':
                  if (!--argc)  break;
                  strncpy(MenuName,*++argv,12);
                  MenuName[12]='\0';
                  break;
            }
            s++;
         }
      }
   }


   if (GetDevName(Ext) == -1)            _CXBRK();
   if (!(ls = GetLang(Ext)))             _CXBRK();
   SA = ls->strings;

   if (!ReadUser(&RStruct,&UserDat,Ext))  _CXBRK();
   if (stack)                             InsertStack(STK, stack);

   WriteLog(SYSOP_CONFIG,RStruct.Name,Ext,SA[1315]);

   while(!exitflag)
   {
      Chk_Abort();

      if (MenuInput(MenuName, Ext, "MSGA", Menu, NUMENTRIES, HandleBuiltIn,
          &UserDat, &RStruct, UserDat.Help_Level, NULL) == MENUNOTFOUND)
         _CXBRK();
   }

   _CXBRK();
}
//-

/// HandleBuiltIn
int HandleBuiltIn(UBYTE cmd)
{
   long area;

   switch(cmd) 
   {
      case 0:         /* Abort */
         exitflag = TRUE;
         break;

      case 1:         /* MSGA_Add */
         Add_Area();
         break;

      case 2:         /* MSGA_Delete */
         area=iinput(1,999999,0, SA[1316]);
         AFPrintf(&UserDat,sout,"\n\n");
         if (!area)  break;
         Delete_Area(area);
         break;

      case 3:         /* MSGA_Edit */
         Edit_Area();
         break;

      case 4:         /* MSGA_Exit */
         _CXBRK();
         break;

      case 5:         /* MSGA_List */
         AFPrintf(&UserDat,sout,"\n\n");
         ListAreas(NULL,&UserDat,0,0);
         break;

      case 6:         /* MSGA_Move */
         Move_Area();
         break;
   }

   return(TRUE);
}
//-

/// _CXBRK
void _CXBRK(void)
{
   WriteRam(&RStruct,Ext);

   if (!Overlay) ChainProgram("DLG:Menu", Ext);
   CloseLibrary(DLGBase);

   exit(0);
}
//-

/// Add_Area
BYTE Add_Area(void) 
{
   BPTR lock;
   long zflag;
   char dirname[20],filename[80];
   int fp,a;

   if (!(a = iinput(1,999999,0, SA[1417])))
   {
      AFPrintf(&UserDat,sout,SA[1318]);
      return(0);
   }

   AFPrintf(&UserDat,sout,"\n\n");

   if (ReadArea(a, &Area, 0))
   {
      AFPrintf(&UserDat,sout,SA[1319]);
      return(0);
   }

   Area.Number=a;

   if (!(DLGInput(NULL,Area.Name,NULL,26,26,0, SA[1320])))
   {
      AFPrintf(&UserDat,sout,SA[1321]);
      return(0);
   }
   AFPrintf(&UserDat,sout,"\n\n");

   Area.Flag = 0;
   zflag=finput(1, SA[1322]);
   AFPrintf(&UserDat,sout,"\n");

   if (zflag)
   {
      Area.Flag   = Area.Flag | AUTO_ACCESS_AREA;
      Area.llevel = iinput(0,255,1, SA[1323]);
      Area.ulevel = iinput(0,255,1, SA[1324]);
      AFPrintf(&UserDat,sout,"\n");
   }
   else
   {
      Area.llevel =  1;
      Area.ulevel = 255;
   }

   Area.uwrite=Area.ukill=Area.uforward=Area.ucopy=Area.uedit=Area.ulevel;
   Area.lwrite=Area.lkill=Area.lforward=Area.lcopy=Area.ledit=Area.llevel;
   Area.lsysop=Area.usysop=255;

   AA_Flags(&Area);

   if (finput(0, SA[1325]))        Area.Flag |= HANDLES_AREA;
   if (finput(0, SA[1326]))        Area.Flag |= SIGNATURE_AREA;
   if (finput(0, SA[1327]))        Area.Flag |= ECHO_AREA;

   if (Area.Flag & ECHO_AREA)
      if (finput(1, SA[1328]))    Area.Flag |= HIDE_SEENBY;

   if (!(Area.Flag & ECHO_AREA))
      if (finput(0, SA[1329]))  Area.Flag |= NETMAIL_AREA;

   if (finput(0, SA[1330]))        Area.Flag |= NEWSGROUP_AREA;

   AFPrintf(&UserDat,sout,"\n");
   strcpy(Area.origin,"");

   if (Area.Flag&NEWSGROUP_AREA)
   {
      DLGInput(NULL,Area.origin,NULL,74,74,0, SA[1331]);
      AFPrintf(&UserDat,sout,"\n");
   }

   if (Area.Flag&ECHO_AREA && !(Area.Flag&NEWSGROUP_AREA))
   {
      DLGInput(NULL,Area.origin,NULL,74,74,0, SA[1332]);
      AFPrintf(&UserDat,sout,"\n");
   }

   DLGInput(NULL,Area.processor,NULL,11,11,0, SA[1333]);
   ASPrintf(NULL,dirname,"MSG:%ld",Area.Number);

   Area.Capacity   = iinput(10,9000,100, SA[1334]);
   Area.UpperLimit = (SHORT)iinput(10,10000,500, SA[1335]);
   AFPrintf(&UserDat,sout,"\n");

   ListSets(255);
   Area.savecharset = iinput(1,255,0, SA[1336]);
   AFPrintf(&UserDat,sout,"\n");

   if (!Exists(dirname))
   {
      if (!(lock=CreateDir(dirname)))
      {
         AFPrintf(&UserDat,sout,SA[1337]);
         return(0);
      }

      UnLock(lock);
      AFPrintf(&UserDat,sout,SA[1338]);
   }

   if ((fp = open("MSG:Area.BBS",O_CREAT | O_WRONLY | O_APPEND)) == EOF)
   {
      AFPrintf(&UserDat,sout,SA[1339]);
      return(0);
   }

   lseek(fp,0L,2);
   write(fp,&Area,sizeof(Area));
   close(fp);

   AFPrintf(&UserDat,sout,SA[1340]);
   ASPrintf(NULL,filename,"MSG:%ld/User.MSG",Area.Number);
   fp = open(filename,O_RDWR | O_CREAT);
   close(fp);

   if (Area.Flag & AUTO_ACCESS_AREA)
   {
      zflag=finput(1, SA[1341]);
      AFPrintf(&UserDat,sout,"\n\n");
      if (zflag)  AddGlobalArea(Area.ulevel,Area.llevel,Area.Number,0,0,Ext);
   }

   Sort_List("MSG:Area.BBS");

   if (BoolQuery("Add area to SIGs?", 0, &ui))
   {
      BPTR sfh = NULL;

      struct SIG_Def sdef;

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

      sfh = Open("DLGConfig:SIGs/Sigs.msg",MODE_OLDFILE);

      if(sfh)
      {
         char sigtemp[256];

         while(Read(sfh,&sdef,sizeof(struct SIG_Def)) == sizeof(struct SIG_Def))
         {
            ASPrintf(&UserDat,sigtemp,"%a5Add to SIG %a2[%a7%s%a2]%a5?",sdef.name);

            if (BoolQuery(sigtemp, 0, &ui))
            {
               BPTR sffh = NULL;
               char sigfilename[256];

               ASPrintf(NULL,sigfilename,"DLGConfig:SIGS/%s.msg",sdef.name);

               sffh = Open(sigfilename,MODE_READWRITE);

               if(sffh)
               {
                  Seek(sffh,0,OFFSET_END);
                  Write(sffh,&Area,sizeof(struct Msg_Area));
                  Close(sffh); sffh = NULL;
                  Sort_List(sigfilename);
                  AFPrintf(NULL,sout,"... added.\n");
               }
               else
               {
                  AFPrintf(NULL,sout,"... failed.\n");
               }
            }
            else
            {
               AFPrintf(NULL,sout,"\n");
            }
         }

         Close(sfh);
      }
   }
   else
   {
      AFPrintf(NULL, sout, "\n");
   }

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


}
//-

/// Edit_Area
BYTE Edit_Area(void)
{
   long  zflag;
   long area;
   long number,oupper,olower;
   char areachange,levelchanged=0;

   olower = Area.llevel;
   oupper = Area.ulevel;

   areachange = 0;
   area       = iinput(1,999999,0, SA[1342]);
   AFPrintf(&UserDat,sout,"\n\n");

   if (!ReadArea(area, &Area, 0))
   {
      AFPrintf(&UserDat,sout,SA[1343]);
      return(0);
   }

   while(TRUE)
   {
      AFPrintf(&UserDat,sout,SA[1344]);
      AFPrintf(&UserDat,sout,SA[1345],Area.Name,Area.Number);
      AFPrintf(&UserDat,sout,SA[1346],(Area.Flag&1)?SA[1347]:SA[1348],(Area.Flag&1)?Area.llevel:0,(Area.Flag&1)?Area.ulevel:0);
      AFPrintf(&UserDat,sout,SA[1349]);
      AFPrintf(&UserDat,sout,SA[1350],Area.lwrite,Area.uwrite);
      AFPrintf(&UserDat,sout,SA[1351],Area.lkill,Area.ukill);
      AFPrintf(&UserDat,sout,SA[1352],Area.lforward,Area.uforward);
      AFPrintf(&UserDat,sout,SA[1353],Area.lcopy,Area.ucopy);
      AFPrintf(&UserDat,sout,SA[1354],Area.ledit,Area.uedit);
      AFPrintf(&UserDat,sout,SA[1355],Area.lsysop,Area.usysop);
      
      if (Area.Flag & ECHO_AREA)
      {
         AFPrintf(&UserDat,sout,SA[1356]);

         if (Area.Flag & HIDE_SEENBY)
            AFPrintf(&UserDat,sout,SA[1347]);
         else
            AFPrintf(&UserDat,sout,SA[1348]);
      }

      AFPrintf(&UserDat,sout,SA[1357]);

      if (Area.Flag & HANDLES_AREA)
         AFPrintf(&UserDat,sout,SA[1347]);
      else
         AFPrintf(&UserDat,sout,SA[1348]);

      AFPrintf(&UserDat,sout,SA[1358]);

      if (Area.Flag & SIGNATURE_AREA)
         AFPrintf(&UserDat,sout,SA[1347]);
      else
         AFPrintf(&UserDat,sout,SA[1348]);

      AFPrintf(&UserDat,sout,SA[1359]);

      if (Area.Flag & ECHO_AREA)
         AFPrintf(&UserDat,sout,SA[1347]);
      else
         AFPrintf(&UserDat,sout,SA[1348]);

      AFPrintf(&UserDat,sout,SA[1360]);

      if (Area.Flag & NETMAIL_AREA)
         AFPrintf(&UserDat,sout,SA[1347]);
      else
         AFPrintf(&UserDat,sout,SA[1348]);

      AFPrintf(&UserDat,sout,SA[1361]);

      if (Area.Flag & NEWSGROUP_AREA)
         AFPrintf(&UserDat,sout,SA[1347]);
      else
         AFPrintf(&UserDat,sout,SA[1348]);

      if (Area.Flag & NEWSGROUP_AREA)
         AFPrintf(&UserDat,sout,SA[1362],Area.origin);
      else
         AFPrintf(&UserDat,sout,SA[1363],Area.origin);

      AFPrintf(&UserDat,sout,SA[1364],Area.processor);
      AFPrintf(&UserDat,sout,SA[1365],Area.Capacity);
      AFPrintf(&UserDat,sout,SA[1366],Area.UpperLimit);
      AFPrintf(&UserDat,sout,SA[1367],Area.savecharset);

      number = iinput(1,14,0, SA[1368]);

      AFPrintf(NULL,sout,"\n\n");
      
      switch(number)
      {
         case 0:
            if (areachange)
            {
               zflag = finput(1, SA[1369]);
               AFPrintf(&UserDat,sout,"\n\n");

               if (zflag)
               {
                  Replace_Area();

                  if (Area.Flag & AUTO_ACCESS_AREA && levelchanged)
                  {
                     if (olower!=Area.llevel || oupper!=Area.ulevel)
                     {
                        AFPrintf(&UserDat,sout,SA[1370]);
                        AlignAreas(&Area,0);
                        levelchanged++;
                     }

                     zflag = finput(1, SA[1341]);
                     AFPrintf(&UserDat,sout,"\n\n");
                     if (zflag)
                        AddGlobalArea(Area.ulevel,Area.llevel,Area.Number,0,2,Ext);
                  }
               }
            }

            return(0);

         case 1:  // Area Name
            DLGInput(NULL,Area.Name,Area.Name,26,26,0, SA[1371]);
            areachange = 1;
            AFPrintf(&UserDat,sout,"\n\n");
            break;

         case 2:  // Auto-Access toggle
            if (Area.Flag & 1)
               Area.Flag = Area.Flag & ~AUTO_ACCESS_AREA;
            else
               Area.Flag = Area.Flag | AUTO_ACCESS_AREA;

            areachange = 1;

            if (Area.Flag & AUTO_ACCESS_AREA)
            {
               Area.llevel=iinput(0,255,1, SA[1372]);
               Area.ulevel=iinput(0,255,1, SA[1324]);
               AFPrintf(&UserDat,sout,"\n\n");
            }
            else
            {
               Area.llevel=0;
               Area.ulevel=0;
            }

            if (Area.Flag & AUTO_ACCESS_AREA)
            {
               zflag = finput(1, SA[1341]);
               AFPrintf(&UserDat,sout,"\n\n");

               if (zflag)
                  AddGlobalArea(Area.ulevel,Area.llevel,Area.Number,0,2,Ext);
            }

            AFPrintf(&UserDat,sout,SA[1373]);
            PurgeArea(Area.llevel,Area.ulevel,Area.Number,0);
            AFPrintf(&UserDat,sout,"\n");
            break;

         case 3:  // Access flags
            AA_Flags(&Area);
            AFPrintf(&UserDat,sout,"\n");
            areachange = 1;
            break;

         case 4:  // Hide Seenbye toggle
            if (Area.Flag & HIDE_SEENBY)
               Area.Flag = Area.Flag & ~HIDE_SEENBY;
            else
               Area.Flag = Area.Flag | HIDE_SEENBY;

            areachange = 1;
            break;

         case 5:  // Handles toggle
            if (Area.Flag & HANDLES_AREA)
               Area.Flag = Area.Flag & ~HANDLES_AREA;
            else
               Area.Flag = Area.Flag | HANDLES_AREA;

            areachange = 1;
            break;

         case 6:  // Signature Toggle
            if (Area.Flag & SIGNATURE_AREA)
               Area.Flag = Area.Flag & ~SIGNATURE_AREA;
            else
               Area.Flag = Area.Flag | SIGNATURE_AREA;

            areachange = 1;
            break;

         case 7:  // Echomail toggle
            if (Area.Flag & ECHO_AREA)
               Area.Flag = Area.Flag & ~ECHO_AREA;
            else
               Area.Flag = Area.Flag | ECHO_AREA;

            areachange = 1;
            break;

         case 8:  // Netmail toggle
            if (Area.Flag & NETMAIL_AREA)
               Area.Flag = Area.Flag & ~NETMAIL_AREA;
            else
               Area.Flag = Area.Flag | NETMAIL_AREA;

            areachange = 1;
            break;

         case 9:  // Newsgroup toggle
            if (Area.Flag & NEWSGROUP_AREA)
               Area.Flag = Area.Flag & ~NEWSGROUP_AREA;
            else
               Area.Flag = Area.Flag | NEWSGROUP_AREA;

            areachange = 1;
            break;

         case 10: // Get newsgroup name or origin line
            if (Area.Flag & NEWSGROUP_AREA)
               DLGInput(NULL,Area.origin,Area.origin,74,74,0, SA[1374]);

            if (Area.Flag & ECHO_AREA && !(Area.Flag & NEWSGROUP_AREA))
               DLGInput(NULL,Area.origin,Area.origin,74,74,0, SA[1332]);

            AFPrintf(&UserDat,sout,"\n\n");
            areachange = 1;
            break;

         case 11: // batch file processor translator
            DLGInput(NULL,Area.processor,NULL,11,11,0, SA[1375]);
            AFPrintf(&UserDat,sout,"\n\n");
            areachange = 1;
            break;

         case 12: // Capacity
            Area.Capacity = iinput(10,9000,100, SA[1376]);
            AFPrintf(&UserDat,sout,"\n\n");
            areachange = 1;
            break;

         case 13: // Upper limit
            Area.UpperLimit = (SHORT)iinput(10,10000,500, SA[1377]);
            AFPrintf(&UserDat,sout,"\n\n");
            areachange = 1;
            break;

         case 14: // character set
            ListSets(255);
            Area.savecharset = iinput(1,255,0, SA[1378]);
            AFPrintf(&UserDat,sout,"\n\n");
            areachange = 1;
            break;
      }
   }
}
//-

/// Replace_Area
void Replace_Area(void)
{
   struct SIG_Def Sig;
   char           filename[64];
   int            fp;

   _Replace_Area("MSG:Area.bbs");

   if ((fp=open("DLGCONFIG:Sigs/Sigs.msg",O_RDONLY))==EOF)
   {
      AFPrintf(&UserDat,sout,SA[1379]);
      return;
   }

   while(read(fp,&Sig,sizeof(Sig))==sizeof(Sig))
   {
      ASPrintf(NULL,filename,"DLGCONFIG:Sigs/%s.msg",Sig.name);
      _Replace_Area(filename);
   }

   AFPrintf(&UserDat,sout,"\n");
   close(fp);
   return;
}
//-

/// _Replace_Area
void _Replace_Area(char *filename)
{
   BPTR     fp;
   struct   Msg_Area temparea;

   AFPrintf(&UserDat,sout,SA[1380],filename);

   fp = Open(filename,MODE_READWRITE);

   if (fp == NULL)  return;

   while(Read(fp,&temparea,sizeof(temparea)) == sizeof(temparea))
   {
      if (temparea.Number == Area.Number)
      {
         Seek(fp,0 - (sizeof(struct Msg_Area)), OFFSET_CURRENT);
         Write(fp,&Area,sizeof(struct Msg_Area));
         // "done"
         AFPrintf(&UserDat,sout,SA[1381]);
         Close(fp);
         return;
      }
   }

   Close(fp);

   // "unchanged"
   AFPrintf(&UserDat,sout,SA[1382]);
   return;
}
//-

/// Delete_Area
void Delete_Area(long area)
{
   char           filename[64];
   char           deldir[80];
   char           string[80];

   int            fp;

   long           zflag;

   struct SIG_Def Sig;
   struct Msg_Area ma;

   if (area == 0)  return;

   if(!ReadArea(area,&ma,0))
   {
      AFPrintf(&UserDat,sout,"Could not find area!\n");
      return;
   }

//   ASPrintf(&UserDat,string,"Delete message area [%ld] \"%s\" - are you sure",area,ma.Name);
   ASPrintf(&UserDat,string,SA[1383],area,ma.Name);
   zflag = finput(string,0);
   AFPrintf(&UserDat,sout,"\n\n");
   if (!zflag)  return;
   ASPrintf(NULL,deldir,"MSG:%ld",area);

   DeleteMsgs(area);

   if (DelDir(deldir, &UserDat))
      AFPrintf(&UserDat,sout,SA[1384]);
   else
      AFPrintf(&UserDat,sout,SA[1385]);

   if (_Delete_Area(area,"MSG:Area.bbs","MSG:temp.bbs"))
   {
      if ((fp=open("DLGCONFIG:Sigs/Sigs.msg",O_RDONLY))!=EOF)
      {
         while(read(fp,&Sig,sizeof(struct SIG_Def))==sizeof(struct SIG_Def))
         {
            ASPrintf(NULL,filename,"DLGCONFIG:Sigs/%s.msg",Sig.name);
            _Delete_Area(area,filename,"DLGCONFIG:Sigs/temp.msg");
         }
         close(fp);
      }

      AddGlobalArea(0,0,area,0,1,Ext);
   }

   return;
}
//-

/// _Delete_Area
BOOL _Delete_Area(long area,char *filename,char *tempfile)
{
   int fp,ft;

   if ((fp = open(filename,O_RDONLY)) == EOF)
   {
      AFPrintf(&UserDat,sout,SA[1386],filename);
      return(FALSE);
   }

   if ((ft = open(tempfile,O_WRONLY | O_CREAT )) == EOF)
   {
      AFPrintf(&UserDat,sout,SA[1387],tempfile);
      close(fp);
      return(FALSE);
   }

   while(read(fp,&Area,sizeof(Area)) == sizeof(Area))
      if(Area.Number != area)
         write(ft,&Area,sizeof(Area));

   close(fp);
   close(ft);
   DeleteFile(filename);
   Rename(tempfile,filename);
   return(TRUE);
}
//-

/// AA_Flags
void AA_Flags(struct Msg_Area *area)
{
   area->lwrite=iinput(1,255,area->lwrite, SA[1388]);
   area->uwrite=iinput(1,255,area->uwrite, SA[1324]);
   AFPrintf(&UserDat,sout,"\n");

   area->lkill=iinput(1,255,area->lkill, SA[1389]);
   area->ukill=iinput(1,255,area->ukill, SA[1324]);
   AFPrintf(&UserDat,sout,"\n");

   area->lcopy=iinput(1,255,area->lcopy, SA[1390]);
   area->ucopy=iinput(1,255,area->ucopy, SA[1324]);
   AFPrintf(&UserDat,sout,"\n");

   area->lforward=iinput(1,255,area->lforward, SA[1391]);
   area->uforward=iinput(1,255,area->uforward, SA[1324]);
   AFPrintf(&UserDat,sout,"\n");

   area->ledit=iinput(1,255,area->ledit, SA[1392]);
   area->uedit=iinput(1,255,area->uedit, SA[1324]);
   AFPrintf(&UserDat,sout,"\n");

   area->lsysop=iinput(1,255,area->lsysop, SA[1393]);
   area->usysop=iinput(1,255,area->usysop, SA[1324]);
   AFPrintf(&UserDat,sout,"\n");

   return;
}
//-

/// Sort_List
BYTE Sort_List(char *name)
{
   ULONG            readsize;
   long             numrecords;
   struct Msg_Area *carea;
   struct Msg_Area *parea;
   struct Msg_Area *arealist;
   struct Msg_Area  temparea;

   SHORT            fp;
   char             filename[128];


   FileSize(name, &readsize);

   if ((fp = open(name, O_RDWR)) == EOF)
   {
      AFPrintf(&UserDat,sout,SA[1394],filename);
      return(1);
   }

   arealist = malloc(readsize);

   if (!arealist)
   {
      AFPrintf(&UserDat,sout,SA[1395]);
      _CXBRK();
   }

   numrecords = readsize / sizeof(struct Msg_Area);

   if ((read(fp, arealist, readsize)) != readsize)
   {
      close(fp);
      return(1);
   }

   for(carea = arealist+1; (carea - arealist) < numrecords; carea++)
   {
      parea = carea - 1;

      if (carea->Number < parea->Number)
      {
         movmem(parea,    &temparea, sizeof(struct Msg_Area));
         movmem(carea,     parea,    sizeof(struct Msg_Area));
         movmem(&temparea, carea,    sizeof(struct Msg_Area));
         if (carea > arealist+1)  carea -= 2;
      }
   }

   lseek(fp, 0, 0);
   write(fp, arealist, readsize);
   close(fp);

   free(arealist);
}
//-

/// Load_Users
BYTE Load_Users(void)
{
   ULONG filesize;

   FileSize("DLGConfig:Misc/Users.bbs",&filesize);
   users = malloc(filesize);

   if (GetFirstStruct("DLGConfig:Misc/Users.bbs", (char *)users, filesize))
   {
      AFPrintf(&UserDat,sout,SA[1396]);
      return(-1);
   }

   return(0);
}
//-

/// DeleteMsgs
BOOL DeleteMsgs(long area)
{
   long low;
   long high;

   GetHiLowPointers(area,NULL,&low,&high,"MsgAreas");
   AFPrintf(&UserDat,sout,SA[1397],low,high);

   for(;low<=high;low++)
   KillMsg(low,area,NULL,"MsgAreas");
   AFPrintf(&UserDat,sout,SA[1398]);

   return(TRUE);
}
//-

/// Move_Area()
BOOL Move_Area(void)
{
   BPTR fh = NULL;

   char CTemp[256];        // General purpose char buffer
   char CTemp2[256];       // General purpose char buffer

   long AreaToMove = 0;
   long NewAreaNumber = 0;
   long TempL;             // General purpose long

   struct DLGAreaInfo ai;
   struct Msg_Area   *ma;
   struct NameStruct *ns;
   struct SearchCookie *msc;

   ULONG masize;
   ULONG nssize;

/// We need to size and allocate memory now so it won't cause problems later
   FileSize("MSG:AREA.BBS",&masize);
   ma = calloc(1,masize);
   if(ma == NULL) return(FALSE);

   FileSize("DLGConfig:Misc/Users.BBS",&nssize);
   ns = calloc(1,nssize);

   if(ns == NULL)
   {
      free(ma);
      return(FALSE);
   }
//-

/// Get area to move, and find out if it exists
//   AreaToMove = iinput("Area to move -> ",1,999999,0);
   AreaToMove = iinput(1,999999,0, SA[1399]);
   AFPrintf(&UserDat,sout,"\n\n");
   if(AreaToMove == 0) return(FALSE);
   ASPrintf(NULL,CTemp,"MSG:%ld",AreaToMove);

   if(!Exists(CTemp))
   {
      free(ns);
      free(ma);
//      AFPrintf(&UserDat,sout,"%a6Error: message area %a7[%a3%ld%a7]%a6 does not exist.\n\n",AreaToMove);
      AFPrintf(&UserDat,sout,SA[1400],AreaToMove);
      return(FALSE);
   }
//-

/// Get new area number, and ensure it doesn't exist
   AFPrintf(&UserDat,sout,"%a3");
//   NewAreaNumber = iinput("Enter new message rea number -> ",1,999999,0);
   NewAreaNumber = iinput(1,999999,0, SA[1317]);

   if(NewAreaNumber  == 0)
   {
      free(ns);
      free(ma);
      return(FALSE);
   }

   if(NewAreaNumber  == AreaToMove)
   {
      free(ns);
      free(ma);
//      AFPrintf(&UserDat,sout,"%a6Error: source and destination are the same.\n\n");
      AFPrintf(&UserDat,sout,SA[1401]);
      return(FALSE);
   }

   AFPrintf(&UserDat,sout,"\n\n");
   ASPrintf(NULL,CTemp,"MSG:%ld",NewAreaNumber);

   if(Exists(CTemp))
   {
      free(ns);
      free(ma);
//      AFPrintf(&UserDat,sout,"That area already exists.\n\n");
      AFPrintf(&UserDat,sout,SA[1319]);
      return(FALSE);
   }
//-

/// Ensure no one is in the area
   EnterArea(AreaToMove,MSGLOCK);

   ai.area = AreaToMove;

   if(0 != GetAreaInfo(&ai,MSGLOCK))
   {
      free(ns);
      free(ma);
//      AFPrintf(&UserDat,sout,"%a6Error: could get info for message area %a7[%a3%ld%a7]%a6.\n\n",AreaToMove);
      AFPrintf(&UserDat,sout,SA[1402],AreaToMove);
      LeaveArea(AreaToMove,MSGLOCK);
      return(FALSE);
   }

   if(ai.users != 1)
   {
      free(ns);
      free(ma);
//      AFPrintf(&UserDat,sout,"%a6Error: %a3%ld%a6 users are present in area %a7[%a3%ld%a7]%a6.\n",(ai.users - 1),AreaToMove);
      AFPrintf(&UserDat,sout,SA[1403],(ai.users - 1),AreaToMove);
//      AFPrintf(&UserDat,sout,"%a6Area cannot be moved while users are in it.\n\n");
      AFPrintf(&UserDat,sout,SA[1404]);
      FreeAreaInfo(&ai);
      LeaveArea(AreaToMove,MSGLOCK);
      return(FALSE);
   }

   FreeAreaInfo(&ai);
   LeaveArea(AreaToMove,MSGLOCK);
//-

/// Now, lock the area away from everyone else
   if(0 != LockArea(AreaToMove,"DLG_MSGA","Moving message area",120,MSGLOCK | WRITELOCK))
   {
      free(ns);
      free(ma);
//      AFPrintf(&UserDat,sout,"%a6Error: could not get lock on message area %a7[%a3%ld%a7]%a6.\n\n",AreaToMove);
      AFPrintf(&UserDat,sout,SA[1405],AreaToMove);
      return(FALSE);
   }
//-

/// Now, change the number in area.bbs
//   AFPrintf(&UserDat,sout,"Updating [%s] ... ","MSG:AREA.BBS");
   AFPrintf(&UserDat,sout,SA[1380],"MSG:AREA.BBS");

   fh = Open("MSG:AREA.BBS",MODE_READWRITE);

   if(!fh)
   {
      free(ns);
      free(ma);
//      AFPrintf(&UserDat,sout,"Error: Cannot open file: [%s]\n\n","MSG:AREA.BBS");
      AFPrintf(&UserDat,sout,SA[1387],"MSG:AREA.BBS");
      FreeArea(AreaToMove,"DLG_MSGA",MSGLOCK);
      return(FALSE);
   }

   Read(fh,ma,masize);

   for(TempL = 0; TempL < (masize / sizeof(struct Msg_Area)); TempL++)
      if(ma[TempL].Number == AreaToMove)
         ma[TempL].Number = NewAreaNumber;

   Seek(fh,0,OFFSET_BEGINNING);
   Write(fh,ma,masize);
   Close(fh);
   free(ma);
   Sort_List("MSG:AREA.BBS");
//   AFPrintf(&UserDat,sout,"done\n\n");
   AFPrintf(&UserDat,sout,SA[1398]);
//-

/// Now do the same for all SIGs

   msc = SearchStart("DLGConfig:SIGs","*.msg");

   if(msc)
   {
      char *SigFileName;
      char  SigPathName[256];

      while(SigFileName = SearchNext(msc))
      {
         if(!Stricmp(SigFileName,"sigs.msg")) continue;

         ASPrintf(NULL,SigPathName,"DLGConfig:SIGs/%s",SigFileName);

         //                "Updating [%s] ...
         AFPrintf(&UserDat,sout,SA[377],SigFileName);

         FileSize(SigPathName,&masize);

         if(masize == 0)
         {
            AFPrintf(NULL,sout,"...no areas.\n");
            continue;
         }

         ma = calloc(1,masize);
         if(ma == NULL) continue;

         fh = Open(SigPathName,MODE_READWRITE);

         if(!fh)
         {
            AFPrintf(&UserDat,sout,"Error: could not open or create %s\n",SigPathName);
            free(ma); ma = NULL;
            continue;
         }

         Read(fh,ma,masize);

         for(TempL = 0; TempL < (masize / sizeof(struct Msg_Area)); TempL++)
            if(ma[TempL].Number == AreaToMove)
            {
               AFPrintf(NULL,sout,"...found area...");
               ma[TempL].Number = NewAreaNumber;
            }

         Seek(fh,0,OFFSET_BEGINNING);
         Write(fh,ma,masize);
         Close(fh);
         free(ma); ma = NULL;
         Sort_List(SigPathName);
//          "done \n"
         AFPrintf(&UserDat,sout,SA[379]);
      }

      SearchEnd(msc);
   }

//-

/// Rename the dir
//   AFPrintf(&UserDat,sout,"%a6Moving directory ... ");
   AFPrintf(&UserDat,sout,SA[1406]);
   ASPrintf(NULL,CTemp,"MSG:%ld",AreaToMove);
   ASPrintf(NULL,CTemp2,"MSG:%ld",NewAreaNumber);

   if(0 != SmartRename(CTemp,CTemp2))
   {
      free(ns);
//      AFPrintf(&UserDat,sout,"%a6Error: could not rename %a7[%a3%s%a7]%a6 -> %a7[%a3%s%a7]%a6..\n\n",CTemp,CTemp2);
      AFPrintf(&UserDat,sout,SA[1407],CTemp,CTemp2);
      FreeArea(AreaToMove,"DLG_MSGA",MSGLOCK);
      return(FALSE);
   }

   AFPrintf(&UserDat,sout,SA[1398]);
//-

/// Load up users
//   AFPrintf(&UserDat,sout,"Updating users in area\n\n");
   AFPrintf(&UserDat,sout,SA[1370]);

   GetFirstStruct("DLGconfig:Misc/Users.BBS",(char *)ns,nssize);

   for(TempL = 0; TempL < (nssize / sizeof(struct NameStruct)); TempL++)
   {
      AFPrintf(&UserDat,sout,"%-30.30s ... ",ns[TempL].name);

///   Convert arc global scan
      ASPrintf(NULL,CTemp,"USER:%s/globalareas.archive",ns[TempL].name);
      UnderScore(CTemp);

      if(ExistsGlobalArea(CTemp,AreaToMove))
      {
         DelArea(CTemp,AreaToMove);
         AddArea(CTemp,NewAreaNumber);
//         AFPrintf(&UserDat,sout,"archive newscan ... ");
         AFPrintf(&UserDat,sout,SA[1408]);
      }
//-

///   Convert msg global scan
      ASPrintf(NULL,CTemp,"USER:%s/globalareas.msg",ns[TempL].name);
      UnderScore(CTemp);

      if(ExistsGlobalArea(CTemp,AreaToMove))
      {
         DelArea(CTemp,AreaToMove);
         AddArea(CTemp,NewAreaNumber);
//         AFPrintf(&UserDat,sout,"msg newscan ... ");
         AFPrintf(&UserDat,sout,SA[1409]);
      }
//-

///   Convert Waitingmail
      ASPrintf(NULL,CTemp,"USER:%s/waitingmail.dat",ns[TempL].name);
      UnderScore(CTemp);

      if(Exists(CTemp))
      {
         ULONG wmsize = 0;
         long NumberOfWM = 0;
         struct WaitingMail *wm = NULL;

         FileSize(CTemp,&wmsize);
         NumberOfWM = wmsize / sizeof(struct WaitingMail);

         if(wmsize != 0)
         {
            wm = calloc(1,wmsize);

            if(wm != NULL)
            {
               BOOL  Changed = FALSE;

               fh = NULL;
               fh = Open(CTemp,MODE_READWRITE);

               if(fh)
               {
                  long l;

                  Read(fh,wm,wmsize);

                  Changed = FALSE;

                  for(l = 0; l < NumberOfWM; l++)
                  {
                     if(wm[l].areanum == AreaToMove)
                     {
                        ASPrintf(NULL,wm[l].msgid,"%04ld:%05d",NewAreaNumber,wm[l].messagenum);
                        Changed = TRUE;
                        wm[l].areanum = NewAreaNumber;

                     }
                  }

                  if(Changed)
                  {
                     qsort(wm,NumberOfWM,sizeof(struct WaitingMail),CompareWM);
                     Seek(fh,0,OFFSET_BEGINNING);
                     Write(fh,wm,wmsize);
//                     AFPrintf(&UserDat,sout,"Waitingmail.dat ... ");
                     AFPrintf(&UserDat,sout,SA[1410]);
                  }

                  Close(fh);
               }

               free(wm);
            }
         }
      }
//-

      AFPrintf(NULL,sout,SA[1398]);
   }

   free(ns);
//-

/// Wrap up
   FreeArea(AreaToMove,"DLG_MSGA",MSGLOCK);
   AFPrintf(&UserDat,sout,"\n\n");
   return(TRUE);
//-

}
//-

/// CompareWM
int CompareWM(struct WaitingMail *wm1, struct WaitingMail *wm2)
{
   return(Stricmp(wm1->msgid, wm2->msgid));
}
//-
