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