/*->c.ftpglue */


#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"
#include "h.bbc"
#include "h.flex"
#include "h.swis"


#include "h.DrawLevel0"


#include "h.etc"
#include "h.def"

#include "h.wos"

#include "h.strdef"

#include "h.timex"
#include "h.main"
#include "h.ram"
#include "h.mym"
#include "h.xext"
#include "h.config"
#include "h.key"
#include "h.pr"
#include "h.script"
#include "h.con"
#include "h.serial"
#include "h.fsx"

#include "h.file"
#include "h.dir"
#include "h.view"
#include "h.sched"
#include "h.txfax"
#include "h.batch"
#include "h.state"
#include "h.dbug"
#include "h.copy"
#include "h.vx"


#include "h.ftpglue"



int rxbitrate=2400;
int txbitrate=2400;

int ftp_ok;

static int online;


static int totlength;
static int bytessofar;



/* get a byte from line, in given time, or return -1 */

int  ftpgetbyte(int time)
{
 int byte;

 time=clock()+time;

 do 
 {
  if((byte=getbyte())!=-1) return(byte);
  pollzt();
  if(!ftp_ok) return(-1);
 } while(time>clock());

 return(-1);
}



int ftpoutbyte(int byte)
{
 return(outbyte(byte));
}



int  ftponline(void)
{
 return(online);
}



/* trash the input buffer */

void ftpflushinput(void)
{
 int r0=1; /* RX    */
 int r1=0; /* purge */
 xexec2("modem_countpurge",&r0,&r1,NULL);
}



/* returns number of bytes in the input buffer */

int ftpinputchars(void)
{
 int r0=1; /* RX              */
 int r1=1; /* bytes in buffer */
 if(!xexec2("modem_countpurge",&r0,&r1,&r1)) r1=0;
 return(r1);
}



/* send cancel string to get the other end to shut up */

void ftpcanit(void)
{
 static char canitstr[]=
 {
  24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
 };
 int i=0;

 while(canitstr[i]) outbyte(canitstr[i++]);
}



/*****************************************************************************/


void ftpinfo(char * format, ...)
{
 va_list args;
 char v[128];
 va_start(args, format);
 vsprintf(v, format, args);
 va_end(args);

 conaction("%s",v);
}


void ftpsetmode(char * mode)
{
 mode=mode;
}

static void ftpwritepc(void)
{
 if(totlength) concomplete((bytessofar*100)/totlength);
 else          concomplete(0);
}


/****************************************************************************/

       char txdname[256];
static int  dtxbn;

int ftpread(void * buff,int size,int number,FILE * fp)
{
 int code;
 code=fread(buff,1,number,fp);
 bytessofar+=code;
 ftpwritepc();
 return(code);
}

int ftpreadfseek(FILE *stream, long int offset, int whence)
{
 int code;
 code=fseek(stream,offset,whence);
 bytessofar=(int)ftell(stream);
 ftpwritepc();
 return(code); 
}


int ftpcloseread(FILE * fp,char * message,int flags)
{
 int code;

 code=0;

 if(fp)
 {
  if(dtxbn>=0)
  {
   conaction("{CON15}");
   conclrfax();
  }

  code=fclose(fp);

  if(dtxbn>=0)
  {
   if(!(flags & FTPCLOSEERROR) && !code)
   {
    schedsentdoc();
    writetolog("{LOG11} %s {LOG12}\n",leaf(txdocname));
   }
  }
 }

 return(code);

 USE(message);
}



FILE * ftpopenread(int bn,int bsize)
{
 fstat f;

 dtxbn=bn;

 if(bn<0)
 {
  stat(txdname,&f);
  totlength=f.length;
  bytessofar=0;
  ftpwritepc();
  conaction("{CON14}");
  confax(leaf(txdname));
  return(fopen(txdname,"rb"));
 }
 else
 {
  totlength=vtable[TXBFILE][bn].stat.length;
  bytessofar=0;
  ftpwritepc();

  conaction("{CON14}");
  confax(leaf(txdocname));

  return(fopen(txdocname,"rb"));
 }
 USE(bsize); /* size in blocks */
}



void ftpdirectsend(char * name)
{
 strcpy(txdname,name);
}


/****************************************************************************/

static int ftpstamp;
static int ftpload;
static int ftpexec;

static char rxname[256];
static int  rxdirect;


FILE * ftpopenwrite(char * rname,int * bn,
                                        int bsize,int len,int * flg,int * hdr)
{
 totlength=len;
 bytessofar=0;
 ftpwritepc();

 if(rxdirect) makefilename(rname,rxname,txdname,0);
 else         makefilename(rname,rxname,path(RXBP),0);

 if(hdr)
 {
  if(*hdr & 0x1) ftpload=*(hdr-1);
  if(*hdr & 0x2) ftpexec=*(hdr-2);
  ftpstamp=1;
 }
 else
  ftpstamp=0;

 return(fopen(rxname,"wb"));

 USE(bsize);
 USE(len);
 USE(flg);
}


int ftpwritefseek(FILE *stream,long int offset,int whence)
{
 int code;
 code=fseek(stream,offset,whence);
 bytessofar=(int)ftell(stream);
 ftpwritepc();
 return(code); 
}


int ftpwrite(void * buff,int size,int number,FILE * fp)
{
 int code;
 code=fwrite(buff,size,number,fp);
 bytessofar+=code;
 ftpwritepc();
 return(code);
}


int ftpwritetell(FILE * fp)
{
 return((int)ftell(fp));
}




int ftpclosewrite(FILE * fp,char * message,int flags)
{
 os_error * err;
 int        code;
 fstat      f;
 int        bn;

 code=0;

 if(fp)
 {
  conaction("{CON15}");
  if(!rxdirect)
  {
   conclrfax();
  }

  code=fclose(fp);

  if(rxdirect)
  {
   if(ftpstamp)
   {
    f.exec=ftpexec;
    f.load=ftpload;
    stamp(rxname,&f);
   }
  }
  else
  {
   stat(rxname,&f);

   if(!(flags & FTPCLOSEERROR) || !batdiscard)
   {
    bn=addtorxbatch(DATA,rxname,0,0)-1;      /* ** */

    writetolog("{LOG11} %s {LOG14}\n",leaf(rxname));

    if(ftpstamp)
    {
     f.exec=ftpexec;
     f.load=ftpload;
     stamp(rxname,&f);

     if(filetype(f.load)==TIFF)
     {
      tiffsum    tsum;

      memset(&tsum,0,sizeof(tiffsum));
      err=checktiff(&tsum,rxname);
      if(!err)
      {
       vtable[RXBFILE][bn].tsum=tsum;
      }
     }
     else
     {
      checkarc(&vtable[RXBFILE][bn].tsum,rxname);
     }
    }
    else
    {
     if(!checkarc(&vtable[RXBFILE][bn].tsum,rxname)) setftype(rxname,ARCHIVE);
    }

    stat(rxname,&vtable[RXBFILE][bn].stat);

    vtable[RXBFILE][bn].autoforward=batforward;
    vtable[RXBFILE][bn].autoprint=0;

    viewupdatetexticon(bn);        /* ** */
    setspritesr(bn);

    addzeroevent(RXFAXZERO);
   }
   else
   {
    fs_delete(rxname);
    writetolog("{LOG15}\n");
   }
  }
 }
 return(code);
}



void ftpdirectreceive(char * name)
{
 if(name) strcpy(txdname,name);
 rxdirect=(name!=NULL);
}


/*****************************************************************************/

static int  onlinectime;     /* time online time was last updated */


static int modemonline(void)
{
 int r0;

 if(!activestate()) return(0);
 else
 if(xexec("modem_online",NULL,NULL,&r0)) return(r0);
 else                                    return(1);
}


void onlinezero(void)
{
 if(zerotime>onlinectime)
 {
  online=modemonline();
  onlinectime=zerotime+100;
 }
}



/* function called if someone hits Cancel button */

static void txcancel(void)
{
 ftp_ok=0;
}


int ftpsendfiles(int fp)
{
 online=modemonline();
 addzeroevent(ONZERO);
 ftp_ok=1;
 setfaxcancelhandler(txcancel);

 setdbdataphase(1,0);
 zmodemtx();
 setdbdataphase(0,0);

 clearfaxcancelhandler();
 remzeroevent(ONZERO); 

 return(0);
 USE(fp);
}



static void rxcancel(void)
{
 ftp_ok=0;
}


int ftpgetfiles(int fp)
{
 online=modemonline();
 addzeroevent(ONZERO);
 ftp_ok=1;
 setfaxcancelhandler(rxcancel);

 setdbdataphase(1,1);
 zmodemrx();
 setdbdataphase(0,1);

 clearfaxcancelhandler();
 remzeroevent(ONZERO);

 return(0);
 USE(fp);
}


