 /*

             RECEIVE RU from APPL
                   r c v r u

  This subroutine receives RUs from APPL module as part of the input segment
  and then places them into the input queue for the  defined RCB.

  Input  : pointer to the RCB, pointer to the segment.
  Output : fill input queue for the supplied RCB.


  CopyRight 1995. Nicholas Poljakov all rights reserved.

*/

#include <stdio.h>
#include <include.h>
#include <rcb.h>
#include <prefix.h>
#include <string.h>
#include <malloc.h>
#include <state1.h>

#define RH_SIZE 3
#define RQB_RH 19
#define PR_SIZE 31

char *buff;
int sk_r_wt(void *);
int SendBlock(void *, void *);
int setrc(void *, void *);
int sendhsf(void *);
int sendhs(void *);
int sendbm(void *, void *);
int sendat(void *);
int rtsend(void *);
unsigned long rmfmh5(void *, void *);
int rcvhs(void *, void *, void *, void *);
int ralloc(void *, void *);
int psrm(int, void *, void *);
int ps_conv(int, void *);
int proterr(void *, unsigned long);
int preptrcv(void *, void *);
int post_rcb(void *);
struct repass *postopen(void *);
int phsrec(void *);
int pfmh5(void *);
int opndst(void *);
int obtsess(void *, unsigned char);
int Lrf_handler(void *);
int get_sess(void *, void *);
int get_attr(void *);
int fsm_error(unsigned char, void *);
int fsm_conv(unsigned char, unsigned char, void *);
int flush (void *);
int dcp(void *);
int dealloc(void *);
int crtp(void *);
int conv(void *);
int chkparm(void *, void *);
int check_end(unsigned int, void *);
struct rqb *call_appl(void *);
int buffmng(unsigned char, void *, void *, void *, unsigned, unsigned char, unsigned);
unsigned long attltck(void *);
unsigned long attacheck(void *);
char *cgetmem(int, int);
int sendhsf(void *);
int opndst(void *);
int alloc_rcb(void *, void *);
int allocate(void *);
int clsdst(void *);
int bldfmh7(struct rcb *, unsigned long);

int main_fd;

rcvru(p_rcb, s_ptr)
struct rcb *p_rcb;
struct segprf *s_ptr;
{
    struct rqb *p_rqb;
    struct segprf *t_seg;
    int i;
    int ti;
    int cnt;
    char *p;
    char *p1;
    unsigned char dsc;
    unsigned int type;
    unsigned long sense;
    unsigned char tp;
    char *tp1;
    union prll {
                  struct chs {
                                unsigned char s1;
                                unsigned char s2;
			      } chs;
                  unsigned int len;
                } *pr_ll;

#if OS_TYPE == 1 /* Unix V */
/*********  Trace facility **********/
unsigned int rtype;   /* type of record */
unsigned int pnum;    /* point number */
char pname[8];        /* name of module */
char *drec;       /* record for dump */
int  lenr;            /* record length */

rtype = INPROC;
strcpy(pname, "rcvru");
pnum = 1;
drec = p_rcb;
lenr = sizeof(struct rcb);
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif

    cnt = 0; /* first segment */
    t_seg = s_ptr;
    p_rqb = (char *)t_seg + PR_SIZE - RQB_RH; /* pointer to RQB */

    /* Read all elements of the seg. chain and
     * place it into an input queue to the RCB
     */
    do {
        if (cnt != 0) {
#if OS_TYPE == 1 /* Unix V */
            if ((i = read(main_fd, buff, MAX_SEG)) == -1) {
                return (0); /* error in reading */
            }
            t_seg = buff;
#endif
#if OS_TYPE == 0 /* MS-DOS */
            t_seg = t_seg -> link;
            i = t_seg -> len - 3; /* without RH */
#endif
#if OS_TYPE == 1 /* Unix V */
/******** Trace  ******************/
rtype = GREC;
strcpy(pname, "rcvru");
pnum = 2;
drec = buff;
lenr = i;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif

        }
        else { /* cnt == 0*/
            /* First segment */
            i = t_seg -> len - 3;  /* RH length */
            p1 = (char *)p_rqb + 16; /*sizeof(struct rqb)*/
            type = *p1;  /* rh[0] - DFC command*/
            cnt++;
	}

	p1 = (char *)t_seg;
	p = p1 + PR_SIZE; /* pointer to RU in buffer */
        p1 = &((*p_rcb).first_in);
        if (t_seg -> link == NULL) {
            dsc = 0;
        }
        else
                dsc = 1;
        if (i == 0) {
               buffmng('A', NULL, p1, p_rcb, i, dsc, type);
        }
        else
             {
             /* Set each logical record as a separate member */
               while (i > 0) {
		    pr_ll = (union prll *)p;
                    tp = pr_ll -> chs.s1;
                    pr_ll -> chs.s1 = pr_ll -> chs.s2;
                    pr_ll -> chs.s2 = tp; /* invert to compatibility with
                                           * IBM mainframe. */
                    ti = pr_ll -> len;    /* with prefix itself */
                    if (ti > i) {
                       ti = i;
                       type = Data_INCOMPLETE;
                    }
                    else
                       type = Data_COMPLETE;
                    if ((tp1 = malloc(ti)) == NULL) {
                       sense = 0x1008600b; /* RESOURCE_FAILURE_NO_RETRY */
                       bldfmh7(p_rcb, sense);
                       return (-1);
                    }
                    memcpy(tp1, p, ti);
                    buffmng('A', tp1, p1, p_rcb, ti, dsc, type);
                    i -= ti;
                    p += ti;
               }
             }

    } while (t_seg -> link != NULL);
    return (0);
}
