#include "pdqnet.h"
#include "ivn.h"

/* globals */

char DLGSerial[8];

struct HiWater MyHiWater;

struct GConfig *GCFG;

char logstring[1000];

BOOL MADECRASH=FALSE;
BOOL MADENORMAL=FALSE;
BOOL BORROWED=FALSE;

BPTR sout = NULL;

UBYTE *CURMSG=NULL;

int CURMSGLENGTH;
int CURlo;
int CURhi;
int CURhiwater;

struct Library *DLGBase;

long __stack = 50000L;

int main(int argc, char **argv)
{
   BPTR fh;
   FILE *fp;

   sout = Output();

   printf("%s\n",ID_STRING);

   if(argc!=2) exit(20);

   DLGBase = OpenLibrary("dlg.library",4L);
   
   if(!DLGBase)
   {
      printf("DLG.Library not found!");
      exit(20);
   }

   GCFG=NULL;

   if(stricmp(argv[1],"NEW")==0)
   {
      FILE *fp;
      char buf[20];

      if(fp=fopen("ENV:GCFG","r"))
      {
         fgets(buf,16,fp);
         fclose(fp);
         GCFG=(struct GConfig *)atoi(buf);
      }
   }
   else
   {
      GCFG=(struct GConfig *)atoi(argv[1]);
   }

   if(GCFG==NULL)
   {
      printf("No GCFG - Exiting\n");
      exit(20);
   }
   if((GCFG->MARKER1 != 5551212) || (GCFG->MARKER2 != 5551212))
   {
      printf("ERROR: GCFG Marker Failure\n");
      exit(20);
   }


   SetZTaskPri();

// new March 1995

   // please note that this code reads the serial number but nothing is
   // done with it later in the program... the serial number is read
   // at pdqmail startup time and that is used instead

   fp=fopen("DLGConfig:misc/dlgserial","r");
   if(fp)
   {
      fgets(DLGSerial,6,fp);
      fclose(fp);
      DLGSerial[6]=0;
   }

// end new

   strcpy(MASTERLOGSTRING,"");

   sprintf(logstring,"%s",ID_STRING);
   Log("*----",logstring);

   _RETURNCODE=0;


   BorrowNetArea();
   EnterNetArea();
   ReturnNetArea();

   fh=Lock("FIDO:DLGMail.MRT",ACCESS_READ);
   if(!fh)
   {
      printf("WARNING: No FIDO:DLGMail.MRT netmail routing file\n");
      Log("|    ","No FIDO:DLGMail.MRT netmail routing file");
   }
   if(fh) UnLock(fh);

   if(GetPointers()==GetHiWater())
   {
      printf("\nNetmail area up to date - No new messages to process.\n\n");
      Log("|    ","Netmail area up to date - No messages to process");
   }
   else
   {
      Log("|*---","Entering ProcessNetArea()");
      ProcessNetArea();
      Log("|*---","Back from PNA()");
      FileToPKT();
   }

   QuietExit();
}

int SetZTaskPri(void)
{
   struct Task *MyTask;

   MyTask=(struct Task *)FindTask(NULL);

   sprintf(logstring,"Task Address is $%X",MyTask);
   Log("-----",logstring);

   if(_ZTASKPRI)
   {
      SetTaskPri(MyTask,_ZTASKPRI);
   }
   return(0);
}
#define MAX_ARGS 20

int MyExecute(char *string,BPTR a,BPTR b)
{
   int rc;
   BPTR fh;
   
   fh=Open("NULL:",MODE_NEWFILE);

   rc=MyFork(string,_TASKPRI,_STACKSIZE,fh);
   if(fh) Close(fh);

   /*printf("the return code from the archiver call was %d\n",rc);*/
   if(rc==0)
      return 1;
   else
      return 0;
}

int MyFork(char *cmdline,int priority, int stack, BPTR outfh)
{
   int rc=255;
   struct ProcID *child=NULL;
   struct FORKENV *fork=NULL;
   char *ARGV[MAX_ARGS];
   int ARGC;
   int error;
   char *cmd=NULL;
   if(stack==0)
      stack=12000;
   if(priority==0)
      priority=_ZTASKPRI;
   fork=(void *)calloc(sizeof(struct FORKENV),1);
   if(fork)
   {
      fork->priority=priority;
      fork->stack=stack;
      fork->std_in=NULL;
      fork->std_out=outfh;

      child=(void *)calloc(sizeof(struct ProcID),1);
      if(child)
      {
         cmd=(void *)calloc(strlen(cmdline)+10,1);
         if(cmd)
         {
            strcpy(cmd,cmdline);
            ARGC=ParseArgs(ARGV,cmd);
            if(ARGC)
            {
               error= ! forkv(ARGV[0],&ARGV[0],fork,child);
               if(error) /* convoluted, but nice for structure */
               {
                  rc=wait(child);
               }
            }
         }
      }
   }
   if(cmd) free(cmd);
   if(child) free(child);
   if(fork) free(fork);
   return rc;
}
/*******************
 *
 * PRIVATE
 * ParseArgs
 *
 *******************/

int ParseArgs(char **argv,char *argstring)
{
   char token[100];
   char *s;
   int i=0;

   s=argstring;

   argv[i]=NULL;

   while(*s != NULL && i<MAX_ARGS)
   {
      s=stpblk(s);
      if(*s)
      {
         argv[i]=s;
         i++;
         argv[i]=NULL;
         s=stptok(s,token,sizeof(token)," \t");
         if(*s) *s++=NULL;
      }
   }
   return(i);
}

int GetPKTPw(char *address, char *password, char *use)
{
   FILE *fp;
   char buf[100];
   char *s;
   char token[50];
   int rc=0;
   
   *password=0;
   *use=0;

   fp=fopen("FIDO:DLGMail.PPW","r");
   if(fp)
   {
      while(fgets(buf,sizeof(buf),fp))
      {
         s=strchr(buf,'\n');
         if(s) *s=0;

         s=buf;
         s=stpblk(s);
         if(*s==';') continue;
         if(!*s) continue;

         s=stptok(s,token,sizeof(token)," \t");
         s=stpblk(s);
         if(!*s) continue;

         if(stricmp(address,token)==0)
         {
            s=stptok(s,token,sizeof(token)," \t");
            s=stpblk(s);
            if(!*s) break;

            strncpy(password,token,8);
            password[8]=0;

            strncpy(use,s,8);
            use[8]=0;
            rc=1;
         }
      }
      fclose(fp);
      return rc;
   }
   return -1; // no password file
}



void QuietExit(void)
{
   if(BORROWED) ReturnNetArea();

   if(remember) FreeMem(remember,rememberlength);

   LeaveNetArea();

   printf("DLGNet Completed...\n");

   _RETURNCODE=0;
   if(MADECRASH) _RETURNCODE |=ACT_CRASH;
   if(MADENORMAL) _RETURNCODE |=ACT_DLGBUN;

   sprintf(logstring,"DLGNet Completed\n");
   Log("*----",logstring);

   exit(0);
}

void BorrowNetArea(void)
{
   short j;

   if(_BORROW)
   {
      j=BorrowArea(_NETMAILDIR,"DLGNet","Scanning",64,MSGLOCK);
      if(MyDEBUG) printf("netmail area borrowed, returned %d\n",j);
      BORROWED=TRUE;
   }
}

void ReturnNetArea(void)
{
   short j;

   if(_BORROW)
   {
      j=FreeArea(_NETMAILDIR,"DLGNet",MSGLOCK);
      if(MyDEBUG) printf("netmail area unborrowed, returned %d\n",j);
      BORROWED=FALSE;
   }
}

void EnterNetArea(void)
{
   int j;

   if(!_BORROW) return;

   j=EnterArea(_NETMAILDIR,MSGLOCK);
   sprintf(logstring,"EnterArea returned %d",j);
   Log("X    ",logstring);
}

void LeaveNetArea(void)
{
   int j;

   if(!_BORROW) return;

   j=LeaveArea(_NETMAILDIR,MSGLOCK);
   sprintf(logstring,"LeaveArea returned %d",j);
   Log("X    ",logstring);
}

int GetPointers(void) /* values are put into globals CURlo, CURhi */
{
   char path[100];
   FILE *fp;

   sprintf(path,"%sPOINTERS.MSG",_NETMAILDIRPATH);

   BorrowNetArea();
   
   fp=fopen(path,"r");
   if(!fp)
   {
      ReturnNetArea();
      CURlo=0;
      CURhi=0;
      return(CURhi);
   }
   fgets(path,10,fp);
   CURlo=atoi(path);
   fgets(path,10,fp);
   CURhi=atoi(path);
   fclose(fp);
   
   ReturnNetArea();
   return(CURhi);
}

BOOL SetPointers(int lo,int hi)
{
   FILE *fp;
   
   char path[100];

   sprintf(path,"%sPOINTERS.MSG",_NETMAILDIRPATH);
   BorrowNetArea();
   
   fp=fopen(path,"r");
   if(!fp)
   {
      ReturnNetArea();
      return(FALSE);
   }
   fprintf(fp,"%d\n%d\n",lo,hi);
   fclose(fp);
   
   ReturnNetArea();
   return(TRUE);
}

int GetHiWater()
{
   char path[100];

   BPTR HIWATERfile;
   int i,j;

   sprintf(path,"%s1.MSG",_NETMAILDIRPATH);

   BorrowNetArea();

   HIWATERfile=Open(path,MODE_OLDFILE);
   if(!HIWATERfile)
   {
      if(MyDEBUG) printf("WARNING: Can't open %s to retrieve hiwater mark\n",path);
      ReturnNetArea();
      return(0);
   }

   i=Read(HIWATERfile,(void *)&MyHiWater,sizeof(struct HiWater));
   Close(HIWATERfile);

   j=MyHiWater.HiWater1;

   if(MyDEBUG) printf("---> Hiwater reported as %d\n",j);
   ReturnNetArea();
   return(j);
}

BOOL SetHiWater(int hiwater)
{
   char path[100];
   BPTR HIWATERfile;

   int i,j;

   char buffer[100];

   BorrowNetArea();

   sprintf(path,"%s1.MSG",_NETMAILDIRPATH);

   HIWATERfile=Open(path,MODE_NEWFILE);
   if(!HIWATERfile)
   {
      printf("ERROR: Can't open %s to store hiwater mark\n",path);
      ReturnNetArea();
      return(0);
   }

   strcpy(MyHiWater.From,"DLGNet");
   strcpy(MyHiWater.To,"DLGNet");

   sprintf(buffer,"DLGNet HiWater Marker being set to %d",hiwater);

   strcpy(MyHiWater.Title,buffer);
   MyHiWater.HiWater1=hiwater;
   MyHiWater.HiWater2=hiwater;
   MyHiWater.HiWater3=hiwater;
   strcpy(MyHiWater.Text,"NOECHO\r\n\r\nIgnore this message. Used to store the area Hi Water Mark for DLGNet\r\n");

   j=MyHiWater.HiWater1;

   i=Write(HIWATERfile,(void *)&MyHiWater,sizeof(struct HiWater));
   Close(HIWATERfile);

   ReturnNetArea();

   if(i!=sizeof(struct HiWater))
      return(FALSE);
   else
      return(TRUE);
}

USHORT FixNumbers(USHORT number)
{
   UBYTE lo;
   UBYTE hi;
   USHORT result;
   
   lo=(number & 0xff00)/256;
   hi=(number & 0x00ff);

   result=hi*256+lo;
   return(result);
}

