/// =-=-=-=-=-=-=- /// @brief function which sends the negotiation message error send_client_server_negotiation_message( irods::network_object_ptr _ptr, cs_neg_t& _cs_neg_msg ) { // =-=-=-=-=-=-=- // pack the negotiation message bytesBuf_t* cs_neg_buf = 0; int status = packStruct( &_cs_neg_msg, &cs_neg_buf, "CS_NEG_PI", RodsPackTable, 0, XML_PROT ); if ( status < 0 ) { return ERROR( status, "failed to pack client-server message" ); } // =-=-=-=-=-=-=- // pack the negotiation message irods::error ret = sendRodsMsg( _ptr, RODS_CS_NEG_T, cs_neg_buf, 0, 0, 0, XML_PROT ); freeBBuf( cs_neg_buf ); if ( !ret.ok() ) { return PASSMSG( "failed to send client-server negotiation message", ret ); } return SUCCESS(); } // send_client_server_negotiation_message
// =-=-=-=-=-=-=- // irods::error writeMsgHeader( irods::network_object_ptr _ptr, msgHeader_t* _header ) { // =-=-=-=-=-=-=- // always use XML_PROT for the Header bytesBuf_t* header_buf = 0; int status = packStruct( static_cast<void *>( _header ), &header_buf, "MsgHeader_PI", RodsPackTable, 0, XML_PROT ); if ( status < 0 || 0 == header_buf ) { return ERROR( status, "packstruct error" ); } // =-=-=-=-=-=-=- // resolve a network interface plugin from the // network object irods::plugin_ptr p_ptr; irods::error ret = _ptr->resolve( irods::NETWORK_INTERFACE, p_ptr ); if ( !ret.ok() ) { freeBBuf( header_buf ); return PASSMSG( "failed to resolve network interface", ret ); } // =-=-=-=-=-=-=- // make the call to the plugin interface irods::first_class_object_ptr ptr = boost::dynamic_pointer_cast< irods::first_class_object >( _ptr ); irods::network_ptr net = boost::dynamic_pointer_cast< irods::network >( p_ptr ); ret = net->call< bytesBuf_t* >( irods::NETWORK_OP_WRITE_HEADER, ptr, header_buf ); freeBBuf( header_buf ); if ( !ret.ok() ) { return PASS( ret ); } return SUCCESS(); } // writeMsgHeader
irods::error sendVersion( irods::network_object_ptr _ptr, int versionStatus, int reconnPort, char* reconnAddr, int cookie ) { version_t myVersion; int status; bytesBuf_t *versionBBuf = NULL; /* setup the version struct */ memset( &myVersion, 0, sizeof( myVersion ) ); myVersion.status = versionStatus; rstrcpy( myVersion.relVersion, RODS_REL_VERSION, NAME_LEN ); rstrcpy( myVersion.apiVersion, RODS_API_VERSION, NAME_LEN ); if ( reconnAddr != NULL ) { myVersion.reconnPort = reconnPort; rstrcpy( myVersion.reconnAddr, reconnAddr, LONG_NAME_LEN ); myVersion.cookie = cookie; } else { // =-=-=-=-=-=-=- // super secret jargon irods detection // sshhhhhhh... myVersion.cookie = 400; } /* alway use XML for version */ status = packStruct( ( char * ) &myVersion, &versionBBuf, "Version_PI", RodsPackTable, 0, XML_PROT ); if ( status < 0 ) { return ERROR( status, "packStruct error" ); } irods::error ret = sendRodsMsg( _ptr, RODS_VERSION_T, versionBBuf, NULL, NULL, 0, XML_PROT ); freeBBuf( versionBBuf ); if ( !ret.ok() ) { return PASS( ret ); } return SUCCESS(); } // sendVersion
// =-=-=-=-=-=-=- // interface for requesting a reconnection irods::error sendReconnMsg( irods::network_object_ptr _ptr, reconnMsg_t* _msg ) { // =-=-=-=-=-=-=- // trap invalid param if ( _msg == NULL ) { return ERROR( USER__NULL_INPUT_ERR, "null msg buf" ); } // =-=-=-=-=-=-=- // pack outgoing message - alway use XML for version bytesBuf_t* recon_buf = NULL; int status = packStruct( static_cast<void*>( _msg ), &recon_buf, "ReconnMsg_PI", RodsPackTable, 0, XML_PROT ); if ( status < 0 ) { return ERROR( status, "failed to pack struct" ); } // =-=-=-=-=-=-=- // pack outgoing message - alway use XML for version irods::error ret = sendRodsMsg( _ptr, RODS_RECONNECT_T, recon_buf, NULL, NULL, 0, XML_PROT ); freeBBuf( recon_buf ); if ( !ret.ok() ) { rodsLogError( LOG_ERROR, status, "sendReconnMsg: sendRodsMsg of reconnect msg failed, status = %d", status ); } return CODE( status ); } // sendReconnMsg
int sendApiReply( rsComm_t * rsComm, int apiInx, int retVal, void * myOutStruct, bytesBuf_t * myOutBsBBuf ) { int status = 0; bytesBuf_t *outStructBBuf = NULL; bytesBuf_t *myOutStructBBuf; bytesBuf_t *rErrorBBuf = NULL; bytesBuf_t *myRErrorBBuf; //#ifndef windows_platform svrChkReconnAtSendStart( rsComm ); //#endif if ( retVal == SYS_HANDLER_DONE_NO_ERROR ) { /* not actually an error */ retVal = 0; } // =-=-=-=-=-=-=- // create a network object irods::network_object_ptr net_obj; irods::error ret = irods::network_factory( rsComm, net_obj ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); return ret.code(); } irods::api_entry_table& RsApiTable = irods::get_server_api_table(); if ( RsApiTable[apiInx]->outPackInstruct != NULL && myOutStruct != NULL ) { status = packStruct( ( char * ) myOutStruct, &outStructBBuf, ( char* )RsApiTable[apiInx]->outPackInstruct, RodsPackTable, FREE_POINTER, rsComm->irodsProt ); if ( status < 0 ) { rodsLog( LOG_NOTICE, "sendApiReply: packStruct error, status = %d", status ); sendRodsMsg( net_obj, RODS_API_REPLY_T, NULL, NULL, NULL, status, rsComm->irodsProt ); svrChkReconnAtSendEnd( rsComm ); return status; } myOutStructBBuf = outStructBBuf; } else { myOutStructBBuf = NULL; } if ( RsApiTable[apiInx]->outBsFlag == 0 ) { myOutBsBBuf = NULL; } if ( rsComm->rError.len > 0 ) { status = packStruct( ( char * ) &rsComm->rError, &rErrorBBuf, "RError_PI", RodsPackTable, 0, rsComm->irodsProt ); if ( status < 0 ) { rodsLog( LOG_NOTICE, "sendApiReply: packStruct error, status = %d", status ); sendRodsMsg( net_obj, RODS_API_REPLY_T, NULL, NULL, NULL, status, rsComm->irodsProt ); svrChkReconnAtSendEnd( rsComm ); freeBBuf( outStructBBuf ); freeBBuf( rErrorBBuf ); return status; } myRErrorBBuf = rErrorBBuf; } else { myRErrorBBuf = NULL; } ret = sendRodsMsg( net_obj, RODS_API_REPLY_T, myOutStructBBuf, myOutBsBBuf, myRErrorBBuf, retVal, rsComm->irodsProt ); if ( !ret.ok() ) { int status1; irods::log( PASS( ret ) ); if ( rsComm->reconnSock > 0 ) { int savedStatus = ret.code(); boost::unique_lock< boost::mutex > boost_lock( *rsComm->thread_ctx->lock ); rodsLog( LOG_DEBUG, "sendApiReply: svrSwitchConnect. cliState = %d,agState=%d", rsComm->clientState, rsComm->agentState ); status1 = svrSwitchConnect( rsComm ); boost_lock.unlock(); if ( status1 > 0 ) { /* should not be here */ rodsLog( LOG_NOTICE, "sendApiReply: Switch connection and retry sendRodsMsg" ); ret = sendRodsMsg( net_obj, RODS_API_REPLY_T, myOutStructBBuf, myOutBsBBuf, myRErrorBBuf, retVal, rsComm->irodsProt ); if ( ret.code() >= 0 ) { rodsLog( LOG_NOTICE, "sendApiReply: retry sendRodsMsg succeeded" ); } else { status = savedStatus; } } } } svrChkReconnAtSendEnd( rsComm ); freeBBuf( outStructBBuf ); freeBBuf( rErrorBBuf ); return status; }
int sendStartupPack( rcComm_t *conn, int connectCnt, int reconnFlag ) { startupPack_t startupPack; int status; char *tmpStr; bytesBuf_t *startupPackBBuf = NULL; /* setup the startup pack */ startupPack.irodsProt = conn->irodsProt; startupPack.connectCnt = connectCnt; startupPack.reconnFlag = reconnFlag; rstrcpy( startupPack.proxyUser, conn->proxyUser.userName, NAME_LEN ); rstrcpy( startupPack.proxyRodsZone, conn->proxyUser.rodsZone, NAME_LEN ); rstrcpy( startupPack.clientUser, conn->clientUser.userName, NAME_LEN ); rstrcpy( startupPack.clientRodsZone, conn->clientUser.rodsZone, NAME_LEN ); rstrcpy( startupPack.relVersion, RODS_REL_VERSION, NAME_LEN ); rstrcpy( startupPack.apiVersion, RODS_API_VERSION, NAME_LEN ); if ( ( tmpStr = getenv( SP_OPTION ) ) != NULL ) { rstrcpy( startupPack.option, tmpStr, NAME_LEN ); } else { startupPack.option[0] = '\0'; } // =-=-=-=-=-=-=- // if the advanced negotiation is requested from the irodsEnv, // tack those results onto the startup pack option string rodsEnv rods_env; status = getRodsEnv( &rods_env ); if ( status >= 0 && strlen( rods_env.rodsClientServerNegotiation ) > 0 ) { strncat( startupPack.option, rods_env.rodsClientServerNegotiation, strlen( rods_env.rodsClientServerNegotiation ) ); } /* always use XML_PROT for the startupPack */ status = packStruct( ( void * ) &startupPack, &startupPackBBuf, "StartupPack_PI", RodsPackTable, 0, XML_PROT ); if ( status < 0 ) { rodsLogError( LOG_NOTICE, status, "sendStartupPack: packStruct error, status = %d", status ); return status; } irods::network_object_ptr net_obj; irods::error ret = irods::network_factory( conn, net_obj ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); freeBBuf( startupPackBBuf ); return ret.code(); } ret = sendRodsMsg( net_obj, RODS_CONNECT_T, startupPackBBuf, NULL, NULL, 0, XML_PROT ); freeBBuf( startupPackBBuf ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); return ret.code(); } return ret.code(); } // sendStartupPack
/** * \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; }
int _rsClientHints( rsComm_t* _comm, bytesBuf_t** _bbuf ) { if ( !_comm || !_bbuf ) { rodsLog( LOG_ERROR, "_rsServerReport: null comm or bbuf" ); return SYS_INVALID_INPUT_PARAM; } ( *_bbuf ) = ( bytesBuf_t* ) malloc( sizeof( bytesBuf_t ) ); if ( !( *_bbuf ) ) { rodsLog( LOG_ERROR, "_rsClientHints: failed to allocate _bbuf" ); return SYS_MALLOC_ERR; } bytesBuf_t* ies_buf = 0; int status = rsIESClientHints( _comm, &ies_buf ); if( status < 0 ) { rodsLog( LOG_ERROR, "_rsClientHints: rsIESClientHints failed %d", status ); return status; } json_error_t j_err; json_t* client_hints = json_loads( ( char* )ies_buf->buf, ies_buf->len, &j_err ); freeBBuf( ies_buf ); if ( !client_hints ) { rodsLog( LOG_ERROR, "_rsClientHints - json_loads failed [%s]", j_err.text ); return ACTION_FAILED_ERR; } std::string hash, hash_policy; irods::error ret = get_hash_and_policy( _comm, hash, hash_policy ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); } json_object_set( client_hints, "hash_scheme", json_string( hash.c_str() ) ); json_object_set( client_hints, "match_hash_policy", json_string( hash_policy.c_str() ) ); char* tmp_buf = json_dumps( client_hints, JSON_INDENT( 4 ) ); // *SHOULD* free All The Things... json_decref( client_hints ); ( *_bbuf )->buf = tmp_buf; ( *_bbuf )->len = strlen( tmp_buf ); return 0; } // _rsClientHints
int sendApiRequest( rcComm_t *conn, int apiInx, void *inputStruct, bytesBuf_t *inputBsBBuf ) { int status = 0; bytesBuf_t *inputStructBBuf = NULL; bytesBuf_t *myInputStructBBuf = NULL; cliChkReconnAtSendStart( conn ); irods::api_entry_table& RcApiTable = irods::get_client_api_table(); irods::api_entry_table::iterator itr = RcApiTable.find( apiInx ); if ( itr == RcApiTable.end() ) { rodsLogError( LOG_ERROR, SYS_UNMATCHED_API_NUM, "API Entry not found at index %d", apiInx ); return SYS_UNMATCHED_API_NUM; } if ( RcApiTable[apiInx]->inPackInstruct != NULL ) { if ( inputStruct == NULL ) { cliChkReconnAtSendEnd( conn ); return ( USER_API_INPUT_ERR ); } status = packStruct( ( void * ) inputStruct, &inputStructBBuf, ( char* )RcApiTable[apiInx]->inPackInstruct, RodsPackTable, 0, conn->irodsProt ); if ( status < 0 ) { rodsLogError( LOG_ERROR, status, "sendApiRequest: packStruct error, status = %d", status ); cliChkReconnAtSendEnd( conn ); return status; } myInputStructBBuf = inputStructBBuf; } else { myInputStructBBuf = NULL; }; if ( RcApiTable[apiInx]->inBsFlag <= 0 ) { inputBsBBuf = NULL; } irods::network_object_ptr net_obj; irods::error ret = irods::network_factory( conn, net_obj ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); return ret.code(); } ret = sendRodsMsg( net_obj, RODS_API_REQ_T, myInputStructBBuf, inputBsBBuf, NULL, RcApiTable[apiInx]->apiNumber, conn->irodsProt ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); if ( conn->svrVersion != NULL && conn->svrVersion->reconnPort > 0 ) { int status1; int savedStatus = ret.code() ; conn->thread_ctx->lock->lock(); status1 = cliSwitchConnect( conn ); rodsLog( LOG_DEBUG, "sendApiRequest: svrSwitchConnect. cliState = %d,agState=%d", conn->clientState, conn->agentState ); conn->thread_ctx->lock->unlock(); if ( status1 > 0 ) { /* should not be here */ rodsLog( LOG_NOTICE, "sendApiRequest: Switch connection and retry sendRodsMsg" ); ret = sendRodsMsg( net_obj, RODS_API_REQ_T, myInputStructBBuf, inputBsBBuf, NULL, RcApiTable[apiInx]->apiNumber, conn->irodsProt ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); } else { status = savedStatus; } } // if status1 > 0 } // if svrVersion != NULL ... } else { // =-=-=-=-=-=-=- // be sure to pass along the return code from the // plugin call status = ret.code(); } freeBBuf( inputStructBBuf ); return ( status ); }
static irods::error get_server_reports(rsComm_t* _comm, json& _resc_arr) { _resc_arr = json::array(); std::map< rodsServerHost_t*, int > svr_reported; rodsServerHost_t* icat_host = 0; char* zone_name = getLocalZoneName(); int status = getRcatHost( MASTER_RCAT, zone_name, &icat_host ); if ( status < 0 ) { return ERROR(status, "getRcatHost failed"); } for (irods::resource_manager::iterator itr = resc_mgr.begin(); itr != resc_mgr.end(); ++itr) { irods::resource_ptr resc = itr->second; rodsServerHost_t* tmp_host = 0; irods::error ret = resc->get_property< rodsServerHost_t* >( irods::RESOURCE_HOST, tmp_host ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); continue; } // skip the icat server as that is done separately // also skip null tmp_hosts resources ( coordinating ) // skip local host if ( !tmp_host || tmp_host == icat_host || LOCAL_HOST == tmp_host->localFlag ) { continue; } // skip previously reported servers std::map< rodsServerHost_t*, int >::iterator svr_itr = svr_reported.find( tmp_host ); if ( svr_itr != svr_reported.end() ) { continue; } std::string resc_name; ret = resc->get_property< std::string >( irods::RESOURCE_NAME, resc_name ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); continue; } svr_reported[ tmp_host ] = 1; int status = svrToSvrConnect( _comm, tmp_host ); if ( status < 0 ) { report_server_connect_error( status, tmp_host->hostName->name, resc_name, _resc_arr); continue; } bytesBuf_t* bbuf = NULL; status = rcServerReport( tmp_host->conn, &bbuf ); if ( status < 0 ) { freeBBuf( bbuf ); bbuf = NULL; rodsLog( LOG_ERROR, "rcServerReport failed for [%s], status = %d", tmp_host->hostName->name, status ); } // possible null termination issues std::string tmp_str = bbuf ? std::string((char*) bbuf->buf, bbuf->len) : std::string(); try { _resc_arr.push_back(json::parse(tmp_str)); freeBBuf(bbuf); } catch (const json::type_error& e) { std::string msg = "json_loads failed ["; msg += e.what(); msg += "]"; irods::log(ERROR(ACTION_FAILED_ERR, msg)); } } // for itr return SUCCESS(); } // get_server_reports
int _rsZoneReport(rsComm_t* _comm, bytesBuf_t** _bbuf) { bytesBuf_t* bbuf = 0; int status = rsServerReport(_comm, &bbuf); if ( status < 0 ) { freeBBuf(bbuf); rodsLog(LOG_ERROR, "_rsZoneReport - rsServerReport failed %d", status); return status; } json cat_svr; try { cat_svr = json::parse(std::string(static_cast<char*>(bbuf->buf), bbuf->len)); freeBBuf(bbuf); } catch (const json::type_error& e) { rodsLog(LOG_ERROR, "_rsZoneReport - json::parse failed [%s]", e.what()); return ACTION_FAILED_ERR; } json coord_resc; irods::error ret = get_coordinating_resources( _comm, coord_resc ); if ( !ret.ok() ) { rodsLog(LOG_ERROR, "_rsZoneReport - get_server_reports failed, status = %d", ret.code()); return ret.code(); } json svr_arr; ret = get_server_reports( _comm, svr_arr ); if ( !ret.ok() ) { rodsLog(LOG_ERROR, "_rsZoneReport - get_server_reports failed, status = %d", ret.code()); return ret.code(); } cat_svr["coordinating_resources"] = coord_resc; auto zone_obj = json::object(); zone_obj["servers"] = svr_arr; zone_obj["icat_server"] = cat_svr; auto zone_arr = json::array(); zone_arr.push_back(zone_obj); auto zone = json::object(); zone["schema_version"] = (boost::format("%s/%s/zone_bundle.json") % irods::get_server_property<const std::string>("schema_validation_base_uri") % irods::get_server_property<const std::string>("schema_version")).str(); zone["zones"] = zone_arr; const auto zr = zone.dump(4); char* tmp_buf = new char[zr.length() + 1]{}; std::strncpy(tmp_buf, zr.c_str(), zr.length()); *_bbuf = (bytesBuf_t*) malloc(sizeof(bytesBuf_t)); if (!*_bbuf) { delete [] tmp_buf; rodsLog( LOG_ERROR, "_rsZoneReport: failed to allocate _bbuf" ); return SYS_MALLOC_ERR; } (*_bbuf)->buf = tmp_buf; (*_bbuf)->len = zr.length(); return 0; } // _rsZoneReport