Example #1
0
int  odxa_errhandler(void)
{
    char buf[257]="";
    char message[513]="        ::[                , 00000000]: ";
    long error_no = 0;
    char error_text[257];
    SYSTIME     time_now;
    i4  len;

//  EXEC SQL INQUIRE_SQL(:error_no = ERRORNO,:error_text = ERRORTEXT);
        IILQisInqSqlio((short *)0,1,30,4,&error_no,2);
        IILQisInqSqlio((short *)0,1,32,256,error_text,63);

    CVlx((u_i4)error_no, buf);
    STprintf(message, ERx("        ::[%-16s, %s]: "), szFuncName, buf);
    TMnow( &time_now );
    TMstr( &time_now, buf );
    STcat(message, buf);
    STcat(message, " MS DTC Ingres XA Interface: ");

    if (STequal(szFuncName,"xa_open"))  /* dump out xa_open's xa_info string */
       {
         len = (i4)STlength(message);
         STcat(message, errlog_xa_info);
         WriteDTCerrToEventLog(S_OK, message);
         message[len] = '\0';   /* chop back to the message header */
       }

    STcat(message, error_text);

    WriteDTCerrToEventLog(S_OK, message);
    return 0;
}
Example #2
0
VOID
history_time(char *timeStr)
{
    SYSTIME                atime ;
    struct TMhuman         htime ;

    TMnow(&atime);
    TMbreak(&atime, &htime);
    STprintf(timeStr, ERx("%s-%s-%s"), htime.day, htime.month, htime.year);
}
Example #3
0
VOID
copyright_year(char *year)
{
	SYSTIME		atime ;
	struct TMhuman	htime ;

	TMnow(&atime);
	TMbreak(&atime, &htime);
	STprintf(year, ERx("%s"), htime.year);

}
Example #4
0
/*
** Name - SAwrite - write a record to the operating system audit trail
**
** Description:
**	This routine writes an audit record to the operating system audit trail.
**	It is preffereable though not compulsory for this routine to return 
**	asynchronously, a subsequent call to SAflush() will hand all 
**	outstanding audits to the operating system for auditing, if SAwrite() 
**	is synchronous then SAflush() will be a no-op routine. SAwrite() may 
**	buffer a number of audit records for performance before writing, if 
**	the caller wishes to guarantee writes a subsequent call to SAflush() 
**	must be used. SAwrite() should attempt, if possible, to write an
**	additional field, other than those passed in SA_AUD_REC, to the 
**	operating system audit trail, that will uniquely identify the record 
**	as an Ingres audit record. The audit trail will be identified by it's 
**	descriptior passed back	from SAopen().
**	
** Inputs:
**	aud_trail_d     a descriptor that identifies this audit trail
**	aud_rec         the audit record to be written
**
** Outputs:
**	err_code        pointer to a variable used to return OS errors.
**
** Returns:
**	OK              if operation succeeded
**	SA_NOOPEN       the audit trail decsribed by this descriptor has not
**			been opened
**	SA_NOWRITE      this audit trail may not be written to
**	SA_BADPARAM     bad parameter values were passed to the routine
**	SA_NOSUPP       the operation is not supported by this implimentation of
**			SA.
**	FAIL            the operation failed
**
** History:
**	7-jan-94 (stephenb)
**	    Initial creation using TRdisplay for testing.
**	28-feb-94 (stephenb)
**	    Updated to current SA spec.
*/
STATUS
SAwrite(PTR             *aud_trail_d,
	SA_AUD_REC      *aud_rec,
	CL_ERR_DESC     *err_code)
{
    /*
    ** This is a "quick and dirty routine" which just re-formats
    ** the audit record and TRdisplay's it
    */
    SYSTIME	stime;
    struct	TMhuman	time;
    char	*date;

    /*
    ** Check that the audit trail is open, this is just a dummy check
    ** that the stub routine SAopen() has been called.
    */
    if (STcompare(((SA_DESC*)*aud_trail_d)->sa_desc, "OS"))
	return (SA_NOOPEN);

    /*
    ** Get a human readable date string
    */
    TMnow(&stime);
    _VOID_ TMbreak(&stime, &time);
    _VOID_ STpolycat(7, time.wday, time.day, time.month, time.year,
	time.hour, time.mins, time.sec, &date);
    /*
    ** add null terminators to blank filled strings  (this will fail
    ** if the string already uses all 32 charaters).
    */
     _VOID_ SAtrim(aud_rec->sa_ruserid, GL_MAXNAME);
     _VOID_ SAtrim(aud_rec->sa_euserid, GL_MAXNAME);
     _VOID_ SAtrim(aud_rec->sa_dbname, GL_MAXNAME);
     _VOID_ SAtrim(aud_rec->sa_userpriv, GL_MAXNAME);
     _VOID_ SAtrim(aud_rec->sa_objpriv, GL_MAXNAME);
     _VOID_ SAtrim(aud_rec->sa_objowner, GL_MAXNAME);
     _VOID_ SAtrim(aud_rec->sa_objname, GL_MAXNAME);
    /*
    ** Send the lot to TRdisplay, not all fields are displayed, just
    ** enough to get the idea
    */
    TRdisplay("%s | %s | %s | %s | %s | %s\n", &date,
	aud_rec->sa_accesstype, aud_rec->sa_eventtype, aud_rec->sa_objname, 
	aud_rec->sa_ruserid, aud_rec->sa_dbname);
    
    return (OK);
}
Example #5
0
STATUS
ERmsg_hdr( char *svr_id, SCALARP session, char *msg_header)
{
    char        host_name[65];
    i4		length;
    SYSTIME	stime;

    GChostname( host_name, sizeof( host_name ) );
    STprintf( msg_header, "%-8.8s::[%-16.16s, %08.8x]: ",
	host_name, svr_id, session );
    TMnow(&stime);
    TMstr(&stime,msg_header + STlength(msg_header));
    length = STlength(msg_header);
    msg_header[length++] = ' ';
    msg_header[length] = EOS;
    return (OK);
}
Example #6
0
/*
**  close_log
*/
STATUS
close_log()
{
    STATUS                 ret_val = OK ;
    SYSTIME                atime ;
    char                   buffer [TEST_LINE] ;
    char                   timestr [TEST_LINE] ;

    append_line((char *)ERx("\n"),(i4)1);
    TMnow(&atime);
    TMstr(&atime,timestr);
    STprintf(buffer,ERx("Ending at: %s"),timestr);
    append_line(buffer,1);
    SIclose(logptr);

    return (ret_val);
}
Example #7
0
void
rfapi_getDateTime( char *dtbuf )
{
    SYSTIME	tm; /* system time in seconds */
    struct TMhuman	dthuman; /* human readable date and time structure */

    /* get the system time */
    TMnow( &tm );

    /* break it up into human readable format */
    TMbreak( &tm, &dthuman );

    STprintf( dtbuf, RFAPI_DATE_FORMAT,
		dthuman.wday,
		dthuman.month,
		dthuman.day,
		dthuman.hour,
		dthuman.mins,
		dthuman.sec,
		dthuman.year );
} 
Example #8
0
VOID
qee_d1_qid(
    QEE_DSH		*v_dsh_p)
{
    QEE_DDB_CB	    *qee_p = v_dsh_p->dsh_ddb_cb;
    DB_CURSOR_ID    *csr_p;
    SYSTIME	    tm_now;
    char	    hi_ascii[QEK_015_LEN],
                lo_ascii[QEK_015_LEN],
                pid_ascii[QEK_015_LEN],
                temp[QEK_050_LEN + DB_CURSOR_MAXNAME];
    PID		    pid;		/* an i4 */


    PCpid(& pid);			/* get process (server) id */
    CVla(pid, pid_ascii);		/* convert to ascii */

    TMnow(& tm_now);

    csr_p = & qee_p->qee_d4_given_qid;
    csr_p->db_cursor_id[0] = tm_now.TM_secs;
    csr_p->db_cursor_id[1] = tm_now.TM_msecs;
    CVla(tm_now.TM_secs, hi_ascii);
    CVla(tm_now.TM_msecs, lo_ascii);
    STpolycat((i4) 4,			/* 4 constituent pieces */
              "dd", lo_ascii, hi_ascii, pid_ascii, temp);
    MEmove(STlength(temp), temp, ' ',
           DB_CURSOR_MAXNAME, csr_p->db_cur_name);

    csr_p = & qee_p->qee_d5_local_qid;
    csr_p->db_cursor_id[0] = 0;
    csr_p->db_cursor_id[1] = 0;
    MEfill(DB_CURSOR_MAXNAME, ' ', (PTR) csr_p->db_cur_name);

    return;
}
Example #9
0
/*{
** Name: psy_cproc - Create a database procedure definition in
**		     the system catalogs.
**
** Description:
**
** Inputs:
**
** Outputs:
**	Exceptions:
**	    none
**
** Side Effects:
**	    Modifies system catalogs.
**
** History:
**      27-apr-88 (stec)
**	    Created.
**	23-aug-88 (stec)
**	    Added comments, initialize new fields in DB_PROCEDURE.
**	26-apr-89 (andre)
**	    For internal procedures, set db_mask[0] to DB_IPROC.
**	12-mar-90 (andre)
**	    set rdr_2types_mask to 0.
**      22-may-90 (teg)
**          init rdr_instr to RDF_NO_INSTR
**	12-jun-90 (andre)
**	    when trying to destroy a dbproc QEP, use "private" alias, which is
**	    always defined as opposed to the "public" alias which would not be
**	    defined if the dbproc is not grantable.
**	04-mar-92 (andre)
**	    set DB_ACTIVE_DBP in db_mask[0] to indicate that the dbproc is not
**	    abandoned.  If the dbproc is grantable, set DB_DBPGRANT_OK in
**	    db_mask[0].
**	18-may-92 (andre)
**	    call psy_dbp_status() to verify that the new dbproc is not abandoned
**	    and trust psy_dbp_status() to determine whether the dbproc is
**	    grantable or just active.
**	19-may-92 (andre)
**	    in pslsgram.yi, pss_dependencies_stream was opened to collect info
**	    about objects/privileges on which the new dbproc depends;
**	    this stream must be closed before leaving this function since the
**	    dependence information will be of no use once we return
**	01-jun-92 (andre)
**	    pass information about objects/privileges on which the new database
**	    procedure depends to QEF.
**	26-jun-92 (andre)
**	    enter information about the dbproc into IIPROCEDURE and the list of
**	    objects and privileges on which it depends into IIDBDEPENDS and
**	    IIPRIV respectively before calling psy_dbp_status() to determine
**	    whether it is active.  This is necessary since otherwise it would be
**	    impossible to create mutually recursive database procedures (if P1
**	    calls P2 and we are trying to create P2 calling P1, psy_dbp_status()
**	    will report that P1 is dormant and prevent us from creating P2)
**
**	    Since we won't know whether the dbproc is active and/or grantable
**	    until psy_dbp_status() is done, we will set only DB_DBP_INDEP_LIST
**	    bit in IIPROCEDURE.dbp_mask1 here, unless the independent
**	    object/privilege list is empty, in which case there is no reason to
**	    call psy_dbp_status(), so we will set DB_DBPGRANT_OK and
**	    DB_ACTIVE_DBP bits in IIPROCEDURE.dbp_mask1.
**
**	    If the independent object/privilege list is not empty and the
**	    procedure is not dormant, psy_dbp_status() will set appropriate bits
**	    (DB_DBPGRANT_OK and/or DB_ACTIVE_DBP) in IIPROCEDURE.dbp_mask1 once
**	    it has determined whether the dbproc is active or grantable
**	09-sep-92 (andre)
**	    psy_dbp_status() no longer accepts or returns an indicator of
**	    whether cache had to be flushed in psy_dbp_priv_check()
**	07-nov-92 (andre)
**	    we will no longer create private aliases for dbproc QPs
**	22-feb-93 (rblumer)
**	    initialize new RDF proc_param variables for both normal and
**	    set-input procedures; reverse order of MEcopy and I4assign in
**	    QP cleanup code so that qsf id gets set up correctly.
**	13-apr-93 (andre)
**	    if creating a system-generated procedure, independent
**	    object/privilege list will be empty - QEF will insert IIDBDEPENDS
**	    tuple recording dependence of the dbproc on a constraint (for
**	    constraint-enforcing dbprocs) or view (for CHECK OPTION-enforcing
**	    dbprocs.)  Here we will set bits indicating that there will be
**	    independent object list and that the dbproc is active but not
**	    grantable (we don't want the user to grant privileges on
**	    system-generated dbprocs)
**	01-sep-93 (andre)
**	    in the course of parsing a dbproc definition, we will try to 
**	    determine id of a base table on which the dbproc depends; here we
**	    will copy it into proctuple.dbPdbp_ubt_id to ensure that it gets 
**	    inserted into IIPROCEDURE
**	22-oct-93 (rblumer)
**	    normal procedures will now have their parameters inserted into the
**	    catalogs (previously just set-input procedures did); changed
**	    initialization of db_parameterCount, rdr_proc_param_cnt and
**	    rdr_proc_params to work for both types of procedures.
**	30-apr-94 (andre)
**	    fix for bug 61087:
**	    proctuple.db_mask[0] was being set before proctuple was MEfill'd 
**	    with NULLCHAR; moved the line initializing proctuple.db_mask[0] 
**	    below call to MEfill() 
**	16-jun-94 (andre)
**	    Bug #64395
**	    it is dangerous to cast a (char *) into a (DB_CURSOR_ID *) and then
**	    dereference the resulting pointer because the chat ptr may not be 
**	    pointing at memory not aligned on an appopriate boundary.  Instead,
**	    we will allocate a DB_CURSOR_ID structure on the stack, initialize 
**	    it and MEcopy() it into the char array
**	19-june-06 (dougi)
**	    Add DBP_DATA_CHANGE flag for BEFORE trigger validation.
**	28-march-2008 (dougi)
**	    Changes to support table procedures and named result row elements.
**	4-feb-2009 (dougi)
**	    Tidy up computation of table procedure result row length.
**	30-mar-2009 (toumi01) b121871
**	    Rewrite and simplify the computation of table procedure input
**	    and output parameter count and width (fixes a logic error that
**	    caused the result width to be decremented by the width of the
**	    first result parameter when there were no input parameters).
*/
DB_STATUS
psy_cproc(
	PSY_CB	   *psy_cb,
	PSS_SESBLK *sess_cb)
{
    RDF_CB		rdf_cb;
    register RDR_RB	*rdf_rb = &rdf_cb.rdf_rb;
    i4			textlen;
    QSF_RCB		qsf_rb;
    DB_PROCEDURE	proctuple;
    DB_STATUS		status, stat;
    i4		err_code;
    PSY_TBL		dbp_descr;
    i4			dbp_mask[2];
    bool		empty_indep_list, rowproc;

    /* If this is a recreate case, and this code gets called
    ** just return since there is no work to be done, not even
    ** recovery of resources.
    */
    if (sess_cb->pss_dbp_flags & PSS_RECREATE)
	return(E_DB_OK);

    /* determine if the new dbproc depends on any object or privileges */
    if (   sess_cb->pss_indep_objs.psq_objs
	|| sess_cb->pss_indep_objs.psq_objprivs
	|| sess_cb->pss_indep_objs.psq_colprivs
       )
    {
	empty_indep_list = FALSE;
    }
    else
    {
	empty_indep_list = TRUE;
    }

    /*
    ** Initialize the header of the QSF control block
    ** NOTE: it is important that we init qsf_rb before calling
    **       psy_dbp_status() - if the dbproc cannot be created, code under
    **	     exit: will expect the control block set up for deleting the query
    **	     text QSF object and the query plan QSF object
    */
    qsf_rb.qsf_type = QSFRB_CB;
    qsf_rb.qsf_ascii_id = QSFRB_ASCII_ID;
    qsf_rb.qsf_length = sizeof(qsf_rb);
    qsf_rb.qsf_owner = (PTR)DB_PSF_ID;
    qsf_rb.qsf_sid = sess_cb->pss_sessid;
    STRUCT_ASSIGN_MACRO(psy_cb->psy_qrytext, qsf_rb.qsf_obj_id);

    /* Retrieve info about the procedure text object */
    status = qsf_call(QSO_INFO, &qsf_rb);

    if (DB_FAILURE_MACRO(status))
    {
	goto exit;
    }

    /* Get the text length. */
    MEcopy((PTR) qsf_rb.qsf_root, sizeof(i4), (PTR) &textlen);

    /* Initialize the II_PROCEDURE tuple. */
    MEfill(sizeof(proctuple), NULLCHAR, (PTR) &proctuple);

    (VOID) MEcopy((PTR)&psy_cb->psy_tabname[0], sizeof(DB_DBP_NAME),   
	(PTR)&proctuple.db_dbpname);

    /* Current user is the owner. */
    STRUCT_ASSIGN_MACRO(sess_cb->pss_user, proctuple.db_owner);

    proctuple.db_txtlen = textlen;

    TMnow((SYSTIME *) &proctuple.db_txtid);

    /*
    ** if the independent object/privilege list is non-empty, we will set
    ** DB_DBP_INDEP_LIST bit and leave it to psy_dbp_status() to set the
    ** remaining bits, if appropriate; otherwise we will set DB_DBPGRANT_OK and
    ** DB_ACTIVE_DBP bits and avoid calling psy_dbp_status()
    **
    ** if creating a system-generated dbproc, mark the dbproc ACTIVE and
    ** indicate that there is independent object list (there is not one at this
    ** point, but QEF will insert IIDBDEPENDS tuple recording dependence of the
    ** dbproc on a constraint (for constraint-enforcing dbprocs) or view (for
    ** CHECK OPTION-enforcingdbprocs.)
    */
    
    /* If working on internal dbproc, set DB_IPROC in db_mask[0] */
    if (sess_cb->pss_dbp_flags & PSS_IPROC)
	proctuple.db_mask[0] |= DB_IPROC;

    if (sess_cb->pss_dbp_flags & PSS_SYSTEM_GENERATED)
	proctuple.db_mask[0] |=
	    DBP_SYSTEM_GENERATED | DB_ACTIVE_DBP | DB_DBP_INDEP_LIST;
    else if (empty_indep_list)
	proctuple.db_mask[0] |= DB_DBPGRANT_OK | DB_ACTIVE_DBP;
    else
	proctuple.db_mask[0] |= DB_DBP_INDEP_LIST;

    if (sess_cb->pss_dbp_flags & PSS_SET_INPUT_PARAM)
	proctuple.db_mask[0] |= DBP_SETINPUT;

    if (sess_cb->pss_dbp_flags & PSS_NOT_DROPPABLE)
	proctuple.db_mask[0] |= DBP_NOT_DROPPABLE;

    if (sess_cb->pss_dbp_flags & PSS_SUPPORTS_CONS)
	proctuple.db_mask[0] |= DBP_CONS;

    if (sess_cb->pss_dbp_flags & PSS_DATA_CHANGE)
	proctuple.db_mask[0] |= DBP_DATA_CHANGE;

    if (sess_cb->pss_dbp_flags & PSS_OUT_PARMS)
	proctuple.db_mask[0] |= DBP_OUT_PARMS;

    if (sess_cb->pss_dbp_flags & PSS_TX_STMT)
	proctuple.db_mask[0] |= DBP_TX_STMT;

    if (sess_cb->pss_dbp_flags & PSS_ROW_PROC)
    {
	rowproc = TRUE;
	proctuple.db_mask[0] |= DBP_ROW_PROC;
    }
    else rowproc = FALSE;

    proctuple.db_mask[1] = 0;

    /*
    ** if we were able to determine id of a base table on which this dbproc will
    ** depend, copy it into proctuple
    */
    proctuple.db_dbp_ubt_id.db_tab_base  = sess_cb->pss_dbp_ubt_id.db_tab_base;
    proctuple.db_dbp_ubt_id.db_tab_index = sess_cb->pss_dbp_ubt_id.db_tab_index;

    /* db_procid to be filled in by RDF or QEF */

    proctuple.db_parameterCount = 0;
    proctuple.db_recordWidth    = 0;
    proctuple.db_rescolCount = 0;
    proctuple.db_resrowWidth    = 0;

    if (sess_cb->pss_procparmlist != (QEF_DATA *) NULL)
    {
	DB_PROCEDURE_PARAMETER	*param_tuple;
	QEF_DATA		*listptr;

	/* compute count and total width of input and result parameters */
	for (listptr = sess_cb->pss_procparmlist;
	     listptr != (QEF_DATA *) NULL;
	     listptr = listptr->dt_next)
	{
	    param_tuple = (DB_PROCEDURE_PARAMETER *)listptr->dt_data;
	    if (param_tuple->dbpp_flags & DBPP_RESULT_COL)
	    {
		proctuple.db_rescolCount++;
		proctuple.db_resrowWidth = param_tuple->dbpp_offset 
			+ param_tuple->dbpp_length;
	    }
	    else
	    {
		proctuple.db_parameterCount++;
		proctuple.db_recordWidth = param_tuple->dbpp_offset 
			+ param_tuple->dbpp_length;
	    }
	}
	if (proctuple.db_rescolCount > 0)
	    proctuple.db_resrowWidth -= proctuple.db_recordWidth;
    }

    /* Initialize the RDF request block. */
    pst_rdfcb_init(&rdf_cb, sess_cb);
    (VOID) MEcopy((PTR)&psy_cb->psy_tabname[0], sizeof(DB_DBP_NAME),
	(PTR)&rdf_rb->rdr_name.rdr_prcname);
    STRUCT_ASSIGN_MACRO(sess_cb->pss_user, rdf_rb->rdr_owner);
    rdf_rb->rdr_types_mask = RDR_PROCEDURE;
    rdf_rb->rdr_update_op = RDR_APPEND;
    rdf_rb->rdr_qrytuple = (PTR) &proctuple; 
    rdf_rb->rdr_l_querytext = textlen;
    rdf_rb->rdr_querytext = ((char *) qsf_rb.qsf_root) + sizeof(i4);

    /*
    ** pass information about objects/privileges on which the new database
    ** procedure depends to QEF
    */
    sess_cb->pss_indep_objs.psq_grantee = &sess_cb->pss_user;
    rdf_rb->rdr_indep = (PTR) &sess_cb->pss_indep_objs;

    /* fill in the description of the procedure's parameters
    ** (which RDF/QEF will store into iiprocedure_parameter);
    */
    rdf_rb->rdr_proc_param_cnt = proctuple.db_parameterCount
					+ proctuple.db_rescolCount;
    rdf_rb->rdr_proc_params    = sess_cb->pss_procparmlist;

    /* Create a new procedure in the system catalogs */
    status = rdf_call(RDF_UPDATE, (PTR) &rdf_cb);

    if (DB_FAILURE_MACRO(status))
    {
	if (rdf_cb.rdf_error.err_code == E_RD0137_DUPLICATE_PROCS)
	{
	    /* Retry */
	    psy_cb->psy_error.err_code = E_PS0008_RETRY;
	}
	else
	{
	    (VOID) psf_rdf_error(RDF_UPDATE, &rdf_cb.rdf_error,
		&psy_cb->psy_error);
	}

	goto exit;
    }

    /*
    ** if the independent object/privilege list is non-empty, verify that the
    ** dbproc we are about to create is not abandoned; strictly speaking, as
    ** long as the independent object list is empty, we are guaranteed that the
    ** dbproc is not abandoned (user posesses required privileges), but we will
    ** take an extra step and try to determine whether it is grantable
    */
    if (!empty_indep_list)
    {
	MEcopy((PTR) psy_cb->psy_tabname, sizeof(DB_DBP_NAME),
	    (PTR) &dbp_descr.psy_tabnm);
	dbp_descr.psy_tabid.db_tab_base = proctuple.db_procid.db_tab_base;
	dbp_descr.psy_tabid.db_tab_index = proctuple.db_procid.db_tab_index;
	
	status = psy_dbp_status(&dbp_descr, sess_cb, (PSF_QUEUE *) NULL,
	    (i4) PSQ_CREDBP, dbp_mask, &psy_cb->psy_error);
	if (DB_FAILURE_MACRO(status))
	{
	    goto exit;
	}
    }


exit:

    /*
    ** close the memory stream which was used to allocate descriptors of
    ** objects/privileges on which the new dbproc depends
    */
    stat = psf_mclose(sess_cb, sess_cb->pss_dependencies_stream, &psy_cb->psy_error);
    if (DB_FAILURE_MACRO(stat) && stat > status)
	status = stat;

    /*
    ** ensure that no one tries to use the stream that is no longer valid
    */
    sess_cb->pss_dependencies_stream = (PSF_MSTREAM *) NULL;

    /* Get a lock on the query text from QSF */
    qsf_rb.qsf_lk_state = QSO_EXLOCK;

    stat = qsf_call(QSO_LOCK, &qsf_rb);

    if (DB_FAILURE_MACRO(stat))
    {
	(VOID) psf_error(E_PS0A08_CANTLOCK, qsf_rb.qsf_error.err_code,
	    PSF_INTERR, &err_code, &psy_cb->psy_error, 0);
	if (stat > status)
	    status = stat;
    }
    else
    {
	/* Now destroy the query text */
	stat = qsf_call(QSO_DESTROY, &qsf_rb);

	if (DB_FAILURE_MACRO(stat))
	{
	    (VOID) psf_error(E_PS0A09_CANTDESTROY, qsf_rb.qsf_error.err_code,
		PSF_INTERR, &err_code, &psy_cb->psy_error, 0);
	    if (stat > status)
		status = stat;
	}
    }


    /* Destroy the procedure QP in QSF if things went wrong. */
    if (DB_FAILURE_MACRO(status))
    {
	PSS_DBPALIAS	dbpid;
	DB_CURSOR_ID	dbp_curs_id;

	qsf_rb.qsf_feobj_id.qso_type = QSO_ALIAS_OBJ;
	qsf_rb.qsf_feobj_id.qso_lname = sizeof(dbpid);

	/* Identify the object first */
	dbp_curs_id.db_cursor_id[0] = dbp_curs_id.db_cursor_id[1] = 0;
	(VOID) MEcopy((PTR)&psy_cb->psy_tabname[0], DB_TAB_MAXNAME,
	    (PTR)dbp_curs_id.db_cur_name);
	MEcopy((PTR) &dbp_curs_id, sizeof(DB_CURSOR_ID), (PTR) dbpid);

	(VOID) MEcopy((PTR) &sess_cb->pss_user, DB_OWN_MAXNAME,
	    (PTR) (dbpid + sizeof(DB_CURSOR_ID)));

	I4ASSIGN_MACRO(sess_cb->pss_udbid,
		       *(i4 *) (dbpid + sizeof(DB_CURSOR_ID) + DB_OWN_MAXNAME));

	(VOID)MEcopy((PTR) dbpid, sizeof(dbpid),
	    (PTR) qsf_rb.qsf_feobj_id.qso_name);

	/* See if QP for the alias already exists. */
	qsf_rb.qsf_lk_state = QSO_SHLOCK;
	stat = qsf_call(QSO_JUST_TRANS, &qsf_rb);

	if (DB_FAILURE_MACRO(stat))
	{
	    if (qsf_rb.qsf_error.err_code != E_QS0019_UNKNOWN_OBJ)
	    {
		(VOID) psf_error(E_PS037A_QSF_TRANS_ERR,
		    qsf_rb.qsf_error.err_code, PSF_INTERR,
		    &err_code, &psy_cb->psy_error, 0);
		if (stat > status)
		    status = stat;
		goto exit1;
	    }
	    else
	    {
		/* QP disappeared, which is alright. */
		goto exit1;
	    }
	}

	/* Now destroy the QP object in QSF */
	stat = qsf_call(QSO_DESTROY, &qsf_rb);

	if (DB_FAILURE_MACRO(stat))
	{
	    (VOID) psf_error(E_PS0A09_CANTDESTROY, qsf_rb.qsf_error.err_code,
		    PSF_INTERR, &err_code, &psy_cb->psy_error, 0);
	    if (stat > status)
		status = stat;
	}
    }

exit1:
    return (status);
}
Example #10
0
/*{
** Name:	RScommit - two-phase commit processing
**
** Description:
**	Prepares to commit locally, commits remotely, commits locally.
**	Logs each step of the commit so that a reasonable attempt can
**	be made to recover if it does not complete.
**
** Inputs:
**	target	- target database, CDDS and connection number
**	row	- distribution queue row
**
** Outputs:
**	none
**
** Returns:
**	OK or Ingres error
**
** Side effects:
**	A distributed transaction is committed using incomplete two-phase
**	commit (a prepare is only done on the local database, so the target
**	database is not aware it is part of a distributed transaction).
*/
STATUS
RScommit(
RS_TARGET	*target,
RS_TRANS_ROW	*row)
{
	i4			high = (i4)RSlocal_conn.db_no;
	SYSTIME			now;
	char			timestamp[21];
	char			timestr[27];
	i4			start_entry_no;
	i4			prepare_entry_no;
	i4			remote_entry_no;
	i4			complete_entry_no;
	RS_TBLDESC		*tbl = row->tbl_desc;
	RS_CONN			*local_conn = &RSlocal_conn;
	RS_CONN			*target_conn = &RSconns[target->conn_no];
	IIAPI_GETEINFOPARM	errParm;
	IIAPI_STATUS		status;

	if (RStwo_phase)	/* two-phase commit is on */
	{
		start_entry_no = RS_2PC_BEGIN;
		prepare_entry_no = RS_PREP_COMMIT;
		remote_entry_no = RS_REMOTE_COMMIT;
		complete_entry_no = RS_2PC_END;
	}
	else			/* two-phase commit is off */
	{
		start_entry_no = RS_NPC_BEGIN;
		remote_entry_no = RS_NPC_REM_COMMIT;
		complete_entry_no = RS_NPC_END;
	}

	TMnow(&now);
	TMstr(&now, timestr);
	mktimestamp(timestr, timestamp);

	SIfprintf(RScommit_fp, log_format, start_entry_no, high, low,
		(i4)target->db_no, tbl->table_owner, tbl->table_name,
		tbl->table_no, row->rep_key.trans_id, row->rep_key.seq_no,
		timestamp, "Start of commit");
	SIflush(RScommit_fp);

	if (RStwo_phase)	/* only prepare to commit if two-phase is on */
	{
		/*
		** Prepare to commit. The high value is %d, The low value is %d
		*/
		messageit(5, 1277, high, low);

		status = IIsw_prepareCommit(&local_conn->tranHandle, &errParm);
		if (status != IIAPI_ST_SUCCESS)
		{
			messageit(1, 1214);
			IIsw_rollback(&target_conn->tranHandle, &errParm);
			IIsw_rollback(&local_conn->tranHandle, &errParm);
			IIsw_releaseXID(&dtrans_id_handle);
			return (status);
		}

		SIfprintf(RScommit_fp, log_format, prepare_entry_no, high, low,
			(i4)target->db_no, tbl->table_owner, tbl->table_name,
			tbl->table_no, row->rep_key.trans_id,
			row->rep_key.seq_no, timestamp, "Prepare to commit");
		SIflush(RScommit_fp);
	}

	status = IIsw_commit(&target_conn->tranHandle, &errParm);
	if (status != IIAPI_ST_SUCCESS)
	{
		IIsw_rollback(&target_conn->tranHandle, &errParm);
		if (IIsw_rollback(&local_conn->tranHandle, &errParm) !=
			IIAPI_ST_SUCCESS)
		{
			RSdo_recover = TRUE;
			messageit(1, 1215);
			messageit(1, 1216);
		}
		else
		{
			messageit(1, 1215);
		}
		IIsw_releaseXID(&dtrans_id_handle);

		SIfprintf(RScommit_fp, log_format, remote_entry_no, high,
			low, (i4)target->db_no, tbl->table_owner,
			tbl->table_name, tbl->table_no, row->rep_key.trans_id,
			row->rep_key.seq_no, timestamp, "Local rollback");
		SIfprintf(RScommit_fp, log_format, complete_entry_no, high,
			low, (i4)target->db_no, tbl->table_owner,
			tbl->table_name, tbl->table_no, row->rep_key.trans_id,
			row->rep_key.seq_no, timestamp, "Commit complete");
		SIflush(RScommit_fp);
		return (status);
	}

	SIfprintf(RScommit_fp, log_format, remote_entry_no, high, low,
		(i4)target->db_no, tbl->table_owner, tbl->table_name,
		tbl->table_no, row->rep_key.trans_id, row->rep_key.seq_no,
		timestamp, "Remote commit");
	SIflush(RScommit_fp);

	status = IIsw_commit(&local_conn->tranHandle, &errParm);
	if (status != IIAPI_ST_SUCCESS)
	{
		RSdo_recover = TRUE;
		IIsw_releaseXID(&dtrans_id_handle);
		return (status);
	}
	IIsw_releaseXID(&dtrans_id_handle);

	SIfprintf(RScommit_fp, log_format, complete_entry_no, high, low,
		(i4)target->db_no, tbl->table_owner, tbl->table_name,
		tbl->table_no, row->rep_key.trans_id, row->rep_key.seq_no,
		timestamp, "Commit complete");
	SIflush(RScommit_fp);

	return (OK);
}
Example #11
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;
}
Example #12
0
static VOID
IILQgtfGcaTraceFile( II_LBQ_CB *IIlbqcb, i4  action )
{
    IILQ_TRACE		*msgtrc = &IIglbcb->iigl_msgtrc;
    FILE		*trace_file = (FILE *)msgtrc->ii_tr_file;
    char		*title = ERx("off");
    SYSTIME		now;
    char		nowbuf[100];
    i4			nowend;

    /*
    ** Check to see that we actually need to open
    ** or close the trace file.
    */
    if ( (action == IITRC_ON  &&  trace_file)    ||
	 (action == IITRC_OFF  &&  ! trace_file)  ||
	 (action == IITRC_SWITCH  &&  ! trace_file) )
	return;

    if ( action == IITRC_SWITCH )  title = ERx("switched");

    if ( action == IITRC_ON )
    {
	LOCATION	trace_loc;
	STATUS		stat;

	/*
	** If trace file name not provided, use default.
	*/
	if ( ! msgtrc->ii_tr_fname )
	    msgtrc->ii_tr_fname = STalloc( GCTRACEFILE );

	LOfroms(FILENAME, msgtrc->ii_tr_fname, &trace_loc );
# ifdef hp9_mpe
	if ( msgtrc->ii_tr_flags & II_TR_APPEND )
	    stat = SIfopen(&trace_loc, ERx("a"), SI_TXT, 252, &trace_file);
	else
	    stat = SIfopen(&trace_loc, ERx("w"), SI_TXT, 252, &trace_file);
# else
	if ( msgtrc->ii_tr_flags & II_TR_APPEND )
	    stat = SIopen(&trace_loc, ERx("a"), &trace_file);
	else
	    stat = SIopen(&trace_loc, ERx("w"), &trace_file);
# endif
	if (stat != OK)
	{
	    /* Simplest error path; don't want IIlocerr functionality */
	    IIUGerr(E_LQ0007_PRINTQRY, 0, 1, msgtrc->ii_tr_fname);

	    /*
	    ** We can't call IILQgstGcaSetTrace() because
	    ** of possible conflicts with the tracing
	    ** semaphore, so just turn off tracing here.
	    */
	    msgtrc->ii_tr_flags &= ~II_TR_FILE;
	    if ( ! (msgtrc->ii_tr_flags & II_TR_HDLR) )
		IIcgct1_set_trace( IIlbqcb->ii_lq_gca, 0, NULL, NULL );
	    return;
	}

	msgtrc->ii_tr_file = (PTR)trace_file;
	title = ERx("on ");
    }

    /* Get time stamp */
    TMnow(&now);
    TMstr(&now, nowbuf);
    nowend = STlength( nowbuf );
    if ( nowbuf[ nowend - 1 ] == '\n' )  nowbuf[ nowend - 1 ] = EOS;

    SIfprintf( trace_file, ERx("---- printgca = %s session %d (%s) ---\n\n"),
	       title, IIlbqcb->ii_lq_sid, nowbuf );
    SIflush( trace_file );

    if ( action != IITRC_OFF )
	msgtrc->ii_tr_sid = IIlbqcb->ii_lq_sid;
    else
    {
	SIclose( trace_file );
	msgtrc->ii_tr_file = NULL;
	msgtrc->ii_tr_sid = 0;
	msgtrc->ii_tr_flags |= II_TR_APPEND;  /* Don't overwrite if reopened */
    }

    return;
} /* IILQgtfGcaTraceFile */
Example #13
0
STATUS
open_log(char *testPrefix,char *testSufix,char *username,char *errbuff)
{
    SYSTIME                atime ;
    char                   uname [20] ;
    char                   logFileName [MAX_LOC+1] ;
    char                   timestr [TEST_LINE] ;
    char                   buffer [MAX_LOC+1] ;
    char                  *dot = NULL ;
    char                  *cptr = NULL ;
	char				   year[5];

    if (shellMode)
        STpolycat(3, testPrefix, ERx("."), testSufix, logFileName);
    else if (updateMode)
            STpolycat(2, testPrefix, ERx(".upd"), logFileName);
         else
            STpolycat(2, testPrefix, ERx(".log"), logFileName);

    if (outputDir)
    {
	if (outputDir_type == PATH)
	{
	    STcopy(outputDir, buffer);
	    LOfroms(PATH, buffer, &logloc);
	    LOfstfile(logFileName, &logloc);
	    LOtos(&logloc, &cptr);
	}
	else
	{
	    LOtos(&outLoc,&cptr);
	}
	STcopy(cptr, logname);
    }
    else
        STcopy(logFileName, logname);
    
    
    if (LOfroms(FILENAME & PATH, logname, &logloc) != OK)
    {
	STprintf(errbuff,ERx("ERROR: could not get location for log file"));
	return(FAIL);
    }
    if (SIopen(&logloc,ERx("w"),&logptr) != OK)
    {
	STprintf(errbuff,ERx("ERROR: could not open log file"));
	return(FAIL);
    }

    if (!updateMode)
    {
	append_line(ERx("/*"),1);

	copyright_year(&year[0]);
	STprintf(buffer, ERx("Copyright (c) %s Ingres Corporation"), &year);
	append_line(buffer, 1);
	append_line(ERx(" "), 1);

	STprintf(buffer,ERx("\tTest Name: %s.%s"), testPrefix, testSufix);
	append_line(buffer,1);
	TMnow(&atime);
	TMstr(&atime,timestr);
	STprintf(buffer,ERx("\tTime: %s"),timestr);
	append_line(buffer,1);
	dot = uname;
	if (username == NULL || *username == '\0')
	    IDname(&dot);
	else
	    STcopy(username,uname);
	STprintf(buffer,ERx("\tUser Name: %s"),uname);
	append_line(buffer,1);
	STprintf(buffer, ERx("\tTerminal type: %s"), terminalType);
	append_line(buffer,1);
	append_line(ERx(" "),1);
    }

    return(OK);
}
Example #14
0
STATUS
ERslookup(
    i4		    msg_number,
    CL_ERR_DESC	    *clerror,
    i4		    flags,
    char	    *sqlstate,
    char	    *msg_buf,
    i4		    msg_buf_size,
    i4		    language,
    i4		    *msg_length,
    CL_ERR_DESC	    *err_code,
    i4		    num_param,
    ER_ARGUMENT	    *param )
{
    i4			erindex;	/* index of ERmulti table */
    i4		status;
    i4			length = 0;
    ER_ARGUMENT		*p;
    ER_ARGUMENT		hidden[CLE_INFO_ITEMS];	/* to access info in clerror */
    char		tempbuf[ER_MAX_LEN+ER_MAX_NAME+2];
    i4			templen;
    char		*p_msg_buf;
    char		*p_tempbuf;
    SYSTIME		stime;
    char		langbuf[ER_MAX_LANGSTR];
    EX_CONTEXT		context;
    ER_SEMFUNCS		*sems;

#define			    D_WIDTH	    23
#define			    F_WIDTH	    20
#define			    X_WIDTH	    18


    /*	Validate the parameters. */

    if (msg_buf == 0 || msg_buf_size == 0 || msg_length == 0)
    {
	return (ER_BADPARAM);
    }
    if (language != -1 && ERlangstr(language,langbuf) != OK)
    {
	return (ER_BADLANGUAGE);
    }
 
    if (!(flags & ER_NAMEONLY))
    {
        EXdump(msg_number,0);
    }
 

    /*	Insert timestamp if requested. */

    if (flags & ER_TIMESTAMP)
    {
	if (msg_buf_size < 21)
	{
	    return (ER_TOOSMALL);
	}
	TMnow(&stime);
	TMstr(&stime,msg_buf);

	length = (i4)STlength(msg_buf);	
	msg_buf[length++] = ' ';
    }

    /*
    **    if (clerror && msg_number)
    **        look up msg_number, optional parameters in clerror->moreinfo
    **    else if (clerror)
    **    {
    **        if (clerror->intern)
    **            look up clerror.intern, optional params in clerror->moreinfo
    **        if (clerror->callid)
    **            look up system error message
    **    }
    */
    if (clerror)
    {
	if (msg_number)	/* Look up message after system error */
	{
	    /*
	    ** Set up an ER_ARGUMENT that references system-dependent
	    ** information in `clerror', and point `param' at it.
	    */
	    i4  i;

	    for (i = 0; i < CLE_INFO_ITEMS; ++i)
	    {
	        /* "...all of whose members begin at offset 0..." (K&R) */

	        hidden[i].er_value = (PTR)&clerror->moreinfo[i].data._i4;
	        hidden[i].er_size = clerror->moreinfo[i].size;
	    }

	    param = &hidden[0];
	    num_param = CLE_INFO_ITEMS;
	}
        else		/* retrieve system-dependent error messages */
	{
	    i4	        len;
	    ER_ARGUMENT	argv[3];

	    if (clerror->intern)    /* look up internal CL error */
	    {
	        i4  i;

	        for (i = 0; i < CLE_INFO_ITEMS; ++i)
	        {
	            argv[i].er_value = (PTR)&clerror->moreinfo[i].data._i4;
	            argv[i].er_size = clerror->moreinfo[i].size;
	        }

	        /*
	        ** Don't timestamp on recursive call, since it's been done
	        ** already (if requested).
	        */
	        if ((status = ERslookup((i4) clerror->intern,
		    (CL_ERR_DESC*) NULL, flags & ~ER_TIMESTAMP | ER_TEXTONLY,
		    NULL, &msg_buf[length], msg_buf_size-length, language, &len,
		    err_code, CLE_INFO_ITEMS, argv)) != OK)
	        {
	            return (status);
	        }
	        length += len;

		if (clerror->callid)
		    msg_buf[length++] = '\n';
	    }

	    if (clerror->callid)    /* look up system error message text */
	    {
                DESCRIPTOR	msg_desc;

    	        msg_desc.desc_length = sizeof(tempbuf) - 1;
	        msg_desc.desc_value = tempbuf;
	        if ((status = cer_sysgetmsg(clerror, &len, &msg_desc, err_code))
		    != OK)
	        {
	            return(status);
	        }

	        argv[0].er_size = argv[1].er_size = argv[2].er_size =
		    ER_PTR_ARGUMENT;

	        argv[0].er_value = (PTR)&clerror->errnum;
	        argv[1].er_value = (PTR)ERNAME((i4) clerror->callid);
	        argv[2].er_value = (PTR)tempbuf;

	        if ((status = ERslookup(ER_UNIXERROR, (CL_ERR_DESC*) NULL,
	                flags & ~ER_TIMESTAMP | ER_TEXTONLY, NULL,
			&msg_buf[length], msg_buf_size - length, language,
			&len,err_code, 3, argv))
		    != OK)
	        {
	            return (status);
	        }
	        length += len;
	    }

	    msg_buf[*msg_length = length] = EOS;
	    return (OK);
        }
    }


    /*
    **	Check if error message file is already opened or not yet. 
    **  First see if the language is initialized.  If not, initialize
    **  it and the message files.
    **	If it is already opened, cer_fndindex function returns the index of
    **	ERmulti table that internal language code is parameter 'language'.
    **  If not yet, it returns '-1'.
    */

    if (cer_issem(&sems))
    {
	if (((sems->sem_type & MU_SEM) ?
	    (*sems->er_p_semaphore)(&sems->er_mu_sem) :
	    (*sems->er_p_semaphore)(1, &sems->er_sem)) != OK)
	{
	    sems = NULL;
	}
    }

    if ((erindex = cer_fndindex(language)) == -1)
    {
	if ((status = cer_nxtindex(language,&erindex)) != OK)
	{   /* Error in initializing the language */
	    if (sems)
	    {
		if (sems->sem_type & MU_SEM)
		    _VOID_ (*sems->er_v_semaphore)(&sems->er_mu_sem);
		else
		    _VOID_ (*sems->er_v_semaphore)(&sems->er_sem);
	    }
	    return (status);
	}
    }

    /*  If the error message file is not opened, open the message file. */

    if (!cer_isopen(erindex,ER_SLOWSIDE))
    {
        if ((status = cer_sinit(language,msg_number,erindex,err_code)) != OK)
        {
	    if (sems)
	    {
		if (sems->sem_type & MU_SEM)
		    _VOID_ (*sems->er_v_semaphore)(&sems->er_mu_sem);
		else
		    _VOID_ (*sems->er_v_semaphore)(&sems->er_sem);
	    }
            return (status);
        }
    }

    /*	If not open then just return. */
    if (!cer_isopen(erindex,ER_SLOWSIDE))
    {
	if (sems)
	{
	    if (sems->sem_type & MU_SEM)
		_VOID_ (*sems->er_v_semaphore)(&sems->er_mu_sem);
	    else
		_VOID_ (*sems->er_v_semaphore)(&sems->er_sem);
	}
	/*
	**  As internal file id is '0', openning file will fail.
	**  In her,return status 'ER_BADOPEN' to show open fail.
	*/
	return (ER_BADOPEN);
    }
	
    /*
    **  Search message string from file and set to buffer.
    **	Error status on system call set to 'err_code'.
    */

    status = cer_sstr(msg_number, sqlstate, tempbuf,
			msg_buf_size - length, erindex, err_code,
			flags & ER_TEXTONLY? ER_GET : ER_LOOKUP);
    if (sems)
    {
	if (sems->sem_type & MU_SEM)
	    _VOID_ (*sems->er_v_semaphore)(&sems->er_mu_sem);
	else
	    _VOID_ (*sems->er_v_semaphore)(&sems->er_sem);
    }

    if (status != OK)
    {
	return (status);
    }

    /*
    **	Format the text with parameters into the callers buffer.
    **  The message is truncated if it will not fit.
    */

    /*  Insert part of name from temporary buffer to buffer */

    status = OK;
    templen = (i4)STlength(tempbuf);
    p_msg_buf = &msg_buf[length];
    p_tempbuf = tempbuf;
    if (!(flags & ER_TEXTONLY))
    {
        while(*p_tempbuf != '\t')
        {
	    CMcpyinc(p_tempbuf,p_msg_buf);
        }
        CMcpyinc(p_tempbuf,p_msg_buf);
    }
    

    /* ============================================ */
    /* Copy text to message substituting arguments. */
    /* -------------------------------------------- */
    /* (But first, declare an exception handler to  */
    /*  catch bad params that may access violate.)  */
    /* ============================================ */

    if (EXdeclare(er_exhandler, &context))
    {
	u_i4	res_len;
	u_i4	bytes_left_in_buf;

	bytes_left_in_buf = (u_i4)(msg_buf_size - (p_msg_buf - msg_buf));
	res_len = STlen( STncpy(p_msg_buf,
   ERx("*** ERslookup() ERROR: Missing or bad parameter for this message. ***"),
	bytes_left_in_buf ));
	p_msg_buf[ bytes_left_in_buf - 1 ] = EOS;
	p_msg_buf += res_len;
	*msg_length = (i4)(p_msg_buf - msg_buf);
	EXdelete();
	return (OK);
    }


    for( ;p_tempbuf - tempbuf < templen; CMnext(p_tempbuf))
    {
        long		number;
        u_long    	unumber;
        double		fnumber;
	i4		i;
	i4		pnum;
 
	if ( (*p_tempbuf != '%') || (flags & ER_NOPARAM) )
	{
	    if ((p_msg_buf - msg_buf) >= msg_buf_size)
		break;
	    CMcpychar(p_tempbuf,p_msg_buf);
	    CMnext(p_msg_buf);
	    continue;
	}
	if (p_tempbuf - tempbuf + 2 >= templen)
	    continue;
	CMnext(p_tempbuf);
	if (*p_tempbuf == '!')
	{
	    if ((p_msg_buf - msg_buf) + 3 >= msg_buf_size)
		continue;
	    CMcpychar(ERx("\r"),p_msg_buf);
	    CMnext(p_msg_buf);
	    CMcpychar(ERx("\n"),p_msg_buf);
	    CMnext(p_msg_buf);
	    CMcpychar(ERx("\t"),p_msg_buf);
	    CMnext(p_msg_buf);
	    continue;
	}
	/*
	** Only works for up to 10 parameters, and makes character set
	** assumptions - should be fixed.
	*/
	if ( *p_tempbuf < '0' || *p_tempbuf > '9' )
	{
	    /* treat any other character as a literal */
	    if ((p_msg_buf - msg_buf) >= msg_buf_size)
		break;
	    if ( *p_tempbuf != '%' )
	    {
	        CMcpychar("%",p_msg_buf);
	        CMnext(p_msg_buf);
	    }
	    CMcpychar(p_tempbuf,p_msg_buf);
	    CMnext(p_msg_buf);
	    continue;
	}
	pnum = *p_tempbuf - '0';
	if (pnum >= num_param)
	{
		EXdelete();
		return(ER_BADPARAM);
	}
	p = &param[pnum];
	CMnext(p_tempbuf);
	switch (*p_tempbuf)
	{
	  case 'd':
	    /* Convert an integer into the buffer with width D_WIDTH */

	    if (p->er_size == ER_PTR_ARGUMENT) /* this is ptr to i4 */
		number = *(i4 *)p->er_value;
	    else if (p->er_size == 0)   /* this is a i4 */
		number = (i4)(SCALARP)p->er_value;
	    else if (p->er_size == 1)
		number = *(i1 *)p->er_value;
	    else if (p->er_size == 2)
		number = *(i2 *)p->er_value;
	    else if (p->er_size == 4)
		number = *(i4 *)p->er_value;
	    else if (p->er_size == 8)
		number = *(i8 *)p->er_value;
	    else
		continue;

	    if (p_msg_buf - msg_buf + D_WIDTH >= msg_buf_size)
	        continue;

	    if (p->er_size == 8)
	    {
	        CVla8(number, p_msg_buf);
	    }
	    else
	    {
	        CVla((i4)number, p_msg_buf);
	    }
	    while (*p_msg_buf)
		CMnext(p_msg_buf);
	    continue;

	  case 'u':
	    /* Convert an integer into the buffer with width D_WIDTH */

	    if (p->er_size == ER_PTR_ARGUMENT) /* this is ptr to u_i4 */
		number = *(u_i4 *)p->er_value;
	    else if (p->er_size == 0)   /* this is a u_i4 */
		number = (u_i4)(SCALARP)p->er_value;
	    else if (p->er_size == 1)
		number = *(u_i1 *)p->er_value;
	    else if (p->er_size == 2)
		number = *(u_i2 *)p->er_value;
	    else if (p->er_size == 4)
		number = *(u_i4 *)p->er_value;
	    else if (p->er_size == 8)
		number = *(u_i8 *)p->er_value;
	    else
		continue;

	    if (p_msg_buf - msg_buf + D_WIDTH >= msg_buf_size)
	        continue;

	    if (p->er_size == 8)
	    {
	        CVula8(number, p_msg_buf);
	    }
	    else
	    {
	        CVula((u_i4)number, p_msg_buf);
	    }
	    while (*p_msg_buf)
		CMnext(p_msg_buf);
	    continue;

	  case 'f':
	  {
	    i2	    res_width;

	    /* Convert a float into the buffer with width F_WIDTH */

	    if (p->er_size == ER_PTR_ARGUMENT) /* Pointer to a double */
		fnumber = *(double *)p->er_value;
	    else if (p->er_size == 4)
		fnumber = *(f4 *)p->er_value;
	    else if (p->er_size == 8)
		fnumber = *(f8 *)p->er_value;
	    else
		continue;

	    if (p_msg_buf - msg_buf + F_WIDTH >= msg_buf_size)
		continue;

	    /* Always convert to 'e' format. */

	    CVfa(fnumber, (i4) 20, (i4) 5, 'e', '.', p_msg_buf, &res_width);
	    p_msg_buf += F_WIDTH;
	    continue;
	  }
	  case 'c':
	    /* Convert a character array into buffer. */

	    if (p->er_value == 0)
		p->er_value = (PTR)ERx("<missing>");
	    if ((p->er_size == 0) || (p->er_size == ER_PTR_ARGUMENT))
	    {
		for (i = 0; ((char *)p->er_value)[i]; i++)
		    ;
		p->er_size = i;
	    }
             
	    if (p_msg_buf - msg_buf + p->er_size >= msg_buf_size)
		continue;

	    if (p->er_size > msg_buf_size - (p_msg_buf - msg_buf))
		p->er_size = (i4)(msg_buf_size - (p_msg_buf - msg_buf));
/*	    p->er_size=STtrmwhite(p_msg_buf);*/
	    MEcopy(p->er_value, p->er_size, p_msg_buf);
	    p->er_size = (i4)STtrmnwhite(p_msg_buf, p->er_size);
	    p_msg_buf += p->er_size;
	    continue;

	  case 'x':
	    /* Convert an integer into the buffer with width D_WIDTH */

	    if (p->er_size == ER_PTR_ARGUMENT)
		unumber = *(u_i4 *)p->er_value;
	    else if (p->er_size == 0)
		unumber = (u_i4)(SCALARP)p->er_value;
	    else if (p->er_size == 1)
		unumber = *(u_i1 *)p->er_value;
	    else if (p->er_size == 2)
		unumber = *(u_i2 *)p->er_value;
	    else if (p->er_size == 4)
		unumber = *(u_i4 *)p->er_value;
	    else if (p->er_size == 8)
		unumber = *(u_i8 *)p->er_value;

	    if (p_msg_buf - msg_buf + X_WIDTH >= msg_buf_size)
		continue;

	    for (i = 8; --i >= 0; )
	    {
		/* {@fix_me@}
		** This is *NOT* machine independent.  This relys on an
		** ASCII-like character set, where the digits '0'-'9' are
		** contiguous and sequential, and the characters 'A'-'F'
		** are contiguous and sequential.  Both ASCII and EBCDIC
		** happen to be this way.
		*/
		if ((*(p_msg_buf + i) = (unumber & 0x0f) + '0') > '9')
		    *(p_msg_buf + i) += 'A' - '9' - 1;
		unumber >>= 4;
	    }
	    p_msg_buf += 8;
	    continue;

	default:
	    continue;
	}
    }
    *msg_length = (i4)(p_msg_buf - msg_buf);
    *p_msg_buf = EOS;
    EXdelete();
    return (OK);
}
Example #15
0
void 
main(int argc, char **argv)
{
	int		i;
	char		buf[MAX_LOC];
	FILE		*fp;
	STATUS		status;
	char		*callstmt;
	i4 		casef;
	char		timestr[512];
	SYSTIME		timeval;
	char		path[512];
	char		drive[2];
	char		current_path[512];

	if (argc < 3)
	{
		SIfprintf(stdout,"Not enough parameters\n");
		PCexit(FAIL);
	}

	/*
	**
	*/
	if (!STbcompare(*++argv, STlength("Net"),
			 "Net", STlength("Net"), casef ))

		callstmt = "@call %II_SYSTEM%\\ingres\\utility\\iisunet";

	else if (!STbcompare(*argv, STlength("Dbms"),
			       "Dbms", STlength("Dbms"), casef ))

		callstmt = "@call %II_SYSTEM%\\ingres\\utility\\iisudbms";

	else if (!STbcompare(*argv, STlength("Star"), 
				"Star", STlength("Star"), casef ))

		callstmt = "@call %II_SYSTEM%\\ingres\\utility\\iisustar";

	else if (!STbcompare(*argv, STlength("Vision"),
				 "Vision", STlength("Vision"), casef ))

		callstmt = "@call %II_SYSTEM%\\ingres\\utility\\iisuabf";

	else if (!STbcompare(*argv, STlength("ESQL"),
				 "ESQL", STlength("ESQL"), casef ))

		callstmt = "@call %II_SYSTEM%\\ingres\\utility\\iisutm";

	else 
		PCexit(FAIL);

	/*
	** 	Set location and file name for the subsequent open.
	*/
	strcpy(path,*++argv);
	strcpy(current_path,*argv+2);
	strcat(path,"\\ingres\\bin\\ipsetup.bat");
	LOfroms(PATH & FILENAME, path, &location);

	
	/*
	** 	Open ipsetup.bat so we can append another line.
	*/
	if ((status = SIopen(&location, "a", &fp)) != OK)
	{
		printf("error opening file\n");
	}

	/*
	** 	Append another line that will call the setup bat files.
	*/
	TMnow(&timeval);
	TMstr(&timeval,&timestr);
	drive[0] = path[0];
	drive[1] = '\0';

	/*
	** Write a statement in the batch file that will set
	** the current drive to the drive passed to us.
	*/
	SIfprintf(fp,"@%s:\n",drive);

	/*
	** Write a statement in the batch file that will set
	** the current path to the path passed to us.
	*/
	SIfprintf(fp,"@cd %s\n",current_path);

	/* 
	** Write a Remark as a primitive log.
	*/
	SIfprintf(fp,"@REM %s installed at %s\n",*argv,timestr);
	
	/*
	** Now write the call statement that will call the appropiate
	** iisu batch file.
	*/
	SIfprintf(fp,"%s\n",callstmt);
}
Example #16
0
DB_STATUS
qel_c0_cre_lnk(
QEF_RCB		*v_qer_p ) 
{
    DB_STATUS		status;
    QEF_CB		*qef_cb = v_qer_p->qef_cb;
    QES_DDB_SES		*dds_p = & v_qer_p->qef_cb->qef_c2_ddb_ses;
    QED_DDL_INFO	*ddl_p = & v_qer_p->qef_r3_ddb_req.qer_d7_ddl_info;
    DD_0LDB_PLUS	*plus_p = & ddl_p->qed_d6_tab_info_p->
			    dd_t9_ldb_p->dd_i2_ldb_plus;
    DD_CAPS		*caps_p = & plus_p->dd_p3_ldb_caps;
    DD_LDB_DESC		ldb,		    /* for replicating LDB desc */
			*ldb_p = & ldb,
			*cdb_p = & dds_p->qes_d4_ddb_p->
			    dd_d3_cdb_info.dd_i1_ldb_desc,
			*ddl_ldb_p = & ddl_p->qed_d6_tab_info_p->
			    dd_t9_ldb_p->dd_i1_ldb_desc;
    QEC_D9_TABLEINFO	tabinfo;	    /* used for table info of link */
    QEC_D2_LDBIDS	ldbids;		    /* used for internal LDB id info */
    QEC_D5_LONG_LDBNAMES
			longnames;	    /* used for excessively long LDB
					    ** name */
    QEC_L16_TABLES	tables;		    /* used for IITABLES-style info */
    QEC_D6_OBJECTS	objects;	    /* used for object info */
    QEC_L6_INDEXES	indexes;
    QEC_MIN_CAP_LVLS	pre_mins,
			aft_mins;
    QEC_LINK		link,		    /* used as global control block */
			*link_p = & link;
    QEQ_1CAN_QRY	del,
			ins,
			sel,
			upd,		    /* used for ordering canned query */
			*upd_p = & upd;
    u_i4		len;
    SYSTIME		now;
    bool		log_ddl_56 = FALSE,
			log_err_59 = FALSE;
    i4		i4_1,
			i4_2;
    QEC_INDEX_ID	ndx_ids[QEK_0MAX_NDX_COUNT + 1];
					    /* working space for index ids */
    RQB_BIND		rq_bind[QEC_CAT_COL_COUNT_MAX + 1];
    QEC_D7_OBJECT_BASE	obj_base,
			*base_p = & obj_base;
    i4			xact_mode;
    char		*cbuf = v_qer_p->qef_cb->qef_trfmt;
    i4			cbufsize = v_qer_p->qef_cb->qef_trsize;

    
    if (ult_check_macro(& qef_cb->qef_trace, QEF_TRACE_DDB_LOG_DDL_56,
	    & i4_1, & i4_2))
    {
        log_ddl_56 = TRUE;
    }
    
    if (ult_check_macro(& qef_cb->qef_trace, QEF_TRACE_DDB_LOG_ERR_59,
	    & i4_1, & i4_2))
    {
        log_err_59 = TRUE;
    }
    sel.qeq_c2_rqf_bind_p = rq_bind;		/* must set up */
    del.qeq_c2_rqf_bind_p = (RQB_BIND *) NULL;
    ins.qeq_c2_rqf_bind_p = (RQB_BIND *) NULL;
    upd.qeq_c2_rqf_bind_p = (RQB_BIND *) NULL;

    /* 1.  set up control block */

    if (dds_p->qes_d7_ses_state == QES_4ST_REFRESH)	
						/* REGISTER WITH REFRESH ? */
	STRUCT_ASSIGN_MACRO(ddl_p->qed_d7_obj_id, tabinfo.d9_1_obj_id);
						/* yes */
    else					/* no */
    {
	tabinfo.d9_1_obj_id.db_tab_base = 0;	/* unknown */
	tabinfo.d9_1_obj_id.db_tab_index = 0;	/* always 0 for non-index */
    }
    link_p->qec_1_ddl_info_p = ddl_p;
    link_p->qec_2_tableinfo_p = & tabinfo;
    link_p->qec_3_ldb_id = 0;			
    link_p->qec_4_col_cnt = 0;
    MEfill(DB_DB_MAXNAME, ' ', link_p->qec_5_ldb_alias);
    link_p->qec_6_select_p = & sel;
    link_p->qec_7_ldbids_p = & ldbids;
    link_p->qec_8_longnames_p = & longnames;
    link_p->qec_9_tables_p = & tables;
    link_p->qec_10_haves = QEC_07_CREATE;
    if (caps_p->dd_c6_name_case == DD_2CASE_UPPER)
	link_p->qec_10_haves |= QEC_06_UPPER_LDB;
    if (caps_p->dd_c1_ldb_caps & DD_7CAP_USE_PHYSICAL_SOURCE)
	link_p->qec_10_haves |= QEC_10_USE_PHY_SRC;
    if (caps_p->dd_c2_ldb_caps & DD_201CAP_DIFF_ARCH)
	link_p->qec_10_haves |= QEC_11_LDB_DIFF_ARCH;

    /* make a copy of the LDB descriptor for non-$ingrs access if necessary */

    if (ddl_ldb_p->dd_l1_ingres_b)
    {
	/* make a copy for non-$ingres access */

	STRUCT_ASSIGN_MACRO(*ddl_ldb_p, ldb);
	ldb_p->dd_l1_ingres_b = FALSE;
	ldb_p->dd_l5_ldb_id = DD_0_IS_UNASSIGNED;
    }
    else
    {	
	/* use provided LDB descriptor but determine if LDB has a long name */

	qed_u0_trimtail(
		ddl_ldb_p->dd_l3_ldb_name, 
		(u_i4) DD_256_MAXDBNAME,
		ldb_p->dd_l3_ldb_name);

	len = STlength(ldb_p->dd_l3_ldb_name);
	if (len > DB_DB_MAXNAME)
	    link_p->qec_10_haves |= QEC_04_LONG_LDBNAME;

	ldb_p = ddl_ldb_p;
    }
    link_p->qec_11_ldb_obj_cnt = 0;
    link_p->qec_12_indexes_p = & indexes;
    link_p->qec_13_objects_p = & objects;
    link_p->qec_15_ndx_cnt = 0;
    link_p->qec_16_ndx_ids_p = ndx_ids;
    link_p->qec_19_ldb_p = ldb_p;
    link_p->qec_20_rqf_bind_p = rq_bind;
    link_p->qec_21_delete_p = & del;
    link_p->qec_22_insert_p = & ins;
    link_p->qec_23_update_p = & upd;

    status = qed_u8_gmt_now(v_qer_p, link_p->qec_24_cur_time);
    if (status)
	return(status);

    link_p->qec_24_cur_time[DD_25_DATE_SIZE] = EOS;
    link_p->qec_25_pre_mins_p = & pre_mins;
    link_p->qec_26_aft_mins_p = & aft_mins;
    link_p->qec_27_select_cnt = 0;
    link_p->qec_28_iistats_cnt = 0;
    
    TMnow(& now);
    link_p->qec_17_ts1 = now.TM_secs;
    link_p->qec_18_ts2 = now.TM_msecs;
    
    /* 2.  inform TPF of update intention on CDB (note that only CREATE does
    **	   LDB retrievals */

    /* 2.1 2PC is required if DDL concurrency is off. */
    if (dds_p->qes_d9_ctl_info & QES_01CTL_DDL_CONCURRENCY_ON)
	xact_mode = QEK_4TPF_1PC;
    else
	xact_mode = QEK_3TPF_UPDATE;

    status = qet_t5_register(v_qer_p, cdb_p, DB_SQL, xact_mode);
    if (status)
	return(status);

    if (log_ddl_56)
    {
	/* display beginning, CDB and LDB info */

	STprintf(cbuf, "\n%s %p: %s REGISTRATION begins%s\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb,
	    IIQE_65_tracing,
	    IIQE_62_3dots);
        qec_tprintf(v_qer_p, cbufsize, cbuf);

	STprintf(cbuf, 
	    "%s %p: ...the CDB:\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
	qed_w1_prt_ldbdesc(v_qer_p, cdb_p);

	STprintf(cbuf, 
	    "%s %p: ...the LDB:\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
	qed_w1_prt_ldbdesc(v_qer_p, ldb_p);

	STprintf(cbuf, "\n");
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    /* 3.  update OBJECT_BASE in II_DD_DB_OBJECT_BASE */

    upd_p->qeq_c1_can_id = UPD_716_DD_DDB_OBJECT_BASE;
    upd_p->qeq_c3_ptr_u.d7_object_base_p = base_p;
    upd_p->qeq_c4_ldb_p = cdb_p;

    status = qel_u1_update(v_qer_p, link_p);
    if (status)
	goto END_TRACING;

    /* 4.  enter phase 1: set up necessary information */

    status = qel_c1_cre_p1(v_qer_p, link_p);
    if (status)
	goto END_TRACING;

    /* 2.  enter phase 2: promote information into STAR catalogs */

    status = qel_c2_cre_p2(v_qer_p, link_p);
    if (status)
	v_qer_p->qef_cb->qef_abort = TRUE;

END_TRACING:

    if (log_ddl_56)
    {
	/* display end tracing message */

	STprintf(cbuf, 
	    "%s %p: %s REGISTRATION ends\n\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb,
	    IIQE_65_tracing);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }

    return(status);
}    
Example #17
0
DB_STATUS
qeu_d6_cre_view(
QEF_CB          *qef_cb,
QEUQ_CB		*i_quq_p)
{
    DB_STATUS		status,
			sav_status = E_DB_OK;
    DB_ERROR		sav_error;
    QEF_RCB		qer,
			*qer_p = & qer;
    QES_DDB_SES		*dds_p = & qef_cb->qef_c2_ddb_ses;
    QED_DDL_INFO	*ddl_p = & qer_p->qef_r3_ddb_req.qer_d7_ddl_info;
    DD_LDB_DESC		*cdb_p = & dds_p->qes_d4_ddb_p->
			    dd_d3_cdb_info.dd_i1_ldb_desc;
    QEC_L16_TABLES	tables;		    /* used for IITABLES-style info */
    QEC_D6_OBJECTS	objects;	    /* used for object info */
    QEC_LINK		link,		    /* used as global control block */
			*lnk_p = & link;
    QEQ_1CAN_QRY	ins,
			sel,
			upd;		    /* used for ordering canned query */
    RQB_BIND		rq_bind[QEC_CAT_COL_COUNT_MAX + 1];
    QEP_PTR_UNION	ptr_u;
    DMU_CB		*dmu_p;
    SYSTIME		now;
    bool		xact_b = FALSE;		/* assume no begin transaction 
						*/
    i4			xact_mode;

    
    ptr_u.qep_ptr_u.qep_1_ptr = i_quq_p->qeuq_dmf_cb;
    dmu_p = ptr_u.qep_ptr_u.qep_3_dmu_cb_p;

    /* 1.  check input information */

    if (i_quq_p->qeuq_type != QEUQCB_CB 
	||
        i_quq_p->qeuq_length != sizeof(*i_quq_p))
    {
	i_quq_p->error.err_code = E_QE0017_BAD_CB;
	return(E_DB_ERROR);
    }

    if ((i_quq_p->qeuq_cq == 0 || i_quq_p->qeuq_qry_tup == 0)
        || 
	(i_quq_p->qeuq_ct == 0 || i_quq_p->qeuq_tre_tup == 0)
        || 
	(i_quq_p->qeuq_db_id == 0)
        || 
	(i_quq_p->qeuq_d_id == 0)
        || 
	(i_quq_p->qeuq_dmf_cb == 0))
    {
	i_quq_p->error.err_code = E_QE0018_BAD_PARAM_IN_CB;
	return(E_DB_ERROR);
    }

    /* 2.  set up control information */

    MEfill(sizeof(qer), '\0', (PTR) & qer);
    qer_p->qef_cb = qef_cb;
    qer_p->error.err_code = 0;
    qer_p->qef_r3_ddb_req.qer_d13_ctl_info = QEF_00DD_NIL_INFO;
    qef_cb->qef_rcb = qer_p;

    MEcopy(dmu_p->dmu_table_name.db_tab_name, 
	sizeof(ddl_p->qed_d1_obj_name),
	ddl_p->qed_d1_obj_name);
    MEcopy(dmu_p->dmu_owner.db_own_name, 
	sizeof(ddl_p->qed_d2_obj_owner),
	ddl_p->qed_d2_obj_owner);
    ddl_p->qed_d3_col_count = i_quq_p->qeuq_ano;
    ddl_p->qed_d4_ddb_cols_pp = NULL;
    ddl_p->qed_d5_qry_info_p = NULL;
    ddl_p->qed_d6_tab_info_p = NULL;
    ddl_p->qed_d7_obj_id.db_tab_base = 0;
    ddl_p->qed_d7_obj_id.db_tab_index = 0;
    ddl_p->qed_d9_reg_info_p = NULL;

    sel.qeq_c2_rqf_bind_p = rq_bind;		/* must set up */
    ins.qeq_c2_rqf_bind_p = (RQB_BIND *) NULL;
    upd.qeq_c2_rqf_bind_p = (RQB_BIND *) NULL;
    
    lnk_p->qec_1_ddl_info_p = ddl_p;
    lnk_p->qec_2_tableinfo_p = NULL;
    lnk_p->qec_3_ldb_id = 0;			
    lnk_p->qec_4_col_cnt = 0;
    MEfill(DB_DB_MAXNAME, ' ', lnk_p->qec_5_ldb_alias);
    lnk_p->qec_6_select_p = & sel;
    lnk_p->qec_7_ldbids_p = NULL;
    lnk_p->qec_8_longnames_p = NULL;
    lnk_p->qec_9_tables_p = & tables;
    lnk_p->qec_10_haves = QEC_07_CREATE;
    lnk_p->qec_11_ldb_obj_cnt = 0;
    lnk_p->qec_12_indexes_p = NULL;
    lnk_p->qec_13_objects_p = & objects;
    lnk_p->qec_15_ndx_cnt = 0;
    lnk_p->qec_16_ndx_ids_p = NULL;
    lnk_p->qec_19_ldb_p = NULL;
    lnk_p->qec_20_rqf_bind_p = rq_bind;
    lnk_p->qec_21_delete_p = NULL;
    lnk_p->qec_22_insert_p = & ins;
    lnk_p->qec_23_update_p = & upd;

    status = qed_u8_gmt_now(qer_p, lnk_p->qec_24_cur_time);
    if (status)
    {
	STRUCT_ASSIGN_MACRO(qer_p->error, i_quq_p->error);
	return(status);
    }
    lnk_p->qec_24_cur_time[DD_25_DATE_SIZE] = EOS;

    lnk_p->qec_25_pre_mins_p = NULL;
    lnk_p->qec_26_aft_mins_p = NULL;
    
    TMnow(& now);
    lnk_p->qec_17_ts1 = now.TM_secs;
    lnk_p->qec_18_ts2 = now.TM_msecs;

    /* transaction semantics
    **	 
    **	  1.	pre-processing: 
    **	    
    **		1.1  if no outstanding transaction, begin a transaction 
    **		     and set xact_b to TRUE;
    **		1.2  if not in auto-commit mode, escalate transaction to MST;
    **
    **	  2.	post-processing:
    **	    
    **		2.1  if processing terminates normally, commit transaction
    **		     only if xact_b is TRUE and not in auto-commit mode;
    **		2.2  if processing terminates abnormally, abort transaction
    **		     only if xact_b is TRUE;
    */

    /* 2.  begin a transaction if necessary */

    if (qef_cb->qef_stat == QEF_NOTRAN)
    {
	status = qet_begin(qef_cb);
	if (status)
	    return(status);

	xact_b = TRUE;
    }

    if (qef_cb->qef_auto == QEF_OFF)
	qef_cb->qef_stat = QEF_MSTRAN;		/* escalate to MST */

    /* 3.  inform TPF of read intention on CDB */

    status = qet_t5_register(qer_p, cdb_p, DB_SQL, QEK_2TPF_READ);
    if (status)
    {
	if (! xact_b)
	{
	    STRUCT_ASSIGN_MACRO(qer_p->error, i_quq_p->error);
	    return(status);
	
	    /* ok to return */
	}

	/* fall thru to terminate SST */
    }

    if (status == E_DB_OK)
    {
	/*  4.  set up new object base, query id */

	status = qeu_10_get_obj_base(qer_p, lnk_p);
	if (status)
	{
	    if (! xact_b)
	    {
		STRUCT_ASSIGN_MACRO(qer_p->error, i_quq_p->error);
		return(status);

		/* ok to return */
	    }
	
	    /* fall thru to terminate SST */
	}
	else
	{
	    objects.d6_4_qry_id.db_qry_high_time = now.TM_secs;
	    objects.d6_4_qry_id.db_qry_low_time = now.TM_msecs;
	}
    }    
 
    if (status == E_DB_OK)
    {
	/*  5.  inform TPF of update intention on CDB */

	/*  5.1 2PC is required if DDL concurrency is off. */
	if (dds_p->qes_d9_ctl_info & QES_01CTL_DDL_CONCURRENCY_ON)
	    xact_mode = QEK_4TPF_1PC;
	else
	    xact_mode = QEK_3TPF_UPDATE;

	status = qet_t5_register(qer_p, cdb_p, DB_SQL, xact_mode);
	if (status)
	{
	    if (! xact_b)
	    {
		STRUCT_ASSIGN_MACRO(qer_p->error, i_quq_p->error);
		return(status);

		/* ok to return */
	    }
	    
	    /* fall thru to terminate SST */
	}
    }

    if (status == E_DB_OK)
    {
	/*  6.  update IIDD_DDB_OBJECT_BASE */	

	status = qeu_11_object_base(qer_p, lnk_p);
	if (status)
	    qef_cb->qef_abort = TRUE;
    }

    if (status == E_DB_OK)
    {
	/*  7.  update IIDD_DDB_OBJECTS */	

	status = qeu_12_objects(qer_p, lnk_p);
	if (status)
	    qef_cb->qef_abort = TRUE;
    }

    if (status == E_DB_OK)
    {
	/*  8.  update IIDD_IITABLES */	

	status = qeu_13_tables(qer_p, i_quq_p, lnk_p);
	if (status)
	    qef_cb->qef_abort = TRUE;
    }

    if (status == E_DB_OK)
    {
	/*  9.  update IIDD_COLUMNS */	

	status = qeu_14_columns(qer_p, i_quq_p, lnk_p);
	if (status)
	    qef_cb->qef_abort = TRUE;
    }

    if (status == E_DB_OK)
    {
	/*  10.  update IIDD_VIEWS */	

	status = qeu_15_views(qer_p, i_quq_p, lnk_p);
	if (status)
	    qef_cb->qef_abort = TRUE;
    }

    if (status == E_DB_OK)
    {
	/*  11.  update IIDD_DDB_TREE */	

	status = qeu_16_tree(qer_p, i_quq_p, lnk_p);
	if (status)
	    qef_cb->qef_abort = TRUE;
    }

    if (status == E_DB_OK)
    {
	/*  12.  update IIDD_DDB_DDB_DBDEPENDS */	

	status = qeu_17_dbdepends(qer_p, i_quq_p, lnk_p);
	if (status)
	    qef_cb->qef_abort = TRUE;
    }

    /* 13.  end transaction if necessary */

    if (status)
    {
	/* error condition */

	sav_status = status;
	STRUCT_ASSIGN_MACRO(qer_p->error, sav_error);
	if (xact_b  || qef_cb->qef_abort)	/* SST or abort */
	    status = qet_abort(qef_cb);
    }
    else
    {
	/* ok condition */

	if (xact_b && qef_cb->qef_auto == QEF_ON)		
	    status = qet_commit(qef_cb);	/* commit SST */
	else
	{
	    /* send message to commit CDB association to avoid deadlocks */

	    status = qed_u11_ddl_commit(qef_cb->qef_rcb);
	}
    }
    
    if (sav_status)
    {
	/* returned saved error */
    
	STRUCT_ASSIGN_MACRO(sav_error, i_quq_p->error);
	return(sav_status);
    }
    else if (status)
    {
	/* return qef_cb error */

	STRUCT_ASSIGN_MACRO(qef_cb->qef_rcb->error, i_quq_p->error);
	return(status);
    }
    return(E_DB_OK);
}    
Example #18
0
DB_STATUS
qee_d2_tmp(
    QEF_RCB		*qef_rcb,
    QEE_DSH		*dsh,
    ULM_RCB		*ulm)
{
    DB_STATUS	    status = E_DB_OK;
    QEF_QP_CB	    *qp_p = dsh->dsh_qp_ptr;
    QEQ_DDQ_CB	    *ddq_p = & qp_p->qp_ddq_cb;
    QEE_DDB_CB	    *qee_p = dsh->dsh_ddb_cb;
    DB_CURSOR_ID    *csr_p;


    if (ddq_p->qeq_d3_elt_cnt > 0)
    {
        SYSTIME	    tm_now,
                    tm_last;
        char	    hi_ascii[QEK_015_LEN],
                    lo_ascii[QEK_015_LEN],
                    /*
                    		    pid_ascii[QEK_015_LEN],
                    */
                    temp[QEK_050_LEN+DB_MAXNAME];/* must be > DB_MAXNAME */
        DD_TAB_NAME    *name_p;
        i4	    *long_p;
        /*
        	PID	    pid;		** an i4 **
        */
        i4	    m, n;
        char	    *p, *q;
        u_i2	    hi_len,
                    /*
                    		    lo_len,
                    */
                    tmp_len;

#define	QEE_10SQL_NAME_LEN    10


        /* allocate space for array of temporary-table names and
        ** generate their names */

        /* 1.  allocate array for DD_TAB_NAMEs */

        ulm->ulm_psize = ddq_p->qeq_d3_elt_cnt * sizeof(DD_TAB_NAME);
        if (status = qec_malloc(ulm))
        {
            qef_rcb->error.err_code = ulm->ulm_error.err_code;
            qed_u10_trap();
            return(status);
        }

        qee_p->qee_d1_tmp_p = (DD_TAB_NAME *) ulm->ulm_pptr;
        /* ptr to array of DD_TAB_NAMEs */
        /* 2.  allocate array for i4 status */

        ulm->ulm_psize = ddq_p->qeq_d3_elt_cnt * sizeof(i4);
        if (status = qec_malloc(ulm))
        {
            qef_rcb->error.err_code = ulm->ulm_error.err_code;
            qed_u10_trap();
            return(status);
        }

        qee_p->qee_d2_sts_p = (i4 *)
                              ulm->ulm_pptr; 	/* ptr to array of i4s */

        /* initialize both allocated arrays */

        name_p = qee_p->qee_d1_tmp_p;
        long_p = qee_p->qee_d2_sts_p;

        tm_last.TM_secs = 0;
        tm_last.TM_msecs = 0;
        /*
        	PCpid(& pid);		** get process (server) id **
        	CVla(pid, pid_ascii);	** convert to ascii **
        */
        for (n = 0; n < ddq_p->qeq_d3_elt_cnt; n++)
        {
            /* 3.  generate temporary table name */

            TMnow(& tm_now);

            if (tm_now.TM_secs == tm_last.TM_secs)
            {
                if (tm_now.TM_msecs <= tm_last.TM_msecs)
                    tm_now.TM_msecs = tm_last.TM_msecs + 1;
            }
            CVla(tm_now.TM_secs, hi_ascii);
            CVla(tm_now.TM_msecs, lo_ascii);

            hi_len = STlength(hi_ascii);

            /* transpose the hi_ascii string to get lower digits */

            p = hi_ascii;
            q = hi_ascii + hi_len - 1;		/* backup past EOS */
            for (m = 0; m < (i4) hi_len - 1; m++)	/* do length - 1 characters */
            {
                *p = *q;
                p++;
                q--;
            }

            STpolycat((i4) 3,	/* 3 constituent pieces */
                      "z", lo_ascii, hi_ascii, temp);

            tmp_len = STlength(temp);

            /* use at most 10 characters */

            if (tmp_len > QEE_10SQL_NAME_LEN)
                tmp_len = QEE_10SQL_NAME_LEN;

            MEmove(tmp_len, temp, ' ', sizeof(DD_TAB_NAME),
                   (char *)name_p);

            STRUCT_ASSIGN_MACRO(tm_now, tm_last);
            /* save for comparison */
            name_p++;		/* pt to next slot */

            /* 4.  initialize status word for this table */

            *long_p = QEE_00M_NIL;
            long_p++;		/* pt to next status word */
        } /* for */
    }
    else
    {
        qee_p->qee_d1_tmp_p = (DD_TAB_NAME *) NULL;
        qee_p->qee_d2_sts_p = (i4 *) NULL;
    }

    /* 5.  initialize */

    qee_p->qee_d3_status = QEE_00Q_NIL;

    if (! (qp_p->qp_status & QEQP_RPT))
    {
        /* initialize if not repeat query */

        csr_p = & qee_p->qee_d4_given_qid;
        csr_p->db_cursor_id[0] = 0;
        csr_p->db_cursor_id[1] = 0;
        MEfill(DB_CURSOR_MAXNAME, ' ', (PTR) csr_p->db_cur_name);
    }

    csr_p = & qee_p->qee_d5_local_qid;
    csr_p->db_cursor_id[0] = 0;
    csr_p->db_cursor_id[1] = 0;
    MEfill(DB_CURSOR_MAXNAME, ' ', (PTR) csr_p->db_cur_name);

    return(status);
}
Example #19
0
DB_STATUS
qeu_csecalarm(
QEF_CB          *qef_cb,
QEUQ_CB		    *qeuq_cb)
{
    DB_IIQRYTEXT	*qtuple;	/* Alarm text */
    DB_SECALARM    	*atuple;	/* New alarm tuple */
    DB_SECALARM    	atuple_temp;	/* Tuple to check for uniqueness */
    DB_STATUS	    	status, local_status;
    i4	    	error=0;
    bool	    	transtarted = FALSE;	    
    bool	    	tbl_opened = FALSE;
    i4		    	i;		/* Querytext tuple counter */
    QEF_DATA	    	*next;		/*	     and data pointer       */
    QEU_CB	    	tranqeu;
    QEU_CB	    	qeu;
    QEU_QUAL_PARAMS	qparams;
    DB_QRY_ID	    	qryid;		/* Ids for query text */
    QEF_DATA	    	qef_data;
    bool		loop=FALSE;
    QEF_RCB		qef_rcb;
    i4		number;
    DMR_ATTR_ENTRY  	akey_array[3];
    DMR_ATTR_ENTRY  	*akey_ptr_array[3];
    DMT_CHAR_ENTRY  	char_spec;	/* DMT_ALTER specification */
    DMT_CB	    	dmt_cb;
    DB_ERROR 		e_error;
    SXF_ACCESS		access;
    SXF_EVENT		evtype;
    DB_OWN_NAME		objowner;

    do
    {
	MEfill(sizeof(objowner),' ',(PTR)&objowner);

	/* Validate CB and parameters */
	if (qeuq_cb->qeuq_type != QEUQCB_CB ||
            qeuq_cb->qeuq_length != sizeof(QEUQ_CB))	
	{
	    status = E_DB_ERROR;
	    error = E_QE0017_BAD_CB;
	    break;
	}
	if (   qeuq_cb->qeuq_cq == 0 || qeuq_cb->qeuq_qry_tup == NULL
            || ( qeuq_cb->qeuq_uld_tup == NULL)
            || (qeuq_cb->qeuq_db_id == NULL)
            || (qeuq_cb->qeuq_d_id == 0))
	{
	    status = E_DB_ERROR;
	    error = E_QE0018_BAD_PARAM_IN_CB;
	    break;
	}
        qef_rcb.qef_cb = qef_cb;
        qef_rcb.qef_db_id = qeuq_cb->qeuq_db_id;
        qef_cb->qef_dbid = qeuq_cb->qeuq_db_id;
		
	/* 
	** Check to see if transaction is in progress, if so set a local
	** transaction, otherwise we'll use the user's transaction.
	*/
	if (qef_cb->qef_stat == QEF_NOTRAN)
	{
	    tranqeu.qeu_type = QEUCB_CB;
	    tranqeu.qeu_length = sizeof(QEUCB_CB);
	    tranqeu.qeu_db_id = qeuq_cb->qeuq_db_id;
	    tranqeu.qeu_d_id = qeuq_cb->qeuq_d_id;
	    tranqeu.qeu_flag = 0;
	    tranqeu.qeu_mask = 0;
	    status = qeu_btran(qef_cb, &tranqeu);
	    if (status != E_DB_OK)
	    {	
		error = tranqeu.error.err_code;
		break;	
	    }	    
	    transtarted = TRUE;
	}
	/* Escalate the transaction to MST */
	if (qef_cb->qef_auto == QEF_OFF)
	    qef_cb->qef_stat = QEF_MSTRAN;

	atuple = (DB_SECALARM *)qeuq_cb->qeuq_uld_tup->dt_data;

        /* For  database alarms, make sure the database exists */
	if(atuple->dba_objtype==DBOB_DATABASE &&
	   !(atuple->dba_flags&DBA_ALL_DBS))
	{
	    status=qeu_db_exists(qef_cb, qeuq_cb, 
		(DB_DB_NAME *)&atuple->dba_objname, SXF_A_CONTROL, &objowner);
	    if(status==E_DB_ERROR)
	    {
		/* Error checking database name */
		break;
	    }
	    else  if  (status==E_DB_WARN)
	    {
		/* Database not found */
		status=E_DB_ERROR;
		/* E_US2474_9332_ALARM_NO_DB */
	        (VOID)qef_error(9332, 0L, E_DB_ERROR,
			    &error, &qeuq_cb->error, 1,
			    qec_trimwhite(sizeof(atuple->dba_objname),
					  (char *)&atuple->dba_objname),
			    (PTR)&atuple->dba_objname);
		break;
	    }
	}
	else if(atuple->dba_objtype==DBOB_TABLE)
	{
	    /* 
            ** Alter the table relstat to flag alarms exist. This validates that
            ** the table exists and ensures that we get an exclusive lock on it.
            */
	    char_spec.char_id = DMT_C_ALARM;      /* create alarm code */
	    char_spec.char_value = DMT_C_ON;
	    MEfill(sizeof(DMT_CB), 0, (PTR) &dmt_cb);
	    dmt_cb.dmt_flags_mask = 0;
	    dmt_cb.dmt_db_id = qeuq_cb->qeuq_db_id;
	    dmt_cb.dmt_char_array.data_in_size = sizeof(DMT_CHAR_ENTRY);
	    dmt_cb.dmt_char_array.data_address = (PTR)&char_spec;
	    dmt_cb.length = sizeof(DMT_CB);
	    dmt_cb.type = DMT_TABLE_CB;
	    dmt_cb.dmt_id.db_tab_base  = atuple->dba_objid.db_tab_base;
	    dmt_cb.dmt_id.db_tab_index = atuple->dba_objid.db_tab_index;
	    dmt_cb.dmt_tran_id = qef_cb->qef_dmt_id;
	    status = dmf_call(DMT_ALTER, &dmt_cb);
	    if (status != E_DB_OK)
    	    {
	        error = dmt_cb.error.err_code;
	        break;
	    }
	}
	/* Get a unique query id */
	TMnow((SYSTIME *)&qryid);
	atuple->dba_txtid.db_qry_high_time = qryid.db_qry_high_time;
	atuple->dba_txtid.db_qry_low_time  = qryid.db_qry_low_time;

	/* Get a unique alarm id */
        
        status = qea_reserveID(&atuple->dba_alarmid, 
			qef_cb, &qef_rcb.error);

	if (status != E_DB_OK)
	{   
		error = qef_rcb.error.err_code;  
		break; 
	}
	/*
	** Generate an alarm name if needed, all blanks indicates no
	** name specified. This is required for uniqueness check below.
	*/
	if(!STskipblank( (char*)&atuple->dba_alarmname, 
				sizeof(atuple->dba_alarmname)))
	{
		status=qeu_gen_alarm_name(
			atuple->dba_objtype,
			(char*)&atuple->dba_objname,
			&qef_rcb,
			&atuple->dba_alarmid,
			(char*)&atuple->dba_alarmname,
			&error);
		if(status!=E_DB_OK)
			break;
	}
	/* Validate that the alarm name is unique */
	qeu.qeu_type = QEUCB_CB;
        qeu.qeu_length = sizeof(QEUCB_CB);
        qeu.qeu_tab_id.db_tab_base  = DM_B_IISECALARM_TAB_ID;
        qeu.qeu_tab_id.db_tab_index  = DM_I_IISECALARM_TAB_ID;
        qeu.qeu_db_id = qeuq_cb->qeuq_db_id;
        qeu.qeu_lk_mode = DMT_IX;
        qeu.qeu_flag = DMT_U_DIRECT;
        qeu.qeu_access_mode = DMT_A_WRITE;
	qeu.qeu_mask = 0;
	status = qeu_open(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = TRUE;
	atuple->dba_alarmno=0;

	/* Retrieve the same named alarm - if not there then ok */
	qeu.qeu_count = 1;
        qeu.qeu_tup_length = sizeof(DB_SECALARM);
	qeu.qeu_output = &qef_data;
	qef_data.dt_next = NULL;
        qef_data.dt_size = sizeof(DB_SECALARM);
        qef_data.dt_data = (PTR)&atuple_temp;
	qeu.qeu_getnext = QEU_REPO;
	qeu.qeu_klen = 0;				/* Not keyed */
	qparams.qeu_qparms[0] = (PTR) atuple;	/* What we're looking for */
	qeu.qeu_qual = qeu_qalarm_by_name;
	qeu.qeu_qarg = &qparams;
	status = qeu_get(qef_cb, &qeu);
	if (status == E_DB_OK)		/* Found the same alarm! */
	{
	    (VOID)qef_error(E_US2472_9330_ALARM_EXISTS, 0L, E_DB_ERROR,
			    &error, &qeuq_cb->error, 1,
			    qec_trimwhite(sizeof(atuple->dba_alarmname),
					  (char *)&atuple->dba_alarmname),
			    (PTR)&atuple->dba_alarmname);
	    error = E_QE0025_USER_ERROR;
	    break;
	}
	if (qeu.error.err_code != E_QE0015_NO_MORE_ROWS)
	{
	    /* Some other error */
	    error = qeu.error.err_code;
	    break;
	}
	status = qeu_close(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened=FALSE;
	/*
	** Generate a unique alarm number. This is primarily for
	** backwards compatibility with "anonymous" alarms which had
	** to be dropped by number, not name.
	*/
	
	status = qeu_open(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = TRUE;
	qeu.qeu_count = 1;
        qeu.qeu_tup_length = sizeof(DB_SECALARM);
	qeu.qeu_input = &qef_data;
	qeu.qeu_output = &qef_data;
	qef_data.dt_next = 0;
        qef_data.dt_size = sizeof(DB_SECALARM);
        qef_data.dt_data = (PTR) &atuple_temp;
	
	qeu.qeu_getnext = QEU_REPO;
	qeu.qeu_klen = 3;       
	qeu.qeu_key = akey_ptr_array;
	akey_ptr_array[0] = &akey_array[0];
	akey_ptr_array[1] = &akey_array[1];
	akey_ptr_array[2] = &akey_array[2];

	akey_ptr_array[0]->attr_number = DM_1_IISECALARM_KEY;
	akey_ptr_array[0]->attr_operator = DMR_OP_EQ;
	akey_ptr_array[0]->attr_value = (char*) &atuple->dba_objtype;

	akey_ptr_array[1]->attr_number = DM_2_IISECALARM_KEY;
	akey_ptr_array[1]->attr_operator = DMR_OP_EQ;
	akey_ptr_array[1]->attr_value = (char*) &atuple->dba_objid.db_tab_base;
        
	akey_ptr_array[2]->attr_number = DM_3_IISECALARM_KEY;
	akey_ptr_array[2]->attr_operator = DMR_OP_EQ;
	akey_ptr_array[2]->attr_value = (char*) &atuple->dba_objid.db_tab_index;
        
	qeu.qeu_qual = 0;
	qeu.qeu_qarg = 0;
     
	/* 
        ** Get all alarm tuples for this object
        ** and determine the next alarm number.
        */
	status = E_DB_OK;
	number = 0;
	while (status == E_DB_OK)
	{
            status = qeu_get(qef_cb, &qeu);
	    if (status != E_DB_OK)
	    {
		error = qeu.error.err_code;
		break;
	    }
	    qeu.qeu_getnext = QEU_NOREPO;
            qeu.qeu_klen = 0;
	    if (atuple_temp.dba_alarmno > number)
                number = atuple_temp.dba_alarmno;
	}
	if (error != E_QE0015_NO_MORE_ROWS)
	    break;
 
	/* 
        ** We have to add 1 to derive the next alarm number.
	*/
	atuple->dba_alarmno=number+1;

	/* Save the alarm tuple */
	status = E_DB_OK;
		
	/* Insert single alarm tuple */
	qeu.qeu_count = 1;
        qeu.qeu_tup_length = sizeof(DB_SECALARM);
	qeu.qeu_input = qeuq_cb->qeuq_uld_tup;
	status = qeu_append(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	status = qeu_close(qef_cb, &qeu);    
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = FALSE;

	/* Update all query text tuples with query id - validate list */
	next = qeuq_cb->qeuq_qry_tup;
	for (i = 0; i < qeuq_cb->qeuq_cq; i++)
	{
	    qtuple = (DB_IIQRYTEXT *)next->dt_data;
	    next = next->dt_next;
	    qtuple->dbq_txtid.db_qry_high_time = qryid.db_qry_high_time;
	    qtuple->dbq_txtid.db_qry_low_time  = qryid.db_qry_low_time;
	    if (i < (qeuq_cb->qeuq_cq -1) && next == NULL)
	    {
		error = E_QE0018_BAD_PARAM_IN_CB;
		status = E_DB_ERROR;
		break;
	    }
	} /* for all query text tuples */
	if (status != E_DB_OK)
	    break;

	/* Insert all query text tuples */
	qeu.qeu_tab_id.db_tab_base = DM_B_QRYTEXT_TAB_ID;
	qeu.qeu_tab_id.db_tab_index = 0L;
	status = qeu_open(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = TRUE;
	qeu.qeu_count = qeuq_cb->qeuq_cq;
        qeu.qeu_tup_length = sizeof(DB_IIQRYTEXT);
	qeu.qeu_input = qeuq_cb->qeuq_qry_tup;
	status = qeu_append(qef_cb, &qeu);
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	status = qeu_close(qef_cb, &qeu);    
	if (status != E_DB_OK)
	{
	    error = qeu.error.err_code;
	    break;
	}
	tbl_opened = FALSE;
	
	if (transtarted)		   /* If we started a transaction */
	{
	    status = qeu_etran(qef_cb, &tranqeu);
	    if (status != E_DB_OK)
	    {
		error = tranqeu.error.err_code;
		break;
	    }
	}
    }
    while(loop);

    /* call qef_error to handle error messages */
    if(error)
	    (VOID) qef_error(error, 0L, status, &error, &qeuq_cb->error, 0);
    
    /* Close off all the tables. */
    local_status = E_DB_OK;
    if (tbl_opened)		    /* If system table opened, close it */
    {
	local_status = qeu_close(qef_cb, &qeu);
	if (local_status != E_DB_OK)
	{
	    (VOID) qef_error(qeu.error.err_code, 0L, local_status, &error, 
		    	     &qeuq_cb->error, 0);
	    if (local_status > status)
		status = local_status;
	}
    }

    if (transtarted)		   /* If we started a transaction */
    {
        local_status = qeu_atran(qef_cb, &tranqeu);
        if (local_status != E_DB_OK)
	{
	    (VOID) qef_error(tranqeu.error.err_code, 0L, local_status, 
			     &error, &qeuq_cb->error, 0);
	    if (local_status > status)
		status = local_status;
	}
    }
  
    if ( Qef_s_cb->qef_state & QEF_S_C2SECURE )
    {
	if(atuple->dba_objtype==DBOB_DATABASE)
	{
	    evtype=SXF_E_DATABASE;
	}
	else
	{
	    evtype=SXF_E_TABLE;
	}
	/*
	** Creating an alarm is a control operation on the base object
	** (database/table)
	*/
	if(status==E_DB_OK)
	    access=(SXF_A_CONTROL|SXF_A_SUCCESS);
	else
	    access=(SXF_A_CONTROL|SXF_A_FAIL);
	if(qeu_secaudit(FALSE, qef_cb->qef_ses_id,
		    (char *)&atuple->dba_objname,
		    &objowner,
		    sizeof(atuple->dba_objname),
		    evtype,
		    I_SX202D_ALARM_CREATE,
		    access,
		    &e_error)!=E_DB_OK)
	{
		error = e_error.err_code;
		status=E_DB_ERROR;
	}
    }

    /*
    ** Log QEF create error
    */
    if(status!=E_DB_OK)
    {
    	(VOID) qef_error(E_QE028B_CREATE_ALARM_ERR, 0L, local_status, 
		     &error, &qeuq_cb->error, 0);
	qeuq_cb->error.err_code= E_QE0025_USER_ERROR;
    }
    return (status);
} /* qeu_csecalarm */
Example #20
0
/*{
** Name: psy_dpermit	- Define a permit.
**
**  INTERNAL PSF call format: status = psy_dpermit(&psy_cb, sess_cb);
**
**  EXTERNAL call format:     status = psy_call(PSY_DPERMIT, &psy_cb, sess_cb);
**
** Description:
**	Given all of the parameters necessary to CREATE/DEFINE a permit on a
**	table or view, this function will store the permission in the system
**	catalogs.  This will include storing the query tree in the tree table,
**	storing the text of the query in the iiqrytext table (really done by
**	QEF), storing a row in the protect table, and issuing an "alter table"
**	operation to DMF to indicate that there are permissions on the given
**	table.
**
** Inputs:
**      psy_cb
**	    .psy_qrytext		Id of query text as stored in QSF.
**	    .psy_cols[]			Array of columns on which to grant
**					permission
**	    .psy_numcols		Number of columns listed above; 0 means
**					give permission on all columns
**          .psy_intree                 QSF id of query tree representing the
**					where clause in the permit
**          .psy_opctl                  Bit map of defined   operations
**          .psy_opmap                  Bit map of permitted operations
**          .psy_user                   Name of user who will get permission
**          .psy_terminal               Terminal at which permission is given
**					(blank if none specified)
**          .psy_timbgn                 Time of day at which the permission
**					begins (minutes since 00:00)
**          .psy_timend                 Time of day at which the permission ends
**					(minutes since 00:00)
**          .psy_daybgn                 Day of week at which the permission
**					begins (0 = Sunday)
**          .psy_dayend                 Day of week at which the permission ends
**					(0 = Sunday)
**	    .psy_grant
**		PSY_CPERM		CREATE/DEFINE PERMIT
**	    .psy_tblq			head of table queue
**	    .psy_colq			head of column queue
**	    .psy_usrq			head of user queue
**	    .psy_qlen			length of first iiqrytext
**	    .psy_flags			useful info
**		PSY_EXCLUDE_COLUMNS	user specified a list of columns to
**					which privilege should not apply
**	sess_cb				Pointer to session control block
**					(Can be NULL)
**
** Outputs:
**      psy_cb
**          .psy_txtid                  Id of query text as stored in the
**					iiqrytext system relation.
**	    .psy_error			Filled in if error happens
**	Returns:
**	    E_DB_OK			Function completed normally.
**	    E_DB_WARN			Function completed with warning(s);
**	    E_DB_ERROR			Function failed; non-catastrophic error
**	    E_DB_FATAL			Function failed; catastrophic error
**	Exceptions:
**	    none
**
** Side Effects:
**	    Stores text of query in iiqrytext relation, query tree in tree
**	    relation, row in protect relation identifying the permit.  Does
**	    an alter table DMF operation to indicate that there are permissions
**	    on the table.
**
** History:
**	02-oct-85 (jeff)
**          written
**      03-sep-86 (seputis)
**          changed some psy_cb. to psy_cb->
**          added .db_att_id reference
**          changed rdr_cb. rdr_cb->
**	02-dec-86 (daved)
**	    bug fixing. check for permit on tables owned by user and not
**	    view.
**	29-apr-87 (stec)
**	    Implemented changes for GRANT statement.
**	10-may-88 (stec)
**	    Make changes for db procs.
**	03-oct-88 (andre)
**	    Modified call to pst_rgent to pass 0 as a query mode since it is
**	    clearly not PSQ_DESTROY
**	06-feb-89 (ralph)
**	    Added support for 300 attributes:
**		Use DB_COL_BITS in place of DB_MAX_COLS
**		Loop over domset array using DB_COL_WORDS
**	06-mar-89 (ralph)
**	    GRANT Enhancements, Phase 1:
**	    Initialize new DB_PROTECTION fields, dbp_seq and dbp_gtype
**	03-apr-89 (ralph)
**	    GRANT Enhancements, Phase 2:
**	    Use DBGR_USER when initializing dbp_gtype
**	08-may-89 (ralph)
**	    Initialize reserved field to blanks (was \0)
**	04-jun-89 (ralph)
**	    Initialize dbp_fill1 to zero
**	    Fix unix portability problems
**	02-nov-89 (neil)
**	    Alerters: Allowed privileges for events.
**	1-mar-90 (andre)
**	    If processing a GRANT on tables, check if 
**	    ALL-TO-ALL or RETRIEVE-TO-ALL has already been granted, and if so,
**	    mark psy_mask appropriately.
**	    If user tried to CREATE ALL/RETRIEVE-TO-ALL, and one already exists,
**	    skip to the exit.
**	12-mar-90 (andre)
**	    set rdr_2types_mask to 0.
**      22-may-90 (teg)
**          init rdr_instr to RDF_NO_INSTR
**	08-aug-90 (ralph)
**	    Initialize new fields in iiprotect tuple
**	14-dec-90 (ralph)
**	    Disallow use of GRANT by non-DBA if xORANGE
**	11-jan-90 (ralph)
**	    Allow user "$ingres" to use GRANT if xORANGE.
**	    This was done for CREATEDB (UPGRADEFE).
**	20-feb-91 (andre)
**	    For CREATE/DEFINE PERMIT, grantee type was stored in
**	    psy_cb->psy_gtype.
**	24-jun-91 (andre)
**	    IIPROTECT tuples for table permits will contain exactly one
**	    privilege.  IIQRYTEXT template built for table-wide privileges
**	    contains a placeholder for a privilege name which will be filled in
**	    with each of the table-wide privileges being granted, one at a time.
**	    PSY_CB.psy_opmap will be set to correspond with privilege name
**	    stored in the IIQRYTEXT permit.
**	16-jul-91 (andre)
**	    responsibility for splitting permit tuples will passed on to
**	    qeu_cprot().  If a permit specified only one privilege, we will
**	    substitute the appropriate privilege name here and will not ask
**	    qeu_cprot() to split tuples.
**	06-aug-91 (andre)
**	    before proceeding to CREATE a permit on a view owned by the current
**	    user, we will call psy_tbl_grant_check() to ensure that this user
**	    may create a permit on his view.  If the object is not owned by the
**	    current user, we will not try to verify that the user may
**	    CREATE/DEFINE a permit since (until the relevant FE changes are
**	    made) we intend to continue allowing any user with CATUPD to
**	    CREATE/DEFINE permits on catalogs and the dba will be allowed to
**	    CREATE/DEFINE permits on extended catalogs
**	11-nov-91 (rblumer)
**	  merged from 6.4:  26-feb-91 (andre)
**	    PST_QTREE was changed to store the range table as an array of
**	    pointers to PST_RNGENTRY structure.
**	14-feb-92 (andre)
**	    we will no longer have to fill in privilege name for permits
**	    specifying one privilege - it will be handled in respective
**	    grammars.
**	15-jun-92 (barbara)
**	    For Sybil, change interface to pst_rgent(), Star returns from
**	    psy_dpermit before permits get stored.
**	07-jul-92 (andre)
**	    DB_PROTECTION tuple will contain an indicator of how the permit was
**	    created, i.e. whether it was created using SQL or QUEL and if the
**	    former, then whether it was created using GRANT statement.  Having
**	    this information will facilitate merging similar and identical
**	    permit tuples.
**	14-jul-92 (andre)
**	    semantics of GRANT ALL [PRIVILEGES] is different from that of
**	    CREATE PERMIT ALL in that the former (as dictated by SQL92) means
**	    "grant all privileges which the current auth id posesses WGO"
**	    whereas the latter (as is presently interpreted) means "grant all
**	    privileges that can be defined on the object" which in case of
**	    tables and views means SELECT, INSERT, DELETE, UPDATE.
**	    psy_tbl_grant_check() (function responsible for determining whether
**	    a user may grant specified privilege on a specified table or view)
**	    will have to be notified whether we are processing GRANT ALL.  Its
**	    behaviour will change as follows:
**	      - if processing GRANT ALL and psy_tbl_grant_check() determines
**	        that the user does not possess some (but not all) of the
**		privileges passed to it by the caller it will not treat it as an
**		error, but will instead inform the caller of privileges that the
**		user does not posess,
**	      - if processing GRANT ALL and psy_tbl_grant_check() determines
**	        that the user does not possess any of the privileges passed to
**		it by the caller it will treat it as an error
**	      - if processing a statement other than GRANT ALL and
**	        psy_tbl_grant_check() determines that the user does not possess
**		some of the privileges passed to it by the caller it will treat
**		it as an error
**	16-jul-92 (andre)
**	    if a permit being created depends on some privileges, build a
**	    structure describing these privileges and store its address in
**	    rdf_cb->rdr_indep.
**	18-jul-92 (andre)
**	    we will no longer be telling QEF to turn off DMT_ALL_PROT or
**	    DMT_RETRIEVE_PRO when a user creates ALL/RETRIEVE TO ALL permit.
**	    QEF will figure out on its own whether PUBLIC now has RETRIEVE or
**	    ALL on a table/view
**	20-jul-92 (andre)
**	    if user specified a list of columns to which privilege(s) should
**	    not apply, set dbp_domset correctly
**	03-aug-92 (barbara)
**	    Invalidate base table infoblk from RDF cache for CREATE PERMIT
**	    and CREATE SEC_ALARM.
**	16-sep-92 (andre)
**	    privilege maps are build using bitwise ops, so care should be
**	    exercised when accessing it using BT*() functions
**	17-jun-93 (andre)
**	    changed interface of psy_secaudit() to accept PSS_SESBLK
**	5-jul-93 (robf)
**	    changed interface of  psy_secaudit() to accept security label
**	 7-jan-94 (swm)
**	    Bug #58635
**	    Added PTR cast for qsf_owner which has changed type to PTR.
**	06-mar-96 (nanpr01)
**	    Move the QSF request block initialization up. because if  
**	    pst_rgnent returns a failure status code, subsequent QSF
**	    calls get bad control block error.
*/
DB_STATUS
psy_dpermit(
	PSY_CB             *psy_cb,
	PSS_SESBLK	   *sess_cb)
{
    RDF_CB              rdf_cb;
    register RDR_RB	*rdf_rb = &rdf_cb.rdf_rb;
    QSF_RCB		qsf_rb;
    DB_STATUS		status;
    DB_STATUS		stat;
    DB_PROTECTION	ptuple;
    register DB_PROTECTION *protup = &ptuple;
    i4			*domset	= ptuple.dbp_domset;
    register i4	i, j;
    i4		err_code;
    PSS_RNGTAB		*rngvar;
    PSS_USRRANGE	*rngtab;
    PST_PROCEDURE	*pnode;
    PST_QTREE		*qtree;
    DB_ERROR		*err_blk = &psy_cb->psy_error;
    i4			textlen;
    i4			tree_lock   = 0;
    i4			text_lock   = 0;
    DB_TAB_ID		tabids[PST_NUMVARS];
    PSQ_INDEP_OBJECTS   indep_objs;
    PSQ_OBJPRIV         obj_priv;       /* space for independent DELETE */
    PSQ_COLPRIV         col_privs[2];   /*
                                        ** space for independent INSERT and
					** UPDATE
					*/
    PST_VRMAP		varmap;
    PSY_TBL		*psy_tbl;
    DB_TIME_ID		timeid;
    DB_NAME             *objname;

    /*
    ** For CREATE/DEFINE PERMIT execute code below.
    */

    /* initialize the QSF control block */
    qsf_rb.qsf_type	= QSFRB_CB;
    qsf_rb.qsf_ascii_id = QSFRB_ASCII_ID;
    qsf_rb.qsf_length	= sizeof(qsf_rb);
    qsf_rb.qsf_owner	= (PTR)DB_PSF_ID;
    qsf_rb.qsf_sid	= sess_cb->pss_sessid;

    rngtab = &sess_cb->pss_auxrng;

    /* table info is stored in the only entry in the table queue */
    psy_tbl = (PSY_TBL *) psy_cb->psy_tblq.q_next;

    status = pst_rgent(sess_cb, rngtab, -1, "", PST_SHWID,
	(DB_TAB_NAME *) NULL, (DB_TAB_OWN *) NULL,
	&psy_tbl->psy_tabid, TRUE, &rngvar, (i4) 0, err_blk);
	
    if (DB_FAILURE_MACRO(status))
	goto exit;

    /* In STAR, we do not actually store permits */
    if (sess_cb->pss_distrib & DB_3_DDB_SESS)
    {
	qsf_rb.qsf_lk_state = QSO_EXLOCK;
	goto exit;
    }

    /* Fill in the RDF request block */
    pst_rdfcb_init(&rdf_cb, sess_cb);

    /* The table which is receiving the permit */
    STRUCT_ASSIGN_MACRO(psy_tbl->psy_tabid, rdf_rb->rdr_tabid);
    
    /* Tell RDF we're doing a permit definition */
    rdf_rb->rdr_update_op   = RDR_APPEND;

    rdf_rb->rdr_types_mask = RDR_PROTECT;
    rdf_rb->rdr_qrytuple = (PTR) protup;

    /* initialize independent object structure */
    indep_objs.psq_objs	= (PSQ_OBJ *) NULL;
    indep_objs.psq_objprivs = (PSQ_OBJPRIV *) NULL;
    indep_objs.psq_colprivs = (PSQ_COLPRIV *) NULL;
    indep_objs.psq_grantee  = &sess_cb->pss_user;

    rdf_rb->rdr_indep	    = (PTR) &indep_objs;

    /*
    ** populate the IIPROTECT tuple
    */

    /* Zero out the template */
    (VOID)MEfill(sizeof(ptuple), (u_char) 0, (PTR) protup);

    /* store grantee type */
    protup->dbp_gtype = psy_cb->psy_gtype;

    /* Init reserved block */
    (VOID)MEfill(sizeof(protup->dbp_reserve),
	(u_char) ' ', (PTR) protup->dbp_reserve);

    /* Init obj name */
    STRUCT_ASSIGN_MACRO(psy_tbl->psy_tabnm, protup->dbp_obname);

    /*@FIX_ME@ Where does this come from? */
    protup->dbp_obstat = ' ';

    /* store the object type indicator */
    if (psy_tbl->psy_mask & PSY_OBJ_IS_TABLE)
    {
	protup->dbp_obtype = DBOB_TABLE;
    }
    else if (psy_tbl->psy_mask & PSY_OBJ_IS_VIEW)
    {
	protup->dbp_obtype = DBOB_VIEW;
    }
    else
    {
	protup->dbp_obtype = DBOB_INDEX;
    }

    STRUCT_ASSIGN_MACRO(psy_tbl->psy_owner, protup->dbp_obown);

    STRUCT_ASSIGN_MACRO(sess_cb->pss_user, protup->dbp_grantor);

    TMnow((SYSTIME *)&timeid);
    protup->dbp_timestamp.db_tim_high_time = timeid.db_tim_high_time;
    protup->dbp_timestamp.db_tim_low_time  = timeid.db_tim_low_time;

    /* The table on which we're giving permission */
    STRUCT_ASSIGN_MACRO(psy_tbl->psy_tabid, protup->dbp_tabid);

    /* Beginning and ending times of day */
    protup->dbp_pdbgn = psy_cb->psy_timbgn;
    protup->dbp_pdend = psy_cb->psy_timend;

    /* Beginning and ending days of week */
    protup->dbp_pwbgn = psy_cb->psy_daybgn;
    protup->dbp_pwend = psy_cb->psy_dayend;

    if (psy_cb->psy_numcols != 0 && ~psy_cb->psy_flags & PSY_EXCLUDE_COLUMNS)
    {
	/* user specified a list of columns to which privilege(s) will apply */
	
	/* Bit map of permitted columns */
	psy_fill_attmap(domset, ((i4) 0));

	for (i = 0; i < psy_cb->psy_numcols; i++)
	{
	    BTset((i4)psy_cb->psy_cols[i].db_att_id, (char *) domset);
	}	
    }
    else
    {
	/*
	** user specified table-wide privilege(s) or a list of columns L s.t.
	** privilege(s) will apply to the entire table except for columns in L
	*/

	psy_fill_attmap(domset, ~((i4) 0));

	if (psy_cb->psy_flags & PSY_EXCLUDE_COLUMNS)
	{
	    /*
	    ** exclude specified columns from the list of columns to which
	    ** privilege(s) will apply
	    */
	    for (i = 0; i < psy_cb->psy_numcols; i++)
	    {
		BTclear((i4) psy_cb->psy_cols[i].db_att_id, (char *) domset);
	    }
	}
    }

    if (rngvar->pss_tabdesc->tbl_status_mask & DMT_VIEW)
    {
	/*
	** if view is owned by the current user, psy_tbl_grant_check() will
	** determine if the permit can, indeed, be created;  as long as we are
	** preserving the kludge that allows users with CATUPD create permits on
	** catalogs and DBAs to create permits on extended catalogs, we shall
	** not call psy_tbl_grant_check() on view not owned by the current user,
	** since it is likely to result in psy_tbl_grant_check() complaining
	** about inadequate permissions
	*/
	if (!MEcmp((PTR) &rngvar->pss_ownname, (PTR) &sess_cb->pss_user,
	    sizeof(sess_cb->pss_user)))
	{
	    i4			    tbl_wide_privs;
	    PSY_COL_PRIVS	    col_specific_privs, *csp,
				    indep_col_specific_privs;
	    DB_TAB_ID		    indep_id;
	    i4			    indep_tbl_wide_privs;
	    bool		    insuf_privs, quel_view;
	    i4		    val1, val2;

	    /*
	    ** build maps of table-wide and column-specific privileges for
	    ** psy_tbl_grant_check()
	    ** if a column list was specified with CREATE PERMIT and
	    ** privileges specified in the statement include a set of
	    ** privileges S s.t. for all P in S, P can only be specified as
	    ** table-wide with GRANT statement (currently this includes
	    ** SELECT, INSERT, DELETE), we will make 
	    ** psy_tbl_grant_check() think that privileges in S are
	    ** table-wide.
	    ** This will work correctly since if the view was defined over
	    ** some objects owned by other user(s), for every P in S we
	    ** would need table-wide privilege WGO on the underlying object.
	    **
	    ** For the purposes of providing more descriptive output for
	    ** trace point ps131, if column-list was specified, we will pass
	    ** the map of attributes even if column-specific UPDATE was not
	    ** specified
	    */

	    if (psy_cb->psy_numcols != 0 &&
		(psy_cb->psy_opmap & DB_REPLACE ||
		 ult_check_macro(&sess_cb->pss_trace, 3, &val1, &val2)
		)
	       )
	    {
		i4	    *ip;

		csp = &col_specific_privs;

		/*
		** column-specific UPDATE privilege will not be translated into
		** a table-wide privilege since GRANT allows for specification
		** of column-specific UPDATE privilege
		*/
		csp->psy_col_privs = psy_cb->psy_opmap & DB_REPLACE;
		tbl_wide_privs = psy_cb->psy_opmap & ~DB_REPLACE;

		/*
		** if creating a permit on a set of columns and UPDATE is not
		** one of the privileges named in the statement, store the
		** attribute map in the first element of the attribute map list
		*/
		ip = (csp->psy_col_privs)
		    ? csp->psy_attmap[PSY_UPDATE_ATTRMAP].map
		    : csp->psy_attmap->map;

		/* copy the attribute map */
		for (i = 0; i < DB_COL_WORDS; i++, ip++)
		{
		    *ip = domset[i];
		}
	    }
	    else
	    {
		tbl_wide_privs = psy_cb->psy_opmap;
		csp = (PSY_COL_PRIVS *) NULL;
	    }

	    status = psy_tbl_grant_check(sess_cb, (i4) PSQ_PROT,
		&rngvar->pss_tabid, &tbl_wide_privs, csp, &indep_id,
		&indep_tbl_wide_privs, &indep_col_specific_privs,
		psy_cb->psy_flags, &insuf_privs, &quel_view,
		&psy_cb->psy_error);
	    if (DB_FAILURE_MACRO(status))
	    {
		goto exit;
	    }

	    if (insuf_privs)
	    {
		/* must audit failure to create a permit */
		if ( Psf_srvblk->psf_capabilities & PSF_C_C2SECURE )
		{
		    DB_ERROR	e_error;

		    /* Must audit CREATE PERMIT failure. */
		    status = psy_secaudit(FALSE, sess_cb,
			    (char *)&rngvar->pss_tabdesc->tbl_name,
			    &rngvar->pss_tabdesc->tbl_owner,
			    sizeof(DB_TAB_NAME), SXF_E_TABLE,
			    I_SX2016_PROT_TAB_CREATE, SXF_A_FAIL | SXF_A_CREATE,
			    &e_error);
		    
		    status = (status > E_DB_ERROR) ? status : E_DB_ERROR;
		}
		goto exit;
	    }
	    else if (quel_view)
	    {
		goto exit;
	    }
	    
	    /*
	    ** If user is trying to grant one or more of
	    ** INSERT/DELETE/UPDATE on his/her view whose underlying table
	    ** or view is owned by another user, psy_tbl_grant_check() will
	    ** return id of the underlying object along with map of
	    ** privileges.  We will convert maps of independent privileges
	    ** into elements of independent privilege list and pass them
	    ** along to QEF
	    */
	    if (   indep_id.db_tab_base != (i4) 0
		&& (   indep_id.db_tab_base != rngvar->pss_tabid.db_tab_base
		    || indep_id.db_tab_index !=
			   rngvar->pss_tabid.db_tab_index
		   )
	       )
	    {
		if (indep_tbl_wide_privs & DB_DELETE)
		{
		    /*
		    ** the only expected independent table-wide privilege
		    ** is DELETE
		    */
		    obj_priv.psq_next		= (PSQ_OBJPRIV *) NULL;
		    obj_priv.psq_objtype		= PSQ_OBJTYPE_IS_TABLE;
		    obj_priv.psq_privmap		= (i4) DB_DELETE;
		    obj_priv.psq_objid.db_tab_base	= indep_id.db_tab_base;
		    obj_priv.psq_objid.db_tab_index = indep_id.db_tab_index;
		    indep_objs.psq_objprivs		= &obj_priv;
		}

		if (indep_col_specific_privs.psy_col_privs)
		{
		    i4		i, j;
		    PSQ_COLPRIV	*csp;
		    i4		*att_map, *p;
		    i4		priv_map = 0;

		    /*
		    ** privilege map is built using bitwise operators, but
		    ** here using BTnext() makes code much more palatable,
		    ** so convert a privilege map
		    */
		    if (indep_col_specific_privs.psy_col_privs & DB_APPEND)
			BTset(DB_APPP, (char *) &priv_map);
		    if (indep_col_specific_privs.psy_col_privs & DB_REPLACE)
			BTset(DB_REPP, (char *) &priv_map);

		    for (i = -1, csp = col_privs;
			 (i = BTnext(i, (char *) &priv_map, BITS_IN(priv_map)))
			      != -1;
			  csp++
			)
		    {
			csp->psq_next = indep_objs.psq_colprivs;
			indep_objs.psq_colprivs = csp;
			csp->psq_objtype = PSQ_OBJTYPE_IS_TABLE;
			csp->psq_tabid.db_tab_base = indep_id.db_tab_base;
			csp->psq_tabid.db_tab_index = indep_id.db_tab_index;
			switch (i)
			{
			    case DB_APPP:	    /* INSERT privilege */
			    {
				csp->psq_privmap = (i4) DB_APPEND;
				att_map = indep_col_specific_privs.
				    psy_attmap[PSY_INSERT_ATTRMAP].map;
				break;
			    }
			    case DB_REPP:
			    {
				csp->psq_privmap = (i4) DB_REPLACE;
				att_map = indep_col_specific_privs.
				    psy_attmap[PSY_UPDATE_ATTRMAP].map;
				break;
			    }
			}

			for (p = csp->psq_attrmap, j = 0;
			     j < DB_COL_WORDS;
			     j++)
			{
			    *p++ = *att_map++;
			}
		    }
		}
	    }
	}
	else
	{
	    /*
	    ** either this is a catalog and the user has CATUPD or
	    ** this is an extended catalog and the user is the DBA;
	    ** since we may be allowing a user to create a permit by
	    ** circumventing the permit system, we only need to ascertain that
	    ** this is an SQL view
	    */
	    i4	    issql = 0;

	    status = psy_sqlview(rngvar, sess_cb, err_blk, &issql);
	    if (status)
	    {
		goto exit;
	    }
	    if (!issql)
	    {
		/* can only have permits on SQL views */
		psf_error(3598L, 0L, PSF_USERERR, &err_code, err_blk, 1, 
		    psf_trmwhite(sizeof(rngvar->pss_tabname),
			(char *) &rngvar->pss_tabname),
		    &rngvar->pss_tabname);
		status = E_DB_ERROR;
		goto exit;
	    }
	}
    }
    /* Name of user getting permission */
    STRUCT_ASSIGN_MACRO(psy_cb->psy_user, protup->dbp_owner);

    /* Terminal at which permission given */
    STRUCT_ASSIGN_MACRO(psy_cb->psy_terminal, protup->dbp_term);

    /* Give RDF pointer to query tree, if any */
    if (!psy_cb->psy_istree)
    {
	rdf_rb->rdr_qry_root_node = (PTR) NULL;
    }
    else
    {
	PST_VRMAP   varset;
	i4	    j;

	STRUCT_ASSIGN_MACRO(psy_cb->psy_intree, qsf_rb.qsf_obj_id);
	qsf_rb.qsf_lk_state = QSO_EXLOCK;
	status = qsf_call(QSO_LOCK, &qsf_rb);
	if (DB_FAILURE_MACRO(status))
	{
	    (VOID) psf_error(E_PS0D19_QSF_INFO, qsf_rb.qsf_error.err_code,
		PSF_INTERR, &err_code, err_blk, 0);
	    goto exit;
	}

	tree_lock		= qsf_rb.qsf_lk_id;
	pnode = (PST_PROCEDURE *) qsf_rb.qsf_root;
	qtree = (PST_QTREE *) pnode->pst_stmts->pst_specific.pst_tree;
	rdf_rb->rdr_qry_root_node = (PTR) pnode;
	/* check for no views in the qualification.
	*/
	(VOID)psy_varset(qtree->pst_qtree, &varset);	
	j = BTnext(-1, (char *) &varset, BITS_IN(varset));
	for ( ; j >= 0; j = BTnext(j, (char *) &varset, BITS_IN(varset)))
	{
	    status = pst_rgent(sess_cb, rngtab, -1, "", PST_SHWID,
		(DB_TAB_NAME *) NULL, (DB_TAB_OWN *) NULL,
		&qtree->pst_rangetab[j]->pst_rngvar, TRUE,
		&rngvar, (i4) 0, err_blk);
	    if (status)
		goto exit;		

	    if (rngvar->pss_tabdesc->tbl_status_mask & DMT_VIEW)
	    {
		psf_error(3597L, 0L, PSF_USERERR, &err_code, err_blk, 1,
		    psf_trmwhite(sizeof(rngvar->pss_tabname),
			(char *) &rngvar->pss_tabname),
		    &rngvar->pss_tabname);
		    status = E_DB_ERROR;
		    goto exit;
	    }
	}
    }
    
    /* Give RDF a pointer to the query text to be stored in iiqrytext */
    STRUCT_ASSIGN_MACRO(psy_cb->psy_qrytext, qsf_rb.qsf_obj_id);
    qsf_rb.qsf_lk_state = QSO_EXLOCK;
    status = qsf_call(QSO_LOCK, &qsf_rb);
    if (DB_FAILURE_MACRO(status))
    {
	(VOID) psf_error(E_PS0D19_QSF_INFO, qsf_rb.qsf_error.err_code,
	    PSF_INTERR, &err_code, err_blk, 0);
	goto exit;
    }

    text_lock = qsf_rb.qsf_lk_id;

    MEcopy((char *) qsf_rb.qsf_root, sizeof(i4), (char *) &textlen);
    rdf_rb->rdr_l_querytext = textlen;
    rdf_rb->rdr_querytext = ((char *) qsf_rb.qsf_root) + sizeof(i4);
    rdf_rb->rdr_status = (sess_cb->pss_lang == DB_SQL) ? DB_SQL : 0;

    /* determine if the permit specifies exactly one privilege */
    if (BTcount((char *) &psy_cb->psy_opmap, BITS_IN(psy_cb->psy_opmap)) > 1)
    {
	/*
	** if permit specified more than one privilege, notify QEF that it will
	** have to split the permit into multiple IIPROTECT tuples
	*/
	rdf_rb->rdr_instr |= RDF_SPLIT_PERM;
    }
    else if (psy_cb->psy_opmap & DB_RETRIEVE)
    {
	/*
	** if qeu_cprot() will not be splitting the permit into multiple tuples
	** and RETRIEVE is the privilege mentioned in it, set the two bits
	** associated with DB_RETRIEVE
	*/
	psy_cb->psy_opmap |= DB_TEST | DB_AGGREGATE;
	psy_cb->psy_opctl |= DB_TEST | DB_AGGREGATE;
    }

    /* Null out the DMU control block pointer, just in case */
    rdf_rb->rdr_dmu_cb = (PTR) NULL;

    /* produce list of dependent tables */
    rdf_rb->rdr_cnt_base_id = 0;
    if (psy_cb->psy_istree && qtree->pst_qtree) 
    {
	j = 0;
	(VOID)psy_varset(qtree->pst_qtree, &varmap);
	for (i = -1; (i = BTnext(i, (char*) &varmap, PST_NUMVARS)) > -1;)
	{
	    /* if this is the table that is getting the permit, ignore */
	    if (qtree->pst_rangetab[i]->pst_rngvar.db_tab_base != 
		    psy_tbl->psy_tabid.db_tab_base
		||
		qtree->pst_rangetab[i]->pst_rngvar.db_tab_index !=
		    psy_tbl->psy_tabid.db_tab_index
	    )
	    {
		rdf_rb->rdr_cnt_base_id++;
		STRUCT_ASSIGN_MACRO(qtree->pst_rangetab[i]->pst_rngvar,
		    tabids[j++]);
	    }
	}
	rdf_rb->rdr_base_id = tabids;
    }

    protup->dbp_popctl = psy_cb->psy_opctl;
    protup->dbp_popset = psy_cb->psy_opmap;
    
    /*
    ** store an indication of whether this permit is being created using SQL or
    ** QUEL
    */
    protup->dbp_flags = (sess_cb->pss_lang == DB_SQL) ? DBP_SQL_PERM : (i2) 0;
    protup->dbp_flags |= DBP_65_PLUS_PERM;

    /* Now let RDF do all the work of the permit definition */
    status = rdf_call(RDF_UPDATE, (PTR) &rdf_cb);
    if (DB_FAILURE_MACRO(status))
    {
	if (rdf_cb.rdf_error.err_code == E_RD0002_UNKNOWN_TBL)
	{
	    (VOID) psf_error(E_PS0903_TAB_NOTFOUND, 0L, PSF_USERERR,
		&err_code, err_blk, 1,
		psf_trmwhite(sizeof(psy_tbl->psy_tabnm),
		    (char *) &psy_tbl->psy_tabnm),
		&psy_tbl->psy_tabnm);
	}
	else
	{
	    (VOID) psf_rdf_error(RDF_UPDATE, &rdf_cb.rdf_error,
		&psy_cb->psy_error);
	}
	goto exit;
    }

    /*
    ** Invalidate base object's infoblk from RDF cache.
    */
    pst_rdfcb_init(&rdf_cb, sess_cb);
    STRUCT_ASSIGN_MACRO(psy_cb->psy_tables[0], rdf_rb->rdr_tabid);
    status = rdf_call(RDF_INVALIDATE, (PTR) &rdf_cb);
    if (DB_FAILURE_MACRO(status))
    {
	(VOID) psf_rdf_error(RDF_INVALIDATE, &rdf_cb.rdf_error,
				&psy_cb->psy_error);
    }

exit:

    qsf_rb.qsf_lk_state = QSO_EXLOCK;

    if (psy_cb->psy_istree)
    {
	/* Destroy query tree */
	STRUCT_ASSIGN_MACRO(psy_cb->psy_intree, qsf_rb.qsf_obj_id);

	if ((qsf_rb.qsf_lk_id = tree_lock) == 0)
	{
	    stat = qsf_call(QSO_LOCK, &qsf_rb);
	    if (DB_FAILURE_MACRO(stat))
	    {
		(VOID) psf_error(E_PS0D18_QSF_LOCK,
		    qsf_rb.qsf_error.err_code, PSF_INTERR,
		    &err_code, &psy_cb->psy_error, 0);
		if (!status || stat == E_DB_FATAL)
		    status = stat;
	    }
	    tree_lock = qsf_rb.qsf_lk_id;
	}

	stat = qsf_call(QSO_DESTROY, &qsf_rb);
	if (DB_FAILURE_MACRO(stat))
	{
	    (VOID) psf_error(E_PS0D1A_QSF_DESTROY,
		qsf_rb.qsf_error.err_code, PSF_INTERR,
		&err_code, &psy_cb->psy_error, 0);
	    if (!status || stat == E_DB_FATAL)
		status = stat;
	}

	tree_lock = 0;
    }

    /* Destroy query text */
    STRUCT_ASSIGN_MACRO(psy_cb->psy_qrytext, qsf_rb.qsf_obj_id);

    if ((qsf_rb.qsf_lk_id = text_lock) == 0)
    {
	stat = qsf_call(QSO_LOCK, &qsf_rb);
	if (DB_FAILURE_MACRO(stat))
	{
	    (VOID) psf_error(E_PS0D18_QSF_LOCK, qsf_rb.qsf_error.err_code,
		PSF_INTERR, &err_code, &psy_cb->psy_error, 0);
	    if (!status || stat == E_DB_FATAL)
		status = stat;
	}
	text_lock = qsf_rb.qsf_lk_id;
    }

    stat = qsf_call(QSO_DESTROY, &qsf_rb);
    if (DB_FAILURE_MACRO(stat))
    {
	(VOID) psf_error(E_PS0D1A_QSF_DESTROY, qsf_rb.qsf_error.err_code,
	    PSF_INTERR, &err_code, &psy_cb->psy_error, 0);
	if (!status || stat == E_DB_FATAL)
	    status = stat;
    }

    return (status);
}
Example #21
0
void IIodbc_timeOutThread()
{
    QUEUE *q, *p, *pq;
    pENV penv;
    pDBC pdbc;
    RETCODE rc;
    SYSTIME expire_time;
    TM_STAMP stamp;
    char stampStr[TM_SIZE_STAMP];

    ODBC_EXEC_TRACE(ODBC_EX_TRACE)
        ("IIodbc_timeOutThread() with timeout %d\n", IIodbc_cb.timeout);
    while(TRUE)
    {
        /*
        ** Search the pool every thirty seconds and check for expired
        ** connections.  Force disconnect and free from the pool
        ** if the connection handle has passed the expiration time.  
        ** Note that the CLI and driver connection handles are not
        ** freed.  
        */
        PCsleep(30000);
        TMget_stamp(&stamp);
        TMstamp_str(&stamp, stampStr);
        ODBC_EXEC_TRACE(ODBC_EX_TRACE)
            ("IIodbc_timeOutThread woke up at %s\n", stampStr);
        TMnow(&expire_time);
        
        if (IIodbc_cb.pooling == DRIVER_POOL)
        {
            applyLock(SQL_HANDLE_IIODBC_CB, NULL);
            for (q = IIodbc_cb.pool_q.q_prev; q!= &IIodbc_cb.pool_q;
                q = p)
            {
                ODBC_EXEC_TRACE(ODBC_EX_TRACE)
                    ("IIodbc_timeOutThread: driver pool count is %d\n", 
                    IIodbc_cb.pool_count);
                p = q->q_prev;
                pdbc = (pDBC)((pPOOL)q)->pdbc;
                ODBC_EXEC_TRACE(ODBC_EX_TRACE)
                    ("IIodbc_timeOutThread: found conn handle %p with time diff %d\n",pdbc,
                    expire_time.TM_secs - pdbc->expire_time.TM_secs);
                if (expire_time.TM_secs - pdbc->expire_time.TM_secs > 
                    IIodbc_cb.timeout)
                {
                    /*
                    **  Note that the connection handle is not freed, only
                    **  removed from the pool. 
                    */
                    ODBC_EXEC_TRACE(ODBC_EX_TRACE)
                        ("IIodbc_timeOutThread: EXPIRED.  pdbc time is %d vs %d\n",
                        pdbc->expire_time.TM_secs, expire_time.TM_secs);
                    rc = IIDisconnect(pdbc->hdr.driverHandle);
                    QUremove(q);
                    MEfree((PTR)q);
                    IIodbc_cb.pool_count -= 1;
                    ODBC_EXEC_TRACE(ODBC_EX_TRACE)
                        ("new pool count is %d\n",IIodbc_cb.pool_count);
                    applyLock(SQL_HANDLE_DBC, pdbc);
                    pdbc->hdr.state = C2;
                    releaseLock(SQL_HANDLE_DBC, pdbc);
                }
            }
            releaseLock(SQL_HANDLE_IIODBC_CB, NULL);
        }
        else
        {
            for (q = IIodbc_cb.env_q.q_prev; q!= &IIodbc_cb.env_q;
                q = q->q_prev)
            {
                penv = (pENV)q;
                TRdisplay("Found env handle %p\n",penv);
                applyLock(SQL_HANDLE_ENV, penv);
                for (pq = penv->pool_q.q_prev; pq != &penv->pool_q;
                    pq = p)
                {
                    ODBC_EXEC_TRACE(ODBC_EX_TRACE)
                        ("Env pool count is %d\n",penv->pool_count);
                    p = q->q_prev;
                    pdbc = (pDBC)((pPOOL)pq)->pdbc;
                    ODBC_EXEC_TRACE(ODBC_EX_TRACE)
                        ("IIodbc_TimeOutThread: Found conn handle %p with time diff %d\n",pdbc,
                        expire_time.TM_secs - pdbc->expire_time.TM_secs);
                    if (expire_time.TM_secs - pdbc->expire_time.TM_secs
                        > 1)
                    {
                        ODBC_EXEC_TRACE(ODBC_EX_TRACE)
                            ("IIodbc_timeOutThread: EXPIRED.  pdbc time is %d vs %d\n",
                            pdbc->expire_time.TM_secs,   
                            expire_time.TM_secs);
                        rc = IIDisconnect(pdbc->hdr.driverHandle);
                        QUremove(q);
                        MEfree((PTR)q);
                        penv->pool_count -= 1;
                        ODBC_EXEC_TRACE(ODBC_EX_TRACE)
                            ("IIodbc_timeOutThread: new pool count is %d\n",
                            penv->pool_count);
                    }
                }
                releaseLock(SQL_HANDLE_ENV, penv);
            } /* for (q = IIodbc_cb.env_q.q_prev; q!= &IIodbc_cb.env_q;
                q = q->q_prev) */
        } /* if (IIodbc_cb.pooling == DRIVER_POOL) */
    } /* while (TRUE) */
}