00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "rsApiHandler.h"
00011 #include "modDataObjMeta.h"
00012 #include "rcMisc.h"
00013 #include "miscServerFunct.h"
00014 #include "regReplica.h"
00015 #include "unregDataObj.h"
00016 #include "modAVUMetadata.h"
00017
00018 #include <boost/thread.hpp>
00019 #include <boost/thread/mutex.hpp>
00020 #include <boost/thread/condition.hpp>
00021 #include <setjmp.h>
00022 jmp_buf Jenv;
00023
00024
00025
00026 #include "eirods_network_factory.h"
00027
00028
00029 int rsApiHandler(
00030 rsComm_t* rsComm,
00031 int apiNumber,
00032 bytesBuf_t* inputStructBBuf,
00033 bytesBuf_t* bsBBuf ) {
00034 int apiInx;
00035 int status = 0;
00036 char *myInStruct = NULL;
00037 funcPtr myHandler = NULL;
00038 void *myOutStruct = NULL;
00039 bytesBuf_t myOutBsBBuf;
00040 int retVal = 0;
00041 int numArg = 0;
00042 void *myArgv[4];
00043
00044 memset( &myOutBsBBuf, 0, sizeof( bytesBuf_t ) );
00045 memset( &rsComm->rError, 0, sizeof( rError_t ) );
00046
00047 apiInx = apiTableLookup( apiNumber );
00048
00049
00050
00051 eirods::network_object_ptr net_obj;
00052 eirods::error ret = eirods::network_factory( rsComm, net_obj );
00053 if ( !ret.ok() ) {
00054 eirods::log( PASS( ret ) );
00055 return apiInx;
00056 }
00057
00058 if ( apiInx < 0 ) {
00059 rodsLog( LOG_ERROR,
00060 "rsApiHandler: apiTableLookup of apiNumber %d failed", apiNumber );
00061
00062 sendRodsMsg( net_obj, RODS_API_REPLY_T, NULL, NULL, NULL,
00063 apiInx, rsComm->irodsProt );
00064 return ( apiInx );
00065 }
00066
00067 rsComm->apiInx = apiInx;
00068
00069 status = chkApiVersion( rsComm, apiInx );
00070 if ( status < 0 ) {
00071 sendApiReply( rsComm, apiInx, status, myOutStruct, &myOutBsBBuf );
00072 return ( status );
00073 }
00074
00075 status = chkApiPermission( rsComm, apiInx );
00076 if ( status < 0 ) {
00077 rodsLog( LOG_NOTICE,
00078 "rsApiHandler: User has no permission for apiNumber %d", apiNumber );
00079 sendApiReply( rsComm, apiInx, status, myOutStruct, &myOutBsBBuf );
00080 return ( status );
00081 }
00082
00083
00084 if ( inputStructBBuf->len > 0 && RsApiTable[apiInx].inPackInstruct == NULL ) {
00085 rodsLog( LOG_NOTICE,
00086 "rsApiHandler: input struct error 1 for apiNumber %d", apiNumber );
00087 sendApiReply( rsComm, apiInx, SYS_API_INPUT_ERR, myOutStruct,
00088 &myOutBsBBuf );
00089 return ( SYS_API_INPUT_ERR );
00090 }
00091
00092 if ( inputStructBBuf->len <= 0 && RsApiTable[apiInx].inPackInstruct != NULL ) {
00093 rodsLog( LOG_NOTICE,
00094 "rsApiHandler: input struct error 2 for apiNumber %d", apiNumber );
00095 sendApiReply( rsComm, apiInx, SYS_API_INPUT_ERR, myOutStruct,
00096 &myOutBsBBuf );
00097 return ( SYS_API_INPUT_ERR );
00098 }
00099
00100 if ( bsBBuf->len > 0 && RsApiTable[apiInx].inBsFlag <= 0 ) {
00101 rodsLog( LOG_NOTICE,
00102 "rsApiHandler: input byte stream error for apiNumber %d", apiNumber );
00103 sendApiReply( rsComm, apiInx, SYS_API_INPUT_ERR, myOutStruct,
00104 &myOutBsBBuf );
00105 return ( SYS_API_INPUT_ERR );
00106 }
00107
00108 if ( inputStructBBuf->len > 0 ) {
00109 status = unpackStruct( inputStructBBuf->buf, ( void ** ) &myInStruct,
00110 RsApiTable[apiInx].inPackInstruct, RodsPackTable, rsComm->irodsProt );
00111 if ( status < 0 ) {
00112 rodsLog( LOG_NOTICE,
00113 "rsApiHandler: unpackStruct error for apiNumber %d, status = %d",
00114 apiNumber, status );
00115 sendApiReply( rsComm, apiInx, status, myOutStruct,
00116 &myOutBsBBuf );
00117 return ( status );
00118 }
00119 }
00120
00121
00122
00123 myHandler = RsApiTable[apiInx].svrHandler;
00124
00125 if ( RsApiTable[apiInx].inPackInstruct != NULL ) {
00126 myArgv[numArg] = myInStruct;
00127 numArg++;
00128 };
00129
00130 if ( RsApiTable[apiInx].inBsFlag != 0 ) {
00131 myArgv[numArg] = bsBBuf;
00132 numArg++;
00133 };
00134
00135 if ( RsApiTable[apiInx].outPackInstruct != NULL ) {
00136 myArgv[numArg] = ( void * ) &myOutStruct;
00137 numArg++;
00138 };
00139
00140 if ( RsApiTable[apiInx].outBsFlag != 0 ) {
00141 myArgv[numArg] = ( void * ) &myOutBsBBuf;
00142 numArg++;
00143 };
00144
00145 if ( numArg == 0 ) {
00146 retVal = ( *myHandler )( rsComm );
00147 }
00148 else if ( numArg == 1 ) {
00149 retVal = ( *myHandler )( rsComm, myArgv[0] );
00150 }
00151 else if ( numArg == 2 ) {
00152 retVal = ( *myHandler )( rsComm, myArgv[0], myArgv[1] );
00153 }
00154 else if ( numArg == 3 ) {
00155 retVal = ( *myHandler )( rsComm, myArgv[0], myArgv[1], myArgv[2] );
00156 }
00157 else if ( numArg == 4 ) {
00158 retVal = ( *myHandler )( rsComm, myArgv[0], myArgv[1], myArgv[2],
00159 myArgv[3] );
00160 }
00161
00162 if ( myInStruct != NULL ) {
00163
00164
00165 if ( strcmp( RsApiTable[apiInx].inPackInstruct, "GenQueryInp_PI" ) == 0 ) {
00166 clearGenQueryInp( ( genQueryInp_t * ) myInStruct );
00167 }
00168 else if ( strcmp( RsApiTable[apiInx].inPackInstruct,
00169 "ModDataObjMeta_PI" ) == 0 ) {
00170 clearModDataObjMetaInp( ( modDataObjMeta_t * ) myInStruct );
00171 }
00172 else if ( strcmp( RsApiTable[apiInx].inPackInstruct,
00173 "RegReplica_PI" ) == 0 ) {
00174 clearRegReplicaInp( ( regReplica_t * ) myInStruct );
00175 }
00176 else if ( strcmp( RsApiTable[apiInx].inPackInstruct,
00177 "UnregDataObj_PI" ) == 0 ) {
00178 clearUnregDataObj( ( unregDataObj_t * ) myInStruct );
00179 }
00180 else if ( strcmp( RsApiTable[apiInx].inPackInstruct,
00181 "DataObjInp_PI" ) == 0 ) {
00182 #if 0
00183 if ( apiNumber == QUERY_SPEC_COLL_AN &&
00184 ( ( dataObjInp_t * ) myInStruct )->specColl != NULL ) [curlybrace here]
00185 #endif
00186 clearDataObjInp( ( dataObjInp_t * ) myInStruct );
00187 }
00188 else if ( strcmp( RsApiTable[apiInx].inPackInstruct,
00189 "DataObjCopyInp_PI" ) == 0 ) {
00190 clearDataObjCopyInp( ( dataObjCopyInp_t * ) myInStruct );
00191 }
00192 else if ( strcmp( RsApiTable[apiInx].inPackInstruct,
00193 "GenQueryOut_PI" ) == 0 ) {
00194 clearGenQueryOut( ( genQueryOut_t * ) myInStruct );
00195 }
00196 else if ( strcmp( RsApiTable[apiInx].inPackInstruct,
00197 "CollInpNew_PI" ) == 0 ) {
00198 clearCollInp( ( collInp_t * ) myInStruct );
00199 }
00200 else if ( strcmp( RsApiTable[apiInx].inPackInstruct,
00201 "BulkOprInp_PI" ) == 0 ) {
00202 clearBulkOprInp( ( bulkOprInp_t * ) myInStruct );
00203 }
00204 else if ( strcmp( RsApiTable[apiInx].inPackInstruct,
00205 "ModAVUMetadataInp_PI" ) == 0 ) {
00206 clearModAVUMetadataInp( ( modAVUMetadataInp_t * ) myInStruct );
00207 }
00208 else if ( strcmp( RsApiTable[apiInx].inPackInstruct,
00209 "authResponseInp_PI" ) == 0 ) {
00210
00211 clearAuthResponseInp( ( void * ) myInStruct );
00212 }
00213 free( myInStruct );
00214 myInStruct = NULL;
00215 }
00216
00217 if ( apiNumber == GSI_AUTH_REQUEST_AN && retVal >= 0 ) {
00218
00219
00220
00221 logAgentProc( rsComm );
00222 }
00223
00224 if ( retVal != SYS_NO_HANDLER_REPLY_MSG ) {
00225 status = sendAndProcApiReply
00226 ( rsComm, apiInx, retVal, myOutStruct, &myOutBsBBuf );
00227 }
00228
00229 if ( retVal >= 0 && status < 0 ) {
00230 return ( status );
00231 }
00232 else {
00233 return ( retVal );
00234 }
00235 }
00236
00237 int
00238 sendAndProcApiReply( rsComm_t * rsComm, int apiInx, int status,
00239 void * myOutStruct, bytesBuf_t * myOutBsBBuf ) {
00240 int retval;
00241
00242 retval = sendApiReply( rsComm, apiInx, status, myOutStruct, myOutBsBBuf );
00243
00244 clearBBuf( myOutBsBBuf );
00245 if ( myOutStruct != NULL ) {
00246 free( myOutStruct );
00247 }
00248 freeRErrorContent( &rsComm->rError );
00249
00250
00251
00252 if ( rsComm->portalOpr != NULL ) {
00253 handlePortalOpr( rsComm );
00254 clearKeyVal( &rsComm->portalOpr->dataOprInp.condInput );
00255 free( rsComm->portalOpr );
00256 rsComm->portalOpr = NULL;
00257 }
00258
00259 return ( retval );
00260 }
00261
00262 int
00263 sendApiReply( rsComm_t * rsComm, int apiInx, int retVal,
00264 void * myOutStruct, bytesBuf_t * myOutBsBBuf ) {
00265 int status;
00266 bytesBuf_t *outStructBBuf = NULL;
00267 bytesBuf_t *myOutStructBBuf;
00268 bytesBuf_t *rErrorBBuf = NULL;
00269 bytesBuf_t *myRErrorBBuf;
00270
00271
00272 svrChkReconnAtSendStart( rsComm );
00273
00274
00275 if ( retVal == SYS_HANDLER_DONE_NO_ERROR ) {
00276
00277 retVal = 0;
00278 }
00279
00280
00281
00282 eirods::network_object_ptr net_obj;
00283 eirods::error ret = eirods::network_factory( rsComm, net_obj );
00284 if ( !ret.ok() ) {
00285 eirods::log( PASS( ret ) );
00286 return ret.code();
00287
00288 }
00289
00290
00291 if ( RsApiTable[apiInx].outPackInstruct != NULL && myOutStruct != NULL ) {
00292
00293 status = packStruct( ( char * ) myOutStruct, &outStructBBuf,
00294 RsApiTable[apiInx].outPackInstruct, RodsPackTable, FREE_POINTER,
00295 rsComm->irodsProt );
00296
00297 if ( status < 0 ) {
00298 rodsLog( LOG_NOTICE,
00299 "sendApiReply: packStruct error, status = %d", status );
00300 sendRodsMsg( net_obj, RODS_API_REPLY_T, NULL,
00301 NULL, NULL, status, rsComm->irodsProt );
00302 svrChkReconnAtSendEnd( rsComm );
00303 return status;
00304 }
00305
00306 myOutStructBBuf = outStructBBuf;
00307 }
00308 else {
00309 myOutStructBBuf = NULL;
00310 }
00311
00312 if ( RsApiTable[apiInx].outBsFlag == 0 ) {
00313 myOutBsBBuf = NULL;
00314 }
00315
00316 if ( rsComm->rError.len > 0 ) {
00317 status = packStruct( ( char * ) &rsComm->rError, &rErrorBBuf,
00318 "RError_PI", RodsPackTable, 0, rsComm->irodsProt );
00319
00320 if ( status < 0 ) {
00321 rodsLog( LOG_NOTICE,
00322 "sendApiReply: packStruct error, status = %d", status );
00323 sendRodsMsg( net_obj, RODS_API_REPLY_T, NULL,
00324 NULL, NULL, status, rsComm->irodsProt );
00325 svrChkReconnAtSendEnd( rsComm );
00326 return status;
00327 }
00328
00329 myRErrorBBuf = rErrorBBuf;
00330 }
00331 else {
00332 myRErrorBBuf = NULL;
00333 }
00334 ret = sendRodsMsg( net_obj, RODS_API_REPLY_T, myOutStructBBuf,
00335 myOutBsBBuf, myRErrorBBuf, retVal, rsComm->irodsProt );
00336 if ( !ret.ok() ) {
00337 int status1;
00338 eirods::log( PASS( ret ) );
00339
00340 if ( rsComm->reconnSock > 0 ) {
00341 int savedStatus = ret.code();
00342 boost::unique_lock< boost::mutex > boost_lock( *rsComm->lock );
00343 rodsLog( LOG_DEBUG,
00344 "sendApiReply: svrSwitchConnect. cliState = %d,agState=%d",
00345 rsComm->clientState, rsComm->agentState );
00346 status1 = svrSwitchConnect( rsComm );
00347 boost_lock.unlock();
00348 if ( status1 > 0 ) {
00349
00350 rodsLog( LOG_NOTICE,
00351 "sendApiReply: Switch connection and retry sendRodsMsg" );
00352 ret = sendRodsMsg( net_obj, RODS_API_REPLY_T,
00353 myOutStructBBuf, myOutBsBBuf, myRErrorBBuf,
00354 retVal, rsComm->irodsProt );
00355
00356 if ( ret.code() >= 0 ) {
00357 rodsLog( LOG_NOTICE,
00358 "sendApiReply: retry sendRodsMsg succeeded" );
00359 }
00360 else {
00361 status = savedStatus;
00362 }
00363 }
00364 }
00365 }
00366
00367 svrChkReconnAtSendEnd( rsComm );
00368
00369 freeBBuf( outStructBBuf );
00370 freeBBuf( rErrorBBuf );
00371
00372 return ( status );
00373 }
00374
00375 int
00376 chkApiVersion( rsComm_t * rsComm, int apiInx ) {
00377 char *cliApiVersion;
00378
00379 if ( ( cliApiVersion = getenv( SP_API_VERSION ) ) != NULL ) {
00380 if ( strcmp( cliApiVersion, RsApiTable[apiInx].apiVersion ) != 0 ) {
00381 rodsLog( LOG_ERROR,
00382 "chkApiVersion:Client's API Version %s does not match Server's %s",
00383 cliApiVersion, RsApiTable[apiInx].apiVersion );
00384 return ( USER_API_VERSION_MISMATCH );
00385 }
00386 }
00387 return ( 0 );
00388 }
00389
00390 int
00391 chkApiPermission( rsComm_t * rsComm, int apiInx ) {
00392 int clientUserAuth;
00393 int proxyUserAuth;
00394 int xmsgSvrOnly;
00395 int xmsgSvrAlso;
00396
00397 clientUserAuth = RsApiTable[apiInx].clientUserAuth;
00398
00399 xmsgSvrOnly = clientUserAuth & XMSG_SVR_ONLY;
00400 xmsgSvrAlso = clientUserAuth & XMSG_SVR_ALSO;
00401
00402 if ( ProcessType == XMSG_SERVER_PT ) {
00403 if ( ( xmsgSvrOnly + xmsgSvrAlso ) == 0 ) {
00404 rodsLog( LOG_ERROR,
00405 "chkApiPermission: xmsgServer not allowed to handle api %d",
00406 RsApiTable[apiInx].apiNumber );
00407 return ( SYS_NO_API_PRIV );
00408 }
00409 }
00410 else if ( xmsgSvrOnly != 0 ) {
00411 rodsLog( LOG_ERROR,
00412 "chkApiPermission: non xmsgServer not allowed to handle api %d",
00413 RsApiTable[apiInx].apiNumber );
00414 return ( SYS_NO_API_PRIV );
00415 }
00416
00417 clientUserAuth = clientUserAuth & 0xfff;
00418
00419 if ( clientUserAuth > rsComm->clientUser.authInfo.authFlag ) {
00420 return ( SYS_NO_API_PRIV );
00421 }
00422
00423 proxyUserAuth = RsApiTable[apiInx].proxyUserAuth & 0xfff;
00424 if ( proxyUserAuth > rsComm->proxyUser.authInfo.authFlag ) {
00425 return ( SYS_NO_API_PRIV );
00426 }
00427 return ( 0 );
00428 }
00429
00430 int
00431 handlePortalOpr( rsComm_t * rsComm ) {
00432 int oprType;
00433 int status;
00434
00435 if ( rsComm == NULL || rsComm->portalOpr == NULL ) {
00436 return ( 0 );
00437 }
00438
00439 oprType = rsComm->portalOpr->oprType;
00440
00441 switch ( oprType ) {
00442 case PUT_OPR:
00443 case GET_OPR:
00444 status = svrPortalPutGet( rsComm );
00445 break;
00446 default:
00447 rodsLog( LOG_NOTICE,
00448 "handlePortalOpr: Invalid portal oprType: %d", oprType );
00449 status = SYS_INVALID_PORTAL_OPR;
00450 break;
00451 }
00452 return ( status );
00453 }
00454
00455 int
00456 readAndProcClientMsg( rsComm_t * rsComm, int flags ) {
00457 int status = 0;
00458 msgHeader_t myHeader;
00459 bytesBuf_t inputStructBBuf, bsBBuf, errorBBuf;
00460
00461 bzero( &inputStructBBuf, sizeof( bytesBuf_t ) );
00462 bzero( &bsBBuf, sizeof( bytesBuf_t ) );
00463 bzero( &errorBBuf, sizeof( bytesBuf_t ) );
00464
00465
00466 svrChkReconnAtReadStart( rsComm );
00467
00468
00469
00470 memset( &bsBBuf, 0, sizeof( bsBBuf ) );
00471
00472
00473
00474
00475
00476 eirods::network_object_ptr net_obj;
00477 eirods::error ret = eirods::network_factory( rsComm, net_obj );
00478 if ( !ret.ok() ) {
00479 eirods::log( PASS( ret ) );
00480 return ret.code();
00481
00482 }
00483
00484 if ( ( flags & READ_HEADER_TIMEOUT ) != 0 ) {
00485 int retryCnt = 0;
00486 struct timeval tv;
00487 tv.tv_sec = READ_HEADER_TIMEOUT_IN_SEC;
00488 tv.tv_usec = 0;
00489
00490 while ( 1 ) {
00491 ret = readMsgHeader( net_obj, &myHeader, &tv );
00492 if ( !ret.ok() ) {
00493 if ( isL1descInuse() && retryCnt < MAX_READ_HEADER_RETRY ) {
00494 rodsLogError( LOG_ERROR, status,
00495 "readAndProcClientMsg:readMsgHeader error. status = %d", ret.code() );
00496 retryCnt++;
00497 continue;
00498 }
00499 if ( ret.code() == USER_SOCK_CONNECT_TIMEDOUT ) {
00500 rodsLog( LOG_ERROR,
00501 "readAndProcClientMsg: readMsgHeader by pid %d timedout",
00502 getpid() );
00503 return ret.code();
00504 }
00505 }
00506 break;
00507
00508 }
00509 }
00510 else {
00511 ret = readMsgHeader( net_obj, &myHeader, NULL );
00512 }
00513
00514 if ( !ret.ok() ) {
00515 eirods::log( PASS( ret ) );
00516
00517
00518 if ( rsComm->reconnSock > 0 ) {
00519 int savedStatus = ret.code();
00520
00521 boost::unique_lock< boost::mutex > boost_lock( *rsComm->lock );
00522 rodsLog( LOG_DEBUG,
00523 "readAndProcClientMsg: svrSwitchConnect. cliState = %d,agState=%d",
00524 rsComm->clientState, rsComm->agentState );
00525 svrSwitchConnect( rsComm );
00526 boost_lock.unlock();
00527 ret = readMsgHeader( net_obj, &myHeader, NULL );
00528 if ( !ret.ok() ) {
00529 svrChkReconnAtReadEnd( rsComm );
00530 return ( savedStatus );
00531 }
00532 }
00533 else {
00534 svrChkReconnAtReadEnd( rsComm );
00535 return( ret.code() );
00536 }
00537 }
00538
00539 #ifdef SYS_TIMING
00540 if ( strcmp( myHeader.type, RODS_API_REQ_T ) == 0 ) {
00541
00542 if ( myHeader.intInfo != AUTH_RESPONSE_AN ) {
00543 initSysTiming( "irodsAgent", "recv request", 0 );
00544 }
00545 }
00546 #endif
00547 ret = readMsgBody( net_obj, &myHeader, &inputStructBBuf,
00548 &bsBBuf, &errorBBuf, rsComm->irodsProt, NULL );
00549 if ( !ret.ok() ) {
00550 eirods::log( PASS( ret ) );
00551 svrChkReconnAtReadEnd( rsComm );
00552 return ( ret.code() );
00553 }
00554
00555 svrChkReconnAtReadEnd( rsComm );
00556
00557
00558
00559 if ( strcmp( myHeader.type, RODS_API_REQ_T ) == 0 ) {
00560 status = rsApiHandler( rsComm, myHeader.intInfo, &inputStructBBuf,
00561 &bsBBuf );
00562 #ifdef SYS_TIMING
00563 char tmpStr[NAME_LEN];
00564 snprintf( tmpStr, NAME_LEN, "handle API %d", myHeader.intInfo );
00565 printSysTiming( "irodsAgent", tmpStr, 0 );
00566 #endif
00567 clearBBuf( &inputStructBBuf );
00568 clearBBuf( &bsBBuf );
00569 clearBBuf( &errorBBuf );
00570
00571 if ( ( flags & RET_API_STATUS ) != 0 ) {
00572 return ( status );
00573 }
00574 else {
00575 return ( 0 );
00576 }
00577 }
00578 else if ( strcmp( myHeader.type, RODS_DISCONNECT_T ) == 0 ) {
00579 rodsLog( LOG_NOTICE,
00580 "readAndProcClientMsg: received disconnect msg from client" );
00581
00582 return ( DISCONN_STATUS );
00583 }
00584 else if ( strcmp( myHeader.type, RODS_RECONNECT_T ) == 0 ) {
00585 rodsLog( LOG_NOTICE,
00586 "readAndProcClientMsg: received reconnect msg from client" );
00587
00588 status = readAndProcClientMsg( rsComm, flags );
00589 return status;
00590 }
00591 else {
00592 rodsLog( LOG_NOTICE,
00593 "agentMain: msg type %s not support by server",
00594 myHeader.type );
00595 return ( USER_MSG_TYPE_NO_SUPPORT );
00596 }
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 int
00614 sendAndRecvBranchMsg( rsComm_t * rsComm, int apiInx, int status,
00615 void * myOutStruct, bytesBuf_t * myOutBsBBuf ) {
00616 int retval;
00617 int savedApiInx;
00618
00619 savedApiInx = rsComm->apiInx;
00620 retval = sendAndProcApiReply( rsComm, apiInx, status,
00621 myOutStruct, myOutBsBBuf );
00622 if ( retval < 0 ) {
00623 rodsLog( LOG_ERROR,
00624 "sendAndRecvBranchMsg: sendAndProcApiReply error. status = %d", retval );
00625 rsComm->apiInx = savedApiInx;
00626 return ( retval );
00627 }
00628
00629 while ( 1 ) {
00630 retval = readAndProcClientMsg( rsComm, RET_API_STATUS );
00631 if ( retval >= 0 || retval == SYS_NO_HANDLER_REPLY_MSG ) {
00632
00633 continue;
00634 }
00635 else {
00636 rsComm->apiInx = savedApiInx;
00637 if ( retval == SYS_HANDLER_DONE_NO_ERROR ) {
00638 return 0;
00639 }
00640 else {
00641 return ( retval );
00642 }
00643 }
00644 }
00645 }
00646
00647 int
00648 svrSendCollOprStat( rsComm_t * rsComm, collOprStat_t * collOprStat ) {
00649 int status;
00650
00651 status = _svrSendCollOprStat( rsComm, collOprStat );
00652
00653 if ( status != SYS_CLI_TO_SVR_COLL_STAT_REPLY ) {
00654 rodsLog( LOG_ERROR,
00655 "svrSendCollOprStat: client reply %d != %d.",
00656 status, SYS_CLI_TO_SVR_COLL_STAT_REPLY );
00657 return ( UNMATCHED_KEY_OR_INDEX );
00658 }
00659 else {
00660 return ( 0 );
00661 }
00662 }
00663
00664 int
00665 _svrSendCollOprStat( rsComm_t * rsComm, collOprStat_t * collOprStat ) {
00666 int myBuf;
00667 int status;
00668
00669 status = sendAndProcApiReply( rsComm, rsComm->apiInx,
00670 SYS_SVR_TO_CLI_COLL_STAT, collOprStat, NULL );
00671 if ( status < 0 ) {
00672 rodsLogError( LOG_ERROR, status,
00673 "svrSendCollOprStat: sendAndProcApiReply failed. status = %d",
00674 status );
00675 return status;
00676 }
00677
00678
00679 status = myRead( rsComm->sock, &myBuf, sizeof( myBuf ), SOCK_TYPE, NULL,
00680 NULL );
00681 if ( status < 0 ) {
00682 rodsLogError( LOG_ERROR, status,
00683 "svrSendCollOprStat: read handshake failed. status = %d", status );
00684 }
00685 return ( ntohl( myBuf ) );
00686 }
00687
00688 int
00689 svrSendZoneCollOprStat( rsComm_t * rsComm, rcComm_t * conn,
00690 collOprStat_t * collOprStat, int retval ) {
00691 int status = retval;
00692
00693 while ( status == SYS_SVR_TO_CLI_COLL_STAT ) {
00694 status = _svrSendCollOprStat( rsComm, collOprStat );
00695 if ( status == SYS_CLI_TO_SVR_COLL_STAT_REPLY ) {
00696 status = _cliGetCollOprStat( conn, &collOprStat );
00697 }
00698 else {
00699 int myBuf = htonl( status );
00700 myWrite( conn->sock, ( void * ) &myBuf, 4, SOCK_TYPE, NULL );
00701 break;
00702 }
00703 }
00704 return ( status );
00705 }
00706
00707 void
00708 readTimeoutHandler( int sig ) {
00709 alarm( 0 );
00710 if ( isL1descInuse() ) {
00711 rodsLog( LOG_ERROR,
00712 "readTimeoutHandler: read header by %d timed out. Lidesc is busy.",
00713 getpid() );
00714 longjmp( Jenv, L1DESC_INUSE );
00715 }
00716 else {
00717 rodsLog( LOG_ERROR,
00718 "readTimeoutHandler: read header by %d has timed out.",
00719 getpid() );
00720 longjmp( Jenv, READ_HEADER_TIMED_OUT );
00721 }
00722 }