Exemple #1
0
/**
 * \fn msiGetTaggedValueFromString (msParam_t *inTagParam, msParam_t *inStrParam, msParam_t *outValueParam, ruleExecInfo_t *rei)
 *
 * \brief   This microservice gets a tagged value from a string; given a tag-name gets the value from a file in tagged-format (pseudo-XML).
 *
 * \module core
 *
 * \since pre-2.1
 *
 * \author  Arcot Rajasekar
 * \date    2007-02-01
 *
 * \note This performs some regular expression matching. Given a regular expression as a tag-value 't', it identifies the
 * corresponding string in the match string with a string that matches a sub-string value: '<t>.*</t>'.
 * The service is used for processing a tagged structure.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] inTagParam - a msParam of type STR_MS_T
 * \param[in] inStrParam - a msParam of type STR_MS_T
 * \param[out] outValueParam - a msParam of type INT_MS_T
 * \param[in,out] rei - The RuleExecInfo structure that is automatically
 *    handled by the rule engine. The user does not include rei as a
 *    parameter in the rule invocation.
 *
 * \DolVarDependence none
 * \DolVarModified none
 * \iCatAttrDependence none
 * \iCatAttrModified none
 * \sideeffect none
 *
 * \return integer
 * \retval 0 on success
 * \pre none
 * \post none
 * \sa none
**/
int msiGetTaggedValueFromString( msParam_t *inTagParam, msParam_t *inStrParam,
                                 msParam_t *outValueParam, ruleExecInfo_t *rei ) {


    int j;
    regex_t preg[2];
    regmatch_t pm[2];
    char errbuff[100];
    char *pstr[2];
    char *t1, *t2, *t3;
    char c;

    t1 = ( char * ) inStrParam->inOutStruct;
    pstr[0] = ( char * ) malloc( strlen( ( char* )inTagParam->inOutStruct ) + 6 );
    pstr[1] = ( char * ) malloc( strlen( ( char* )inTagParam->inOutStruct ) + 6 );
    sprintf( pstr[0], "<%s>", ( char * ) inTagParam->inOutStruct );
    j = regcomp( &preg[0], pstr[0], REG_EXTENDED );
    if ( j != 0 ) {
        regerror( j, &preg[0], errbuff, sizeof( errbuff ) );
        rodsLog( LOG_NOTICE, "msiGetTaggedValueFromString: Error in regcomp: %s\n", errbuff );
        return( INVALID_REGEXP );
    }
    sprintf( pstr[1], "</%s>", ( char * ) inTagParam->inOutStruct );
    j = regcomp( &preg[1], pstr[1], REG_EXTENDED );
    if ( j != 0 ) {
        regerror( j, &preg[1], errbuff, sizeof( errbuff ) );
        rodsLog( LOG_NOTICE, "msiGetTaggedValueFromString: Error in regcomp: %s\n", errbuff );
        return( INVALID_REGEXP );
    }
    /*    rodsLog (LOG_NOTICE,"TTTTT:%s",t1);*/
    if ( regexec( &preg[0], t1, 1, &pm[0], 0 ) == 0 ) {
        t2 = t1 + pm[0].rm_eo ;                     /* t2 starts value */
        if ( regexec( &preg[1], t2, 1, &pm[1], 0 ) != 0 ) {
            fillMsParam( outValueParam, NULL, STR_MS_T, 0, NULL );
        }
        else {
            t3 = t2 + pm[1].rm_so;                      /* t3 ends value */
            c = *t3;
            *t3 = '\0';
            fillMsParam( outValueParam, NULL, STR_MS_T, t2, NULL );
            *t3 = c;
        }
    }
    else {
        fillMsParam( outValueParam, NULL, STR_MS_T, 0, NULL );
    }
    regfree( &preg[0] );
    regfree( &preg[1] );
    free( pstr[0] );
    free( pstr[1] );
    return( 0 );
}
Exemple #2
0
/**
 * \fn msiListEnabledMS(msParam_t *outKVPairs, ruleExecInfo_t *rei)
 *
 * \brief Returns the list of compiled microservices on the local iRODS server
 *
 * \module framework
 *
 * \since 2.1
 *
 *
 * \note This microservice looks at reAction.hpp and returns the list of compiled
 *  microservices on the local iRODS server.
 *      The results are written to a KeyValPair_MS_T. For each pair the keyword is the MS name
 *  while the value is the module where the microservice belongs.
 *  Standard non-module microservices are listed as "core".
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[out] outKVPairs - A KeyValPair_MS_T containing the results.
 * \param[in,out] rei - The RuleExecInfo structure that is automatically
 *    handled by the rule engine. The user does not include rei as a
 *    parameter in the rule invocation.
 *
 * \DolVarDependence none
 * \DolVarModified none
 * \iCatAttrDependence none
 * \iCatAttrModified none
 * \sideeffect none
 *
 * \return integer
 * \retval 0 on success
 * \pre none
 * \post none
 * \sa none
**/
int
msiListEnabledMS(
    msParam_t*      outKVPairs,
    ruleExecInfo_t* rei ) {

    extern irods::ms_table MicrosTable;
    keyValPair_t *results;		/* the output data structure */


    /* For testing mode when used with irule --test */
    RE_TEST_MACRO( "    Calling msiEnabledMS" )


    /* Sanity test */
    if ( rei == NULL || rei->rsComm == NULL ) {
        rodsLog( LOG_ERROR, "msiListEnabledMS: input rei or rsComm is NULL." );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }

    /* Allocate memory for our result struct */
    results = ( keyValPair_t* )malloc( sizeof( keyValPair_t ) );
    memset( results, 0, sizeof( keyValPair_t ) );

    // =-=-=-=-=-=-=-
    // scan table for msvc names and add to kvp struct
    irods::ms_table::iterator itr = MicrosTable.begin();
    for ( ; itr != MicrosTable.end(); ++itr ) {
        addKeyVal( results, itr->first.c_str(), "core" );

    } // for i

    // =-=-=-=-=-=-=-
    // scan plugin directory for additional plugins
    std::string plugin_home;
    irods::error ret = irods::resolve_plugin_path( irods::PLUGIN_TYPE_MICROSERVICE, plugin_home );
    if ( !ret.ok() ) {
        free( results );
        irods::log( PASS( ret ) );
        return ret.code();
    }

    irods::plugin_name_generator name_gen;
    irods::plugin_name_generator::plugin_list_t plugin_list;
    ret = name_gen.list_plugins( plugin_home, plugin_list );
    if ( ret.ok() ) {
        irods::plugin_name_generator::plugin_list_t::iterator it = plugin_list.begin();
        for ( ; it != plugin_list.end(); ++it ) {
            addKeyVal( results, it->c_str(), "plugin" );
        }
    }

    /* Send results out to outKVPairs */
    fillMsParam( outKVPairs, NULL, KeyValPair_MS_T, results, NULL );

    return 0;
}
/**
 * \fn msiPropertiesNew( msParam_t *listParam, ruleExecInfo_t *rei )
 *
 * \brief Create a new empty property list
 *
 * \module properties
 *
 * \since pre-2.1
 *
 * \author  David R. Nadeau / University of California, San Diego
 * \date    2007
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[out] listParam - a KeyValPair_MS_T, the newly created property list
 * \param[in,out] rei - The RuleExecInfo structure that is automatically
 *    handled by the rule engine. The user does not include rei as a
 *    parameter in the rule invocation.
 *
 * \DolVarDependence none
 * \DolVarModified none
 * \iCatAttrDependence none
 * \iCatAttrModified none
 * \sideeffect none
 *
 * \return integer
 * \retval 0 on success
 * \pre none
 * \post none
 * \sa none
**/
int
msiPropertiesNew( msParam_t *listParam, ruleExecInfo_t *rei )
{
	RE_TEST_MACRO( "    Calling msiPropertiesNew" );

	/* Create empty list */
	fillMsParam( listParam, NULL,
		KeyValPair_MS_T, mallocAndZero( sizeof(keyValPair_t) ), NULL );
	return 0;
}
/**
 * \fn msiPropertiesClone( msParam_t *listParam, msParam_t *cloneParam, ruleExecInfo_t *rei )
 *
 * \brief Clone a property list, returning a new property list
 *
 * \module properties
 *
 * \since pre-2.1
 *
 * \author  David R. Nadeau / University of California, San Diego
 * \date    2007
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] listParam - a KeyValPair_MS_T, the property list to clone
 * \param[out] cloneParam - a KeyValPair_MS_T, the returned clone (new property list)
 * \param[in,out] rei - The RuleExecInfo structure that is automatically
 *    handled by the rule engine. The user does not include rei as a
 *    parameter in the rule invocation.
 *
 * \DolVarDependence none
 * \DolVarModified none
 * \iCatAttrDependence none
 * \iCatAttrModified none
 * \sideeffect a new peoperty list is created
 *
 * \return integer
 * \retval 0 on success
 * \pre none
 * \post none
 * \sa none
**/
int
msiPropertiesClone( msParam_t *listParam, msParam_t *cloneParam, ruleExecInfo_t *rei )
{
	RE_TEST_MACRO( "    Calling msiPropertiesClone" );

	/* Check parameters */
	if ( strcmp( listParam->type, KeyValPair_MS_T ) != 0 )
		return USER_PARAM_TYPE_ERR;

	fillMsParam( cloneParam, NULL,
		KeyValPair_MS_T, mallocAndZero( sizeof(keyValPair_t) ), NULL );
	replKeyVal( (keyValPair_t*)listParam->inOutStruct, (keyValPair_t*)cloneParam->inOutStruct );
	return 0;
}
/**
 * \fn msiPropertiesFromString( msParam_t *stringParam, msParam_t* listParam, ruleExecInfo_t *rei )
 *
 * \brief Parse a string into a new property list.  The existing property list, if any, is deleted.
 *
 * \module properties
 *
 * \since pre-2.1
 *
 * \author  David R. Nadeau / University of California, San Diego
 * \date     2007
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] stringParam - a STR_MS_T, a string buffer
 * \param[out] listParam - a KeyValPair_MS_T, the property list with the strings added
 * \param[in,out] rei - The RuleExecInfo structure that is automatically
 *    handled by the rule engine. The user does not include rei as a
 *    parameter in the rule invocation.
 *
 * \DolVarDependence none
 * \DolVarModified none
 * \iCatAttrDependence none
 * \iCatAttrModified none
 * \sideeffect none
 *
 * \return integer
 * \retval 0 on success
 * \pre none
 * \post none
 * \sa  none
**/
int
msiPropertiesFromString( msParam_t *stringParam, msParam_t* listParam, ruleExecInfo_t *rei )
{
	keyValPair_t* list = NULL;

	RE_TEST_MACRO( "    Calling msiPropertiesToString" );

	/* Check parameters */
	if ( strcmp( stringParam->type, STR_MS_T ) != 0 )
		return USER_PARAM_TYPE_ERR;

	/* Parse string and return list */
	if ( keyValFromString( (char*)stringParam->inOutStruct, &list ) == 0 )
		fillMsParam( listParam, NULL, KeyValPair_MS_T, list, NULL );
	return 0;
}
/**
 * \fn msiPropertiesGet( msParam_t *listParam, msParam_t* keywordParam, msParam_t* valueParam, ruleExecInfo_t *rei )
 *
 * \brief Get the value of a property in a property list.
 *
 * \module properties
 *
 * \since pre-2.1
 *
 * \author  David R. Nadeau / University of California, San Diego
 * \date    2007
 *
 * \note The property list is left unmodified.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in,out] listParam - a KeyValPair_MS_T, the property list to be queried
 * \param[in] keywordParam - a STR_MS_T, a keyword to get
 * \param[out] valueParam - a STR_MS_T, the returned value
 * \param[in,out] rei - The RuleExecInfo structure that is automatically
 *    handled by the rule engine. The user does not include rei as a
 *    parameter in the rule invocation.
 *
 * \DolVarDependence none
 * \DolVarModified none
 * \iCatAttrDependence none
 * \iCatAttrModified none
 * \sideeffect none
 *
 * \return integer
 * \retval 0 on success
 * \pre  none
 * \post none
 * \sa none
**/
int
msiPropertiesGet( msParam_t *listParam, msParam_t* keywordParam, msParam_t* valueParam, ruleExecInfo_t *rei )
{
	char* value = NULL;

	RE_TEST_MACRO( "    Calling msiPropertiesGet" );

	/* Check parameters */
	if ( strcmp( listParam->type, KeyValPair_MS_T ) != 0 )
		return USER_PARAM_TYPE_ERR;
	if ( strcmp( keywordParam->type, STR_MS_T ) != 0 )
		return USER_PARAM_TYPE_ERR;

	/* Get value and return it */
	value = getValByKey( (keyValPair_t*)listParam->inOutStruct,
		(char*)keywordParam->inOutStruct );
	fillMsParam( valueParam, NULL, STR_MS_T, value, NULL );
	return 0;
}
Exemple #7
0
/**
 * \fn msiListEnabledMS(msParam_t *outKVPairs, ruleExecInfo_t *rei)
 *
 * \brief Returns the list of compiled microservices on the local iRODS server
 *
 * \module framework
 *
 * \since 2.1
 *
 * \author  Antoine de Torcy
 * \date    2009-02-12
 *
 * \note This microservice looks at reAction.hpp and returns the list of compiled
 *  microservices on the local iRODS server.
 *      The results are written to a KeyValPair_MS_T. For each pair the keyword is the MS name
 *  while the value is the module where the microservice belongs.
 *  Standard non-module microservices are listed as "core".
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[out] outKVPairs - A KeyValPair_MS_T containing the results.
 * \param[in,out] rei - The RuleExecInfo structure that is automatically
 *    handled by the rule engine. The user does not include rei as a
 *    parameter in the rule invocation.
 *
 * \DolVarDependence none
 * \DolVarModified none
 * \iCatAttrDependence none
 * \iCatAttrModified none
 * \sideeffect none
 *
 * \return integer
 * \retval 0 on success
 * \pre none
 * \post none
 * \sa none
**/
int
msiListEnabledMS( msParam_t *outKVPairs, ruleExecInfo_t *rei ) {
    FILE *radhpp = 0;			/* reAction(dot)hpp */

    keyValPair_t *results;		/* the output data structure */

    char lineStr[LONG_NAME_LEN];	/* for line and string parsing */
    char modName[NAME_LEN];
    char *begPtr, *endPtr;


    /* For testing mode when used with irule --test */
    RE_TEST_MACRO( "    Calling msiEnabledMS" )


    /* Sanity test */
    if ( rei == NULL || rei->rsComm == NULL ) {
        rodsLog( LOG_ERROR, "msiListEnabledMS: input rei or rsComm is NULL." );
        return ( SYS_INTERNAL_NULL_INPUT_ERR );
    }


    /* Open reAction.hpp for reading */
    radhpp = fopen( "../re/include/reAction.hpp", "r" );
    if ( !radhpp ) {
        rodsLog( LOG_ERROR, "msiListEnabledMS: unable to open reAction.hpp for reading." );
        return ( UNIX_FILE_READ_ERR );
    }


    /* Skip the first part of the file */
    while ( fgets( lineStr, LONG_NAME_LEN, radhpp ) != NULL ) {
        if ( strstr( lineStr, "microsdef_t MicrosTable[]" ) == lineStr ) {
            break;
        }
    }


    /* Default microservices come first, will be listed are "core" */
    strncpy( modName, "core", NAME_LEN ); /* Pad with null chars in the process */


    /* Allocate memory for our result struct */
    results = ( keyValPair_t* )malloc( sizeof( keyValPair_t ) );
    memset( results, 0, sizeof( keyValPair_t ) );


    /* Scan microservice table one line at a time*/
    while ( fgets( lineStr, LONG_NAME_LEN, radhpp ) != NULL ) {
        /* End of the table? */
        if ( strstr( lineStr, "};" ) == lineStr ) {
            break;
        }

        /* Get microservice name */
        if ( ( begPtr = strchr( lineStr, '\"' ) ) && ( endPtr = strrchr( lineStr, '\"' ) ) ) {
            endPtr[0] = '\0';
            addKeyVal( results, &begPtr[1], modName );
        }
        else {
            /* New Module? */
            if ( strstr( lineStr, "module microservices" ) ) {
                /* Get name of module (between the first two spaces) */
                begPtr = strchr( lineStr, ' ' );
                endPtr = strchr( ++begPtr, ' ' );
                endPtr[0] = '\0';

                strncpy( modName, begPtr, NAME_LEN - 1 );
            }
        }
    }


    /* Done */
    fclose( radhpp );


    /* Send results out to outKVPairs */
    fillMsParam( outKVPairs, NULL, KeyValPair_MS_T, results, NULL );


    return 0;
}
/**
 * \fn msiVerifyFileSizeRange (msParam_t* collinp, msParam_t* minsizeinp, msParam_t* maxsizeinp, 
 *  msParam_t* bufout, msParam_t* statout, ruleExecInfo_t *rei)
 *
 * \brief This microservice checks to see if file sizes are NOT within a certain range.
 *
 * \deprecated Since 3.0, the integrityChecks module microservices have been reproduced
 *    using rules.  These microservices only handled 256 files per collection.
 *    The example rules handle an arbitrary number of files.
 *
 * \module integrityChecks
 *
 * \since pre-2.1
 *
 * \author  Susan Lindsey
 * \date    August 2008
 *
 * \usage See clients/icommands/test/rules3.0/ 
 *
 * \param[in] collinp - a STR_MS_T containing the collection's name
 * \param[in] minsizeinp - a STR_MS_T containing the lower limit on filesize
 * \param[in] maxsizeinp - a STR_MS_T containing the upper limit on filesize
 * \param[out] bufout - a STR_MS_T containing the output string
 * \param[out] statout - the returned status
 * \param[in,out] rei - The RuleExecInfo structure that is automatically
 *    handled by the rule engine. The user does not include rei as a
 *    parameter in the rule invocation.
 *
 * \DolVarDependence none
 * \DolVarModified none
 * \iCatAttrDependence none
 * \iCatAttrModified none
 * \sideeffect none
 *
 * \return integer
 * \retval rei->status
 * \pre none
 * \post none
 * \sa none
**/
int
msiVerifyFileSizeRange (msParam_t* collinp, msParam_t* minsizeinp, msParam_t* maxsizeinp, 
  msParam_t* bufout, msParam_t* statout, ruleExecInfo_t *rei)
{

	genQueryInp_t genQueryInp;
	genQueryOut_t *genQueryOut = NULL;
	char condStr[MAX_NAME_LEN];
	rsComm_t *rsComm;
	char collname[MAX_NAME_LEN];
	char maxfilesize[MAX_NAME_LEN]; 
	char minfilesize[MAX_NAME_LEN];
	int i,j;
	sqlResult_t *dataName;
	sqlResult_t *dataSize;
	keyValPair_t	*results;	
	char* key;
	char* value;
	
	RE_TEST_MACRO ("    Calling msiVerifyFileSizeRange")

	/* Sanity check */
	if (rei == NULL || rei->rsComm == NULL) {
		rodsLog (LOG_ERROR, "msiVerifyFileSizeRange: input rei or rsComm is NULL");
		return (SYS_INTERNAL_NULL_INPUT_ERR);
	}

	rsComm = rei->rsComm;

	/* construct an SQL query from the input parameter list */
	strcpy (collname,  (char*) collinp->inOutStruct);
	strcpy (minfilesize, (char*) minsizeinp->inOutStruct);
	strcpy (maxfilesize, (char*) maxsizeinp->inOutStruct);

	/* But first, make sure our size range is valid */
	if (atoi(minfilesize) >= atoi(maxfilesize)) {
		return (USER_PARAM_TYPE_ERR);
	}

	// initialize results to 0; AddKeyVal does all our malloc-ing
	results = (keyValPair_t*) malloc (sizeof(keyValPair_t));
	memset (results, 0, sizeof(keyValPair_t));

	memset (&genQueryInp, 0, sizeof(genQueryInp_t));
	genQueryInp.maxRows = MAX_SQL_ROWS;

	/* this is the info we want returned from the query */
	addInxIval (&genQueryInp.selectInp, COL_DATA_NAME, 1);
	addInxIval (&genQueryInp.selectInp, COL_DATA_SIZE, 1);
	addInxIval (&genQueryInp.selectInp, COL_COLL_NAME, 1);

	/* build the condition:
		collection name AND (filesize < minfilesize or filesize > maxfilesize) */

	snprintf (condStr, MAX_NAME_LEN, " < '%s' || > '%s'", minfilesize, maxfilesize);
	addInxVal (&genQueryInp.sqlCondInp, COL_DATA_SIZE, condStr); 
	snprintf (condStr, MAX_NAME_LEN, " = '%s'", collname);
	addInxVal (&genQueryInp.sqlCondInp, COL_COLL_NAME, condStr); 

	j = rsGenQuery (rsComm, &genQueryInp, &genQueryOut);

	if (j != CAT_NO_ROWS_FOUND) {

		/* we got results - do something cool */
		dataName = getSqlResultByInx (genQueryOut, COL_DATA_NAME);
		dataSize = getSqlResultByInx (genQueryOut, COL_DATA_SIZE);
		for (i=0; i<genQueryOut->rowCnt; i++) {
			// fprintf (stderr, "dataName[%d]:%s\n",i,&dataName->value[dataName->len * i]);
			key = strdup (&dataName->value[dataName->len *i]);
			// fprintf (stderr, "dataSize[%d]:%s\n",i,&dataSize->value[dataSize->len * i]);
			value = strdup (&dataSize->value[dataSize->len * i]);
			addKeyVal (results, key, value);
		}

	} else {
		fillIntInMsParam (statout, rei->status);
		return (rei->status);  
	}

	//printGenQueryOut(stderr, NULL, NULL, genQueryOut);

	fillMsParam (bufout, NULL, KeyValPair_MS_T, results, NULL);
	fillIntInMsParam (statout, rei->status);
  
	return(rei->status);

}
/**
 * \fn msiVerifyDataType (msParam_t* collinp, msParam_t* datatypeinp, msParam_t* bufout, msParam_t* statout, ruleExecInfo_t* rei)
 *
 * \brief This microservice checks if files in a given collection are of a given data type(s).
 *
 * \deprecated Since 3.0, the integrityChecks module microservices have been reproduced
 *    using rules.  These microservices only handled 256 files per collection.
 *    The example rules handle an arbitrary number of files.
 *
 * \module integrityChecks
 *
 * \since pre-2.1
 *
 * \author  Susan Lindsey
 * \date    August 2008
 *
 * \usage See clients/icommands/test/rules3.0/ 
 *
 * \param[in] collinp - a STR_MS_T containing the collection's name
 * \param[in] datatypeinp - a STR_MS_T containing the comma delimited datatype list
 * \param[out] bufout - a STR_MS_T containing the output string
 * \param[out] statout - the returned status
 * \param[in,out] rei - The RuleExecInfo structure that is automatically
 *    handled by the rule engine. The user does not include rei as a
 *    parameter in the rule invocation.
 *
 * \DolVarDependence none
 * \DolVarModified none
 * \iCatAttrDependence none
 * \iCatAttrModified none
 * \sideeffect none
 *
 * \return integer
 * \retval rei->status
 * \pre none
 * \post none
 * \sa none
**/
int
msiVerifyDataType (msParam_t* collinp, msParam_t* datatypeinp, msParam_t* bufout, msParam_t* statout, ruleExecInfo_t* rei)
{

	genQueryInp_t genQueryInp;
	genQueryOut_t *genQueryOut = NULL;
	char condStr[MAX_NAME_LEN];
	rsComm_t *rsComm;
	char collname[MAX_NAME_LEN];
	char datatypeparam[MAX_NAME_LEN];
	int i,j;
	sqlResult_t *dataName;
	sqlResult_t *dataType;
	char delims[]=",";
	char* word;
	keyValPair_t	*results;	
	char* key;
	char* value;
	
	RE_TEST_MACRO ("    Calling msiVerifyDataType")

	/* Sanity check */
	if (rei == NULL || rei->rsComm == NULL) {
		rodsLog (LOG_ERROR, "msiVerifyDataType: input rei or rsComm is NULL");
		return (SYS_INTERNAL_NULL_INPUT_ERR);
	}

	rsComm = rei->rsComm;

	/* construct an SQL query from the parameter list */
	strcpy (collname,  (char*) collinp->inOutStruct);
	strcpy (datatypeparam, (char*) datatypeinp->inOutStruct);

	fprintf (stderr, "datatypeparam: %s\n", datatypeparam);

	// initialize results to 0; AddKeyVal does all our malloc-ing
	results = (keyValPair_t*) malloc (sizeof(keyValPair_t));
	memset (results, 0, sizeof(keyValPair_t));

	/* Parse the comma-delimited datatype list & make a separate query for each datatype*/
	for (word=strtok(datatypeparam, delims); word; word=strtok(NULL, delims)) {

		fprintf (stderr, "word: %s\n", word);

		memset (&genQueryInp, 0, sizeof(genQueryInp_t));
		genQueryInp.maxRows = MAX_SQL_ROWS;

		/* this is the info we want returned from the query */
		addInxIval (&genQueryInp.selectInp, COL_DATA_NAME, 1);
		addInxIval (&genQueryInp.selectInp, COL_DATA_TYPE_NAME, 1);
		snprintf (condStr, MAX_NAME_LEN, " = '%s'", word);
		addInxVal (&genQueryInp.sqlCondInp, COL_DATA_TYPE_NAME, condStr); 
	

		j = rsGenQuery (rsComm, &genQueryInp, &genQueryOut);

		if (j != CAT_NO_ROWS_FOUND) {

			fprintf (stderr, "word: %s\trows:%d\n", word, genQueryOut->rowCnt);

			/* we got results - do something cool */
			dataName = getSqlResultByInx (genQueryOut, COL_DATA_NAME);
			dataType = getSqlResultByInx (genQueryOut, COL_DATA_TYPE_NAME);

			for (i=0; i<genQueryOut->rowCnt; i++) {
				key = strdup (&dataName->value[dataName->len *i]);
				value = strdup (&dataType->value[dataType->len * i]);
				addKeyVal (results, key, value);
			}	

			printGenQueryOut(stderr, NULL, NULL, genQueryOut);

		} else continue; 

	}

	fillMsParam (bufout, NULL, KeyValPair_MS_T, results, NULL);
	fillIntInMsParam (statout, rei->status);
  
	return(rei->status);

}
    /**
    * \fn msiH5Dataset_read (msParam_t *inpH5DatasetParam, msParam_t *outH5DatasetParam,
    * ruleExecInfo_t *rei)
    *
    * \brief This microservice is for reading a dataset from an opened HDF5 file.
    *
    * \module hdf5
    *
    * \since pre-2.1
    *
    * \author uiuc.edu Mike Wan
    * \date  2008
    *
    * \usage See clients/icommands/test/rules3.0/
    *
    * \param[in] inpH5DatasetParam - The input H5Dataset. Must be h5Dataset_MS_T.
    * \param[out] outH5DatasetParam - The output H5Dataset - Must be h5Dataset_MS_T.
    * \param[in,out] rei - The RuleExecInfo structure that is automatically
    *    handled by the rule engine. The user does not include rei as a
    *    parameter in the rule invocation.
    *
    * \DolVarDependence none
    * \DolVarModified none
    * \iCatAttrDependence none
    * \iCatAttrModified none
    * \sideeffect none
    *
    * \return integer
    * \retval 0 upon success
    * \pre none
    * \post none
    * \sa none
    **/
    int
    msiH5Dataset_read (msParam_t *inpH5DatasetParam, msParam_t *outH5DatasetParam,
    ruleExecInfo_t *rei)
    {
        rsComm_t *rsComm;
        H5Dataset *ind;
        H5Dataset *outd;
        int l1descInx;
        dataObjInfo_t *dataObjInfo;
        int remoteFlag;
        rodsServerHost_t *rodsServerHost;

        RE_TEST_MACRO ( ( char * )"    Calling msiH5Dataset_read")

        if (rei == NULL || rei->rsComm == NULL) {
            rodsLog (LOG_ERROR,
              "msiH5Dataset_read: input rei or rsComm is NULL");
            return (SYS_INTERNAL_NULL_INPUT_ERR);
        }

        rsComm = rei->rsComm;

        if (inpH5DatasetParam == NULL || outH5DatasetParam == NULL) {
            rei->status = SYS_INTERNAL_NULL_INPUT_ERR;
            rodsLogAndErrorMsg (LOG_ERROR, &rsComm->rError, rei->status,
              ( char * )"msiH5Dataset_read: NULL input/output Param");
            return (rei->status);
        }

        if (strcmp (inpH5DatasetParam->type, h5Dataset_MS_T) == 0) {
            ind = (H5Dataset*)inpH5DatasetParam->inOutStruct;
        } else {
            rei->status = USER_PARAM_TYPE_ERR;
            rodsLogAndErrorMsg (LOG_ERROR, &rsComm->rError, rei->status,
              ( char * )"msiH5Dataset_read: wrong inpH5DatasetParam type %s",
              inpH5DatasetParam->type);
            return (rei->status);
        }

        l1descInx = getL1descInxByFid (ind->fid);
        if (l1descInx < 0) {
            rei->status = SYS_BAD_FILE_DESCRIPTOR;
            rodsLogAndErrorMsg (LOG_ERROR, &rsComm->rError, rei->status,
              ( char * )"msiH5Dataset_read: bad fid %d", ind->fid);
            return (rei->status);
        }

        dataObjInfo = L1desc[l1descInx].dataObjInfo;

        remoteFlag = resolveHostByDataObjInfo (dataObjInfo,
          &rodsServerHost);

        if (remoteFlag == LOCAL_HOST) {
            outd = (H5Dataset*)malloc (sizeof (H5Dataset));
            rei->status = H5Dataset_read (ind, outd);
        } else {
            /* do the remote close */
            outd = NULL;
            if ((rei->status = svrToSvrConnect (rsComm, rodsServerHost)) >= 0) {
                rei->status = _clH5Dataset_read (rodsServerHost->conn, ind, &outd);
            }
        }

        /* prepare the output */

        fillMsParam (outH5DatasetParam, NULL, ( char * )h5Dataset_MS_T, outd, NULL);

        if (ind) H5Dataset_dtor(ind);

        return rei->status;

    }