/*ProfiPacket - packet radio terminal program
  Copyright (C) 1999  Alexander Feigl

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

  Author:

  Alexander Feigl
  Burachstraße 51

  D-88250 Weingarten

  Mail : Alexander.Feigl@gmx.de
*/


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "global.h"
#include "QSO.h"
#include "GUIProtos.h"

#ifdef AmigaOS

#include "GUI/MUI/Editor.h"
#include <exec/memory.h>
#include <dos/exall.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#ifdef __GNUC__
extern void *SysBase;
extern void *DOSBase;
#include <inline/exec.h>
#include <inline/dos.h>
#endif /*__GNUC__*/

#else

#include "amigaemu.h"

#endif /*AmigaOS*/

struct HoldChannel
 {
  unsigned long    Connected;
  unsigned char    MyCall[10];
  unsigned char    HardCall[10];
  unsigned short   SelfConnect;
  unsigned char    Call[10];
  unsigned char    Path[8][10];
  unsigned char    CurrentDir[196];
  unsigned long    CompressedMode;
  struct DateStamp ConnectTime;
  struct DateStamp ActivityTime;
  unsigned long    SysopMode;
#ifdef AmigaOS
  struct ANSIStream EditInStream;
  struct ANSIStream EditOutStream;
  struct ANSIStream PacketOutStream;
#endif /*AmigaOS*/
  unsigned long    PrivateDir;
  unsigned char    CipherInputBuffer[1536];
  unsigned char    CipherOutputBuffer[1536];    
  unsigned char    XPKType[4];
  unsigned long    XPKEfficiency;
  unsigned long    XPKSublibrary;
  struct DateStamp LastLogin;
  unsigned char    XPDecompress[260];
  unsigned char    XPacketKey[128];
 };

struct HoldChannel *HoldArray;

#define HOLDING_FILE "data/connects.dat"

static int QSO_GetHoldArray(void)
 {
  int i;
  unsigned char *hchan;
  
  if (HoldArray==NULL)
   {
    HoldArray=AllocVec(sizeof(struct HoldChannel)*MaxChannel,1);
    if (HoldArray==NULL) return(-1);
   }
  
  hchan=(unsigned char *) HoldArray;
  i=sizeof(struct HoldChannel)*MaxChannel;
  
  while (i>0)
   {
    *(hchan++)=0;
    --i;
   }
   return(0);
  }
 
 
void QSO_FreeHoldArray(void)
 {
  if (HoldArray!=NULL)
   {
    FreeVec(HoldArray);
    HoldArray=NULL;
   }
  }
  
int QSO_LoadHoldings(void)
 {
  BPTR hfile;
  
  if (QSO_GetHoldArray()) return (-1);
  
  hfile=Open(HOLDING_FILE,MODE_OLDFILE);
  
  if (hfile==NULL) 
   {
    QSO_FreeHoldArray();
    return(-1);
   }
   
   {
    unsigned long hfilelen;
    
    if (Read(hfile,&hfilelen,4)!=4)
     {
      Close(hfile);
      DeleteFile(HOLDING_FILE);
      QSO_FreeHoldArray();
      return(-1);      
     }
   
    if (hfilelen!=sizeof(struct HoldChannel))
     {
      Close(hfile);
      DeleteFile(HOLDING_FILE);
      QSO_FreeHoldArray();
      return(-1);
     }
    hfilelen*=MaxChannel;
    if (Read(hfile,HoldArray,hfilelen)!=hfilelen)
     {
      Close(hfile);
      DeleteFile(HOLDING_FILE);
      QSO_FreeHoldArray();
      return(-1);
     }
   }
  Close(hfile);
  DeleteFile(HOLDING_FILE);  
  return(0);
 }
 
 int QSO_SaveHoldings(void)
  {
   BPTR hfile;
   struct HoldChannel *hchan;
   struct QSO *qso;
   
   int i,k,uchan;
   
   if (QSO_GetHoldArray()) return(-1);
  
   uchan=0;
   
   for (i=0,hchan=HoldArray,qso=QSOs;i<MaxChannel;++i,++hchan,++qso)
    {
     
     if (qso->LinkStatus==0)
      {
       hchan->Connected=0;
       continue;
      } 
     hchan->Connected=1;
     ++uchan;
     CopyString(hchan->MyCall,qso->MyCall);
     CopyString(hchan->Call,qso->Call);
     CopyString(hchan->HardCall,qso->HardCall);
     
     for (k=0;k<8;++k)
      {
       CopyString(hchan->Path[k],qso->Path[k]);
      }
      
     CopyString(hchan->CurrentDir,qso->CurrentDir);
     hchan->CompressedMode=qso->CompressedMode;
     hchan->SelfConnect=qso->SelfConnect;
     hchan->ConnectTime=qso->ConnectTime;
     hchan->ActivityTime=qso->ActivityTime;
     hchan->LastLogin=qso->LastLogin;
     
     hchan->SysopMode=qso->SysopMode;
     hchan->PrivateDir=qso->PrivateDir;
 #ifdef AmigaOS
      {
       unsigned char *s1,*s2,*s3,*t1,*t2,*t3;
       
       s1=(unsigned char *) &qso->EditInStream;
       t1=(unsigned char *) &hchan->EditInStream;
       s2=(unsigned char *) &qso->EditOutStream;
       t2=(unsigned char *) &hchan->EditOutStream;
       s3=(unsigned char *) &qso->PacketOutStream;
       t3=(unsigned char *) &hchan->PacketOutStream;
       for (k=0;k<sizeof(struct ANSIStream);++k)
        {
         *(t1++)=*(s1++);
         *(t2++)=*(s2++);
         *(t3++)=*(s3++);
        }
      }
 #endif /*AmigaOS*/
      {
       unsigned char *s1,*s2,*t1,*t2;
       
       s1=qso->CipherInputBuffer;
       s2=qso->CipherOutputBuffer;
       t1=hchan->CipherInputBuffer;
       t2=hchan->CipherOutputBuffer;
       for (k=0;k<384;++k)
        {
         *(t1++)=*(s1++);
         *(t2++)=*(t2++);
        }
      }
     hchan->XPKType[0]=qso->XPKType[0];
     hchan->XPKType[1]=qso->XPKType[1];
     hchan->XPKType[2]=qso->XPKType[2];
     hchan->XPKType[3]=qso->XPKType[3];
     
     hchan->XPKEfficiency=qso->XPKEfficiency;
     hchan->XPKSublibrary=qso->XPKSublibrary;
     for (k=0;k<260;++k)
      {
       hchan->XPDecompress[k]=qso->XPDecompress[k];      
      }     
     for (k=0;k<128;++k)
      {
       hchan->XPacketKey[k]=qso->XPacketKey[k];
      }
    }
    
   if (uchan==0)
    {
     DeleteFile(HOLDING_FILE);
     QSO_FreeHoldArray();
     return(0);
    }

   hfile=Open(HOLDING_FILE,MODE_NEWFILE);
  
   if (hfile==NULL)
    {
     QSO_FreeHoldArray();
     return(-1);
    }
  
    {
     unsigned long klen;
     
     klen=sizeof(struct HoldChannel);
     
     if (Write(hfile,&klen,4)!=4)
      {
       Close(hfile);
       DeleteFile(HOLDING_FILE);
       QSO_FreeHoldArray();
       return(-1);
      }
     
     if (Write(hfile,HoldArray,sizeof(struct HoldChannel)*MaxChannel)!=
         sizeof(struct HoldChannel)*MaxChannel)
      {
       Close(hfile);
       DeleteFile(HOLDING_FILE);
       QSO_FreeHoldArray();
       return(-1);
      }
    }

   Close(hfile);
   QSO_FreeHoldArray();
   return(0);
  }
  
 int QSO_HoldRestorePre(unsigned long channel,int selfconnect,
                         int freshconnect)
  {
   struct HoldChannel *hold;
   struct QSO *qso;
   int i;
   
   if (HoldArray==NULL) return(0);
   
   hold=HoldArray+(channel-1);
   qso=QSOs+(channel-1);
   
   if (hold->Connected==0) return(0);
   
   if ( (selfconnect) || (freshconnect) || (qso->LinkStatus==0) ||
        (!CompareString(hold->HardCall,qso->HardCall) ) ||
        (!CompareString(hold->MyCall,qso->MyCall) ) )
    {
     hold->Connected=0;
     return(0);
    }
    
   qso->SelfConnect=hold->SelfConnect;
   
   CopyString(qso->Call,hold->Call);
   for (i=0;i<8;++i)
    {
     CopyString(qso->Path[i],hold->Path[i]);
    }
   
   hold->Connected=0;
   return(1);
  }
  
void QSO_HoldRestorePost(unsigned long channel)
 {
  struct HoldChannel *hchan;
  struct QSO *qso;
  int k;
  
  if (HoldArray==NULL) return;
  
  hchan=HoldArray+(channel-1);
  qso=QSOs+(channel-1);

   CopyString(qso->CurrentDir,hchan->CurrentDir);
  
   {
     qso->CompressedMode=hchan->CompressedMode;
     qso->ConnectTime=hchan->ConnectTime;
     qso->ActivityTime=hchan->ActivityTime;
     qso->LastLogin=hchan->LastLogin;
     
     qso->SysopMode=hchan->SysopMode;
     qso->PrivateDir=hchan->PrivateDir;
 #ifdef AmigaOS
      {
       unsigned char *s1,*s2,*s3,*t1,*t2,*t3;
       
       t1=(unsigned char *) &qso->EditInStream;
       s1=(unsigned char *) &hchan->EditInStream;
       t2=(unsigned char *) &qso->EditOutStream;
       s2=(unsigned char *) &hchan->EditOutStream;
       t3=(unsigned char *) &qso->PacketOutStream;
       s3=(unsigned char *) &hchan->PacketOutStream;
       for (k=0;k<sizeof(struct ANSIStream);++k)
        {
         *(t1++)=*(s1++);
         *(t2++)=*(s2++);
         *(t3++)=*(s3++);
        }
      }
 #endif /*AmigaOS*/
      {
       unsigned char *s1,*s2,*t1,*t2;
       
       t1=qso->CipherInputBuffer;
       t2=qso->CipherOutputBuffer;
       s1=hchan->CipherInputBuffer;
       s2=hchan->CipherOutputBuffer;
       for (k=0;k<384;++k)
        {
         *(t1++)=*(s1++);
         *(t2++)=*(t2++);
        }
      }
     qso->XPKType[0]=hchan->XPKType[0];
     qso->XPKType[1]=hchan->XPKType[1];
     qso->XPKType[2]=hchan->XPKType[2];
     qso->XPKType[3]=hchan->XPKType[3];
     
     qso->XPKEfficiency=hchan->XPKEfficiency;
     qso->XPKSublibrary=hchan->XPKSublibrary;
     for (k=0;k<260;++k)
      {
       qso->XPDecompress[k]=hchan->XPDecompress[k];      
      }     
     for (k=0;k<128;++k)
      {
       qso->XPacketKey[k]=hchan->XPacketKey[k];
      }
    }
 
 }
