Ejemplo n.º 1
0
GCD_CIB *
gcd_new_cib( u_i2 count )
{
    GCD_CIB	*cib = NULL;
    u_i2	len = sizeof( GCD_CIB ) + (sizeof(CONN_PARM) * (count - 1));

    if ( count < ARR_SIZE( GCD_global.cib_free ) )
	if (! (cib = (GCD_CIB *)QUremove(GCD_global.cib_free[count].q_next)))
	    if ( (cib = (GCD_CIB *)MEreqmem( 0, len, FALSE, NULL )) )
		cib->id = GCD_global.cib_total++;

    if ( ! cib )
	gcu_erlog(0, GCD_global.language, E_GC4808_NO_MEMORY, NULL, 0, NULL);
    else  
    {
	u_i4	id = cib->id;
	char	buff[16];

	MEfill( len, 0, (PTR)cib );
	cib->id = id;
	cib->parm_max = count;
	QUinit( &cib->caps );

	MOulongout( 0, (u_i8)cib->id, sizeof( buff ), buff );
	MOattach( MO_INSTANCE_VAR, GCD_MIB_DBMS, buff, (PTR)cib );

	GCD_global.cib_active++;

	if ( GCD_global.gcd_trace_level >= 6 )
	    TRdisplay( "%4d    GCD new CIB (%d)\n", -1, cib->id );
    }

    return( cib );
}
Ejemplo n.º 2
0
STATUS
jdbc_gca_init( char *myaddr )
{
    GCA_PARMLIST	parms;
    STATUS		status;

    MEfill( sizeof(parms), 0, (PTR) &parms);
    parms.gca_in_parms.gca_local_protocol = JDBC_GCA_PROTO_LVL;
    parms.gca_in_parms.gca_normal_completion_exit = gca_sm;
    parms.gca_in_parms.gca_expedited_completion_exit = gca_sm;
    parms.gca_in_parms.gca_modifiers |= GCA_API_VERSION_SPECD;
    parms.gca_in_parms.gca_api_version = GCA_API_LEVEL_5;

    IIGCa_cb_call( &gca_cb, GCA_INITIATE, 
		   &parms, GCA_SYNC_FLAG, NULL, -1, &status );
			
    if ( status != OK || (status = parms.gca_in_parms.gca_status) != OK )
    {
	gcu_erlog( 0, JDBC_global.language, status, 
		   &parms.gca_in_parms.gca_os_status, 0, NULL );
	return( status );
    }

    MEfill( sizeof(parms), 0, (PTR) &parms);
    parms.gca_rg_parms.gca_srvr_class = JDBC_SRV_CLASS;
    parms.gca_rg_parms.gca_l_so_vector = 0;
    parms.gca_rg_parms.gca_served_object_vector = NULL;
    parms.gca_rg_parms.gca_installn_id = "";
	    
    IIGCa_cb_call( &gca_cb, GCA_REGISTER, 
		   &parms, GCA_SYNC_FLAG, NULL, -1, &status );

    if ( status != OK || (status = parms.gca_rg_parms.gca_status) != OK )
    {
	gcu_erlog( 0, JDBC_global.language, 
		   status, &parms.gca_rg_parms.gca_os_status, 0, NULL );
	return( status );
    }

    gca_sm( 0 );
    STcopy( parms.gca_rg_parms.gca_listen_id, myaddr );

    return( OK );
}
Ejemplo n.º 3
0
bool
gcd_alloc_qdesc( QDATA *qdata, u_i2 count, PTR desc )
{
    qdata->max_rows = 0;
    qdata->max_cols = count;
    qdata->col_cnt = 0;
    qdata->cur_col = 0;
    qdata->more_segments = FALSE;
    qdata->desc = NULL;
    if ( ! qdata->max_cols )  return( FALSE );

    if ( desc )
	qdata->desc = desc;
    else
    {
	/*
	** Expand descriptor array if needed.
	*/
	if ( qdata->max_cols > qdata->desc_max )
	{
	    if ( qdata->param_desc )
	    {
		IIAPI_DESCRIPTOR *desc = (IIAPI_DESCRIPTOR *)qdata->param_desc;
		u_i2		 i;

		for( i = 0; i < qdata->desc_max; i++ )
		    if ( desc[i].ds_columnName )  
			MEfree( desc[i].ds_columnName );

		MEfree( qdata->param_desc );
	    }


	    if ( ! (qdata->param_desc = 
	    		MEreqmem( 0, sizeof(IIAPI_DESCRIPTOR) * 
				     qdata->max_cols, TRUE, NULL )) )
	    {
		gcu_erlog( 0, GCD_global.language, 
			   E_GC4808_NO_MEMORY, NULL, 0, NULL);
		return( FALSE );
	    }

	    qdata->desc_max = qdata->max_cols;
	}

	qdata->desc = qdata->param_desc;
    }

    return( TRUE );
}
Ejemplo n.º 4
0
GCD_PCB *
gcd_new_pcb( GCD_CCB *ccb )
{
    GCD_PCB *pcb;

    if ( ! (pcb = (GCD_PCB *)MEreqmem( 0, sizeof( GCD_PCB ), TRUE, NULL )) )
	gcu_erlog(0, GCD_global.language, E_GC4808_NO_MEMORY, NULL, 0, NULL);
    else
    {
	if ( GCD_global.gcd_trace_level >= 6 )
	    TRdisplay( "%4d    GCD new PCB (%p)\n", ccb->id, pcb );

	pcb->ccb = ccb;
    }

    return( pcb );
}
Ejemplo n.º 5
0
GCD_CCB *
gcd_new_ccb( void )
{
    GCD_CCB	*ccb;

    if ( ! (ccb = (GCD_CCB *)QUremove( GCD_global.ccb_free.q_next )) )
	if ( (ccb = (GCD_CCB *)MEreqmem( 0, sizeof(GCD_CCB), FALSE, NULL )) )
	    ccb->id = GCD_global.ccb_total++;

    if ( ! ccb )
	gcu_erlog(0, GCD_global.language, E_GC4808_NO_MEMORY, NULL, 0, NULL);
    else
    {
	u_i4	id = ccb->id;

	MEfill( sizeof( GCD_CCB ), 0, (PTR)ccb );
	ccb->id = id;
	ccb->use_cnt = 1;
	ccb->max_buff_len = 1 << DAM_TL_PKT_MIN;
	ccb->tl.proto_lvl = DAM_TL_PROTO_1;
	ccb->xact.auto_mode = GCD_XACM_DBMS;
	ccb->api.env = NULL;
	QUinit( &ccb->q );
	QUinit( &ccb->rcb_q );
	QUinit( &ccb->gcc.send_q );
	QUinit( &ccb->msg.msg_q );
	QUinit( &ccb->msg.info_q );
	QUinit( &ccb->stmt.stmt_q );
	QUinit( &ccb->rqst.rqst_q );

	GCD_global.ccb_active++;
	QUinsert( &ccb->q, &GCD_global.ccb_q );

	if ( GCD_global.gcd_trace_level >= 5 )
	    TRdisplay( "%4d    GCD new CCB (%d)\n", ccb->id, ccb->id );
    }

    return( ccb );
}
Ejemplo n.º 6
0
GCD_RCB *
gcd_new_rcb( GCD_CCB *ccb, i2 len )
{
    GCD_RCB *rcb;

    /*
    ** Adjust length to reserve header space.
    **
    ** The majority of RCB allocations are for default
    ** buffer sizes or no buffers.  Re-use free RCB with
    ** same buffer size if available.
    */
    if ( len == 0 )
	rcb = (GCD_RCB *)QUremove( GCD_global.rcb_q.q_next );
    else  if ( len < 0 )
    {
	/*
	** Use the negotiated TL protocol buffer size from 
	** the CCB (TL header length already included) and
	** provide space for the NL header.
	*/
	len = ccb->max_buff_len + (u_i2)GCD_global.nl_hdr_sz;
	rcb = (GCD_RCB *)QUremove( ccb->rcb_q.q_next );
    }
    else
    {
	/*
	** NL protocol restricts the size of buffers which
	** may be sent.  Provide space for TL header by
	** increasing requested buffer length.  Space is
	** also provided for the NL header.
	*/
	len = min( len + (u_i2)GCD_global.tl_hdr_sz, ccb->max_buff_len ) +
	      (u_i2)GCD_global.nl_hdr_sz;
	rcb = NULL;	/* RCB must be allocated */
    }

    if ( rcb )
	MEfill( sizeof( GCD_RCB ), 0, rcb );
    else
    {
	rcb = (GCD_RCB *)MEreqmem( 0, sizeof( GCD_RCB ) + len, TRUE, NULL );

    	if ( ! rcb )
	{
	    gcu_erlog( 0, GCD_global.language, 
	    	       E_GC4808_NO_MEMORY, NULL, 0, NULL );
	    return( NULL );
	}

	if ( GCD_global.gcd_trace_level >= 6 )
	    TRdisplay( "%4d    GCD new RCB[%d] (%p)\n", ccb->id, len, rcb );
    }

    rcb->ccb = ccb;

    if ( len )
    {
	rcb->buffer = (u_i1 *)rcb + sizeof( GCD_RCB );
	rcb->buf_max = (u_i2)len;
	gcd_init_rcb( rcb );
    }

    return( rcb );
}
Ejemplo n.º 7
0
static bool
alloc_qdata( QDATA *qdata, u_i2 max_rows, bool alloc_buffers )
{
    IIAPI_DESCRIPTOR	*desc;
    IIAPI_DATAVALUE	*data;
    u_i2		row, col, seg_len;
    u_i4                dv;
    u_i4		blen, length;
    u_i4		tot_cols = max_rows * qdata->max_cols;

    qdata->max_rows = max_rows;
    qdata->col_cnt = 0;
    qdata->cur_col = 0;
    qdata->more_segments = FALSE;
    if ( ! qdata->max_rows  ||  ! qdata->max_cols )  return( FALSE );
    
    /*
    ** Expand data value array if needed.
    */
    if ( tot_cols > qdata->data_max )
    {
	if ( qdata->data )  MEfree( qdata->data );
	if ( ! (qdata->data = MEreqmem( 0, sizeof( IIAPI_DATAVALUE ) * 
					   tot_cols, TRUE, NULL )) )
	{
	    gcu_erlog( 0, GCD_global.language, 
		       E_GC4808_NO_MEMORY, NULL, 0, NULL);
	    return( FALSE );
	}

	qdata->data_max = tot_cols;
    }

    if ( ! alloc_buffers )  return( TRUE );

    desc = (IIAPI_DESCRIPTOR *)qdata->desc;
    data = (IIAPI_DATAVALUE *)qdata->data;

    for( col = length = seg_len = 0; col < qdata->max_cols; col++ )
	switch( desc[ col ].ds_dataType)
	{
	     case IIAPI_LVCH_TYPE:
	     case IIAPI_LNVCH_TYPE: 
	     case IIAPI_LBYTE_TYPE:
	     case IIAPI_GEOM_TYPE:
	     case IIAPI_POINT_TYPE:
	     case IIAPI_MPOINT_TYPE:
	     case IIAPI_LINE_TYPE:
	     case IIAPI_MLINE_TYPE:
	     case IIAPI_POLY_TYPE:
	     case IIAPI_MPOLY_TYPE:
	     case IIAPI_GEOMC_TYPE:
	     {
		seg_len = max( seg_len, desc[ col ].ds_length );
		break;
	     }
	     default:
	     {
		length += desc[ col ].ds_length;
		break;
	     }
	}

    if ( (blen = (length * qdata->max_rows)) > qdata->db_max )
    {
	if ( qdata->data_buff )  MEfree( qdata->data_buff );
	if ( ! (qdata->data_buff = MEreqmem( 0, blen, FALSE, NULL )) )
	{
	    gcu_erlog( 0, GCD_global.language, 
		       E_GC4808_NO_MEMORY, NULL, 0, NULL);
	    return( FALSE );
	}

	qdata->db_max = blen;
    }

    if ( seg_len > qdata->bb_max )
    {
	if ( qdata->blob_buff )  MEfree( qdata->blob_buff );
	if ( ! (qdata->blob_buff = MEreqmem( 0, seg_len, FALSE, NULL )) )
	{
	    gcu_erlog( 0, GCD_global.language, 
		       E_GC4808_NO_MEMORY, NULL, 0, NULL);
	    return( FALSE );
	}

	qdata->bb_max = seg_len;
    }

    for( row = dv = length = 0; row < qdata->max_rows; row++ )
	for( col = 0; col < qdata->max_cols; col++, dv++ )
	    switch( desc[ col ].ds_dataType)
	    {
		 case IIAPI_LVCH_TYPE:
		 case IIAPI_LNVCH_TYPE:
		 case IIAPI_LBYTE_TYPE:
		 case IIAPI_GEOM_TYPE:
		 case IIAPI_POINT_TYPE:
		 case IIAPI_MPOINT_TYPE:
		 case IIAPI_LINE_TYPE:
		 case IIAPI_MLINE_TYPE:
		 case IIAPI_POLY_TYPE:
		 case IIAPI_MPOLY_TYPE:
		 case IIAPI_GEOMC_TYPE:
		 {
		    data[ dv ].dv_value = (char *)qdata->blob_buff;
		    break;
		 }
		 default:
		 {
		    data[ dv ].dv_value = (char *)qdata->data_buff + length;
		    length += desc[ col ].ds_length;
		 }
	    }

    return( TRUE );
}
Ejemplo n.º 8
0
static STATUS
initialize( i4 argc, char **argv )
{
    CL_ERR_DESC	cl_err;
    char	*instance = ERx("*");
    char	*env;
    char	name[ 16 ];
    i4		i;

    GCD_global.language = 1;
    MHsrand( TMsecs() );

    for( i = 1; i < argc; i++ )
	if ( ! STbcompare( argv[i], 0, ERx("-instance"), 9, TRUE ) )
	{
	    if ( argv[i][9] == ERx('=')  &&  argv[i][10] != EOS )
		instance = &argv[i][10];
	    else  if ( argv[i][9] == EOS  &&  (i + 1) < argc )
		instance = argv[++i];
	    break;
	}

    NMgtAt( ERx("II_INSTALLATION"), &env );
    STprintf( name, ERx("II_CHARSET%s"), (env  &&  *env) ? env : "" );
    NMgtAt( name, &env );

    if ( ! env  ||  ! *env || STlength(env) > CM_MAXATTRNAME)
    {
	switch( CMgetDefCS() )
	{
#if ( !defined(UNIX) && !defined(VMS) )
	case CM_IBM :	    env = "IBMPC850";	break;
#endif
	case CM_DECMULTI :  env = "DECMULTI";	break;
	default :	    env = "ISO88591";	break;
	}
    }

    GCD_global.charset = STalloc( env );
    CVupper( GCD_global.charset );
    gcu_read_cset( gcd_cset_id );

    if ( CMset_attr( GCD_global.charset, &cl_err) != OK )
    {
	gcu_erlog( 0, GCD_global.language, 
		    E_GC0105_GCN_CHAR_INIT, NULL, 0, NULL );
	return( E_GC0105_GCN_CHAR_INIT );
    }

    PMinit();

    switch( PMload( (LOCATION *)NULL, (PM_ERR_FUNC *)NULL ) )
    {
	case OK: break;

	case PM_FILE_BAD:
	    gcu_erlog( 0, GCD_global.language, 
			E_GC003D_BAD_PMFILE, NULL, 0, NULL );
	    return( E_GC003D_BAD_PMFILE );
	    break;

	default:
	    gcu_erlog( 0, GCD_global.language, 
			E_GC003E_PMLOAD_ERR, NULL, 0, NULL );
	    return( E_GC003E_PMLOAD_ERR );
	    break;
    }

    PMsetDefault( 0, SystemCfgPrefix );
    PMsetDefault( 1, PMhost() );
    PMsetDefault( 2, ERx("gcd") );
    PMsetDefault( 3, instance );

    gcd_tl_services[0] = &gcd_dmtl_service;
    gcd_tl_services[1] = &gcd_jctl_service;
    GCD_global.tl_services = gcd_tl_services;
    GCD_global.tl_srvc_cnt = ARR_SIZE( gcd_tl_services );

    QUinit( &GCD_global.pib_q );
    QUinit( &GCD_global.rcb_q );
    QUinit( &GCD_global.ccb_q );
    QUinit( &GCD_global.ccb_free );
    for( i = 0; i < ARR_SIZE( GCD_global.cib_free ); i++ )  
	QUinit( &GCD_global.cib_free[ i ] );

    env = NULL;
    gcu_get_tracesym( NULL, ERx("!.client_max"), &env );
    if ( env  &&  *env )
    {
	i4 count;

	if ( CVal( env, &count ) == OK  &&  count > 0 )
	    GCD_global.client_max = count;
    }

    env = NULL;
    gcu_get_tracesym( NULL, ERx("!.client_timeout"), &env );
    if ( env  &&  *env )  
    {
	i4 timeout;

	if ( CVal( env, &timeout ) == OK  &&  timeout > 0 )
	    GCD_global.client_idle_limit = timeout * 60; /* Cnvt to seconds */
    }

    env = NULL;
    gcu_get_tracesym( NULL, ERx("!.connect_pool_status"), &env );
    if ( env  &&  *env )
    {
	if ( ! STbcompare( env, 0, "optional", 0, TRUE ) )
	    GCD_global.client_pooling = TRUE;

	if ( GCD_global.client_pooling  ||
	     ! STbcompare( env, 0, "on", 0, TRUE ) )
	{
	    env = NULL;
	    gcu_get_tracesym( NULL, ERx("!.connect_pool_size"), &env );
	    if ( env  &&  *env )  CVal( env, &GCD_global.pool_max );

	    env = NULL;
	    gcu_get_tracesym( NULL, ERx("!.connect_pool_expire"), &env );
	    if ( env  &&  *env )  
	    {
		i4 limit;

		if ( CVal( env, &limit ) == OK  &&  limit > 0 )
		    GCD_global.pool_idle_limit = limit * 60; /* Seconds */
	    }
	}
    }

    env = NULL;
    gcu_get_tracesym( "II_GCD_TRACE", ERx("!.gcd_trace_level"), &env );
    if ( env  &&  *env )  CVal( env, &GCD_global.gcd_trace_level );

    env = NULL;
    gcu_get_tracesym( "II_GCD_LOG", ERx("!.gcd_trace_log"), &env );
    if ( env  &&  *env ) 
	TRset_file( TR_F_OPEN, env, (i4)STlength( env ), &cl_err );

    return( OK );
}
Ejemplo n.º 9
0
int
main( int argc, char **argv )
{
    EX_CONTEXT		context;
    char		name[ GCC_L_PORT + 1 ];
    u_i2		apivers;
    PTR 		hndl;

#ifdef LNX
    PCsetpgrp();
#endif

    MEadvise( ME_INGRES_ALLOC );

    if ( EXdeclare( GCX_exit_handler, &context ) != OK )
    {
	gcu_erlog( 0, 1, E_GC480F_EXCEPTION, NULL, 0, NULL );
	PCexit( OK );
	return( 0 );
    }

    GChostname( GCD_global.host, sizeof( GCD_global.host ) );
    gcu_erinit( GCD_global.host, GCD_LOG_ID, "" );

    if ( initialize( argc, argv ) != OK )  gcd_exit();
    gcd_init_mib();
    if ( gcd_gca_init( ) != OK )  gcd_exit();
    gcu_erinit( GCD_global.host, GCD_LOG_ID, GCD_global.gcd_lcl_id );

    if ( gcd_adm_init() != OK ) gcd_exit();
    apivers = gcd_msg_version( MSG_DFLT_PROTO ); 
    if ( gcd_get_env( apivers, &hndl ) != OK ) gcd_exit();
    if ( gcd_pool_init() != OK )  gcd_exit();
    if ( gcd_gcc_init() != OK )  gcd_exit();

    /*
    ** Log Server startup.
    */
    {
	char		server_flavor[256], server_type[32];
	char		*tmpbuf = PMgetDefault(3);
	ER_ARGUMENT	erlist[2];

	SIstd_write(SI_STD_OUT, "PASS\n");

	if ( ! STbcompare( tmpbuf, 0, "*", 0, TRUE ) )
	    STcopy( "(DEFAULT)", server_flavor );
	else
	    STcopy( tmpbuf, server_flavor );

	STcopy(PMgetDefault(2), server_type);
	CVupper(server_type);

	erlist[0].er_value = server_flavor;
	erlist[0].er_size = STlength(server_flavor);
	erlist[1].er_value = server_type;
	erlist[1].er_size = STlength(server_type);

	gcu_erlog( 0, GCD_global.language, E_GC4802_LOAD_CONFIG, NULL, 2, 
		   (PTR)&erlist );
	gcu_erlog( 0, GCD_global.language, E_GC4800_STARTUP, NULL, 0, NULL );
    }

    GCexec();

    gcd_gcc_term();
    gcd_pool_term();
    gcd_rel_env(0);
    gcd_adm_term();
    gcd_gca_term();
    gcu_erlog( 0, GCD_global.language, E_GC4801_SHUTDOWN, NULL, 0, NULL );

    EXdelete();
    PCexit( OK );
    return( 0 );
}
Ejemplo n.º 10
0
static void
crsr_cols
( 
    GCD_CCB	*ccb, 
    GCD_SCB	*scb, 
    GCD_RCB	**rcb_ptr, 
    u_i2	row,
    bool	more_segments 
)
{
    IIAPI_DESCRIPTOR	*desc = (IIAPI_DESCRIPTOR *)scb->column.desc;
    IIAPI_DATAVALUE	*data = &((IIAPI_DATAVALUE *)scb->column.data)[ 
						row * scb->column.max_cols ];
    u_i2		end = scb->column.cur_col + scb->column.col_cnt;
    u_i2		col, len;

    for( col = scb->column.cur_col; col < end; col++ )
    {
	if ( desc[ col ].ds_nullable  &&  data[ col ].dv_null )
	{
	    gcd_put_i1( rcb_ptr, 0 );	/* No data - NULL value */
	    continue;
	}

	/*
	** Write the data indicator byte, for BLOBs this is
	** only done on the first segment (more_segments is
	** saved below once the segment has been processed,
	** so the saved value is FALSE on the first segment).
	*/
	if ( (desc[ col ].ds_dataType != IIAPI_LVCH_TYPE  &&
	      desc[ col ].ds_dataType != IIAPI_LNVCH_TYPE &&
	      desc[ col ].ds_dataType != IIAPI_LBYTE_TYPE)  ||
	     ! scb->column.more_segments )
	    gcd_put_i1( rcb_ptr, 1 );

	switch( desc[ col ].ds_dataType )
	{
	case IIAPI_INT_TYPE :
	    switch( desc[ col ].ds_length )
	    {
	    case 1 : gcd_put_i1p(rcb_ptr, (u_i1 *)data[col].dv_value); break;
	    case 2 : gcd_put_i2p(rcb_ptr, (u_i1 *)data[col].dv_value); break;
	    case 4 : gcd_put_i4p(rcb_ptr, (u_i1 *)data[col].dv_value); break;
	    case 8 : gcd_put_i8p(rcb_ptr, (u_i1 *)data[col].dv_value); break;
	    }
	    break;

	case IIAPI_FLT_TYPE :
	    switch( desc[ col ].ds_length )
	    {
	    case 4 : gcd_put_f4p(rcb_ptr, (u_i1 *)data[col].dv_value); break;
	    case 8 : gcd_put_f8p(rcb_ptr, (u_i1 *)data[col].dv_value); break;
	    }
	    break;

	case IIAPI_MNY_TYPE :
	    {
		IIAPI_DESCRIPTOR	idesc, ddesc;
		IIAPI_DATAVALUE		idata, ddata;
		STATUS			status;
		char			dbuff[ 130 ];	/* varchar(128) */
		char			dec[ 8 ];

		/*
		** It would be nice to convert directly to
		** varchar, but money formatting is nasty.  
		** So we first convert to decimal, then to 
		** varchar.
		*/
		idesc.ds_dataType = IIAPI_DEC_TYPE;
		idesc.ds_nullable = FALSE;
		idesc.ds_length = sizeof( dec );
		idesc.ds_precision = 15;
		idesc.ds_scale = 2;
		idata.dv_null = FALSE;
		idata.dv_length = sizeof( dec );
		idata.dv_value = (PTR)&dec;

		ddesc.ds_dataType = IIAPI_VCH_TYPE;
		ddesc.ds_nullable = FALSE;
		ddesc.ds_length = sizeof( dbuff );
		ddesc.ds_precision = 0;
		ddesc.ds_scale = 0;
		ddata.dv_null = FALSE;
		ddata.dv_length = sizeof( dbuff );
		ddata.dv_value = dbuff;

		if ( (status = gcd_api_format( ccb, &desc[ col ], &data[ col ],
						&idesc, &idata )) != OK  ||
		     (status = gcd_api_format( ccb, &idesc, &idata, 
						&ddesc, &ddata )) != OK )
		{
		    /*
		    ** Conversion error.  Send a zero-length 
		    ** string as error indication and log error.
		    */
		    gcd_put_i2( rcb_ptr, 0 );
		    gcu_erlog( 0, GCD_global.language, status, NULL, 0, NULL );
		}
		else
		{
		    MEcopy( (PTR)dbuff, 2, (PTR)&len );
		    gcd_put_i2( rcb_ptr, len );
		    gcd_put_bytes( rcb_ptr, len, (u_i1 *)&dbuff[2] );
		}
	    }
	    break;

	case IIAPI_BOOL_TYPE :
	    gcd_put_i1p( rcb_ptr, (u_i1 *)data[ col ].dv_value );
	    break;

	case IIAPI_DEC_TYPE :	/* These types are all sent in text format */
	case IIAPI_DTE_TYPE :
	case IIAPI_DATE_TYPE :
	case IIAPI_TIME_TYPE :
	case IIAPI_TMWO_TYPE :
	case IIAPI_TMTZ_TYPE :
	case IIAPI_TS_TYPE :
	case IIAPI_TSWO_TYPE :
	case IIAPI_TSTZ_TYPE :
	case IIAPI_INTYM_TYPE :
	case IIAPI_INTDS_TYPE :
	    {
		IIAPI_DESCRIPTOR	ddesc;
		IIAPI_DATAVALUE		ddata;
		STATUS			status;
		char			dbuff[ 130 ];	/* varchar(128) */

		ddesc.ds_dataType = IIAPI_VCH_TYPE;
		ddesc.ds_nullable = FALSE;
		ddesc.ds_length = sizeof( dbuff );
		ddesc.ds_precision = 0;
		ddesc.ds_scale = 0;
		ddata.dv_null = FALSE;
		ddata.dv_length = sizeof( dbuff );
		ddata.dv_value = dbuff;

		status = gcd_api_format( ccb, &desc[ col ], &data[ col ], 
					  &ddesc, &ddata );

		if ( status != OK )  
		{
		    /*
		    ** Conversion error.  Send a zero-length 
		    ** string as error indication and log error.
		    */
		    gcd_put_i2( rcb_ptr, 0 );
		    gcu_erlog( 0, GCD_global.language, status, NULL, 0, NULL );
		}
		else
		{
		    MEcopy( (PTR)dbuff, 2, (PTR)&len );
		    gcd_put_i2( rcb_ptr, len );
		    gcd_put_bytes( rcb_ptr, len, (u_i1 *)&dbuff[2] );
		}
	    }
	    break;

	case IIAPI_CHA_TYPE :
	case IIAPI_CHR_TYPE :
	case IIAPI_BYTE_TYPE :
	    gcd_put_bytes( rcb_ptr, desc[ col ].ds_length, 
			    (u_i1 *)data[ col ].dv_value );
	    break;

	case IIAPI_NCHA_TYPE :
	    gcd_put_ucs2( rcb_ptr, desc[ col ].ds_length / sizeof( UCS2 ),
			   (u_i1 *)data[ col ].dv_value );
	    break;

	case IIAPI_TXT_TYPE :
	case IIAPI_LTXT_TYPE :
	case IIAPI_VCH_TYPE :	
	case IIAPI_VBYTE_TYPE :
	    MEcopy( data[ col ].dv_value, 2, (PTR)&len );
	    gcd_put_i2( rcb_ptr, len );
	    gcd_put_bytes( rcb_ptr, len, (u_i1 *)data[ col ].dv_value + 2 );
	    break;

	case IIAPI_NVCH_TYPE :
	    MEcopy( data[ col ].dv_value, 2, (PTR)&len );
	    gcd_put_i2( rcb_ptr, len );
	    gcd_put_ucs2( rcb_ptr, len, (u_i1 *)data[ col ].dv_value + 2 );
	    break;

	case IIAPI_LCLOC_TYPE :
	case IIAPI_LNLOC_TYPE :
	case IIAPI_LBLOC_TYPE :
	    gcd_put_i4p( rcb_ptr, (u_i1 *)data[ col ].dv_value );
	    break;

	case IIAPI_LVCH_TYPE :
	case IIAPI_LNVCH_TYPE :
	case IIAPI_LBYTE_TYPE :
	    {
		u_i1	*ptr;
		u_i2	seg_len, chrs, char_size = sizeof( char );
		bool	ucs2 = FALSE;

		if ( desc[ col ].ds_dataType == IIAPI_LNVCH_TYPE )
		{
		    ucs2 = TRUE;
		    char_size = sizeof( UCS2 );
		}

		if ( data[ col ].dv_length < 2 )
		    seg_len = 0;
		else
		{
		    MEcopy( data[ col ].dv_value, 2, (PTR)&seg_len );
		    ptr = (u_i1 *)data[ col ].dv_value + 2;
		    seg_len *= char_size;  /* convert array len to byte len */
		}

		/*
		** Output data as long as there is sufficient
		** data to fill the current message.  Any data
		** remaining is saved until additional data is
		** received or the end of the BLOB is reached.
		**
		** We actually make sure that room for the
		** segment (length indicator and data) and an
		** end-of-segments indicator is left in the
		** message buffer.  This way the end-of-BLOB
		** processing below does not need to worry
		** about splitting the message.
		**
		** The test against the save buffer size is
		** redundent since the buffer should be at 
		** least as big as a message buffer, but we 
		** make the test just to be safe.
		*/
		while( (seg_len + scb->seg_len + 4) > RCB_AVAIL(*rcb_ptr)  ||
		       (seg_len + scb->seg_len) > scb->seg_max )
		{
		    /*
		    ** Can a valid data segment be placed in the buffer?
		    */
		    if ( RCB_AVAIL(*rcb_ptr) >= (2 + char_size)  &&  
			 (seg_len + scb->seg_len) >= char_size )
		    {
			len = min( seg_len + scb->seg_len, 
				   RCB_AVAIL( *rcb_ptr ) - 2 );
			chrs = len / char_size;
			len = chrs * char_size;

			gcd_put_i2( rcb_ptr, chrs );

			if ( GCD_global.gcd_trace_level >= 5 )
			    TRdisplay( "%4d    GCD send segment: %d (%d,%d)\n",
					ccb->id, len, scb->seg_len, seg_len );

			/*
			** First, send saved data.
			*/
			if ( scb->seg_len >= char_size )
			{
			    len = min( scb->seg_len, RCB_AVAIL( *rcb_ptr ) );
			    chrs = len / char_size;
			    len = chrs * char_size;

			    if ( ! ucs2 )
				gcd_put_bytes( rcb_ptr, len, scb->seg_buff );
			    else
				gcd_put_ucs2( rcb_ptr, chrs, scb->seg_buff );

			    scb->seg_len -= len;
			    if ( scb->seg_len ) 
				MEcopy( (PTR)(scb->seg_buff + len), 
					scb->seg_len, (PTR)scb->seg_buff );
			}

			/*
			** Now send data from current segment.
			*/
			if ( seg_len >= char_size  &&  
			     RCB_AVAIL( *rcb_ptr ) >= char_size )
			{
			    len = min( seg_len, RCB_AVAIL( *rcb_ptr ) );
			    chrs = len / char_size;
			    len = chrs * char_size;

			    if ( ! ucs2 )
				gcd_put_bytes( rcb_ptr, len, ptr );
			    else
				gcd_put_ucs2( rcb_ptr, chrs, ptr );

			    ptr += len;
			    seg_len -= len;
			}
		    }

		    gcd_msg_end( rcb_ptr, FALSE );
		    gcd_msg_begin( ccb, rcb_ptr, MSG_DATA, 0 );
		}

		/*
		** Save any data left in the current segment.
		** The preceding loop makes sure there is room
		** in the buffer for the remainder of the
		** current segment.
		*/
		if ( seg_len )
		{
		    if ( ! scb->seg_buff )
		    {
			scb->seg_buff = (u_i1 *)MEreqmem( 0, scb->seg_max,
							  FALSE, NULL );
			if ( ! scb->seg_buff )
			{
			    if ( GCD_global.gcd_trace_level >= 1 )
				TRdisplay( "%4d    GCD alloc fail seg: %d\n",
					   ccb->id, scb->seg_max );
			    gcu_erlog( 0, GCD_global.language, 
				       E_GC4808_NO_MEMORY, NULL, 0, NULL );
			    gcd_sess_abort( ccb, E_GC4808_NO_MEMORY );
			    return;
			}
		    }

		    if ( GCD_global.gcd_trace_level >= 5 )
			TRdisplay( "%4d    GCD save segment: %d (total %d) \n",
				    ccb->id, seg_len, scb->seg_len + seg_len );
		    MEcopy( (PTR)ptr, seg_len, 
			    (PTR)(scb->seg_buff + scb->seg_len) );
		    scb->seg_len += seg_len;
		}

		/*
		** When the BLOB is complete, write the last
		** segment and end-of-segments indicator.
		*/
		if ( ! (scb->column.more_segments = more_segments) )
		{
		    /*
		    ** The processing loop above makes sure there
		    ** is room for the last segment.
		    */
		    if ( scb->seg_len )
		    {
			if ( GCD_global.gcd_trace_level >= 5 )
			    TRdisplay( "%4d    GCD send segment: %d \n",
					ccb->id, scb->seg_len );

			chrs = scb->seg_len / char_size;
			len = chrs * char_size;
			scb->seg_len = 0;

			gcd_put_i2( rcb_ptr, chrs );

			if ( ! ucs2 )
			    gcd_put_bytes( rcb_ptr, len, scb->seg_buff );
			else
			    gcd_put_ucs2( rcb_ptr, chrs, scb->seg_buff );
		    }

		    if ( GCD_global.gcd_trace_level >= 5 )
			TRdisplay( "%4d    GCD send end-of-segments\n",
				    ccb->id );
		    gcd_put_i2( rcb_ptr, 0 );
		}
	    }
	    break;

	default :
	    /* Should not happen since checked in send_desc() */
	    if ( GCD_global.gcd_trace_level >= 1 )
		TRdisplay( "%4d    GCD invalid datatype: %d\n",
				    ccb->id, desc[ col ].ds_dataType );
	    gcd_sess_abort( ccb, E_GC4812_UNSUPP_SQL_TYPE );
	    return;
	}
    }

    return;
}
Ejemplo n.º 11
0
STATUS
gcd_api_init( u_i2 api_ver, PTR *env )
{
    IIAPI_INITPARM	init;
    IIAPI_SETENVPRMPARM	set;
    bool		done;
    STATUS		status = OK;

    init.in_timeout = -1;
    init.in_version = api_ver;

    IIapi_initialize( &init );

    if ( init.in_status != IIAPI_ST_SUCCESS  &&
	 GCD_global.gcd_trace_level >= 1 )
	TRdisplay( "%4d    GCD Error initializing API: %s\n", 
		   -1, gcu_lookup( apiMap, init.in_status ) );

    switch( init.in_status )
    {
    case IIAPI_ST_SUCCESS :
	*env = init.in_envHandle;
	break;
    
    case IIAPI_ST_OUT_OF_MEMORY :
	status = E_GC4808_NO_MEMORY;
	break;
    
    default :
	status = E_GC4809_INTERNAL_ERROR;
	break;
    }

    for( done = (status != OK); ! done; done = TRUE )
    {
	II_LONG	value;

	set.se_envHandle = *env;
	set.se_paramID = IIAPI_EP_TRACE_FUNC;
	set.se_paramValue = (II_PTR)gcd_api_trace;

	IIapi_setEnvParam( &set );
	if ( (status = set.se_status) != OK )  break;

	if( api_ver >= IIAPI_VERSION_6 )
	{
	    set.se_paramID = IIAPI_EP_DATE_ALIAS;
	    set.se_paramValue = IIAPI_EPV_INGDATE;

	    IIapi_setEnvParam( &set );
	    if ( (status = set.se_status) != OK )  break;
	}

	set.se_paramID = IIAPI_EP_DATE_FORMAT;
	value = IIAPI_EPV_DFRMT_FINNISH;
	set.se_paramValue = (II_PTR)&value;

	IIapi_setEnvParam( &set );
	if ( (status = set.se_status) != OK )  break;

	set.se_paramID = IIAPI_EP_TIMEZONE;
	set.se_paramValue = "gmt";

	IIapi_setEnvParam( &set );
	if ( (status = set.se_status) != OK )  break;

	set.se_paramID = IIAPI_EP_MAX_SEGMENT_LEN;
	value = 8192;
	set.se_paramValue = (II_PTR)&value;

	IIapi_setEnvParam( &set );
	if ( (status = set.se_status) != OK )  break;
   
	set.se_paramID = IIAPI_EP_DECIMAL_CHAR;
	set.se_paramValue  = ".";

	IIapi_setEnvParam( &set );
	if ( (status = set.se_status) != OK )  break;

	set.se_paramID = IIAPI_EP_MONEY_SIGN ;
	set.se_paramValue  = "$";

	IIapi_setEnvParam( &set );
	if ( (status = set.se_status) != OK )  break;

	set.se_paramID = IIAPI_EP_MONEY_LORT ;
	value = IIAPI_EPV_MONEY_LEAD_SIGN;
	set.se_paramValue  =  (II_PTR)&value;

	IIapi_setEnvParam( &set );
	if ( (status = set.se_status) != OK )  break;

	set.se_paramID = IIAPI_EP_MONEY_PRECISION ;
	value = 2;
	set.se_paramValue  =  (II_PTR)&value;

	IIapi_setEnvParam( &set );
	if ( (status = set.se_status) != OK )  break;
    }

    if ( status != OK )
	gcu_erlog( 0, GCD_global.language, status, NULL, 0, NULL );

    return( status );
}
Ejemplo n.º 12
0
static void
gca_sm( i4 sid )
{
    GCA_LCB 	*lcb = &gca_lcb_tab[ sid ];
    bool 	branch = FALSE;

top:

    if ( 
	 JDBC_global.trace_level >= 5  &&
	 lsn_states[ lcb->state ].action != LSA_LABEL  &&
	 lsn_states[ lcb->state ].action != LSA_GOTO
       )
	TRdisplay( "%4d    JDBC  %s status 0x%x %s\n", sid, 
		   lsn_sa_names[ lsn_states[ lcb->state ].action ],
		   lcb->statusp ? *lcb->statusp : OK,
		   branch ? " (branch)" : "" );

    branch = FALSE;

    switch( lsn_states[ lcb->state++ ].action )
    {
    	case LSA_INIT :			/* Initialize, branch if listening */
	    branch = listening;
	    lcb->sp = 0;
	    lcb->flags = 0;

	    if ( ! labels[ 1 ] )
	    {
		i4 i;

		for( i = 0; i < ARR_SIZE( lsn_states ); i++ )
		    if ( lsn_states[ i ].action == LSA_LABEL )
			labels[ lsn_states[ i ].label ] = i + 1;
	    }
	    break;

	case LSA_GOTO : 		/* Branch unconditionally */
	    branch = TRUE;
	    break;

	case LSA_GOSUB :		/* Call subroutine */
	    lcb->ss[ lcb->sp++ ] = lcb->state;
	    branch = TRUE;
	    break;
	
	case LSA_RETURN :		/* Return from subroutine */
	    lcb->state = lcb->ss[ --lcb->sp ];
	    break;

	case LSA_EXIT :			/* Terminate thread */
	    lcb->state = 0;	/* Initialize state */

	    /*
	    ** Exit if there shutting down or there is an
	    ** active listen.  Otherwise, the current
	    ** thread continues as the new listen thread.
	    */
	    if ( lcb->flags & LCB_SHUTDOWN  ||  listening )  return;
	    break;

	case LSA_IF_RESUME :		/* Branch if INCOMPLETE */
	    branch = (*lcb->statusp == E_GCFFFE_INCOMPLETE);
	    break;

	case LSA_IF_TIMEOUT :		/* Branch if TIMEOUT */
	    branch = (*lcb->statusp == E_GC0020_TIME_OUT);
	    break;

	case LSA_IF_ERROR :		/* Branch if status not OK */
	    branch = (*lcb->statusp != OK);
	    break;

	case LSA_IF_SHUT :		/* Branch if SHUTDOWN requested */
	    branch = (lcb->flags & LCB_SHUTDOWN) ? TRUE : FALSE;
	    break;

	case LSA_SET_SHUT:		/* Prepare to shutdown server */
	    GCshut();
	    lcb->stat = E_GC0040_CS_OK;
	    lcb->statusp = &lcb->stat;
	    break;

	case LSA_CLEAR_ERR :		/* Set status to OK */
	    lcb->stat = OK;
	    lcb->statusp = &lcb->stat;
	    break;

	case LSA_LOG :			/* Log an error */
	    if ( *lcb->statusp != OK  &&  *lcb->statusp != FAIL  &&
		 *lcb->statusp != E_GC0032_NO_PEER )
	        gcu_erlog( 0, JDBC_global.language, 
			   *lcb->statusp, NULL, 0, NULL );
	    break;

	case LSA_CHECK :		/* Background checks */
	    jdbc_idle_check();
	    jdbc_pool_check();
	    break;

	case LSA_LISTEN:			/* Post a listen */
	    {
		i4	timeout = -1;
		SYSTIME now;

		MEfill( sizeof(lcb->parms), 0, (PTR) &lcb->parms );
		lcb->statusp = &lcb->parms.gca_ls_parms.gca_status;
		listening = TRUE;
		TMnow( &now );

		if ( JDBC_global.client_idle_limit )
		{
		    i4 secs;

		    if ( JDBC_global.client_check.TM_secs <= 0 )
			secs = JDBC_global.client_idle_limit;
		    else  if ( TMcmp( &now, &JDBC_global.client_check ) < 0 )
			secs = JDBC_global.client_check.TM_secs - now.TM_secs;
		    else
			secs = JDBC_global.client_idle_limit / 2;

		    if ( timeout <= 0  ||  secs < timeout )  timeout = secs;
		}

		if ( JDBC_global.pool_idle_limit )
		{
		    i4 secs;

		    if ( JDBC_global.pool_check.TM_secs <= 0 )
			secs = JDBC_global.pool_idle_limit;
		    else  if ( TMcmp( &now, &JDBC_global.pool_check ) < 0 )
			secs = JDBC_global.pool_check.TM_secs - now.TM_secs;
		    else
			secs = JDBC_global.pool_idle_limit / 2;

		    if ( timeout <= 0  ||  secs < timeout )  timeout = secs;
		}

		/*
		** If there is a timeout, leave some
		** lee-way to ensure we actually pass
		** the target check time.  Also, convert
		** seconds to milli-seconds.
		*/
		if ( timeout >= 0 )  timeout = (timeout + 10) * 1000;

		IIGCa_cb_call( &gca_cb, GCA_LISTEN, &lcb->parms, 
			       GCA_ASYNC_FLAG, (PTR)sid, timeout, &lcb->stat );
		if ( lcb->stat != OK )  break;
	    }
	    return;

	case LSA_LS_RESUME :		/* Resume a listen */
	    IIGCa_cb_call( &gca_cb, GCA_LISTEN, &lcb->parms, 
			   GCA_RESUME, (PTR)sid, -1, &lcb->stat );
	    if ( lcb->stat != OK )  break;
	    return;

	case LSA_REPOST:		/* Repost a listen */
	    {
		i4 id;

		listening = FALSE;

		for( id = 0; id < LCB_MAX; id++ )
		    if ( ! gca_lcb_tab[ id ].state )
		    {
			gca_sm( id );
			break;
		    }
	    }
	    break;

	case LSA_LS_DONE :		/* Listen request has completed */
	    lcb->assoc_id = lcb->parms.gca_ls_parms.gca_assoc_id;
	    break;

	case LSA_NEGOTIATE :		/* Validate client */
	    lcb->protocol = min( lcb->parms.gca_ls_parms.gca_partner_protocol,
				 JDBC_GCA_PROTO_LVL );

	    /*
	    ** Check for shutdown/quiesce request.
	    */
	    while( lcb->parms.gca_ls_parms.gca_l_aux_data > 0 )
	    {
		GCA_AUX_DATA	aux_hdr;
		char		*aux_data;
		i4		aux_len;

		MEcopy( lcb->parms.gca_ls_parms.gca_aux_data,
			sizeof( aux_hdr ), (PTR)&aux_hdr );
		aux_data = (char *)lcb->parms.gca_ls_parms.gca_aux_data +
			   sizeof( aux_hdr );
		aux_len = aux_hdr.len_aux_data - sizeof( aux_hdr );

		switch( aux_hdr.type_aux_data )
		{
		    case GCA_ID_QUIESCE :
		    case GCA_ID_SHUTDOWN :
			lcb->flags |= LCB_SHUTDOWN;
			break;
		}

		lcb->parms.gca_ls_parms.gca_aux_data = 
						(PTR)(aux_data + aux_len);
		lcb->parms.gca_ls_parms.gca_l_aux_data -= 
						aux_hdr.len_aux_data;
	    }
	    break;

	case LSA_REJECT :		/* Reject a client request */
	    lcb->stat = E_JD010B_NO_CLIENTS;
	    lcb->statusp = &lcb->stat;
	    break;

	case LSA_RQRESP :		/* Respond to client request */
            MEfill( sizeof(lcb->parms), 0, (PTR) &lcb->parms);
	    lcb->parms.gca_rr_parms.gca_assoc_id = lcb->assoc_id;
	    lcb->parms.gca_rr_parms.gca_request_status = *lcb->statusp;
	    lcb->parms.gca_rr_parms.gca_local_protocol = lcb->protocol;
	    lcb->statusp = &lcb->parms.gca_rr_parms.gca_status;

	    IIGCa_cb_call( &gca_cb, GCA_RQRESP, &lcb->parms, 
			   GCA_ASYNC_FLAG, (PTR)sid, -1, &lcb->stat );
	    if ( lcb->stat != OK )  break;
	    return;

	case LSA_DISASSOC :		/* Disconnect association */
            MEfill( sizeof(lcb->parms), 0, (PTR) &lcb->parms );
	    lcb->parms.gca_da_parms.gca_association_id = lcb->assoc_id;
	    lcb->statusp = &lcb->parms.gca_da_parms.gca_status;

	    IIGCa_cb_call( &gca_cb, GCA_DISASSOC, &lcb->parms, 
			   GCA_ASYNC_FLAG, (PTR)sid, -1, &lcb->stat );
	    if ( lcb->stat != OK ) break;
	    return;

	case LSA_DA_RESUME :		/* Resume disassociate */
	    IIGCa_cb_call( &gca_cb, GCA_DISASSOC, &lcb->parms, 
			   GCA_RESUME, (PTR)sid, -1, &lcb->stat );
	    if ( lcb->stat != OK )  break;
	    return;
    }

    if ( branch )  lcb->state = labels[ lsn_states[ lcb->state - 1 ].label ];

    goto top;
}