
  /************************************************************************
                         APPL
  **************************************************************************/

  #include <stdio.h>
  #include "include.h"
  #include <malloc.h>
  #include <state1.h>
  #include <dos.h>
  #define RESRU 19
  #define RESRH 16
  #define APPC 0x68            /* 1068 */


extern struct segprf *preqseg(int n);
extern struct rqb *preqrq(int n);
extern void pattach(int n,char far *pdata,int len);
extern void prelseg(struct segprf *wseg);
extern void prelrq(struct rqb *wrqb);
extern void delhscb(struct hscb *whscb);


  extern struct rqb *appl1(struct rqb *wrqb);
  struct rqb *apost(short i,short k,unsigned char n);

  void Call_APPC(unsigned char RecForm,void far *p);

  struct rqb *findrqb(char *(*pq),short syscr);
  int bu_seg(short n, unsigned char t,char *p,struct hscb *whscb);

struct hscb *crhscb( char *mylu, char *partlu);
struct hscb *findhscb( unsigned long ccor );
     int rqbind(struct rqb *wrqbb);
     int unbind(struct rqb *wrqbb);
     int rqsend(struct rqb *wrqbb);
     int rspbind(struct rqb *wrqbb);
     int rspunbnd(struct rqb *wrqbb);



  struct rqb *appl(wrqb)
  struct rqb *wrqb;
  {
     int parm,n,rtncd;
     struct rh *wrh;
     union ru *wru;
     struct segprf *wseg;

     if (!(wrqb->th.ra.code & FROM))
            {
                     return (appl1(wrqb));
            }
     wseg=(struct segprf *)((char*)wrqb-12);
     if (wseg -> len < 3 )
             return 0;
     wru=(char*)wrqb+RESRU;
     wrh=(char*)wrqb+RESRH;
     if (wrh->rh[0] & RSP)
         goto RESP;
     if ((wrh->rh[0] == 0x6b) & (wrh->rh[1] == 0x80) )
          {
              if (wru->cru[0]==0x31) {
	      rtncd=rqbind(wrqb); goto BAC; }
              if (wru->cru[0]==0x32) {
	      rtncd=unbnd(wrqb); goto BAC; }
         }
     rtncd=rqsend(wrqb);
     goto BAC;
     RESP: n=0;
           if (wrh->rh[1] & ERTI)
                n=2;
           if (wru->cru[n]==0x31) {
	      rtncd=rspbind(wrqb);goto BAC; }
           if (wru->cru[n]==0x32) {
	      rtncd=rspunbnd(wrqb);goto BAC;}
           rtncd=rqsend(wrqb);
     BAC:
	  return 0;
     } /************ end of APPL ***************/
     /**************** BIND ******************/
     int rqbind(wrqbb)
     struct rqb *wrqbb;
     {
     struct th *wth;
     struct rqb *wpost;
     union ru *wru;
     struct bind *wbind;
     struct nau *wnau;
     struct hscb *whscb;
     struct rh *wrh;
     short netaddr;
     char *cor;
     int i;

     wbind=(char*)wrqbb+RESRU;
     whscb=crhscb(wbind->slu,wbind->plu);
     whscb->cor=wrqbb->th.ra.wa.hh.hscb;
     wrh=(char*)wrqbb+RESRH;
     wrh->rh[0] |= RSP;
     wrh->rh[1]=0;
     wrqbb->link=NULL;                     /* 0172 */
     wrqbb->th.ra.stcb=FISC_CODE;
     wrqbb->th.ra.code=0x02;
     wrqbb->th.ra.code |= FROM;        /* 0172 */
     wth=&(wrqbb->th.th);
     /* memcpy (&netaddr,&(wth->dest.lan.daf),2); */
     /* memcpy (&(wth->dest.lan.daf),&(wth->dest.lan.oaf),2); */
     /* memcpy (&(wth->dest.lan.oaf),&netaddr,2); */
    /*     wth->t13.rout.tnpath |= TPATH;  */ /* 0172 */
     pattach (1,wrqbb,4);
     wpost=apost(1,11,1);         /* 0279 */
     if (wpost==NULL)
	    return 0;
     wpost->th.ra.wa.hh.hscb=whscb->cor;
     wru=(char*)wpost+RESRU;
     memcpy (wru,&(whscb->hslunam[0]),8);
     Call_APPC (1,wpost);       /*@2003 */
     return 0 ;

     }/***************** end of bind **************/
     /****************** RSP(BIND) **************/
     int rspbind(wrqbrb)
     struct rqb *wrqbrb;
     {
        struct segprf *wsegbf;
        struct rqb *wrqbbf,*wpost;
        struct th *wth;
        struct rh *wrh;
        union ru *wru,*wrup;
        struct hscb *whscb;
        struct bind *wbind;
        struct rqb *wrqbq;
        struct nau *wnau;
        struct segprf *wseg;
        short i;
        wseg=(struct segprf *)((char*)wrqbrb-12);
          wrh=(char*)wrqbrb+RESRH;
          wru=(char*)wrqbrb+RESRU;
          whscb=findhscb(wrqbrb->th.ra.wa.hh.hscb);
          wnau=whscb->naup;
          wth=&(wrqbrb->th.th);
          if ((wrh->rh[1] & ERTI) == 0)
                goto POSRSP;
          wbind=&(wru->cru[2]);
	         wseg->link=NULL;   /*5002*/
	         wrqbrb->link=NULL; /*5002*/
          prelseg(wseg);
            wrqbq=findrqb(&(wnau->opnq),wth->t912.old.snf); /* 1068 */
          if (wrqbq==NULL)
                return 0;
          wrqbq->th.ra.rparm.parm.parm1=5;
          wrqbq->th.ra.rparm.parm.parm2=0xff;
          wrqbq->th.ra.code=0xda;
          Call_APPC(5,wrqbq);     /* @2003 */
           return 0;
        POSRSP:
           wrqbq=findrqb(&(wnau->opnq),wth->t912.old.snf);  /* 1068 */
           if (wrqbq==NULL)
              { wpost=apost(1,19,1);         /* 0279 */   /* 2005 */
                if(wpost==NULL)
			return 0;
                wpost->th.ra.wa.hh.hscb=whscb->cor;
                wrup=(char*)wpost+RESRU;
                 memcpy (wrup,&(whscb->hslunam[0]),8);
                 memcpy (wrup+8,&(whscb->hsnodnam[0]),8);    /* 2005 */
        Call_APPC(1,wpost);          /* @2003 */
	         wseg->link=NULL;   /*5002*/
	         wrqbrb->link=NULL; /*5002*/
                prelseg (wseg);
                return 0;
              }
          wrqbq->th.ra.rparm.parm.parm1=5;
          wrqbq->th.ra.rparm.parm.parm2=0xff;
          wrqbq->th.ra.code=0xc2;
          wrqbq->th.ra.wa.hh.hscb=whscb->cor;
         Call_APPC(5,wrqbq);        /* @2003  */
	         wseg->link=NULL;   /*5002*/
	         wrqbrb->link=NULL; /*5002*/
          prelseg(wseg);
          return 0;
    }  /***************end of rsp(bind)**********************/
    /********************** SEND ********************************/
     int rqsend(wrqbs)
     struct rqb *wrqbs;
    {
        int i,k;
        struct nau *wnau;
        struct hscb *whscb;
        unsigned char type;
    struct rh *wrh;
    union ru *wru;
    char *pru,*prh;
    struct segprf *wseg;
	wseg=(struct segprf *)((char*)wrqbs-12);
    whscb=findhscb(wrqbs->th.ra.wa.hh.hscb);
       wnau=whscb->naup;

      wrh=(char*)wrqbs+RESRH;
      prh = wrh;
    wru=(char*)wrqbs+RESRU;
    pru = wru;
    i=wseg -> len - 3 ;
        if ( i == 0 )
                {
                  if ( ((*prh & 0x0b) == 0x0b) && ((*(prh+1) & 0x80) == 0x80) )
                        {
                          type= Request_to_send;
                          bu_seg(0,type,NULL,whscb);
                        }
                  if ( ((*prh & 0x81) == 0x81) && ((*(prh+1) & 0xa0) == 0xa0) )
                        {
                          type= COnfirmed;
                          bu_seg(0,type,NULL,whscb);
                        }
       if ( (*(prh+2) & 0x21 )  == 0 )
            {   /* no change dir */
                 if ( (((*prh) & 0x01 ) == 0x01) && (((*(prh+1)) & 0xa0) == 0xa0))
                          { type = Confirm;
                            bu_seg(0, type, NULL,whscb);
                          }
            }
       if ( ((*(prh+2)) & 0x20) == 0x20 ) /* prep to rec */
            {
                if ( (*(prh+1) & 0xb0 ) == 0x90)   /* flush */
                           type = PREP_TO_RCV_FLUSH;
                if ( (*(prh+1) & 0xb0 ) == 0xa0)   /* short */
                           type = PREP_TO_RCV_CONFIRM_SH;
                if ( (*(prh+1) & 0xb0 ) == 0xb0)   /* long */
                           type = PREP_TO_RCV_CONFIRM_LG;
                bu_seg( 0, type,NULL,whscb);
            }
       if ( ((*(prh+2)) & 0x01 ) == 0x01)   /* deallocate */
            {
                if ( (*(prh+1) & 0xb0 ) == 0xa0)   /* conf */
                           type = Deallocate_confirm;
                if ( (*(prh+1) & 0xb0 ) == 0xb0)   /* flush */
                           type = Deallocate_flush;
                bu_seg( 0, type,NULL,whscb);
            }
		  goto ALLOK;
                }
       if ( (*prh & 0x08) == 0x08 )   /* FMH */
            { k= *pru;      /* FMH length */
             type= Fmh;
             bu_seg(k,type,pru,whscb);
             if (i > k)      /* FMH + data */
                    { memcpy (pru,pru+k,i-k);
                      wseg -> len -= k;
                    }
             i -= k;
            }

       if ( (*(prh+2) & 0x21 )  == 0 )
            {   /* no change dir */
                 if ( (((*prh) & 0x01 ) == 0x01) && (((*(prh+1)) & 0xa0) == 0xa0))
                          { type = Confirm;
                            bu_seg(0, type, NULL,whscb);
                          }
            }
       if ( i != 0 )
            {
             type= Send_data;
             bu_seg( i, type,pru,whscb);
           }
       if ( ((*(prh+2)) & 0x20) == 0x20 ) /* prep to rec */
            {
                if ( (*(prh+1) & 0xb0 ) == 0x90)   /* flush */
                           type = PREP_TO_RCV_FLUSH;
                if ( (*(prh+1) & 0xb0 ) == 0xa0)   /* short */
                           type = PREP_TO_RCV_CONFIRM_SH;
                if ( (*(prh+1) & 0xb0 ) == 0xb0)   /* long */
                           type = PREP_TO_RCV_CONFIRM_LG;
                bu_seg( 0, type,NULL,whscb);
            }
       if ( ((*(prh+2)) & 0x01 ) == 0x01)   /* deallocate */
            {
                if ( (*(prh+1) & 0xb0 ) == 0xa0)   /* conf */
                           type = Deallocate_confirm;
                if ( (*(prh+1) & 0xb0 ) == 0xb0)   /* flush */
                           type = Deallocate_flush;
                bu_seg( 0, type,NULL,whscb);
            }
	    ALLOK:
	    wseg->link = NULL;
	    wrqbs->link = NULL;
	    prelseg(wseg);
             return 0;
    } /******************************************************************/
    bu_seg (k, t , ptr,whscb)
            short k;
            unsigned char t;
            char *ptr;
            struct hscb *whscb;
                {
                    struct  rqb *wpost;
		    struct nau *wnau;
		    struct segprf *wseg;
		    struct rh *wrh;
		    union ru *wru;
                       wnau=whscb->naup;

                       if ( t == Fmh)
                           wpost=apost(1,k+3,0);       /* 0279 */
                       else
                           wpost=apost(1,k+3,4);       /* 0279 */
                       if (wpost==NULL)
                            {
                                wpost = apost(0,0,7);
                                memcpy (&(wpost->th.ra.wa.area[0]),&(whscb->hslunam),8);
            Call_APPC(7,wpost);       /* 1070 */
                                 prelrq(wpost);
                                 return 0;
                             }
                       memcpy (&(wpost->th.ra.wa.area[0]),&(whscb->hslunam),8);
                       if (k != 0)
                           {
			     wru=(char*)wpost+RESRU;
			     memcpy(wru,ptr,k);
                           }
		       wrh=(char*)wpost+RESRH;
		       wrh->rh[0]= t ;
        if (t == Fmh)
              Call_APPC(0,wpost);       /* 1070 */
        else
               Call_APPC(4,wpost);     /* 1070 *//* @2003 */
		 wseg=(struct segprf *)((char*)wpost - 12);
	         wseg->link=NULL;   /*5002*/
		 wpost->link=NULL;  /*5002*/
             prelseg(wseg);

        return 0;
     }/************** end of bu_seg *******************/
     unbnd(wrqbu)
     struct rqb *wrqbu;
    {
	struct th *wth;
        struct rh *wrh;
        short netaddr;
        struct rqb *wpost;
        struct nau *wnau;
        struct hscb *whscb;
        struct segprf *wseg;
        wrh=(char*)wrqbu+RESRH;
        wrh->rh[0] |= RSP;
        wrh->rh[1]=0;
        wth=&(wrqbu->th.th);
        memcpy (&netaddr,&(wth->dest.lan.daf),2);
        memcpy (&(wth->dest.lan.daf),&(wth->dest.lan.oaf),2);
        memcpy (&(wth->dest.lan.oaf),&netaddr,2);
        wth->t13.rout.tnpath |= TPATH;
    whscb=findhscb(wrqbu->th.ra.wa.hh.hscb);
	wnau=whscb->naup;                        /* @2002 */
        wseg=(struct segprf *)((char*)wrqbu-12);
        wrqbu->th.ra.stcb=DFC_CODE;
        wrqbu->th.ra.code=0x02;
        wrqbu->th.ra.code|=FROM;
        pattach(1,wrqbu,3);
        wpost=apost(0,0,2);           /* 0279 */
        if (wpost==NULL)
		return 0;
           memcpy (&(wpost->th.ra.wa.area[0]),&(whscb->hslunam),8);
          Call_APPC(2,wpost);        /* @2003 */
          delhscb(whscb);
           return 0;
      } /************** end of unbind ***************************/
      /***************** RSP(UNBIND) ****************************/
     int rspunbnd(wrqbru)
     struct rqb *wrqbru;
     {
        struct segprf *wseg;
	struct hscb *whscb;

       whscb=findhscb(wrqbru->th.ra.wa.hh.hscb);
	   wseg=(struct segprf *)((char*)wrqbru-12);
	      wseg->link=NULL;   /*5002*/
	      wrqbru->link=NULL;  /*5002*/
       prelseg(wseg);
       delhscb(whscb);
       return 0;
    }/***************** end of rsp(unbind) ************************/
    /*************** request RQB or SEG for post *******************/
    struct rqb *apost( i,k,n)           /* 0279 */
     short i;   /*0-RQB,1-SEG*/
     short k;   /*length RU for SEG*/
     unsigned char n;   /*request code*/
     {
        struct rqb *wrqb;
        struct segprf *wseg;
        if (i==0) /* RQB */
                {wrqb=preqrq (1);
                 if (wrqb==NULL)
			{
                         return (NULL);
                        }
                 wrqb->th.ra.code=0;
                 wrqb->th.ra.code|=RTYPE;
               }
            else /* SEG */
                {
                 wseg=preqseg(k);
                 if (wseg == NULL)
			{
                         return (NULL);
                        }
                 wseg->flag=0;
                 wseg->link=NULL;
                 wrqb=(struct rqb*)((char*)wseg+12);
                 wrqb->th.ra.code=0;
                 wseg->len=k;
               }
        wrqb->link=NULL;
        wrqb->th.ra.code|=2;
        wrqb->th.ra.code|=FROM;
        wrqb->th.ra.rparm.parm.parm2=0xff;
        wrqb->th.ra.rparm.parm.parm1=n;
        return (wrqb);
   }/******* end of post ************************/
   /******** find RQB in queue *******************/
   struct rqb *findrqb (pq,syscr)
   char *(*pq);
   short syscr;
  {
        short usrcr;
        struct rqb *prqb,*mrqb;
            prqb=*pq;



            if (prqb==NULL)
                    return (NULL);
            memcpy (&usrcr,&(prqb->th.ra.wa.area[0]),2);
            if (usrcr==syscr)
                    {*pq=prqb->link;
                      return (prqb);
                    }
            mrqb=prqb;
            while (prqb->link!=NULL)
                    {prqb=prqb->link;
                     memcpy (&usrcr,&(prqb->th.ra.wa.area[0]),2);
                     if (usrcr==syscr)
                            {mrqb->link=prqb->link;
                             return (prqb);
                            }
                     mrqb=prqb;
                    }
            return (NULL);
     }/******* end of findrqb *****************/
#if OS_TYPE == 0                 /* @2003 */
    void Call_APPC(RecForm,p)
	unsigned char RecForm;
        void far *p;
         {
            union REGS inregs,outregs;
            struct SREGS segregs;
                inregs.x.ax=RecForm*256+255;
                segregs.ds=FP_SEG(p);
                inregs.x.dx=FP_OFF(p);
                int86x( APPC,&inregs,&outregs,&segregs);
         }
#endif                     /* @2003 */
     /****************THE END*************************************/
