 /********************************************************
 *                                                       *
 *                 POSTOPEN                              *
 *                                                       *
 *  Function : Search for the RCB in the "wait" queue and*
 *             process it then.                          *
 *                                                       *
 *  Input  : the RQB which has code 0x05ff and the user  *
 *           correlator.                                 *
 *  Output : the RCB has been deleted from the "wait"    *
 *           queue and response to TP with "return" code *
 *           has been sent.                              *
 *                                                       *
 *                                                       *
 * CopyRight 1995. Nicholas Poljakov all rights reserved.*
 *                                                       *
 ********************************************************/
#include <include.h>
#include <rcb.h>
#include <repass.h>
#include <common.h>
#include <psp.h>
#include <rpl.h>
#include <nib.h>
#include <lucb.h>
#include <scb.h>
#include <string.h>
#include <state1.h>
#include <malloc.h>
#include <drcb.h>
#include <prefix.h>  /* 27.11.92 */

struct psp psp_ini;
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 recwait(void *);
int rcvru(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 *);

extern struct lucb lu6;

struct repass *postopen(p_rqb)
struct rqb *p_rqb;
{
    struct rcb *p_rcb;
    struct rcb *temp_rcb;
    struct repass *p_rep;
    struct com *p_com;
    struct scb *p_scb;
    struct scb *temp_scb;
    struct rpl *p_rpl;
    struct nib *p_nib;
    int i;
    struct drcb d_rcb;
    struct scb *t_scb;    /* 27.11.92 */
    struct scb *t1_scb;   /* 27.11.92 */
    struct prefix *prf;   /* 27.11.92 */
    unsigned long s_crl;
    char *p;
    unsigned char p1;

#if OS_TYPE == 1
/*********  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, "postopn");
pnum = 1;
drec = p_rqb;
lenr = 16;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif

    p = (char *)&s_crl;
    for (i = 0; i < 4; i++) {
        p[i] = p_rqb -> th.ra.wa.hh.rswa[i];
    }

    if ((temp_rcb = psp_ini.wait_chain) == NULL) {
        return (NULL);
    }

    while (temp_rcb != NULL) {
        if (temp_rcb -> sess_corl == s_crl) {
            goto pRCB;
        }
        temp_rcb = temp_rcb -> next;
    }
    return (NULL); /* RCB not found ! */

pRCB:
    /* RCB found */
    p_rcb = temp_rcb;
#if OS_TYPE == 1     /* Unix V */
    del_wait(p_rcb); /* Delete RCB from the "wait" qeue */
#endif
#if OS_TYPE == 0     /* MS-DOS */
    post_rcb(p_rcb); /* post rcb if it was found in the wait queue */
#endif
    p_rcb -> sess_corl = p_rqb -> th.ra.wa.hh.hscb; /* Save CID */
    p_rcb -> conv_state = SEND;  /* Initial state for primary LU */
    p_scb = p_rcb -> p_scb;
    p_rpl = p_scb -> p_rpl;
    p_rpl -> arg = p_rqb -> th.ra.wa.hh.hscb; /* Save CID in RPL*/
    p_rep = p_rcb -> verb_ptr;
    p_com = p_rcb -> verb_ptr;
    p_rep -> complete = 0; /* no retry */

    /* Test return code for OPNDST request */

    p1 = p_rqb -> th.ra.code & 0x3c; /* select return code from RQB*/
    if (p1 != OK) {
        p1 = ALLOC_FAIL_NO_RETRY;
        fsm_error(p1, p_rcb);
        p_com -> prim_rc = ALLOCATION_FAILURE_NO_RETRY;
        prf = p_rcb -> first_out;
	buffmng('D',prf,&((*p_rcb).first_out),p_rcb,0,0,0); /* FMH */
	d_rcb.p_rcb = p_rcb;
	d_rcb.p_tcb = p_rcb -> p_tcb;
        psrm(DEALLOCATE_RCB, &d_rcb, 0);

        /*
         * Free the SCB and the related blocks (RPL, NIB)
         */
        if ((temp_scb = p_scb -> prev) == NULL) {
                /*
                 * first SCB in chain.
                 */
                lu6.scb_list = p_scb -> next;
        }
        else
                temp_scb -> next = p_scb -> next;

        p_nib = p_rpl -> p_nib;
        if (p_nib != NULL) {
           free( p_nib );
        }
        free( p_rpl );
        free( p_scb );
        p_rcb -> p_scb = NULL;
        lu6.cur_sess--;

        return (p_com);
    }
    if (p_rcb -> first_out == NULL) {
        return (NULL);
    }
    /*
    if ((i = sendhs(p_rcb)) == OK) {
        p_com -> prim_rc = OK;
    }
    else
            p_com -> prim_rc = ALLOCATION_FAILURE_RETRY;
    */
    p_com -> prim_rc = OK;

    return (p_com);
}
