Пример #1
0
/**
 * \fn msiGetDiffTime(msParam_t* inpParam1, msParam_t* inpParam2, msParam_t* inpParam3, msParam_t* outParam, ruleExecInfo_t *rei)
 *
 * \brief This microservice returns the difference between two system times
 *
 * \module framework
 *
 * \since 2.1
 *
 * \author  Antoine de Torcy
 * \date    2007-09-19
 *
 * \note If we have arithmetic MSs in the future we should use DOUBLE_MS_T instead of strings.
 *       Default output format is in seconds, use 'human' as the third input param for human readable format.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] inpParam1 - a STR_MS_T containing the start date (system time in seconds)
 * \param[in] inpParam2 - a STR_MS_T containing the end date (system time in seconds)
 * \param[in] inpParam3 - Optional - a STR_MS_T containing the desired output format
 * \param[out] outParam - a STR_MS_T containing the time elapsed between the two dates
 * \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
msiGetDiffTime( msParam_t* inpParam1, msParam_t* inpParam2, msParam_t* inpParam3, msParam_t* outParam, ruleExecInfo_t *rei ) {
    long hours, minutes, seconds;
    char timeStr[TIME_LEN];
    char *format;
    int status;


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


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


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

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


    /* get time values from strings */
    seconds = atol( ( char * ) inpParam2->inOutStruct ) - atol( ( char * )inpParam1->inOutStruct );

    /* get desired output format */
    format = ( char * ) inpParam3->inOutStruct;


    /* did they ask for human readable format? */
    if ( format && !strcmp( format, "human" ) ) {
        /* get hours-minutes-seconds */
        hours = seconds / 3600;
        seconds = seconds % 3600;
        minutes = seconds / 60;
        seconds = seconds % 60;

        snprintf( timeStr, TIME_LEN, "%ldh %ldm %lds", hours, minutes, seconds );
    }
    else {
        snprintf( timeStr, TIME_LEN, "%011ld", seconds );
    }


    /* result goes to outParam */
    status = fillStrInMsParam( outParam, timeStr );

    return( status );
}
Пример #2
0
/**
 * \fn msiAddKeyVal(msParam_t *inKeyValPair, msParam_t *key, msParam_t *value, ruleExecInfo_t *rei)
 *
 * \brief  Adds a new key and value to a keyValPair_t
 *
 * \module core
 *
 *
 * \note A new keyValPair_t is created if inKeyValPair is NULL.
 *
 * \usage See clients/icommands/test/rules/
 *
 * \param[in,out] inKeyValPair - Optional - a KeyValPair_MS_T
 * \param[in] key - Required - A STR_MS_T containing the key
 * \param[in] value - Optional - A STR_MS_T containing the 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 msiAddKeyVal( msParam_t *inKeyValPair, msParam_t *key, msParam_t *value, ruleExecInfo_t *rei ) {
    char *key_str, *value_str;
    keyValPair_t *newKVP;

    /*************************************  INIT **********************************/

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

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


    /********************************** PARAM PARSING  *********************************/

    /* Parse key */
    if ( ( key_str = parseMspForStr( key ) ) == NULL ) {
        rodsLog( LOG_ERROR, "msiAddKeyVal: input key is NULL." );
        return USER__NULL_INPUT_ERR;
    }

    /* Parse value */
    value_str = parseMspForStr( value );

    /* Check for wrong parameter type */
    if ( inKeyValPair->type && strcmp( inKeyValPair->type, KeyValPair_MS_T ) ) {
        rodsLog( LOG_ERROR, "msiAddKeyVal: inKeyValPair is not of type KeyValPair_MS_T." );
        return USER_PARAM_TYPE_ERR;
    }

    /* Parse inKeyValPair. Create new one if empty. */
    if ( !inKeyValPair->inOutStruct ) {
        /* Set content */
        newKVP = ( keyValPair_t* )malloc( sizeof( keyValPair_t ) );
        memset( newKVP, 0, sizeof( keyValPair_t ) );
        inKeyValPair->inOutStruct = ( void* )newKVP;

        /* Set type */
        if ( !inKeyValPair->type ) {
            inKeyValPair->type = strdup( KeyValPair_MS_T );
        }
    }


    /******************************* ADD NEW PAIR AND DONE ******************************/

    rei->status = addKeyVal( ( keyValPair_t* )inKeyValPair->inOutStruct, key_str, value_str );

    /* Done */
    return rei->status;
}
Пример #3
0
int msiset_avu(
    msParam_t* _item_type,
    msParam_t* _item_name,
    msParam_t* _attr_name,
    msParam_t* _attr_val,
    msParam_t* _attr_unit,
    ruleExecInfo_t* _rei ) {

    char *it_str = parseMspForStr( _item_type );
    if( !it_str ) {
        return SYS_INVALID_INPUT_PARAM;
    }

    char *in_str = parseMspForStr( _item_name );
    if( !in_str ) {
        return SYS_INVALID_INPUT_PARAM;
    }

    char *an_str = parseMspForStr( _attr_name );
    if( !an_str ) {
        return SYS_INVALID_INPUT_PARAM;
    }

    char *av_str = parseMspForStr( _attr_val );
    if( !av_str ) {
        return SYS_INVALID_INPUT_PARAM;
    }

    char *au_str = parseMspForStr( _attr_unit );
    if( !au_str ) {
        return SYS_INVALID_INPUT_PARAM;
    }

    char op[]  = "set";

    modAVUMetadataInp_t avuOp;
    memset(&avuOp, 0, sizeof(avuOp));
    avuOp.arg0 = op;
    avuOp.arg1 = it_str;
    avuOp.arg2 = in_str;
    avuOp.arg3 = an_str;
    avuOp.arg4 = av_str;
    avuOp.arg5 = au_str;

    _rei->status = rsModAVUMetadata(_rei->rsComm, &avuOp);

    return _rei->status;

}
Пример #4
0
int 
msiGetFieldFromRodsObjStat(msParam_t *in_rodsObjStat, msParam_t *in_Field, msParam_t *out, ruleExecInfo_t *rei) {
    rodsObjStat_t *rodsObjStatIn = NULL;
    char output[MAX_NAME_LEN];
    char *field;
    
    rei->status = 0;
    
    //process input parameter
    if(in_rodsObjStat->inOutStruct == NULL) {
        rei->status = -1;
        return rei->status;
    }
    rodsObjStatIn = (rodsObjStat_t *)in_rodsObjStat->inOutStruct;
    field = parseMspForStr(in_Field);
    if(field == NULL) {
        rodsLog(LOG_ERROR, (char *) "msiGetFieldFromRodsObjStat :: supplied field cannot be NULL.");
        rei->status = -1;
        return rei->status;
    }
    
    //extract requested field
    if(strcmp(field, "size") == 0 || strcmp(field, "SIZE") == 0) {
        snprintf(output, MAX_NAME_LEN, "%i", rodsObjStatIn->objSize);
    } else {
        rei->status = -1;
        rodsLog(LOG_ERROR, (char *) "msiGetFieldFromRodsObjStat :: unkown field supplied: [%s]", field);
    }
    
    //set output
    if(rei->status >= 0) {
        rei->status = fillStrInMsParam(out, output);        
    }
    return rei->status;
}
Пример #5
0
/**
 * msiGetRescAddr
 *
 * @param[in]		rescName	the resource name 
 * @param[out]		outAddress	the returned IP address
 * @param[in,out]	rei		the rule execution information
 * @return				the status code, 0 on success
 */
int
msiGetRescAddr( msParam_t *rescName, msParam_t *outAddress,
	ruleExecInfo_t *rei )
{
    char *tmpPtr;
    int status;
    rescGrpInfo_t *rescGrpInfo = NULL;

    RE_TEST_MACRO( "    Calling msiGetRescAddr" );

    tmpPtr = parseMspForStr (rescName);

    if (tmpPtr == NULL)  {
	rodsLog (LOG_ERROR, "msiGetRescAddr: missing name input");
	rei->status = USER__NULL_INPUT_ERR;
	return USER__NULL_INPUT_ERR;
    }

    status = _getRescInfo (rei->rsComm, tmpPtr, &rescGrpInfo);
    if (status < 0) {
         rodsLog (LOG_ERROR,
          "msiGetRescAddr: _getRescInfo of %s error. stat = %d",
          rescName, status);
        return status;
    }

    fillStrInMsParam (outAddress, rescGrpInfo->rescInfo->rescLoc);

    rei->status = 0;
    return 0;
}
// =-=-=-=-=-=-=-
// 1. Write a standard issue microservice
    int irods_http_send_file( msParam_t* url, msParam_t* src_obj, ruleExecInfo_t* rei ) {
        dataObjInp_t dataObjInp, *myDataObjInp;
        char *myUrl;

        // Sanity checks
        if ( !rei || !rei->rsComm ) {
            rodsLog( LOG_ERROR, "irods_http_send_file Input rei or rsComm is NULL." );
            return ( SYS_INTERNAL_NULL_INPUT_ERR );
        }

        // Get path of destination object
        rei->status = parseMspForDataObjInp( src_obj, &dataObjInp, &myDataObjInp, 0 );
        if ( rei->status < 0 ) {
            rodsLog( LOG_ERROR, "irods_http_send_file: Input object error. status = %d", rei->status );
            return ( rei->status );
        }

        // Create irodsCurl instance
        irodsCurl myCurl( rei->rsComm );

        // Call irodsCurl::post
        rei->status = myCurl.post( parseMspForStr( url ), myDataObjInp->objPath );

        // Done
        return rei->status;

    }
Пример #7
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);
}
Пример #8
0
int 
msiWriteToLog(msParam_t *in_level, msParam_t *in_msg, ruleExecInfo_t *rei) {
    char *level;
    char *msg;
    
    level = parseMspForStr(in_level);
    msg = parseMspForStr(in_msg);
    
    if(strcmp(level, "debug") == 0) {
        rodsLog(LOG_DEBUG, "msiWriteToLog :: %s", msg);
    } else if(strcmp(level, "error") == 0) {
        rodsLog(LOG_ERROR, "msiWriteToLog :: %s", msg);
    } else {
        rodsLog(LOG_NOTICE, "msiWriteToLog :: %s", msg);
    }
    

    return 0;
}
Пример #9
0
int 
msiGetZoneNameFromPath(msParam_t *inPath, msParam_t *outZoneName, ruleExecInfo_t *rei) {
    char *path;
    char tmp[MAX_NAME_LEN];
    char *ptr;  
    
    path = parseMspForStr(inPath);
    snprintf(tmp, MAX_NAME_LEN, "%s", path);
    strtok_r (tmp, "/", &ptr);
    fillStrInMsParam(outZoneName, tmp);
    
    return 0;
}
/**
 * \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);
}
Пример #11
0
/*
 * replace slash "/" symbol in string with an hyphen "_"
 * Input: String with / as absolute address of file ex. /tempZone/DATA/file.txt
 * Output: String with _ ex. _tempZone_DATA_file.txt
 * TODO: is there any better Search-Function after slash in C-library ?
 */
int msiReplaceSlash(msParam_t *inPath, msParam_t *outPath, ruleExecInfo_t *rei)
{
    rei->status = 0;
    char *strad =  parseMspForStr(inPath);
    int length = strlen(strad)+1;
    char *buffer = (char*) malloc(length);
    snprintf(buffer, length, "%s", strad);

    int i;
    for (i = 0; i < length; buffer[i] = buffer[i] == '/' ? '_' : buffer[i], i++)

    fillStrInMsParam (outPath, buffer);
    free(buffer);
    return rei->status;
}
Пример #12
0
/**
 * \fn msiDbrRollback(msParam_t *dbrName, ruleExecInfo_t *rei)
 *
 * \brief This microservice does a rollback on a Database Resource (DBR)
 *
 * \module core
 *
 * \since 2.5
 *
 * \author Wayne Schroeder
 * \date   2010-11-23
 *
 * \usage See clients/icommands/test/rules3.0/ and https://www.irods.org/index.php/DBR
 *
 * \param[in] dbrName - a STR_MS_T, name of the DBR being used
 * \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
msiDbrRollback(msParam_t *dbrName, ruleExecInfo_t *rei)
{
    rsComm_t *rsComm; 
    int status;

    databaseObjControlInp_t databaseObjControlInp;
    databaseObjControlOut_t *databaseObjControlOut;

    char *myDbrName;

    RE_TEST_MACRO ("    Calling msiDboRollback")

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

    memset((void *)&databaseObjControlInp, 0, sizeof(databaseObjControlInp));

    myDbrName = parseMspForStr(dbrName);
    if (myDbrName == NULL) {
       rodsLogAndErrorMsg (LOG_ERROR, &rsComm->rError, rei->status,
			   "msiDbrRollback: input dbrName is NULL");
       return(USER__NULL_INPUT_ERR);
    }

   databaseObjControlInp.dbrName = myDbrName;

   databaseObjControlInp.option =  DBR_ROLLBACK;

   status = rsDatabaseObjControl(rsComm, &databaseObjControlInp, 
				 &databaseObjControlOut);
   return(status);

}
Пример #13
0
/**
 * \fn msiHumanToSystemTime(msParam_t* inpParam, msParam_t* outParam, ruleExecInfo_t *rei)
 *
 * \brief Converts a human readable date to a system timestamp
 *
 * \module framework
 *
 * \since pre-2.1
 *
 *
 * \note Expects an input date in the form: YYYY-MM-DD-hh.mm.ss
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] inpParam - a STR_MS_T containing the input date
 * \param[out] outParam - a STR_MS_T containing the timestamp
 * \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
msiHumanToSystemTime( msParam_t* inpParam, msParam_t* outParam, ruleExecInfo_t *rei ) {
    //CID26185: prevent buffer overrun
    char sys_time[TIME_LEN + 1], *hr_time;
    int status;

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


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


    /* parse inpParam (date input string) */
    if ( ( hr_time = parseMspForStr( inpParam ) ) == NULL ) {
        rodsLog( LOG_ERROR, "msiHumanToSystemTime: parseMspForStr error for input param." );
        return rei->status;
    }


    /* left padding with a zero for DB format. Might change that later */
    memset( sys_time, '\0', TIME_LEN );
    sys_time[0] = '0';


    /* conversion */
    if ( ( status = localToUnixTime( hr_time, &sys_time[1] ) )  == 0 ) {
        status = fillStrInMsParam( outParam, sys_time );
    }


    return status;
}
Пример #14
0
/**
 * \fn msiStrToBytesBuf(msParam_t* str_msp, msParam_t* buf_msp, ruleExecInfo_t *rei)
 *
 * \brief Converts a string to a bytesBuf_t
 *
 * \module core
 *
 * \since pre-2.1
 *
 * \author  Antoine de Torcy
 * \date    2008-09-16
 *
 * \note For easily passing parameters to microservices that require a BUF_LEN_MS_T
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] str_msp - a STR_MS_T
 * \param[out] buf_msp - a BUF_LEN_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
msiStrToBytesBuf( msParam_t* str_msp, msParam_t* buf_msp, ruleExecInfo_t *rei ) {
    char *inStr;
    bytesBuf_t *outBuf;

    /* parse str_msp */
    if ( ( inStr = parseMspForStr( str_msp ) ) == NULL ) {
        rodsLog( LOG_ERROR, "msiStrToBytesBuf: input str_msp is NULL." );
        return ( USER__NULL_INPUT_ERR );
    }

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

    /* fill string in buffer */
    outBuf->len = strlen( inStr );
    outBuf->buf = inStr;

    /* fill buffer in buf_msp */
    fillBufLenInMsParam( buf_msp, outBuf->len, outBuf );

    return 0;
}
Пример #15
0
/**
 * Hello world example.
 *
 * @param[in]		name		the name of a person 
 * @param[out]		outParam	the output hello message
 * @param[in,out]	rei		the rule execution information
 * @return				the status code, 0 on success
 */
int
msiHello( msParam_t *name, msParam_t *outParam,
	ruleExecInfo_t *rei )
{
    char *tmpPtr;
    char outStr[MAX_NAME_LEN];

    RE_TEST_MACRO( "    Calling msiHello" );

    tmpPtr = parseMspForStr (name);

    if (tmpPtr == NULL)  {
	rodsLog (LOG_ERROR, "msiHello: missing name input");
	rei->status = USER__NULL_INPUT_ERR;
	return USER__NULL_INPUT_ERR;
    }

    snprintf (outStr, MAX_NAME_LEN, "Hello world from %s", tmpPtr);
    
    fillStrInMsParam (outParam, outStr);

    rei->status = 0;
    return 0;
}
Пример #16
0
/**
 * \fn msiPrintGenQueryOutToBuffer(msParam_t *queryOut, msParam_t *format, msParam_t *buffer, ruleExecInfo_t *rei)
 *
 * \brief  Writes the contents of a GenQueryOut_MS_T into a BUF_LEN_MS_T.
 *
 * \module core
 *
 * \author  Antoine de Torcy
 * \date    2009-12-16
 *
 * \note This microservice writes the contents of a GenQueryOut_MS_T into a BUF_LEN_MS_T.
 *       The results can be formatted with an optional C-style format string the same way it is done in iquest.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] queryOut - Required - A GenQueryOut_MS_T.
 * \param[in] format - Optional - A STR_MS_T with a C-style format string, like in iquest.
 * \param[out] buffer - A BUF_LEN_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
msiPrintGenQueryOutToBuffer( msParam_t *queryOut, msParam_t *format, msParam_t *buffer, ruleExecInfo_t *rei ) {
    genQueryOut_t *genQueryOut;
    char *format_str;
    bytesBuf_t *bytesBuf;
    FILE *stream;
    char readbuffer[MAX_NAME_LEN];

    /*************************************  INIT **********************************/

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

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


    /********************************** PARAM PARSING  *********************************/

    /* Check for proper param type */
    if ( !queryOut || !queryOut->inOutStruct || !queryOut->type || strcmp( queryOut->type, GenQueryOut_MS_T ) ) {
        rodsLog( LOG_ERROR, "msiPrintGenQueryOutToBuffer: Invalid input for queryOut." );
        return( USER_PARAM_TYPE_ERR );
    }
    genQueryOut = ( genQueryOut_t * )queryOut->inOutStruct;


    /* Parse format */
    format_str = parseMspForStr( format );


    /********************************** EXTRACT SQL RESULTS  *********************************/

    /* Let's use printGenQueryOut() here for the sake of consistency over efficiency (somewhat). It needs a stream. */
    stream = tmpfile();
    if ( !stream ) { /* Since it won't be caught by printGenQueryOut */
        rodsLog( LOG_ERROR, "msiPrintGenQueryOutToBuffer: tmpfile() failed." );
        return( FILE_OPEN_ERR ); /* accurate enough */
    }

    /* Write results to temp file */
    rei->status = printGenQueryOut( stream, format_str, NULL, genQueryOut );
    if ( rei->status < 0 ) {
        rodsLog( LOG_ERROR, "msiPrintGenQueryOutToBuffer: printGenQueryOut() failed, status = %d", rei->status );
        return( rei->status );
    }

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

    /* Read from temp file and write to bytesBuf */
    rewind( stream );
    while ( fgets( readbuffer, MAX_NAME_LEN, stream ) != NULL ) {
        appendToByteBuf( bytesBuf, readbuffer );
    }


    /********************************* RETURN AND DONE **********************************/

    /* Free memory previously allocated for previous result batches (when used in loop). */
    if ( buffer && buffer->inpOutBuf ) {
        freeBBuf( buffer->inpOutBuf );
    }
    resetMsParam( buffer );

    /* Fill bytesBuf in our buffer output */
    fillBufLenInMsParam( buffer, bytesBuf->len, bytesBuf );

    return 0;

}
Пример #17
0
/**
 * \fn msiDboExec(msParam_t *dbrName, msParam_t *dboName, msParam_t *dborName,
 *      msParam_t *options,
 *      msParam_t *inpParam1, msParam_t *inpParam2, 
 *      msParam_t *inpParam3, msParam_t *inpParam4, 
 *      msParam_t *inpParam5, msParam_t *inpParam6, 
 *      ruleExecInfo_t *rei)
 *
 * \brief Execute a database object on a DBR
 *
 * \module core
 *
 * \since 2.5
 *
 * \author Wayne Schroeder
 * \date   2010-11-23
 *
 * \usage See clients/icommands/test/rules3.0/ and https://www.irods.org/index.php/DBR
 *
 * \param[in] dbrName - a STR_MS_T, name of the DBR being used
 * \param[in] dboName - a STR_MS_T, name of the DBO being used
 * \param[in] dborName - a STR_MS_T, name of the DBOR being used
 * \param[in] options - a STR_MS_T, currently 'force' or not
 * \param[in] inpParam1 - Optional - STR_MS_T parameters to the DBO SQL.
 * \param[in] inpParam2 - Optional - STR_MS_T parameters to the DBO SQL.
 * \param[in] inpParam3 - Optional - STR_MS_T parameters to the DBO SQL.
 * \param[in] inpParam4 - Optional - STR_MS_T parameters to the DBO SQL.
 * \param[in] inpParam5 - Optional - STR_MS_T parameters to the DBO SQL.
 * \param[in] inpParam6 - Optional - STR_MS_T parameters to the DBO SQL.
 * \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
msiDboExec(msParam_t *dbrName, msParam_t *dboName, msParam_t *dborName,
	   msParam_t *options,
	   msParam_t *inpParam1, msParam_t *inpParam2, 
	   msParam_t *inpParam3, msParam_t *inpParam4, 
	   msParam_t *inpParam5, msParam_t *inpParam6, 
	   ruleExecInfo_t *rei) {
    rsComm_t *rsComm; 
    char *myDbrName;
    char *myDboName;
    char *myDborName;
    char *myOptions;
    char *p1;
    char *p2;
    char *p3;
    char *p4;
    char *p5;
    char *p6;
    databaseObjControlInp_t databaseObjControlInp;
    databaseObjControlOut_t *databaseObjControlOut;
    int status;

    RE_TEST_MACRO ("    Calling msiDboExec")

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

    myDbrName = parseMspForStr(dbrName);
    if (myDbrName == NULL) {
	rodsLogAndErrorMsg (LOG_ERROR, &rsComm->rError, rei->status,
          "msiDboExec: input dbrName is NULL");
        return (USER__NULL_INPUT_ERR);
    }

    myDboName = parseMspForStr(dboName);
    if (myDboName == NULL) {
	rodsLogAndErrorMsg (LOG_ERROR, &rsComm->rError, rei->status,
          "msiDboExec: input dboName is NULL");
        return (USER__NULL_INPUT_ERR);
    }


    myDborName = parseMspForStr(dborName);
    if (myDborName == NULL) {
	rodsLogAndErrorMsg (LOG_ERROR, &rsComm->rError, rei->status,
          "msiDboExec: input dborName is NULL");
        return (USER__NULL_INPUT_ERR);
    }

    myOptions = parseMspForStr(options);

    p1 = parseMspForStr(inpParam1);
    p2 = parseMspForStr(inpParam2);
    p3 = parseMspForStr(inpParam3);
    p4 = parseMspForStr(inpParam4);
    p5 = parseMspForStr(inpParam5);
    p6 = parseMspForStr(inpParam6);

    if (rei->status < 0) {
        rodsLogAndErrorMsg (LOG_ERROR, &rsComm->rError, rei->status,
          "msiDboExec: input inpParam error. status = %d", rei->status);
        return (rei->status);
    }

    memset((void *)&databaseObjControlInp, 0, sizeof(databaseObjControlInp));

    databaseObjControlInp.option = DBO_EXECUTE;

    databaseObjControlInp.dbrName = myDbrName;
    databaseObjControlInp.dboName = myDboName;
    databaseObjControlInp.dborName = myDborName;

    if (strcmp(myOptions, "force")==0) {
       databaseObjControlInp.subOption = 1;
    }

    databaseObjControlInp.args[0] = p1;
    databaseObjControlInp.args[1] = p2;
    databaseObjControlInp.args[2] = p3;
    databaseObjControlInp.args[3] = p4;
    databaseObjControlInp.args[4] = p5;
    databaseObjControlInp.args[5] = p6;

    status = rsDatabaseObjControl(rsComm, &databaseObjControlInp, 
				  &databaseObjControlOut);
    if (status) {
       return(status);
    }
    if (*databaseObjControlOut->outBuf != '\0') {
       int stat2;
       stat2 = _writeString("stdout",databaseObjControlOut->outBuf,rei);
    }

    return(status);
}
Пример #18
0
/**
 * \fn writeKeyValPairs(msParam_t *where, msParam_t *inKVPair, msParam_t *separator, ruleExecInfo_t *rei)
 *
 * \brief  This microservice writes keyword value pairs to stdout or stderr, using the given separator.
 *
 * \module core
 *
 * \since 2.1
 *
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] where - a msParam of type STR_MS_T which is the buffer name in ruleExecOut. It can be stdout or stderr.
 * \param[in] inKVPair - a msParam of type KeyValPair_MS_T
 * \param[in] separator - Optional - a msParam of type STR_MS_T, the desired parameter
 * \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 writeKeyValPairs( msParam_t *where, msParam_t *inKVPair, msParam_t *separator, ruleExecInfo_t *rei ) {
    keyValPair_t *KVPairs;
    char *writeId;
    char *writeStr;
    char *sepStr;
    int i;
    size_t size;


    RE_TEST_MACRO( "    Calling writeKeyValPairs" )


    /* sanity checks */
    if ( !rei ) {
        rodsLog( LOG_ERROR, "writeKeyValPairs: input rei is NULL." );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }

    if ( !where ) {
        rodsLog( LOG_ERROR, "writeKeyValPairs: No destination provided for writing." );
        return USER__NULL_INPUT_ERR;
    }

    /* empty? */
    if ( !inKVPair || !inKVPair->inOutStruct ) {
        return 0;
    }

    /* check for proper input type and get keyValPair input */
    if ( inKVPair->type && strcmp( inKVPair->type, KeyValPair_MS_T ) ) {
        rodsLog( LOG_ERROR, "writeKeyValPairs: input parameter is not of KeyValPair_MS_T type." );
        return USER_PARAM_TYPE_ERR;
    }
    KVPairs = ( keyValPair_t * )inKVPair->inOutStruct;


    /* where are we writing to? */
    if ( where->inOutStruct != NULL ) {
        writeId = ( char* )where->inOutStruct;
    }
    else {
        writeId = where->label;
    }


    /* get separator string or use default */
    if ( ( sepStr = parseMspForStr( separator ) ) == NULL )  {
        sepStr = "\t|\t";
    }


    /* find out how much memory is needed for writeStr */
    size = 0;
    for ( i = 0; i < KVPairs->len; i++ ) {
        size += strlen( KVPairs->keyWord[i] ) + strlen( sepStr ) + strlen( KVPairs->value[i] ) + strlen( "\n" );
    }

    /* allocate memory for writeStr and pad with null chars */
    writeStr = ( char * )malloc( size + MAX_COND_LEN );
    memset( writeStr, '\0', size + MAX_COND_LEN );


    /* print each key-value pair to writeStr */
    for ( i = 0; i < KVPairs->len; i++ )  {
        strcat( writeStr, KVPairs->keyWord[i] );
        strcat( writeStr, sepStr );
        strcat( writeStr, KVPairs->value[i] );
        strcat( writeStr, "\n" );
    }


    /* call _writeString() routine */
    rei->status = _writeString( writeId, writeStr, rei );


    /* free writeStr since its content has been copied somewhere else */
    if ( writeStr != NULL ) {
        free( writeStr );
    }

    return rei->status;
}
Пример #19
0
/**
 * \fn msiSetQuota(msParam_t *type, msParam_t *name, msParam_t *resource, msParam_t *value, ruleExecInfo_t *rei)
 *
 * \brief Sets disk usage quota for a user or group
 *
 * \module core
 *
 * \since 3.0.x
 *
 * \author  Antoine de Torcy
 * \date    2011-07-07
 *
 *
 * \note  This microservice sets a disk usage quota for a given user or group.
 *          If no resource name is provided the quota will apply across all resources.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] type - a STR_MS_T - Can be either "user" or "group"
 * \param[in] name - a STR_MS_T with the name of the user or group
 * \param[in] resource - Optional - a STR_MS_T with the name of the resource where
 *      the quota will apply, or "total" for the quota to be system-wide.
 * \param[in] value - an INT_MST_T or DOUBLE_MS_T or STR_MS_T with the quota (in bytes)
 * \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 rei->uoic->authInfo.authFlag must be >= 5 (local admin)
 * \DolVarModified None
 * \iCatAttrDependence None
 * \iCatAttrModified Updates r_quota_main
 * \sideeffect None
 *
 * \return integer
 * \retval 0 on success
 * \pre None
 * \post None
 * \sa None
 **/
int
msiSetQuota( msParam_t *type, msParam_t *name, msParam_t *resource, msParam_t *value, ruleExecInfo_t *rei ) {
    generalAdminInp_t generalAdminInp;              /* Input for rsGeneralAdmin */
    char quota[21];
    int status;


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

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


    /* Must be called from an admin account */
    if ( rei->uoic->authInfo.authFlag < LOCAL_PRIV_USER_AUTH ) {
        status = CAT_INSUFFICIENT_PRIVILEGE_LEVEL;
        rodsLog( LOG_ERROR, "msiSetQuota: User %s is not local admin. Status = %d",
                 rei->uoic->userName, status );
        return ( status );
    }


    /* Prepare generalAdminInp. It needs to be set up as follows:
     *    generalAdminInp.arg0: "set-quota"
     *    generalAdminInp.arg1: type ("user" or "group")
     *    generalAdminInp.arg2: name of user/group
     *    generalAdminInp.arg3: resource name or "total"
     *    generalAdminInp.arg4: quota value
     *    generalAdminInp.arg5: ""
     *    generalAdminInp.arg6: ""
     *    generalAdminInp.arg7: ""
     *    generalAdminInp.arg8: ""
     *    generalAdminInp.arg9: ""
     */
    memset( &generalAdminInp, 0, sizeof( generalAdminInp_t ) );
    generalAdminInp.arg0 = "set-quota";

    /* Parse type */
    generalAdminInp.arg1 = parseMspForStr( type );
    if ( strcmp( generalAdminInp.arg1, "user" ) && strcmp( generalAdminInp.arg1, "group" ) ) {
        status = USER_BAD_KEYWORD_ERR;
        rodsLog( LOG_ERROR, "msiSetQuota: Invalid user type: %s. Valid types are \"user\" and \"group\"",
                 generalAdminInp.arg1 );
        return ( status );
    }

    /* Parse user/group name */
    generalAdminInp.arg2 = parseMspForStr( name );

    /* parse resource name */
    if ( ( generalAdminInp.arg3 = parseMspForStr( resource ) ) == NULL ) {
        generalAdminInp.arg3 = "total";
    }

    /* Parse value */
    if ( value->type && !strcmp( value->type, STR_MS_T ) ) {
        generalAdminInp.arg4 = ( char * )value->inOutStruct;
    }
    else if ( value->type && !strcmp( value->type, INT_MS_T ) ) {
        snprintf( quota, 11, "%d", *( int * )value->inOutStruct );
        generalAdminInp.arg4 = quota;
    }
    else if ( value->type && !strcmp( value->type, DOUBLE_MS_T ) ) {
        snprintf( quota, 21, "%lld", *( rodsLong_t * )value->inOutStruct );
        generalAdminInp.arg4 = quota;
    }
    else {
        status = USER_PARAM_TYPE_ERR;
        rodsLog( LOG_ERROR, "msiSetQuota: Invalid type for param value. Status = %d", status );
        return ( status );
    }

    /* Fill up the rest of generalAdminInp */
    generalAdminInp.arg5 = "";
    generalAdminInp.arg6 = "";
    generalAdminInp.arg7 = "";
    generalAdminInp.arg8 = "";
    generalAdminInp.arg9 = "";


    /* Call rsGeneralAdmin */
    status = rsGeneralAdmin( rei->rsComm, &generalAdminInp );


    /* Done */
    return status;
}
Пример #20
0
/**
 * \fn msiAddConditionToGenQuery(msParam_t *attribute, msParam_t *opr, msParam_t *value, msParam_t *queryInput, ruleExecInfo_t *rei)
 *
 * \brief Adds a condition to a genQueryInp_t
 *
 * \module core
 *
 * \author  Antoine de Torcy
 * \date    2009-12-07
 *
 * \note This microservice adds a condition to an existing genQueryInp_t, from three parameters.
 *       One is an iCAT attribute index given without its 'COL_' prefix.
 *       The second one is the SQL operator. The third one is the value and may contain wildcards.
 *       To be used with #msiAddSelectFieldToGenQuery and #msiExecGenQuery to build queries from the
 *       results of other microservices or actions within an iRODS rule.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] attribute - Required - A STR_MS_T with the iCAT attribute name (see wiki.irods.org/index.php/icatAttributes).
 * \param[in] opr - Required - A STR_MS_T with the operator.
 * \param[in] value - Required - A STR_MS_T with the value.
 * \param[in,out] queryInput - Required - A GenQueryInp_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
msiAddConditionToGenQuery( msParam_t *attribute, msParam_t *opr, msParam_t *value, msParam_t *queryInput, ruleExecInfo_t *rei ) {
    genQueryInp_t *genQueryInp;
    char condStr[MAX_NAME_LEN];
    char *att_str, *op_str, *val_str;
    int att_inx;

    /*************************************  INIT **********************************/

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

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


    /********************************** PARAM PARSING  *********************************/

    /* Parse attribute */
    if ( ( att_str = parseMspForStr( attribute ) ) == NULL ) {
        rodsLog( LOG_ERROR, "msiAddConditionToGenQuery: input attribute is NULL." );
        return ( USER__NULL_INPUT_ERR );
    }

    /* Parse operator */
    if ( ( op_str = parseMspForStr( opr ) ) == NULL ) {
        rodsLog( LOG_ERROR, "msiAddConditionToGenQuery: input opr is NULL." );
        return ( USER__NULL_INPUT_ERR );
    }

    /* Parse value */
    if ( ( val_str = parseMspForStr( value ) ) == NULL ) {
        rodsLog( LOG_ERROR, "msiAddConditionToGenQuery: input value is NULL." );
        return ( USER__NULL_INPUT_ERR );
    }

    /* Check for proper parameter type for queryInput */
    if ( queryInput->type && strcmp( queryInput->type, GenQueryInp_MS_T ) ) {
        rodsLog( LOG_ERROR, "msiAddConditionToGenQuery: queryInput is not of type GenQueryInp_MS_T." );
        return ( USER_PARAM_TYPE_ERR );
    }

    /* Parse queryInput. Must not be empty. */
    if ( !queryInput->inOutStruct ) {
        rodsLog( LOG_ERROR, "msiAddConditionToGenQuery: input queryInput is NULL." );
        return ( USER__NULL_INPUT_ERR );
    }
    else {
        genQueryInp = ( genQueryInp_t* )queryInput->inOutStruct;
    }


    /***************************** ADD CONDITION TO QUERY INPUT  *****************************/

    /* Get attribute index */
    att_inx = getAttrIdFromAttrName( att_str );

    /* Error? */
    if ( att_inx < 0 ) {
        rodsLog( LOG_ERROR, "msiAddConditionToGenQuery: Unable to get valid ICAT column index." );
        return( att_inx );
    }

    /* Make the condition */
    snprintf( condStr, MAX_NAME_LEN, " %s '%s'", op_str, val_str );

    /* Add condition to genQueryInput */
    addInxVal( &genQueryInp->sqlCondInp, att_inx, condStr );  /* condStr gets strdup'ed */


    /*********************************** DONE *********************************************/
    return 0;
}
Пример #21
0
/**
 * \fn msiMakeGenQuery(msParam_t* selectListStr, msParam_t* condStr, msParam_t* genQueryInpParam, ruleExecInfo_t *rei)
 *
 * \brief This microservice sets up a GenQueryInp_MS_T from a list of parameters and conditions
 *
 * \module core
 *
 * \since pre-2.1
 *
 * \author  Antoine de Torcy
 * \date    2008-09-19
 *
 * \note This microservice sets up a genQueryInp_t data structure needed by calls to rsGenQuery().
 *    To be used before #msiExecGenQuery and #msiGetMoreRows.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] selectListStr - Required - a STR_MS_T containing the parameters.
 * \param[in] condStr - Required - a STR_MS_T containing the conditions
 * \param[out] genQueryInpParam - a GenQueryInp_MS_T containing the parameters and conditions.
 * \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
msiMakeGenQuery( msParam_t* selectListStr, msParam_t* condStr, msParam_t* genQueryInpParam, ruleExecInfo_t *rei ) {
    genQueryInp_t *genQueryInp;
    char *sel, *cond, *rawQuery, *query;


    RE_TEST_MACRO( "    Calling msiMakeGenQuery" )

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


    /* parse selectListStr */
    if ( ( sel = parseMspForStr( selectListStr ) ) == NULL ) {
        rodsLog( LOG_ERROR, "msiMakeGenQuery: input selectListStr is NULL." );
        return ( USER__NULL_INPUT_ERR );
    }


    /* parse condStr */
    if ( ( cond = parseMspForStr( condStr ) ) == NULL ) {
        rodsLog( LOG_ERROR, "msiMakeGenQuery: input condStr is NULL." );
        return ( USER__NULL_INPUT_ERR );
    }


    /* The code below is partly taken from msiMakeQuery and msiExecStrCondQuery. There may be a better way to do this. */

    /* Generate raw SQL query string */
    rei->status = _makeQuery( sel, cond, &rawQuery );

    /* allocate more memory for query string with expanded variable names */
    query = ( char * )malloc( strlen( rawQuery ) + 10 + MAX_COND_LEN * 8 );
    strcpy( query, rawQuery );

    /* allocate memory for genQueryInp */
    genQueryInp = ( genQueryInp_t* )malloc( sizeof( genQueryInp_t ) );
    memset( genQueryInp, 0, sizeof( genQueryInp_t ) );

    /* set up GenQueryInp */
    genQueryInp->maxRows = MAX_SQL_ROWS;
    genQueryInp->continueInx = 0;
    rei->status = fillGenQueryInpFromStrCond( query, genQueryInp );
    if ( rei->status < 0 ) {
        rodsLog( LOG_ERROR, "msiMakeGenQuery: fillGenQueryInpFromStrCond failed." );
        free( rawQuery ); // cppcheck - Memory leak: rawQuery
        return( rei->status );
    }


    /* return genQueryInp through GenQueryInpParam */
    genQueryInpParam->type = strdup( GenQueryInp_MS_T );
    genQueryInpParam->inOutStruct = genQueryInp;


    /* cleanup */
    free( rawQuery );
    free( query );

    return( rei->status );
}
Пример #22
0
/**
 * \fn msiAddSelectFieldToGenQuery(msParam_t *select, msParam_t *function, msParam_t *queryInput, ruleExecInfo_t *rei)
 *
 * \brief  Sets a select field in a genQueryInp_t
 *
 * \module core
 *
 *
 * \author  Antoine de Torcy
 * \date    2009-11-28
 *
 * \note This microservice sets a select field in a genQueryInp_t, from two parameters.
 *       One is an iCAT attribute index given without its 'COL_' prefix.
 *       The second one is the optional SQL operator.
 *       A new genQueryInp_t is created if queryInput is NULL.
 *       Followed with #msiExecGenQuery, #msiAddSelectFieldToGenQuery allows to take the
 *       results of other microservices to build and execute queries within a rule.
 *
 * \usage See clients/icommands/test/rules3.0/
 *
 * \param[in] select - Required - A STR_MS_T with the select field.
 * \param[in] function - Optional - A STR_MS_T with the function. Valid values are [MIN|MAX|SUM|AVG|COUNT]
 * \param[in,out] queryInput - Optional - A GenQueryInp_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
msiAddSelectFieldToGenQuery( msParam_t *select, msParam_t *function, msParam_t *queryInput, ruleExecInfo_t *rei ) {
    char *column_str;
    int column_inx, function_inx;
    genQueryInp_t *genQueryInp;

    /*************************************  INIT **********************************/

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

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


    /********************************** PARAM PARSING  *********************************/

    /* Parse select */
    if ( ( column_str = parseMspForStr( select ) ) == NULL ) {
        rodsLog( LOG_ERROR, "msiAddSelectFieldToGenQuery: input select is NULL." );
        return ( USER__NULL_INPUT_ERR );
    }

    /* Parse function and convert to index directly, getSelVal() returns 1 if string is NULL or empty. */
    function_inx = getSelVal( parseMspForStr( function ) );

    /* Check for proper parameter type for queryInput */
    if ( queryInput->type && strcmp( queryInput->type, GenQueryInp_MS_T ) ) {
        rodsLog( LOG_ERROR, "msiAddSelectfieldToGenQuery: queryInput is not of type GenQueryInp_MS_T." );
        return ( USER_PARAM_TYPE_ERR );
    }

    /* Parse queryInput. Create new structure if empty. */
    if ( !queryInput->inOutStruct ) {
        /* Set content */
        genQueryInp = ( genQueryInp_t* )malloc( sizeof( genQueryInp_t ) );
        memset( genQueryInp, 0, sizeof( genQueryInp_t ) );
        genQueryInp->maxRows = MAX_SQL_ROWS;
        queryInput->inOutStruct = ( void* )genQueryInp;

        /* Set type */
        if ( !queryInput->type ) {
            queryInput->type = strdup( GenQueryInp_MS_T );
        }
    }
    else {
        genQueryInp = ( genQueryInp_t* )queryInput->inOutStruct;
    }


    /***************************** ADD INDEXES TO QUERY INPUT  *****************************/

    /* Get column index */
    column_inx = getAttrIdFromAttrName( column_str );

    /* Error? */
    if ( column_inx < 0 ) {
        rodsLog( LOG_ERROR, "msiAddSelectfieldToGenQuery: Unable to get valid ICAT column index." );
        return( column_inx );
    }

    /* Add column and function to genQueryInput */
    addInxIval( &genQueryInp->selectInp, column_inx, function_inx );


    /*********************************** DONE *********************************************/
    return 0;
}