Example #1
0
static char *
saveloc(char	*path)
{
    char	*rval = NULL;
    char	ptmp[MAX_PATH_LEN + 2];

    if (STlength(path) > MAX_PATH_LEN)
    {
	i4 maxl = MAX_PATH_LEN;

	IIUGmsg(ERget(E_XF0130_Path_Too_Long), FALSE, 2, path, &maxl);

	/* Truncate and save */
	(void) STlcopy(path, ptmp, MAX_PATH_LEN);
	rval = STalloc(ptmp);
    }
    else
    {
	rval = STalloc(path);
    }

    /* Truncate and save */
    (void) STlcopy(path, ptmp, MAX_PATH_LEN);
    rval = STalloc(ptmp);

    return (rval);
}
Example #2
0
/*{
** Name: CXset_context	- Set the CX node "context".
**
** Description:
**
**	If configured for clusters, the CX "context" determines
**	what node the calling utility is bound to.   That is,
**	what directory is used when mapping shared segments, how
**	file names are "decorated", and It determines the default
**	PM hostname, and if running NUMA clusters, the host name
**	override.
**
** Inputs:
**	host	- Node name or host name for the context.
**		  If NULL, value from PHhost is used.
**	rad	- If running NUMA clusters, 1st argument must be the host
**		  name, (or NULL), and a node name is constructed from
**		  the hostname(PMhost)/rad pair as "R<radid>_<hostname>"
**		  If not running NUMA clusters, this must be zero.
**
** Outputs:
**	none.
**
**	Returns:
**		OK				- Context was set.
**		E_CL2C2F_CX_E_BADRAD		- Rad value out of range.
**		E_CL2C42_CX_E_NOT_CONFIGURED	- Node or RAD not configured
**						  as part of the cluster.
**		
**	Exceptions:
**	    none
**
** Side Effects:
**	    Important & plentyful, see description.
**
** History:
**	16-sep-2002 (devjo01)
**	    Created.
*/
STATUS
CXset_context( char * host, i4 rad )
{
#   define HOST_PM_IDX	 1

    STATUS		 status = OK;
    CX_NODE_INFO        *pni;
    char		 namebuf[ CX_MAX_NODE_NAME_LEN + 1 ];

    do
    {
	if ( !host )
	{
	    host = CXhost_name();
	}

	if ( CXcluster_configured() )
	{
	    pni = CXnode_info( host, rad );
	    if ( NULL == pni )
	    {
		status = E_CL2C42_CX_E_NOT_CONFIGURED;
		break;
	    }

	    namebuf[CX_MAX_NODE_NAME_LEN] = '\0';
	    STlcopy( pni->cx_node_name, namebuf, CX_MAX_NODE_NAME_LEN );
	    CVlower( namebuf );
	    STcopy(namebuf, cx_saved_node_name);

	    if ( pni->cx_host_name_l &&
		 ( pni->cx_host_name_l != pni->cx_node_name_l ||
		   0 != STxcompare( pni->cx_node_name, pni->cx_node_name_l,
				    pni->cx_host_name, pni->cx_host_name_l,
				    TRUE, FALSE ) ) )
	    {
		STlcopy( pni->cx_host_name, namebuf, CX_MAX_NODE_NAME_LEN );
		CVlower( namebuf );
		PMsetDefault( HOST_PM_IDX, namebuf );
	    }
	    else
	    {
		PMsetDefault( HOST_PM_IDX, namebuf );
	    }
	    if ( 0 != pni->cx_rad_id )
		CX_Proc_CB.cx_numa_user_rad = pni->cx_rad_id;
	    CX_Proc_CB.cx_numa_cluster_rad = pni->cx_rad_id;
	}
	else
	{
	    PMsetDefault( HOST_PM_IDX, host );
	    if ( 0 != rad )
		CX_Proc_CB.cx_numa_user_rad = rad;
	}
    } while (0);
    return status;
} /* CXset_context */
Example #3
0
void Time2Chars (double dSecond, char* buffer)
{
	char* p;
	char buff1[16];
	char buff2[16];
	int m = 0;
	int h = 0;
	while (dSecond >= 60.0)
	{
		dSecond -= 60.0;
		m++;
	}
	while (m >= 60)
	{
		m -= 60;
		h++;
	}
	dSecond = dSecond*100;
	STprintf(buff1, "%04d", (int)dSecond);
	STlcopy (buff1, buff2, 2);
	p = buff1;
	p += 2;
	STprintf (buffer, "%02d%:%02d:%s", h, m, buff2);

	STcat(buffer, ".");
	STcat(buffer, p);
}
Example #4
0
/*{
** Name: II_GetErrorMessage
**
** Description:
**      Returns the associated error message for the error status.
**
** Inputs:
**      status      Error status.
**      errmsg      Area to be updated with message text.  The maximum length,
**                  in octets, of a returned message is MAX_IIERR_LEN and
**                  does not include the end-of-string marker.
**                  The minimum size of this area should be
**                  (MAX_IIERR_LEN + 1).
**
** Outputs:
**      errmsg      Error text.  If the message text exceeds MAX_IIERR_LEN
**                  then the message is truncated to MAX_IIERR_LEN.
**
** Returns:
**      None.
**
** Example:
**  # include "tngapi.h"
**
**  II_CHAR errmsg[ MAX_IIERR_LEN + 1] = {'\0'};
**  II_INT  status = II_NULL_PARAM;
**
**  II_GetErrorMessage( status, errmsg );
**  printf( "Error message =%s\n", errmsg );
**
** History:
**      24-Jun-2002 (fanra01)
**          Created.
**
}*/
void
II_GetErrorMessage( II_UINT4 status, char* errmsg )
{
    char errormessage[ MAX_IIERR_LEN + 1 ] = { 0 };
#if defined(NT_GENERIC)
    char* p = errormessage;
    int  nlen = 0;

    if (errmsg)
    {
        if (hModule == NULL)
        {
            hModule =  GetModuleHandle( II_MODULENAME );
        }
        if (hModule != NULL)
        {
            FormatMessage(
                FORMAT_MESSAGE_FROM_SYSTEM |
                FORMAT_MESSAGE_FROM_HMODULE |
                FORMAT_MESSAGE_IGNORE_INSERTS,
                (LPCVOID)hModule,
                status,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
                (LPTSTR) errormessage,
                MAX_IIERR_LEN,
                NULL
            );
            STlcopy( errormessage, errmsg, MAX_IIERR_LEN );
        }
    }

#else   /* NT_GENERIC */
 
    /* Here is for Unix platforms , Send back error message to the caller */

    if( status != OK )
     {
      STprintf( errormessage, ERget(status) );
      SIfprintf( stderr,  errormessage );
      STlcopy( errormessage, errmsg, STlength(errormessage) );
     }

#endif 
    return;
}
Example #5
0
static bool
writeMgrFile( char *altPath )
{
    char *dirPath;
    char fullPath[OCFG_MAX_STRLEN];
    FILE *pfile;
    LOCATION loc;
    STATUS status;

# ifdef VMS
    NMgtAt(SYSTEM_LOCATION_VARIABLE,&dirPath);  /* usually II_SYSTEM */
    if (dirPath != NULL && *dirPath)
        STlcopy(dirPath,fullPath,sizeof(fullPath)-20-1);
    else
        return (FALSE);
    STcat(fullPath,"[");
    STcat(fullPath,SYSTEM_LOCATION_SUBDIRECTORY);  /* usually "ingres"  */
    STcat(fullPath,".files]");
    STcat(fullPath,MGR_STR_FILE_NAME);
# else
    NMgtAt(SYSTEM_LOCATION_VARIABLE,&dirPath);  /* usually II_SYSTEM */
    if (dirPath != NULL && *dirPath)
        STlcopy(dirPath,fullPath,sizeof(fullPath)-20-1);
    else
        return (FALSE);
    STcat(fullPath,"/");
    STcat(fullPath,SYSTEM_LOCATION_SUBDIRECTORY);  /* usually "ingres"  */
    STcat(fullPath,"/files/");
    STcat(fullPath,MGR_STR_FILE_NAME);
# endif /* ifdef VMS */

    if ( LOfroms(PATH & FILENAME, fullPath, &loc) != OK )
       return FALSE;

    if (SIfopen(&loc, "w", (i4)SI_TXT, OCFG_MAX_STRLEN, &pfile) != OK)
        return FALSE;

    if (altPath && *altPath)
        SIfprintf(pfile,"%s=%s\n",MGR_STR_PATH,altPath);
    SIfprintf(pfile,"%s=%s\n",MGR_STR_MANAGER,
	driverManager == MGR_VALUE_UNIX_ODBC ? 
        MGR_STR_UNIX_ODBC : MGR_STR_CAI_PT);
    return TRUE;
}
Example #6
0
/*{
** Name: CXhost_name	- Get host name for current machine.
**
** Description:
**
**	This is just a wrapper for PMhost, which assures that
**	the name is not more than CX_MAX_NODE_NAME_LEN characters
**	long and is entirely lower case.
**
** Inputs:
**	none
**
** Outputs:
**	none
**
**	Returns:
**		Address of cached host name.
**		
**	Exceptions:
**	    none
**
** Side Effects:
**	    none.
**
** History:
**	01-oct-2001 (devjo01)
**	    Created.
**	17-dec-2004 (devjo01)
**	    Correct 'cx_saved_node_name' ref to intended 'cx_hostname'.
*/
char *
CXhost_name()
{
    static char cx_hostname[CX_MAX_HOST_NAME_LEN] = { '\0', };

    if ( '\0' == cx_hostname[0] )
    {
	STlcopy( PMhost(), cx_hostname, CX_MAX_HOST_NAME_LEN );
	CVlower(cx_hostname);
    }
    return cx_hostname;
} /* CXhost_name */
Example #7
0
static void
yyputline( char *outtext)
{
	char token_buf[MAX_LINE+1];
	char token_val[MAX_LINE+1];
	char *p = token_buf;
	static char *symc = ERx( 
	   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$");
	i4 symc_l = STlength(symc);
	i4 defidx;
	static i4  iterate_level = 0;

	/* Check to make sure we don't have runaway recursion */
	if (iterate_level++ > MAX_ITERATION)
	{
		SIfprintf( stderr, E_YAPP006 );
		yydump();
	}

	/* Break up the string into tokens and try to resolve symbols */
	while (*outtext != EOS)
	{
		p = token_buf;
		while (STindex(symc, outtext, symc_l) != NULL) {
			STlcopy(outtext, p, 1);
			CMnext(outtext);
			CMnext(p);
		}

		/* Found a token that may be defined as a symbol */
		if (p != token_buf)
		{
			/* If the token is defined then translate the */
			/* value of the substituted text, otherwise just */
			/* output the untranslated text. */
			STcopy(ERx(""), p);
			if (OK == is_defined(token_buf, token_val)) 
				yyputline( token_val );
			else 
				SIprintf("%s", token_buf);
		}

		/* The text being processed at this point is whitespace, */
		/* operators, or some other characters that are not */
		/* valid for tokens. */
		else 
		{
			SIputc(*outtext, stdout);
			CMnext(outtext);
		}
	}
	iterate_level--;
}
Example #8
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;
}
Example #9
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);
}
Example #10
0
/*
** Name:	scs_gwinfo_subget
**
** Description:
**  	grab the value part of the gw string of the form
**          
** 	    var1=value2,var2='value2',var3='value3',var4=value4
**
**  	the input substr is of the form "varN=".  We strip out any quotes
**  	and copy the value to the user buffer.
**
**  	if there are more than one entry for a var, then take
**  	the first one.
**
** Inputs:
**	substr	    substring of the variable name
**  	scb 	    scb with the gw_parm string to scan.
**  	lbuf	    length of output buffer
**
** Outputs:
**	buf 	    buffer to put extracted value string, less quotes.
**  	    	    if substr not found, set to empty string.
**
** Returns:
**	OK  	    	    if got string OK, or no string found.
**  	MO_VALUE_TRUNCATED  if value got truncated to lbuf.
**
** History:
**      22-Apr-1994 (daveb)
**          documented, changed to "first wins"
*/
STATUS
ascs_gwinfo_subget( char *substr, SCD_SCB *scb, i4  lbuf, char *buf )
{
    STATUS  cl_stat = OK;
    i4  sublen;
    i4  outlen;
    i4  inquote = FALSE;
    char *str;
    char *loc;

    *buf = EOS;
    if( (str = scb->scb_sscb.sscb_ics.ics_gw_parms) != NULL )
    {
	sublen = STlength( substr );

	/* for each potential match, check for full match */

	for( ; *str && (loc = STindex( str, substr, 0 )) != NULL ; str++ )
	{
	    /* if this is the substring, get the good stuff. */
	    if( !STbcompare( loc, 0, substr, sublen, FALSE ) )
	    {
		loc += sublen;
		if( *loc == '\'' )
		{
		    loc++;
		    inquote = TRUE;
		}
		str = loc;
		
		while( *loc && (inquote && *loc != '\'') ||
		      (!inquote && *loc != ','))
		    loc++;
		outlen = loc - str;
		if( outlen > (lbuf - 1) )
		{
		    outlen = lbuf - 1;
		    cl_stat = MO_VALUE_TRUNCATED;
		}
		STlcopy( str, buf, outlen );
		break;
	    }
	}
    }
    return( cl_stat );
}
Example #11
0
/*{
** Name: CXdecorate_file_name - Append node name to filename.
**
** Description:
**
**	Append upper case node name to passed filename, keeping
**	total filelength 36 chars or below.
**
** Inputs:
**	filename - buffer holding filename.  Must be > 36 chars in length.
**	nodename - name to append, or if NULL, CXnode_name is used.
**
** Outputs:
**	none.
**
**	Returns:
**		- Pointer to passed filename, so this can be used in-line
**		  to printf, etc.
**		
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
** History:
**	26-sep-2002 (devjo01)
**	    Created.
*/
char *
CXdecorate_file_name( char *filename, char *node )
{
    i4		len, extlen;

    len = STlength(filename);

    if ( NULL == node ) node = CXnode_name(NULL);

    if (len < DI_FILENAME_MAX)
    {
	*(filename + len++) = '_';
	if (len < DI_FILENAME_MAX)
	{
	    extlen = STlcopy(node, filename + len, DI_FILENAME_MAX - len);
	    *(filename + len + extlen) = '\0';
	    CVupper(filename + len);
	}
    }
    return filename;
}
Example #12
0
i4
yylex()
{
	bool pattern;
	bool component;
	bool keyword;
	char *keyhead;
	char yytext[ SI_MAX_TXT_REC + 1 ];
	i4 yyleng;

	/* skip whitespace and comments */
	while( CMwhite( yyp ) || *yyp == EOS || *yyp == '-' )
	{
		/* check for comment */
		if( *yyp == '-' )
		{
			if( STbcompare( yyp, 2, ERx( "--" ), 2, FALSE ) == 0 )
			{
				while( *yyp != EOS )
					CMnext( yyp );
			}
			else
				break;
		}

		if( *yyp == EOS )
		{
			if( SIgetrec( yybuf, sizeof( yybuf ), yyin ) != OK &&
				yywrap() )
			{
				return( 0 );
			}
			else
			{
				yyp = yybuf;
				++yylineno;
			}
		}
		else
			CMnext( yyp );
	}

	/* check for a SYMBOL, PATTERN or keyword */
	yyleng = 0;
	pattern = FALSE;
	keyword = TRUE;
	keyhead = yyp;
	while( CMalpha( yyp ) || *yyp == '%' || *yyp == '$' || *yyp == '*' )
	{
		/* check for component of legal SYMBOL or PATTERN */ 
		component = FALSE;

		/* check for single-character component */
		switch( *yyp )
		{
			case '%':
				pattern = TRUE;
			case '*':
			case '$':
				component = TRUE;
				++yyleng;
				CMnext( yyp );
				if( *yyp == '.' )
				{
					++yyleng;
					CMnext( yyp );
					keyword = FALSE;
					continue;
				}
				else if( CMalpha( yyp ) )
					yyerror(); 
				continue;
		}

		while( CMalpha( yyp ) || CMdigit( yyp ) ||
			*yyp == '_' || *yyp == '-' )
		{
			++yyleng;
			CMnext( yyp );
			component = TRUE;
		}
		if( component )
		{
			if( *yyp == '.' )
			{
				++yyleng;
				CMnext( yyp );
				keyword = FALSE;
				continue;
			}
			continue;
		}
	}

	/* check for uneaten '.' */
	if( *yyp == '.' )
		yyerror();

	if( yyleng > 0 )
	{
		/* A keyword, SYMBOL or PATTERN was scanned */
		char *p;
		i4 i;

		/* put NULL-terminated copy in yytext */
		STlcopy( keyhead, yytext, yyleng );	
		for( p = yytext, i = 0; i <= yyleng; CMnext( p ), i++ );
		*p = EOS;	

		/* check for keywords */
		if( CMalpha( keyhead) && keyword )
		{
			if( STequal( ERx( "IF" ), yytext ) != 0 )
				return( IF );

			if( STequal( ERx( "ELSE" ), yytext ) != 0 )
				return( ELSE );

			if( STequal( ERx( "ELSEIF" ), yytext ) != 0 )
				return( ELSEIF );

			if( STequal( ERx( "ENDIF" ), yytext ) != 0 )
				return( ENDIF );

			if( STequal( ERx( "MIN" ), yytext ) != 0 )
				return( MIN );

			if( STequal( ERx( "MAX" ), yytext ) != 0 )
				return( MAX );

			if( STequal( ERx( "VALID" ), yytext ) != 0 )
				return( VALID );

			if( STequal( ERx( "PRIME" ), yytext ) != 0 )
				return( PRIME );

			if( STequal( ERx( "SIGNED_INT" ), yytext ) != 0 )
				return( SIGNED_INT );

			if( STequal( ERx( "DECIMAL" ), yytext ) != 0 )
				return( DECIMAL );

			if( STequal( ERx( "SIZETYPE" ), yytext ) != 0 )
				return( SIZETYPE );

			if( STequal( ERx( "POWER2" ), yytext ) != 0 )
				return( POWER2 );

			if( STequal( ERx( "REQUIRES" ), yytext ) != 0 )
				return( REQUIRES );

			if( STequal( ERx( "UNDEFINED" ), yytext ) != 0 )
				return( UNDEFINED );

			if( STequal( ERx( "SUM" ), yytext ) != 0 )
			{
				yylval.integer = SUM;
				return( SUM );
			}

			if( STequal( ERx( "ON" ), yytext ) != 0 )
			{
				yylval.real = 1;
				return( BOOL_CON );
			}

			if( STequal( ERx( "OFF" ), yytext ) != 0 )
			{
				yylval.real = 0;
				return( BOOL_CON );
			}

			if( STequal( ERx( "IS" ), yytext ) != 0 )
			{
				yylval.string = STalloc( yytext );
				return( COMPARE_OP );
			}

			if( STequal( ERx( "DIRECTORY" ), yytext ) != 0 )
				return( DIRECTORY );

			if( STequal( ERx( "FILE" ), yytext ) != 0 )
				return( FILESPEC );

		}
		/* valid SYMBOL or PATTERN */
		yylval.string = STalloc( yytext );
		if( pattern )
			return( PATTERN );
		/* don't accept a single '*' as SYMBOL */
		if( yyleng != 1 || *yytext != '*' )
			return( SYMBOL );

		/* push '*' back onto the input stream */
		CMprev( yyp, yybuf );
	}

	/* check for EXEC_TEXT, STR_CON, or EXEC_TEXT_STR */
	if( *yyp == '`' || *yyp == '"' )
	{
		int exec_str = 0;
		char *initstr = yyp;
		char *p = yyp, *text, *yyprev;

		if ( *yyp == '"' )
		{
			CMnext( yyp );
			if ( *yyp == '`' )
			{
				CMnext( p );
				exec_str = 1;
			}
			else
				yyp = p;
		}
		for( yyleng = 0, CMnext( yyp ), yyprev = ERx( "" );
			*yyp != *p || *yyprev == '\\';
			yyprev = ( *yyprev == EOS ) ? yyp : CMnext( yyprev ),
			CMnext( yyp ), ++yyleng )
		{
			if( *yyp == *p && *yyprev == '\\' )
			{
				/* remove escape character */
				char *p1, *p2;

				for( p1 = p2 = yyprev, CMprev( p1, p );
					p1 >= p; CMprev( p1, p ),
					CMprev( p2, p ) )
				{
					CMcpychar( p1, p2 );
				}
				--yyleng;
				CMnext( p );
			}

			if( *yyp == EOS )
				yyerror();
		}
		CMnext( yyp );
		if ( exec_str )
		{
			if ( *yyp == '"' )
				CMnext( yyp );
			else
			{
				/* keep scanning to final '"' */
				p = initstr;
				exec_str = 0;
				yyleng++;
				for( ; *yyp != *p || *yyprev == '\\';
					yyprev = ( *yyprev == EOS ) ? yyp : 
					CMnext( yyprev ),
					CMnext( yyp ), ++yyleng )
				{
					if( *yyp == EOS )
						yyerror();
				}
			}
		}
		text = p;
		CMnext( text );
		STlcopy( text, yytext, yyleng );
		yytext[ yyleng ] = EOS;
		yylval.string = STalloc( yytext );
		if( *p == '`' )
		{
			if ( exec_str )
				return( EXEC_TEXT_STR );
			return( EXEC_TEXT );
		}
		return( STR_CON );
	}

	/* check for NUM_CON */
	yyleng = 0;
	if( *yyp == '-' || CMdigit( yyp ) )
	{
		f8 factor;
		char *p = yyp;

		if( *yyp == '-' )
		{
			++yyleng;
			factor = -1;
			CMnext( yyp );
		}
		else
			factor = 1;
		
		if( !CMdigit( yyp ) )
			CMprev( yyp, yybuf );
		else
		{
			if( *yyp == '-' )
			{
				CMnext( yyp );	
				
			}
			else
				factor = 1;

			while( CMdigit( yyp ) )
			{
				++yyleng;
				CMnext( yyp );
			}

			if( *yyp == '.' )
			{
				++yyleng;
				CMnext( yyp );
				if( !CMdigit( yyp ) )
					yyerror();
				while( CMdigit( yyp ) )
				{
					++yyleng;
					CMnext( yyp );
				}
			}
			else if( *yyp == 'K' || *yyp == 'M' )
			{
				++yyleng;
				CMnext( yyp );
			}

			STlcopy( p, yytext, yyleng ); 
			yytext[ yyleng ] = EOS;

			if( yytext[ yyleng - 1 ] == 'K' )
			{
				factor = 1024;
				yytext[ yyleng - 1 ] = EOS;
			}
			else if( yytext[ yyleng - 1 ] == 'M' )
			{
				factor = 1048576;
				yytext[ yyleng - 1 ] = EOS;
			}
			CVaf( yytext, ERx( '.' ), &yylval.real );
			yylval.real *= factor;
			return( NUM_CON );
		}
	}

	if( STbcompare( yyp, 2, ERx( ">=" ), 2, FALSE ) == 0 )
	{
		yylval.string = STalloc( ERx( ">=" ) );
		CMnext( yyp );
		CMnext( yyp );
		return( COMPARE_OP );
	}
	if( STbcompare( yyp, 2, ERx( "<=" ), 2, FALSE ) == 0 )
	{
		yylval.string = STalloc( ERx( "<=" ) );
		CMnext( yyp );
		CMnext( yyp );
		return( COMPARE_OP );
	}
	/* check for COMPARE_OP */
	if( STbcompare( yyp, 1, ERx( "<" ), 1, FALSE ) == 0 )
	{
		yylval.string = STalloc( ERx( "<" ) );
		CMnext( yyp );
		return( COMPARE_OP );
	}
	if( STbcompare( yyp, 1, ERx( ">" ), 1, FALSE ) == 0 ) 
	{
		yylval.string = STalloc( ERx( ">" ) );
		CMnext( yyp );
		return( COMPARE_OP );
	}
	if( STbcompare( yyp, 2, ERx( "==" ), 2, FALSE ) == 0 )
	{
		yylval.string = STalloc( ERx( "==" ) );
		CMnext( yyp );
		CMnext( yyp );
		return( COMPARE_OP );
	}

	/* check for characters which get passed directly */
	switch( *yyp )
	{
		char *p;

		case '(':
		case ')':
		case '[':
		case ']':
		case '{':
		case '}':
		case ':':
		case ';':
		case ',':
		case '=':
			p = yyp;
			CMnext( yyp );
			return( *p );	

		case '+':
			yylval.string = STalloc( ERx( "+" ) );
			CMnext( yyp );
			return( *yylval.string );

		case '-':
			yylval.string = STalloc( ERx( "-" ) );
			CMnext( yyp );
			return( *yylval.string );

		case '*':
			yylval.string = STalloc( ERx( "*" ) );
			CMnext( yyp );
			return( *yylval.string );

		case '/':
			yylval.string = STalloc( ERx( "/" ) );
			CMnext( yyp );
			return( *yylval.string );
	}

	/* check for LOGIC_OP */
	if( STbcompare( yyp, 3, ERx( "&&" ), 3, FALSE ) == 0 )
	{
		yylval.string = STalloc( ERx( "&&" ) );
		CMnext( yyp );
		CMnext( yyp );
		return( LOGIC_OP );
	}
	if( STbcompare( yyp, 3, ERx( "||" ), 3, FALSE ) == 0 )
	{
		yylval.string = STalloc( ERx( "||" ) );
		CMnext( yyp );
		CMnext( yyp );
		return( LOGIC_OP );
	}

	/* anything else is an error */
	yyerror();

}
Example #13
0
STATUS
xfsetdirs(char *dir, char *frompath, char *intopath)
{
    auto i2	dirflag;
    auto char 	*s;
    char	*locbuf;
    STATUS	status;

    locbuf = XF_REQMEM(MAX_LOC + 1, FALSE);

    if (dir == NULL || *dir == EOS)	
    {
	/* Default to current directory. */
	status = LOgt(locbuf, &Xf_dir);
        if(status != OK)
        {
#ifdef UNIX                 
            status = LOfakepwd(locbuf, &Xf_dir);
#endif
            if(status != OK)
            {
                IIUGerr(E_XF0061_Can_Not_Determine_Dir, UG_ERR_ERROR, 0);
                return(FAIL);
            }
        }
	dir = NULL;
    }
    else
    {
	STlcopy(dir, locbuf, MAX_LOC);
	if (LOfroms(PATH, locbuf, &Xf_dir) != OK)
	{
	    IIUGerr(E_XF0006_Invalid_directory_pat, UG_ERR_ERROR, 1, dir);
	    return (FAIL);
	}

	if (!LOisfull(&Xf_dir))
	{
	    auto LOCATION	xloc;
	    char		xbuf[MAX_LOC + 1];

	    /* 
	    ** path spec. is a relative specification -- we must expand it 
	    ** to a full pathname. 
	    */
	    LOcopy(&Xf_dir, xbuf, &xloc);
	    status = LOgt(locbuf, &Xf_dir);
            if(status != OK)
            {
                IIUGerr(E_XF0061_Can_Not_Determine_Dir, UG_ERR_ERROR, 0);
                return(FAIL);
            }
	    LOaddpath(&Xf_dir, &xloc, &Xf_dir);
	}

	/* LOisdir and LOexist are archaic and should be replaced by LOinfo. */
	LOisdir(&Xf_dir, &dirflag);
	if (dirflag != ISDIR || LOexist(&Xf_dir) != OK)
	{
	    IIUGerr(E_XF0006_Invalid_directory_pat, UG_ERR_ERROR, 1, dir);
	    return (FAIL);
	}
    }
    LOtos(&Xf_dir, &s);

    /* the COPY FROM path doesn't have to exist. */
    if (frompath != NULL && *frompath != EOS)
	Xf_from_path = saveloc(frompath);

    /* the COPY INTO path doesn't have to exist. */
    if (intopath != NULL && *intopath != EOS)
	Xf_into_path = saveloc(intopath);

    IIUGmsg(ERget(S_XF0064_Unload_Directory_is), FALSE, 1, 
		(PTR)(Xf_into_path == NULL ? s : Xf_into_path));
    IIUGmsg(ERget(S_XF0065_Reload_Directory_is), FALSE, 1, 
		(PTR)(Xf_from_path == NULL ? s : Xf_from_path));

    return (OK);
}
Example #14
0
bool
EXsys_report( register EX_ARGS	*exargs, char *buffer )
{
    /*
    ** Number of message arguments; we add 2 because the PC and PSL are
    ** present in exarg_array (which is simply the exception signal vector)
    ** but aren't counted in exarg_count.
    */
    i4 arg_count = exargs->exarg_count + 2;

    /* Report Hardware Exceptions
    **
    **	This should report all hardware or system exceptions (including
    **	those that get mapped into internal Ingres exceptions.  All available
    **  program information should be formatted and printed into the output
    **	buffer.
    **
    **  We return FALSE for normal INGRES exceptions.  These are exceptions
    **  where:
    **	1.	The exception number is in the correct range for INGRES
    **		exceptions.  Unfortunately, this will also be true if someone
    **		signals an RMS failure.  So in addition, we check that:
    **	2.	The signal array's PC is where lib$signal returns to EXsignal,
    **		meaning that EXsignal signaled this exception.
    */
    /*
    **    if (CLERROR(exargs->exarg_num) &&
    **        exargs->exarg_array[arg_count-2] == &EXsignal_PC)
    */
    if (CLERROR(exargs->exarg_num))
    {
        return FALSE;
    }
    else
    {
        char	bufs[256];
        $DESCRIPTOR(buf, bufs);
        unsigned short	len;
        unsigned char	info[4];

        EXdump(EV_SIGVIO_DUMP);

        if ( !in_sysrep )
        {
            in_sysrep = TRUE;

            if (Ex_print_stack)
            {
                Ex_print_stack(NULL, NULL, NULL, ex_print_error, TRUE);
            }

            in_sysrep = FALSE;
        }

        lib$sys_getmsg(&exargs->exarg_num, &len, &buf, 0, info);
        if (info[1] == 0 || arg_count < info[1])
        {
            /*
            ** No args or insufficient args; don't try to format it.
            */
            STlcopy(bufs, buffer, len);
        }
        else
        {
            $DESCRIPTOR(obuf, buffer);

            /* Format it.  Use lib$sys_faol, so any number of args works */
            obuf.dsc$w_length = buf.dsc$w_length;
            buf.dsc$w_length = len;
            lib$sys_faol(&buf, &len, &obuf, exargs->exarg_array);
            buffer[len] = '\0';
        }
        return TRUE;
    }
}
Example #15
0
/*
** Name: gipParseSaveSet()
**
** Description:
**	
**	Extract save set data from XML DOM nodes and use the to populate
**	new_pkgs_info structure.
**
** input:
**	doc - Pointer to XML document containing instance info
**	cur - Pointer to saveset element in XML doc 
**
** History:
**	04-Sep-2007 (hanje04)
**	    Created.
*/
static void
gipParseSaveSet( xmlDocPtr doc, xmlNodePtr cur )
{
    xmlChar *ele_text;
    xmlChar	*attrib;

    attrib = xmlGetProp(cur, "product"); /* ingres or vectorwise */
    STlcopy(attrib, new_pkgs_info.product, MAX_REL_LEN);
    DBG_PRINT("Parsing saveset: product=%s\n",new_pkgs_info.product);

    cur = cur->xmlChildrenNode;
    while (cur != NULL)
    {
	char tmpbuf[MAX_LOC];

	if ( ! xmlStrcmp( cur->name, (const xmlChar *)"basename" ) )
	{
	    ele_text = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
	    if ( STlen( ele_text ) < MAX_REL_LEN )
	    {
		STprintf( tmpbuf, "%s", ele_text );
		STcopy( tmpbuf, new_pkgs_info.pkg_basename );
	    }

	    xmlFree( ele_text );
	}
	else if ( ! xmlStrcmp( cur->name, (const xmlChar *)"version" ) )
	{
	    ele_text = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
	    if ( STlen( ele_text ) < MAX_VERS_LEN )
	    {
		STprintf( tmpbuf, "%s", ele_text );
		STcopy( tmpbuf, new_pkgs_info.version );
	    }

	    xmlFree( ele_text );
	}
	else if ( ! xmlStrcmp( cur->name, (const xmlChar *)"arch" ) )
	{
	    ele_text = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
	    if ( STlen( ele_text ) < MAX_ARCH_LEN )
	    {
		STprintf( tmpbuf, "%s", ele_text );
		STcopy( tmpbuf, new_pkgs_info.arch );
	    }

	    xmlFree( ele_text );
	}
	else if ( ! xmlStrcmp( cur->name, (const xmlChar *)"format" ) )
	{
	    ele_text = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
	    if ( STlen( ele_text ) < MAX_FORMAT_LEN )
	    {
		STprintf( tmpbuf, "%s", ele_text );
		STcopy( tmpbuf, new_pkgs_info.format );
	    }

	    xmlFree( ele_text );
	}
	else if ( ! xmlStrcmp( cur->name, (const xmlChar *)"location" ) )
	{
	    /* skip this one, new_pkgs_info.file_loc is set at startup */
	}
	else if ( ! xmlStrcmp( cur->name, (const xmlChar *)"package" ) )
	{
	    u_char	idxstr[5];

	    ele_text = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
	    attrib = xmlGetProp(cur, "idx"); /* get the attribute */
	    new_pkgs_info.pkgs |= packages[atoi(attrib)]->bit;

	    xmlFree( ele_text );
	    xmlFree( attrib );
	}
	cur = cur->next;
    }

    return;
}
Example #16
0
i4
main (int argc, char **argv) 
{
    STATUS status=OK;
    PTR drvH=NULL;
    char **list=NULL;
    ATTR_ID **attrList=NULL;
    char **defAttr=NULL;
    i4 count=0, attrCount = 0, retcount;
    i4 i;
    bool badCmdLine = FALSE, rmPkg = FALSE, has_default = FALSE, has_alt
        = FALSE, isReadOnly = FALSE, mgrSpecified = FALSE, batch = FALSE,
	def_or_alt=FALSE;
    i4 pathType = OCFG_SYS_PATH; 
    char altPath[OCFG_MAX_STRLEN] = "\0";
    char drvMgr[OCFG_MAX_STRLEN] = "\0";
    char line[MAXLINE],prompt[MAXLINE];
    char driverPath[OCFG_MAX_STRLEN];
    char *dirPath;
    char driverName[OCFG_MAX_STRLEN];
    char *ii_installation;
    char *p = NULL;
    char custName[OCFG_MAX_STRLEN];
    char etxt[512];

    ATTR_ID driverList[6] = 
    {
        { DRV_ATTR_DRIVER,          "\0" },
        { DRV_ATTR_DRIVER_ODBC_VER, DRV_STR_VERSION },
        { DRV_ATTR_DRIVER_READONLY, DRV_STR_N },
        { DRV_ATTR_DRIVER_TYPE,     DRV_STR_INGRES },
        { DRV_ATTR_VENDOR,          DRV_STR_INGRES_CORP },
        { DRV_ATTR_DONT_DLCLOSE,    DRV_STR_ONE }
    };
    int drvCount = sizeof(driverList) / sizeof(driverList[0]);

    ATTR_ID **drvList = (ATTR_ID **)MEreqmem( (u_i2) 0, 
	(u_i4)drvCount, TRUE, (STATUS *) NULL);

    for (i = 0; i < drvCount; i++)
    {
        drvList[i] = (ATTR_ID *)MEreqmem( (u_i2) 0, 
	    (u_i4)sizeof(ATTR_ID), TRUE, (STATUS *) NULL);
        drvList[i]->id = driverList[i].id;
        drvList[i]->value = (char *)MEreqmem( (u_i2) 0, 
    	    (u_i4)OCFG_MAX_STRLEN, TRUE, (STATUS *) NULL);
        STcopy(driverList[i].value, drvList[i]->value);
    }

    if ( argc > 7 )
        badCmdLine = TRUE;

    /*
    ** Parse the command line.  Reject invalid arguments.
    */
    if ( !badCmdLine && argc > 1 )
    {
	if (checkArgs("-h", argc, argv, NULL, NULL ) )
	{
	   display_help();
           PCexit(0);	
	}
	if (checkArgs("-help", argc, argv, NULL, NULL ) )
	{
	   display_help();
           PCexit(0);	
	}
        if ( checkArgs("-batch", argc, argv, NULL, NULL ) )
            batch = TRUE;
        if ( checkArgs("-rmpkg", argc, argv, NULL, NULL ) )
            rmPkg = TRUE;
        if (checkArgs("-r", argc, argv, NULL, NULL ) )
            isReadOnly = TRUE;
        if ( checkArgs("-p", argc, argv, altPath, NULL ) )
            pathType = OCFG_ALT_PATH;
        if ( checkArgs("-m", argc, argv, NULL, drvMgr ) )
			mgrSpecified = TRUE;
    }

    /*
    ** Set driver manager according to user input.  Default is unixODBC.
    */
    if (mgrSpecified && !STbcompare( drvMgr, 0, MGR_STR_CAI_PT, 0, TRUE ) )
        driverManager = MGR_VALUE_CAI_PT;
    else
	driverManager = MGR_VALUE_UNIX_ODBC;

    /*
    ** If none of the arguments are recognized, flag an error.
    */
    if ( !batch && !rmPkg && !isReadOnly && pathType != OCFG_ALT_PATH && !mgrSpecified && argc > 1)
        badCmdLine = TRUE;

    if ( badCmdLine )
    {
        display_help();
        PCexit(FAIL);
    }
    
    if ( isReadOnly )
        STcopy(DRV_STR_Y, drvList[2]->value); 
    else
        STcopy(DRV_STR_N, drvList[2]->value); 

    if ( !writeMgrFile( altPath ) )
    {
        SIprintf("Aborting due to error writing %s/files/%s\n",
           SYSTEM_LOCATION_SUBDIRECTORY, MGR_STR_FILE_NAME); 
        PCexit(FAIL);
    }
    defAttr = getDefaultInfo(); 
    if (defAttr == NULL)
    {
        SIprintf("Aborting due to error reading %s/install/%s\n",
            SYSTEM_LOCATION_VARIABLE, INFO_STR_FILE_NAME);
        PCexit(FAIL);
    }

    /*
    ** Get the path of the driver library and create the path/libname string.
    */
    NMgtAt(SYSTEM_LOCATION_VARIABLE,&dirPath);  /* usually II_SYSTEM */
    if (dirPath != NULL && *dirPath)
        STlcopy(dirPath,driverPath,sizeof(driverPath)-20-1);
    else
    {
        SIprintf("Error--%s is not defined\n",SYSTEM_LOCATION_VARIABLE);
        PCexit(FAIL);
    }
# ifdef VMS
    STcat(driverPath,"[");
    STcat(driverPath,SYSTEM_LOCATION_SUBDIRECTORY);  /* usually "ingres"  */
    STcat(driverPath,".library]");
    if ( isReadOnly )
        STcat(driverPath,defAttr[INFO_ATTR_RONLY_DRV_FNAME]);
    else
        STcat(driverPath,defAttr[INFO_ATTR_DRIVER_FILE_NAME]);
# else
    STcat(driverPath,"/");
    STcat(driverPath,SYSTEM_LOCATION_SUBDIRECTORY);  /* usually "ingres"  */
    STcat(driverPath,"/lib/");
    if ( isReadOnly )
        STcat(driverPath,defAttr[INFO_ATTR_RONLY_DRV_FNAME]);
    else
        STcat(driverPath,defAttr[INFO_ATTR_DRIVER_FILE_NAME]);
# endif /* ifdef VMS */
    STcopy(driverPath,drvList[0]->value);
    /*
    ** Initialize the cache from the odbcinst.ini file.
    */
    openConfig(NULL, pathType, altPath, &drvH, &status);
    if (status != OK)
    {
        STprintf(etxt,"Could not open from path %s.\n",
            pathType == OCFG_ALT_PATH ? altPath : "/usr/local/etc");
        display_err(etxt,status);
        PCexit(FAIL);
    }
    if (rmPkg)
    {
        delConfigEntry( drvH, defAttr[INFO_ATTR_DRIVER_NAME], &status );
        delConfigEntry( drvH, defAttr[INFO_ATTR_ALT_DRIVER_NAME], &status );
        closeConfig(drvH, &status);
        PCexit(OK);
    }
    /*
    ** Get the driver count.
    */
    retcount = listConfig( drvH, count, list, &status );
    if (status != OK)
    {
        STprintf(etxt,"Could not list drivers.\n");
        display_err(etxt,status);
        PCexit(FAIL);
    }
    count = retcount;
    if (count)
    {
        /*
        ** Get the list of recognized drivers.
        */
	list = (char **)MEreqmem( (u_i2) 0, 
	    (u_i4)(count * sizeof(char *)), TRUE, 
	    (STATUS *) NULL);
	for (i = 0; i < count; i++)
	    list[i] =  (char *)MEreqmem( (u_i2) 0, (u_i4)OCFG_MAX_STRLEN, 
	        TRUE, (STATUS *) NULL);
        listConfig( drvH, count, list, &status );
        if (status != OK)
        {
            STprintf(etxt,"Could not list drivers.\n");
            display_err(etxt,status);
            PCexit(FAIL);
        }
    }
    for (i = 0; i < count; i++)
    {
        def_or_alt = FALSE;
	if (!has_default)
	{
            has_default = STbcompare( list[i], 0, 
                defAttr[INFO_ATTR_DRIVER_NAME], 0, TRUE ) 
                   == 0 ? TRUE : FALSE;
            if (has_default)
                def_or_alt = TRUE; 
        }
        if (!has_alt)
        {
            has_alt = STbcompare( list[i], 0, 
                defAttr[INFO_ATTR_ALT_DRIVER_NAME], 0, 
                   TRUE ) == 0 ? TRUE : FALSE;
            if (has_alt)
                def_or_alt = TRUE; 
        }
        if (def_or_alt)
        {
            if ( !batch )
	    {
                STprintf(prompt,
         "\tInstallation has pre-defined version of %s.\n\tOverwrite? (Yes/No)", 
		list[i]);
                if ( line_get( prompt, "", FALSE, line ) == EOF )
                {
                    SIprintf("ODBC driver installation safely aborted\n");
                    PCexit(OK);
                }
                STzapblank(line,line);
                if ( line[0] != 'y' && line [0] != 'Y' )
                {
                    SIprintf( "%s left untouched\n", list[i] );
		    continue; 
                }
            } /* if (!batch) */
            STcopy(list[i],driverName);
            setConfigEntry( drvH, driverName, drvCount, drvList, &status );
            if (status != OK)
            {
                STprintf(etxt,"Could not write driver entry.\n");
                display_err(etxt,status);
                PCexit(FAIL);
            }
        } /* if (has_default || has_alt) */ 
        else if ( !batch )
        {
                STprintf(prompt,
         "\tInstallation has custom version of %s.\n\tDelete? (Yes/No)", 
		list[i]);
                if ( line_get( prompt, "", FALSE, line ) == EOF )
                {
                    SIprintf("ODBC driver installation safely aborted\n");
                    PCexit(OK);
                }
                STzapblank(line,line);
                if ( line[0] != 'y' && line [0] != 'Y' )
                {
                    SIprintf( "%s left untouched\n", list[i] );
                    continue;
                }
            STcopy(list[i],driverName);
            delConfigEntry( drvH, driverName, &status );
            if (status != OK)
            {
                STprintf(etxt,"Could not write driver entry.\n");
                display_err(etxt,status);
                PCexit(FAIL);
            } 
        } /* if (!batch) && !has_default */
    } /* for (count... */
    if (!has_default) 
    {
        setConfigEntry( drvH, defAttr[INFO_ATTR_DRIVER_NAME], drvCount,
	    drvList, &status );
        if (status != OK)
        {
            STprintf(etxt,"Could not write driver entry.\n");
            display_err(etxt,status);
            PCexit(FAIL);
        }
    }
    if (!has_alt) 
    {
        setConfigEntry( drvH, defAttr[INFO_ATTR_ALT_DRIVER_NAME], drvCount,
	    drvList, &status );
        if (status != OK)
        {
            STprintf(etxt,"Could not write driver entry.\n");
            display_err(etxt,status);
            PCexit(FAIL);
        }
    }
    closeConfig(drvH, &status);
    if (status != OK)
    {
        STprintf(etxt,"Could not close driver info.\n");
        display_err(etxt,status);
        PCexit(FAIL);
    }
    if (count)
    {
        for (i = 0; i < count; i++)
	    MEfree((PTR)list[i]);
        MEfree((PTR)list);
    }
    for (i = 0; i < drvCount; i++)
    {
        MEfree((PTR)drvList[i]->value);
        MEfree((PTR)drvList[i]);
    }
    MEfree((PTR)drvList);

    PCexit(OK);
}
Example #17
0
/* Name: adu_getconverter - Obtains the name of converter mapping file
**			    to use for unicode coercion. 
** Description:
**
** To obtain the mapping file to be used for carrying out unicode-local
** character conversion. The following mechanism is followed:
**
** 1. Check symbol table for user defined converter setting
**    II_UNICODE_CONVERTER. If set then return this setting 
** 2. If the variable is not set then 
**	2.a Get the platform character set
**	2.b Read the aliasmaptbl file. 
** 	2.c Search the alias file for platform charset.
** 3. If still not found then find the II_CHARSETxx value
**    for ingres installation and search the alias file for 
**    this value. 
** 4. If none of these attempts succeed then return default 
**    with a warning to the errorlog if this happens 
** 
** Input:
**	converter -	Place holder for the output string, 
**			It is assumed that the area is at least MAX_LOC
**			chars in size.
** Output:
**	converter -	Pointer to string where the output
**			converter name is stored.
** History:
**
**	22-jan-2004 (gupsh01)
**	    Added.
**	14-Jun-2004 (schka24)
**	    Safe charset name handling.
*/
STATUS
adu_getconverter(
    char	*converter)
{
    STATUS		stat;
    char		*tptr;
    char		*env = 0;
    char		chset[CM_MAXATTRNAME+1];
    char		pcs[CM_MAXLOCALE+1]; /* platform character set */
    char		norm_pcs[CM_MAXLOCALE+1];
    CL_ERR_DESC         syserr;
    char                *alias_buffer = NULL;
    char                *bufptr = NULL;
    char                *buf = NULL;
    ADU_ALIAS_MAPPING   *aliasmapping;
    ADU_ALIAS_DATA	*aliasdata;	
    char 		*datasize;
    SIZE_TYPE		filesize = 0;
    SIZE_TYPE		sizemap = 0;
    SIZE_TYPE		sizedata = 0;
    i4			bytes_read;
    char		*abufptr;
    i4			i = 0;
    i4			index = 0;


/* STEP 1 */
    NMgtAt(ERx("II_UNICODE_CONVERTER"), &env);
    if (env && *env)
    {
        STlcopy(env, converter, MAX_LOC-1);
	return OK;
    }

/* STEP 2 */
    stat = CM_getcharset(pcs);
    
    if (CMopen_col("aliasmaptbl", &syserr, CM_UCHARMAPS_LOC) != OK)
    {
      /* return an ERROR if we are unable to open the file */
      return FAIL;
    }

    /* initialize buf to help read from the aliasmaptbl file */
    buf = MEreqmem(0, COL_BLOCK, TRUE, &stat);
    if (buf == NULL || stat != OK)
    {
       CMclose_col(&syserr, CM_UCHARMAPS_LOC);
       return (FAIL);
    }

    /* First file buffer has size information. */
    stat = CMread_col(buf, &syserr);
    if (stat != OK)
    {
        MEfree((char *)buf);
        CMclose_col(&syserr, CM_UCHARMAPS_LOC);
       return (FAIL);
    }

    tptr = buf;
    bytes_read = COL_BLOCK;

    /* filesize is the first entry of the map file */
    filesize = *(SIZE_TYPE *) buf;
    tptr += sizeof(SIZE_TYPE);
    tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR));

    /* allocate working space for the data */
    alias_buffer = (char *)MEreqmem(0, filesize, TRUE, &stat);
    if (alias_buffer == NULL || stat != OK)
    {
       CMclose_col(&syserr, CM_UCHARMAPS_LOC);
       return (FAIL);
    }
    abufptr = alias_buffer;
    MEcopy (buf, COL_BLOCK, abufptr);
    abufptr += COL_BLOCK;

    /* Read the file till it is read completely */
    for ( ;bytes_read < filesize;)
    {
        stat = CMread_col(buf, &syserr);
        if (stat != OK)
        {
          MEfree((char *)buf);
          MEfree((char *)alias_buffer);
          CMclose_col(&syserr, CM_UCHARMAPS_LOC);
          return (FAIL);
	}
	bytes_read += COL_BLOCK;
        MEcopy (buf, COL_BLOCK, abufptr);
        abufptr += COL_BLOCK;
    }

    if (bytes_read < filesize)
    {
      /* we had to exit for some unknown reason */
      MEfree((char *)buf);
      MEfree((char *)alias_buffer);
      CMclose_col(&syserr, CM_UCHARMAPS_LOC);
      return (FAIL);
    }
    tptr = alias_buffer;
    tptr += sizeof(SIZE_TYPE);
    tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR));

    /* Read the size of the MappingArray nodes */
    sizemap = *(SIZE_TYPE *) tptr;
    tptr += sizeof(SIZE_TYPE);
    tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR));

    /* initialize buffer for ADU_ALIAS_MAPPING buffer */
    aliasmapping = (ADU_ALIAS_MAPPING *) MEreqmem(0, sizemap, TRUE, &stat);
    if (aliasmapping == NULL)
    {
      MEfree((char *)buf);
      MEfree((char *)alias_buffer);
      CMclose_col(&syserr, CM_UCHARMAPS_LOC);
      return (FAIL);
    }

    /* Copy data for ADU_ALIAS_MAPPING array */
    MEcopy(tptr, sizemap, aliasmapping);
    tptr += sizemap;
    tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR));

    /* Get size for the aliasdata */
    sizedata = *(SIZE_TYPE *) tptr;
    tptr += sizeof(SIZE_TYPE);
    tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR));

     /* Initialize buffer for ADU_ALIAS_MAPPING buffer */
    aliasdata = (ADU_ALIAS_DATA *) MEreqmem(0, sizedata, TRUE, &stat);
    if (aliasdata == NULL)
    {
      MEfree((char *)buf);
      MEfree((char *)alias_buffer);
      MEfree((char *)aliasmapping);
      CMclose_col(&syserr, CM_UCHARMAPS_LOC);
      return (FAIL);
    }

    /* Copy the ADU_ALIAS_DATA array */
    MEcopy(tptr, sizedata, aliasdata);
    tptr += sizedata;
    tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR));

    /* Close the "aliasmaptbl" file */
    CMclose_col(&syserr, CM_UCHARMAPS_LOC);

    /* Normalize pcs */

    adu_csnormalize (pcs, STlength(pcs), norm_pcs);

    /* Retrieve the pcs value */
    for (i=0; i < sizedata/sizeof(ADU_ALIAS_DATA); i++)
    {
      if ((STcompare (aliasdata[i].aliasNameNorm, norm_pcs)) == 0)
      {
	index = aliasdata[i].aliasMapId; 
	/* found */
	STcopy (aliasmapping[index].mapping_id, 
		  converter);

        /* cleanup */
        MEfree((char *)buf);
        MEfree((char *)alias_buffer);
        MEfree((char *)aliasmapping);
        MEfree((char *)aliasdata);

        return (OK);
      } 
    }

/* STEP 3 */
    /* Obtain Ingres characterset */
    STcopy("default", converter);
    CMget_charset_name(&chset[0]);
    if (STcasecmp(chset, "UTF8") != 0)
    { 
	    /* search maptable for env  */ 
	for (i=0; i < sizedata/sizeof(ADU_ALIAS_DATA); i++)
	{
	    if ((STcompare (aliasdata[i].aliasNameNorm, norm_pcs)) == 0)
	    {
		index = aliasdata[i].aliasMapId; 
		/* found */
		STcopy (aliasmapping[index].mapping_id, converter);
		break;
	    }
	}
    }

    /* cleanup */
    MEfree((char *)buf);
    MEfree((char *)alias_buffer);
    MEfree((char *)aliasmapping);
    MEfree((char *)aliasdata);

    /* FIXME warning or error if still "default" ? */

    return (OK);
}
Example #18
0
/*{
** Name: LGK_initialize()	-  initialize the lg/lk shared mem segment.
**
** Description:
**	This routine is called by the LGinitialize or LKinitialize routine.  IT
**	assumes that a previous caller has allocated the shared memory segment.
**
**	If it discovers that the shared memory segment has not yet been
**	initialized, it calls the LG and LK initialize-memory routines to do so.
**
** Inputs:
**	flag		- bit mask of:
**			  LOCK_LGK_MEMORY to lock the shared data segment
**			  LGK_IS_CSP if process is CSP process this node.
**
** Outputs:
**	sys_err		- place for system-specific error information.
**
**	Returns:
**	    OK	- success
**	    !OK - failure (CS*() routine failure, segment not mapped, ...)
**	
**  History:
**	Summer, 1992 (bryanp)
**	    Working on the new portable logging and locking system.
**	19-oct-1992 (bryanp)
**	    Check memory version number when attaching.
**	22-oct-1992 (bryanp)
**	    Change LGLKDATA.MEM to lglkdata.mem.
**	23-Oct-1992 (daveb)
**	    name the semaphore too.
**	13-feb-1993 (keving)
**	    Remove support for II_LGK_MEMORY_SIZE. If II_LG_MEMSIZE
**	    is not set then calculate memory size from PM values. 
**	24-may-1993 (bryanp)
**	    If the shared memory is the wrong version, don't install the
**	    at_exit handlers (the rundown routines won't be able to interpret
**	    the memory properly).
**	26-jul-1993 (jnash)
**	    Add 'flag' param lock the LGK data segment.
**	20-sep-1993 (bryanp)
**	    In addition to calling PCatexit, call (on VMS) sys$dclexh, since
**		there are some situations (image death and image rundown without
**		process rundown) which are caught neither by PCatexit (since
**		PCexit isn't run) nor by check-dead threads (since process
**		rundown never happened). This fixes a hole where an access-
**		violating ckpdb or auditdb command never got cleaned up.
**	31-jan-1994 (bryanp)
**	    Back out a few "features" which are proving countereffective:
**	    1) Don't bother checking mem_creator_pid to see if the previous
**		creator of the shared memory has died. This was an attempt to
**		gracefully re-use sticky shared memory following a system crash,
**		but it is suspected as being the culprit in a series of system
**		failures by re-initializing the shared memory at inopportune
**		times.
**	    2) Don't complain if the shared memory already exists but is of a
**		different size than you expected. Just go ahead and try to use
**		it anyway.
**	21-feb-1994 (bryanp)
**	    Reverse item (1) of the above 31-jan-1994 change and re-enable the
**		graceful re-use of shared memory. People weren't happy with
**		having to run ipcclean and csinstall all the time.
**	23-may-1994 (bryanp)
**	    On VMS, disable ^Y for LG/LK-aware processes. We don't want to allow
**		^Y because you might interrupt the process right in the middle
**		of an LG or LK operation, while holding the shared memory
**		semaphore, and this would then wedge the whole installation.
**          
**      17-May-1994 (daveb) 59127
**          Attach lgk_mem semaphore if we're attaching to the segment.
**      30-jan-1995 (lawst01) bug 61984
**          Use memory needed calculation from the 'lgk_calculate_size'
**          function to determine the size of the shared memory pool for
**          locking and locking. If the II_LG_MEMSIZE variable is specified
**          with a value larger than needed use the supplied value. If
**          lgk_calculate_size is unable to calculate a size then use the
**          magic number of 400000.  In addition issue a warning message
**          and continue executing in the event the number of pages
**          allocated is less than the number requested. 
**	24-apr-1997 (nanpr01)
**	    Reinstate Bryanp's change. In the process of fixing bug 61984
**	    by Steve Lawrence and subsequent undo of Steve's fix by Nick
**	    Ireland on 25-jun-96 (nick) caused the if 0 code removed.
**	    Part of the Steve's change was not reinstated such as not returning
**	    the status and exit and continue.
**	    1. Don't complain if the shared memory already exists but is of a
**	    different size than you expected. Just go ahead and try to use
**	    it.
**     18-aug-1998 (hweho01)
**          Reclaim the kernel resource if LG/LK shared memory segment is  
**          reinitialized. If the shared segment is re-used (the previous creator 
**          of the shared segment has died), the cross-process semaphores get 
**          initialized more than once at the same locations. That cause the
**          kernel resource leaks on DG/UX (OS release 4.11MU04). To fix the 
**          problem, CS_cp_sem_cleanup() is called to destroy all the 
**          semaphores before LG/LK shraed segment get recreated. 
**          CS_cp_sem_cleanup() is made dependent on xCL_NEED_SEM_CLEANUP and
**          OS_THREADS_USED, it returns immediately for most platforms.  
**	27-Mar-2000 (jenjo02)
**	    Added test for crossed thread types, refuse connection
**	    to LGK memory with E_DMA811_LGK_MT_MISMATCH.
**	18-apr-2001 (devjo01)
**	    s103715 (Portable cluster support)
**	    - Add CX mem requirement calculations.
**	    - Add LGK_IS_CSP flag to indicate that LGK memory is being
**	      initialized for a CSP process.
**	    - Add basic CX initialization.
**      19-sep-2002 (devjo01)
**          If running NUMA clustered allocate memory out of local RAD.
**	30-Apr-2003 (jenjo02)
**	    Rearchitected to silence long-tolerated race conditions.
**	    BUG 110121.
**	27-feb-2004 (devjo01)
**	    Rework allocation of CX shared memory to be compatible
**	    with race condition fix introduced for bug 110121.
**	29-Dec-2008 (jonj)
**	    If lgk_calculate_size() returns FAIL, the total memory
**	    needed exceeds MAX_SIZE_TYPE and we can't continue, but
**	    tell what we can about the needs of the various bits of
**	    memory before quitting.
**	06-Aug-2009 (wanfr01)
**	    Bug 122418 - Return E_DMA812 if LOCK_LGK_MUST_ATTACH is
**	    is passed in and memory segment does not exist
**      20-Nov-2009 (maspa05) bug 122642
**          In order to synchronize creation of UUIDs across servers added
**          a semaphore and a 'last time' variable into LGK memory. 
**      14-Dec-2009 (maspa05) bug 122642
**          #ifdef out the above change for Windows. The rest of the change
**          does not apply to Windows so the variables aren't defined.
*/
STATUS
LGK_initialize(
i4	  	flag,
CL_ERR_DESC	*sys_err,
char		*lgk_info)
{
    PTR		ptr;
    SIZE_TYPE	memleft;
    SIZE_TYPE	size;
    STATUS	ret_val;
    STATUS	mem_exists;
    char	mem_name[15];
    SIZE_TYPE	allocated_pages;
    i4		me_flags;
    i4		me_locked_flag;
    SIZE_TYPE	memory_needed;
    char	*nm_string;
    SIZE_TYPE	pages;
    LGK_MEM	*lgk_mem;
    i4		err_code;
    SIZE_TYPE   min_memory;
    i4		retries;
    i4		i;
    i4		attached;
    PID		*my_pid_slot;
    i4		clustered;
    u_i4	nodes;
    SIZE_TYPE	cxmemreq;
    PTR		pcxmem;
    LGLK_INFO	lgkcount;
    char	instid[4];

    CL_CLEAR_ERR(sys_err);

    /*
    ** if LGK_base is set then this routine has already been called.  It is
    ** set up so that both LGiniitalize and LKinitialize calls it, but only
    ** the first call does anything.
    */

    if (LGK_base.lgk_mem_ptr)
	return(OK);

    PCpid( &LGK_my_pid );

    memory_needed = 0;
    NMgtAt("II_LG_MEMSIZE", &nm_string);
    if (nm_string && *nm_string)
#if defined(LP64)
	if (CVal8(nm_string, (long*)&memory_needed))
#else
	if (CVal(nm_string, (i4 *)&memory_needed))
#endif /* LP64 */
	    memory_needed = 0;

    /* Always calculate memory needed from PM resource settings  */
    /* and compare with supplied value, if supplied value is less */
    /* than minimum then use minimum                             */

    min_memory = 0;
    if ( OK == lgk_get_counts(&lgkcount, FALSE))
    {
	if ( lgk_calculate_size(FALSE, &lgkcount, &min_memory) )
	{
	    /*
	    ** Memory exceeds MAX_SIZE_TYPE, can't continue.
	    ** 
	    ** Do calculation again, this time with "wordy"
	    ** so user can see allocation bits, then quit.
	    */
	    lgk_calculate_size(TRUE, &lgkcount, &min_memory);
	    return (E_DMA802_LGKINIT_ERROR); 
	}
    }
    if (min_memory)
       memory_needed = (memory_needed < min_memory) ? min_memory
                                                    : memory_needed;
    else
       memory_needed = (memory_needed < 400000 ) ? 400000 
                                                 : memory_needed;

    clustered = (i4)CXcluster_enabled();
    cxmemreq = 0;
    if ( clustered )
    {

	if ( OK != CXcluster_nodes( &nodes, NULL ) )
	    nodes = 0;
	cxmemreq = CXshm_required( 0, nodes, lgkcount.lgk_max_xacts,
		    lgkcount.lgk_max_locks, lgkcount.lgk_max_resources );
	if ( MAX_SIZE_TYPE - memory_needed < cxmemreq )
	{
	    /*
	    ** Memory exceeds MAX_SIZE_TYPE, can't continue.
	    ** 
	    ** Do calculation again, this time with "wordy"
	    ** so user can see allocation bits, then quit.
	    */
	    SIprintf("Total LG/LK/CX allocation exceeds max of %lu bytes by %lu\n"
	    	     "Adjust logging/locking configuration values and try again\n",
		         MAX_SIZE_TYPE, cxmemreq - (MAX_SIZE_TYPE - memory_needed));
	    lgk_calculate_size(TRUE, &lgkcount, &min_memory);
	    return (E_DMA802_LGKINIT_ERROR); 
	}
	memory_needed += cxmemreq;
    }

    if ( memory_needed < MAX_SIZE_TYPE - ME_MPAGESIZE )
	pages = (memory_needed + ME_MPAGESIZE - 1) / ME_MPAGESIZE;
    else
        pages = memory_needed / ME_MPAGESIZE;

    /*
    ** Lock the LGK segment if requested to do so
    */
    if (flag & LOCK_LGK_MEMORY)
	me_locked_flag = ME_LOCKED_MASK;
    else
	me_locked_flag = 0;

    me_flags = (me_locked_flag | ME_MSHARED_MASK | ME_IO_MASK | 
		ME_CREATE_MASK | ME_NOTPERM_MASK | ME_MZERO_MASK);
    if (CXnuma_user_rad())
        me_flags |= ME_LOCAL_RAD;

    STcopy("lglkdata.mem", mem_name);

    /*
    ** In general, we just want to attach to the shared memory and detect if
    ** we are the first process to do so. However, there are ugly race
    ** conditions to consider, as well as complications because the shared
    ** memory may be left around following a system crash.
    **
    ** First we attempt to create the shared memory. Usually it already exists,
    ** so we check for and handle the case of "already exists".
    */

    /*
    ** (jenjo02)
    **
    ** Restructured to better handle all those ugly race conditions
    ** which are easily reproduced by running two scripts, one that
    ** continuously executes "lockstat" while the other is starting
    ** and stopping Ingres.
    **
    ** For example,
    **
    **		lockstat A	acquires and init's the memory
    **		RCP		attaches to "A" memory
    **		lockstat A	terminates normally
    **		lockstat B	attaches to "A" memory, sees that
    **				"A"s pid is no longer alive, and
    **				reinitializes the memory, much to
    **				the RCP's chagrin.
    ** or (more commonly)
    **
    **		lockstat A	acquires and begins to init the mem
    **		RCP		attaches to "A" memory which is
    **				still being zero-filled by lockstat,
    **				checks the version number (zero),
    **				and fails with a E_DMA434 mismatch.
    **
    ** The fix utilizes the mem_ext_sem to synchronize multiple
    ** processes; if the semaphore hasn't been initialized or
    ** if mem_version_no is zero, we'll wait one second and retry,
    ** up to 60 seconds before giving up. This gives the creating
    ** process time to complete initialization of the memory.
    **
    ** Up to LGK_MAX_PIDS are allowed to attach to the shared
    ** memory. When a process attaches it sets its PID in the
    ** first vacant slot in lgk_mem->mem_pid[]; if there are
    ** no vacant slots, the attach is refused. When the process
    ** terminates normally by calling LGK_rundown(), it zeroes
    ** its PID slot.
    **
    ** When attaching to an existing segment, we check if  
    ** there are any live processes still using the memory;
    ** if so, we can't destroy it (no matter who created it).
    ** If there are no live processes attached to the memory,
    ** we destroy and reallocate it (based on current config.dat
    ** settings).
    */

    for ( retries = 0; ;retries++ )
    {
	LGK_base.lgk_mem_ptr = (PTR)NULL;
	
	/* Give up if unable to get memory in one minute */
#if defined(conf_CLUSTER_BUILD)
        if (retries > 1)
#else
	if ( retries )
#endif
	{
	    if ( retries < 60 )
		PCsleep(1000);
	    else
	    {
		/* Another process has it blocked way too long */
		uleFormat(NULL, E_DMA800_LGKINIT_GETMEM, (CL_ERR_DESC *)NULL,
				ULE_LOG, NULL, NULL, 0, NULL, &err_code, 0);
		/* Unable to attach allocated shared memory segment. */
		return (E_DMA802_LGKINIT_ERROR); 
	    }
	}

	ret_val = MEget_pages(me_flags,
				pages, mem_name, (PTR*)&lgk_mem,
				&allocated_pages, sys_err);

	if ( mem_exists = ret_val )
	{
	    if (ret_val == ME_ALREADY_EXISTS)
	    {
		ret_val = MEget_pages((me_locked_flag | 
				       ME_MSHARED_MASK | ME_IO_MASK),
				      pages, mem_name, (PTR*)&lgk_mem,
				      &allocated_pages, sys_err);
#if defined(conf_CLUSTER_BUILD)
                if (ret_val && !retries)
                    continue;  /* try one more time */
#endif
	    }
	    if (ret_val)
	    {
		uleFormat(NULL, ret_val, sys_err,
				ULE_LOG, NULL, NULL, 0, NULL, &err_code, 0);
		uleFormat(NULL, E_DMA800_LGKINIT_GETMEM, (CL_ERR_DESC *)NULL,
				ULE_LOG, NULL, NULL, 0, NULL, &err_code, 0);
		/* Unable to attach allocated shared memory segment. */
		return (E_DMA802_LGKINIT_ERROR); 
	    }
	}
	else if (flag & LOCK_LGK_MUST_ATTACH)
	{	
	    /* Do not use the shared segment you just allocated */
	    MEfree_pages((PTR)lgk_mem, allocated_pages, sys_err);
	    return (E_DMA812_LGK_NO_SEGMENT); 
	}

	size = allocated_pages * ME_MPAGESIZE;

	/* Expose this process to the memory */
	LGK_base.lgk_mem_ptr = (PTR)lgk_mem;

	if ( mem_exists )
	{
	    /*
	    ** Memory exists.
	    **
	    ** Try to acquire the semaphore. If it's
	    ** uninitialzed, retry from the top.
	    **
	    ** If the version is zero, then another
	    ** process is initializing the memory;
	    ** keep retrying until the version is 
	    ** filled in.
	    **
	    */
	    if ( ret_val = CSp_semaphore(1, &lgk_mem->mem_ext_sem) )
	    {
		if ( ret_val != E_CS000A_NO_SEMAPHORE )
		{
		    uleFormat(NULL, ret_val, sys_err,
				ULE_LOG, NULL, NULL, 0, NULL, &err_code, 0);
		    ret_val = E_DMA802_LGKINIT_ERROR;
		    break;
		}
		continue;
	    }

	    /* Retry if still being init'd by another process */
	    if ( !lgk_mem->mem_version_no )
	    {
		CSv_semaphore(&lgk_mem->mem_ext_sem);
		continue;
	    }

	    /*
	    ** Check pids which appear to be attached to
	    ** the memory:
	    **
	    ** If any process is still alive, then we
	    ** assume the memory is consistent and use it.
	    **
	    ** If a process is now dead, it terminated
	    ** without going through LGK_rundown
	    ** to zero its PID slot, zero it now.
	    **
	    ** If there are no live PIDs attached to 
	    ** the memory, we destroy and recreate it.
	    */
	    my_pid_slot = (PID*)NULL;
	    attached = 0;

	    for ( i = 0; i < LGK_MAX_PIDS; i++ )
	    {
		if ( lgk_mem->mem_pid[i] && 
		     PCis_alive(lgk_mem->mem_pid[i]) )
		{
		    attached++;
		}
		else
		{
		    /* Vacate the slot */
		    if (lgk_mem->mem_pid[i])
		    {
			uleFormat(NULL, E_DMA499_DEAD_PROCESS_INFO, (CL_ERR_DESC *)NULL,
				ULE_LOG, NULL, NULL, 0, NULL, &err_code, 2,
				0, lgk_mem->mem_pid[i],
				0, lgk_mem->mem_info[i].info_txt);
		    }
		    lgk_mem->mem_pid[i] = (PID)0;
		    lgk_mem->mem_info[i].info_txt[0] = EOS;

		    /* Use first vacant slot for this process */
		    if ( !my_pid_slot )
		    {
			my_pid_slot = &lgk_mem->mem_pid[i];
			LGK_base.lgk_pid_slot = i;
		    }
		}
		/* Quit when both questions answered */
		if ( attached && my_pid_slot )
		    break;
	    }

	    /* If no living pids attached, destroy/reallocate */
	    if ( !attached )
	    {
		CSv_semaphore(&lgk_mem->mem_ext_sem);
		if ( LGK_destroy(allocated_pages, sys_err) )
		{
		    ret_val = E_DMA802_LGKINIT_ERROR;
		    break;
		}
		continue;
	    }

	    /* All attached pids alive? */
	    if ( !my_pid_slot )
	    {
		/* ... then there's no room for this process */
		uleFormat(NULL, E_DMA80A_LGK_ATTACH_LIMIT, (CL_ERR_DESC *)NULL,
		    ULE_LOG, NULL, NULL, 0, NULL, &err_code, 1,
		    0, attached);
	        ret_val = E_DMA802_LGKINIT_ERROR;
	    }
	    else if (lgk_mem->mem_version_no != LGK_MEM_VERSION_CURRENT)
	    {
		uleFormat(NULL, E_DMA434_LGK_VERSION_MISMATCH, (CL_ERR_DESC *)NULL,
		    ULE_LOG, NULL, NULL, 0, NULL, &err_code, 2,
		    0, lgk_mem->mem_version_no, 0, LGK_MEM_VERSION_CURRENT);
		ret_val = E_DMA435_WRONG_LGKMEM_VERSION;
	    }
	    /*
	    ** Don't allow mixed connections of MT/non-MT processes.
	    ** Among other things, the mutexing mechanisms are 
	    ** incompatible!
	    */
	    else if ( (CS_is_mt() && (lgk_mem->mem_status & LGK_IS_MT) == 0) ||
		     (!CS_is_mt() &&  lgk_mem->mem_status & LGK_IS_MT) )
	    {
		uleFormat(NULL, E_DMA811_LGK_MT_MISMATCH, (CL_ERR_DESC *)NULL,
		    ULE_LOG, NULL, NULL, 0, NULL, &err_code, 2,
		    0, (lgk_mem->mem_status & LGK_IS_MT) ? "OS"
							 : "INTERNAL",
		    0, (CS_is_mt()) ? "OS"
				    : "INTERNAL");
		ret_val = E_DMA802_LGKINIT_ERROR;
	    }
	    else
	    {
		/*
		** CX memory (if any) will lie immediately past LGK header.
		*/
		pcxmem = (PTR)(lgk_mem + 1);
		pcxmem = (PTR)ME_ALIGN_MACRO(pcxmem, sizeof(ALIGN_RESTRICT));

		LGK_base.lgk_lkd_ptr = (char *)LGK_base.lgk_mem_ptr +
					lgk_mem->mem_lkd;
		LGK_base.lgk_lgd_ptr = (char *)LGK_base.lgk_mem_ptr +
					lgk_mem->mem_lgd;
		
		/* Stuff our pid in first vacant slot */
		*my_pid_slot = LGK_my_pid;
		STlcopy(lgk_info, lgk_mem->mem_info[i].info_txt, LGK_INFO_SIZE-1);
	    }

#if defined(VMS) || defined(UNIX)
	    /* set up pointers to reference the uuid mutex and last time
	     * variable */

	    if (!ID_uuid_sem_ptr)
           	ID_uuid_sem_ptr=&lgk_mem->id_uuid_sem;

	    if (!ID_uuid_last_time_ptr)
                ID_uuid_last_time_ptr=&lgk_mem->uuid_last_time;

	    if (!ID_uuid_last_cnt_ptr)
                ID_uuid_last_cnt_ptr=&lgk_mem->uuid_last_cnt;
#endif

	    CSv_semaphore(&lgk_mem->mem_ext_sem);
	}
	else
	{

	    /* Memory did not exist */
	    /* Zero the version to keep other processes out */
	    lgk_mem->mem_version_no = 0;

#if defined(VMS) || defined(UNIX)
	    /* set up the uuid mutex and last time pointers to
	     * reference the objects in shared memory */

	    {
	        STATUS id_stat;

	        ID_uuid_sem_ptr=&lgk_mem->id_uuid_sem;
                ID_uuid_last_time_ptr=&lgk_mem->uuid_last_time;
                ID_uuid_last_cnt_ptr=&lgk_mem->uuid_last_cnt;
	        *ID_uuid_last_cnt_ptr=0;
	        ID_UUID_SEM_INIT(ID_uuid_sem_ptr,CS_SEM_MULTI,"uuid sem",
				&id_stat);
	    }
#endif

	    /* ... then initialize the mutex */
	    CSw_semaphore(&lgk_mem->mem_ext_sem, CS_SEM_MULTI,
	    			    "LGK mem ext sem" );

	    /* Record if memory created for MT or not */
	    if ( CS_is_mt() )
		lgk_mem->mem_status = LGK_IS_MT;

	    /*
	    ** memory is as follows:
	    **
	    **	-----------------------------------------------------------|
	    **	| LGK_MEM struct (keep track of this mem)	           |
	    **	|							   |
	    **	-----------------------------------------------------------|
	    **	| If a clustered installation memory reserved for CX       |
	    **	|							   |
	    **	------------------------------------------------------------
	    **	| LKD - database of info for lk system			   |
	    **	|							   |
	    **	------------------------------------------------------------
	    **	| LGD - database of info for lg system			   |
	    **	|							   |
	    **	------------------------------------------------------------
	    **	| memory manipulated by LGKm_* routines for structures used |
	    **	| by both the lk and lg systems.			   |
	    **	|							   |
	    **	------------------------------------------------------------
	    */

	    /* put the LGK_MEM struct at head of segment leaving ptr pointing 
	    ** at next aligned piece of memory
	    */

	    /*
	    ** CX memory (if any) will lie immediately past LGK header.
	    */
	    pcxmem = (PTR)(lgk_mem + 1);
	    pcxmem = (PTR)ME_ALIGN_MACRO(pcxmem, sizeof(ALIGN_RESTRICT));

	    LGK_base.lgk_lkd_ptr = pcxmem + cxmemreq;
	    LGK_base.lgk_lkd_ptr = (PTR) ME_ALIGN_MACRO(LGK_base.lgk_lkd_ptr,
						sizeof(ALIGN_RESTRICT));
	    lgk_mem->mem_lkd = (i4)((char *)LGK_base.lgk_lkd_ptr -
					 (char *)LGK_base.lgk_mem_ptr);

	    LGK_base.lgk_lgd_ptr = (PTR) ((char *) LGK_base.lgk_lkd_ptr +
					    sizeof(LKD));
	    LGK_base.lgk_lgd_ptr = (PTR) ME_ALIGN_MACRO(LGK_base.lgk_lgd_ptr,
						sizeof(ALIGN_RESTRICT));
	    lgk_mem->mem_lgd = (i4)((char *)LGK_base.lgk_lgd_ptr -
					 (char *)LGK_base.lgk_mem_ptr);

	    /* now initialize the rest of memory for allocation */

	    /* how much memory is left? */

	    ptr = ((char *)LGK_base.lgk_lgd_ptr + sizeof(LGD));
	    memleft = size - (((char *) ptr) - ((char *) LGK_base.lgk_mem_ptr));

	    if ( (ret_val = lgkm_initialize_mem(memleft, ptr)) == OK &&
		 (ret_val = LG_meminit(sys_err)) == OK &&
		 (ret_val = LK_meminit(sys_err)) == OK )
	    {
		/* Clear array of attached pids and pid info */
		for ( i = 0; i < LGK_MAX_PIDS; i++ )
		{
		    lgk_mem->mem_pid[i] = (PID)0;
		    lgk_mem->mem_info[i].info_txt[0] = EOS;
		}

		/* Set the creator pid */
		LGK_base.lgk_pid_slot = 0;
		lgk_mem->mem_creator_pid = LGK_my_pid;

		/* Set the version, releasing other processes */
		lgk_mem->mem_version_no = LGK_MEM_VERSION_CURRENT;
	    }
	    else
	    {
		uleFormat(NULL, ret_val, (CL_ERR_DESC *)NULL,
			    ULE_LOG, NULL, NULL, 0, NULL, &err_code, 0);
		ret_val = E_DMA802_LGKINIT_ERROR;

		/* Destroy the shared memory */
		LGK_destroy(allocated_pages, sys_err);
	    }
	}

	if ( ret_val == OK )
	{
	    PCatexit(LGK_rundown);

	    if ( clustered )
	    {
		/*
		** Perform preliminary cluster connection and CX memory init.
		*/

		/* Get installation code */
		NMgtAt("II_INSTALLATION", &nm_string);
		if ( nm_string )
		{
		    instid[0] = *(nm_string);
		    instid[1] = *(nm_string+1);
		}
		else
		{
		    instid[0] = 'A';
		    instid[1] = 'A';
		}
		instid[2] = '\0';
		ret_val = CXinitialize( instid, pcxmem, flag & LGK_IS_CSP );
		if ( ret_val )
		{
		    /* Report error returned from CX */
		    uleFormat(NULL, ret_val, (CL_ERR_DESC *)NULL,
			ULE_LOG, NULL, NULL, 0, NULL, &err_code, 0 );
		    break;
		}
	    }

#ifdef VMS
	    {
	    static $EXHDEF	    exit_block;
	    i4			ctrl_y_mask = 0x02000000;

	    /*
	    ** On VMS, programs like the dmfjsp and logstat run as images in
	    ** the shell process. That is, the system doesn't start and stop
	    ** a process for each invocation of the program, it just starts
	    ** and stops an image in the same process. This means that if
	    ** the program should die, the image may be rundown but the process
	    ** will remain, which means that the check-dead threads of other
	    ** processes in the installation will not feel that they need to
	    ** rundown this process, since it's still alive.
	    **
	    ** By declaring an exit handler, which will get a chance to run
	    ** even if PCexit isn't called, we improve our chances of getting
	    ** to perform rundown processing if we should die unexpectedly.
	    **
	    ** Furthermore, we ask DCL to disable its ^Y processing, which
	    ** lessens the chance that the user will interrupt us while we
	    ** are holding the semaphore.
	    */
	    exit_block.exh$g_func = LGK_rundown;
	    exit_block.exh$l_argcount = 1;
	    exit_block.exh$gl_value = &exit_block.exh$l_status;

	    if (sys$dclexh(&exit_block) != SS$_NORMAL)
		ret_val = FAIL;

	    lib$disable_ctrl(&ctrl_y_mask, 0);
	    }
#endif
	}
	break;
    }

    if ( ret_val )
	LGK_base.lgk_mem_ptr = NULL;

    return(ret_val);
}
Example #19
0
/*{
** Name: CXget_context - Parse command arguments for NUMA args.
**
** Description:
**
**	One particularly ugly requirement of NUMA clusters, is the need
**	to specify the target context of certain commands that
**	normally could easily determine a default context by themselves.
**
**	E.g. 'lockstat' run on any node of a non-NUMA cluster "knows"
**	implicitly that the current node corresponds to the current host.
**
**	However, in a NUMA cluster, this happy state, no longer applies.
**	If our sysadm logs onto a node which is configured into two or
**	more virtual NUMA nodes, there is no way for 'lockstat', etc.,
**	to guess which of the virtual nodes is the target for the Ingres
**	tool.
**
**	We try to make a virtue of this neccesity by centralizing the
**	parsing needed for these commands and in passing pick up a
**	generalized way of setting processor affinity for Ingres tools.
**	
**	Two types of arguments are checked here:
**	 '-rad' is a RAD spec, in which the host machine is implicitly
**	the local machine.
**
**	 '-node' may refer to either a local RAD by its node name or 
**	node alias, or to a node anywhere in thr cluster if CX_NSC_NODE_GLOBAL
**	is set.
**
**	Both arguments can be in the form -arg=value, or -arg value.
**
**	The users input	is checked against the following rules:
**
**	R1: If NOT running clusters, '-node' parameter will always
**	    cause an error.
**
**	R2: Only one of either "-node" or "-rad" is allowed.
**
**	R3: If "-rad" is present, value must correspond to a valid RAD.
**
**	R4: If "-node" is present, it must be a valid node, or node alias.
**
**	    R4a: If CX_NSC_NODE_GLOBAL is not set, node must match local host
**	         name or be hosted (virtual nodes only) by local host.
**
**	R5: If not otherwise specified, and running NUMA clusters,
**	    RAD value is taken from environment variable II_DEFAULT_RAD.
**
**	R6: If running NUMA clusters, and CX_NSC_RAD_OPTIONAL is not
**	    set, an error will be reported if context is not set by a
**	    valid -rad, or -node, or II_DEFAULT_RAD value.
**
**	R7: If rules R2-R6 are not violated, and CX_NSC_CONSUME is set,
**	    and an matching parameter or parameter pair was provided,
**	    the parameters are removed from the argument vector, and
**	    the argument count is adjusted.
**
**	R8: If CX_NSC_SET_CONTEXT is set, and not running NUMA clusters,
**	    and a valid RAD value was provided with an explicit '-rad'
**	    argument, CXnuma_bind_to_rad is called to set process affinity
**	    to the specified RAD.
**
**	R9: If CX_NSC_SET_CONTEXT is set, running NUMA clusters, or
**	    if a valid '-node' parameter was supplied, CXset_cluster
**	    is called for the specified node.
**
**	R10: If CX_NSC_REPORT_ERRS is set, and an error occurred,
**	    message is sent to stdout.
**	
**	If all appropriate rules are met, then OK is returned.
**	Caller should be set up to catch and complain about any
**	extra invalid parameters.
**	
**	If outbuf is not NULL, node name if copied out if status =
**	OK, else error message text is copies out.  In both cases
**	only a max of outlen chars are returned, including an EOS.
**
** Inputs:
**	
**	pargc	- Address of integer holding # of arg strings.
**
**	argv	- Array of string pointers to argument values.
**
**	flags	- Flag bits OR'ed together.  Valid flags are:
**
**		CX_NSC_REPORT_ERRS - Emit any error message to stdout.
**
**		CX_NSC_NODE_GLOBAL - Allow node argument to refer to
**				     Nodes outside the current host.
**
**		CX_NSC_CONSUME	   - Eat any -rad/-node args & values if OK.
**
**		CX_NSC_IGNORE_NODE - Ignore '-node' params in scan.
**
**		CX_NSC_SET_CONTEXT - Set CX context based on good params.
**
**		CX_NSC_RAD_OPTIONAL - Don't fail if NUMA & RAD not set.
**				     If running NUMA clusters, only
**				     set this in combination with
**				     CX_NSC_SET_CONTEXT if you are sure
**				     that shared memory won't be accessed,
**				     and all you need is to retreive the
**				     context later (e.g. iirun).
**
**	outbuf  - buffer to receive nodename, or error message text.
**
**	outlen  - limit to # bytes copied to outbuf.
**
** Outputs:
**	
**	*pargc	- decremented by if argument(s) are consumed.
**
**	argv	- Adjused to remove consumed argument(s).
**
**	outbuf  - Holds '\0' terminated string with either nodename
**		  or error message depending on status.
**
**	Returns:
**		OK				- All is well.
**		E_CL2C40_CX_E_BAD_PARAMETER	- Bad params values, 
**						  or bad combination
**						  of parameters.
**		E_CL2C43_CX_E_REMOTE_NODE	- Node specified was not on
**						  current host machine.
**		E_CL2C2F_CX_E_BADRAD		- Rad value out of range.
**		E_CL2C42_CX_E_NOT_CONFIGURED	- Node or RAD not configured
**						  as part of a cluster.
**		E_CL2C41_CX_E_MUST_SET_RAD	- Running NUMA clusters,
**						  and no argument, or
**						  environment variable, set
**					          the RAD context.
**	
**	Exceptions:
**	    none
**
** Side Effects:
**	    See CXnuma_bind_to_rad(), if called with a '-rad'
**	    argument outside a NUMA cluster, else see
**	    CXset_context().
**
** Notes:
**	Typically in a NUMA cluster configuration, the target RAD
**	information is needed very early in the applications logic,
**      since it cannot implicitly determine the virtual node it
**	is intended to be running on.
**
** History:
**	18-sep-2002 (devjo01)
**	    Created.
*/
STATUS
CXget_context( i4 *pargc, char *argv[], i4 flags, char *outbuf, i4 outlen )
{
    STATUS		 status = OK;
    CX_NODE_INFO        *pni = NULL;
    bool		 numa;
    i4			 arg, radarg = 0, nodearg = 0, badarg = 0;
    i4			 target_rad;
    i4			 argstokill = 1;
    char		*pvalue = NULL, *argp, *host;
    char		 lclbuf[256];
    i4			 erargc;
    ER_ARGUMENT	 	 erargs[2];

    host = CXhost_name();

    do
    {
	/* Scan passed arguments for "-rad" & "-node" */
	for ( arg = 1; arg < *pargc; arg++ )
	{
	    argp = argv[arg];
	    if ( '-' != *argp ) continue;

	    if ( 0 == STxcompare(argp, 4, ERx( "-rad" ), 4, FALSE, FALSE) )
	    {
		if ( radarg || nodearg )
		{
		    /* R2 */
		    badarg = arg;
		    break;
		}

		radarg = arg;
		if ( *(argp + 4) == '=' )
		{
		    pvalue = argp + 5;
		}
		else if ( '\0' != *(argp + 4) || 
			  (arg >= (*pargc - 1)) )
		{
		    /* R3 */
		    badarg = arg;
		    break;
		}
		else
		{
		    /* Next argument must be a valid RAD ID */
		    pvalue = argv[++arg];
		    argstokill = 2;
		}
		if ( '\0' == *pvalue )
		{
		    /* R3 */
		    badarg = radarg;
		    break;
		}
		if ( OK != CVan( pvalue, &target_rad ) ||
				  target_rad <= 0 )
		{
		    /* R3 */
		    badarg = arg;
		    break;
		}
	    }
	    else if ( !(CX_NSC_IGNORE_NODE & flags) &&
		      0 == STxcompare(argp, 5, ERx( "-node" ), 5,
				      FALSE, FALSE ) ) 
	    {
		if ( radarg || nodearg )
		{
		    /* R2 */
		    badarg = arg;
		    break;
		}
		nodearg = arg;
		if ( *(argp + 5) == '=' )
		{
		    pvalue = argp + 6;
		}
		else if ( ('\0' != *(argp + 5)) || 
			  (arg >= (*pargc - 1)) )
		{
		    /* R4 */
		    badarg = arg;
		    break;
		}
		else
		{
		    /* Next argument must be a node ID */
		    pvalue = argv[++arg];
		    argstokill = 2;
		}
		if ( '\0' == *pvalue )
		{
		    /* R4 */
		    badarg = nodearg;
		    break;
		}
	    }
	} /* end for */

	/* If bad syntax seen, scram & fail */
	if ( badarg )
	{
	    status = E_CL2C40_CX_E_BAD_PARAMETER;
	    erargc = 1;
	    erargs[0].er_size = 0; erargs[0].er_value = (PTR)argv[badarg];
	    break;
	}

	numa = CXnuma_cluster_configured();

	/* If no explicit parameters seen, try default */
	if ( numa && !pvalue && !(flags & CX_NSC_RAD_OPTIONAL) )
	{
	    /* R5 */
	    argp = ERx( "II_DEFAULT_RAD" );
	    pvalue = getenv( argp );
	    if ( pvalue &&
		 ( ( '\0' == *pvalue ) || OK != CVan(pvalue, &target_rad) ) )
		pvalue = NULL;
	}

	/* Got a value either from command line or environment */
	if ( pvalue )
	{
	    if ( nodearg )
	    {
		if ( CXcluster_configured() )
		{
		    pni = CXnode_info(pvalue, 0);
		    if ( pni )
		    {
			/* If can't be global, make sure its local */
			if ( !(flags & CX_NSC_NODE_GLOBAL) &&
			     !( ( 0 == STxcompare( host, 0,
				 pni->cx_node_name, pni->cx_node_name_l,
				 TRUE, FALSE ) ) ||
				( ( 0 != pni->cx_host_name_l ) &&
				  ( 0 == STxcompare( host, 0,
				    pni->cx_host_name,
				    pni->cx_host_name_l, TRUE, FALSE ) ) )
			      )
			   )
			{
			    /* Node must be local and was not.  (R4a) */
			    status = E_CL2C43_CX_E_REMOTE_NODE;
			    erargc = 2;
			    erargs[0].er_size = 0;
			    erargs[0].er_value = (PTR)argv[0];
			    erargs[1].er_size = pni->cx_host_name_l;
			    erargs[1].er_value = (PTR)(pni->cx_host_name);
			    break;
			}
		    }
		}
	    }
	    else if ( numa )
	    {
		pni = CXnode_info(host, target_rad);
	    }
	    else if ( target_rad > CXnuma_rad_count() )
	    {
		if ( !(flags & CX_NSC_RAD_OPTIONAL) )
		{
		    /* R3 */
		    status = E_CL2C2F_CX_E_BADRAD;
		    erargc = 0;
		    break;
		}
		target_rad = 0;
	    }

	    if ( ( numa || nodearg ) && ( NULL == pni ) )
	    {
		/* Requested node/rad not configured */
		/* R3, R4 */
		if ( !argp ) argp = argv[radarg+nodearg];
		status = E_CL2C42_CX_E_NOT_CONFIGURED;
		erargc = 1;
		erargs[0].er_size = 0; erargs[0].er_value = (PTR)argp;
		break;
	    }
	}
	else
	{
	    if ( numa && !(flags & CX_NSC_RAD_OPTIONAL) )
	    {
		/* If required argument missing, scram & fail */
		status = E_CL2C41_CX_E_MUST_SET_RAD;
		erargc = 1;
		erargs[0].er_size = 0; erargs[0].er_value = (PTR)argv[0];
		break;
	    }
	}

	if ( (flags & CX_NSC_CONSUME) && (radarg || nodearg) )
	{
	    for ( arg = radarg + nodearg + argstokill; arg < *pargc; arg++ )
	    {
		argv[arg-argstokill] = argv[arg];
	    }
	    *pargc = *pargc - argstokill;
	    argv[*pargc] = NULL;
	}

    } while (0);	

    if ( OK == status )
    {
	lclbuf[CX_MAX_NODE_NAME_LEN] = '\0';
	if ( NULL == pni )
	{
	    (void)STlcopy(host, lclbuf, CX_MAX_NODE_NAME_LEN);
	}
	else
	{
	    (void)STlcopy(pni->cx_node_name, lclbuf, CX_MAX_NODE_NAME_LEN);
	}
	CVlower( lclbuf );
	if ( flags & CX_NSC_SET_CONTEXT )
	{
	    if ( !numa && 0 != target_rad )
	    {
		(void)CXnuma_bind_to_rad( target_rad );
	    }
	    (void)CXset_context(lclbuf, 0);
	}
    }

    if ( OK != status )
    {
	cx_fmt_msg( status, lclbuf, sizeof(lclbuf), erargc, erargs );
        if ( flags & CX_NSC_REPORT_ERRS )
	    (void)SIprintf( "\n%s\n", lclbuf );
    }

    if ( outbuf )
    {
	STlcopy( lclbuf, outbuf, outlen - 1 );
	*(outbuf + outlen - 1) = '\0';
    }
    return status;
} /*CXget_context*/
Example #20
0
/*
** Name: makeutable - make unicode collation element table
**
** Descrription:
**	Reads input collation element text file and compiles a table.
**	also reads the Unicode character database and adds attributes for 
**	each character found. Currently we only take note of canonical
**	decomposition for normalization.
**
** Inputs:
**	desfile	- collation element description file
**
** Outputs:
**	None
**
** Returns:
**	utbl - collation element table
**
** History:
**	14-mar-2001 (stephenb)
**	    Created
**	5-apr-2001 (stephenb)
**	    Add code to read unciode character database.
**	17-may-2001 (stephenb)
**	    Read in combining class from character database.
**	24-dec-2001 (somsa01)
**	    Modified such that the varsize which is placed in the Unicode
**	    table is now a SIZE_TYPE rather than an i4.
**	12-dec-2001 (devjo01)
**	    Make sure 1st overflow entry is properly aligned.
**	    Add messages to report if files cannot be opened.
**	17-jul-2001 (gupsh01)
**	    Modified the placing of the decomposition enty to 
**	    decomp structure in the file, to be the first entry. 
**      04-Mar-2005 (hanje04)
**          Add support for reverse hybrid builds, i.e. 64bit exe needs to
**          call 32bit version.
**	17-May-2007 (gupsh01)
**	    Added support for reverse sorting of the accented characters.
**	    This is done to support @backwards tag in custom collation file. 
**	08-Aug-2007 (kiria01) b118917
**	    Detect lines relating to conditional special caseing and ignore them.
**	08-Aug-2007 (gupsh01)
**	    Fixed the typo for CASE_IGNORABLE setting. Also fixed the 
**	    handling of Final_Sigma in the special_casing.txt.
**	08-Aug-2007 (gupsh01)
**	    Fixed the decomposition mapping which were not being set for 
**	    composite characters.
**	24-Nov-2008 (gupsh01)
**	    When alloating the memory for recombination table make sure
**	    we initialize the buffer. 
*/
static	ADUUCETAB *
makeutable(
	   char		*desfile)
{
    char     		buf[MAX_UCOL_REC];
    FILE      		*fp;
    FILE		*dfp;
    LOCATION   		loc;
    char		table_vers[MAX_UVERS] = "";
    i4			lno = 0;
    char		*recptr;
    char		*separator;
    ADUUCETAB		*tab = &w.utab;
    i4			num_rvals = 0;
    ADUUCETAB		*epointer = (ADUUCETAB *)w.buff; /* entries first */
    /* then instructions */    
    char		*ipointer; 
    SIZE_TYPE		*varsize;
    char		*tptr;
    ADU_UCEFILE		*rrec = NULL;
    ADU_UCEFILE		*cerec = NULL;
    char		csval[7];
    char		svalue[21];
    char		*ceptr;
    char		*comment;
    u_i4		cval;
    i4			numce;
    bool		combent;
    i4			i;
    /* Stuff to track the size of the recomb_tbl entries */
    u_i2        	**recomb_def2d;
    u_i2        	*recomb_def1d;
    char        	*recombtbl;
    char        	*tracker;
    SIZE_TYPE		*recomb_tbl_size;
    i4          	tr = 0;
    i4          	j = 0;
    STATUS		stat;
    i4			rcbufsz;
    char		*tempbuf;
    i4			current_bytes;
    char		*upperval;
    char		*lowerval;
    char		*titleval;
    char		*endval;
    i4 			bts = 0;
    i4 			lcnt = 0;
    i4 			tcnt = 0;
    i4 			ucnt = 0;
    i4 			row = 0;
    i4 			col = 0;
    bool		backward_set = FALSE;

    /* open file */
    STcopy(desfile, buf);
    LOfroms(FILENAME, buf, &loc);
    if (SIopen(&loc, "r", &fp) != OK)
    {
	SIprintf("aducompile: Unable to open input file \"%s\".\n",
		 loc.string );
        return NULL;    
    }

    varsize = (SIZE_TYPE *)(w.buff + ENTRY_SIZE);
    recomb_tbl_size = (SIZE_TYPE *)(varsize + 1);
    ipointer = (char*)(recomb_tbl_size + 1);
    ipointer = ME_ALIGN_MACRO(ipointer, sizeof(PTR));

    /* this is a sparse table, make sure we initialize it */
    MEfill(INSTRUCTION_SIZE + ENTRY_SIZE, 0, w.buff);
    *varsize = 0;

    /* read data */
    while (SIgetrec(buf, sizeof(buf), fp) != ENDFILE)
    {
	lno++;
	if (buf[0] == '#')
	    /* comment line */
	    continue;
	(VOID)STtrmwhite(buf);
	if (STcompare(buf, "") == 0)
	    /* blank line */
	    continue;
	/* should first find version */
	if (table_vers[0] == EOS)
	{
	    if (STbcompare(buf, 8, "@version", 8, TRUE) == 0)
	    {
		/* we don't parse the version string, maybe we should */
		STlcopy(buf+9, table_vers, MAX_UVERS);
		continue;
	    }
	    else
	    {
		SIprintf("Syntax error on line %d, version line must be first \
non-comment line in the file, ignored\n", lno);
		continue;
	    }
	}
	/* then alternate weights (optional), currently un-supported */
	if (STbcompare(buf, 10, "@alternate", 10, TRUE) == 0)
	{
	    SIprintf("Syntax error on line %d, alternate weights are not \
currently supported, ignored\n", lno);
	    continue;
	}

	/* now backwards lines (also not currently supported) */
	if (STbcompare(buf, 10, "@backwards", 10, TRUE) == 0)
	{ 
    	    backward_set = TRUE;
	    continue;
	}

	/* and rearrange lines */
	if (STbcompare(buf, 10, "@rearrange", 10, TRUE) == 0)
	{
	    bool	strend = FALSE;
	    u_i4	rval;

	    for (recptr = buf + 10;;)
	    {
		/* skip blanks */
		if ((recptr = STskipblank(recptr, STlength(recptr))) == NULL)
		{
		    /* blank string, ignore */
		    SIprintf("Syntax error on line %d, no characters in \
rearrange list, ignoring\n", lno);
		    strend = TRUE;
		    break;
		}
		/* find next comma separator */
		if ((separator = STindex(recptr, ",", 0)) == NULL)
		{
		    strend = TRUE;
		    separator = recptr + 4;
		}
		if (separator - recptr != 4)
		{
		    SIprintf("Syntax error on line %d, characters in a rearrange\
line must be a comma separated list of 4 digit hex values, ABORTING\n", lno);
		    tab = NULL;
		    break;
		}