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