示例#1
0
    /**
    * \fn msiNcGetArrayLen (msParam_t *inpParam, msParam_t *outParam, ruleExecInfo_t *rei)
    * \brief Get the array length of a NcInqWithIdOut_MS_T (output of msiNcInqWithId) or NcGetVarOut_MS_T (output of msiNcGetVarsByType).
    * \module core
    *
    * \since 3.2
    *
    * \author  Mike Wan
    * \date    2012
    *
    * \usage See clients/icommands/test/rules3.0/netcdfTest1.r, netcdfTest2.r and netcdfTest3.r.
    * \param[in] inpParam - A NcInqWithIdOut_MS_T or NcGetVarOut_MS_T which are outputs of the msiNcInqWithId and msiNcGetVarsByType msi, respectively.
    * \param[out] outParam - An INT_MS_T containing the array length.
    *
    * \DolVarDependence none
    * \DolVarModified none
    * \iCatAttrDependence none
    * \iCatAttrModified none
    * \sideeffect none
    *
    * \return integer
    * \retval 0 upon success
    * \pre N/A
    * \post N/A
    * \sa N/A
    *
    **/
    int
    msiNcGetArrayLen (msParam_t *inpParam, msParam_t *outParam,
    ruleExecInfo_t *rei)
    {
        // should use rodsLong_t, but some problem with rule engine */
        // rodsLong_t arrayLen;
        int arrayLen;

        RE_TEST_MACRO ("    Calling msiNcGetArrayLen")

        if (inpParam == NULL || outParam == NULL) return USER__NULL_INPUT_ERR;

        if (strcmp (inpParam->type, NcInqWithIdOut_MS_T) == 0) {
            ncInqWithIdOut_t *ncInqWithIdOut;
            ncInqWithIdOut = (ncInqWithIdOut_t *) inpParam->inOutStruct;
            arrayLen = ncInqWithIdOut->mylong;
        } else if (strcmp (inpParam->type, NcGetVarOut_MS_T) == 0) {
            ncGetVarOut_t *ncGetVarOut;
            ncGetVarOut = (ncGetVarOut_t *) inpParam->inOutStruct;
            if (ncGetVarOut == NULL || ncGetVarOut->dataArray == NULL)
                return USER__NULL_INPUT_ERR;
            arrayLen = ncGetVarOut->dataArray->len;
        } else {
            rodsLog (LOG_ERROR,
              "msiNcGetArrayLen: Unsupported input Param type %s",
              inpParam->type);
            return (USER_PARAM_TYPE_ERR);
        }
        fillIntInMsParam (outParam, arrayLen);
        return 0;
    }
示例#2
0
int
readXMsg( msParam_t* inStreamId, msParam_t *inCondRead,
          msParam_t *outMsgNum, msParam_t *outSeqNum,
          msParam_t *outHdr, msParam_t *outMsg,
          msParam_t *outUser, msParam_t *outAddr, ruleExecInfo_t *rei ) {
    int i;
    int sNum = 0;
    int mNum = 0;
    char *hdr = NULL;
    char *msg = NULL;
    char *user = NULL;
    char *addr = NULL;
    int streamId;
    xmsgTicketInfo_t *xmsgTicketInfo;
    char *condRead = NULL;
    RE_TEST_MACRO( "    Calling readXMsg" );

    if ( !strcmp( inStreamId->type, XmsgTicketInfo_MS_T ) ) {
        xmsgTicketInfo = ( xmsgTicketInfo_t * ) inStreamId->inOutStruct;
        streamId = xmsgTicketInfo->rcvTicket;
    }
    else if ( !strcmp( inStreamId->type, STR_MS_T ) ) {
        streamId = ( int ) atoi( ( char* )inStreamId->inOutStruct );
    }
    else {
        streamId = CAST_PTR_INT  inStreamId->inOutStruct;
    }
    condRead = ( char * ) inCondRead->inOutStruct;
    i = _readXMsg( streamId, condRead, &mNum, &sNum, &hdr, &msg, &user, &addr );
    if ( i >= 0 ) {
        outHdr->inOutStruct = ( void * ) hdr;
        outHdr->type = strdup( STR_MS_T );
        outMsg->inOutStruct = ( void * ) msg;
        outMsg->type = strdup( STR_MS_T );
        fillIntInMsParam( outMsgNum, mNum );
        fillIntInMsParam( outSeqNum, sNum );
        outUser->inOutStruct = ( void * ) user;
        outUser->type = strdup( STR_MS_T );
        outAddr->inOutStruct = ( void * ) addr;
        outAddr->type = strdup( STR_MS_T );

    }
    return i;
}
示例#3
0
/**
 * \fn msiApplyDCMetadataTemplate(msParam_t* inpParam, msParam_t* outParam, ruleExecInfo_t *rei)
 *
 * \brief This microservice adds 15 empty Dublin Core Metadata fields to an object or collection.
 *
 * \module framework
 *
 * \since pre-2.1
 *
 * \author  Antoine de Torcy
 * \date    2008-04-04
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] inpParam - a STR_MS_T containing the target object's path
 * \param[out] outParam - an INT_MS_T containing the 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 0 on success
 * \pre none
 * \post none
 * \sa none
**/
int
msiApplyDCMetadataTemplate(msParam_t* inpParam, msParam_t* outParam, ruleExecInfo_t *rei)
{
	char *objPath;
	char objType[NAME_LEN];
	modAVUMetadataInp_t modAVUMetadataInp;
	int i, status;

	/* Dublin Core metadata elements */
	char *elements[]={"DC.Title", "DC.Creator", "DC.Subject", "DC.Description", "DC.Publisher", "DC.Contributor", "DC.Date", "DC.Type", "DC.Format", "DC.Identifier", "DC.Source", "DC.Language", "DC.Relation", "DC.Coverage", "DC.Rights" };
	

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


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


	/* Check for proper input */
	if ((objPath = parseMspForStr(inpParam)) == NULL) {
		rodsLog (LOG_ERROR, "msiApplyDCMetadataTemplate: input parameter is NULL");
		return (USER__NULL_INPUT_ERR);
	}


	/* Get type of target object */
	status = getObjType(rei->rsComm, objPath, objType);


	/* Add each DC element */
	for (i=0; i<15; i++) {
		/* set up our modAVU input */
		memset (&modAVUMetadataInp, 0, sizeof(modAVUMetadataInp_t));
		modAVUMetadataInp.arg0 = "add";
		modAVUMetadataInp.arg1 = objType;
		modAVUMetadataInp.arg2 = objPath;
		modAVUMetadataInp.arg3 = elements[i];	/* attribute */
		modAVUMetadataInp.arg4 = " ";		/* value, cannot be empty */
		modAVUMetadataInp.arg5 = "";		/* units, can be empty */

		/* add metadata AVU triplet */
		status = rsModAVUMetadata (rei->rsComm, &modAVUMetadataInp);
	}


	/* return operation status through outParam */
	fillIntInMsParam (outParam, status);


	return(status);
}
示例#4
0
/**
 * \fn msiCheckAccess(msParam_t *inObjName, msParam_t * inOperation, msParam_t * outResult, ruleExecInfo_t *rei)
 *
 * \brief   This microservice checks the access permission to perform a given operation
 *
 * \module core
 *
 * \since 3.0
 *
 *
 * \usage See clients/icommands/test/rules/
 *
 * \param[in] inObjName - name of Object. A param of type STR_MS_T
 * \param[in] inOperation - type of Operation that will be performed. A param of type STR_MS_T.
 * \param[out] outResult - result of the operation. 0 for failure and 1 for success. a param 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 msiCheckAccess( msParam_t *inObjName, msParam_t * inOperation,
                    msParam_t * outResult, ruleExecInfo_t *rei ) {
    char *objName, *oper;
    char objType[MAX_NAME_LEN];
    int i = 0;
    char *user;
    char *zone;

    RE_TEST_MACRO( "  Calling msiCheckAccess" );

    if ( inObjName == NULL || inObjName->inOutStruct == NULL ||
            inObjName->type == NULL || strcmp( inObjName->type, STR_MS_T ) != 0 ) {
        return USER_PARAM_TYPE_ERR;
    }

    if ( inOperation == NULL || inOperation->inOutStruct == NULL ||
            inOperation->type == NULL || strcmp( inOperation->type, STR_MS_T ) != 0 ) {
        return USER_PARAM_TYPE_ERR;
    }

    if ( rei == NULL || rei->rsComm == NULL ) {
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }

    if ( strlen( rei->rsComm->clientUser.userName ) == 0 ||
            strlen( rei->rsComm->clientUser.rodsZone ) == 0 ) {
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }

    oper = ( char * ) inOperation->inOutStruct;
    objName = ( char * ) inObjName->inOutStruct;
    user = rei->rsComm->clientUser.userName;
    zone = rei->rsComm->clientUser.rodsZone;

    i = getObjType( rei->rsComm, objName, objType );
    if ( i < 0 ) {
        return i;
    }

    i = checkPermissionByObjType( rei->rsComm, objName, objType, user, zone, oper );

    if ( i == 0 ) {	// hack
        i = checkPermissionByObjType( rei->rsComm, objName, objType, "public", zone, oper );
    }

    if ( i < 0 ) {
        return i;
    }
    fillIntInMsParam( outResult, i );

    return 0;

}
示例#5
0
    /**
    * \fn msiNcOpenGroup (msParam_t *rootNcidParam, msParam_t *fullGrpNameParam,
    msParam_t *outParam, ruleExecInfo_t *rei)
    * \brief Open a fully qualified group name and get the group id.  nc_inq_grp_full_ncid is called to get the grpncid
    * \module core
    *
    * \since 3.2
    *
    * \author  Mike Wan
    * \date    2012
    *
    * \usage See clients/icommands/test/rules3.0/netcdfTest1.r, netcdfTest2.r and netcdfTest3.r.
    * \param[in] rootNcidParam - An INT_MS_T containing the rootNcid.
    * \param[in] fullGrpNameParam - A STR_MS_T containing the full group name
    * \param[out] outParam - An INT_MS_T containing the group ncid
    *
    **/
    int
    msiNcOpenGroup (msParam_t *rootNcidParam, msParam_t *fullGrpNameParam,
    msParam_t *outParam, ruleExecInfo_t *rei)
    {
        rsComm_t *rsComm;
        ncOpenInp_t ncOpenInp;
        int *grpNcid = NULL;

        RE_TEST_MACRO ("    Calling msiNcOpenGroup")

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

        bzero (&ncOpenInp, sizeof (ncOpenInp));
        if (rootNcidParam == NULL) {
            rodsLog (LOG_ERROR,
              "msiNcOpenGroup: input rootNcidParam is NULL");
            return (SYS_INTERNAL_NULL_INPUT_ERR);
        }
        ncOpenInp.rootNcid = parseMspForPosInt (rootNcidParam);
        if (strcmp (fullGrpNameParam->type, STR_MS_T) == 0) {
            rstrcpy (ncOpenInp.objPath, (char*)fullGrpNameParam->inOutStruct,
              MAX_NAME_LEN);
        } else {
            rodsLog (LOG_ERROR,
              "msiNcOpenGroup: Unsupported input fullGrpNameParam type %s",
              fullGrpNameParam->type);
            return (USER_PARAM_TYPE_ERR);
        }
        rei->status = irods::server_api_call ( NC_OPEN_GROUP_AN, rsComm, &ncOpenInp, &grpNcid);

        clearKeyVal (&ncOpenInp.condInput);
        if (rei->status >= 0) {
            fillIntInMsParam (outParam, *grpNcid);
            free (grpNcid);
        } else {
          rodsLogAndErrorMsg (LOG_ERROR, &rsComm->rError, rei->status,
            "msiNcOpenGroup: api call to ncOpenGroup failed for rootNcid %d, status = %d",
            ncOpenInp.rootNcid, rei->status);
        }
        return (rei->status);
    }
示例#6
0
/**
 * \fn msiPropertiesExists( msParam_t *listParam, msParam_t* keywordParam, msParam_t* trueFalseParam, ruleExecInfo_t *rei )
 *
 * \brief check for a property in a list
 *
 * \module properties
 *
 * \since pre-2.1
 *
 * \author  David R. Nadeau / University of California, San Diego
 * \date    2007
 *
 * \remark Terrell Russell - msi documentation, 2009-06-22
 *
 * \note Return true (integer 1) if the keyword has a property value in the property list,
 * and false (integer 0) otherwise.  The property list is unmodified.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in,out] listParam - a KeyValPair_MS_T, the property list to look in
 * \param[in] keywordParam - a STR_MS_T, a keyword to set
 * \param[out] trueFalseParam - a INT_MS_T, true if set
 * \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
msiPropertiesExists( msParam_t *listParam, msParam_t* keywordParam, msParam_t* trueFalseParam, ruleExecInfo_t *rei )
{
	char* value = NULL;

	RE_TEST_MACRO( "    Calling msiPropertiesExists" );

	/* 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 true if exists */
	value = getValByKey( (keyValPair_t*)listParam->inOutStruct,
		(char*)keywordParam->inOutStruct );
	fillIntInMsParam( trueFalseParam, (value==NULL) ? 0 : 1 );
	free( (char*)value );
	return 0;
}
示例#7
0
/**
 * \fn msiGetContInxFromGenQueryOut(msParam_t *genQueryOutParam, msParam_t *continueInx, ruleExecInfo_t *rei)
 *
 * \brief This microservice gets the continue index value from genQueryOut generated by msiExecGenQuery
 *
 * \module core
 *
 * \since 2.2
 *
 * \author  Arcot Rajasekar
 * \date    2009-10
 *
 * \note The resulting continueInx can be used to determine whether there are remaining rows to retrieve from the generated query.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] genQueryOutParam - Required - of type GenQueryOut_MS_T.
 * \param[out] continueInx - a INT_MS_T containing the new continuation index (after the query).
 * \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 msiExecGenQuery, msiGetMoreRows
**/
int
msiGetContInxFromGenQueryOut( msParam_t* genQueryOutParam, msParam_t* continueInx, ruleExecInfo_t *rei ) {
    genQueryOut_t *genQueryOut;

    RE_TEST_MACRO( "    Calling msiGetContInxFromGenQueryOut" )
    /* check for non null parameters */
    if ( !genQueryOutParam ) {
        rodsLog( LOG_ERROR, "msiGetContInxFromGenQueryOut: Missing parameter(s)" );
        return ( USER__NULL_INPUT_ERR );
    }
    /* check for proper input types */
    if ( strcmp( genQueryOutParam->type, GenQueryOut_MS_T ) ) {
        rodsLog( LOG_ERROR,
                 "msiGetContInxFromGenQueryOut: genQueryOutParam type is %s, should be GenQueryOut_MS_T",
                 genQueryOutParam->type );
        return ( USER_PARAM_TYPE_ERR );
    }

    genQueryOut = ( genQueryOut_t* )genQueryOutParam->inOutStruct;
    fillIntInMsParam( continueInx, genQueryOut->continueInx );
    return( 0 );
}
示例#8
0
文件: msiHelper.c 项目: UPPMAX/irods
/**
 * \fn msiWriteRodsLog (msParam_t *inpParam1,  msParam_t *outParam, ruleExecInfo_t *rei)
 *
 * \brief Writes a message into the server rodsLog.
 *
 * \module core
 *
 * \since 2.3
 *
 * \author  Jean-Yves Nief
 * \date    2009-06-15
 *
 * \note  This call should only be used through the rcExecMyRule (irule) call
 *        i.e., rule execution initiated by clients and should not be called
 *        internally by the server since it interacts with the client through
 *        the normal client/server socket connection.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] inpParam1 - A STR_MS_T which specifies the message to log.
 * \param[out] outParam - An INT_MS_T containing the 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 0 upon success
 * \pre N/A
 * \post N/A
 * \sa N/A
**/
int
msiWriteRodsLog (msParam_t *inpParam1,  msParam_t *outParam, ruleExecInfo_t *rei)
{
    rsComm_t *rsComm;

    RE_TEST_MACRO (" Calling msiWriteRodsLog")

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

    rsComm = rei->rsComm;

    if ( inpParam1 == NULL ) {
        rodsLogAndErrorMsg (LOG_ERROR, &rsComm->rError, rei->status,
        "msiWriteRodsLog: input Param1 is NULL");
        rei->status = USER__NULL_INPUT_ERR;
        return (rei->status);
    }

    if (strcmp (inpParam1->type, STR_MS_T) == 0) {
        rodsLog(LOG_NOTICE,
          "msiWriteRodsLog message: %s", inpParam1->inOutStruct);
    } else {
        rodsLogAndErrorMsg (LOG_ERROR, &rsComm->rError, rei->status,
        "msiWriteRodsLog: Unsupported input Param1 types %s",
        inpParam1->type);
        rei->status = UNKNOWN_PARAM_IN_RULE_ERR;
        return (rei->status);
    }

    rei->status = 0;

    fillIntInMsParam (outParam, rei->status);

    return (rei->status);
}
/**
 * \fn msiCopyAVUMetadata(msParam_t *inpParam1, msParam_t *inpParam2, msParam_t *outParam, ruleExecInfo_t *rei)
 *
 * \brief Copies metadata triplets from one iRODS object to another
 *
 * \author  Antoine de Torcy
 * \date    2007-09-26
 *
 * \note This microservice copies metadata triplets from one iRODS object to another.
 *    The source and destination can be a data object or a collection, independently.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] inpParam1 - A STR_MS_T with the irods path of the source object.
 * \param[in] inpParam2 - A STR_MS_T with the irods path of the destination object.
 * \param[out] outParam - An INT_MS_T containing the 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 0 on success
 * \pre None
 * \post None
 * \sa None
**/
int
msiCopyAVUMetadata(msParam_t *inpParam1, msParam_t *inpParam2, msParam_t *outParam, ruleExecInfo_t *rei)
{
	rsComm_t *rsComm;

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


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


	/* Check for proper input */
	if ((parseMspForStr(inpParam1) == NULL)) {
		rodsLog (LOG_ERROR, "msiCopyAVUMetadata: input inpParam1 is NULL");
		return (USER__NULL_INPUT_ERR);
	}

	if ((parseMspForStr (inpParam2) == NULL)) {
		rodsLog (LOG_ERROR, "msiCopyAVUMetadata: input inpParam2 is NULL");
		return (USER__NULL_INPUT_ERR);
	}


	/* Call copyAVUMetadata() */
	rei->status = copyAVUMetadata((char*)inpParam2->inOutStruct, (char*)inpParam1->inOutStruct, rsComm);

	/* Return operation status */
	fillIntInMsParam (outParam, rei->status);
	return (rei->status);
}
示例#10
0
/**
 * \fn msiGetMoreRows(msParam_t *genQueryInp_msp, msParam_t *genQueryOut_msp, msParam_t *continueInx, ruleExecInfo_t *rei)
 *
 * \brief This microservice continues an unfinished query.
 *
 * \module core
 *
 * \since pre-2.1
 *
 * \author  Antoine de Torcy
 * \date    2008-09-18
 *
 * \note This microservice gets the next batch of rows for an open iCAT query. Likely to follow #msiMakeGenQuery and #msiExecGenQuery.
 *
 * \usage None
 *
 * \param[in] genQueryInp_msp - Required - a GenQueryInp_MS_T containing the query parameters and conditions.
 * \param[in] genQueryOut_msp - Required - a GenQueryOut_MS_T to write results to. If its continuation index is 0 the query will be closed.
 * \param[out] continueInx - a INT_MS_T containing the new continuation index (after the query).
 * \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
msiGetMoreRows( msParam_t *genQueryInp_msp, msParam_t *genQueryOut_msp, msParam_t *continueInx, ruleExecInfo_t *rei ) {
    genQueryInp_t *genQueryInp;
    genQueryOut_t *genQueryOut;


    RE_TEST_MACRO( "    Calling msiGetMoreRows" )

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


    /* check for non null parameters */
    if ( !genQueryInp_msp || !genQueryOut_msp ) {
        rodsLog( LOG_ERROR, "msiGetMoreRows: Missing parameter(s)" );
        return ( USER__NULL_INPUT_ERR );
    }


    /* check for proper input types */
    if ( strcmp( genQueryOut_msp->type, GenQueryOut_MS_T ) ) {
        rodsLog( LOG_ERROR, "msiGetMoreRows: genQueryOut_msp type is %s, should be GenQueryOut_MS_T", genQueryOut_msp->type );
        return ( USER_PARAM_TYPE_ERR );
    }

    if ( strcmp( genQueryInp_msp->type, GenQueryInp_MS_T ) ) {
        rodsLog( LOG_ERROR, "msiGetMoreRows: query_msp type is %s, should be GenQueryInp_MS_T", genQueryInp_msp->type );
        return ( USER_PARAM_TYPE_ERR );
    }


    /* retrieve genQueryXXX data structures */
    genQueryOut = ( genQueryOut_t* )genQueryOut_msp->inOutStruct;
    genQueryInp = ( genQueryInp_t* )genQueryInp_msp->inOutStruct;


    /* match continuation indexes */
    genQueryInp->continueInx = genQueryOut->continueInx;

    if ( genQueryInp->continueInx > 0 ) {
        /* get the next batch */
        genQueryInp->maxRows = MAX_SQL_ROWS;
    }
    else {
        /* close query */
        genQueryInp->maxRows = -1;
    }


    /* free memory allocated for previous results */
    freeGenQueryOut( &genQueryOut );


    /* query */
    rei->status = rsGenQuery( rei->rsComm, genQueryInp, &genQueryOut );


    if ( rei->status == 0 ) {
        /* return query results */
        genQueryOut_msp->inOutStruct = genQueryOut;

        /* return continuation index separately in case it is needed in conditional expressions */
        resetMsParam( continueInx );
        fillIntInMsParam( continueInx, genQueryOut->continueInx );
    }

    return ( rei->status );
}
示例#11
0
/**
 * \fn msiVerifyExpiry (msParam_t* collinp, msParam_t* timeinp, msParam_t* typeinp, msParam_t* bufout, msParam_t* statout, ruleExecInfo_t* rei)
 *
 * \brief This microservice checks whether files in a collection have expired or not expired.
 *
 * \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    September 2008
 *
 * \usage See clients/icommands/test/rules3.0/ 
 *
 * \param[in] collinp - a STR_MS_T containing the collection's name
 * \param[in] timeinp - a STR_MS_T containing a date
 * \param[in] typeinp - a STR_MS_T containing one of {EXPIRED or NOTEXPIRED}
 * \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
msiVerifyExpiry (msParam_t* collinp, msParam_t* timeinp, msParam_t* typeinp, msParam_t* bufout, msParam_t* statout, ruleExecInfo_t* rei)
{

	rsComm_t *rsComm;
	genQueryInp_t gqin;
	genQueryOut_t *gqout = NULL;
	char condStr[MAX_NAME_LEN];
	char tmpstr[MAX_NAME_LEN];
	char* collname;
	sqlResult_t *dataName;
	sqlResult_t *dataExpiry;
	bytesBuf_t*	mybuf=NULL;
	int i,j,status;

	char* inputtime;
	char* querytype;
	int	checkExpiredFlag=0;
	char inputtimestr[TIME_LEN];

	RE_TEST_MACRO ("    Calling msiVerifyExpiry")

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

	rsComm = rei->rsComm;

	/* init stuff */
	memset (&gqin, 0, sizeof(genQueryInp_t));
	gqin.maxRows = MAX_SQL_ROWS;
    mybuf = (bytesBuf_t *) malloc (sizeof (bytesBuf_t));
    memset (mybuf, 0, sizeof (bytesBuf_t));
	gqout = (genQueryOut_t*) malloc (sizeof (genQueryOut_t));
	memset (gqout, 0, sizeof (genQueryOut_t));


	/* construct an SQL query from the parameter list */
	collname = strdup ((char*)collinp->inOutStruct);
	inputtime = strdup ((char*)timeinp->inOutStruct);
	querytype = strdup ((char*)typeinp->inOutStruct);

	/* 
		We have a couple of rule query possibilities:
		1. If 'inputtime' is valid & querytype == EXPIRED then list files which have an expiration date equal or past the input time
		2. If 'inputtime' is valid & querytype == NOTEXPIRED then list files which have yet to expire
	*/

	/* gotta at least have a collection name input */
	if (collname==NULL) return (USER_PARAM_TYPE_ERR);
	
	/* convert inputtime to unixtime */
	/* SUSAN we should make an option that inputtime = "now" */
	rstrcpy (inputtimestr, inputtime, TIME_LEN);
	status = checkDateFormat (inputtimestr);
	if (status < 0) return (DATE_FORMAT_ERR);

	/* now figure out what kind of query to perform */
	if (!strcmp(querytype, "EXPIRED")) {
		checkExpiredFlag = 1;
	} else if (!strcmp(querytype, "NOTEXPIRED")) {
		checkExpiredFlag = 0;
	} else return (USER_PARAM_TYPE_ERR); 
	

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

	j = rsGenQuery (rsComm, &gqin, &gqout);

	if (j<0) {

		appendToByteBuf (mybuf, "General Query was bad");

	} else if (j != CAT_NO_ROWS_FOUND) {

		int dataobjexpiry, inputtimeexpiry;

		dataName = getSqlResultByInx (gqout, COL_DATA_NAME);
		dataExpiry = getSqlResultByInx (gqout, COL_D_EXPIRY);
		inputtimeexpiry = atoi (inputtimestr);

		for (i=0; i<gqout->rowCnt; i++) {
			dataobjexpiry = atoi(&dataExpiry->value[dataExpiry->len*i]);

			/* check for expired files */
			if (checkExpiredFlag) { 
				if (dataobjexpiry < inputtimeexpiry)   {
					sprintf (tmpstr, "Data object:%s\twith Expiration date:%s has expired\n", 
						&dataName->value[dataName->len *i], &dataExpiry->value[dataExpiry->len *i]);
					appendToByteBuf (mybuf, tmpstr);
				}
			} else { 
				if (dataobjexpiry >= inputtimeexpiry) {
					sprintf (tmpstr, "Data object:%s\twith Expiration date:%s is expiring\n", 
						&dataName->value[dataName->len *i], &dataExpiry->value[dataExpiry->len *i]);
					appendToByteBuf (mybuf, tmpstr);
				}
			} 
				
		}
	} else appendToByteBuf (mybuf, "No rows found\n");

	fillBufLenInMsParam (bufout, mybuf->len, mybuf);
	fillIntInMsParam (statout, rei->status);
  
	return(rei->status);

}
示例#12
0
/**
 * \fn msiVerifyOwner (msParam_t* collinp, msParam_t* ownerinp, msParam_t* bufout, msParam_t* statout, ruleExecInfo_t *rei)
 *
 * \brief This microservice checks if files in a given collection have a consistent owner.
 *
 * \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] ownerinp - a STR_MS_T containing comma separated list of owner usernames
 * \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
msiVerifyOwner (msParam_t* collinp, msParam_t* ownerinp, 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;
	char* ownerlist;
	int i,j;
	sqlResult_t *dataName;
	sqlResult_t *dataOwner;
	char delims[]=",";
	char* word;
	char** olist=NULL;
	bytesBuf_t*	stuff=NULL;
	
	RE_TEST_MACRO ("    Calling msiVerifyOwner")

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

	rsComm = rei->rsComm;

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

   /* buffer init */
    stuff = (bytesBuf_t *)malloc(sizeof(bytesBuf_t));
    memset (stuff, 0, sizeof (bytesBuf_t));

	/* construct an SQL query from the parameter list */
	collname = strdup ((char*)collinp->inOutStruct);

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

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

	/* Now for each file retrieved in the query, determine if it's owner is in our list */

	if (j != CAT_NO_ROWS_FOUND) {

		printGenQueryOut(stderr, NULL, NULL, genQueryOut);

		dataName = getSqlResultByInx (genQueryOut, COL_DATA_NAME);
		dataOwner = getSqlResultByInx (genQueryOut, COL_D_OWNER_NAME);

		ownerlist = strdup ((char*)ownerinp->inOutStruct);
		//fprintf(stderr, "ownerlist: %s\n", ownerlist);

		if (strlen(ownerlist)>0) { /* our rule contains a list of owners we want to compare against */
			int ownercount=0;

			/* Construct a list of owners*/
			for (word=strtok(ownerlist, delims); word; word=strtok(NULL, delims)) {
				olist = (char**) realloc (olist, sizeof (char*) * (ownercount));  
				olist[ownercount] = strdup (word);
				ownercount++;
			}

			/* Now compare each file's owner with our list */
			for (i=0; i<genQueryOut->rowCnt; i++) {
				int foundflag=0;
				for (j=0; j<ownercount; j++) {
					char* thisowner = strdup(&dataOwner->value[dataOwner->len*i]);

					//fprintf(stderr, "comparing %s and %s\n", thisowner, olist[j]);
					if (!(strcmp(thisowner, olist[j]))) {
						/* We only care about the ones that DON'T match */
						foundflag=1;
						break;
					}
				}

				if (!foundflag) {
					char tmpstr[80];
					sprintf (tmpstr, "File: %s with owner: %s does not match input list\n", 
						&dataName->value[dataName->len *i], &dataOwner->value[dataOwner->len * i]);
					appendToByteBuf (stuff, tmpstr);
				}
			}

		} else { /* input parameter for owner is not set */
			
			rodsLog (LOG_ERROR, "msiVerifyOwner: ownerlist is NULL");

			/* just check if the owner name (whatever it is) is consistent across all files */
			/* We'll just compare using the first file's owner - this can probably be done several ways */
			char* firstowner = strdup(&dataOwner->value[0]); 

			int matchflag=1;  /* Start off assuming all owners match */

			for (i=1; i<genQueryOut->rowCnt; i++) {
				char* thisowner = strdup( &dataOwner->value[dataOwner->len*i]);
				if (strcmp(firstowner, thisowner)) { /* the two strings are not equal */
					appendToByteBuf (stuff, "Owner is not consistent across this collection");
					matchflag=0;
					break;
				}
			}

			if (matchflag) /* owner field was consistent across all data objects */
				appendToByteBuf (stuff, "Owner is consistent across this collection.\n");
			else
				appendToByteBuf (stuff, "Owner is not consistent across this collection.\n");
		}	
	} 

	fillBufLenInMsParam (bufout, stuff->len, stuff);
	fillIntInMsParam (statout, rei->status);
  
	return(rei->status);

}
示例#13
0
/**
 * \fn msiVerifyAVU (msParam_t* collinp, msParam_t* avunameinp, msParam_t* avuvalueinp, msParam_t* avuattrsinp, 
 *    msParam_t* bufout, msParam_t* statout, ruleExecInfo_t* rei)
 *
 * \brief This microservice performs operations on the AVU metadata on files in a given collection.
 *
 * \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
 *
 * \note See if all files in a collection match a given AVU.
 *
 * \usage See clients/icommands/test/rules3.0/ 
 *
 * \param[in] collinp - a STR_MS_T containing the collection's name
 * \param[in] avunameinp - a STR_MS_T containing the AVU name to check
 * \param[in] avuvalueinp - a STR_MS_T containing the AVU value to check
 * \param[in] avuattrsinp - a STR_MS_T containing the AVU attrs to check
 * \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
msiVerifyAVU (msParam_t* collinp, msParam_t* avunameinp, msParam_t* avuvalueinp, msParam_t* avuattrsinp, 
  msParam_t* bufout, msParam_t* statout, ruleExecInfo_t* rei)
{

	genQueryInp_t gqin;
	genQueryOut_t *gqout1 = NULL;
	genQueryOut_t *gqout2 = NULL;
	char condStr[MAX_NAME_LEN];
	char tmpstr[MAX_NAME_LEN];
	rsComm_t *rsComm;
	int i,j;
	sqlResult_t *dataName;
	sqlResult_t *dataID1; /* points to the data ID column in our first query */
	sqlResult_t *dataID2; /* points to the data ID column in our second query */
	sqlResult_t *dataAttrName;
	sqlResult_t *dataAttrValue;
	sqlResult_t *dataAttrUnits;
	bytesBuf_t*	mybuf=NULL;
	char* collname;
	char* inputattrname;
	char* inputattrvalue;
	char* inputattrunits;
	
	RE_TEST_MACRO ("    Calling msiVerifyAVU")

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

	/*
		Query 1 - just return the files in the collection
		Query 2 - return the files and their AVU triplet
	
		Note that Query 2 might be a subset of Query 1 since Query 2 will not return files that have no AVU listed.
		
		Foreach file in Query1 - see if the same file exists in Query2
			if so, see if the AVU triplet matches the input parameter
				if the AVU triplet doesn't match
					append error message to buf
			if not, append error message to buf
	*/

	rsComm = rei->rsComm;

	/* init structs */
	memset (&gqin, 0, sizeof (genQueryInp_t));
	gqin.maxRows = MAX_SQL_ROWS;
    mybuf = (bytesBuf_t*) malloc(sizeof(bytesBuf_t));
    memset (mybuf, 0, sizeof (bytesBuf_t));
	gqout1 = (genQueryOut_t*) malloc (sizeof (genQueryOut_t));
	memset (gqout1, 0, sizeof (genQueryOut_t));
	gqout2 = (genQueryOut_t*) malloc (sizeof (genQueryOut_t));
	memset (gqout2, 0, sizeof (genQueryOut_t));
 

	/* construct an SQL query from the parameter list */
	collname = strdup ((char*)collinp->inOutStruct);

	/* Return just the name and id of all the files in the collection for our first query */
	addInxIval (&gqin.selectInp, COL_DATA_NAME, 1);
	addInxIval (&gqin.selectInp, COL_D_DATA_ID, 1);
	snprintf (condStr, MAX_NAME_LEN, " = '%s'", collname);
	addInxVal (&gqin.sqlCondInp, COL_COLL_NAME, condStr);

	j = rsGenQuery (rsComm, &gqin, &gqout1);

	if (j<0)
		return (-1); /*RAJA badness what's the correct return error message */
	if (j != CAT_NO_ROWS_FOUND) {

		printGenQueryOut(stderr, NULL, NULL, gqout1);

		/* Now construct our second query, get the AVU information */
		memset (&gqin, 0, sizeof (genQueryInp_t));
		gqin.maxRows = MAX_SQL_ROWS;

		addInxIval (&gqin.selectInp, COL_DATA_NAME, 1);
		addInxIval (&gqin.selectInp, COL_D_DATA_ID, 1);
		addInxIval (&gqin.selectInp, COL_META_DATA_ATTR_NAME, 1);
		addInxIval (&gqin.selectInp, COL_META_DATA_ATTR_VALUE, 1);
		addInxIval (&gqin.selectInp, COL_META_DATA_ATTR_UNITS, 1);
		snprintf (condStr, MAX_NAME_LEN, " = '%s'", collname);
		addInxVal (&gqin.sqlCondInp, COL_COLL_NAME, condStr);

		j = rsGenQuery (rsComm, &gqin, &gqout2);

		if (j != CAT_NO_ROWS_FOUND) { /* Second query results */

			int q1rows = gqout1->rowCnt;
			int q2rows = gqout2->rowCnt;
			int q1thisdataid, q2thisdataid;
			char* q1thisdataname;
			char* thisdataattrname;
			char* thisdataattrvalue;
			char* thisdataattrunits; 

			/* OK now we have the results of two queries - time to compare
				data objects and their AVU's */
			dataName = getSqlResultByInx (gqout1, COL_DATA_NAME);
			dataID1 = getSqlResultByInx (gqout1, COL_D_DATA_ID);  /* we'll use this field for indexing into the second query */
			dataID2 = getSqlResultByInx (gqout2, COL_D_DATA_ID);  
			dataAttrName = getSqlResultByInx (gqout2, COL_META_DATA_ATTR_NAME);  
			dataAttrValue = getSqlResultByInx (gqout2, COL_META_DATA_ATTR_VALUE);  
			dataAttrUnits = getSqlResultByInx (gqout2, COL_META_DATA_ATTR_UNITS);  

			/* Assigning the inputted AVU values */
			inputattrname = strdup ((char*)avunameinp->inOutStruct);
			inputattrvalue = strdup ((char*)avuvalueinp->inOutStruct);
			inputattrunits = strdup ((char*)avuattrsinp->inOutStruct);

			/* Ok now for each data object id returned in Query 1, see if there's a matching ID returned in Query 2 */
			for (i=0; i<q1rows; i++) {
				int avufoundflag=0;
				q1thisdataname = strdup((&dataName->value[dataName->len*i]));
				q1thisdataid = atoi(&dataID1->value[dataID1->len*i]);
				for (j=0; j<q2rows; j++) {
					q2thisdataid = atoi(&dataID2->value[dataID2->len*j]);
					if (q1thisdataid == q2thisdataid) { /* means this data object has an AVU triplet set*/
						avufoundflag=1;
						/* now see if the AVU matches our input */
						thisdataattrname = strdup((&dataAttrName->value[dataAttrName->len*j]));
						thisdataattrvalue = strdup((&dataAttrValue->value[dataAttrValue->len*j]));
						thisdataattrunits = strdup((&dataAttrUnits->value[dataAttrUnits->len*j]));
						if (strcmp(thisdataattrname, inputattrname)) { /* no match */
							sprintf (tmpstr, "Data object:%s with AVU:%s,%s,%s does not match input\n",
								q1thisdataname, thisdataattrname, thisdataattrvalue, thisdataattrunits);	
							appendToByteBuf (mybuf, tmpstr);
						}
						if (strcmp(thisdataattrvalue, inputattrvalue)) { /* no match */
							sprintf (tmpstr, "Data object:%s with AVU:%s,%s,%s does not match input\n",
								q1thisdataname, thisdataattrname, thisdataattrvalue, thisdataattrunits);	
							appendToByteBuf (mybuf, tmpstr);
						}
						if (strcmp(thisdataattrunits, inputattrunits)) { /* no match */
							sprintf (tmpstr, "Data object:%s with AVU:%s,%s,%s does not match input\n",
								q1thisdataname, thisdataattrname, thisdataattrvalue, thisdataattrunits);	
							appendToByteBuf (mybuf, tmpstr);
						}
						break;
					} 
					
				}
				if (!avufoundflag) { /* this data object has no AVU associated with it */
					sprintf (tmpstr, "Data object:%s has no AVU triplet set\n", q1thisdataname);	
					appendToByteBuf (mybuf, tmpstr);
				}
				
			}
			

		} else {
			/* Query 2 returned no results */
		}
	} else {
		/* Query 1 returned no results */
	}

	fillBufLenInMsParam (bufout, mybuf->len, mybuf);
	fillIntInMsParam (statout, rei->status);
  
	return(rei->status);

}
示例#14
0
/**
 * \fn msiVerifyACL (msParam_t* collinp, msParam_t* userinp, msParam_t* authinp, msParam_t* notflaginp, 
 *    msParam_t* bufout, msParam_t* statout, ruleExecInfo_t *rei)
 *
 * \brief Check the ACL on a collection
 *
 * \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
 *
 * \note
 * \code
 *    This function can perform three different checks, depending on flags set via input parameters:
 *    1. check that its ACL contains the same set of user-authorization pairs as others in its collection
 *    2. check that its ACL contains at least a given set of user-authorization pairs
 *    3. check that its ACL does not contain a given set of user-authorization pairs 
 *    
 *    We have four input parameters: Collection Name, User Name, Authorization Type & NOT flag
 *    For the above conditions, the following are examples of how to call the rule
 *    1. collname=/sdscZone/home/rods%*User=rods%*Auth=own  
 *    2. collname=/sdscZone/home/rods  
 *    3. collname=/sdscZone/home/rods%*User=rods%*Auth=own*Notflag=1  
 * \endcode
 *    
 * \usage See clients/icommands/test/rules3.0/ 
 *
 * \param[in] collinp - a STR_MS_T containing the collection's name
 * \param[in] userinp - Optional - a STR_MS_T containing comma separated list of owner usernames
 * \param[in] authinp - Optional - a STR_MS_T containing comma separated list 
 * \param[in] notflaginp - Optional - a STR_MS_T
 * \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
msiVerifyACL (msParam_t* collinp, msParam_t* userinp, msParam_t* authinp, msParam_t* notflaginp, 
	msParam_t* bufout, msParam_t* statout, ruleExecInfo_t *rei)
{

	int i,j;
	int querytype=0;
	char tmpstr[MAX_NAME_LEN];
	genQueryInp_t	gqin;
	genQueryOut_t*	gqout = NULL;
	char* collname=NULL;
	char* collid=NULL;
	char* username=NULL;
	char* accessauth=NULL;
	char* notflag=NULL;
	rsComm_t *rsComm;
	bytesBuf_t* mybuf=NULL;
	sqlResult_t* collCollId;
	sqlResult_t* dataName;
	sqlResult_t* dataAccessName;
	sqlResult_t* dataAccessType;
	sqlResult_t* dataAccessDataId;
	sqlResult_t* dataAccessUserId;
	//sqlResult_t* dataTokenNamespace;

	RE_TEST_MACRO ("    Calling msiVerifyACL")

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

	/* 
		This function can perform three different checks, depending on flags set via input parameters:
		1. check that its ACL contains the same set of user-authorization pairs as others in its collection
		2. check that its ACL contains at least a given set of user-authorization pairs
		3. check that its ACL does not contain a given set of user-authorization pairs 

		We have four input parameters: Collection Name, User Name, Authorization Type & NOT flag
		For the above conditions, the following are examples of how to call the rule
		1. collname=/sdscZone/home/rods%*User=rods%*Auth=own  
		2. collname=/sdscZone/home/rods  
		3. collname=/sdscZone/home/rods%*User=rods%*Auth=own*Notflag=1  
	*/

	collname = strdup ((char*)collinp->inOutStruct);
	if (collname == NULL) return (USER__NULL_INPUT_ERR);
	/* These next three don't necessarily have to be set */
	username = strdup ((char*)userinp->inOutStruct);
	accessauth = strdup ((char*)authinp->inOutStruct);
	notflag = strdup ((char*)notflaginp->inOutStruct);
	
	if ((username==NULL) && (accessauth==NULL)) {
		querytype=1; /* Case #1. see above */
		notflag=NULL; /* we don't care about this variable in this case */
	} 
	/* just an exclusive OR - both of these variables, username & accessauth HAVE to be set */
	else if (((username==NULL) && (accessauth!=NULL)) || ((username!=NULL) && (accessauth==NULL))) {
			return (USER__NULL_INPUT_ERR);
	} else {
		if (atoi(notflag)==0)
			querytype=2;
		else
			querytype=3;
	}
		
	
	/* init gqout, gqin & mybuf structs */
	gqout = (genQueryOut_t*) malloc (sizeof (genQueryOut_t));
	memset (gqout, 0, sizeof (genQueryOut_t));
	mybuf = (bytesBuf_t*) malloc(sizeof(bytesBuf_t));
	memset (mybuf, 0, sizeof (bytesBuf_t));
	gqin.maxRows = MAX_SQL_ROWS;


	/* First get the collection id from the collection name, then
		use the collection id field as a key to obtaining all the
		other nifty info we need */ 
	snprintf (tmpstr, MAX_NAME_LEN, " = '%s'", collname);
	addInxVal (&gqin.sqlCondInp, COL_COLL_NAME, tmpstr);
	addInxIval (&gqin.selectInp, COL_D_COLL_ID, 1);

	j = rsGenQuery (rsComm, &gqin, &gqout);
	
	if (j<0) {
		appendToByteBuf (mybuf, "Coll ID Not found\n");
	}
	else if (j != CAT_NO_ROWS_FOUND) {

		printGenQueryOut(stderr, NULL, NULL, gqout);

		/* RAJA don't we really just need the first element, since all the collection id's should be the same? */
		collCollId = getSqlResultByInx (gqout, COL_D_COLL_ID);
		collid = strdup (&collCollId->value[0]);
		sprintf (tmpstr, "Collection ID:%s\n", &collCollId->value[0]);
		appendToByteBuf (mybuf, tmpstr);

	} else {
		appendToByteBuf (mybuf, "RAJA - what unknown error\n");
		return (1);  /* what return value RAJA */
	}

	/* Now do another query to get all the interesting ACL information */
	memset (&gqin, 0, sizeof (genQueryInp_t));
	gqin.maxRows = MAX_SQL_ROWS;
	
	addInxIval (&gqin.selectInp, COL_DATA_NAME, 1);
	addInxIval (&gqin.selectInp, COL_DATA_ACCESS_NAME, 1);
	addInxIval (&gqin.selectInp, COL_DATA_ACCESS_TYPE, 1);
	addInxIval (&gqin.selectInp, COL_DATA_ACCESS_DATA_ID, 1);
	addInxIval (&gqin.selectInp, COL_DATA_ACCESS_USER_ID, 1);
	//addInxIval (&gqin.selectInp, COL_DATA_TOKEN_NAMESPACE, 1);

	/* Currently necessary since other namespaces exist in the token table */
	//snprintf (tmpstr, MAX_NAME_LEN, "='%s'", "access_type");
	//addInxVal (&gqin.sqlCondInp, COL_COLL_TOKEN_NAMESPACE, tmpStr);

	snprintf (tmpstr, MAX_NAME_LEN, " = '%s'", collid);
	addInxVal (&gqin.sqlCondInp, COL_D_COLL_ID, tmpstr);

	j = rsGenQuery (rsComm, &gqin, &gqout);

	if (j<0) {
		 appendToByteBuf (mybuf, "Second gen query bad\n");
	} else if  (j != CAT_NO_ROWS_FOUND) {

		dataName = getSqlResultByInx (gqout, COL_DATA_NAME);
		dataAccessType = getSqlResultByInx (gqout, COL_DATA_ACCESS_TYPE);
		dataAccessName = getSqlResultByInx (gqout, COL_DATA_ACCESS_NAME);
		dataAccessDataId = getSqlResultByInx (gqout, COL_DATA_ACCESS_DATA_ID);
		dataAccessUserId = getSqlResultByInx (gqout, COL_DATA_ACCESS_USER_ID);
		//dataTokenNamespace = getSqlResultByInx (gqout, COL_DATA_TOKEN_NAMESPACE);

		for (i=0; i<gqout->rowCnt; i++) {
			sprintf (tmpstr, "Data name:%s\tData Access Type:%s\tData Access Name:%s\tData Access Data Id:%s\t Data Access User ID:%s\tNamespace:%s\n",
				&dataName->value[dataName->len *i], 
				&dataAccessType->value[dataAccessType->len *i], 
				&dataAccessName->value[dataAccessName->len *i],
				&dataAccessDataId->value[dataAccessDataId->len *i],
				&dataAccessUserId->value[dataAccessUserId->len *i],
		//		&dataTokenNamespace->value[dataTokenNamespace->len *i]);
				"some namespace");
			appendToByteBuf (mybuf, tmpstr);
		}	

		printGenQueryOut(stderr, NULL, NULL, gqout);
	} else appendToByteBuf (mybuf, "something else gone bad RAJA");
	

	fillBufLenInMsParam (bufout, mybuf->len, mybuf);
	fillIntInMsParam (statout, rei->status);
  
	return(rei->status);

	return(0);
	
}
示例#15
0
void *startMonScript( void *arg ) {
    /***********************************************************
     * launch Perl script on each server, retrieve the result  *
     * and give it to the rodsMonPerfLog function in order to  *
     * insert it into the database .                           *
     **********************************************************/
    char *output;
    msParam_t msp1, msp2, msp3, msp4, msp5, msout;
    int thrid,  status;
    int retval;

    thrInp_t *tinput = ( thrInp_t* )arg;
#ifndef windows_platform
    pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );
    pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
#endif
    fillStrInMsParam( &msp1, tinput->cmd );
    fillStrInMsParam( &msp2, tinput->cmdArgv );
    fillStrInMsParam( &msp3, tinput->execAddr );
    fillStrInMsParam( &msp4, tinput->hintPath );
    fillIntInMsParam( &msp5, tinput->addPathToArgv );
    thrid = tinput->threadId;

    threadIsAlive[thrid] = 0;
    status = msiExecCmd( &msp1, &msp2, &msp3, &msp4, &msp5, &msout, &( tinput->rei ) );

    if ( status < 0 ) {
        char noanswer[MAXSTR] = MON_OUTPUT_NO_ANSWER;
        rodsLogError( LOG_ERROR, status, "Call to msiExecCmd failed in msiServerMonPerf. " );
        rodsMonPerfLog( tinput->execAddr, tinput->rescName, noanswer, &( tinput->rei ) );
        threadIsAlive[thrid] = 1;
        retval = -1;
#ifndef windows_platform
        pthread_exit( ( void * )&retval );
#endif
    }

    /* if (&msout != NULL) { */
    /* write into the irodsMonPerf log file */
    if ( ( char * )( *( ( execCmdOut_t * ) msout.inOutStruct ) ).stdoutBuf.buf != NULL ) {
        output = ( char * )( *( ( execCmdOut_t * ) msout.inOutStruct ) ).stdoutBuf.buf;
        rodsMonPerfLog( tinput->execAddr, tinput->rescName, output, &( tinput->rei ) );
    }
    else {
        char noanswer[MAXSTR] = MON_OUTPUT_NO_ANSWER;
        rodsLog( LOG_ERROR, "Server monitoring: no output for the server %s, status = %i \n", tinput->execAddr, status );
        rodsMonPerfLog( tinput->execAddr, tinput->rescName, noanswer, &( tinput->rei ) );
        threadIsAlive[thrid] = 1;
        retval = -1;
#ifndef windows_platform
        pthread_exit( ( void * )&retval );
#endif
    }
    /*}
      else {
      char noanswer[MAXSTR] = MON_OUTPUT_NO_ANSWER;
      rodsLog(LOG_ERROR, "Server monitoring: problem with the server %s, status = %i \n", tinput->execAddr, status);
      rodsMonPerfLog(tinput->execAddr, tinput->rescName, noanswer,
      &(tinput->rei));
      threadIsAlive[thrid] = 1;
      retval = -1;
      #ifndef windows_platform
      pthread_exit((void *)&retval);
      #endif
      } */

    threadIsAlive[thrid] = 1;

    retval = 0;
#ifndef windows_platform
    pthread_exit( ( void * )&retval );
#endif
}
示例#16
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);

}
示例#17
0
/**
 * \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 msiNcGetElementInArray (msParam_t *arrayStructParam, msParam_t *indexParam, msParam_t *outParam, ruleExecInfo_t *rei)
    * \brief Get the value of an element in an array. The position of the element in the array is given in the indexParam input.
    * \module core
    *
    * \since 3.2
    *
    * \author  Mike Wan
    * \date    2012
    *
    * \usage See clients/icommands/test/rules3.0/netcdfTest1.r, netcdfTest2.r and netcdfTest3.r.
    * \param[in] indexParam - An INT_MS_T containing the index of an element in the array
    * \param[out] outParam - An INT_MS_T, CHAR_MS_T, STR_MS_T, or DOUBLE_MS_T, etc (depending on the dataType of the array) containing the value of the element).
    *
    * \DolVarDependence none
    * \DolVarModified none
    * \iCatAttrDependence none
    * \iCatAttrModified none
    * \sideeffect none
    *
    * \return integer
    * \retval 0 upon success
    * \pre N/A
    * \post N/A
    * \sa N/A
    *
    **/
    int
    msiNcGetElementInArray (msParam_t *arrayStructParam, msParam_t *indexParam,
    msParam_t *outParam, ruleExecInfo_t *rei)
    {
        int myindex;
        void *myarray;
        int dataType;
        int arrayLen;
        char *charArray;
        int *intArray;
        float *floatArray;
        rodsLong_t *longArray;
        char **strArray;

        RE_TEST_MACRO ("    Calling msiNcGetElementInArray")

        if (arrayStructParam == NULL || indexParam == NULL ||
          outParam == NULL) return USER__NULL_INPUT_ERR;

        if (strcmp (arrayStructParam->type, NcInqWithIdOut_MS_T) == 0) {
            /* intArray for the id array */
            ncInqWithIdOut_t *ncInqWithIdOut;
            ncInqWithIdOut = (ncInqWithIdOut_t *) arrayStructParam->inOutStruct;
            dataType = NC_INT;
            myarray = (void *) ncInqWithIdOut->intArray;
            arrayLen = ncInqWithIdOut->ndim;
        } else if (strcmp (arrayStructParam->type, NcGetVarOut_MS_T) == 0) {
            ncGetVarOut_t *ncGetVarOut;
            ncGetVarOut = (ncGetVarOut_t *) arrayStructParam->inOutStruct;
            if (ncGetVarOut == NULL || ncGetVarOut->dataArray == NULL)
                return USER__NULL_INPUT_ERR;
            dataType = ncGetVarOut->dataArray->type;
            myarray = ncGetVarOut->dataArray->buf;
            arrayLen = ncGetVarOut->dataArray->len;
        } else {
            rodsLog (LOG_ERROR,
              "msiNcGetNumDim: Unsupported input Param type %s",
              arrayStructParam->type);
            return (USER_PARAM_TYPE_ERR);
        }
        myindex = parseMspForPosInt (indexParam);
        if (myindex < 0 || myindex >= arrayLen) {
            rodsLog (LOG_ERROR,
              "msiNcGetElementInArray: input index %d out of range. arrayLen = %d",
              myindex, arrayLen);
            return (NETCDF_DIM_MISMATCH_ERR);
        }

        switch (dataType) {
          case NC_CHAR:
          case NC_BYTE:
          case NC_UBYTE:
            charArray = (char *) myarray;
            fillCharInMsParam (outParam, charArray[myindex]);
            break;
          case NC_STRING:
            strArray = (char **) myarray;
            fillStrInMsParam (outParam, strArray[myindex]);
            break;
          case NC_INT:
          case NC_UINT:
            intArray = (int *) myarray;
            fillIntInMsParam (outParam, intArray[myindex]);
            break;
          case NC_FLOAT:
            floatArray = (float *) myarray;
            fillFloatInMsParam (outParam, floatArray[myindex]);
            break;
          case NC_INT64:
          case NC_UINT64:
          case NC_DOUBLE:
            longArray = (rodsLong_t *) myarray;
            fillDoubleInMsParam (outParam, longArray[myindex]);
            break;
          default:
            rodsLog (LOG_ERROR,
              "msiNcGetElementInArray: Unknow dataType %d", dataType);
            return (NETCDF_INVALID_DATA_TYPE);
        }
        return 0;
    }
    /**
    * \fn msiNcGetVarIdInInqOut (msParam_t *ncInqOutParam, msParam_t *whichVarParam,
    msParam_t *outParam, ruleExecInfo_t *rei)
    * \brief Get the NETCDF variable ID of a variable in a NcInqOut_MS_T
    * \module core
    *
    * \since 3.2
    *
    * \author  Mike Wan
    * \date    2012
    *
    * \usage See clients/icommands/test/rules3.0/netcdfTest1.r, netcdfTest2.r and netcdfTest3.r.
    * \param[in] ncInqOutParam - A NcInqOut_MS_T which is the output of msiNcInq.
    * \param[in] whichVarParam - If it is a STR_MS_T, it contains the name of the variable. If it is an INT_MS_T, it contains the index of an element in the variable array.
    * \param[out] outParam - An INT_MS_T containing the variable ID.
    *
    * \DolVarDependence none
    * \DolVarModified none
    * \iCatAttrDependence none
    * \iCatAttrModified none
    * \sideeffect none
    *
    * \return integer
    * \retval 0 upon success
    * \pre N/A
    * \post N/A
    * \sa N/A
    *
    **/
    int
    msiNcGetVarIdInInqOut (msParam_t *ncInqOutParam, msParam_t *whichVarParam,
    msParam_t *outParam, ruleExecInfo_t *rei)
    {
        ncInqOut_t *ncInqOut;
        int inx;
        char *varName;
        int id = -1;

        RE_TEST_MACRO ("    msiNcGetVarIdInInqOut msiNcGetVarNameInInqOut")

        if (ncInqOutParam == NULL || whichVarParam == NULL || outParam == NULL)
            return USER__NULL_INPUT_ERR;

        if (strcmp (ncInqOutParam->type, NcInqOut_MS_T) != 0) {
            rodsLog (LOG_ERROR,
              "msiNcGetVarIdInInqOut: ncInqOutParam must be NcInqOut_MS_T. %s",
              ncInqOutParam->type);
            return (USER_PARAM_TYPE_ERR);
        } else {
            ncInqOut = (ncInqOut_t *) ncInqOutParam->inOutStruct;
        }
      /* whichVarParam can be inx or attName */
        if (strcmp (whichVarParam->type, STR_MS_T) == 0) {
            varName = (char *)whichVarParam->inOutStruct;
            inx = -1;
        } else if (strcmp (whichVarParam->type, INT_MS_T) == 0) {
            inx = *((int *) whichVarParam->inOutStruct);
            varName = NULL;
        } else {
            rodsLog (LOG_ERROR,
              "msiNcGetVarIdInInqOut:whichVarParam must be INT_MS_T/STR_MS_T. %s",
              whichVarParam->type);
            return (USER_PARAM_TYPE_ERR);
        }

        if (varName == NULL) {
            if (inx < 0 || inx >= ncInqOut->nvars) {
                rodsLog (LOG_ERROR,
                  "msiNcGetVarIdInInqOut:inp inx %d out of range. nvars=%d",
                  inx, ncInqOut->nvars);
                return NETCDF_VAR_COUNT_OUT_OF_RANGE;
            }
            id = ncInqOut->var[inx].id;
        } else {
            /* input is a var name */
            int i;
            for (i = 0; i < ncInqOut->nvars; i++) {
                if (strcmp (varName, ncInqOut->var[i].name) == 0) {
                    id = ncInqOut->var[i].id;
                    break;
                }
            }
            if (id < 0) {
                rodsLog (LOG_ERROR,
                  "msiNcGetVarIdInInqOut: unmatched varName %s", varName);
                return NETCDF_UNMATCHED_NAME_ERR;
            }
        }
        fillIntInMsParam (outParam, id);

        return 0;
    }