#include "Includes.h"
#include "Defines.h"
#include "Protos.h"
#include "Version.h"
#include "Vars.h"

#include <link/io.h>

#define DEBUGPRINT 0

/// ToPrint
BPTR ToPrint(BPTR window,BPTR mynull,int conditional)
{
   if(conditional)
      return window;
   else
      return mynull;
}
//-

/// __PROCESS
int __PROCESS(int argc, char **argv, BPTR window, BPTR mynull)
{

/* possible (logical) things that must be done here
 *
 * PROCESS LOOP 
 *
 * Check inbound:
 *
 *      Set DLGIMP flag if mail is present
 *      Set DLGTIC flag if tic files are present (or ATTACH flag if other files)
 * If nothing is present except trapdoor and .DMG files, then exit
 *
 * if(DLGIMP) Import:
 *      Did echomail come in? Set DLGEXP flag
 *      Did netmail come in? Set DLGNET flag
 * Did we get any areafix messages? Process, set DLGAFX flag
 * 
 * if(DLGAFX) Areafix:
 *
 * Process requests, set DLGNET flag accordingly
 *
 * if(DLGTIC) Tick:
 *
 * Did we process any files in? Set DLGNET and DLGEXP flags accordingly
 * and append area numbers into .EXP file
 *
 * DLGHub:
 *
 *
 * if(DLGEXP) DLGExp:
 * 
 * Set DLGBUN flag accordingly
 *
 * Check inbound:
 *
 * If no files present, continue;
 * If mail files are present, continue;
 * If tic files are present, continue;
 * if ATTACH files are present, process them
 *
 * if(DLGNET) DLGNet:
 *
 * Set BUN flag accordingly
 *
 * if(BUN) DLGBundle
 * 
 * RETURN TO TOP OF LOOP
 *
 */

   int ACTIVITYMEMORY;
   int rc,counter=0,counter2=0;

   DoAScript("PRE_Process.DMB",NULLFH);

   while(1)
   {
      ACTIVITYMEMORY=0;

      DeleteFile(EXPFILE);

      if(DLGMAILSTOP) break;

      rc=CheckInbound();

      if(rc & IN_PKT) ACTIVITYMEMORY |= ACT_DLGIMP;
      if(rc & IN_BUN) ACTIVITYMEMORY |= ACT_DLGIMP;

      if((rc & IN_TIC) && (rc & IN_ATTACH))
      {
         if(counter<2) ACTIVITYMEMORY |= ACT_DLGTIC;
         counter++;
      }

      if(DLGMAILSTOP) break;

      if((rc & IN_ATTACH) || (rc & IN_DMG))
      {
         if(counter2<1) ACTIVITYMEMORY |=ACT_DLGHUB;
         counter2++;
      }

      if(ACTIVITYMEMORY==0) break; /* nothing to do */

      if(ACTIVITYMEMORY & ACT_DLGIMP) /*DLGImp modified for V2*/
      {
         PerformImport(ToPrint(window,mynull,_SHOWIMP));
         ACTIVITYMEMORY |= _RETURNCODE;
      }

      if(ACTIVITYMEMORY & ACT_QUIT) break;

      if(DLGMAILSTOP) break;

      if(_ENABLE_AREAFIX)
      {
         if(Exists("T:AFX_LIST"))
         {
            ACTIVITYMEMORY |= ACT_DLGAFX;
         }

         if(ACTIVITYMEMORY & ACT_DLGAFX) /*DLGAreafix modified for V2*/
         {
            ACTIVITYMEMORY |= ACT_DLGNET;
            DoAScript("PRE_AFX.DMB",NULLFH);
            DoAreafix(ToPrint(window,mynull,_SHOWARE));
            DoAScript("POST_AFX.DMB",NULLFH);
         }

         if(_AREACRC==0)
         {
            _AREACRC=CalcAreasCRC(_ROSSAREAS);
         }
      }

      if(ACTIVITYMEMORY & ACT_QUIT) break;

      if(DLGMAILSTOP) break;

      if(_ENABLE_TICK)
      {
         if(ACTIVITYMEMORY & ACT_DLGTIC) /*DLGTick modified _MAYBE_ */
         {
            DoAScript("PRE_TICK.DMB",NULLFH);

            if(Exists("FIDO:DLGTICK"))
            {
               rc = Spawn(NULL, ToPrint(window, mynull, _SHOWTIC), "Fido:DLGTick TICK");
               ACTIVITYMEMORY |= _RETURNCODE;
            }
            else
            {
               DoAScript("GenericTick.DMB",NULLFH);
            }

            DoAScript("POST_TICK.DMB",NULLFH);
         }
      }

      if(ACTIVITYMEMORY & ACT_QUIT) break;

      if(DLGMAILSTOP) break;

      if((ACTIVITYMEMORY & ACT_DLGHUB) && _ENABLE_HUB)
      {
         DoAScript("PRE_HUB.DMB",NULLFH);
         rc = Spawn(NULL, ToPrint(window, mynull, _SHOWHUB), "FIDO:DLGHub");
         DoAScript("POST_HUB.DMB",NULLFH);
      }

      if(ACTIVITYMEMORY & ACT_QUIT) break;

      if(DLGMAILSTOP) break;

      if(ACTIVITYMEMORY & ACT_DLGEXP) /*DLGExp modified for V2*/
      {
         PerformExport(ToPrint(window,mynull,_SHOWEXP));
         ACTIVITYMEMORY |= _RETURNCODE;
      }

      if(ACTIVITYMEMORY & ACT_QUIT) break;

      if(DLGMAILSTOP) break;

      if(ACTIVITYMEMORY & ACT_DLGNET) /*DLGNet modiefied for V2 */
      {
         PerformNetscan(ToPrint(window,mynull,_SHOWNET));
         ACTIVITYMEMORY |= _RETURNCODE;
      }

      if(ACTIVITYMEMORY & ACT_QUIT) break;

      if(DLGMAILSTOP) break;

      ACTIVITYMEMORY |= ACT_DLGBUN;

      if(ACTIVITYMEMORY & ACT_DLGBUN) /*DLGBundle modified for V2 */
      {
         PerformBundle(ToPrint(window,mynull,_SHOWBUN));
         ACTIVITYMEMORY |= _RETURNCODE;
      }

      if(ACTIVITYMEMORY & ACT_QUIT) break;

      if(DLGMAILSTOP) break;

      if(ACTIVITYMEMORY & ACT_CRASH)
      {
         UBYTE clock[10];
         char hr;

         getclk(clock);

         hr=_CALLTYPES[clock[4]];

         if(hr != 'Z')
            SendRexx2(DLGMAILREXXPORT,"CRASH",NULL);
      }

      if(DLGMAILSTOP) break;

      DoAScript("POST_Process.DMB",NULLFH);

   }
   return 1;
}
//-

/// __USEREXPORT
int __USEREXPORT(int argc,char **argv,BPTR window, BPTR mynull)
{
   int ACTIVITYMEMORY=0;
   BPTR lock;

   DeleteFile(EXPFILE);

   lock=Lock(USEREXPFILE,ACCESS_READ);

   if(lock)
   {
      UnLock(lock);
      Rename(USEREXPFILE,EXPFILE);
   }

   if(lock)
   {
      if(!DLGMAILSTOP)
         PerformExport(ToPrint(window,mynull,_SHOWEXP));
      DeleteFile(EXPFILE);
      ACTIVITYMEMORY |= _RETURNCODE;
   }

   if(!DLGMAILSTOP)
      PerformNetscan(ToPrint(window,mynull,_SHOWNET));

   ACTIVITYMEMORY |= _RETURNCODE;


   ACTIVITYMEMORY |= ACT_DLGBUN;

   if(ACTIVITYMEMORY & ACT_DLGBUN)
   {
      if(!DLGMAILSTOP)
         PerformBundle(ToPrint(window,mynull,_SHOWBUN));

      ACTIVITYMEMORY |= _RETURNCODE;
   }


   if(ACTIVITYMEMORY & ACT_CRASH)
   {
      if(!DLGMAILSTOP)
         SendRexx2(DLGMAILREXXPORT,"CRASH",NULL);
   }
   return 1;
} 
//-

/// __EXPORT
int __EXPORT(int argc, char **argv, BPTR window, BPTR mynull)
{
   int ACTIVITYMEMORY=0;
   int i;
   BPTR fp;

   DeleteFile(EXPFILE);

   if(argc)
   {
      fp=Open(EXPFILE,MODE_NEWFILE);
      
      if(fp)
      {
         for(i=0;i<argc;i++)
         {
            AFPrintf(NULL,fp,"%s\n",argv[i]);
         }
         Close(fp);
      }
   }

   if(!DLGMAILSTOP)
      PerformExport(ToPrint(window,mynull,_SHOWEXP));

   ACTIVITYMEMORY |= _RETURNCODE;
   DeleteFile(EXPFILE);

   if(!DLGMAILSTOP)
      PerformNetscan(ToPrint(window,mynull,_SHOWNET));

   ACTIVITYMEMORY |= _RETURNCODE;

   ACTIVITYMEMORY |= ACT_DLGBUN;

   if(ACTIVITYMEMORY & ACT_DLGBUN)
   {
      if(!DLGMAILSTOP)
         PerformBundle(ToPrint(window,mynull,_SHOWBUN));

      ACTIVITYMEMORY |= _RETURNCODE;
   }


   if(ACTIVITYMEMORY & ACT_CRASH)
   {
      if(!DLGMAILSTOP)
         SendRexx2(DLGMAILREXXPORT,"CRASH",NULL);
   }
   return 1;
}
//-

/// __NETSCAN
int __NETSCAN(int argc, char **argv, BPTR window, BPTR mynull)
{
   int ACTIVITYMEMORY=0;

   if(!DLGMAILSTOP)
      PerformNetscan(ToPrint(window,mynull,_SHOWNET));
   ACTIVITYMEMORY |= _RETURNCODE;

   if(ACTIVITYMEMORY & ACT_DLGBUN)
   {
      if(!DLGMAILSTOP)
         PerformBundle(ToPrint(window,mynull,_SHOWBUN));
      ACTIVITYMEMORY |= _RETURNCODE;
   }


   if(ACTIVITYMEMORY & ACT_CRASH)
   {
      if(!DLGMAILSTOP)
         SendRexx2(DLGMAILREXXPORT,"CRASH",NULL);
   }

   return 1;
}
//-

/// __CHANGEFLOW
int __CHANGEFLOW(int argc, char **argv, BPTR window, BPTR mynull)
{
   ChangeIt(argc,argv,"F",ToPrint(window,mynull,_SHOWDLG),mynull);
   return 0;

}
//-

/// __CHANGEPKT
int __CHANGEPKT(int argc, char **argv, BPTR window, BPTR mynull)
{
   ChangeIt(argc,argv,"P",ToPrint(window,mynull,_SHOWDLG),mynull);
   return 0;
}
//-

/// __CHANGEBOTH
int __CHANGEBOTH(int argc, char **argv, BPTR window, BPTR mynull)
{
   ChangeIt(argc,argv,"F",ToPrint(window,mynull,_SHOWDLG),mynull);
   ChangeIt(argc,argv,"P",ToPrint(window,mynull,_SHOWDLG),mynull);
   return 0;
}
//-

/// ChangeIt
int ChangeIt(int argc, char **argv, char *huh, BPTR window, BPTR mynull)
{
   char d2d4[25];
   int i;

   int izone=0;
   int inet=0;
   int inode=0;
   int ipoint=0;
   ULONG type=0;

   char czone[10];
   char cnet[10];
   char cnode[10];
   char cpoint[10];
   char cext[10];


   ULONG oldtype=0;
   ULONG newtype=0;

   char string[100];
   char huntfor[100];

   char newname[100];
   char *oldname;

   BPTR fh;

   BOOL pollexport=FALSE;
   BOOL flag=FALSE;

   struct FileInfoBlock *myfib;

   i=0;

   while(argv[0][i]!=NULL)
   {
      if(argv[0][i]=='*')
      {
         flag=TRUE;
         break;
      }
      i++;
   }
   if(*huh=='P') flag=TRUE;   /* this would be illegal */

   if(argc>3)
   {
      myfib=AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC | MEMF_CLEAR);
      
      if(myfib )
      {
         type=__UserType(argv[1],huh);
         newtype=__UserType(argv[3],huh);

         strcpy(d2d4,argv[0]);
         TwoDto4D(d2d4);

         __AddToWild(d2d4,huntfor,type);

         AFPrintf(NULL,window,"Reflavoring OutBound Mail\n\n");
         AFPrintf(NULL,window,"Searching: [[33m%s[0m]\n",huntfor);

         fh=Lock("OUTBOUND:",ACCESS_READ);
         
         if(fh)
         {
            if(Examine(fh,myfib))
            {
               while(1)
               {
                  if(FALSE==ExNext(fh,myfib)) break;
                  oldname=myfib->fib_FileName;
                  Upper(oldname);
               
                  if(__FidoPatternMatch(oldname,huntfor))
                  {
                     flag=TRUE;

                     /* we need to act on this one */
                     
                     __EvaluateFilename(oldname,NULL,&izone,&inet,&inode,&ipoint,&oldtype);
                     __CreateNewName(newname,izone,inet,inode,ipoint,newtype);

/* do an export here before renaming */

                     if(pollexport==FALSE)
                     {
                        if(argc>4)
                        {
                           if(*huh=='F' && 0==Stricmp(argv[4],"POLL"))
                           {
                              if(   argc>5 && 0==Stricmp(argv[5],"EXPORT")  )
                              {
                                 pollexport=TRUE;
                                 AFPrintf(NULL, window,"     [32mEcho and Netmail being exported...[0m\n");

                                 __EXPORT(0,NULL,window,mynull);

                                 AFPrintf(NULL, window,"     [32mReflavoring export completed...[0m\n");
                              }
                           }
                        }
                     }

/* end of special call to export */

                     AFPrintf(NULL, window,"     [[32m%s[0m]==>[[32m%s[0m] ",oldname,newname);

                     if(__RenameOutbound(oldname,newname))
                        AFPrintf(NULL,window,"Reflavored\n");
                     else
                        AFPrintf(NULL, window,"Error\n");

                  }
               
                  if(!flag && MyDEBUG) AFPrintf(NULL, window, "     No matching files found...\n");
               }
            }
         
            UnLock(fh);
         }
      
         FreeMem(myfib,sizeof(struct FileInfoBlock));
      }

/* at this point, all the matching shit has been reflavored */

      if(argc>4)
      {
         if((*huh=='F') && (flag==FALSE) && (0==Stricmp(argv[4],"POLL")))
         {
            /* we need to generate a poll flow file with the flavor
            specifed in argv[3] */

            if(strchr(d2d4,'*') || strchr(d2d4,'?'))
            {
               AFPrintf(NULL, window,"     POLL arg error: Can't create a POLL file from wildcards\n");
            
               /* error */
            }
            else
            {
               __mystrsfn(d2d4,czone,cnet,cnode,cpoint,cext);
               __CreateNewName(newname,atoi(czone),atoi(cnet),atoi(cnode),atoi(cpoint),newtype);

               ASPrintf(NULL,string,"OUTBOUND:%s",newname);
            
               fh=Open(string,MODE_NEWFILE);
            
               if(fh)
               {
                  AFPrintf(NULL, window,"     Creating POLL file [[32m%s[0m]\n",newname);
                  Close(fh);
               }
            }     
         }
      }
   }
   
   Delay(250);
   return(1);
}
//-

/// DoAreaFix
int DoAreafix(BPTR window)
{
   BPTR fp;
   char buf[50];
   char *s;

   if(!_ENABLE_AREAFIX) return(0);

   fp=Open("t:AFX_LIST",MODE_OLDFILE);

   if(fp)
   {
      while(1)
      {
         s=FGets(fp,buf,98);
         if(!s) break;
         buf[strlen(buf)-1]=NULL;

         if(Exists("Fido:DLGAreaFix"))
         {
            Spawn(NULL, NULLFH, "FIDO:DLGAreaFix %s",buf);
         }
         else
         {
            if(Exists("Fido:DLGAreaFix"))
               Spawn(NULL, NULLFH,"FIDO:DLGAreafix %s",buf);
            else
               DoAScript("GenericAFX.DMC",NULLFH);
         }
      }
      Close(fp);
      DeleteFile("t:AFX_LIST");
   }
   return 1;
}
//-

/// TwoDto4D
int TwoDto4D(char *string)
{
   char *s;
   char tmp[20];
   int zone,net,node,point;
   char ZONE[20],NET[20],NODE[20],POINT[20],BLECH[20];

   __mystrsfn2(string,ZONE,NET,NODE,POINT,BLECH);

   zone=atoi(ZONE);
   net=atoi(NET);
   node=atoi(NODE);
   point=atoi(POINT);

   if(strchr(ZONE,'*') || strchr(ZONE,'?'))
   {
      if(s=strchr(ZONE,':')) *s=NULL;
   }
   else
   {
      zone=atoi(ZONE);
      if(zone==0) zone=_MyZone;
      ASPrintf(NULL,ZONE,"%d",zone);
   }

   if(strchr(NET,'*') || strchr(NET,'?'))
   {
      if(s=strchr(NET,'/')) *s=NULL;
   }
   else
   {
      net=atoi(NET);
      if(net==0) net=_MyNet;
      ASPrintf(NULL,NET,"%d",net);
   }

   if(strchr(NODE,'*') || strchr(NODE,'?'))
   {
      if(s=strchr(NODE,'.')) *s=NULL;
   }
   else
   {
      node=atoi(NODE);
      ASPrintf(NULL,NODE,"%d",node);
   }

   if(strchr(POINT,'*') || strchr(POINT,'?'))
   {
      if(s=strchr(POINT,'.'))
      {
         strcpy(tmp,POINT);
         s=tmp;
         s++;
         strcpy(POINT,s);
      }
   }
   else
   {
      point=atoi(POINT);
      ASPrintf(NULL,POINT,"%d",point);
   }

   ASPrintf(NULL,string,"%s:%s/%s.%s",ZONE,NET,NODE,POINT);
   if(DEBUGPRINT) Delay(200);
   return 1;
}
//-

/// __TRIMLOGS
int __TRIMLOGS(int argc, char **argv, BPTR window, BPTR mynull)
{
   char names[500];
   BPTR lock;
   struct FileInfoBlock *fib;

   char name[35];
   char extension[35];
   int size;

   strcpy(names,""); /* nothing to trim at this point */

   fib=(void *)AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC);
   if(fib)
   {
      lock=Lock("LOGS:",ACCESS_READ);
      if(lock)
      {
         if(Examine(lock,fib))
         {
            while(1)
            {
               if(ExNext(lock,fib))
               {
                  strcpy(name,fib->fib_FileName);
                  Upper(name);
                  size=fib->fib_Size;

                  if(size<=(_LOGLINES*80)) continue;

                  /* isolate the extension here */

                  strsfn(name,NULL,NULL,NULL,extension);
                  if(0==Stricmp(extension,"LOG"))
                  {
                     strncat(names,name,499);
                     strncat(names," ",499);
                  }
               }
               else break;
            }
         }
         UnLock(lock);
      }
      FreeMem((void *)fib,sizeof(struct FileInfoBlock));
   }

   if(strlen(names))
      TruncateFiles(names,_LOGLINES,window);

   DeleteFile(INFILE);

   return 0;
}
//-

/// TruncateFiles
int TruncateFiles(char *names,int length, BPTR window)
{
   char *s;
   char token[50];

   s=names;

   while(1)
   {
      if(DLGMAILSTOP)
         break;
      if(*s==NULL) 
         break;

      s=stpblk(s);
      s=stptok(s,token,sizeof(token)," \t");
      s=stpblk(s);

      if(*token)
      {
         if(window)
            AFPrintf(NULL,window,"Trimming log [%s] to approximately %d lines\n",token,_LOGLINES);

         TruncateFile(token,length);
      }
   }
   return 0;
}
//-

/// TruncateFile
int TruncateFile(char *name, int length)
{
   int rc=1;
   char *buffer;
   BPTR in;
   BPTR out;
   char string[100];
   int size;
   int dump;
   int actual;
   int count;
   int i;

   CP_CommandLine(4,"Truncating log [%s]",name);

   Delay(100);

   buffer=(void *)calloc(COPYBUFSIZE,1);
   if(buffer)
   {
      rc=0;
      DeleteFile(INFILE);

      ASPrintf(NULL,string,"LOGS:%s",name);

      count=0;
      while(1)
      {
         if(i=Rename(string,INFILE)) break;
         Delay(5);
         count++;
         if(count>20) break;
      }
      if(i)
      {
         in=Open(INFILE,MODE_OLDFILE);
         if(in)
         {
            Seek(in,0,OFFSET_END);
            size=Seek(in,0,OFFSET_BEGINNING);

            dump=size-(length * 80);

            Seek(in,dump,OFFSET_BEGINNING);

            count=0;
            while(1)
            {
               out=Open(string,MODE_NEWFILE);
               if(out) break;
               Delay(5);
               count++;
               if(count>10) break;
            }
            if(out)
            {
               while(1)
               {
                  actual=Read(in,buffer,COPYBUFSIZE);
                  Write(out,buffer,actual);
                  if(actual != COPYBUFSIZE)
                     break;
               }
               Close(out);
            }
            else
            {
               rc=1;
               DeleteFile(string);
               Close(in);
               in=NULL;
               DeleteFile(string);
               Rename(INFILE,string); /* give up on truncation */
            }
            if(in) Close(in);
         }
         else
         {
            rc=1;
            DeleteFile(string);
            Rename(INFILE,string);
         }
      }
      else
      {
         rc=1;
         /*printf("couldn't ever rename the file\n");*/
      }
      free((void *)buffer);
   }

   Delay(50);

   if(rc)
      CP_CommandLine(4,"Log [%s] not properly truncated",name);
   else
      CP_CommandLine(4,"Log [%s] truncated",name);

   return 0;
}
//-

/// PerformImport
PerformImport(BPTR where)
{
   int rc;

   DoAScript("PRE_Import.DMB",NULLFH);
   rc=Spawn(NULL, where, "FIDO:DLGImp NEW");
   DoAScript("POST_Import.DMB",NULLFH);

   return rc;
}
//-

/// PerformExport
PerformExport(BPTR where)
{
   int rc;

   DoAScript("PRE_Export.DMB",NULLFH);
   rc=Spawn(NULL, where, "FIDO:DLGExp NEW");
   DoAScript("POST_Export.DMB",NULLFH);

   return rc;
}
//-

/// PerformNetscan
PerformNetscan(BPTR where)
{
   int rc;

         DoAScript("PRE_Netscan.DMB",NULLFH);
   rc =  Spawn(NULL, where, "FIDO:DLGNet NEW");
         DoAScript("POST_Netscan.DMB",NULLFH);

   return rc;
}
//-

/// PerformBundle
PerformBundle(BPTR where)
{
   int rc;

   i_am_bundling=1;

         DoAScript("PRE_Bundle.DMB",NULLFH);
   rc =  Spawn(NULL, where, "FIDO:DLGBundle NEW");
         DoAScript("POST_Bundle.DMB",NULLFH);

   i_am_bundling=0;

   return rc;
}
//-
