Exemple #1
0
DB_STATUS
qel_c5_ldbid_long(
QEF_RCB		    *v_qer_p,
QEC_LINK	    *v_lnk_p )
{
    DB_STATUS	    status;
    QES_DDB_SES	    *dds_p = & v_qer_p->qef_cb->qef_c2_ddb_ses;
    DD_LDB_DESC	    *cdb_p = & dds_p->qes_d4_ddb_p->
			dd_d3_cdb_info.dd_i1_ldb_desc,
		    *ldb_p = v_lnk_p->qec_19_ldb_p;

    QEQ_1CAN_QRY    *sel_p = v_lnk_p->qec_6_select_p;
    QEC_D5_LONG_LDBNAMES
		    *long_p = v_lnk_p->qec_8_longnames_p;


    /* 1.  set up for accessing IIDD_DDB_LDB_LONGNAMES */

    sel_p->qeq_c3_ptr_u.d5_long_ldbnames_p = long_p; 
    sel_p->qeq_c4_ldb_p = cdb_p;
    sel_p->qeq_c5_eod_b = FALSE;
    sel_p->qeq_c6_col_cnt = 0;

    qed_u0_trimtail(
	ldb_p->dd_l3_ldb_name,
	(u_i4) DD_256_MAXDBNAME,
	long_p->d5_1_ldb_name);

    /* 3.  retrieve the LDB's 32-char alias if it exists */

    sel_p->qeq_c1_can_id = SEL_014_DD_DDB_LONG_LDBNAMES;

    status = qel_s4_prepare(v_qer_p, v_lnk_p);
    if (status)
	return(status);

    if (! sel_p->qeq_c5_eod_b)	    
    {
	/* no data */
    
	status = qel_s3_flush(v_qer_p, v_lnk_p);
	if (status) 
	    return(status);

	/* generate alias */

	STcopy(IIQE_30_alias_prefix, v_lnk_p->qec_5_ldb_alias);   /* prefix */
	CVla(v_lnk_p->qec_2_tableinfo_p->d9_1_obj_id.db_tab_base,
	     &v_lnk_p->qec_5_ldb_alias[QEK_5_SIZE_OF_PREFIX]);

	return(E_DB_OK);
    }

    /* 4.  send SELECT query to retrieve ldb id if it exists */

    status = qel_c4_ldbid_short(TRUE, v_qer_p, v_lnk_p);
						/* TRUE for using alias */
    return(status);
}
Exemple #2
0
static void
formatXID( IIAPI_XA_DIS_TRAN_ID *xid, char *str )
{
    u_i4	count, val;
    u_i1	*data;

    CVlx( xid->xa_tranID.xt_formatID, str );
    str += STlength( str );

    *(str++) = ':';
    CVla( xid->xa_tranID.xt_gtridLength, str );
    str += STlength( str );

    *(str++) = ':';
    CVla( xid->xa_tranID.xt_bqualLength, str );
    str += STlength( str );

    data = (u_i1 *)xid->xa_tranID.xt_data;
    count = (xid->xa_tranID.xt_gtridLength + xid->xa_tranID.xt_bqualLength + 
		sizeof( i4 ) - 1) / sizeof( i4 );

    while( count-- )
    {
	val = (*data << 24) | (*(data+1) << 16) |
                   (*(data+2) << 8) | *(data+3);
        data+= 4;
	*(str++) = ':';
	CVlx( val, str );
	str += STlength( str );
    }

    STcat( str, ERx( ":XA" ) );
    str += STlength( str );

    *(str++) = ':';
    CVna( xid->xa_branchSeqnum, str );
    str += STlength( str );

    *(str++) = ':';
    CVna( xid->xa_branchFlag, str );
    str += STlength( str );

    STcat( str, ERx( ":EX" ) );
    return;
}
Exemple #3
0
static STATUS
my_dynamic_index(i4 msg,
		 PTR cdata,
		 i4  linstance,
		 char *instance, 
		 PTR *instdata )
{
    STATUS stat = OK;
    i4 ival;
    char buf[ 20 ];

    switch( msg )
    {
    case MO_GET:
	*instdata = (PTR)instance;
	break;

    case MO_GETNEXT:
	if( *instance == EOS )
	    ival = 0;

	stat = CVal( instance, &ival ); /* value is the instance */
	if( stat != OK )
	    break;
	
	if( ival > 9 )		/* validate this instance */
	    stat = MO_NO_INSTANCE;
	else if( ++ival > 9 ) /* validate next */
	    stat = MO_NO_NEXT;

	if( stat != OK )
	    break;

	CVla( ival, buf );
	
	/* assumes caller doesn't blast instance before passing
	   it to a get/set method.  Otherwise hard to handle,
	   because we don't want to allocate memory here to
	   be freed in the get or set routine. */

	*instdata = (PTR)instance;
	
	STncpy( instance, buf, linstance );
	instance [ linstance ] = EOS;
	if( STlength( buf ) != STlen ( instance ))
	    stat = MO_INSTANCE_TRUNCATED;

	break;

    default:
	stat = MO_BAD_MSG;
    }
    return( stat );
}
Exemple #4
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;
}
Exemple #5
0
static STATUS
myintget( i4  offset,
	 i4  objsize,
	 PTR object,
	 i4  luserbuf,
	 char *userbuf )
{
    STATUS stat = OK;

    char buf[ 20 ];

    CVla( private_num, buf );
    STncpy( userbuf, buf, luserbuf ) ;
    userbuf[ luserbuf ] = EOS;
    if( STlength( buf ) != STlength( userbuf ) )
	stat = MO_VALUE_TRUNCATED;
    return( stat );
}
Exemple #6
0
/*
** Name: PCexec_suid - Execute a command as the ingres user.
**
** Description:
**	This procedure works with the Ingres service to run the given
**	command as the ingres user. It mimicks the "setuid" bit in UNIX.
**
** Inputs:
**	cmdbuf - command to execute as the ingres user
**
** Outputs:
**	none
**
** Returns:
**	OK
**	FAIL
**
** Side Effects:
**	none
**
** History:
**	08-jan-1998 (somsa01)
**	    Created.
**	19-feb-1998 (somsa01)
**	    We need to pass to the service the current working directory
**	    as well.  (Bug #89006)
**	25-feb-1998 (somsa01)
**	    We now have an input file for the process' stdin which
**	    runs through the OpenIngres service.
**	19-jun-1998 (somsa01)
**	    Use SYSTEM_PRODUCT_NAME for the name of the service.
**	10-jul-1998 (kitch01)
**		Bug 91362. If user is 'system' run through OpenIngres service
**		despite having access to server shared memory 'system' does not
**		have required privilege to access semaphores/mutexes.
**	11-jun-1999 (somsa01)
**	    If the command is a startup command, then it is always run through
**	    the Ingres service.
**	03-nov-1999 (somsa01)
**	    A failure from ControlService() should be treated as a severe
**	    error which should not let us continue.
** 	22-jan-2000 (somsa01)
**	    Return the exit code of the spawned process. Also, if the
**	    files exist, truncate them. The service name is now keyed off
**	    of II_INSTALLATION.
**	05-jun-2000 (somsa01)
**	    The Ingres installation may be started as the SYSTEM account,
**	    in which the 'ingres' user will not automatically have access
**	    to the shared memory segments. Therefore, even if the real
**	    user is 'ingres', check to see if he has access.
**	24-oct-2000 (somsa01)
**	    Removed the check on shared memory access. Access to the shared
**	    memory segment does not necessarily mean that the user running
**	    the process does not need to run the specified process as the
**	    Ingres owner. Also, generalized the check of the user with
**	    IDname_service().
**	18-dec-2000 (somsa01)
**	    Modified the cases to run the command "as is" without the Ingres
**	    service.
**	20-mar-2002 (somsa01)
**	    If all is well, return the exit code of the child process that
**	    was executed.
**	29-mar-2002 (somsa01)
**	    Properly return the child process exit code.
**	11-apr-2003 (somsa01)
**	    While waiting for "pending" to not be set, give some CPU back
**	    to the OS.
**      29-Jul-2005 (drivi01)
**	    Allow user to run the command if he/she owns a shared
**	    segment and ingres is not running as a service.
**	06-Dec-2006 (drivi01)
**	    Adding support for Vista, Vista requires "Global\" prefix for
**	    shared objects as well.  Replacing calls to GVosvers with 
**	    GVshobj which returns the prefix to shared objects.
**	    Added PCadjust_SeDebugPrivilege to allow quering of 
**	    System processes.
**	25-Jul-2007 (drivi01)
**		On Vista, PCexec_suid is unable to use SE_DEBUG Privilege
**	    to query process status and retireve its exit code.
**		The routine for monitoring a process and retrieving 
**	    its exit code has been moved to Ingres Service.
**	05-Nov-2009 (wanfr01) b122847
**	    Don't do a PCsleep unless you are waiting for more input
*/
STATUS
PCexec_suid(char *cmdbuf)
{
    EX_CONTEXT		context;
    SERVICE_STATUS	ssServiceStatus;
    LPSERVICE_STATUS	lpssServiceStatus = &ssServiceStatus;
    struct SETUID	setuid;
    DWORD		ProcID;
    HANDLE		SaveStdout;
    SECURITY_ATTRIBUTES	sa;
    CHAR		szRealUserID[25] = "";
    CHAR		*pszRealUserID = szRealUserID;
    CHAR		szServiceUserID[25] = "";
    CHAR		*pszServiceUserID = szServiceUserID;
    DWORD		BytesWritten, BytesRead = 0;
    CHAR		*inst_id;
    CHAR		SetuidShmName[64];
    CHAR		*temp_loc;
    CHAR		InBuf[256], OutBuf[256];
    static CHAR		SetuidPipeName[32];
    CL_ERR_DESC		err_code;
    CHAR		ServiceName[255];
    DWORD		ExitCode = 0;
    CHAR		tchII_INSTALLATION[3];
    BOOL		SetuidDbCmd = FALSE, ServiceCommand = FALSE;
    int			i, cmdlen;
    char		*ObjectPrefix;
	u_i4		drType;
    SC_HANDLE		schSCManager, OpIngSvcHandle;
    BOOL		bServiceStarted = FALSE;

    if (EXdeclare(ex_handler, &context) != OK)
    {
	EXdelete();
	PCexit(FAIL);
    }
    NMgtAt("II_INSTALLATION", &inst_id);
    STcopy(inst_id, tchII_INSTALLATION);

    /*
    ** See if this is a command that MUST be run through the Ingres
    ** service.
    */
    cmdlen = (i4)STlength(cmdbuf);
    for (i = 0; ServiceCommands[i] ; i++)
    {
	if (STbcompare( cmdbuf, cmdlen, ServiceCommands[i],
			(i4)STlength(ServiceCommands[i]), FALSE ) == 0)
	{
	    ServiceCommand = TRUE;
	    break;
	}
    }

    /*
    ** If the user is the same as the user who started the Ingres
    ** service, just spawn the command.
    */
    if (!ServiceCommand)
    {
	IDname(&pszRealUserID);
	if (!IDname_service(&pszServiceUserID) &&
	    STcompare(pszServiceUserID, pszRealUserID) == 0 && 
		PCisAdmin())
	{
	    /*
	    ** Attempt to just execute the command.
	    */
	    return( PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT,
		    (LOCATION *) NULL, &err_code) );
	}
	else
	{
	    /*
	    ** If current user is not the same as service user and ingres is not
	    ** running as a service, check if shared memory segment is owned
	    ** by current user, if user has access to shared segment allow him
	    ** to run the command.
	    */
	    PTR	shmem;
	    SIZE_TYPE	allocated_pages=0;
	    STATUS status;

	    if((status = MEget_pages(ME_MSHARED_MASK, 1, "lglkdata.mem",
	                 &shmem, &allocated_pages, &err_code)) == OK)
	    {
	        STprintf(ServiceName, "%s_Database_%s", SYSTEM_SERVICE_NAME, 
		tchII_INSTALLATION);
	        if ((schSCManager = OpenSCManager(NULL, NULL, 
					SC_MANAGER_CONNECT)) != NULL)
	        {
		    if ((OpIngSvcHandle = OpenService(schSCManager, ServiceName,
					SERVICE_QUERY_STATUS)) != NULL)
		    {
		       if (QueryServiceStatus(OpIngSvcHandle,lpssServiceStatus))
		       {
		    	if (ssServiceStatus.dwCurrentState != SERVICE_STOPPED)
			     bServiceStarted = TRUE;
		        }
		    }
	        }	
	        if (!bServiceStarted)
		    return(PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT,
			(LOCATION *) NULL, &err_code) );
	    }

	}

	/*
	** See if this command is an Ingres command which needs to interact
	** with at least one database.
	*/
	for (i = 0; validSetuidDbCmds[i] ; i++)
	{
	    if (STbcompare( cmdbuf, cmdlen, validSetuidDbCmds[i],
			    (i4)STlength(validSetuidDbCmds[i]), FALSE ) == 0)
	    {
		SetuidDbCmd = TRUE;
		break;
	    }
	}

	/*
	** If the user has access to the Ingres shared memory segment,
	** just spawn the command provided that it is not in the
	** validSetuidDbCmds list.
	*/
	if (!SetuidDbCmd)
	{
	    PTR	shmem;
	    SIZE_TYPE	allocated_pages=0;
	    STATUS	status;

	    if (((status = MEget_pages(ME_MSHARED_MASK, 1, "lglkdata.mem",
		&shmem,
		&allocated_pages, &err_code)) == OK) ||
		(status == ME_NO_SUCH_SEGMENT))
	    {
		if (status != ME_NO_SUCH_SEGMENT)
		    MEfree_pages(shmem, allocated_pages, &err_code);
		
		return( PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT,
			(LOCATION *) NULL, &err_code) );
	    }
	}
    }

    /*
    ** We must run the command through the Ingres service.
    */

    if ( STstrindex(cmdbuf, "-silent", 0, FALSE ) )
	SilentMode = TRUE;

    iimksec(&sa);


	GVshobj(&ObjectPrefix);
	STprintf(SetuidShmName, "%s%sSetuidShm", ObjectPrefix, tchII_INSTALLATION);

    if ( (SetuidShmHandle = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE,
					    FALSE,
					    SetuidShmName)) == NULL )
    {
	error_exit(GetLastError());
	return(FAIL);
    }
    if ( (SetuidShmPtr = MapViewOfFile(SetuidShmHandle,
				       FILE_MAP_WRITE | FILE_MAP_READ,
				       0,
				       0,
				       sizeof(struct SETUID_SHM))) == NULL )
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    /* Set up the information to send to the service. */
    STcopy(cmdbuf, setuid.cmdline);
    GetCurrentDirectory(sizeof(setuid.WorkingDirectory),
			setuid.WorkingDirectory);
	NMgtAt("II_TEMPORARY", &temp_loc);
	drType = GetDriveType(NULL);
	if (drType == DRIVE_REMOTE)
	{
		STcopy(temp_loc, setuid.WorkingDirectory);
	}
    SaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    CVla(GetCurrentProcessId(), setuid.ClientProcID);
    STprintf(SetuidPipeName, "\\\\.\\PIPE\\INGRES\\%s\\SETUID", inst_id);

    /* Set up the stdout file for the command. */
    STprintf(OutfileName, "%s\\%sstdout.tmp", temp_loc, setuid.ClientProcID);
    if ( (OutFile = CreateFile(OutfileName,
			       GENERIC_READ | GENERIC_WRITE,
			       FILE_SHARE_READ | FILE_SHARE_WRITE,
			       &sa,
			       CREATE_ALWAYS,
			       FILE_ATTRIBUTE_NORMAL,
			       NULL)) == INVALID_HANDLE_VALUE )
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    /* Set up the stdin file for the command. */
    STprintf(InfileName, "%s\\%sstdin.tmp", temp_loc, setuid.ClientProcID);
    if ( (InFile = CreateFile(InfileName,
			      GENERIC_READ | GENERIC_WRITE,
			      FILE_SHARE_READ | FILE_SHARE_WRITE,
			      &sa,
			      CREATE_ALWAYS,
			      FILE_FLAG_WRITE_THROUGH,
			      NULL)) == INVALID_HANDLE_VALUE )
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    /* Wait until the service is ready to process our request. */
    while (SetuidShmPtr->pending == TRUE)
	PCsleep(100);
    SetuidShmPtr->pending = TRUE;

    /* Trigger the "setuid" event of the service. */
    if ( (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)) == NULL)
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    STprintf(ServiceName, "%s_Database_%s", SYSTEM_SERVICE_NAME,
	     tchII_INSTALLATION );
	OpIngSvcHandle = OpenService(schSCManager, ServiceName,
						SERVICE_USER_DEFINED_CONTROL);
	if (OpIngSvcHandle == NULL)
	{
		STprintf(ServiceName, "%s_DBATools_%s", SYSTEM_SERVICE_NAME,
	     tchII_INSTALLATION );
		OpIngSvcHandle = OpenService(schSCManager, ServiceName,
						SERVICE_USER_DEFINED_CONTROL);
	}
    if ( OpIngSvcHandle == NULL)
    {
	error_exit(GetLastError());
	return(FAIL);
    }
    if (!ControlService(OpIngSvcHandle, RUN_COMMAND_AS_INGRES,
			lpssServiceStatus))
    {
	error_exit(GetLastError());
	CloseServiceHandle(schSCManager);
	return(FAIL);
    }

    WaitNamedPipe(SetuidPipeName, NMPWAIT_WAIT_FOREVER);

    /* Send the information to the service. */
    if ( (Setuid_Handle = CreateFile(SetuidPipeName,
				     GENERIC_READ|GENERIC_WRITE,
				     FILE_SHARE_READ|FILE_SHARE_WRITE,
				     &sa,
				     OPEN_EXISTING,
				     FILE_ATTRIBUTE_NORMAL,
				     NULL)) == INVALID_HANDLE_VALUE )
    {
	error_exit(GetLastError());
	return(FAIL);
    }
    if (!WriteFile(Setuid_Handle, &setuid, sizeof(struct SETUID),
		   &BytesWritten, NULL))
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    /*
    ** Retrieve information back from the service, and then
    ** disconnect from the pipe.
    */
    if (!ReadFile(Setuid_Handle, &setuid, sizeof(struct SETUID),
		  &BytesRead, NULL))
    {
	error_exit(GetLastError());
	return(FAIL);
    }

    ProcID = setuid.CreatedProcID;
    SetuidShmPtr->pending = FALSE;

    UnmapViewOfFile(SetuidShmPtr);
    SetuidShmPtr = NULL;
    CloseHandle(SetuidShmHandle);

    if ( (ProcID != -1) && (ProcID != -2) )
    {
	/*
	** Wait for the "spawned" process to exit, reading its output
	** from the stdout file.
	*/
	for (;;)
	{
	    if ( ((!ReadFile(OutFile, OutBuf, sizeof(OutBuf), &BytesRead, NULL)
		  || (BytesRead == 0)) && setuid.ExitCode != STILL_ACTIVE ))
		break;

	    if ( BytesRead &&
		 (!WriteFile(SaveStdout, OutBuf, BytesRead, &BytesWritten,
		  NULL)) && setuid.ExitCode != STILL_ACTIVE)
		break;
	    else if (BytesRead < sizeof(OutBuf))
		PCsleep(200);

	    /*
	    ** Currently, the only DBA program which can require
	    ** user input is verifydb. Therefore, when it spits out
	    ** the appropriate messages asking for user input, get
	    ** it from the end user and pass it along to the spawned
	    ** process.
	    */
	    if ( (STrstrindex(OutBuf, "S_DU04FF_CONTINUE_PROMPT", 0, FALSE)
			!= NULL) ||
		 (STrstrindex(OutBuf, "S_DU0300_PROMPT", 0, FALSE) != NULL) )
	    {
		SIflush(stdout);
		MEfill(sizeof(OutBuf), ' ', &OutBuf);
		MEfill(sizeof(InBuf), ' ', &InBuf);
		SIgetrec(InBuf, 255, 0);
		WriteFile(InFile, InBuf, sizeof(OutBuf), &BytesWritten, NULL);
	    }
	}

	ExitCode = setuid.ExitCode;
	CloseHandle(Setuid_Handle);
	CloseHandle(InFile);
	DeleteFile(InfileName);
	CloseHandle(OutFile);
	DeleteFile(OutfileName);
	CloseServiceHandle(OpIngSvcHandle);
	CloseServiceHandle(schSCManager);
        return(ExitCode);
    }
    else
    {
	error_exit(GetLastError());
	return(FAIL);
    }
}
Exemple #7
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);
}
Exemple #8
0
DB_STATUS
adu_copascii(
ADF_CB		*adf_scb,
DB_DATA_VALUE	*dv1,
DB_DATA_VALUE	*rdv)
{
    register char       *p;
    char		temp[ADI_OUTMXFIELD];
    i4			leftfill;
    i4			plen;
    i4			str_len;
    i2			out_width;

    p = temp;

    switch(dv1->db_datatype)
    {
      case DB_INT_TYPE:
        if (dv1->db_length == 8)
        {
            CVla8(*(i8 *) dv1->db_data, p);
        }
        else if (dv1->db_length == 4)
        {
            CVla(*(i4 *) dv1->db_data, p);
        }
        else if (dv1->db_length == 2)
        {
            CVla((i4) *(i2 *) dv1->db_data, p);
        }
        else
        {
            CVla(I1_CHECK_MACRO(*(i1 *) dv1->db_data), p);
        }

        break;

      case DB_DEC_TYPE:
	{
	    i4		pr = DB_P_DECODE_MACRO(dv1->db_prec);
	    i4		sc = DB_S_DECODE_MACRO(dv1->db_prec);
	    i4		available_width = rdv->db_length;
	    char	decimal = (adf_scb->adf_decimal.db_decspec
					? (char) adf_scb->adf_decimal.db_decimal
					: '.'
				  );
				  
	    if (    rdv->db_datatype == DB_VCH_TYPE
		||  rdv->db_datatype == DB_TXT_TYPE
		||  rdv->db_datatype == DB_LTXT_TYPE
	       )
		available_width -= DB_CNTSIZE;

	    /* now convert to ascii: use formula from lenspec for length, get
	    ** scale # of digits after decimal point, use left-justify
	    */
	    if (CVpka((PTR)dv1->db_data, pr, sc, decimal,
		    AD_PS_TO_PRN_MACRO(pr, sc), sc, CV_PKLEFTJUST, p, &str_len)
		== CV_OVERFLOW)
	    {
		/* this should never happen */
		return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }

	    if (str_len > available_width)
		return(adu_error(adf_scb, E_AD1030_F_COPY_STR_TOOSHORT, 0));
	}
        break;

      case DB_FLT_TYPE:
	{
	    char    decimal = (adf_scb->adf_decimal.db_decspec ?
				(char) adf_scb->adf_decimal.db_decimal : '.');
	    i4	    available_width = rdv->db_length;


	    if (    rdv->db_datatype == DB_VCH_TYPE
		||  rdv->db_datatype == DB_TXT_TYPE
		||  rdv->db_datatype == DB_LTXT_TYPE
	       )
		available_width -= DB_CNTSIZE;

	    if (dv1->db_length == 4)
	    {
		f8 f8tmp = (f8) *(f4 *) dv1->db_data;

                /*  BUG : b119968
		**
		**  CVfa is a utility routine for both f8 and f4 floats.
		**  In the f4 case, the value is converted to f8 prior 
		**  to call (as here).
		**
		**  This works well except for the boundary case, where 
		**  the f4 is FLT_MAX. In this case, an effective 
		**  rounding up of the f8 that occurs as we convert to 
		**  a string (eventually through fcvt) "overflows" the 
		**  original f4 value.
		**
		**  We bump down the last sig bit of the f4, and then
		**  we have no problems.
		*/
		if ( f8tmp == FLT_MAX )
		{
		    f8tmp = FLT_MAX_ROUND;
		} 
                else if ( f8tmp == -FLT_MAX ) 
		{
		    f8tmp = -FLT_MAX_ROUND;
		} 
		CVfa(f8tmp,
		     adf_scb->adf_outarg.ad_f4width,
		     adf_scb->adf_outarg.ad_f4prec,
		     adf_scb->adf_outarg.ad_f4style,
		     decimal, p, &out_width);

		if (out_width > available_width)
		    return(adu_error(adf_scb, E_AD1030_F_COPY_STR_TOOSHORT, 0));
	    }
	    else
	    {
		CVfa(*(f8 *)dv1->db_data,
		     adf_scb->adf_outarg.ad_f8width,
		     adf_scb->adf_outarg.ad_f8prec,
		     adf_scb->adf_outarg.ad_f8style,
		     decimal, p, &out_width);

		if (out_width > available_width)
		    return(adu_error(adf_scb, E_AD1030_F_COPY_STR_TOOSHORT, 0));
	    }
	}
	break;

      default:
	return(adu_error(adf_scb, E_AD5002_BAD_NUMBER_TYPE, 0));
    }

    while (*p == ' ')
        p++;

    /*
    ** TEXT, VARCHAR, and LONGTEXT are variable length copies,
    ** so no need to pad on the left.
    */
    if (    rdv->db_datatype == DB_TXT_TYPE
	||  rdv->db_datatype == DB_VCH_TYPE
	||  rdv->db_datatype == DB_LTXT_TYPE
       )	
    {
        return(adu_movestring(adf_scb, (u_char *) p, 
				(i4) STlength(p), dv1->db_datatype, rdv));
    }

    /*
    ** At this point the result type can be C or CHAR
    */
    plen     = min(STlength(p), rdv->db_length);
    leftfill = rdv->db_length - plen;

    MEfill(leftfill, ' ', rdv->db_data);
    MEcopy((PTR)p, plen, (PTR)((char *)rdv->db_data + leftfill));

    return(E_DB_OK);
}
Exemple #9
0
DB_STATUS
adu_ascii(
ADF_CB			*adf_scb,
register DB_DATA_VALUE	*dv1,
DB_DATA_VALUE		*rdv)
{
    DB_STATUS           db_stat = E_DB_OK;
    register char       *p;
    char		temp[ADI_OUTMXFIELD]; /* could probably be smaller */
    u_char		*str_addr;
    i4			str_len;
    i2			reswidth;
    bool		char_text = FALSE;
    i8			i8_tmp = 0;

    p = temp;

    switch(dv1->db_datatype)
    {
      case DB_INT_TYPE:
        if (dv1->db_length == 8)
	{
            CVla8(*(i8 *) dv1->db_data, p);
	}
        else if (dv1->db_length == 4)
        {
            CVla(*(i4 *) dv1->db_data, p);
        }
        else if (dv1->db_length == 2)
        {
            CVla((i4) (*(i2 *) dv1->db_data), p);
        }
        else
        {
            CVla(I1_CHECK_MACRO(*(i1 *) dv1->db_data), p);
        }

        break;

      case DB_BOO_TYPE:
        if (((DB_ANYTYPE *)dv1->db_data)->db_booltype == DB_FALSE)
            STcopy("FALSE", p);
        else
            STcopy("TRUE", p);
        break;

      case DB_VCH_TYPE:
      case DB_CHA_TYPE:
      case DB_CHR_TYPE:
      case DB_TXT_TYPE:
      case DB_LTXT_TYPE:
      case DB_BYTE_TYPE:
      case DB_VBYTE_TYPE:
	if ((db_stat = adu_3straddr(adf_scb, dv1, (char **) &str_addr)))
	    return(db_stat);
	if ((db_stat = adu_size(adf_scb, dv1, &str_len)))
	    return(db_stat);
        if ((db_stat = adu_movestring(adf_scb, str_addr, str_len, 
					dv1->db_datatype, rdv)))
	    return(db_stat);
        char_text = TRUE;

        break;

      case DB_DEC_TYPE:
	{
	    i4		pr = DB_P_DECODE_MACRO(dv1->db_prec);
	    i4		sc = DB_S_DECODE_MACRO(dv1->db_prec);
	    char	decimal = (adf_scb->adf_decimal.db_decspec
					? (char) adf_scb->adf_decimal.db_decimal
					: '.'
				  );
				  
	    /* now convert to ascii: use formula from lenspec for length, get
	    ** scale # of digits after decimal point, use left-justify option
	    */
	    if (CVpka((PTR)dv1->db_data, pr, sc, decimal,
		    AD_PS_TO_PRN_MACRO(pr, sc), sc, CV_PKLEFTJUST, p, &str_len)
		== CV_OVERFLOW)
	    {
		/* this should never happen */
		return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }
	}
        break;

      case DB_FLT_TYPE:
	{
	    char    decimal = (adf_scb->adf_decimal.db_decspec ?
				(char) adf_scb->adf_decimal.db_decimal : '.');
	    
	    if (dv1->db_length == 4)
	    {
		CVfa((f8) *(f4 *) dv1->db_data,
		     adf_scb->adf_outarg.ad_f4width,
		     adf_scb->adf_outarg.ad_f4prec,
		     adf_scb->adf_outarg.ad_f4style,
		     decimal, p, &reswidth);
	    }
	    else
	    {
		CVfa(*(f8 *)dv1->db_data,
		     adf_scb->adf_outarg.ad_f8width,
		     adf_scb->adf_outarg.ad_f8prec,
		     adf_scb->adf_outarg.ad_f8style,
		     decimal, p, &reswidth);
	    }
	}
        break;

      case DB_DTE_TYPE:
      case DB_ADTE_TYPE:
      case DB_TMWO_TYPE:
      case DB_TMW_TYPE:
      case DB_TME_TYPE:
      case DB_TSWO_TYPE:
      case DB_TSW_TYPE:
      case DB_TSTMP_TYPE:
      case DB_INYM_TYPE:
      case DB_INDS_TYPE:
	return( adu_6datetostr( adf_scb, dv1, rdv));
	       
      case DB_MNY_TYPE:
	return( adu_9mnytostr( adf_scb, dv1, rdv));

      case DB_LVCH_TYPE:
      case DB_LBYTE_TYPE:
      case DB_GEOM_TYPE:
      case DB_POINT_TYPE:
      case DB_MPOINT_TYPE:
      case DB_LINE_TYPE:
      case DB_MLINE_TYPE:
      case DB_POLY_TYPE:
      case DB_MPOLY_TYPE:
      case DB_GEOMC_TYPE:
      case DB_LNVCHR_TYPE:
      case DB_LCLOC_TYPE:
      case DB_LBLOC_TYPE:
      case DB_LNLOC_TYPE:
	return( adu_lvch_move( adf_scb, dv1, rdv));
	
      case DB_BIT_TYPE:
      case DB_VBIT_TYPE:
	return( adu_bit2str( adf_scb, dv1, rdv));
	
      case DB_LOGKEY_TYPE:
      case DB_TABKEY_TYPE:
	return( adu_3logkeytostr( adf_scb, dv1, rdv));

      default:
	return(adu_error(adf_scb, E_AD2090_BAD_DT_FOR_STRFUNC, 0));
    }

    if (!char_text)
    {
        if ((db_stat = adu_movestring(adf_scb, (u_char *) p,
				      (i4) STlength(p), 
				      dv1->db_datatype, rdv))
	    != E_DB_OK
	   )
	    return(db_stat);
    }

    return(E_DB_OK);
}
Exemple #10
0
/*{
** Name: psy_print	- Format query text to send to user
**
** Description:
**      This function decodes query text that comes from the iiqrytext relation
**	and formats it to send to the user.  It is useful for the "help permit",
**	"help integrity", and "help view" commands.
**
**	Query text stored in the iiqrytext relation consists of human-readable
**	text and special symbols.  Some of these special symbols are numbers
**	and strings sent from EQUEL or ESQL programs.  Others stand for table
**	names, range variables, and column numbers.  This functio decodes all
**	this stuff, and puts the result into a chain of PSY_QTEXT blocks to be
**	sent back to the user.
**
** Inputs:
**	mstream				Memory stream to allocate blocks from
**	map				map of range var numbers to those
**					in rngtab.
**	block				Current query text block
**      text                            Pointer to the query text
**	length				Length of the query text
**	rngtab				The range table (used for decoding the
**					special symbol standing for range
**					variable numbers, and column numbers).
**					The result range variable should stand
**					for the table we're getting help on.
**	err_blk				Filled in if an error happens
**
** Outputs:
**      err_blk                         Filled in if an error happened
**	Returns:
**	    E_DB_OK			Success
**	    E_DB_ERROR			Non-catastrophic failure
**	    E_DB_FATAL			Catastrophic failure
**	Exceptions:
**	    none
**
** Side Effects:
**	    Sends query text to user
**
** History:
**      15-jul-86 (jeff)
**          written
**	14-jul-93 (ed)
**	    replacing <dbms.h> by <gl.h> <sl.h> <iicommon.h> <dbdbms.h>
*/
DB_STATUS
psy_print(
	PSF_MSTREAM	   *mstream,
	i4		    map[],
	PSY_QTEXT	   **block,
	u_char             *text,
	i4		   length,
	PSS_USRRANGE	   *rngtab,
	DB_ERROR	   *err_blk)
{
    char                buf[1024 + DB_TAB_MAXNAME];
    i4                  i4align;
    i2                  i2align;
    f8                  f8align;
    register u_char	*p;
    register i4	j;
    register i4	i;
    PSS_RNGTAB		*lastvar = (PSS_RNGTAB *) NULL;
    DB_STATUS		status;
    i4			slength;

    /* Put out range statements */
    for (i = 0; i < PST_NUMVARS; i++)
    {
	/* Only look at range vars that are being used */
	if (!rngtab->pss_rngtab[i].pss_used ||
	    rngtab->pss_rngtab[i].pss_rgno < 0)
	{
	    continue;
	}

	status = psy_put(mstream, (char*) "range of ", 
	    (i4) sizeof("range of ") - 1, block, 
	    err_blk);
	if (DB_FAILURE_MACRO(status))
	    return (status);

	/* NULL terminate and trim blanks from range variable name */
	MEcopy(rngtab->pss_rngtab[i].pss_rgname, DB_TAB_MAXNAME, buf);
	buf[DB_TAB_MAXNAME] = '\0';
	slength = STtrmwhite(buf);
	status = psy_put(mstream, buf, slength, block, err_blk);
	if (DB_FAILURE_MACRO(status))
	    return (status);
	status = psy_put(mstream, " is ", (i4) sizeof(" is ") - 1,
	     block, err_blk);
	if (DB_FAILURE_MACRO(status))
	    return (status);

	/* NULL terminate and trim blanks from table name */
	MEcopy((char *) &rngtab->pss_rngtab[i].pss_tabname, DB_TAB_MAXNAME, buf);
	buf[DB_TAB_MAXNAME] = '\0';
	slength = STtrmwhite(buf);
	status = psy_put(mstream, buf, slength, block, err_blk);
	if (DB_FAILURE_MACRO(status))
	    return (status);

	/* Newline after every range statement */
	status = psy_put(mstream, (char*) "\n", (i4) 1, block, err_blk);
	if (DB_FAILURE_MACRO(status))
	    return (status);
    }

    for (p = text; p < (u_char*) text + length;)
    {
	switch (*p++)
	{
	case PSQ_HVSTR:	    /* String sent from user program */
	    slength = STlength((char*) p);

	    /* Emit opening quote */
	    status = psy_put(mstream, (char *) "\"", 1, block, err_blk);
	    if (DB_FAILURE_MACRO(status))
		return (status);

	    for (j = slength; j > 0; j--, p++)
	    {
		if (*p == '"')
		{
		    /* Escape any quote characters */
		    status = psy_put(mstream, "\\\"", 2, block, err_blk);
		    if (DB_FAILURE_MACRO(status))
			return (status);
		}
		else if (!CMprint(p))
		{
		    /* Non-printing characters show up as escape sequence */
		    STprintf(buf, "\\%o", *p);
		    status = psy_put(mstream, buf, (i4) STlength(buf),
			block, err_blk);
		    if (DB_FAILURE_MACRO(status))
			return (status);
		}
		else
		{
		    status = psy_put(mstream, (char*) p, 1, block, err_blk);
		    if (DB_FAILURE_MACRO(status))
			return (status);
		}
	    }
	    break;

	case PSQ_HVF8:	    /* f8 sent from user program */
	    MEcopy((char *) p, sizeof(f8align), (char *) &f8align);
	    STprintf(buf, "%f", f8align);
	    status = psy_put(mstream, buf, (i4) STlength(buf), block, err_blk);
	    if (DB_FAILURE_MACRO(status))
		return (status);
	    p += sizeof(f8align);
	    break;

	case PSQ_HVI4:	    /* i4 sent from user program */
	    MEcopy((char *) p, sizeof(i4align), (char *) &i4align);
	    CVla(i4align, buf);
	    status = psy_put(mstream, buf, (i4) STlength(buf), block, err_blk);
	    if (DB_FAILURE_MACRO(status))
		return (status);
	    p += sizeof(i4align);
	    break;

	case PSQ_HVI2:	    /* i2 sent from user program */
	    MEcopy((char *) p, sizeof(i2align), (char *) &i2align);
	    CVla((i4) i2align, buf);
	    status = psy_put(mstream, buf, (i4) STlength(buf), block, err_blk);
	    if (DB_FAILURE_MACRO(status))
		return (status);
	    p += sizeof(i2align);
	    break;

	case DB_INTRO_CHAR: /* Intro char for special sequence */
	    switch (*p++)
	    {
	    case DB_RNG_VAR:
		/* Put a blank before the table name */
		status = psy_put(mstream, " ", 1, block, err_blk);
		if (DB_FAILURE_MACRO(status))
		    return (status);

		/* Get the range variable number */
		MEcopy((char *) p, sizeof(i4align), (char *) &i4align);
		p += sizeof(i4align);

		i4align = map[i4align];
		/* Look up range variable number */
		for (j = 0; j < PST_NUMVARS; j++)
		{
		    if (rngtab->pss_rngtab[j].pss_used &&
			rngtab->pss_rngtab[j].pss_rgno == i4align)
		    {
			break;
		    }
		}

		/* If found, give variable name, otherwise question marks */
		if (j < PST_NUMVARS)
		{
		    /* trim trailing blanks and NULL terminate */
		    MEcopy(rngtab->pss_rngtab[j].pss_rgname, DB_TAB_MAXNAME, buf);
		    buf[DB_TAB_MAXNAME] = '\0';
		    slength = STtrmwhite(buf);
		    status = psy_put(mstream, buf, slength, block, err_blk);
		    if (DB_FAILURE_MACRO(status))
			return (status);
		    /* Remember the range variable for when we get the colnum */
		    lastvar = &rngtab->pss_rngtab[j];
		}
		else
		{
		    lastvar = (PSS_RNGTAB*) 0;
		    /* Put question marks if not found */
		    status = psy_put(mstream, "???", 3, block, err_blk);
		    if (DB_FAILURE_MACRO(status))
			return (status);
		}
		break;

	    case DB_COL_NUM:	    /* Column number for a range var */

		/* Get the column number */
		MEcopy((char *) p, sizeof(i4align), (char *) &i4align);
		p += sizeof(i4align);

		/* If there was no range variable, put question marks */
		if (lastvar != (PSS_RNGTAB *) NULL)
		{
		    status = psy_put(mstream, 
			lastvar->pss_attdesc[i4align]->att_nmstr,
			lastvar->pss_attdesc[i4align]->att_nmlen,
			block, err_blk);
		    if (DB_FAILURE_MACRO(status))
			return (status);
		}
		else
		{
		    /* Don't know column name, just give question marks */
		    status = psy_put(mstream, "???", 3, block, err_blk);
		    if (DB_FAILURE_MACRO(status))
			return (status);
		}

		/* Put a blank after the column name */
		status = psy_put(mstream, " ", 1, block, err_blk);
		if (DB_FAILURE_MACRO(status))
		    return (status);

		break;

	    case DB_TBL_NM:
		/* The table name is in the result slot of the range table */

		/* Put a blank before the table name */
		status = psy_put(mstream, " ", 1, block, err_blk);
		if (DB_FAILURE_MACRO(status))
		    return (status);

		/* NULL terminate and trim blanks from the table name */
		MEcopy((char *) &rngtab->pss_rsrng.pss_tabname,
		    sizeof(DB_TAB_NAME), buf);
		buf[DB_TAB_MAXNAME] = '\0';
		slength = STtrmwhite(buf);
		status = psy_put(mstream, buf, slength, block, err_blk);
		if (DB_FAILURE_MACRO(status))
		    return (status);

		/* Put a blank after the table name */
		status = psy_put(mstream, " ", 1, block, err_blk);
		if (DB_FAILURE_MACRO(status))
		    return (status);

		break;

	    case DB_RES_COL:	/* Result column: column in result table */
		/* Put a blank before the column name */
		status = psy_put(mstream, " ", 1, block, err_blk);
		if (DB_FAILURE_MACRO(status))
		    return (status);

		/* Get the column number for the result column */
		MEcopy((char *) p, sizeof(i4align), (char *) &i4align);
		p += sizeof(i4align);

		/* Get the column name from the result range variable */
		lastvar = &rngtab->pss_rsrng;
		status = psy_put(mstream,
			lastvar->pss_attdesc[i4align]->att_nmstr,
			lastvar->pss_attdesc[i4align]->att_nmlen,
			block, err_blk);
		if (DB_FAILURE_MACRO(status))
		    return (status);

		/* Put a blank after the column name */
		status = psy_put(mstream, " ", 1, block, err_blk);
		if (DB_FAILURE_MACRO(status))
		    return (status);
		break;

	    default:
		/* Unknown special sequence: just put out as it came in */
		status = psy_put(mstream, (char*) p - 1, 2, block, err_blk);
		if (DB_FAILURE_MACRO(status))
		    return (status);
		break;
	    }
	    break;
	default:
	    /* No special case, just put the char */
	    status = psy_put(mstream, (char*) p - 1, 1, block, err_blk);
	    break;
	}
    }

    /* Put a newline just after the statement */
    status = psy_put(mstream, "\n", 1, block, err_blk);
    return (status);
}
Exemple #11
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);
}
Exemple #12
0
DB_STATUS
psy_kalarm(
	PSY_CB             *psy_cb,
	PSS_SESBLK	   *sess_cb)
{
    RDF_CB              rdf_cb;
    RDR_RB		*rdf_rb = &rdf_cb.rdf_rb;
    RDF_CB              rdf_inv_cb;
    DB_STATUS		status;
    DB_SECALARM		*atuple= &psy_cb->psy_tuple.psy_alarm;
    i4			i;
    PSY_OBJ		*psy_obj;
    bool		loop=FALSE;


    /* Fill in the RDF request blocks */
    pst_rdfcb_init(&rdf_cb, sess_cb);
    rdf_rb->rdr_types_mask  = RDR_SECALM;	/* Alarm deletion */
    rdf_rb->rdr_update_op   = RDR_DELETE;
    rdf_rb->rdr_qrytuple    = (PTR)atuple;/* Alarm tuple */

    pst_rdfcb_init(&rdf_inv_cb, sess_cb);
    rdf_inv_cb.rdf_rb.rdr_types_mask |= RDR_SECALM;

    do
    {
	/*
	** Loop through each alarm in turn deleting them.
	** User may have specified alarms by name or by number, or by all
	*/
	if (psy_cb->psy_numnms == 0 && 
	    (PSY_OBJ*)psy_cb->psy_objq.q_next ==  (PSY_OBJ*)&psy_cb->psy_objq)
	{
	    /*
	    ** Drop all alarms on the indicated object
	    */
	    rdf_rb->rdr_types_mask  |= RDR_DROP_ALL;	
	    STmove(ERx("all alarms"),' ',
			sizeof(atuple->dba_alarmname),
			(char*)&atuple->dba_alarmname);
	    status = rdf_call(RDF_UPDATE, (PTR) &rdf_cb);	/* Destroy alarm */
	    if (status != E_DB_OK)
	    {
	        _VOID_ psf_rdf_error(RDF_UPDATE, &rdf_cb.rdf_error, 
			&psy_cb->psy_error);
	    }
	}
	if(psy_cb->psy_numnms)
	{
	    /*
	    ** Dropping alarms by number, so walk through all numbers dropping.
	    */
	    for (i=0;i <psy_cb->psy_numnms; i++)
	    {
		char tmpstr[64];
		CVla((i4)psy_cb->psy_numbs[i],tmpstr);
		STmove(tmpstr,' ', 
			sizeof(atuple->dba_alarmname),
			(char*)&atuple->dba_alarmname);
	     	atuple->dba_alarmno=psy_cb->psy_numbs[i];
	     	status = rdf_call(RDF_UPDATE, (PTR) &rdf_cb);
	     	if (status != E_DB_OK)
	     	{
		     _VOID_ psf_rdf_error(RDF_UPDATE, &rdf_cb.rdf_error, 
			&psy_cb->psy_error);
		     break;
	        }
	    }
	}
	if((PSY_OBJ*)psy_cb->psy_objq.q_next!= (PSY_OBJ*)&psy_cb->psy_objq)
	{
	    /*
	    ** Dropping alarms by name, so walk through all names dropping
	    */
	    for (psy_obj  = (PSY_OBJ *)  psy_cb->psy_objq.q_next;
	      psy_obj != (PSY_OBJ *) &psy_cb->psy_objq;
	      psy_obj  = (PSY_OBJ *)  psy_obj->queue.q_next
	    )
	    {
	     	MEcopy((PTR)&psy_obj->psy_objnm,
		    sizeof(atuple->dba_alarmname), (PTR)&atuple->dba_alarmname);
	     	atuple->dba_alarmno=0;
	     	status = rdf_call(RDF_UPDATE, (PTR) &rdf_cb);/* Destroy alarm */
	     	if (status != E_DB_OK)
	     	{
		    _VOID_ psf_rdf_error(RDF_UPDATE, &rdf_cb.rdf_error, 
			&psy_cb->psy_error);
		    break;
	         }
	    }
	}
    }
    while(loop);

    if(status==E_DB_OK && atuple->dba_objtype==DBOB_TABLE)
    {
	/*
	** Invalidate table infoblk from RDF cache.
	*/
	STRUCT_ASSIGN_MACRO(atuple->dba_objid, rdf_inv_cb.rdf_rb.rdr_tabid);
	status = rdf_call(RDF_INVALIDATE, (PTR) &rdf_inv_cb); /* drop infoblk */
	if (DB_FAILURE_MACRO(status))
	{
	    (VOID) psf_rdf_error(RDF_INVALIDATE, &rdf_inv_cb.rdf_error,
				&psy_cb->psy_error);
	    return(status);
	}
    }
    return (status);
} /* psy_kalarm */
Exemple #13
0
/*
** Name: psl_lm4_setlockparm_num()  - perform semantic action for SETLOCKPARM
**				      production when the characteristic value
**				      has been specified as a number or a string
**				      constant containing a number
**
** Input:
**	char_type		    characteristic type
**	char_val		    value as specified by the user
**	sess_cb			    PSF session CB
**	    pss_distrib	    	    DB_3_DDB_SESS if distributed thread
**	    pss_stmt_flags  	    PSS_SET_LOCKMODE_SESS if SET LOCKMODE
**				    SESSION (distributed thread only)
**	    pss_object		    points to DMC_CB (or QEF_RCB) structure
**		dmc_char_array	    characteristics array
**		dmc_sl_scope	    scope of SET LOCKMODE
**	    pss_auxrng
**		pss_rerng	    if setting lockmode on a table, table's
**				    description can be found here
**
** Output:
**	err_blk		    filled in if an error occurred
**
** Returns:
**	E_DB_{OK, ERROR, SEVERE}
**
** Side effects:
**	None
**
**  History:
**	07-mar-91 (andre)
**	    plagiarized from SETLOCKPARM production
**	21-apr-92 (barbara)
**	    Added support for Sybil.  For distributed thread, on
**	    SET LOCKMODE SESSION .. TIMEOUT we set timeout value
**	    specifically for QEF.
**	19-oct-92 (barbara)
**	    Test for non_distrib before testing dmc_cb fields (because
**	    Star doesn't have valid dmc_cb).
*/
DB_STATUS
psl_lm4_setlockparm_num(
	i4	    char_type,
	i4	    char_val,
	PSS_SESBLK  *sess_cb,
	DB_ERROR    *err_blk)
{
    i4		err_code, err_no = 0L;
    DMC_CHAR_ENTRY	*chr;
    DMC_CB		*dmc_cb;
    bool		not_distr = ~sess_cb->pss_distrib & DB_3_DDB_SESS;


    if (not_distr)
    {
    	dmc_cb = (DMC_CB *) sess_cb->pss_object;

    	if (dmc_cb->dmc_char_array.data_in_size / sizeof (DMC_CHAR_ENTRY) ==
	    MAX_LOCKMODE_CHARS)
    	{
	    (VOID) psf_error(5931L, 0L, PSF_USERERR, &err_code, err_blk, 0);
	    return (E_DB_ERROR);	/* non-zero return means error */
    	}   

        chr = (DMC_CHAR_ENTRY *)
	    ((char *) dmc_cb->dmc_char_array.data_address +
	     dmc_cb->dmc_char_array.data_in_size);
    }

    switch (char_type)
    {
	case LOCKLEVEL:
	    /* Can't set locklevel to a number */
	    err_no = 5924L;
	    break;

	case READLOCK:
	    /* Can't set readlocks to a number */
	    err_no = 5925L;
	    break;

	case MAXLOCKS:
	    if (not_distr)	
	    {
	    	chr->char_id = DMC_C_LMAXLOCKS;
	    }
	    break;

	case TIMEOUT:
	{
	    extern PSF_SERVBLK  *Psf_srvblk;

	    /*
	    ** if server was started with OPF flag which may result in
	    ** deadlock when accesing SCONSUR catalogs, iihistogram, and
	    ** iistatistics, we have to prevent user from specifying
	    ** TIMEOUT=0 for any of these catalogs
	    */

	    if (not_distr &&
		Psf_srvblk->psf_flags & PSF_NO_ZERO_TIMEOUT &&
		dmc_cb->dmc_sl_scope == DMC_SL_TABLE) 
	    {
		DB_TAB_ID	*tabid = &dmc_cb->dmc_table_id;
		PSS_RNGTAB	*tbl = &sess_cb->pss_auxrng.pss_rsrng;
		i4		mask = tbl->pss_tabdesc->tbl_status_mask;

		if (mask & DMT_CATALOG
		    &&
		    char_val == 0L
		    &&
		    (mask & DMT_CONCURRENCY
		     ||
		     tabid->db_tab_base == DM_B_STATISTICS_TAB_ID &&
		     tabid->db_tab_index == DM_I_STATISTICS_TAB_ID
		     ||
		     tabid->db_tab_base == DM_B_HISTOGRAM_TAB_ID  &&
		     tabid->db_tab_index == DM_I_HISTOGRAM_TAB_ID
		    )
		   )
		{
		    (VOID) psf_error(E_PS0352_ILLEGAL_0_TIMEOUT, 0L,
			PSF_USERERR, &err_code, err_blk, 1,
			psf_trmwhite(sizeof(tbl->pss_tabname),
				     (char *) &tbl->pss_tabname),
			&tbl->pss_tabname);
		    return (E_DB_ERROR);
		}
	    }
	    
	    if (not_distr)
	    {
	    	chr->char_id = DMC_C_LTIMEOUT;
	    }
	    else if (sess_cb->pss_stmt_flags & PSS_SET_LOCKMODE_SESS)
	    {
	    	/*
	    	** The distributed server is interested in the value from 
	    	** the SETLOCKKEY production when the SETLOCKSCOPE value
	    	** was session; otherwise the set statement is just
	    	** pased on to the LDBs.
	    	*/
		((QEF_RCB*)sess_cb->pss_object)->qef_r3_ddb_req.
			qer_d14_ses_timeout = char_val;
	    }
	    break;
	}

	default:
	    /* Unknown "set lockmode" parameter */
	    (VOID) psf_error(E_PS0351_UNKNOWN_LOCKPARM, 0L, PSF_INTERR, 
		&err_code, err_blk, 1,
		(i4) sizeof(char_type), &char_type);
	    return (E_DB_SEVERE);    /* non-zero return means error */
    }

    if (err_no != 0L)
    {
	char	num_buf[30];

	CVla((i4) char_val, num_buf);
	(VOID) psf_error(err_no, 0L, PSF_USERERR, &err_code, err_blk, 1,
	    (i4) STlength(num_buf), num_buf);
	return (E_DB_ERROR);    /* non-zero return means error */
    }
    else if (not_distr)
    {
	chr->char_value = char_val;
	dmc_cb->dmc_char_array.data_in_size += sizeof (DMC_CHAR_ENTRY);
    }

    return(E_DB_OK);
}