/*
    $Header: Welmat:src/Welmat/xprfts/RCS/lotek.c,v 1.2 92/11/24 23:40:31 rwm Exp Locker: rwm $

    Perform a Lotek/DietIFNA session

    Copyright (C) 1988,1989,1990 Michael Richardson
    Copyright (C) 1992 Russell McOrmond

    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., 675 Mass Ave, Cambridge, MA 02139, USA.

*/


#ifdef RCSID
static char RCSid[]="$Id: lotek.c,v 1.2 92/11/24 23:40:31 rwm Exp Locker: rwm $\n";
#endif

#include <proto/all.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xproto.h"
#include "xmodem.h"
#include "xprfts.h"

struct ExecBase *SysBase=(struct ExecBase *)4l;

/* Main file transmission routine; called by comm program */
long  __saveds XProtocolSend(struct XPR_IO *io) {
  struct Vars *v;
  int state;
  char filename[256];

  /* Perform common setup and initializations */
  if (!(v = setup(io)))  return XPRS_FAILURE;

#ifdef KDEBUG
  KPrintF("7%lc C%lc O%lc I%lc P%lc S%lc B%lc A%lc N%lc W%lc F%lc M%lc D:%ld\n",
   v->option_7,v->option_c,v->option_o,v->option_i,v->option_p,
   v->option_s,v->option_b,v->option_a,v->option_n,v->option_w,v->option_f,
   v->option_m, v->debug);
#endif

  (void) xpr_sread(v,filename,255,1000000);

  state=sendXFiles(v);

  if(state==NODCD) goto ret1;
  else if(state!=OK) {
    updmsg(v,"Couldn't indicate end of outbound file attaches!");
    goto ret1;
  } else 
    updmsg(v,"End of outbound file attaches.");

  if(v->option_p=='N') {
    updmsg(v,"Not picking up.");
    goto ret1;
  }
  xpr_sflush(&v->io);

/*
 |-----+----------+-------------------------+-------------------------+-----|
 | R3* | RecMail  |                         | (XMODEM rec packet XR0) | R4  |
 |-----+----------+-------------------------+-------------------------+-----|
 | R4  | XRecEnd  | 1 XMODEM successful     | delay 1 second          | R5  |
 |     |          |                         |   flush input           |     |
 |     |          | 2 XMODEM failed         | hang up, rept mail fail | exit|
 */

  updmsg(v,"Exchanging roles");
  filename[0]='\0';
  if((state=receiveXFile(filename,v,FALSE))==OK) {
    updstatus(v,filename,XPRS_SUCCESS);
    while(state==OK) {
      filename[0]='\0';
      state = receiveXFile(filename,v,TRUE);
      updstatus(v,filename,(state==OK) ? XPRS_SUCCESS : XPRS_FAILURE);
    }
  }

  ret1:
  SPrintF(v->scratch,"R2: End of outbound Lotek/DietIFNA session.(%ld)\n",state);
  updmsg(v,v->scratch);

  /* Clean up and return */
  FreeMem(v,(long)sizeof(struct Vars));
  return ((state==ERROR) ? XPRS_FAILURE : XPRS_SUCCESS );
}


/* Main protocol for inbound calls */
long __saveds XProtocolReceive(struct XPR_IO *io) {
  struct Vars *v;
  int state;
  char filename[256];

  /* Perform common setup and initializations */
  if (!(v = setup(io))) return XPRS_FAILURE;

#ifdef KDEBUG
  KPrintF("7%lc C%lc O%lc I%lc P%lc S%lc B%lc A%lc N%lc W%lc F%lc M%lc D:%ld\n",
   v->option_7,v->option_c,v->option_o,v->option_i,v->option_p,
   v->option_s,v->option_b,v->option_a,v->option_n,v->option_w,v->option_f,
   v->option_m, v->debug);
#endif

  (void) xpr_sread(v,filename,255,1000000);

/*
 |-----+----------+-------------------------+-------------------------+-----|
 | R3* | RecMail  |                         | (XMODEM rec packet XR0) | R4  |
 |-----+----------+-------------------------+-------------------------+-----|
 | R4  | XRecEnd  | 1 XMODEM successful     | delay 1 second          | R5  |
 |     |          |                         |   flush input           |     |
 |     |          | 2 XMODEM failed         | hang up, rept mail fail | exit|
 */

  updmsg(v,"Mail bundles");
  filename[0]='\0';
  if((state=receiveXFile(filename,v,FALSE))!=OK && state!=GOTEOT) {
    updstatus(v,filename,XPRS_FAILURE);
    goto ret2;
  }
  updstatus(v,filename,XPRS_SUCCESS);
  filename[0]='\0';

  if (state!=GOTEOT) {
    updmsg(v,"Inbound File attaches");
    while((state=receiveXFile(filename,v,TRUE))==OK) {
      updstatus(v,filename,XPRS_SUCCESS);
      filename[0]='\0';
    }
    if(state!=GOTEOT) {
      updstatus(v,filename,XPRS_FAILURE);
      goto ret2;
    }
    updstatus(v,filename,XPRS_SUCCESS);
  }
  updmsg(v,"End of inbound file attaches");
  updmsg(v,"Turn around and send");

  state=sendXFiles(v);
 ret2:

  SPrintF(v->scratch,"R2: End of inbound Lotek/DietIFNA session.(%ld)\n",state);
  updmsg(v,v->scratch);

  /* Clean up and return */
  FreeMem(v,(long)sizeof(struct Vars));
  return ((state==ERROR) ? XPRS_FAILURE : XPRS_SUCCESS);
}

int AllocWindowX(struct WindowX *WindowXBuff)
{
  int i;

  NewList(&WindowXBuff->wx_blocks);
  NewList(&WindowXBuff->wx_freeblocks);
  if((WindowXBuff->blockBuffer=AllocMem(sizeof(block)*(MAXXWINDOW+1),
           MEMF_PUBLIC|MEMF_CLEAR))==NULL)
            return(FALSE);

  for(i=0; i<=(MAXXWINDOW); i++) {
    AddTail(&WindowXBuff->wx_freeblocks,(void *)((long)(WindowXBuff->blockBuffer)
                         +(i*sizeof(block))));
  }
  return(TRUE);
}

void FreeWindowX(struct WindowX *WindowXBuff)
{
  FreeMem(WindowXBuff->blockBuffer,sizeof(block)*(MAXXWINDOW+1));
}

void AckNak(struct Vars *v,int SeaLink,int blocknum,char AckNak)
{
  char *c;
  char temp[100];

  c="Unknown";
  switch(AckNak) {
    case ACK:
      c="S:ACK";
      break;
    case NAK:
      c="S:NAK";
      break;
    case CNAK:
      c="S:CNAK";
      break;
  }
  temp[0]=AckNak;
  xpr_swrite(&v->io,temp,1);
  if(SeaLink) {
    temp[0]=blocknum&0xff;
    temp[1]=(~blocknum)&0xff;
    xpr_swrite(&v->io,temp,2);
    SPrintF(temp,"%s*",c);
    updmsg(v,temp);
  } else
    updmsg(v,c);
}
