int rsMkCollR( rsComm_t *rsComm, const char *startColl, const char *destColl ) { int status; int startLen; int pathLen, tmpLen; char tmpPath[MAX_NAME_LEN]; startLen = strlen( startColl ); pathLen = strlen( destColl ); rstrcpy( tmpPath, destColl, MAX_NAME_LEN ); tmpLen = pathLen; while ( tmpLen > startLen ) { if ( isCollAllKinds( rsComm, tmpPath, NULL ) >= 0 ) { break; } /* Go backward */ while ( tmpLen && tmpPath[tmpLen] != '/' ) { tmpLen --; } tmpPath[tmpLen] = '\0'; } /* Now we go forward and make the required coll */ while ( tmpLen < pathLen ) { collInp_t collCreateInp; /* Put back the '/' */ tmpPath[tmpLen] = '/'; memset( &collCreateInp, 0, sizeof( collCreateInp ) ); rstrcpy( collCreateInp.collName, tmpPath, MAX_NAME_LEN ); status = rsCollCreate( rsComm, &collCreateInp ); if ( status == CAT_NAME_EXISTS_AS_DATAOBJ && isTrashPath( tmpPath ) ) { /* name conflict with a data object in the trash collection */ dataObjCopyInp_t dataObjRenameInp; memset( &dataObjRenameInp, 0, sizeof( dataObjRenameInp ) ); dataObjRenameInp.srcDataObjInp.oprType = dataObjRenameInp.destDataObjInp.oprType = RENAME_DATA_OBJ; rstrcpy( dataObjRenameInp.srcDataObjInp.objPath, tmpPath, MAX_NAME_LEN ); rstrcpy( dataObjRenameInp.destDataObjInp.objPath, tmpPath, MAX_NAME_LEN ); appendRandomToPath( dataObjRenameInp.destDataObjInp.objPath ); status = rsDataObjRename( rsComm, &dataObjRenameInp ); if ( status >= 0 ) { status = rsCollCreate( rsComm, &collCreateInp ); } } /* something may be added by rsCollCreate */ clearKeyVal( &collCreateInp.condInput ); if ( status < 0 ) { // =-=-=-=-=-=-=- // JMC - backport 4819 if ( status == CATALOG_ALREADY_HAS_ITEM_BY_THAT_NAME ) { rodsLog( LOG_DEBUG, "rsMkCollR: rsCollCreate - coll %s already exist.stat = %d", tmpPath, status ); status = 0; } else { rodsLog( LOG_ERROR, "rsMkCollR: rsCollCreate failed for %s, status =%d", tmpPath, status ); } // =-=-=-=-=-=-=- return status; } while ( tmpLen && tmpPath[tmpLen] != '\0' ) { tmpLen ++; } } return 0; }
int rsRmColl( rsComm_t *rsComm, collInp_t *rmCollInp, collOprStat_t **collOprStat ) { int status; ruleExecInfo_t rei; collInfo_t collInfo; rodsServerHost_t *rodsServerHost = NULL; specCollCache_t *specCollCache = NULL; resolveLinkedPath( rsComm, rmCollInp->collName, &specCollCache, &rmCollInp->condInput ); status = getAndConnRcatHost( rsComm, MASTER_RCAT, ( const char* )rmCollInp->collName, &rodsServerHost ); if ( status < 0 || NULL == rodsServerHost ) { // JMC cppcheck - nullptr return status; } else if ( rodsServerHost->rcatEnabled == REMOTE_ICAT ) { int retval; retval = _rcRmColl( rodsServerHost->conn, rmCollInp, collOprStat ); status = svrSendZoneCollOprStat( rsComm, rodsServerHost->conn, *collOprStat, retval ); return status; } initReiWithCollInp( &rei, rsComm, rmCollInp, &collInfo ); status = applyRule( "acPreprocForRmColl", NULL, &rei, NO_SAVE_REI ); if ( status < 0 ) { if ( rei.status < 0 ) { status = rei.status; } rodsLog( LOG_ERROR, "rsRmColl:acPreprocForRmColl error for %s,stat=%d", rmCollInp->collName, status ); return status; } if ( collOprStat != NULL ) { *collOprStat = NULL; } if ( getValByKey( &rmCollInp->condInput, RECURSIVE_OPR__KW ) == NULL ) { status = _rsRmColl( rsComm, rmCollInp, collOprStat ); } else { if ( isTrashPath( rmCollInp->collName ) == False && getValByKey( &rmCollInp->condInput, FORCE_FLAG_KW ) != NULL ) { rodsLog( LOG_NOTICE, "rsRmColl: Recursively removing %s.", rmCollInp->collName ); } status = _rsRmCollRecur( rsComm, rmCollInp, collOprStat ); } rei.status = status; rei.status = applyRule( "acPostProcForRmColl", NULL, &rei, NO_SAVE_REI ); if ( rei.status < 0 ) { rodsLog( LOG_ERROR, "rsRmColl:acPostProcForRmColl error for %s,stat=%d", rmCollInp->collName, status ); } return status; }
int rsDataObjUnlink (rsComm_t *rsComm, dataObjInp_t *dataObjUnlinkInp) { int status; ruleExecInfo_t rei; int trashPolicy; dataObjInfo_t *dataObjInfoHead = NULL; rodsServerHost_t *rodsServerHost = NULL; int rmTrashFlag = 0; specCollCache_t *specCollCache = NULL; resolveLinkedPath (rsComm, dataObjUnlinkInp->objPath, &specCollCache, &dataObjUnlinkInp->condInput); status = getAndConnRcatHost (rsComm, MASTER_RCAT, dataObjUnlinkInp->objPath, &rodsServerHost); if (status < 0) { return (status); } else if (rodsServerHost->rcatEnabled == REMOTE_ICAT) { int retval; retval = rcDataObjUnlink (rodsServerHost->conn, dataObjUnlinkInp); return status; } if (getValByKey ( &dataObjUnlinkInp->condInput, IRODS_ADMIN_RMTRASH_KW) != NULL || getValByKey ( &dataObjUnlinkInp->condInput, IRODS_RMTRASH_KW) != NULL) { if (isTrashPath (dataObjUnlinkInp->objPath) == False) { return (SYS_INVALID_FILE_PATH); } rmTrashFlag = 1; } dataObjUnlinkInp->openFlags = O_WRONLY; /* set the permission checking */ status = getDataObjInfoIncSpecColl (rsComm, dataObjUnlinkInp, &dataObjInfoHead); if (status < 0) return (status); if (rmTrashFlag == 1) { char *tmpAge; int ageLimit; if ((tmpAge = getValByKey (&dataObjUnlinkInp->condInput, AGE_KW)) != NULL) { ageLimit = atoi (tmpAge) * 60; if ((time (0) - atoi (dataObjInfoHead->dataModify)) < ageLimit) { /* younger than ageLimit. Nothing to do */ freeAllDataObjInfo (dataObjInfoHead); return 0; } } } if (dataObjUnlinkInp->oprType == UNREG_OPR || getValByKey (&dataObjUnlinkInp->condInput, FORCE_FLAG_KW) != NULL || getValByKey (&dataObjUnlinkInp->condInput, REPL_NUM_KW) != NULL || dataObjInfoHead->specColl != NULL || rmTrashFlag == 1) { status = _rsDataObjUnlink (rsComm, dataObjUnlinkInp, &dataObjInfoHead); } else { initReiWithDataObjInp (&rei, rsComm, dataObjUnlinkInp); status = applyRule ("acTrashPolicy", NULL, &rei, NO_SAVE_REI); trashPolicy = rei.status; if (trashPolicy != NO_TRASH_CAN) { status = rsMvDataObjToTrash (rsComm, dataObjUnlinkInp, &dataObjInfoHead); freeAllDataObjInfo (dataObjInfoHead); return status; } else { status = _rsDataObjUnlink (rsComm, dataObjUnlinkInp, &dataObjInfoHead); } } initReiWithDataObjInp (&rei, rsComm, dataObjUnlinkInp); rei.doi = dataObjInfoHead; rei.status = status; rei.status = applyRule ("acPostProcForDelete", NULL, &rei, NO_SAVE_REI); if (rei.status < 0) { rodsLog (LOG_NOTICE, "rsDataObjUnlink: acPostProcForDelete error for %s. status = %d", dataObjUnlinkInp->objPath, rei.status); } /* dataObjInfoHead may be outdated */ freeAllDataObjInfo (dataObjInfoHead); return (status); }
int _rsPhyRmColl( rsComm_t *rsComm, collInp_t *rmCollInp, dataObjInfo_t *dataObjInfo, collOprStat_t **collOprStat ) { char *tmpValue; int status; collInp_t openCollInp; collEnt_t *collEnt; int handleInx; dataObjInp_t dataObjInp; collInp_t tmpCollInp; int rmtrashFlag = 0; int savedStatus = 0; int fileCntPerStatOut = FILE_CNT_PER_STAT_OUT; int entCnt = 0; ruleExecInfo_t rei; collInfo_t collInfo; memset( &openCollInp, 0, sizeof( openCollInp ) ); rstrcpy( openCollInp.collName, rmCollInp->collName, MAX_NAME_LEN ); /* cannot query recur because collection is sorted in wrong order */ openCollInp.flags = 0; handleInx = rsOpenCollection( rsComm, &openCollInp ); if ( handleInx < 0 ) { rodsLog( LOG_ERROR, "_rsPhyRmColl: rsOpenCollection of %s error. status = %d", openCollInp.collName, handleInx ); return handleInx; } memset( &dataObjInp, 0, sizeof( dataObjInp ) ); memset( &tmpCollInp, 0, sizeof( tmpCollInp ) ); /* catch the UNREG_OPR */ dataObjInp.oprType = tmpCollInp.oprType = rmCollInp->oprType; if ( ( tmpValue = getValByKey( &rmCollInp->condInput, AGE_KW ) ) != NULL ) { if ( CollHandle[handleInx].rodsObjStat != NULL ) { /* when a collection is moved, the modfiyTime of the object in * the collectin does not change. So, we'll depend on the * modfiyTime of the collection */ int ageLimit = atoi( tmpValue ) * 60; int modifyTime = atoi( CollHandle[handleInx].rodsObjStat->modifyTime ); if ( ( time( 0 ) - modifyTime ) < ageLimit ) { rsCloseCollection( rsComm, &handleInx ); return 0; } } addKeyVal( &dataObjInp.condInput, AGE_KW, tmpValue ); addKeyVal( &tmpCollInp.condInput, AGE_KW, tmpValue ); } addKeyVal( &dataObjInp.condInput, FORCE_FLAG_KW, "" ); addKeyVal( &tmpCollInp.condInput, FORCE_FLAG_KW, "" ); if ( ( tmpValue = getValByKey( &rmCollInp->condInput, AGE_KW ) ) != NULL ) { addKeyVal( &dataObjInp.condInput, AGE_KW, tmpValue ); addKeyVal( &tmpCollInp.condInput, AGE_KW, tmpValue ); } if ( collOprStat != NULL && *collOprStat == NULL ) { *collOprStat = ( collOprStat_t* )malloc( sizeof( collOprStat_t ) ); memset( *collOprStat, 0, sizeof( collOprStat_t ) ); } if ( getValByKey( &rmCollInp->condInput, ADMIN_RMTRASH_KW ) != NULL ) { if ( isTrashPath( rmCollInp->collName ) == False ) { return SYS_INVALID_FILE_PATH; } if ( rsComm->clientUser.authInfo.authFlag != LOCAL_PRIV_USER_AUTH ) { return CAT_INSUFFICIENT_PRIVILEGE_LEVEL; } addKeyVal( &tmpCollInp.condInput, ADMIN_RMTRASH_KW, "" ); addKeyVal( &dataObjInp.condInput, ADMIN_RMTRASH_KW, "" ); rmtrashFlag = 2; } else if ( getValByKey( &rmCollInp->condInput, RMTRASH_KW ) != NULL ) { if ( isTrashPath( rmCollInp->collName ) == False ) { return SYS_INVALID_FILE_PATH; } addKeyVal( &tmpCollInp.condInput, RMTRASH_KW, "" ); addKeyVal( &dataObjInp.condInput, RMTRASH_KW, "" ); rmtrashFlag = 1; } // =-=-=-=-=-=-=- // JMC - backport 4552 if ( getValByKey( &rmCollInp->condInput, EMPTY_BUNDLE_ONLY_KW ) != NULL ) { addKeyVal( &tmpCollInp.condInput, EMPTY_BUNDLE_ONLY_KW, "" ); addKeyVal( &dataObjInp.condInput, EMPTY_BUNDLE_ONLY_KW, "" ); } // =-=-=-=-=-=-=- while ( ( status = rsReadCollection( rsComm, &handleInx, &collEnt ) ) >= 0 ) { if ( entCnt == 0 ) { entCnt ++; /* cannot rm non-empty home collection */ if ( isHomeColl( rmCollInp->collName ) ) { return CANT_RM_NON_EMPTY_HOME_COLL; } } if ( collEnt->objType == DATA_OBJ_T ) { snprintf( dataObjInp.objPath, MAX_NAME_LEN, "%s/%s", collEnt->collName, collEnt->dataName ); status = rsDataObjUnlink( rsComm, &dataObjInp ); if ( status < 0 ) { rodsLog( LOG_ERROR, "_rsPhyRmColl:rsDataObjUnlink failed for %s. stat = %d", dataObjInp.objPath, status ); /* need to set global error here */ savedStatus = status; } else if ( collOprStat != NULL ) { ( *collOprStat )->filesCnt ++; if ( ( *collOprStat )->filesCnt >= fileCntPerStatOut ) { rstrcpy( ( *collOprStat )->lastObjPath, dataObjInp.objPath, MAX_NAME_LEN ); status = svrSendCollOprStat( rsComm, *collOprStat ); if ( status < 0 ) { rodsLogError( LOG_ERROR, status, "_rsPhyRmColl: svrSendCollOprStat failed for %s. status = %d", rmCollInp->collName, status ); *collOprStat = NULL; savedStatus = status; break; } *collOprStat = ( collOprStat_t* )malloc( sizeof( collOprStat_t ) ); memset( *collOprStat, 0, sizeof( collOprStat_t ) ); } } } else if ( collEnt->objType == COLL_OBJ_T ) { if ( strcmp( collEnt->collName, rmCollInp->collName ) == 0 ) { continue; /* duplicate */ } rstrcpy( tmpCollInp.collName, collEnt->collName, MAX_NAME_LEN ); if ( collEnt->specColl.collClass != NO_SPEC_COLL ) { if ( strcmp( collEnt->collName, collEnt->specColl.collection ) == 0 ) { continue; /* no mount point */ } } initReiWithCollInp( &rei, rsComm, &tmpCollInp, &collInfo ); status = applyRule( "acPreprocForRmColl", NULL, &rei, NO_SAVE_REI ); if ( status < 0 ) { if ( rei.status < 0 ) { status = rei.status; } rodsLog( LOG_ERROR, "_rsPhyRmColl:acPreprocForRmColl error for %s,stat=%d", tmpCollInp.collName, status ); return status; } status = _rsRmCollRecur( rsComm, &tmpCollInp, collOprStat ); rei.status = status; rei.status = applyRule( "acPostProcForRmColl", NULL, &rei, NO_SAVE_REI ); if ( rei.status < 0 ) { rodsLog( LOG_ERROR, "_rsRmColl:acPostProcForRmColl error for %s,stat=%d", tmpCollInp.collName, status ); } } if ( status < 0 ) { savedStatus = status; } free( collEnt ); /* just free collEnt but not content */ } rsCloseCollection( rsComm, &handleInx ); if ( ( rmtrashFlag > 0 && ( isTrashHome( rmCollInp->collName ) > 0 || // JMC - backport 4561 isOrphanPath( rmCollInp->collName ) == is_ORPHAN_HOME ) ) || ( isBundlePath( rmCollInp->collName ) == True && getValByKey( &rmCollInp->condInput, EMPTY_BUNDLE_ONLY_KW ) != NULL ) ) { /* don't rm user's home trash coll or orphan collection */ status = 0; } else { if ( dataObjInfo != NULL && dataObjInfo->specColl != NULL ) { if ( dataObjInfo->specColl->collClass == LINKED_COLL ) { rstrcpy( rmCollInp->collName, dataObjInfo->objPath, MAX_NAME_LEN ); status = svrUnregColl( rsComm, rmCollInp ); } else { status = l3Rmdir( rsComm, dataObjInfo ); } } else { status = svrUnregColl( rsComm, rmCollInp ); if ( status < 0 ) { savedStatus = status; } } } clearKeyVal( &tmpCollInp.condInput ); clearKeyVal( &dataObjInp.condInput ); return savedStatus; }
int rsDataObjUnlink( rsComm_t *rsComm, dataObjInp_t *dataObjUnlinkInp ) { int status; ruleExecInfo_t rei; int trashPolicy; dataObjInfo_t *dataObjInfoHead = NULL; rodsServerHost_t *rodsServerHost = NULL; int rmTrashFlag = 0; specCollCache_t *specCollCache = NULL; resolveLinkedPath( rsComm, dataObjUnlinkInp->objPath, &specCollCache, &dataObjUnlinkInp->condInput ); status = getAndConnRcatHost( rsComm, MASTER_RCAT, ( const char* )dataObjUnlinkInp->objPath, &rodsServerHost ); if ( status < 0 || NULL == rodsServerHost ) { // JMC cppcheck - nullptr return status; } else if ( rodsServerHost->rcatEnabled == REMOTE_ICAT ) { rcDataObjUnlink( rodsServerHost->conn, dataObjUnlinkInp ); return status; } // =-=-=-=-=-=-=- // working on the "home zone", determine if we need to redirect to a different // server in this zone for this operation. if there is a RESC_HIER_STR_KW then // we know that the redirection decision has already been made // =-=-=-=-=-=-=- // determine the resource hierarchy if one is not provided addKeyVal( &dataObjUnlinkInp->condInput, irods::UNLINK_OPERATION.c_str(), "true" ); if ( getValByKey( &dataObjUnlinkInp->condInput, RESC_HIER_STR_KW ) == NULL ) { std::string hier; irods::error ret = irods::resolve_resource_hierarchy( irods::OPEN_OPERATION, rsComm, dataObjUnlinkInp, hier ); if ( !ret.ok() ) { std::stringstream msg; msg << "failed in irods::resolve_resource_hierarchy for ["; msg << dataObjUnlinkInp->objPath << "]"; irods::log( PASSMSG( msg.str(), ret ) ); return ret.code(); } // =-=-=-=-=-=-=- // we resolved the redirect and have a host, set the hier str for subsequent // api calls, etc. addKeyVal( &dataObjUnlinkInp->condInput, RESC_HIER_STR_KW, hier.c_str() ); } // if keyword if ( getValByKey( &dataObjUnlinkInp->condInput, ADMIN_RMTRASH_KW ) != NULL || getValByKey( &dataObjUnlinkInp->condInput, RMTRASH_KW ) != NULL ) { if ( isTrashPath( dataObjUnlinkInp->objPath ) == False ) { return SYS_INVALID_FILE_PATH; } rmTrashFlag = 1; } dataObjUnlinkInp->openFlags = O_WRONLY; /* set the permission checking */ status = getDataObjInfoIncSpecColl( rsComm, dataObjUnlinkInp, &dataObjInfoHead ); if ( status < 0 ) { char* sys_error = NULL; const char* rods_error = rodsErrorName( status, &sys_error ); std::stringstream msg; msg << __FUNCTION__; msg << " - Failed to get data objects."; msg << " - " << rods_error << " " << sys_error; irods::error result = ERROR( status, msg.str() ); irods::log( result ); free( sys_error ); return status; } if ( rmTrashFlag == 1 ) { char *tmpAge; int ageLimit; if ( ( tmpAge = getValByKey( &dataObjUnlinkInp->condInput, AGE_KW ) ) != NULL ) { ageLimit = atoi( tmpAge ) * 60; if ( ( time( 0 ) - atoi( dataObjInfoHead->dataModify ) ) < ageLimit ) { /* younger than ageLimit. Nothing to do */ freeAllDataObjInfo( dataObjInfoHead ); return 0; } } } if ( dataObjUnlinkInp->oprType == UNREG_OPR || getValByKey( &dataObjUnlinkInp->condInput, FORCE_FLAG_KW ) != NULL || getValByKey( &dataObjUnlinkInp->condInput, REPL_NUM_KW ) != NULL || getValByKey( &dataObjUnlinkInp->condInput, EMPTY_BUNDLE_ONLY_KW ) != NULL || dataObjInfoHead->specColl != NULL || rmTrashFlag == 1 ) { status = _rsDataObjUnlink( rsComm, dataObjUnlinkInp, &dataObjInfoHead ); } else { initReiWithDataObjInp( &rei, rsComm, dataObjUnlinkInp ); status = applyRule( "acTrashPolicy", NULL, &rei, NO_SAVE_REI ); trashPolicy = rei.status; if ( trashPolicy != NO_TRASH_CAN ) { status = rsMvDataObjToTrash( rsComm, dataObjUnlinkInp, &dataObjInfoHead ); freeAllDataObjInfo( dataObjInfoHead ); return status; } else { status = _rsDataObjUnlink( rsComm, dataObjUnlinkInp, &dataObjInfoHead ); } } initReiWithDataObjInp( &rei, rsComm, dataObjUnlinkInp ); rei.doi = dataObjInfoHead; rei.status = status; // make resource properties available as rule session variables rei.condInputData = (keyValPair_t *)malloc(sizeof(keyValPair_t)); memset(rei.condInputData, 0, sizeof(keyValPair_t)); irods::get_resc_properties_as_kvp(rei.doi->rescHier, rei.condInputData); rei.status = applyRule( "acPostProcForDelete", NULL, &rei, NO_SAVE_REI ); if ( rei.status < 0 ) { rodsLog( LOG_NOTICE, "rsDataObjUnlink: acPostProcForDelete error for %s. status = %d", dataObjUnlinkInp->objPath, rei.status ); } /* dataObjInfoHead may be outdated */ freeAllDataObjInfo( dataObjInfoHead ); return status; }