#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <fcntl.h>
#include <exec/types.h>
#include <ctype.h>

#include <dlg/resman.h>
#include <dlg/dlg.h>
#include <dlg/msg.h>

#include <link/io.h>
#include <link/lang.h>

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

#include <pragmas/dlg.h>

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

void  main(int, char **);
long  MakeAreaArray(long *,char *);
long  MakeEchoNet  (long *, long, unsigned char);
void _CXBRK(void);
void  Usage(char *);
void  CleanUp(char *);


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

#define NumAreas 100000
long   *AreaArray = NULL;
char    flags  =  WRITELOCK|PENDLOCK;
int     fp     =  EOF;

/// main
void main(int argc,char **argv)
{
   long  retval;
   long  numareas;
   long  area;

   char *alist  =  NULL;
   char *passwd = "DLG";
   char *reason = "Unspecified";
   char  pri    =  0;

   sout    = Output();
   DLGBase = OpenLibrary(DLGNAME, DLGVERSION);
   if (!DLGBase)               CleanUp("Unable to open dlg.library");
   if (!(SA = getlang(NULL)))  CleanUp("Can't read language file");

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

/// parse args
   while(--argc>0)
   {
      char *s;

      s = *++argv;
      if (*s++=='-')
      {
         while(*s)
         {
            switch(toupper(*s))
            {
               case 'A': if (!--argc)  break;
               alist=*++argv;
               break;

               case 'K': if (!--argc)  break;
               passwd = *++argv;
               break;

               case 'R': if (!--argc)  break;
               reason = *++argv;
               break;

               case 'L': if (!--argc)  break;
               pri = atoi(*++argv);
               break;

               case 'M': flags |= MSGLOCK;
               break;

               case 'F': flags |= FILELOCK;
               break;

               case 'B': flags |= QUICKLOCK;
               break;

               case 'D': flags &= ~WRITELOCK;
               break;
            }

            s++;
         }
      }
   }
//-

   if (!alist)  Usage(SA[2728]);

   if(! (AreaArray = calloc(NumAreas,sizeof(long))))
      CleanUp(NULL);

   numareas = MakeAreaArray(AreaArray, alist);
   lqsort(AreaArray, numareas);

   for(area=0; area < numareas; area++)
   {
      AFPrintf(NULL, sout, SA[2729],AreaArray[area]);

      retval = LockArea(AreaArray[area],passwd,reason,pri,flags);

      if (retval==RMNOERR)
         AFPrintf(NULL, sout, SA[2730]);
      else
      {
         if (retval==NORM)
            AFPrintf(NULL, sout, SA[2731]);
         else
            AFPrintf(NULL, sout, SA[2732]);

         numareas = area;

         for(area = 0; area < numareas; area++)
         {
            AFPrintf(NULL, sout, SA[2733], AreaArray[area]);

            retval = FreeArea(AreaArray[area],passwd,flags);

            if (retval==RMNOERR)
               AFPrintf(NULL, sout, SA[2734]);
            else
            {
               if (retval==NORM)
                  CleanUp(SA[2735]);
               else
                  if (retval==BADAREA)
                     AFPrintf(NULL, sout, SA[2736]);
                  else
                     if (retval==NOTLOCKED)
                        AFPrintf(NULL, sout, SA[2737]);
                     else
                        AFPrintf(NULL, sout, SA[2738]);
               break;
            }
         }

         retval=-1;
         break;
      }
   }

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

/// MakeAreaArray
long MakeAreaArray(long *array, char *alist)
{
   long          area;
   char         *s;

   unsigned char EchoFlag  = 0;
   unsigned char NetFlag   = 0;
   unsigned char LocalFlag = 0;

   s = alist;

   for(area=0; area < NumAreas; area++)
   {
      while(*s==32) s++;
      if (!*s) break;

      if (!Strnicmp(s,"ECHO",4))
      {
         if (EchoFlag)
         {
            AFPrintf(NULL, sout, SA[2739]);
            area--;
         }
         else
         if (flags & FILELOCK)
         {
            AFPrintf(NULL, sout, SA[2740]);
            area--;
         }
         else
         {
            EchoFlag = 1;
            area     = MakeEchoNet(array, area, ECHO_AREA);
         }
      }
      else
      if (!Strnicmp(s,"NET",3))
      {
         if (NetFlag)
         {
            AFPrintf(NULL, sout, SA[2741]);
            area--;
         }
         else
         if (flags & FILELOCK)
         {
            AFPrintf(NULL, sout, SA[2742]);
            area--;
         }
         else
         {
            NetFlag = 1;
            area    = MakeEchoNet(array, area, NETMAIL_AREA);
         }
      }
      else
      if (!Strnicmp(s,"LOCAL",5))
      {
         if (LocalFlag)
         {
            AFPrintf(NULL, sout, SA[2743]);
            area--;
         }
         else
         {
            LocalFlag = 1;
            area      = MakeEchoNet(array, area, 0);
         }
      }
      else
      array[area] = atoi(s);

      while((*s)&&(*s!=32)) s++;
   }

   if (area == NumAreas)
   AFPrintf(NULL, sout, SA[2744], NumAreas);

   return(area);
}
//-

/// MakeEchoNet
long MakeEchoNet(long array[], long area, unsigned char type)
{
   char              areafile[80];
   struct  Msg_Area  Area;

   ASPrintf(NULL, areafile, "%s:Area.bbs", ((flags & FILELOCK)?"FILE":"MSG"));

   if ((fp = open(areafile,O_RDONLY)) == EOF)
   AFPrintf(NULL, sout, SA[2745], areafile);
   else
   {
      while(((read(fp, &Area, sizeof(Area))) == sizeof(Area)) && (area < NumAreas))
      {
         if ((Area.Flag & type)  ||  (!type && !(Area.Flag & (ECHO_AREA | NETMAIL_AREA))))
         {
            array[area] = Area.Number;
            area++;
         }
      }

      close(fp);
      fp = EOF;
   }

   --area;
   return(area);
}
//-

/// _CXBRK
void _CXBRK(void)
{
   CleanUp(NULL);
}
//-

/// Usage
void Usage(char *string)
{
   AFPrintf(NULL, sout, SA[2746],string);
   AFPrintf(NULL, sout, SA[2747]);
   AFPrintf(NULL, sout, SA[2748]);
   AFPrintf(NULL, sout, SA[2749]);
   AFPrintf(NULL, sout, SA[2750]);
   AFPrintf(NULL, sout, SA[2751]);
   AFPrintf(NULL, sout, SA[2752]);
   AFPrintf(NULL, sout, SA[2753]);
   AFPrintf(NULL, sout, SA[2754]);
   AFPrintf(NULL, sout, SA[2755]);

   CleanUp(NULL);
}
//-

/// CleanUp
void CleanUp(char *s)
{
   if (AreaArray)  free(AreaArray);
   if (fp != EOF)  close(fp);
   if (DLGBase)    CloseLibrary(DLGBase);

   if (s)
   {
      Write(sout, "\n Error: ", 9);
      Write(sout,  s,    strlen(s));
      Write(sout, "\n\n",       2);
   }

   exit(s?5:0);
}
//-
