int specCollSubStat( rsComm_t *rsComm, specColl_t *specColl, char *subPath, specCollPerm_t specCollPerm, dataObjInfo_t **dataObjInfo ) { int status; int objType; rodsStat_t *rodsStat = NULL; dataObjInfo_t *myDataObjInfo = NULL;; if ( dataObjInfo == NULL ) { return USER__NULL_INPUT_ERR; } *dataObjInfo = NULL; if ( specColl->collClass == MOUNTED_COLL ) { /* a mount point */ myDataObjInfo = *dataObjInfo = ( dataObjInfo_t * ) malloc( sizeof( dataObjInfo_t ) ); memset( myDataObjInfo, 0, sizeof( dataObjInfo_t ) ); /*status = resolveResc (specColl->resource, &myDataObjInfo->rescInfo); if (status < 0) { rodsLog( LOG_ERROR,"specCollSubStat: resolveResc error for %s, status = %d", specColl->resource, status); freeDataObjInfo (myDataObjInfo); *dataObjInfo = NULL; return status; }*/ rstrcpy( myDataObjInfo->objPath, subPath, MAX_NAME_LEN ); rstrcpy( myDataObjInfo->subPath, subPath, MAX_NAME_LEN ); rstrcpy( myDataObjInfo->rescName, specColl->resource, NAME_LEN ); rstrcpy( myDataObjInfo->rescHier, specColl->rescHier, MAX_NAME_LEN ); rstrcpy( myDataObjInfo->dataType, "generic", NAME_LEN ); status = getMountedSubPhyPath( specColl->collection, specColl->phyPath, subPath, myDataObjInfo->filePath ); if ( status < 0 ) { freeDataObjInfo( myDataObjInfo ); *dataObjInfo = NULL; return status; } replSpecColl( specColl, &myDataObjInfo->specColl ); } else if ( specColl->collClass == LINKED_COLL ) { /* a link point */ specCollCache_t *specCollCache = NULL; char newPath[MAX_NAME_LEN]; specColl_t *curSpecColl; char *accessStr; dataObjInp_t myDataObjInp; rodsObjStat_t *rodsObjStatOut = NULL; *dataObjInfo = NULL; curSpecColl = specColl; status = getMountedSubPhyPath( curSpecColl->collection, curSpecColl->phyPath, subPath, newPath ); if ( status < 0 ) { return status; } status = resolveLinkedPath( rsComm, newPath, &specCollCache, NULL ); if ( status < 0 ) { return status; } if ( specCollCache != NULL && specCollCache->specColl.collClass != LINKED_COLL ) { status = specCollSubStat( rsComm, &specCollCache->specColl, newPath, specCollPerm, dataObjInfo ); return status; } bzero( &myDataObjInp, sizeof( myDataObjInp ) ); rstrcpy( myDataObjInp.objPath, newPath, MAX_NAME_LEN ); status = collStat( rsComm, &myDataObjInp, &rodsObjStatOut ); if ( status >= 0 && NULL != rodsObjStatOut ) { /* a collection */ // JMC cppcheck - nullptr myDataObjInfo = *dataObjInfo = ( dataObjInfo_t * ) malloc( sizeof( dataObjInfo_t ) ); memset( myDataObjInfo, 0, sizeof( dataObjInfo_t ) ); replSpecColl( curSpecColl, &myDataObjInfo->specColl ); rstrcpy( myDataObjInfo->objPath, newPath, MAX_NAME_LEN ); myDataObjInfo->dataId = strtoll( rodsObjStatOut->dataId, 0, 0 ); rstrcpy( myDataObjInfo->dataOwnerName, rodsObjStatOut->ownerName, NAME_LEN ); rstrcpy( myDataObjInfo->dataOwnerZone, rodsObjStatOut->ownerZone, NAME_LEN ); rstrcpy( myDataObjInfo->dataCreate, rodsObjStatOut->createTime, TIME_LEN ); rstrcpy( myDataObjInfo->dataModify, rodsObjStatOut->modifyTime, TIME_LEN ); freeRodsObjStat( rodsObjStatOut ); return COLL_OBJ_T; } freeRodsObjStat( rodsObjStatOut ); /* data object */ if ( specCollPerm == READ_COLL_PERM ) { accessStr = ACCESS_READ_OBJECT; } else if ( specCollPerm == WRITE_COLL_PERM ) { accessStr = ACCESS_DELETE_OBJECT; } else { accessStr = NULL; } status = getDataObjInfo( rsComm, &myDataObjInp, dataObjInfo, accessStr, 0 ); if ( status < 0 ) { myDataObjInfo = *dataObjInfo = ( dataObjInfo_t * ) malloc( sizeof( dataObjInfo_t ) ); memset( myDataObjInfo, 0, sizeof( dataObjInfo_t ) ); replSpecColl( curSpecColl, &myDataObjInfo->specColl ); rstrcpy( myDataObjInfo->objPath, newPath, MAX_NAME_LEN ); rodsLog( LOG_DEBUG, "specCollSubStat: getDataObjInfo error for %s, status = %d", newPath, status ); return status; } else { replSpecColl( curSpecColl, &( *dataObjInfo )->specColl ); return DATA_OBJ_T; } } else if ( getStructFileType( specColl ) >= 0 ) { /* bundle */ dataObjInp_t myDataObjInp; dataObjInfo_t *tmpDataObjInfo; bzero( &myDataObjInp, sizeof( myDataObjInp ) ); rstrcpy( myDataObjInp.objPath, specColl->objPath, MAX_NAME_LEN ); // add the resource hierarchy to the condInput of the inp addKeyVal( &myDataObjInp.condInput, RESC_HIER_STR_KW, specColl->rescHier ); status = getDataObjInfo( rsComm, &myDataObjInp, dataObjInfo, NULL, 1 ); if ( status < 0 ) { rodsLog( LOG_ERROR, "specCollSubStat: getDataObjInfo error for %s, status = %d", myDataObjInp.objPath, status ); *dataObjInfo = NULL; return status; } /* screen out any stale copies */ status = sortObjInfoForOpen( dataObjInfo, &myDataObjInp.condInput, 0 ); if ( status < 0 ) { rodsLog( LOG_ERROR, "specCollSubStat: sortObjInfoForOpen error for %s. status = %d", myDataObjInp.objPath, status ); return status; } if ( strlen( specColl->resource ) > 0 ) { if ( requeDataObjInfoByResc( dataObjInfo, specColl->resource, 0, 1 ) >= 0 ) { if ( strcmp( specColl->resource, ( *dataObjInfo )->rescName ) != 0 ) { rodsLog( LOG_ERROR, "specCollSubStat: %s in %s does not match cache resc %s", myDataObjInp.objPath, ( *dataObjInfo )->rescName, specColl->resource ); freeAllDataObjInfo( *dataObjInfo ); *dataObjInfo = NULL; return SYS_CACHE_STRUCT_FILE_RESC_ERR; } } else { rodsLog( LOG_ERROR, "specCollSubStat: requeDataObjInfoByResc %s, resc %s error", myDataObjInp.objPath, specColl->resource ); freeAllDataObjInfo( *dataObjInfo ); *dataObjInfo = NULL; return SYS_CACHE_STRUCT_FILE_RESC_ERR; } } /* free all the other dataObjInfo */ if ( ( *dataObjInfo )->next != NULL ) { freeAllDataObjInfo( ( *dataObjInfo )->next ); ( *dataObjInfo )->next = NULL; } /* fill in DataObjInfo */ tmpDataObjInfo = *dataObjInfo; replSpecColl( specColl, &tmpDataObjInfo->specColl ); rstrcpy( specColl->resource, tmpDataObjInfo->rescName, NAME_LEN ); rstrcpy( specColl->rescHier, tmpDataObjInfo->rescHier, MAX_NAME_LEN ); rstrcpy( specColl->phyPath, tmpDataObjInfo->filePath, MAX_NAME_LEN ); rstrcpy( tmpDataObjInfo->subPath, subPath, MAX_NAME_LEN ); specColl->replNum = tmpDataObjInfo->replNum; if ( strcmp( ( *dataObjInfo )->subPath, specColl->collection ) == 0 ) { /* no need to go down */ return COLL_OBJ_T; } } else { rodsLog( LOG_ERROR, "specCollSubStat: Unknown specColl collClass = %d", specColl->collClass ); return SYS_UNKNOWN_SPEC_COLL_CLASS; } status = l3Stat( rsComm, *dataObjInfo, &rodsStat ); if ( status < 0 ) { return status; } if ( rodsStat->st_ctim != 0 ) { snprintf( ( *dataObjInfo )->dataCreate, TIME_LEN, "%d", rodsStat->st_ctim ); snprintf( ( *dataObjInfo )->dataModify, TIME_LEN, "%d", rodsStat->st_mtim ); } if ( rodsStat->st_mode & S_IFDIR ) { objType = COLL_OBJ_T; } else { objType = DATA_OBJ_T; ( *dataObjInfo )->dataSize = rodsStat->st_size; } free( rodsStat ); return objType; }
int _rsQuerySpecColl( rsComm_t *rsComm, int specCollInx, dataObjInp_t *dataObjInp, genQueryOut_t *genQueryOut, int continueFlag ) { int status = 0; rodsDirent_t *rodsDirent = NULL; dataObjInfo_t *dataObjInfo; int rowCnt; objType_t selObjType; char *tmpStr; dataObjInp_t newDataObjInp; int recurFlag; if ( SpecCollDesc[specCollInx].inuseFlag != FD_INUSE ) { rodsLog( LOG_ERROR, "_rsQuerySpecColl: Input specCollInx %d not active", specCollInx ); return BAD_INPUT_DESC_INDEX; } if ( ( tmpStr = getValByKey( &dataObjInp->condInput, SEL_OBJ_TYPE_KW ) ) != NULL ) { if ( strcmp( tmpStr, "dataObj" ) == 0 ) { selObjType = DATA_OBJ_T; } else { selObjType = COLL_OBJ_T; } } else { selObjType = UNKNOWN_OBJ_T; } if ( getValByKey( &dataObjInp->condInput, RECURSIVE_OPR__KW ) != NULL ) { recurFlag = 1; } else { recurFlag = 0; } dataObjInfo = SpecCollDesc[specCollInx].dataObjInfo; while ( genQueryOut->rowCnt < MAX_SPEC_COLL_ROW ) { dataObjInfo_t myDataObjInfo; rodsDirent_t myRodsDirent; status = specCollReaddir( rsComm, specCollInx, &rodsDirent ); if ( status < 0 ) { break; } myRodsDirent = *rodsDirent; free( rodsDirent ); if ( strcmp( myRodsDirent.d_name, "." ) == 0 || strcmp( myRodsDirent.d_name, ".." ) == 0 ) { continue; } myDataObjInfo = *dataObjInfo; snprintf( myDataObjInfo.subPath, MAX_NAME_LEN, "%s/%s", dataObjInfo->subPath, myRodsDirent.d_name ); snprintf( myDataObjInfo.filePath, MAX_NAME_LEN, "%s/%s", dataObjInfo->filePath, myRodsDirent.d_name ); rodsStat_t *fileStatOut = NULL; status = l3Stat( rsComm, &myDataObjInfo, &fileStatOut ); if ( status < 0 ) { rodsLog( LOG_ERROR, "_rsQuerySpecColl: l3Stat for %s error, status = %d", myDataObjInfo.filePath, status ); /* XXXXX need clean up */ return status; } if ( ( fileStatOut->st_mode & S_IFREG ) != 0 ) { /* a file */ if ( selObjType == COLL_OBJ_T ) { free( fileStatOut ); continue; } rowCnt = genQueryOut->rowCnt; rstrcpy( &genQueryOut->sqlResult[0].value[MAX_NAME_LEN * rowCnt], dataObjInfo->subPath, MAX_NAME_LEN ); rstrcpy( &genQueryOut->sqlResult[1].value[MAX_NAME_LEN * rowCnt], myRodsDirent.d_name, MAX_NAME_LEN ); snprintf( &genQueryOut->sqlResult[2].value[NAME_LEN * rowCnt], NAME_LEN, "%d", fileStatOut->st_ctim ); snprintf( &genQueryOut->sqlResult[3].value[NAME_LEN * rowCnt], NAME_LEN, "%d", fileStatOut->st_mtim ); snprintf( &genQueryOut->sqlResult[4].value[NAME_LEN * rowCnt], NAME_LEN, "%lld", fileStatOut->st_size ); free( fileStatOut ); genQueryOut->rowCnt++; } else { if ( selObjType != DATA_OBJ_T ) { rowCnt = genQueryOut->rowCnt; rstrcpy( &genQueryOut->sqlResult[0].value[MAX_NAME_LEN * rowCnt], myDataObjInfo.subPath, MAX_NAME_LEN ); snprintf( &genQueryOut->sqlResult[2].value[NAME_LEN * rowCnt], NAME_LEN, "%d", fileStatOut->st_ctim ); snprintf( &genQueryOut->sqlResult[3].value[NAME_LEN * rowCnt], NAME_LEN, "%d", fileStatOut->st_mtim ); snprintf( &genQueryOut->sqlResult[4].value[NAME_LEN * rowCnt], NAME_LEN, "%lld", fileStatOut->st_size ); genQueryOut->rowCnt++; } free( fileStatOut ); if ( recurFlag > 0 ) { /* need to drill down */ int newSpecCollInx; newDataObjInp = *dataObjInp; rstrcpy( newDataObjInp.objPath, dataObjInfo->subPath, MAX_NAME_LEN ); newSpecCollInx = openSpecColl( rsComm, &newDataObjInp, specCollInx ); if ( newSpecCollInx < 0 ) { rodsLog( LOG_ERROR, "_rsQuerySpecColl: openSpecColl err for %s, stat = %d", newDataObjInp.objPath, newSpecCollInx ); status = newSpecCollInx; break; } status = _rsQuerySpecColl( rsComm, newSpecCollInx, &newDataObjInp, genQueryOut, 0 ); if ( status < 0 ) { break; } } } } // while if ( status == EOF || status == CAT_NO_ROWS_FOUND ) { status = 0; } if ( genQueryOut->rowCnt < MAX_SPEC_COLL_ROW ) { int parentInx; /* get to the end or error */ specCollClosedir( rsComm, specCollInx ); parentInx = SpecCollDesc[specCollInx].parentInx; freeSpecCollDesc( specCollInx ); if ( status >= 0 && recurFlag && continueFlag && parentInx > 0 ) { newDataObjInp = *dataObjInp; rstrcpy( newDataObjInp.objPath, SpecCollDesc[parentInx].dataObjInfo->objPath, MAX_NAME_LEN ); status = _rsQuerySpecColl( rsComm, parentInx, &newDataObjInp, genQueryOut, continueFlag ); } else { /* no more */ genQueryOut->continueInx = -1; } if ( status == EOF || status == CAT_NO_ROWS_FOUND ) { status = 0; } } else { /* more to come */ if ( genQueryOut->continueInx < 0 ) { /* if one does not already exist */ genQueryOut->continueInx = specCollInx; } } if ( status >= 0 && genQueryOut->rowCnt == 0 ) { status = CAT_NO_ROWS_FOUND; } return status; }