00001
00002
00003
00004
00005
00006
00007
00008 #include "querySpecColl.h"
00009 #include "rcMisc.h"
00010 #include "fileOpendir.h"
00011 #include "fileReaddir.h"
00012 #include "fileClosedir.h"
00013 #include "objMetaOpr.h"
00014 #include "specColl.h"
00015 #include "dataObjClose.h"
00016 #include "subStructFileOpendir.h"
00017 #include "subStructFileReaddir.h"
00018 #include "subStructFileClosedir.h"
00019 #include "fileStat.h"
00020 #include "genQuery.h"
00021 #include "rsGlobalExtern.h"
00022 #include "rcGlobalExtern.h"
00023
00024
00025
00026 #include "eirods_resource_backport.h"
00027 #include "eirods_resource_redirect.h"
00028 #include "eirods_stacktrace.h"
00029 #include "eirods_hierarchy_parser.h"
00030
00031
00032 int
00033 rsQuerySpecColl (rsComm_t *rsComm, dataObjInp_t *dataObjInp,
00034 genQueryOut_t **genQueryOut)
00035 {
00036
00037 int specCollInx;
00038 int status;
00039 int continueFlag;
00040 int remoteFlag;
00041 rodsServerHost_t *rodsServerHost;
00042 remoteFlag = getAndConnRcatHost (rsComm, SLAVE_RCAT, dataObjInp->objPath,
00043 &rodsServerHost);
00044
00045 if (remoteFlag < 0) {
00046 return (remoteFlag);
00047 } else if (remoteFlag == REMOTE_HOST) {
00048 status = rcQuerySpecColl (rodsServerHost->conn, dataObjInp,
00049 genQueryOut);
00050 return status;
00051 }
00052
00053
00054
00055
00056
00057 std::string hier;
00058 char* hier_kw = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW );
00059 if( NULL == hier_kw ) {
00060 eirods::error ret = eirods::resolve_resource_hierarchy( eirods::EIRODS_OPEN_OPERATION, rsComm,
00061 dataObjInp, hier );
00062 if( !ret.ok() ) {
00063 std::stringstream msg;
00064 msg << "failed for [";
00065 msg << dataObjInp->objPath << "]";
00066 eirods::log( PASSMSG( msg.str(), ret ) );
00067 return ret.code();
00068 }
00069
00070
00071
00072
00073 addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() );
00074
00075 }
00076
00077 if ((specCollInx = dataObjInp->openFlags) <= 0) {
00078 specCollInx = openSpecColl (rsComm, dataObjInp, -1);
00079 if (specCollInx < 0) {
00080 rodsLog (LOG_NOTICE,
00081 "rsQuerySpecColl: openSpecColl error for %s, status = %d",
00082 dataObjInp->objPath, specCollInx);
00083 return (specCollInx);
00084 }
00085 continueFlag = 0;
00086 } else {
00087 continueFlag = 1;
00088 }
00089
00090 initOutForQuerySpecColl (genQueryOut);
00091
00092 status = _rsQuerySpecColl (rsComm, specCollInx, dataObjInp,
00093 *genQueryOut, continueFlag);
00094
00095 if (status < 0) {
00096 freeGenQueryOut (genQueryOut);
00097 }
00098 return (status);
00099 }
00100
00101 int
00102 openSpecColl (rsComm_t *rsComm, dataObjInp_t *dataObjInp, int parentInx)
00103 {
00104 int specCollInx;
00105 dataObjInfo_t *dataObjInfo = NULL;
00106 int status;
00107 int l3descInx;
00108
00109 status = resolvePathInSpecColl (rsComm, dataObjInp->objPath,
00110
00111 UNKNOW_COLL_PERM, 0, &dataObjInfo);
00112
00113 if (status < 0 || NULL == dataObjInfo ) {
00114 rodsLog (LOG_NOTICE,
00115 "rsQuerySpecColl: resolveSpecColl error for %s, status = %d",
00116 dataObjInp->objPath, status);
00117 return (status);
00118 }
00119
00120 if (dataObjInfo->specColl->collClass == LINKED_COLL) {
00121 rodsLog (LOG_ERROR,
00122 "rsQuerySpecColl: %s is a linked collection",
00123 dataObjInp->objPath);
00124 return SYS_UNKNOWN_SPEC_COLL_CLASS;
00125 }
00126
00127 char* resc_hier = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW );
00128 if( resc_hier ) {
00129 strncpy( dataObjInfo->rescHier, resc_hier, MAX_NAME_LEN );
00130 }
00131
00132 l3descInx = l3Opendir (rsComm, dataObjInfo);
00133
00134 if (l3descInx < 0) {
00135 rodsLog (LOG_NOTICE,
00136 "openSpecColl: specCollOpendir error for %s, status = %d",
00137 dataObjInp->objPath, l3descInx);
00138 return (l3descInx);
00139 }
00140 specCollInx = allocSpecCollDesc ();
00141 if (specCollInx < 0) {
00142 freeDataObjInfo (dataObjInfo);
00143 return (specCollInx);
00144 }
00145 SpecCollDesc[specCollInx].l3descInx = l3descInx;
00146 SpecCollDesc[specCollInx].dataObjInfo = dataObjInfo;
00147 SpecCollDesc[specCollInx].parentInx = parentInx;
00148
00149 return (specCollInx);
00150 }
00151
00152 int
00153 initOutForQuerySpecColl (genQueryOut_t **genQueryOut)
00154 {
00155 genQueryOut_t *myGenQueryOut;
00156
00157
00158
00159 myGenQueryOut = *genQueryOut =
00160 (genQueryOut_t *) malloc (sizeof (genQueryOut_t));
00161
00162 memset (myGenQueryOut, 0, sizeof (genQueryOut_t));
00163
00164 myGenQueryOut->attriCnt = 5;
00165
00166 myGenQueryOut->sqlResult[0].attriInx = COL_COLL_NAME;
00167 myGenQueryOut->sqlResult[0].len = MAX_NAME_LEN;
00168 myGenQueryOut->sqlResult[0].value =
00169 (char*)malloc (MAX_NAME_LEN * MAX_SPEC_COLL_ROW);
00170 memset (myGenQueryOut->sqlResult[0].value, 0,
00171 MAX_NAME_LEN * MAX_SPEC_COLL_ROW);
00172 myGenQueryOut->sqlResult[1].attriInx = COL_DATA_NAME;
00173 myGenQueryOut->sqlResult[1].len = MAX_NAME_LEN;
00174 myGenQueryOut->sqlResult[1].value =
00175 (char*)malloc (MAX_NAME_LEN * MAX_SPEC_COLL_ROW);
00176 memset (myGenQueryOut->sqlResult[1].value, 0,
00177 MAX_NAME_LEN * MAX_SPEC_COLL_ROW);
00178 myGenQueryOut->sqlResult[2].attriInx = COL_D_CREATE_TIME;
00179 myGenQueryOut->sqlResult[2].len = NAME_LEN;
00180 myGenQueryOut->sqlResult[2].value =
00181 (char*)malloc (NAME_LEN * MAX_SPEC_COLL_ROW);
00182 memset (myGenQueryOut->sqlResult[2].value, 0,
00183 NAME_LEN * MAX_SPEC_COLL_ROW);
00184 myGenQueryOut->sqlResult[3].attriInx = COL_D_MODIFY_TIME;
00185 myGenQueryOut->sqlResult[3].len = NAME_LEN;
00186 myGenQueryOut->sqlResult[3].value =
00187 (char*)malloc (NAME_LEN * MAX_SPEC_COLL_ROW);
00188 memset (myGenQueryOut->sqlResult[3].value, 0,
00189 NAME_LEN * MAX_SPEC_COLL_ROW);
00190 myGenQueryOut->sqlResult[4].attriInx = COL_DATA_SIZE;
00191 myGenQueryOut->sqlResult[4].len = NAME_LEN;
00192 myGenQueryOut->sqlResult[4].value =
00193 (char*)malloc (NAME_LEN * MAX_SPEC_COLL_ROW);
00194 memset (myGenQueryOut->sqlResult[4].value, 0,
00195 NAME_LEN * MAX_SPEC_COLL_ROW);
00196
00197 myGenQueryOut->continueInx = -1;
00198
00199 return (0);
00200 }
00201
00202 int
00203 _rsQuerySpecColl (rsComm_t *rsComm, int specCollInx,
00204 dataObjInp_t *dataObjInp, genQueryOut_t *genQueryOut, int continueFlag)
00205 {
00206 int status;
00207 rodsDirent_t *rodsDirent = NULL;
00208 dataObjInfo_t *dataObjInfo;
00209 rodsStat_t *fileStatOut = NULL;
00210 int rowCnt;
00211 objType_t selObjType;
00212 char *tmpStr;
00213 dataObjInp_t newDataObjInp;
00214 int recurFlag;
00215
00216 if (SpecCollDesc[specCollInx].inuseFlag != FD_INUSE) {
00217 rodsLog (LOG_ERROR,
00218 "_rsQuerySpecColl: Input specCollInx %d not active", specCollInx);
00219 return (BAD_INPUT_DESC_INDEX);
00220 }
00221
00222 if ((tmpStr = getValByKey (&dataObjInp->condInput, SEL_OBJ_TYPE_KW)) !=
00223 NULL) {
00224 if (strcmp (tmpStr, "dataObj") == 0) {
00225 selObjType = DATA_OBJ_T;
00226 } else {
00227 selObjType = COLL_OBJ_T;
00228 }
00229 } else {
00230 selObjType = UNKNOWN_OBJ_T;
00231 }
00232
00233 if (getValByKey (&dataObjInp->condInput, RECURSIVE_OPR__KW) != NULL) {
00234 recurFlag = 1;
00235 } else {
00236 recurFlag = 0;
00237 }
00238
00239 dataObjInfo = SpecCollDesc[specCollInx].dataObjInfo;
00240
00241 while (genQueryOut->rowCnt < MAX_SPEC_COLL_ROW) {
00242 dataObjInfo_t myDataObjInfo;
00243 rodsDirent_t myRodsDirent;
00244
00245 status = specCollReaddir (rsComm, specCollInx, &rodsDirent);
00246
00247 if (status < 0) {
00248 break;
00249 }
00250
00251 myRodsDirent = *rodsDirent;
00252 free (rodsDirent);
00253
00254 if (strcmp (myRodsDirent.d_name, ".") == 0 ||
00255 strcmp (myRodsDirent.d_name, "..") == 0) {
00256 continue;
00257 }
00258
00259 myDataObjInfo = *dataObjInfo;
00260
00261 snprintf( myDataObjInfo.subPath, MAX_NAME_LEN, "%s/%s",
00262 dataObjInfo->subPath, myRodsDirent.d_name);
00263 snprintf( myDataObjInfo.filePath, MAX_NAME_LEN, "%s/%s",
00264 dataObjInfo->filePath, myRodsDirent.d_name);
00265
00266 status = l3Stat (rsComm, &myDataObjInfo, &fileStatOut);
00267 if (status < 0) {
00268 rodsLog (LOG_ERROR,
00269 "_rsQuerySpecColl: l3Stat for %s error, status = %d",
00270 myDataObjInfo.filePath, status);
00271
00272 return (status);
00273 }
00274
00275 if ((fileStatOut->st_mode & S_IFREG) != 0) {
00276 if (selObjType == COLL_OBJ_T) {
00277 free (fileStatOut);
00278 continue;
00279 }
00280 rowCnt = genQueryOut->rowCnt;
00281 rstrcpy (&genQueryOut->sqlResult[0].value[MAX_NAME_LEN * rowCnt],
00282 dataObjInfo->subPath, MAX_NAME_LEN);
00283 rstrcpy (&genQueryOut->sqlResult[1].value[MAX_NAME_LEN * rowCnt],
00284 myRodsDirent.d_name, MAX_NAME_LEN);
00285 snprintf (&genQueryOut->sqlResult[2].value[NAME_LEN * rowCnt],
00286 NAME_LEN, "%d", fileStatOut->st_ctim);
00287 snprintf (&genQueryOut->sqlResult[3].value[NAME_LEN * rowCnt],
00288 NAME_LEN, "%d", fileStatOut->st_mtim);
00289 snprintf (&genQueryOut->sqlResult[4].value[NAME_LEN * rowCnt],
00290 NAME_LEN, "%lld", fileStatOut->st_size);
00291
00292 free (fileStatOut);
00293
00294 genQueryOut->rowCnt++;
00295
00296 } else {
00297 if (selObjType != DATA_OBJ_T) {
00298 rowCnt = genQueryOut->rowCnt;
00299 rstrcpy( &genQueryOut->sqlResult[0].value[MAX_NAME_LEN * rowCnt],
00300 myDataObjInfo.subPath, MAX_NAME_LEN );
00301 snprintf( &genQueryOut->sqlResult[2].value[NAME_LEN * rowCnt],
00302 NAME_LEN, "%d", fileStatOut->st_ctim);
00303 snprintf (&genQueryOut->sqlResult[3].value[NAME_LEN * rowCnt],
00304 NAME_LEN, "%d", fileStatOut->st_mtim);
00305 snprintf (&genQueryOut->sqlResult[4].value[NAME_LEN * rowCnt],
00306 NAME_LEN, "%lld", fileStatOut->st_size);
00307 genQueryOut->rowCnt++;
00308 }
00309
00310 free (fileStatOut);
00311
00312 if (recurFlag > 0) {
00313
00314 int newSpecCollInx;
00315 newDataObjInp = *dataObjInp;
00316 rstrcpy (newDataObjInp.objPath, dataObjInfo->subPath,
00317 MAX_NAME_LEN);
00318 newSpecCollInx =
00319 openSpecColl (rsComm, &newDataObjInp, specCollInx);
00320 if (newSpecCollInx < 0) {
00321 rodsLog (LOG_ERROR,
00322 "_rsQuerySpecColl: openSpecColl err for %s, stat = %d",
00323 newDataObjInp.objPath, newSpecCollInx);
00324 status = newSpecCollInx;
00325 break;
00326 }
00327 status = _rsQuerySpecColl (rsComm, newSpecCollInx,
00328 &newDataObjInp, genQueryOut, 0);
00329 if (status < 0) {
00330 break;
00331 }
00332 }
00333 }
00334 }
00335
00336 if (status == EOF || status == CAT_NO_ROWS_FOUND) {
00337 status = 0;
00338 }
00339
00340 if (genQueryOut->rowCnt < MAX_SPEC_COLL_ROW) {
00341 int parentInx;
00342
00343 specCollClosedir (rsComm, specCollInx);
00344 parentInx = SpecCollDesc[specCollInx].parentInx;
00345 freeSpecCollDesc (specCollInx);
00346 if (status >= 0 && recurFlag && continueFlag && parentInx > 0) {
00347 newDataObjInp = *dataObjInp;
00348 rstrcpy (newDataObjInp.objPath,
00349 SpecCollDesc[parentInx].dataObjInfo->objPath, MAX_NAME_LEN);
00350 status = _rsQuerySpecColl (rsComm, parentInx,
00351 &newDataObjInp, genQueryOut, continueFlag);
00352 } else {
00353
00354 genQueryOut->continueInx = -1;
00355 }
00356 if (status == EOF || status == CAT_NO_ROWS_FOUND) {
00357 status = 0;
00358 }
00359 } else {
00360
00361 if (genQueryOut->continueInx < 0) {
00362
00363 genQueryOut->continueInx = specCollInx;
00364 }
00365 }
00366
00367 if (status >= 0 && genQueryOut->rowCnt == 0) {
00368 status = CAT_NO_ROWS_FOUND;
00369 }
00370
00371 return (status);
00372 }
00373
00374 int
00375 specCollReaddir (rsComm_t *rsComm, int specCollInx, rodsDirent_t **rodsDirent)
00376 {
00377 fileReaddirInp_t fileReaddirInp;
00378 specColl_t *specColl;
00379 int status;
00380 dataObjInfo_t *dataObjInfo = SpecCollDesc[specCollInx].dataObjInfo;
00381
00382 if (dataObjInfo == NULL || (specColl = dataObjInfo->specColl) == NULL) {
00383 return (SYS_INTERNAL_NULL_INPUT_ERR);
00384 }
00385
00386
00387
00388 std::string location;
00389 eirods::error ret = eirods::get_loc_for_hier_string( dataObjInfo->rescHier, location );
00390 if( !ret.ok() ) {
00391 eirods::log( PASSMSG( "specCollReaddir - failed in get_loc_for_hier_string", ret ) );
00392 return -1;
00393 }
00394
00395
00396 if (getStructFileType (dataObjInfo->specColl) >= 0) {
00397 subStructFileFdOprInp_t subStructFileReaddirInp;
00398 memset (&subStructFileReaddirInp, 0, sizeof (subStructFileReaddirInp));
00399 subStructFileReaddirInp.type = dataObjInfo->specColl->type;
00400 subStructFileReaddirInp.fd = SpecCollDesc[specCollInx].l3descInx;
00401 rstrcpy (subStructFileReaddirInp.addr.hostAddr,
00402 location.c_str(), NAME_LEN);
00403 status = rsSubStructFileReaddir (rsComm, &subStructFileReaddirInp,
00404 rodsDirent);
00405 } else if (specColl->collClass == MOUNTED_COLL) {
00406 fileReaddirInp.fileInx = SpecCollDesc[specCollInx].l3descInx;
00407 status = rsFileReaddir (rsComm, &fileReaddirInp, rodsDirent);
00408 } else {
00409 rodsLog (LOG_ERROR,
00410 "specCollReaddir: Unknown specColl collClass = %d",
00411 specColl->collClass);
00412 status = SYS_UNKNOWN_SPEC_COLL_CLASS;
00413 }
00414
00415 return (status);
00416 }
00417
00418 int
00419 specCollClosedir (rsComm_t *rsComm, int specCollInx)
00420 {
00421 fileClosedirInp_t fileClosedirInp;
00422 specColl_t *specColl;
00423 int status;
00424 dataObjInfo_t *dataObjInfo = SpecCollDesc[specCollInx].dataObjInfo;
00425
00426 if (dataObjInfo == NULL || (specColl = dataObjInfo->specColl) == NULL) {
00427 return (SYS_INTERNAL_NULL_INPUT_ERR);
00428 }
00429
00430
00431
00432 std::string location;
00433 eirods::error ret = eirods::get_loc_for_hier_string( dataObjInfo->rescHier, location );
00434 if( !ret.ok() ) {
00435 eirods::log( PASSMSG( "specCollClosedir - failed in get_loc_for_hier_string", ret ) );
00436 return -1;
00437 }
00438
00439 if (getStructFileType (dataObjInfo->specColl) >= 0) {
00440 subStructFileFdOprInp_t subStructFileClosedirInp;
00441 memset (&subStructFileClosedirInp, 0, sizeof (subStructFileClosedirInp));
00442 subStructFileClosedirInp.type = dataObjInfo->specColl->type;
00443 subStructFileClosedirInp.fd = SpecCollDesc[specCollInx].l3descInx;
00444 rstrcpy (subStructFileClosedirInp.addr.hostAddr,
00445 location.c_str(), NAME_LEN);
00446 status = rsSubStructFileClosedir (rsComm, &subStructFileClosedirInp);
00447 } else if (specColl->collClass == MOUNTED_COLL) {
00448 fileClosedirInp.fileInx = SpecCollDesc[specCollInx].l3descInx;
00449 status = rsFileClosedir (rsComm, &fileClosedirInp);
00450 } else {
00451 rodsLog (LOG_ERROR,
00452 "specCollClosedir: Unknown specColl collClass = %d",
00453 specColl->collClass);
00454 status = SYS_UNKNOWN_SPEC_COLL_CLASS;
00455 }
00456
00457 return (status);
00458 }
00459
00460 int
00461 l3Opendir (rsComm_t *rsComm, dataObjInfo_t *dataObjInfo)
00462 {
00463 fileOpendirInp_t fileOpendirInp;
00464 int status;
00465
00466 if (dataObjInfo == NULL) return (SYS_INTERNAL_NULL_INPUT_ERR);
00467
00468
00469
00470 std::string location;
00471 eirods::error ret = eirods::get_loc_for_hier_string( dataObjInfo->rescHier, location );
00472 if( !ret.ok() ) {
00473 eirods::log( PASSMSG( "l3Opendir - failed in get_loc_for_hier_string", ret ) );
00474 return -1;
00475 }
00476
00477 if (getStructFileType (dataObjInfo->specColl) >= 0) {
00478 subFile_t subStructFileOpendirInp;
00479 status = 0;
00480
00481
00482 memset ( &subStructFileOpendirInp, 0, sizeof (subStructFileOpendirInp));
00483 rstrcpy( subStructFileOpendirInp.subFilePath, dataObjInfo->subPath, MAX_NAME_LEN );
00484
00485 rstrcpy( subStructFileOpendirInp.addr.hostAddr, location.c_str(), NAME_LEN );
00486 subStructFileOpendirInp.specColl = dataObjInfo->specColl;
00487 status = rsSubStructFileOpendir (rsComm, &subStructFileOpendirInp);
00488 } else {
00489 memset (&fileOpendirInp, 0, sizeof (fileOpendirInp));
00490 rstrcpy (fileOpendirInp.dirName, dataObjInfo->filePath, MAX_NAME_LEN);
00491 rstrcpy( fileOpendirInp.resc_name_, dataObjInfo->rescInfo->rescName, MAX_NAME_LEN );
00492 rstrcpy( fileOpendirInp.resc_hier_, dataObjInfo->rescHier, MAX_NAME_LEN );
00493 fileOpendirInp.fileType = static_cast< fileDriverType_t >( -1 );
00494 rstrcpy (fileOpendirInp.addr.hostAddr, location.c_str(), NAME_LEN);
00495
00496 status = rsFileOpendir (rsComm, &fileOpendirInp);
00497 if (status < 0) {
00498 rodsLog (LOG_ERROR,
00499 "l3Opendir: rsFileOpendir for %s error, status = %d",
00500 dataObjInfo->filePath, status);
00501 }
00502 }
00503 return (status);
00504 }
00505