/*
 *  CopyRight 1995. Nicholas Poljakov all rights reserved.
 */
#include <bios.h>
#include <dos.h>
#include <memory.h>
#include <direct.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <io.h>
#include <fcntl.h>
#include <stdlib.h>
#include <crtp.h>
#include <state1.h>

#define BORDER 1
#define REV_VID 0x70
#define NORM_VID 0x1E
#define MAX_FRAME 31
#define BKSP 8
#define F1 59
#define F2 60
#define F3 61
#define F4 62
#define F5 63
#define F6 64
#define F7 65
#define F8 66
#define F9 67
#define F10 68
#define HM  71   /* Home key     */
#define UP  72   /* Up Arrow     */
#define PU  73   /* Page Up      */
#define LT  75   /* Left Arrow   */
#define RT  77   /* Right Arrow  */
#define END 79   /* End key      */
#define DN  80   /* Down Arrow   */
#define PD  81   /* Page Down    */
#define ESC '\033'

#define lsl	 1
#define max_tps  1
#define partsl   1
#define maxru    2017
#define pac      1
#define MAX_FRAME 31
#define L_PSTR	sizeof(struct part) * 4
extern short cur_ln;
extern struct menu_frame {
    int startx, endx, starty, endy;
    unsigned char *p;
    char **menu;
    char *keys;
    int border;
    int count;
    unsigned char attrib;
    int active;
    int curx, cury;
    char *header;
    unsigned char shd;
    } frame[MAX_FRAME];

extern struct LU_PARM{
       unsigned long conv_id;
       unsigned char lu_id[8];
       unsigned char tp_id[8];
       char tp_name[64];
}*p_lparm;
extern struct APL_PARM{
       int status;  /* 0-start aplmain,1-start transaction,2-dos shell */
       char p[80];  /* string for system(p) */
       char args[64];/* string of arguments */
       int rc;      /* aplmain return code */
       char dir[60];/* directory name for aplmain */
       int drlen;   /* directory name length */
       void *tpe;   /* entry of exit program */
       char pgm_state;
}*p_aparm;
extern char *sv;
extern char *vid_mem;
extern char tp_exist; /* Tp_exist eq. 0 if TP not active, and 1 vice versus.*/
extern char lu_name[9];
extern char lu_id[8];
extern unsigned  long conv_id;
extern char mode_name[9];
extern char tp_id[8];
extern unsigned char pgm_state;
extern char InTp[40]; /* received TP name */
extern struct crtp *p_crtp;
extern unsigned char **tlx;
extern void SendFil(char *, int);

extern char ps[4][14];
int Fmh5Handler();
void rem_exe(char *);
void rem_com(char *);
extern int p_lu_num;   /* number of LU - partners */
extern struct	part	{	     /* partner structure */
                  char   plu[8] ;             /* str plu_name        */
                  int psl;                    /* str plu_s_limit     */
                  char   mode_name[8] ;       /* str mode_name       */
                  int max_ru_size;            /* str ru_h_size       */
                  int pacing;                 /* str =               */
                  unsigned char lu_type;
               }  pstr[4];
void _interrupt _far tpe( unsigned _es, unsigned _ds, unsigned _di,
			       unsigned _si, unsigned _bp, unsigned _sp,
			       unsigned _bx, unsigned _dx, unsigned _cx,
			       unsigned _ax, unsigned _ip, unsigned _cs,
                unsigned _flags );

SetLu()
{
    unsigned int ch;
    union inkey {
                   char ch[2];
                   unsigned int i;
                } *c;
    char buff[9];
    int i;
    int j;
    int n;
    unsigned long rc;
    char retstr[6];
    void *tp_exit;
    unsigned char rtr;   /* retry switch for local menu operations */
    unsigned char key;

    if (lu_id[0] != 0) {
        window(14);
	window_xy(14, 2, 1);
        window_puts(14, "One LU can be attached only!");
        window_xy(14, 3, 4);
        window_puts(14, "Press ESC to continue");
        while ((ch = getch()) != ESC) ;
        deactivate( 14 );
        return 0;
    }
    if (p_lu_num != 0) {
        window(5);
        window_xy(5, 1, 6);
        window_puts(5, "Reset configuration ?");
        window_xy(5, 2, 12);
        window_puts(5, "[Y]");
        window_xy(5, 2, 13);
     ReIn:
	ch = getch();
        ch &= 0x00ff;
        if ((ch == 'y')||(ch == 'Y')) {
             p_lu_num = 0;
             lu_name[0] = 0x00;
             mode_name[0] = 0x00;
             set0(&pstr, L_PSTR);
             p_lu_num = 0;
             deactivate( 5 );
        }
        else
             if ((ch == 'n')||(ch == 'N')) {
                deactivate( 5 );
                n = p_lu_num;
                goto Att_lu;
             }
             else
                goto ReIn;
    }

    rtr = 0;
    c = &ch;
    window(5);
    window_xy(5, 1, 1);
    window_puts(5, "LU name............");
    window_xy(5, 2, 1);
    window_puts(5, "Mode name..........");
   SetLLu:
    window_xy(5, 1, 20);
    window_puts(5, "        ");
    window_xy(5, 1, 20);
    if (window_gets(5, buff) == 1) { /* read local LU name */
        goto SetExit;
    }
    strcpy(lu_name, buff);
    window_xy(5, 2, 20);
    if (window_gets(5, buff) == 1) { /* read local mode name */
        goto SetLLu;
    }
    if (buff[0] == 0x00) {
      strcpy(buff, "MODE6");
      window_puts(5, "MODE6");
    }
    strcpy(mode_name, buff);
    /* Read LU partners names and others */
    for (i = 0; i < 4; i++) {
        window(16 + i);
        window_xy(16 + i, 1, 1);
        window_puts(16 + i, "LU name............");
        window_xy(16 + i, 2, 1);
        window_puts(16 + i, "Mode name..........");
        window_xy(16 + i, 3, 1);
        window_puts(16 + i, "LU type............");
    SetPLu:
        window_xy(16 + i, 1, 20);
        window_puts(16 + i, "        ");
        window_xy(16 + i, 1, 20);
        if (window_gets(16 + i, buff) == 1) { /* read partner LU name */
             rtr = 1;
             goto ClsWin;
        }
        strcpy(pstr[i].plu, buff);
     SetMode:
        window_xy(16 + i, 2, 20);
        window_puts(16 + i, "        ");
        window_xy(16 + i, 2, 20);
        if (window_gets(16 + i, buff) == 1) { /* read partner mode name */
             rtr = 1;
             goto SetPLu;
        }
        if (buff[0] == 0x00) {
          strcpy(buff, "MODE6");
          window_puts(16 + i, "MODE6");
        }
        strcpy(pstr[i].mode_name, buff);
     SetType:
        window_xy(16 + i, 3, 20);
        ch = window_getche(16 + i);
        if (ch == ESC) {
            goto SetMode;
        }
        key = c -> ch[0] & 0x0f;
        if ((key != 6)&&(key != 0)) {
           window(14);
           window_xy(14, 2, 5);
           window_puts(14, "Type must be 6 or 0");
           window_xy(14, 3, 4);
           window_puts(14, "Press ESC to continue");
           while ((ch = getch()) != ESC) ;
           deactivate(14);
           window_xy(16 + i, 3, 20);
           window_puts(16 + i, "        ");
           window_xy(16 + i, 3, 20);
           goto SetType;
        }
        pstr[i].lu_type = key;
        pstr[i].psl=partsl;
        pstr[i].max_ru_size=maxru;
        pstr[i].pacing=pac;
        if ((ch = getch()) == ESC) {
            goto ClsWin;
        }
    }
    i = 3;
ClsWin:
    n = i + 1;
    p_lu_num = n;
    for (j = i; j >= 0; j--) {
        deactivate(16 + j);
    }
    if (rtr) {
        rtr = 0;
        window_xy(5, 2, 20);
        window_puts(5, "        ");
        window_xy(5, 2, 20);
        goto SetLLu;
    }
Att_lu:
    tp_exit = p_aparm -> tpe;
    attachlu   (
             lu_name,
             lsl,
             max_tps,
             tp_exit,
             n,
             &pstr,
             &rc,
             lu_id);
    if (rc != 0) {
        window(14);
        window_xy(14, 1, 1);
        window_puts(14, "Return code from ATTACH_LU");
        sprintf(retstr,"%lx",rc);
        i = (30 - strlen(retstr))/2;
        window_xy(14, 2, i);
        window_puts(14, retstr);
        while ((ch = getch()) != ESC) ;
        deactivate(14);
    }
    else
            {
               window(15);
               window_xy(15, 2, 8);
               window_puts(15, "LU is active!");
               while ((ch = getch()) != ESC) ;
	       deactivate(15);
	       cur_ln = 0; /* initial value */
	    }
 /*
    if (!tp_exist) {
        tp_started
                 (lu_id,
                  tp_id,
                  &rc);
        if (rc != 0) {
            window_xy(20, 6, 1);
            window_puts(20, "TP_started failure. Press ESC to exit.");
	    goto SetExit;
	}
	tp_exist = 1;
    }
 */

SetExit:
    deactivate(5);
};
SelPtLu()
{
       register int i;
       char *p_nm[4];
       char p[8];

       for (i = 0; i < p_lu_num; i++) {
	   ps[i][0] = (i + 1) | 0x30;
	   ps[i][1] = 0x00;
	   strcat(ps[i], ". ");
	   strcat(ps[i], pstr[i].plu);
	   p_nm[i] = ps[i];
       }
       make_menu(24, p_nm, "1234", p_lu_num, 3, 12, BORDER, 0x72, 1);
       sfs(sv, vid_mem);
       cur_ln = pulldown(24);
       restore_video( 24 );
};
SelectFile()
{
};
Fmh5Handler()
{
        unsigned key;

     WaitFMH:
        p_aparm -> pgm_state = 0;
        window(21);
        window_xy(21, 3, 2);
	window_puts(21, "Waiting for request from remote LU");
	window_xy(21, 5, 10);
	window_puts(21, "Press ESC for EXIT...");
        while (!(p_aparm -> pgm_state)) {
             _asm
                  {
                     mov   ax, 0b00h
                     int   21h
                     and   ax, 00ffh
                     mov   word ptr key[0], ax
                  }
             if (key != 0) {
                    if ((key = getch()) == ESC) {
                        goto HdExit;
                    }
             }
	/*
             if (_bios_keybrd( _KEYBRD_READY ) != 0) {
                 key = _bios_keybrd( _KEYBRD_READ );
                 key &= 0x00ff;
                 if (key == 27) {
                     goto HdExit;
                 }
	     }
	 */
	}
	memcpy(tp_id, p_lparm->tp_id, 8);
	memcpy(lu_id, p_lparm->lu_id, 8);
	memcpy(InTp, p_lparm->tp_name, 40);
	conv_id = p_lparm -> conv_id;

	if (memcmp(InTp, "TTY", 3) == 0) {
	     em_tty();
	     goto WaitFMH;
        }
        else
              if (memcmp(InTp, "SEND", 4) == 0) {
                  rcv(InTp);
                  goto WaitFMH;
              }
              else
                    if (memcmp(InTp, "DIR", 3) == 0) {
                        dir(InTp);
                        goto WaitFMH;
                    }
                    else
                           if (memcmp(InTp, "RCV", 3) == 0) {
                                snd(InTp);
                                goto WaitFMH;
                           }
                           else
                                if (memcmp(InTp,"COPY",4) == 0){
                                    rem_cp(InTp);
                                    goto WaitFMH;
                                }
                                else
                                     if (memcmp(InTp,"EXE",3) == 0){
                                         rem_exe(InTp);
                                     }
                                     else
                                         if (memcmp(InTp,"COM",3) == 0){
                                                 rem_com(InTp);
                                         }
					 else
                                             goto WaitFMH;
   HdExit:
        deactivate(21);
        p_aparm -> pgm_state = 0;  /* Off state flag */
        return 0;
}
void rem_exe(char *p){

 unsigned char rts;
 unsigned char wr;
 unsigned int max_length ;
 char gds[8];
 char *p_arg;
 char l_arg;
 int length;
 struct rc {
         unsigned int prim;
         unsigned long sec;
 } v_rc;
 unsigned long rc;

    max_length = 2017;
    recwait (tp_id,
          conv_id,
          ll,
          &v_rc,
          &length,
          max_length,
          &rts,
          &gds,
          &wr);
    deallocate (tp_id,
                conv_id,
                Flush,
                &v_rc);
    tp_ended (tp_id, &rc);
    p_aparm -> status = 1;
    p_aparm -> rc = 1;
    strcpy( p_aparm -> p,&p[4]);
    p_arg = strchr(p_aparm -> p,' ');
    strcpy( p_aparm -> args, p_arg);
    *p_arg = 0x00;
    p_arg++;
    l_arg = (char)strlen(p_arg);
    l_arg++;
    p_aparm -> args[0] = l_arg;
    p_aparm -> args[l_arg] = 0x0d;
    p_aparm -> args[l_arg+1] = 0x00;
    p_lparm -> conv_id = conv_id;
    memcpy( p_lparm -> lu_id, lu_id,8);
    memcpy( p_lparm -> tp_id, tp_id,8);
    save_ini();
    cls(0);
    goto_xy(0,0);
    exit (1);
}
void rem_com(char *p){

 unsigned char rts;
 unsigned char wr;
 unsigned int max_length ;
 char gds[8];
 char *p_arg;
 char l_arg;
 int length;
 struct rc {
         unsigned int prim;
         unsigned long sec;
 } v_rc;
 unsigned long rc;

    max_length = 2017;
    recwait (tp_id,
          conv_id,
          ll,
          &v_rc,
          &length,
          max_length,
          &rts,
          &gds,
          &wr);
    deallocate (tp_id,
                conv_id,
                Flush,
                &v_rc);
    tp_ended (tp_id, &rc);
    p_aparm -> rc = 3;
    l_arg = (char)strlen(&p[4]);
    p_aparm -> args[0] = l_arg;
    strcpy( &(p_aparm -> args[1]),&p[4]);
    p_lparm -> conv_id = conv_id;
    memcpy( p_lparm -> lu_id, lu_id,8);
    memcpy( p_lparm -> tp_id, tp_id,8);
    save_ini();
    cls(0);
    goto_xy(0,0);
    exit (3);
}
showp(ind)
int ind;
{
        int i;
	unsigned char type[2];
        unsigned char att;

	type[1] = 0x00;
        window(22);
        for (i = 0; i < 3; i++) {
             write_string(6 + i, 26, tlx[i], frame[22].attrib);
        }
	for (i = 0; i < p_lu_num; i++) {
	     if (cur_ln == i)
		att = frame[22].attrib | 0x0e;
	     else
		att = frame[22].attrib;
	     write_string(9 + i, 26, tlx[3], frame[22].attrib);
	     write_string(9 + i, 28, pstr[i].plu, att);
	     write_string(9 + i, 46, pstr[i].mode_name, frame[22].attrib);
	     type[0] = pstr[i].lu_type | 0x30;
	     write_string(9 + i, 59, type, frame[22].attrib);
        }
        write_string(9 + i, 26, tlx[4], frame[22].attrib);
        att = frame[22].attrib;
        att |= 0x09;
	write_string(7, 14, "Local LU" ,att);
        att |= 0x0f;
	write_string(9, 14, lu_name, att);
        if (ind) {
           getch();
	   deactivate(22);
	}
}
rcv(p)
char *p;
{
        struct rcvd {
                      int len;
                      char  dt[2000];
                    } *p_data;
        unsigned long rc;
        unsigned ch;
        unsigned char rts;
        unsigned char wr;
        struct rc {
                  unsigned int prim;
                  unsigned long sec;
                } v_rc;
        unsigned  int max_length ;
	unsigned long cnt;
	int  length;
        char ccnt[10];
	char fn[18];
	char path[_MAX_PATH];
        int fd;

        strcpy(fn, &p[5]);

        window(26);  /* Receive window */
        window_xy(26, 2, 1);
        window_puts(26, "Receive file : ");
        window_puts(26, fn);
        window_xy(26, 3, 1);
	window_puts(26, "Current path is : ");
	_getdcwd( 0, path, _MAX_PATH );
	window_puts(26, path);
        window_xy(26, 4, 1);
        window_puts(26, "Current count is : 0");

    if ((fd = open(fn, O_WRONLY | O_CREAT | O_BINARY)) < 0) {
              window(14);
              window_xy(14, 2, 5);
              window_puts(14, "Error File Open");
              window_xy(14, 3, 4);
              window_puts(14, "Press ESC to continue");
              while ((ch = getch()) != ESC) ;
              goto RcvExit;
    }
    if ((p_data = malloc(sizeof(struct rcvd))) == NULL) {
        return 1;
    }
       cnt = 0;
       max_length = 2000;
 lcicl :
       recwait (tp_id,
                conv_id,
                ll,
                &v_rc,
                &length,
                max_length,
                &rts,
                p_data,
		&wr);
       if( v_rc.prim == OK) {
             write(fd,p_data->dt, p_data->len - 2);
             window_xy(26, 4, 20);
	     cnt += p_data -> len-2;
	     sprintf(ccnt, "%lu", cnt);
             window_puts(26, ccnt);
       }
       else
            goto RcvExit;
       recwait(tp_id,
                conv_id,
                ll,
                &v_rc,
                &length,
                max_length,
                &rts,
                p_data,
		&wr);
       if( v_rc.prim == OK) {
          goto lcicl;
       }
RcvExit:
        close( fd );
        free(p_data);
        window_xy(26, 5, 1);
        window_puts(26, "End of File... ");
        deactivate( 26 );
        if (p_aparm -> pgm_state == 1) { /* remote control */
            tp_ended (tp_id, &rc);
        }
        return 0;
}
snd(p)
char *p;

{
   SendFil(p + 4, 0);
}
