/** * \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 ); }
/** * \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; }
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; }
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; }
/** * 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; }
/** * \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); }
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; }
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); }
/* * 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; }
/** * \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); }
/** * \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; }
/** * \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; }
/** * 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; }
/** * \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; }
/** * \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); }
/** * \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; }
/** * \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; }
/** * \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; }
/** * \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 ); }
/** * \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; }