int dataObjUnlinkS (rsComm_t *rsComm, dataObjInp_t *dataObjUnlinkInp, dataObjInfo_t *dataObjInfo) { int status; unregDataObj_t unregDataObjInp; if (dataObjInfo->specColl == NULL) { if (dataObjUnlinkInp->oprType == UNREG_OPR && rsComm->clientUser.authInfo.authFlag != LOCAL_PRIV_USER_AUTH) { ruleExecInfo_t rei; initReiWithDataObjInp (&rei, rsComm, dataObjUnlinkInp); rei.doi = dataObjInfo; rei.status = DO_CHK_PATH_PERM; /* default */ applyRule ("acSetChkFilePathPerm", NULL, &rei, NO_SAVE_REI); if (rei.status != NO_CHK_PATH_PERM) { char *outVaultPath; rodsServerHost_t *rodsServerHost; status = resolveHostByRescInfo (dataObjInfo->rescInfo, &rodsServerHost); if (status < 0) return status; /* unregistering but not an admin user */ status = matchVaultPath (rsComm, dataObjInfo->filePath, rodsServerHost, &outVaultPath); if (status != 0) { /* in the vault */ rodsLog (LOG_DEBUG, "dataObjUnlinkS: unregistering in vault file %s", dataObjInfo->filePath); return CANT_UNREG_IN_VAULT_FILE; } } #if 0 /* don't need this since we are doing orphan */ } else if (RescTypeDef[dataObjInfo->rescInfo->rescTypeInx].driverType == WOS_FILE_TYPE && dataObjUnlinkInp->oprType != UNREG_OPR) { /* WOS_FILE_TYPE, unlink first before unreg because orphan files * cannot be reclaimed */ status = l3Unlink (rsComm, dataObjInfo); if (status < 0) { rodsLog (LOG_NOTICE, "dataObjUnlinkS: l3Unlink error for WOS file %s. status = %d", dataObjUnlinkInp->objPath, status); return status; } unregDataObjInp.dataObjInfo = dataObjInfo; unregDataObjInp.condInput = &dataObjUnlinkInp->condInput; status = rsUnregDataObj (rsComm, &unregDataObjInp); if (status < 0) { rodsLog (LOG_NOTICE, "dataObjUnlinkS: rsUnregDataObj error for %s. status = %d", dataObjUnlinkInp->objPath, status); } return status; #endif } unregDataObjInp.dataObjInfo = dataObjInfo; unregDataObjInp.condInput = &dataObjUnlinkInp->condInput; status = rsUnregDataObj (rsComm, &unregDataObjInp); if (status < 0) { rodsLog (LOG_NOTICE, "dataObjUnlinkS: rsUnregDataObj error for %s. status = %d", dataObjUnlinkInp->objPath, status); return status; } } if (dataObjUnlinkInp->oprType != UNREG_OPR) { status = l3Unlink (rsComm, dataObjInfo); if (status < 0) { int myError = getErrno (status); rodsLog (LOG_NOTICE, "dataObjUnlinkS: l3Unlink error for %s. status = %d", dataObjUnlinkInp->objPath, status); /* allow ENOENT to go on and unregister */ if (myError != ENOENT && myError != EACCES) { char orphanPath[MAX_NAME_LEN]; int status1 = 0; rodsLog (LOG_NOTICE, "dataObjUnlinkS: orphan file %s", dataObjInfo->filePath); while (1) { if (isOrphanPath (dataObjUnlinkInp->objPath) == NOT_ORPHAN_PATH) { /* don't rename orphan path */ status1 = rsMkOrphanPath (rsComm, dataObjInfo->objPath, orphanPath); if (status1 < 0) break; /* reg the orphan path */ rstrcpy (dataObjInfo->objPath, orphanPath,MAX_NAME_LEN); } status1 = svrRegDataObj (rsComm, dataObjInfo); if (status1 == CAT_NAME_EXISTS_AS_DATAOBJ || status1 == CATALOG_ALREADY_HAS_ITEM_BY_THAT_NAME) { continue; } else if (status1 < 0) { rodsLogError (LOG_ERROR, status1, "dataObjUnlinkS: svrRegDataObj of orphan %s error", dataObjInfo->objPath); } break; } return (status); } else { status = 0; } } } 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 dataObjUnlinkS( rsComm_t *rsComm, dataObjInp_t *dataObjUnlinkInp, dataObjInfo_t *dataObjInfo ) { int status = 0; unregDataObj_t unregDataObjInp; if ( dataObjInfo->specColl == NULL ) { if ( dataObjUnlinkInp->oprType == UNREG_OPR && rsComm->clientUser.authInfo.authFlag != LOCAL_PRIV_USER_AUTH ) { ruleExecInfo_t rei; initReiWithDataObjInp( &rei, rsComm, dataObjUnlinkInp ); rei.doi = dataObjInfo; rei.status = DO_CHK_PATH_PERM; /* default */ // JMC - backport 4758 // 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); applyRule( "acSetChkFilePathPerm", NULL, &rei, NO_SAVE_REI ); if ( rei.status != NO_CHK_PATH_PERM ) { // =-=-=-=-=-=-=- // extract the host location from the resource hierarchy std::string location; irods::error ret = irods::get_loc_for_hier_string( dataObjInfo->rescHier, location ); if ( !ret.ok() ) { irods::log( PASSMSG( "dataObjUnlinkS - failed in get_loc_for_hier_string", ret ) ); return ret.code(); } rodsHostAddr_t addr; rodsServerHost_t *rodsServerHost = 0; memset( &addr, 0, sizeof( addr ) ); rstrcpy( addr.hostAddr, location.c_str(), NAME_LEN ); int remoteFlag = resolveHost( &addr, &rodsServerHost ); if ( remoteFlag < 0 ) { // error condition? } /* unregistering but not an admin user */ std::string out_path; ret = resc_mgr.validate_vault_path( dataObjInfo->filePath, rodsServerHost, out_path ); if ( !ret.ok() ) { /* in the vault */ std::stringstream msg; msg << "unregistering a data object which is in a vault ["; msg << dataObjInfo->filePath << "]"; irods::log( PASSMSG( msg.str(), ret ) ); return CANT_UNREG_IN_VAULT_FILE; } } } unregDataObjInp.dataObjInfo = dataObjInfo; unregDataObjInp.condInput = &dataObjUnlinkInp->condInput; status = rsUnregDataObj( rsComm, &unregDataObjInp ); if ( status < 0 ) { rodsLog( LOG_NOTICE, "dataObjUnlinkS: rsUnregDataObj error for %s. status = %d", dataObjUnlinkInp->objPath, status ); return status; } } if ( dataObjUnlinkInp->oprType != UNREG_OPR ) { // Set the in_pdmo flag char* in_pdmo = getValByKey( &dataObjUnlinkInp->condInput, IN_PDMO_KW ); if ( in_pdmo != NULL ) { rstrcpy( dataObjInfo->in_pdmo, in_pdmo, MAX_NAME_LEN ); } else { dataObjInfo->in_pdmo[0] = '\0'; } status = l3Unlink( rsComm, dataObjInfo ); if ( status < 0 ) { int myError = getErrno( status ); rodsLog( LOG_NOTICE, "dataObjUnlinkS: l3Unlink error for %s. status = %d", dataObjUnlinkInp->objPath, status ); /* allow ENOENT to go on and unregister */ if ( myError != ENOENT && myError != EACCES ) { char orphanPath[MAX_NAME_LEN]; int status1 = 0; rodsLog( LOG_NOTICE, "dataObjUnlinkS: orphan file %s", dataObjInfo->filePath ); while ( 1 ) { if ( isOrphanPath( dataObjUnlinkInp->objPath ) == NOT_ORPHAN_PATH ) { /* don't rename orphan path */ status1 = rsMkOrphanPath( rsComm, dataObjInfo->objPath, orphanPath ); if ( status1 < 0 ) { break; } /* reg the orphan path */ rstrcpy( dataObjInfo->objPath, orphanPath, MAX_NAME_LEN ); } status1 = svrRegDataObj( rsComm, dataObjInfo ); if ( status1 == CAT_NAME_EXISTS_AS_DATAOBJ || status1 == CATALOG_ALREADY_HAS_ITEM_BY_THAT_NAME ) { continue; } else if ( status1 < 0 ) { rodsLogError( LOG_ERROR, status1, "dataObjUnlinkS: svrRegDataObj of orphan %s error", dataObjInfo->objPath ); } break; } return status; } else { status = 0; } } } return status; }