
  /************************************************************************
                         APPL
  **************************************************************************/

  #include <stdio.h>
  #include <memory.h>
  #include <string.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 );
extern struct rqb *preqrq(int );
extern void pattach(int ,char far *,int );
extern void prelseg(struct segprf *);
extern void prelrq(struct rqb *);
extern void delhscb(struct hscb *);


  extern struct rqb *appl1(struct rqb *);
  struct rqb *apost(short,short,unsigned char);

  void Call_APPC(unsigned char,void far *);

  struct rqb *findrqb(char *(*pq),short syscr);
  int bu_seg(short, unsigned char ,char *,struct hscb *);

extern struct hscb *crhscb( char *, char *);
extern struct hscb *findhscb( unsigned long );
extern struct hscb *fndhsad(char *);
     int rqbind(struct rqb *);
     int unbnd(struct rqb *);
     int rqsend(struct rqb *);
     int rspbind(struct rqb *);
     int rspunbnd(struct rqb *);



  struct rqb *appl(struct rqb *wrqb)
  {
     int n,rtncd;
     struct rh *wrh;
     union ru *wru;

     if (!(wrqb->th.ra.code & FROM))
            {
                     return (appl1(wrqb));
            }
     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(struct rqb *wrqbb)
     {
     struct segprf *wseg;
     struct rqb *wpost;
     union ru *wru;
     struct bind *wbind;
     struct hscb *whscb;
     struct rh *wrh;
     struct th *wth;

     wbind=(char*)wrqbb+RESRU;
     wseg = (struct segprf *)((char *)wrqbb - 12);
     wseg -> len = 4;
     wth = &(wrqbb -> th.th);
     wth -> t912.old.dcf = 4;
     whscb=crhscb(wbind->slu,wbind->plu);
     wrh=(char*)wrqbb+RESRH;
     wrh->rh[0] |= RSP;
     wrh->rh[1]=0;
     if ( whscb == NULL){
        wrh -> rh[1] |= ERTI;
        wru = (char*)wrqbb + RESRU;
        wru -> cru[2] = 0x31;
     }
     wrqbb->link=NULL;                     /* 0172 */
     wrqbb->th.ra.stcb=FISC_CODE;
     wrqbb->th.ra.code=0x02;
     wrqbb->th.ra.code |= FROM;        /* 0172 */
     memcpy ( wseg -> net_ad, whscb -> part_net_ad,6);
     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(struct rqb *wrqbrb)
     {
	struct rqb *wpost;
        struct rh *wrh;
        union ru *wru,*wrup;
        struct hscb *whscb;
        struct bind *wbind;
	struct rqb *wrqbq;
	struct th *wth;
        struct nau *wnau;
        struct segprf *wseg;

          wseg=(struct segprf *)((char*)wrqbrb-12);
          wrh=(char*)wrqbrb+RESRH;
	  wru=(char*)wrqbrb+RESRU;
	  wth=&(wrqbrb->th.th);
          if((whscb=fndhsad(wseg->net_ad)) == NULL)
		return (-1);
	  wnau = whscb -> naup;
          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(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=fndhsad(wseg->net_ad);
    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,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 (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(struct rqb *wrqbu)
    {
        struct rh *wrh;
        struct rqb *wpost;
        struct nau *wnau;
        struct hscb *whscb;
        struct segprf *wseg;
        struct th *wth;

        wrh=(char*)wrqbu+RESRH;
        wrh->rh[0] |= RSP;
        wrh->rh[1]=0;
        wseg = (struct segprf *)((char*)wrqbu-12);
        wseg -> len = 4;
        wth = &(wrqbu -> th.th);
        wth -> t912.old.dcf = 4;
        whscb=fndhsad( wseg->net_ad );
        wnau=whscb->naup;                        /* @2002 */
        wrqbu->th.ra.stcb=DFC_CODE;
        wrqbu->th.ra.code=0x02;
        wrqbu->th.ra.code|=FROM;
        memcpy(wseg -> net_ad,whscb -> part_net_ad,6);
        pattach(1,wrqbu,4);
        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(struct rqb *wrqbru)
     {
        struct segprf *wseg;
	struct hscb *whscb;

	   wseg=(struct segprf *)((char*)wrqbru-12);
       whscb=fndhsad(wseg->net_ad);
	      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(short i,short k,unsigned char n)		 /* 0279 */
     {
        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->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(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(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*************************************/
