Ejemplo n.º 1
0
bool
ascs_chk_priv( char *user_name, char *priv_name )
{
	char	pmsym[128], userbuf[DB_OWN_MAXNAME+1], *value, *valueptr ;
	char	*strbuf = 0;
	int	priv_len;

        /* 
        ** privileges entries are of the form
        **   ii.<host>.*.privilege.<user>:   SERVER_CONTROL,NET_ADMIN,...
	**
	** Currently known privs are:  SERVER_CONTROL,NET_ADMIN,
	**  	    MONITOR,TRUSTED
        */

	STlcopy( user_name, userbuf, DB_OWN_MAXNAME );
	STtrmwhite( userbuf );
	STprintf(pmsym, "$.$.privileges.user.%s", userbuf);
	
	/* check to see if entry for given user */
	/* Assumes PMinit() and PMload() have already been called */

	if( PMget(pmsym, &value) != OK )
	    return FALSE;
	
	valueptr = value ;
	priv_len = STlength(priv_name) ;

	/*
	** STindex the PM value string and compare each individual string
	** with priv_name
	*/
	while ( *valueptr != EOS && (strbuf=STindex(valueptr, "," , 0)))
	{
	    if (!STscompare(valueptr, priv_len, priv_name, priv_len))
		return TRUE ;

	    /* skip blank characters after the ','*/	
	    valueptr = STskipblank(strbuf+1, 10); 
	}

	/* we're now at the last or only (or NULL) word in the string */
	if ( *valueptr != EOS  && 
              !STscompare(valueptr, priv_len, priv_name, priv_len))
		return TRUE ;

	return FALSE;
}
Ejemplo n.º 2
0
/*
** Name: WTSOpenUpLoad() -
**
** Description:
**
** Inputs:
**      contentType
**      session
**
** Outputs:
**
** Returns:
**	GSTATUS	:	GSTAT_OK
**
** Exceptions:
**	None
**
** Side Effects:
**	None
**
** History:
*/
GSTATUS
WTSOpenUpLoad(
    char        *contentType,
    WTS_SESSION *session)
{
    GSTATUS     err;
    i4          length = STlength(MULTIPART);
    PWTS_UPLOAD load = NULL;
    char*       bound;
    i4          blen;

    if (contentType != NULL &&
        STscompare(contentType, length, MULTIPART, length) == 0)
    {
        session->status = UPLOAD;
        if ((err = GAlloc ((char**)&load, sizeof(WTS_UPLOAD),
            FALSE)) == GSTAT_OK)
        {
            session->load = load;
            bound = STindex (contentType, BOUNDARY, 0) + STlength(BOUNDARY);
            blen  = STlength (bound);

            /*
            ** Allocate space for a start boundary and and en boundary
            ** each having the delimiters and null terminator.
            */
            if (((err = GAlloc (&load->start, blen + 3, FALSE)) == GSTAT_OK) &&
                ((err = GAlloc (&load->end, blen + 5, FALSE)) == GSTAT_OK))
            {
                STcopy ("--",load->start);
                STlcopy (bound, load->start + 2, blen);
                STcopy (load->start, load->end);
                STcat (load->end, "--");
            }
            load->state = US_BEGIN;
        }
    }
    else
    {
        session->status = NO_UPLOAD;
        session->load   = NULL;
    }
    session->list = NULL;
    session->variable = NULL;
    session->vlen = 0;

    return(GSTAT_OK);
}
Ejemplo n.º 3
0
void 
main(int argc, char *argv[])
{
#define 	MAXBUF	4095
#define 	MAX_NAME  32	

	char 		buf[ MAXBUF+1 ];
	char 		repbuf[ MAXBUF+1 ];
	int		iarg, ibuf, ichr;
	char		*database = NULL;
	char 		username[MAX_NAME] = {""};
	LOCATION	tloc;
	LOCATION        loc_out;
	LOCATION        loc_in;
	char            loc_buf[MAX_LOC + 1];
	char            tmp_buf[MAX_LOC + 1];
	char			otmp_buf[MAX_LOC + 1];
	char		dev[MAX_LOC + 1];
	char		path[MAX_LOC + 1];
	char		fprefix[MAX_LOC + 1];
	char		fsuffix[MAX_LOC + 1];
	char		version[MAX_LOC + 1];
	char            odev[MAX_LOC + 1];
	char            opath[MAX_LOC + 1];
	char            ofprefix[MAX_LOC + 1];
	char            ofsuffix[MAX_LOC + 1];
	char            oversion[MAX_LOC + 1];
	char            *new_filename;
	char		*temploc;
	CL_ERR_DESC 	err_code;
	char 		*p1 = NULL;
	bool		usergiven = FALSE;
	bool		Repmod = FALSE;
	bool		nowait = TRUE;
	char	 	waitflag[3];
	
	
	if (argc < 2) 
	{
		usage();
	    PCexit(FAIL);
	}
	
	/* Get the temporary path location */	
	NMloc(TEMP, PATH, NULL, &tloc);		
	LOcopy(&tloc, tmp_buf, &loc_in);
	LOtos(&tloc, &temploc);
	LOcopy(&tloc, otmp_buf, &loc_out);
	     	
	/* Get the new filename for path location */	
	LOuniq(ERx("usrmod"), ERx("sql"), &loc_in);	
	LOtos(&loc_in, &new_filename);
	
	LOuniq(ERx("usrmod"), ERx("out"), &loc_out);

	/* Get just the filename for copydb code   */	
	LOdetail(&loc_in, dev, path, fprefix, fsuffix, version); 
	if ( *fsuffix !=  '\0' )
	{
	    STcat(fprefix, ".");
	    STcat(fprefix, fsuffix);
	}
       /* Get just the filename for copydb code   */
         LOdetail(&loc_out, odev, opath, ofprefix, ofsuffix,oversion);
		STcat(ofprefix, ".");
		STcat(ofprefix, ofsuffix);
	

	STprintf(buf, 
        ERx("copydb -with_modify -nodependency_check -with_index -with_comments -no_persist -parallel -no_repmod -group_tab_idx -no_warn -d\"%s\" -infile=\"%s\" -outfile=\"%s\""
	), temploc, fprefix,ofprefix);
	ibuf = STlength(buf); 

	for (iarg = 1; (iarg < argc) && (ibuf < MAXBUF); iarg++) 
	{

	    if( STscompare( argv[ iarg ], 1, ERx( "-" ), 1 ) == 0 )
		{
			p1 = argv[ iarg ]; 
			(void) CMnext( p1 );

			if ( (STlength(p1) == 0) || 
			  !(((STscompare( p1, 1, ERx( "u" ), 1 ) == 0 ) ||
			  (STscompare( p1, 5, ERx( "noint" ), 5 ) == 0 ) || 
			  (STscompare( p1, 6, ERx( "repmod" ), 6 ) == 0 ) || 
			  (STscompare( p1, 1, ERx( "w" ), 6 ) == 0 ) ||
			  (STscompare( p1, 6, ERx( "online"), 6 ) == 0 )) &&
			  ( argc > 2 ) ))
			{
				usage(); 
				PCexit(FAIL);
			}
			/*
			** Get the username if the -u flag is passed in
			** with the input
			*/
			
			if (STscompare( p1, 1, ERx( "u" ), 1 ) == 0 )
			{
				STcopy(&argv[iarg][2] , (char *)&username);
				usergiven = TRUE;
			}
			else if (STscompare( p1, 1, ERx( "r" ), 1 ) == 0 )
			{ 	
				Repmod = TRUE;
				continue;
			}
			else if (STscompare( p1, 1, ERx( "w"), 1 ) == 0)	
			{	
				nowait = TRUE;
				continue;
			}	
                }              	
		
        if( STscompare( argv[ iarg ], 1, ERx( "+" ), 1 ) == 0 )
		{
			p1 = argv[ iarg ];
			(void) CMnext( p1 );
			if (STscompare( p1, 1, ERx( "w" ), 1 ) == 0 )
			{
				nowait = FALSE;	
				continue;
			}
			else
			{
				usage();
				PCexit(FAIL); 
			}
		}

        if((database == NULL) &&
           (STscompare( argv[ iarg ], 1, ERx( "+" ), 1 ) != 0) &&
           (STscompare( argv[ iarg ], 1, ERx( "-" ), 1 ) != 0))
        {
            database =  argv[ iarg ];
        }

	buf[ibuf++] = ' ';
		for (ichr = 0; (argv[iarg][ichr] != '\0') && (ibuf < MAXBUF); 
			ichr++, ibuf++)
		{
			buf[ibuf] = argv[iarg][ichr];
		}
		buf[ibuf] = '\0';
	}

	/*
	**	Execute the command.
	*/

	if( PCcmdline((LOCATION *) NULL, buf, PC_WAIT, 
			(LOCATION *) NULL, &err_code) != OK )
	    PCexit(FAIL);

	/*
	**	we should run the sql script 
	**	  sql dbname < new_filename
	**	if -u flag given then run:
	**	  sql -uusername dbname < new_filename	
	*/

	if (usergiven)
	  STprintf(buf, ERx( "sql -u%s -s %s <%s" ),
			username, database, new_filename );
	else
	  STprintf(buf, ERx( "sql -s %s <%s" ),
				database, new_filename );

	/*
	**	Execute the command.
	*/

        if( PCcmdline((LOCATION *) NULL, buf, PC_WAIT, 
                        (LOCATION *) NULL, &err_code) != OK )
        {
            STprintf(buf, ERx(" Warning: Non-persistent objects associated with the base table\n in the failed query may have been lost. Please refer to\n %s\n to determine whether any corrective action is required.\n"), new_filename);
            SIfprintf(stdout, buf);
	    PCexit(FAIL);
        }

	/* Now execute the repmod command if the replicator 
	** modify is also required by the user (-repmod)
	*/
	
	if (Repmod)
	{
		
	  if (nowait)
	    STcopy("-w", waitflag) ;
	  else
	    STcopy("+w", waitflag) ;
		
	  if (usergiven)
	    STprintf(repbuf, ERx( "repmod -u%s %s %s" ), 
		username, database, waitflag );
	  else
	    STprintf(repbuf, ERx( "repmod %s %s" ), 
		database, waitflag );
            	
	
	  if( PCcmdline((LOCATION *) NULL, repbuf, PC_WAIT,
                 (LOCATION *) NULL, &err_code) != OK )
     	    PCexit(FAIL);

	}	
	/*
	**	Delete the location
	*/
	LOdelete(&loc_in); 
	LOdelete(&loc_out);
	PCexit(OK);
}
Ejemplo n.º 4
0
main(int argc, char **argv)
{
	char 			*value = NULL; 
	char			*host, *server_type, *command_line; 
	char 			*server_location, *env, *arguments;
	u_i4 			command_line_length;
	char 			config_string[256];
	char 			iidbms[256];
	STARTUPINFO 		si;
	PROCESS_INFORMATION 	ProcessInfo;
	BOOL 			Status;
	SECURITY_ATTRIBUTES     sa;
	HANDLE			hRead, hWrite;
	HANDLE			hStdout;
	char			buffer[512];
	DWORD			bufferl = sizeof(buffer);
	DWORD			pipe_size = 0;	/* Use default buffer size */
	DWORD			datal = 0;
	bool			havequote, failed = FALSE;


	MEadvise( ME_INGRES_ALLOC );

	switch (argc)
	{

	case 1:
		server_type = ERx("dbms");
		server_location = ERx("*");
		break;

	case 2:
		server_type = argv[1];
		server_location = ERx("*");
		break;

	default:
		server_type = argv[1];
    		if (STcompare(server_type, "recovery") == 0)
			server_location = ERx("*");
		else
			server_location = argv[2];
		break;

	}
	
	get_sys_dependencies();

	/*
	**	Get the host name, formally used iipmhost.
	*/
	host = PMhost();

	/*
	**	Build the string we will search for in the config.dat file.
	*/
	STprintf( config_string,
		  ERx("%s.%s.%s.%s.image_name"),
		  SystemCfgPrefix, host, server_type, server_location );

	/*
	**	Get set up for the PMget call.
	*/
	PMinit();
	if( PMload( NULL, (PM_ERR_FUNC *)NULL ) != OK )
		PCexit( FAIL );

	/*
	**	Go search config.dat for a match on the string we just built.
	*/
	PMget( config_string, &value );

	if ( value == NULL )
	{
		NMgtAt( SystemLocationVariable, &env );
		if (STcompare(server_type, "recovery") == 0)
		{
		    STprintf(iidbms, ERx("%s\\%s\\bin\\%sdbms"),
			     env, SystemLocationSubdirectory, SystemCfgPrefix);
		}
		else
		{
		    STprintf(iidbms, ERx("%s\\%s\\bin\\%s%s"),
			     env, SystemLocationSubdirectory, SystemCfgPrefix,
			     server_type);
		}
	}
	else if ( *value == '/' || 
		  *value == '\\' ||
		  (*(value+1) == ':' && *(value+2) == '\\') )
	{
		/* Must be a qualified path name */
		STcopy( value, iidbms );
	}
	else 
	{
		NMgtAt( SystemLocationVariable, &env );
		STprintf( iidbms, ERx("%s\\%s\\bin\\%s"),
			  env, SystemLocationSubdirectory, value );
	}
	
	/*
 	** 	Initialize the startinfo structure.	
	*/
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);

	/*
	**	Get the original command line.
	*/
	arguments = GetCommandLine();
        havequote = FALSE;
        while (*arguments != '\0' && *arguments != '\n')
        {
            if ( *arguments == '"' )
                havequote = (havequote) ? FALSE : TRUE;
            if ( CMwhite(arguments) && havequote == FALSE )
                break;
            arguments++;
        }
	/*
	** 	Put together a command line to create a process with.
	**      - 4 blank separators, quotes, null termination 
	*/
	command_line_length = STlength(arguments) + STlength(iidbms) + 
				STlength(iirun) + 6 + 1; 
	if((command_line = (char *)
		MEreqmem(0, command_line_length, TRUE, NULL)) == NULL)
	{
		error(ERx("Request for memory failed"),NULL);
	}

	STprintf( command_line, "%s \"%s\" %s", iirun, iidbms, arguments );

	/*
	**	Save standard out's handle, to be restored later.
	*/
	hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

 	/*
	**      Initialize the security attributes structure that will
	**      be used to make the pipe handles inheritable.
	*/
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;       /* Make object inheritable */

	/*
	**	Define a anonymous pipe to catch the server's startup message.
	*/
	if((Status = CreatePipe(&hRead,&hWrite,&sa,pipe_size)) != TRUE)
	{
		error(ERx("CreatePipe failed"),ERx("error code = "));
	}

	SetStdHandle(STD_OUTPUT_HANDLE,hWrite);

 	/*
	**      Initialize the security attributes structure that will
	**      be used to make the pipe handles inheritable.
	*/
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;       /* Make object inheritable */

	/*
	**	Initialize the startup information structure.
	*/
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	/* 
	**	Start it up.
	*/
	/*
	**	Start iirun which will start the server.
	*/
	if ((Status = CreateProcess(NULL,command_line,&sa,NULL,TRUE,
		HIGH_PRIORITY_CLASS, NULL,
	     NULL,&si,&ProcessInfo)) != TRUE)
	{
		DWORD dwError = GetLastError();
		switch(dwError)
		{
		     case ERROR_ACCESS_DENIED:
			error(ERROR_REQ_PRIVILEGE, ERx(""));
			break;
		     case ERROR_ELEVATION_REQUIRED:
			error(ERROR_DENIED_PRIVILEGE, ERROR_REQ_ELEVATION);
			break;
		     default:				
			error(ERx("CreateProcess failed"),ERx("error code = "));
			break;
		}
	}

	SetStdHandle(STD_OUTPUT_HANDLE,hStdout);

	for (;;)
	{
	    char	*tmpptr;

	    if((Status = ReadFile(hRead,&buffer,bufferl,&datal,NULL)) != TRUE)
	    {
		error(ERx("ReadFile failed"),ERx("error code = "));
	    }

	    buffer[datal] = '\0';	 		
	    if ((tmpptr = STstrindex(buffer, "PASS\n", 0, FALSE)))
	    {
		*tmpptr = '\0';
		if (STlength(buffer))
		    SIfprintf(stdout, "%s", buffer);

		break;
	    }

	    SIfprintf(stdout, "%s", buffer);

	    if ((tmpptr = STstrindex(buffer, bad_msg, 0, FALSE)))
	    {
		*tmpptr = '\0';
		if (STlength(buffer))
		    SIfprintf(stdout, "%s", buffer);

		failed = TRUE;
		break;
	    }
	}

	/*
	**	Close handles since we don't need them anymore.
	*/
	CloseHandle(ProcessInfo.hThread);
	CloseHandle(ProcessInfo.hProcess);
	CloseHandle(hRead);
	CloseHandle(hWrite);

	if (failed &&
	    STscompare(server_type, STlength(server_type), "gcb", 3) != 0 &&
	    STscompare(server_type, STlength(server_type), "gcc", 3) != 0 &&
	    STscompare(server_type, STlength(server_type), "jdbc", 4) != 0)
	{
		SIfprintf( stderr,"\n%s: server would not start.\n",
			   iirundbms );

		SIfprintf(stderr,
		" %s must be set in your environment.\n", 
		    SystemLocationVariable );

		SIfprintf(stderr,
		" Has the csinstall program been run?\n");

		SIfprintf(stderr,
		" %s_DATABASE, %s_CHECKPOINT, %s_JOURNAL and %s_DUMP\n",
		    SystemVarPrefix,
		    SystemVarPrefix,
		    SystemVarPrefix,
		    SystemVarPrefix );

		SIfprintf(stderr,
		" must also be set. See %s_CONFIG\\symbol.tbl.\n",
		    SystemVarPrefix );

		SIfprintf(stderr,
		" Check the file '%%%s%%\\%s\\files\\errlog.log'\n",
		    SystemLocationVariable, SystemLocationSubdirectory );

		SIfprintf(stderr,
		" for more details concerning internal errors.\n");

		SIfprintf(stderr,
		" See your Installation and Operation Guide for more\n");

		SIfprintf(stderr,
		" information concerning server startup.\n");

		PCexit(FAIL);
	}
	else
	{
		PCexit(OK);
	}
}
Ejemplo n.º 5
0
/*{
** Name: adt_compare() - Compare 2 data values.
**
** Description:
**	This routine compares two data values.  This will tell the caller if the
**	supplied values are equal, or if not, which one is "greater than" the
**	other.
**
**	This routine exists as a performance boost for DMF.  DMF is not allowed
**	to know how to compare data values for the various datatypes.
**	Therefore, if this routine did not exist, DMF would have to make a
**	function call to "adc_compare()" for every attribute in the tuples
**	being compared.  Even though tuples are constructs that seem a level
**	above what ADF logically handles, the performance improvement in this
**	case justifies this routine.
**
**	To avoid the overhead of an adc_compare call,
**	this routine has built into it the semantics for
**	comparing several of the most common datatypes supported by INGRES.
**
**	If the routine does run across a datatype that is not in this list, it
**	will call the general routine "adc_compare()", thereby guaranteeing
**	that it will function (perhaps slower), for ALL datatypes, even future
**	user defined ADTs.
**
**	When NULL values are involved, this routine will use the same semantics
**	that "adc_compare()" uses:  a NULL value will be considered greater
**	than any other value, and equal to another NULL value.
**
**	PLEASE NOTE:  As with "adc_compare()", no pattern matching for
**	-----------   the string datatypes is done within this routine.
**
**
** Inputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.
**		.ad_ebuflen		The length, in bytes, of the buffer
**					pointed to by ad_errmsgp.
**		.ad_errmsgp		Pointer to a buffer to put formatted
**					error message in, if necessary.
**      atr                             Pointer to DB_ATTR.
**      d1                        	Pointer to first value.
**      d2                              Pointer to second value.
**
** Outputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.  If an
**					error occurs the following fields will
**					be set.  NOTE: if .ad_ebuflen = 0 or
**					.ad_errmsgp = NULL, no error message
**					will be formatted.
**		.ad_errcode		ADF error code for the error.
**		.ad_errclass		Signifies the ADF error class.
**		.ad_usererr		If .ad_errclass is ADF_USER_ERROR,
**					this field is set to the corresponding
**					user error which will either map to
**					an ADF error code or a user-error code.
**		.ad_emsglen		The length, in bytes, of the resulting
**					formatted error message.
**		.adf_errmsgp		Pointer to the formatted error message.
**      status                          Status returned from
**					adc_compare(), if called.
**	
**	    The following DB_STATUS codes may be returned by adc_compare():
**	    E_DB_OK, E_DB_WARN, E_DB_ERROR, E_DB_SEVERE, E_DB_FATAL
**
**	    If a DB_STATUS code other than E_DB_OK is returned, the caller
**	    can look in the field adf_scb.adf_errcb.ad_errcode to determine
**	    the ADF error code.  The following is a list of possible ADF error
**	    codes that can be returned by this routine:
**
**          E_AD0000_OK                 Operation succeeded.
**          E_AD2004_BAD_DTID           Datatype id unknown to ADF.
**          E_AD2005_BAD_DTLEN          Internal length is illegal for
**					the given datatype.
**		(Others not yet defined)
**
** Returns:
**      i4  < 0   if 1st < 2nd
**          = 0   if 1st = 2nd
**          > 0   if 1st > 2nd
**
** Exceptions:
**       none
**
** Side Effects:
**       none
**
** History:
**      10-Feb-86 (thurston)
**          Initial creation.
**	03-apr-86 (thurston)
**	    Initial coding.  Also, added two more return statuses (stati?):
**          E_AD2004_BAD_DTID and E_AD2005_BAD_DTLEN.
**      11-jun-86 (jennifer)
**          Fixed bug compare result asigned to adt_cmp_result instead
**          of indirect through this pointer, i.e. *adt_cmp_result.
**      11-jun-86 (jennifer)
**	    Fixed bug where the first entry of attribute array (0)
**          was being used.  This entry is always garbage since 
**          attributes are numbered from 1.
**      27-jul-86 (ericj)
**	    Converted for new ADF error handling.
**	19-nov-86 (thurston)
**	    Fixed the comparison for text.
**	22-sep-88 (thurston)
**	    Added bit representation check as a first pass on each attr.  Also,
**	    added code to deal with nullable types here ... this could be a big
**	    win, since all nullable types were going through adc_compare(), now
**	    they need not.  Also, added cases for CHAR and VARCHAR.
**	21-oct-88 (thurston)
**	    Got rid of all of the `#ifdef BYTE_ALIGN' stuff by using the
**	    appropriate [I2,I4,F4,F8]ASSIGN_MACROs.  This also avoids a bunch
**	    of MEcopy() calls on BYTE_ALIGN machines.
**	21-Apr-89 (anton)
**	    Added local collation support
**	17-Jun-89 (anton)
**	    Moved local collation routines to ADU from CL
**	25-jul-89 (jrb)
**	    Added support for decimal datatype.
**	02-jan-90 (jrb)
**	    Fix alignment problem.
**	08-aug-91 (seg)
**	    "d1" and "d2" are dereferenced too often with the assumption
**	    that (PTR) == (char *) to fix.  Made them (char *).
**	28-mar-2001 (abbjo03)
**	    Add support for DB_NCHR_TYPE and DB_NVCHR_TYPE.
**	16-dec-04 (inkdo01)
**	    Add collation ID parm to aduucmp() calls.
**	02-Feb-2005 (jenjo02)
**	    Consolidated from the nine adt functions which duplicated
**	    this "compare" code. Runs the most optimal compare
**	    based on datatype for a single attribute.
**
**	    Optimized CHA/VCH compares to use MEcmp rather than
**	    CMcmpcase loop when possible.
**
**	    Replace giant switch statement with if-then-else
**	    ordered most likely to least likely, more or less.
**	    The switch was consuming 27% of the CPU used by this
**	    function.
**
**	    Added DB_STATUS *status as a function parameter so
**	    if adc_compare returns an error, it will be returned
**	    to the caller rather than as a bogus compare "result".
**	27-Apr-2005 (jenjo02 for stial01)
**	    Replaced computing compare value using arithmetic
**	    (d1 - d2) with logical compares ( d1 < d2...) as
**	    the arithmetic may over/underflow and return the
**	    wrong result.
**	13-May-2005 (thaju02)
**	    For differing length vchar, return value based on 
**	    comparison of longer length vchar to blank. (B114514)
**	19-Jun-2006 (gupsh01)
**	    Added support for new date/time types.
**	3-may-2007 (dougi)
**	    Tweak slightly to allow MEcmp() on collation/double byte
**	    if they're bytewise equal.
**	10-may-2007 (dougi)
**	    Add logic to handle ordering of c/text/char/varchar in UTF8
**	    server.
**	25-jul-2007 (gupsh01)	
**	    Although UTF8 is multibyte it is meant to be processed through
**	    UTF8 comparison code utilizing unicode comparison.
**	17-Aug-2007 (gupsh01)
**	    Fix the UTF8 handling.
*/
i4
adt_compare(
ADF_CB		    *adf_scb,
DB_ATTS		    *atr,		/* Attribute in question */
char		    *d1,		/* Ptr to 1st value */
char		    *d2,		/* Ptr to 2nd value */
DB_STATUS	    *status)		/* Status from adc_compare */

{
    i4			cur_cmp;	/* Result of latest attr cmp */
    i4			vi1, vi2;	/* Temp i4's used to cmp ints */
    i8			lli1, lli2;	/* Compare i8's */
    f8			vf1, vf2;	/* Temp f8's used to cmp flts */
    u_char	        *lc1, *lc2;
    u_char	        blank;
    i4			atr_bdt;	/* Base datatype of attr */
    i2			atr_len;	/* Length of cur attribute */
    i4			d1_isnull, d2_isnull;
    DB_DATA_VALUE	dv1, dv2;	/* Data value structs for call
					** to adc_compare(), if that is
					** necessary.
					*/
    u_char		*tc1, *tc2;	/* Temps used for string compare */
    u_char		*endtc1, *endtc2;
    UCS2		*tn1, *tn2;	/* Temps used for Nstring compare */
    UCS2		*endtn1, *endtn2;
	/*
	**  The following four lines provide temp storage to solve
	**  byte allignment problems on some archictectures.
	*/
    i2			i2_t1, i2_t2;
    i4			i4_t1, i4_t2;
    f4			f4_t1, f4_t2;
    f8			f8_t1, f8_t2;

#define	ADT_LT	(i4)-1
#define ADT_EQ	(i4)0
#define	ADT_GT	(i4)1

    *status = E_DB_OK;

    atr_len = atr->length;

    if ( (atr_bdt = atr->type) < 0 )
    {
	/* Nullable datatype */

	d1_isnull = (*((char *)d1 + atr_len - 1) & ADF_NVL_BIT);
	d2_isnull = (*((char *)d2 + atr_len - 1) & ADF_NVL_BIT);

	if ( !d1_isnull && !d2_isnull )
	{
	    /* Neither is the Null value, look at data */
	    atr_bdt = -atr_bdt;
	    atr_len--;
	}
	else if (d1_isnull && d2_isnull)
	    return(ADT_EQ);   /* both are Null values; 1st = 2nd */
	else if (d1_isnull)
	    return(ADT_GT);   /* 1st is Null value; 1st > 2nd */
	else
	    return(ADT_LT);  /* 2nd is Null value; 1st < 2nd */
    }

    /* "if then else" consumes ~27% less CPU than "switch" */

    if ( atr_bdt == DB_INT_TYPE )
    {
	/* If both operands aligned... */
	/* Extra casts to shut up compilers -- only care about low bits */
	if ( (((i4)(SCALARP)d1 | (i4)(SCALARP)d2) & atr_len-1) == 0 )
	{
	    if ( atr_len == 4 )
	    {
		if      (*(i4*)d1 < *(i4*)d2)	return(ADT_LT);
		else if (*(i4*)d1 > *(i4*)d2)	return(ADT_GT);
		else			  	return(ADT_EQ);
	    }
	    if ( atr_len == 8 )
	    {
		if      (*(i8*)d1 < *(i8*)d2)	return(ADT_LT);
		else if (*(i8*)d1 > *(i8*)d2)	return(ADT_GT);
		else			  	return(ADT_EQ);
	    }
	    if ( atr_len == 2 )
	    {
		if      (*(i2*)d1 < *(i2*)d2)	return(ADT_LT);
		else if (*(i2*)d1 > *(i2*)d2)	return(ADT_GT);
		else			  	return(ADT_EQ);
	    }
	
	    if      (*(i1*)d1 < *(i1*)d2)	return(ADT_LT);
	    else if (*(i1*)d1 > *(i1*)d2)	return(ADT_GT);
	    else			  	return(ADT_EQ);
	}
	/* One or both not aligned... */
	if (atr_len == 4)
	{
	    I4ASSIGN_MACRO(*d1, i4_t1);
	    I4ASSIGN_MACRO(*d2, i4_t2);
	    if      (i4_t1 < i4_t2)	return(ADT_LT);
	    else if (i4_t1 > i4_t2)	return(ADT_GT);
	    else			return(ADT_EQ);
	}
	if (atr_len == 8)
	{
	    I8ASSIGN_MACRO(*d1, lli1);
	    I8ASSIGN_MACRO(*d2, lli2);
	    if      (lli1 < lli2)	return(ADT_LT);
	    else if (lli1 > lli2)	return(ADT_GT);
	    else		  	return(ADT_EQ);
	}
	if (atr_len == 2)
	{
	    I2ASSIGN_MACRO(*d1, i2_t1);
	    I2ASSIGN_MACRO(*d2, i2_t2);
	    if      (i2_t1 < i2_t2)	return(ADT_LT);
	    else if (i2_t1 > i2_t2)	return(ADT_GT);
	    else			return(ADT_EQ);
	}
	if      (*(i1*)d1 < *(i1*)d2)	return(ADT_LT);
	else if (*(i1*)d1 > *(i1*)d2)	return(ADT_GT);
	else			  	return(ADT_EQ);
    }

    if ( atr_bdt == DB_FLT_TYPE || atr_bdt == DB_MNY_TYPE )
    {
	/* If both operands aligned... */
	/* Extra casts to shut up compilers, only care about low bits */
	if ( (((i4)(SCALARP)d1 | (i4)(SCALARP)d2) & atr_len-1) == 0 )
	{
	    if ( atr_len == 8 )
	    {
		if      (*(f8*)d1 < *(f8*)d2) return(ADT_LT);
		else if (*(f8*)d1 > *(f8*)d2) return(ADT_GT);
		else                  	  return(ADT_EQ);
	    }
	    if      (*(f4*)d1 < *(f4*)d2) return(ADT_LT);
	    else if (*(f4*)d1 > *(f4*)d2) return(ADT_GT);
	    else                  	  return(ADT_EQ);
	}

	/* One or both not aligned... */
	if ( atr_len == 8 )
	{
	    F8ASSIGN_MACRO(*d1, f8_t1);
	    F8ASSIGN_MACRO(*d2, f8_t2);
	    if      (f8_t1 < f8_t2) return(ADT_LT);
	    else if (f8_t1 > f8_t2) return(ADT_GT);
	    else   		    return(ADT_EQ);
	}
	F4ASSIGN_MACRO(*d1, f4_t1);
	F4ASSIGN_MACRO(*d2, f4_t2);
	if      (f4_t1 < f4_t2) return(ADT_LT);
	else if (f4_t1 > f4_t2) return(ADT_GT);
	else   		        return(ADT_EQ);
    }

    if ( atr_bdt == DB_BYTE_TYPE || atr_bdt == DB_TABKEY_TYPE ||
	      atr_bdt == DB_LOGKEY_TYPE )
    {
	return(MEcmp(d1, d2, atr_len));
    }

    if ( atr_bdt == DB_CHA_TYPE || atr_bdt == DB_VCH_TYPE )
    {
	if ( atr_bdt == DB_CHA_TYPE )
	{
	    /* Try the turbo compare. */
	    cur_cmp = MEcmp(d1, d2, atr_len);

	    /* If not equal and UTF8-enabled ... */
	    if (cur_cmp && (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED))
		return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, 
							d1, d2, status));

	    /* If neither collation nor doublebyte or if byte-wise equal ... */
	    if ( !(adf_scb->adf_collation || 
		   Adf_globs->Adi_status & ADI_DBLBYTE) || cur_cmp == 0)
	    {
		return(cur_cmp);
	    }

	    tc1    = (u_char *) d1;
	    tc2    = (u_char *) d2;
	    endtc1 = tc1 + atr_len;
	    endtc2 = tc2 + atr_len;
	}
	else
	{
	    I2ASSIGN_MACRO(((DB_TEXT_STRING *)d1)->db_t_count, i2_t1);
	    I2ASSIGN_MACRO(((DB_TEXT_STRING *)d2)->db_t_count, i2_t2);
	    tc1 = (u_char *)d1 + DB_CNTSIZE;
	    tc2 = (u_char *)d2 + DB_CNTSIZE;

	    /* Try the turbo compare on the prefix. */
	    cur_cmp = MEcmp((char *)tc1, (char *)tc2, min(i2_t1, i2_t2));

	    /* If neither collation nor doublebyte... */
	    if ( !(adf_scb->adf_collation || 
		   Adf_globs->Adi_status & ADI_DBLBYTE) || 
			(adf_scb->adf_utf8_flag & AD_UTF8_ENABLED))
	    {
		i2	diff = i2_t1 - i2_t2;
	    
		/* If not equal or lengths differ and UTF8-enabled ... */
		if ((diff || cur_cmp) && 
			(adf_scb->adf_utf8_flag & AD_UTF8_ENABLED))
		    return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, 
							d1, d2, status));

		/* If short compare produces inequality or lengths are
		** the same ... */
		if ( cur_cmp || diff == 0 )
		{
		    return(cur_cmp);
		}

		/*
		** Equal for shorter length.
		** If longer trails all blanks, they're equal
		*/
		if ( diff > 0 )
		{
		    /* tc1 is longer */
		    tc1 += i2_t2;
		    while ( *(tc1++) == MIN_CHAR && --diff > 0 );

		    if (!diff)
			return( ADT_EQ );
		    else
		    {
			tc1--;
			if (*tc1 > MIN_CHAR)
			    return(ADT_GT);
			else
			    return(ADT_LT);
		    }
		}
		else
		{
		    /* tc2 is longer */
		    tc2 += i2_t1;
		    while ( *(tc2++) == MIN_CHAR && ++diff < 0 );

		    if (!diff)
			return( ADT_EQ );
		    else
		    {
			tc2--;
			if (MIN_CHAR > *tc2)
			    return(ADT_GT);
			else 
			    return(ADT_LT);
		    }
		}

	    }
	    else if (i2_t1 == i2_t2 && cur_cmp == 0)
		return(cur_cmp);	/* byte wise compare returns "=" */

	    endtc1 = tc1 + i2_t1;
	    endtc2 = tc2 + i2_t2;
	}

	if (adf_scb->adf_collation)
	    return(adugcmp((ADULTABLE *)adf_scb->adf_collation,
			 ADUL_BLANKPAD, tc1, endtc1, tc2, endtc2));

	/* Doublebyte is rather more tedious */
	blank = (u_char)MIN_CHAR;
	cur_cmp = ADT_EQ;
	
	while ( cur_cmp == ADT_EQ )
	{
	    if (tc1 < endtc1)
	    {
		lc1 = tc1;
		CMnext(tc1);
	    }
	    else
	    {
		lc1 = &blank;
	    }
	    
	    if (tc2 < endtc2)
	    {
		lc2 = tc2;
		CMnext(tc2);
	    }
	    else
	    {
		lc2 = &blank;
	    }
	    
	    /* if both pointing to blank or we happen to be comparing
	    ** a string to itself then break
	    */
	    if (lc1 == lc2)
		break;
	    
	    cur_cmp = CMcmpcase(lc1, lc2);
	}
	return(cur_cmp);
    }

    if ( atr_bdt == DB_NCHR_TYPE || atr_bdt == DB_NVCHR_TYPE )
    {
	if ( atr_bdt == DB_NCHR_TYPE )
	{
	    tn1 = (UCS2 *)d1;
	    tn2 = (UCS2 *)d2;
	    endtn1 = tn1 + atr_len / sizeof(UCS2);
	    endtn2 = tn2 + atr_len / sizeof(UCS2);
	}
	else
	{
	    tn1 = ((DB_NVCHR_STRING *)d1)->element_array;
	    tn2 = ((DB_NVCHR_STRING *)d2)->element_array;
	    I2ASSIGN_MACRO(((DB_NVCHR_STRING *)d1)->count, i2_t1);
	    I2ASSIGN_MACRO(((DB_NVCHR_STRING *)d2)->count, i2_t2);
	    endtn1 = tn1 + i2_t1;
	    endtn2 = tn2 + i2_t2;
	}
      
	*status = aduucmp(adf_scb, ADUL_BLANKPAD,
	    tn1, endtn1, tn2, endtn2, &cur_cmp, atr->collID);
	return (cur_cmp);
    }

    if ( atr_bdt == DB_CHR_TYPE )
    {
	if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)
	    return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, 
							d1, d2, status));

	if (adf_scb->adf_collation)
	    return(adugcmp((ADULTABLE *)adf_scb->adf_collation,
			     ADUL_SKIPBLANK, (u_char *)d1,
			     atr_len + (u_char *)d1, (u_char *)d2,
			     atr_len + (u_char *)d2));
	return(STscompare((char *)d1, atr_len, (char *)d2, atr_len));
    }

    if ( atr_bdt == DB_TXT_TYPE )
    {
	if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)
	    return(adt_utf8comp(adf_scb, atr, atr_bdt, atr_len, 
							d1, d2, status));

	I2ASSIGN_MACRO(((DB_TEXT_STRING *)d1)->db_t_count, i2_t1);
	I2ASSIGN_MACRO(((DB_TEXT_STRING *)d2)->db_t_count, i2_t2);
	tc1 = (u_char *)d1 + DB_CNTSIZE;
	tc2 = (u_char *)d2 + DB_CNTSIZE;
	endtc1 = tc1 + i2_t1;
	endtc2 = tc2 + i2_t2;

	if (adf_scb->adf_collation)
	    return(adugcmp((ADULTABLE *)adf_scb->adf_collation,
			     0, tc1, endtc1, tc2, endtc2));

	cur_cmp = ADT_EQ;
	while (cur_cmp == ADT_EQ && tc1 < endtc1  &&  tc2 < endtc2)
	{
	    if ( (cur_cmp = CMcmpcase(tc1, tc2)) == ADT_EQ )
	    {
		CMnext(tc1);
		CMnext(tc2);
	    }
	}
	
	/* If equal up to shorter, short strings < long */
	return( (cur_cmp) ? cur_cmp : (endtc1 - tc1) - (endtc2 - tc2) );
    }

    if ( atr_bdt == DB_DEC_TYPE )
    {
	/*  See if the bit representation is identical. */
	if ( MEcmp(d1, d2, atr_len) )
	{
	    i4	    pr;
	    i4	    sc;

	    pr = DB_P_DECODE_MACRO(atr->precision);
	    sc = DB_S_DECODE_MACRO(atr->precision);
	    return(MHpkcmp((PTR)d1, pr, sc, (PTR)d2, pr, sc));
	}
	return(ADT_EQ);
    }

    /* Bit-equivalent dates we can handle here */
    if (( atr_bdt == DB_DTE_TYPE || 
	 atr_bdt == DB_ADTE_TYPE ||
	 atr_bdt == DB_TMWO_TYPE ||
	 atr_bdt == DB_TMW_TYPE ||
	 atr_bdt == DB_TME_TYPE ||
	 atr_bdt == DB_TSWO_TYPE ||
	 atr_bdt == DB_TSW_TYPE ||
	 atr_bdt == DB_TSTMP_TYPE ||
	 atr_bdt == DB_INYM_TYPE ||
	 atr_bdt == DB_INDS_TYPE ) &&
	MEcmp(d1, d2, (u_i2)atr_len) == 0 )
    {
	return(ADT_EQ);
    }

    /* Will have to do it the slow way */
    dv1.db_datatype = dv2.db_datatype = (DB_DT_ID)atr_bdt;
    dv1.db_prec = dv2.db_prec = atr->precision;
    dv1.db_length = dv2.db_length = atr_len;
    dv1.db_collID = dv2.db_collID = atr->collID;
    dv1.db_data = d1;
    dv2.db_data = d2;
    *status = adc_compare(adf_scb, &dv1, &dv2, &cur_cmp);

    return(cur_cmp);
}
Ejemplo n.º 6
0
/*{
** Name: scs_monitor	- Implement the SCS part of the monitor task
**
** Description:
**	This routine is called ala the regular thread processing routine.
**	It parses its input, decides what to do, and returns the output.
**
**	The commmands completely interpreted here are:
**
**		set server shut	(CS_CLOSE)
**			Disallow new connections, shutdown when
**			last current session exits.
**          
**          	remove SESSION
**          	    	New improved "safe" version, acts the same
**  	    	    	as front-end exiting and dropping GCA connection.
**	
**		kill SESSION
**			Signal CS_KILL_EVENT to a user session actively
**			running a query.
**          
**	NEW:
**		set server closed
**			Disallow new regular user sessions.
**          
**		set server open
**			Reallow new regular user sessions.  Cancel
**			any pending 'set server shut' shutdown.
**
**		show server listen
**
**		crash session SESSIONID
**
**	Commands partially handled here and partially in CSmonitor are:
**
**		stop server	(CS_KILL)
**			Kill user sessions, shutdown when they're gone.
**          
**		stop server conditional (CS_COND_CLOSE)
**			Shutdown if no sessions, which never works because
**			this session always exists.
**          
**		crash server	(CS_CRASH)
**			Take the server down immediately.
**
**	All other commands are passed to CSmonitor for handling.
**
** Inputs:
**	mode				Mode of operation
**					    CS_INPUT, _OUPUT, ...
**	scb				Sessions control block to monitor
**	*command			Text of the command
**	powerful			Is this user powerful
**	output_fcn			Function to call to perform the output.
**					This routine will be called as
**					    (*output_fcn)(newline_present,
**							    length,
**							    buffer)
**					where buffer is the length character
**					output string, and newline_present
**					indicates whether a newline needs to
**					be added to the end of the string.
**
** Outputs:
**	next_mode			As above.
**	Returns:
**	    OK
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
** History:
**	26-Jul-1993 (daveb)
**	    created.
**	15-Sep-1993 (daveb)
**	    ifdef out all but drop connection for now.
**	1-Nov-1993 (daveb)
**	    Match LRC proposal.  Drop becomes remove, remove becomes kill.
**      10-Nov-1993 (daveb)
**          Match approved proposal.  Kill becomes "crash session SESSIONID"
**	15-dec-93 (robf)
**          Add prototype "broadcast" message request.
**	4-mar-94 (robf)
**          Add initial security auditing to iimonitor events.
**	12-dec-1996 (canor01)
**	    Add support for sampler thread.
**	24-Apr-2003 (jenjo02)
**	    Added "kill" command to abort eligible queries
**	    while leaving the session intact, SIR 110141.
**	17-Sep-2004 (schka24)
**	    Manual fix to remove command so that it fires.
**      05-may-2005 (horda03) Bug 114453/INGSRV 3290
**          For server/session changes log the command.
**      22-may-2007 (horda03) Bug 117966
**          Log the command before calling CSmonitor, as
**          the CS could be crashing the server.
**      23-Sep-2009 (hanal04) Bug 115316
**          Added "SHOW SERVER CAPABILITIES".
*/
static STATUS
scs_monitor( i4 mode, CS_SCB *scb, i4 *nmode, char *command,
	    i4 powerful, i4 (*output_fcn)(PTR, i4, char *) )
{
    STATUS		ret_stat;
    char		buf[81];
    bool		completely_done;
    PTR			ptr_scb;
    SCD_SCB		*an_scb;
    i4                  log_cmd = 0;
    i4                  local_error;
    SCD_SCB		*my_scb = (SCD_SCB*)scb;
    
    *nmode = CS_EXCHANGE;
    completely_done = FALSE;
    ret_stat = OK;
    
    switch (mode)
    {
    case CS_INITIATE:
	*nmode = CS_INPUT;
	break;
	
    case CS_TERMINATE:
	break;
	
    case CS_INPUT:
		
	CVlower(command);
	if (STscompare("setservershut", 0, command, 0) == 0)
	{
	    /* Audit log the attempt here? */
	    if (!powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser status required to stop servers");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_FAIL,
			    I_SX274D_SET_SERVER_SHUT
			    );
	    }
	    else /* disallow regular listens, exit when last conn exits */
	    {
		Sc_main_cb->sc_listen_mask = 
		    (SC_LSN_TERM_IDLE |SC_LSN_SPECIAL_OK) ;
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Server will stop. %d. sessions remaining",
			 Sc_main_cb->sc_current_conns );
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_SUCCESS,
			    I_SX274D_SET_SERVER_SHUT
			    );
                log_cmd = 1;
	    }
	    completely_done = TRUE;
	}
	else if (STscompare("setserverclosed", 0, command, 0) == 0)
	{
	    /* Audit log the attempt here? */
	    if (!powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser status required to disable connections");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_FAIL,
			    I_SX2748_SET_SERVER_CLOSED
			    );
	    }
	    else		/* Disallow regular listens */
	    {
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_SUCCESS,
			    I_SX2748_SET_SERVER_CLOSED
			    );
		Sc_main_cb->sc_listen_mask &= (~SC_LSN_REGULAR_OK);
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "User connections now disabled" );
                log_cmd = 1;
	    }
	    completely_done = TRUE;
	}
	else if (STscompare("setserveropen", 0, command, 0) == 0)
	{
	    /* Audit log the attempt here? */
	    if (!powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser status required to enable connections");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_FAIL,
			    I_SX2749_SET_SERVER_OPEN
			    );
	    }
	    else  /* allow all listens, cancel any impending shutdown */
	    {
		Sc_main_cb->sc_listen_mask =
		    (SC_LSN_REGULAR_OK | SC_LSN_SPECIAL_OK);
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "User connections now allowed" );
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_SUCCESS,
			    I_SX2749_SET_SERVER_OPEN
			    );
                log_cmd = 1;
	    }
	    completely_done = TRUE;
	}
	else if (STncasecmp("broadcast", command, 9) == 0)
	{
	    /* Audit log the attempt here? */
	    if (!powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser status required to broadcast messages");
	    }
	    else  
	    {
		/*
		** Broadcast the message to any connected sessions
		*/
		scs_scan_scbs(scs_broadcast_mesg, (PTR)(command+10));
	    }
	    completely_done = TRUE;
	}
	else if (STscompare("stopserverconditional", 0, command, 0) == 0 ||
		 STscompare("stopserver", 0, command, 0) == 0 ||
		 STscompare("crashserver", 0, command, 0) == 0 )
	{
	    /* Audit log the attempt here? */
	    if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		scs_mon_audit((SCD_SCB*)scb, 
			powerful?
			    SXF_A_CONTROL|SXF_A_SUCCESS:
			    SXF_A_CONTROL|SXF_A_FAIL,         /* Action */
			I_SX274A_STOP_SERVER
			);
                log_cmd = powerful;
	}
        else if (STscompare("showservercapabilities", 0, command, 0) == 0)
        {
            TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "%v",
                     SC_CAPABILITIES_FLAGS, Sc_main_cb->sc_capabilities );
            completely_done = TRUE;
        }
	else if (STscompare("showserverlisten", 0, command, 0) == 0)
	{
	    TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "%s", 
		     Sc_main_cb->sc_listen_mask & SC_LSN_REGULAR_OK ?
		     "OPEN" : "CLOSED" );
	    completely_done = TRUE;
	}
	else if (STscompare("showservershutdown", 0, command, 0) == 0)
	{
	    TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "%s", 
		     Sc_main_cb->sc_listen_mask & SC_LSN_TERM_IDLE ?
		     "PENDING" : "OPEN" );
	    completely_done = TRUE;
	}
# ifdef NOT_SUPPORTED
	else if (STscompare("showconnections", 0, command, 0) == 0 )
	{
	    scs_scan_scbs( scs_show_func, (PTR)&powerful );
	    completely_done = TRUE;
	}
	else if (STscompare("show connection", 15, command, 15) == 0 )
	{
	    completely_done = TRUE;
	    STzapblank(command, command);
	    if (CVaxptr(command + 14, &ptr_scb) ||
		!scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) )
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Invalid connection id");
		break;
	    }
	    scs_show_func( an_scb, &powerful );
	}
# endif
	else if (STscompare("remove", 6, command, 6) == 0)
	{
	    completely_done = TRUE;
	    STzapblank(command, command);
	    if (CVaxptr(command + 6, &ptr_scb) || scb == NULL ||
		!scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) ||
		an_scb == my_scb )
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Invalid session id");
		break;
	    }
	    if ((MEcmp(an_scb->cs_scb.cs_username, scb->cs_username,
		       sizeof(scb->cs_username))) && !powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser or owner status required to remove session");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_FAIL,
			    I_SX274B_REMOVE_SESSION
			    );
		break;
	    }
	    if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		scs_mon_audit((SCD_SCB*)scb, 
			SXF_A_CONTROL|SXF_A_SUCCESS,
			I_SX274B_REMOVE_SESSION
			);
	    scs_remove_sess( an_scb );
	    TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
		     "Session %p removed", an_scb);
            log_cmd = 1;
	}
	else if (STscompare("crash session", 13, command, 13) == 0)
	{
	    completely_done = TRUE;
	    STzapblank(command, command);
	    if (CVaxptr(command + 12, &ptr_scb) || scb == NULL ||
		!scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) ||
		an_scb == my_scb )
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Invalid session id");
		break;
	    }
	    if ((MEcmp(an_scb->cs_scb.cs_username, scb->cs_username,
		       sizeof(scb->cs_username))) && !powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser or owner status required to crash session");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			SXF_A_CONTROL|SXF_A_FAIL,
			I_SX274C_CRASH_SESSION
			);
		break;
	    }
	    if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		scs_mon_audit((SCD_SCB*)scb, 
			SXF_A_CONTROL|SXF_A_SUCCESS,
			I_SX274C_CRASH_SESSION
			);
	    scs_crash_sess( an_scb );
	    TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
		     "Session %p crashed", an_scb);
            log_cmd = 1;
	}
	else if (STscompare("kill", 4, command, 4) == 0)
	{
	    completely_done = TRUE;
	    STzapblank(command, command);
	    if (CVaxptr(command + 4, &ptr_scb) || scb == NULL ||
		!scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) ||
		an_scb == my_scb )
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Invalid session id");
	    }
	    else if ((MEcmp(an_scb->cs_scb.cs_username, scb->cs_username,
		       sizeof(scb->cs_username))) && !powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser or owner status required to kill query");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			SXF_A_CONTROL|SXF_A_FAIL,
			I_SX2755_KILL_QUERY
			);
	    }
	    else switch ( an_scb->scb_sscb.sscb_qmode )
	    {
		case 0:
		    TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			    "Session %p is not executing a query", an_scb);
		    break;

		/* Honor only "meaningful" types of queries: */
		case PSQ_RETRIEVE:
		case PSQ_RETINTO:
		case PSQ_APPEND:
		case PSQ_REPLACE:
		case PSQ_DELETE:
		case PSQ_COPY:
		case PSQ_MODIFY:
		case PSQ_EXECQRY:
		case PSQ_EXCURS:
		case PSQ_CALLPROC:
		case PSQ_REPCURS:
		case PSQ_RETCURS:
		case PSQ_EXEDBP:
		case PSQ_REGPROC:
		case PSQ_DDEXECPROC:
		case PSQ_CREATE:
		    if ( an_scb->scb_sscb.sscb_force_abort ||
			 an_scb->scb_sscb.sscb_interrupt )
		    {
			TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			     "Session %p query already aborting", an_scb);
		    }
		    else
		    {
			scs_kill_query( an_scb );
			if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
			    scs_mon_audit((SCD_SCB*)scb, 
				    SXF_A_CONTROL|SXF_A_SUCCESS,
				    I_SX2755_KILL_QUERY
				    );
			TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
				 "Session %p query killed", an_scb);
		    }
		    break;

		default:
		    TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			     "Session %p query cannot be killed", an_scb);
		    break;
	    }
	}
# ifdef NOT_SUPPORTED
	else if (STscompare("help", 0, command, 0) == 0)
	{
	    TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
		     "SCS monitor commands:\nset server shut\nset server closed\nset server open\nshow server listen\nshow server shutdown\nremove SESSION\ncrash session SESSION\n\nCS monitor commands:\n");
	}
# endif
        else if (! CS_is_mt())
	    /* OS Thread version will start an OS thread in the CS */
            if ((STscompare("start sampling", 14, command, 14) == 0))
            {
                if (!powerful)
                {
                    TRformat(output_fcn, (i4 *) 1, buf, sizeof(buf)-1,
                        "Superuser status required to start sampling.", 0L);
                }
                else
                {
                    GCA_LS_PARMS        local_crb;
	            CL_ERR_DESC         errdesc;

                    local_crb.gca_status = 0;
                    local_crb.gca_assoc_id = 0;
                    local_crb.gca_size_advise = 0;
                    local_crb.gca_user_name = "<Sampler Thread>";
                    local_crb.gca_account_name = 0;
                    local_crb.gca_access_point_identifier = "NONE";
                    local_crb.gca_application_id = 0;

		    /* set up all the CS control blocks for the sampler */
	            ret_stat = CSmonitor( mode, scb, nmode, command,
				          powerful, output_fcn );

		    if ( ret_stat == OK )
                        ret_stat = CSadd_thread(CS_LIM_PRIORITY-1, (PTR) &local_crb,
                                                SCS_SSAMPLER, (CS_SID*)NULL, &errdesc);

                    if (ret_stat)
                    {
                        TRformat(output_fcn, (i4 *) 1, buf, sizeof(buf)-1,
                               "Sampling failed to start.");
                    }
                }
            }

        /* log the command before calling CSmonitor(), as the server could be left in an
        ** unknown state if the command CRASH SERVER or STOP SERVER are used
        */

        if (log_cmd)
        {
           ule_format( I_SC051E_IIMONITOR_CMD, 0, ULE_LOG, NULL, 0, 0, 0, &local_error,
                       3, STlength(command), command,
                       DB_OWN_MAXNAME, &((SCD_SCB *)scb)->scb_sscb.sscb_ics.ics_rusername,
                       sizeof(DB_TERM_NAME), &((SCD_SCB *)scb)->scb_sscb.sscb_ics.ics_terminal, 
                       0, 0);
        }

	if( !completely_done )
	    ret_stat = CSmonitor( mode, scb, nmode, command,
				 powerful, output_fcn );
	break;
	
    case CS_OUTPUT:
	break;
    }

    return( ret_stat );
}
Ejemplo n.º 7
0
/*
** Name: main			-main routine.
**
** Description:
**	This routine is the main control routine for iirundbms. Starting an
**	iidbms server consists of:
**	    1) Opening and reading the PM data
**	    2) Validating server arguments, converting to VMS internal format.
**	    3) Creating mailbox for communication with server.
**	    4) creating server processing.
**	    5) Sending server process its commands.
**	    6) Checking whether server startup succeeded or not.
**
**	iirundbms command line format is:
**	    iirundbms <server type> <server flavor>
**	where server type is something like "dbms", "recovery", "star", and
**	server flavor is something like "public", "nonames", "benchmark".
**
** Inputs:
**	argc			- number of arguments (should be 1, 2 or 3)
**	argv			- argument array.
**
** Outputs:
**	None
**
** Returns:
**	a VMS status code is returned.
**
** History:
**	31-jan-1994 (bryanp)
**	    Added comment header.
**      21-Jan-1998 (horda03) Bug 68559
**          For GCC servers where a server flavour has been specified,
**          command line to start the server must specify the server
**          flavour in the form; "-instance=<server_flavor>" in order
**          for the GCC to pickup the correct configuration details.
**      22-feb-1998 (chash01)
**          RMCMD (Visual DBA backend server) startup takes two VMS CREPRC
**          calls, one ihere, one in rmcmd.exe.  When RMCMD server starts
**          the PID returned by CREPRC in this module is no longer valid.
**          WE have to first decode pid in the t_user_data field returned by
**          RMCMD server in termination  mailbox before print PID and 
**          server name to terminal.
**      31-Aug-2007 (ashco01) Bug #113490 & Bug #119021.
**          Corrected detection of 'instance name' for GCB & GCD.
**      05-Dec-2007 (ashco01) Bug #119561.
**          Ensure that all Ingres back-end detached processes define the 
**          SYS$SCRATCH logical as this is referenced via II_TEMPORARY
**          when placing temporary DCL files.
**      10-Dec-2007 (ashco01) Bug #119561
**          Define SYS$SCRATCH within all detached processes.
*/
main( int argc, char **argv )
{
    static $DESCALLOC( prcnam );
    unsigned int pqlcnt = 0;
    $DESCALLOC( uicdsc );
    char *param;
    char prcbuf[16];
    ACCDEF2 accmsg;
    unsigned int pid;
    unsigned short chan;
    unsigned short term;
    unsigned int mbxunt;
    int dviitem;
    char buf[128], tmp[128];
    II_VMS_MASK_LONGWORD  efc_state;
    char	*log_start_commands;
    IOSB	iosb;
    ER_ARGUMENT dummy_arg;
    i4		i;
    STATUS status;
    i4          gcc = 0;
    i4          gcc_instance = 0;
    i4          gcb = 0;
    i4          gcb_instance = 0;
    i4          gcd = 0;
    i4          gcd_instance = 0;

	/*
	** setup the type and server_flavor parameters
	*/
    if ( argc >= 2 )
    {
	server_type = argv[1];

        /* Are we starting a GCB, GCC or GCD ? */

        if (STbcompare( server_type, 3, "gcc", 3, TRUE ) == 0) gcc++;
        if (STbcompare( server_type, 3, "gcb", 3, TRUE ) == 0) gcb++;
        if (STbcompare( server_type, 3, "gcd", 3, TRUE ) == 0) gcd++;
    }

    if ( argc >= 3 )
    {
	server_flavor = argv[2];

        /* Need to precede server_flavor with "-instance="
        ** if we're starting a GCB, GCC or GCD.
        */
        gcc_instance = gcc;
        gcb_instance = gcb;
        gcd_instance = gcd;
    }

	/*
	** initialize PM routines and setup the default
	** search parameters for config.dat
	*/
    status = PMinit( );
    if (status)
    {
	pmerr_func(status, 0, &dummy_arg);
	return (status);
    }

    switch( status = PMload((LOCATION *)NULL, pmerr_func) )
    {
	case OK:
	    /* Loaded sucessfully */
	    break;

	case PM_FILE_BAD:
	    /* syntax error */
	    if (status != FAIL)	/* As of Nov 1993, PM.H defines PM_FILE_BAD 1 */
		pmerr_func(status, (i4)0, &dummy_arg);
	    return (status);

	default: 
	    /* unable to open file */
	    if (status != FAIL)	/* FAIL is a useless status to report... */
		pmerr_func(status, (i4)0, &dummy_arg);
	    return (status);
    }

#ifdef EDBC
    PMsetDefault( 0, ERx( "ed" ) );
#else
    PMsetDefault( 0, ERx( "ii" ) );
#endif
    PMsetDefault( 1, PMhost( ) );
    PMsetDefault( 2, server_type );
    PMsetDefault( 3, server_flavor );

	/* read and process pm parameters
	 */
    for ( i = 0; pm_option[i].PM_name != NULL; i++ )
    {
	status = PMget( pm_option[i].PM_name, &param );
	if ( status != OK )
	    continue;

	switch ( pm_option[i].type )
	{
	    unsigned int *target;

	    case TYPE_CLRFLG:
		if ( STbcompare(param, 0, "off", 0, TRUE) != 0 &&
		     STbcompare(param, 0, "on", 0, TRUE)  != 0 )
		{
		    SIprintf("IIRUNDBMS: %s value must be ON or OFF\n",
				pm_option[i].PM_name);
		    SIflush(stdout);
		    log_errmsg( "Must be ON or OFF", SS$_BADPARAM, 1 );
		    return (SS$_BADPARAM);
		}

		target = (unsigned int *)pm_option[i].target;

		if ( STbcompare(param, 0, pm_option[i].keyword, 0, TRUE) == 0)
		     *target &= ~(int)pm_option[i].parameter;

		if ( msg_echo && (STscompare( pm_option[i].PM_name, 0, echo, 0 ) == 0) )
		     ERoptlog( pm_option[i].PM_name, param );

		break;

	    case TYPE_SETFLG:
		if ( STbcompare(param, 0, "off", 0, TRUE) != 0 &&
		     STbcompare(param, 0, "on", 0, TRUE)  != 0 )
		{
		    SIprintf("IIRUNDBMS: %s value must be ON or OFF\n",
				pm_option[i].PM_name);
		    SIflush(stdout);
		    log_errmsg( "Must be ON or OFF", SS$_BADPARAM, 1 );
		    return (SS$_BADPARAM);
		}

		target = (unsigned int *)pm_option[i].target;

		if ( STbcompare(param, 0, pm_option[i].keyword, 0, TRUE) == 0)
		     *target |= (int)pm_option[i].parameter;

		if ( msg_echo )
		     ERoptlog( pm_option[i].PM_name, param );

		break;

	    case TYPE_INT:
		target = (unsigned int *)pm_option[i].target;

		status = CVal( param, target );
		if (status)
		{
		    SIprintf("IIRUNDBMS: %s value must be an integer\n",
				pm_option[i].PM_name);
		    SIflush(stdout);
		    pmerr_func(status, 0, &dummy_arg);
		    return (SS$_BADPARAM);
		}

		if ( msg_echo )
		{
		    STprintf( buf, "%d", *target );
		    ERoptlog( pm_option[i].PM_name, buf );
		}

		break;

	    case TYPE_UIC:
	    {
		$DESCINIT( uicdsc, param );

		status = iics_cvtuic( &uicdsc, (char *)pm_option[i].target );

		if ( !(status & 1) )
		{
		    log_errmsg( "vms_uic invalid", status, 1 );
		    return (status);				/* B56811 */
		}

		if ( msg_echo )
		{
		    if ( *(unsigned int *)(pm_option[i].target) != 0 )
		    {
			STprintf( buf, "%s [%o,%o]", param,
				  ((uic >> 16) & 0xffff), (uic & 0xffff) );
			ERoptlog( pm_option[i].PM_name, buf );
		    }
		}

		break;
            }

	    case TYPE_STR:
		 if (STlength(param) > MAX_STRING_OPTION_LENGTH)
		 {
		    SIprintf("IIRUNDBMS: Max length for %s is %d\n",
				pm_option[i].PM_name, MAX_STRING_OPTION_LENGTH);
		    SIflush(stdout);
		    return (SS$_BADPARAM);
		 }

		 STcopy( param, (char *)pm_option[i].target );

		 if ( msg_echo )
		    ERoptlog( pm_option[i].PM_name, param );

	         break;

	    case TYPE_PQL:
		    /*
		    ** build VMS process quota block
		    */
		quota[pqlcnt].name = (char)pm_option[i].parameter;

		status = CVal( param, &quota[pqlcnt].value );
		if (status)
		{
		    SIprintf("IIRUNDBMS: %s value must be an integer\n",
				pm_option[i].PM_name);
		    SIflush(stdout);
		    pmerr_func(status, 0, &dummy_arg);
		    return (SS$_BADPARAM);
		}

		pqlcnt++;

		if ( msg_echo )
		    ERoptlog( pm_option[i].PM_name, param );

		break;

	    case TYPE_PRIV:
	    {
		char prvbuf[512];
		char *p, *q;
		i4 j;

		    /*
		    ** Remove white space then
		    ** convert the string to upper case, then 
		    ** remove leading and trailing parens
		    */
		if (STlength(param) >= sizeof(prvbuf))
		{
		    SIprintf("IIRUNDBMS: vms_privileges are too long\n");
		    SIprintf("    Actual length (%d) exceeds maximum (%d)\n",
				STlength(param), sizeof(prvbuf));
		    SIflush(stdout);
		    return (SS$_BADPARAM);
		}

		STcopy( param, prvbuf);
		STtrmwhite( prvbuf );
		CVupper( prvbuf );

		    /*
		    ** Scan the comma seperated privilege list and set the
		    ** privileges for each privileges keywork in the list.
		    */
		for ( p = prvbuf; p != 0 && *p != 0; p = q )
		{
		    if ( (q = STindex( p, ERx( "," ), 0 )) != NULL )
			*q++ = '\0';
		    else if ( (q = STindex( p, ERx( ")" ), 0 )) != NULL )
			*q++ = '\0';

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

		    for ( j = 0; prv_table[j].prv_name != NULL; j++ )
		    {
			if ( STscompare( p, 4, prv_table[j].prv_name, 4 ) == 0 )
			{
			    prvadr[0] |= prv_table[j].prv_code_low;
			    prvadr[1] |= prv_table[j].prv_code_hi;
			    if ( msg_echo )
				ERoptlog( pm_option[i].PM_name, prv_table[j].prv_name );
			    break;
			}
		    }
		    if (prv_table[j].prv_name == NULL)
		    {
			/*
			** We failed to find privilege "p" in our table
			*/
			SIprintf("IIRUNDBMS: Syntax error in privilege list\n");
			SIprintf("    Error near byte %d of string %s",
				    p - prvbuf, param);
			SIflush(stdout);
			ERoptlog("Unrecognized privilege:", p);
			return (SS$_BADPARAM);
		    }
		}

		break;
	    }

	    default:
		break;
	}
    }