mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-04 23:55:26 +02:00
[392012] [dstore] make server safer for delete operations
This commit is contained in:
parent
1062b05a6a
commit
4b0b3fbd1b
3 changed files with 139 additions and 93 deletions
|
@ -45,6 +45,7 @@
|
|||
* David McKnight (IBM) - [371401] [dstore][multithread] avoid use of static variables - causes memory leak after disconnect
|
||||
* Noriaki Takatsu (IBM) - [380562] [multithread][dstore] File Search is not canceled by the client UI on disconnect
|
||||
* David McKnight (IBM) - [390037] [dstore] Duplicated items in the System view
|
||||
* David McKnight (IBM) - [392012] [dstore] make server safer for delete operations
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.dstore.universal.miners;
|
||||
|
@ -53,6 +54,7 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -462,6 +464,7 @@ public class UniversalFileSystemMiner extends Miner {
|
|||
public void updateCancellableThreads(DataElement command, ICancellableHandler thread)
|
||||
{
|
||||
//First Check to make sure that there are no "zombie" threads
|
||||
List threadsToRemove = new ArrayList();
|
||||
Iterator iter = _cancellableThreads.keySet().iterator();
|
||||
try
|
||||
{
|
||||
|
@ -472,7 +475,12 @@ public class UniversalFileSystemMiner extends Miner {
|
|||
if ((theThread == null) ||
|
||||
theThread.isDone() || theThread.isCancelled())
|
||||
{
|
||||
_cancellableThreads.remove(threadElement);
|
||||
threadsToRemove.add(threadElement);
|
||||
}
|
||||
}
|
||||
if (!threadsToRemove.isEmpty()){
|
||||
for (int i = 0; i < threadsToRemove.size(); i++){
|
||||
_cancellableThreads.remove(threadsToRemove.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -485,7 +493,7 @@ public class UniversalFileSystemMiner extends Miner {
|
|||
_cancellableThreads.put(command, thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Method to list the files for a given filter.
|
||||
|
@ -645,10 +653,24 @@ public class UniversalFileSystemMiner extends Miner {
|
|||
* Method to Delete a file or folder.
|
||||
*/
|
||||
public DataElement handleDelete(DataElement subject, DataElement status, boolean refreshDataStore) {
|
||||
DeleteThread deleteThread = new DeleteThread(subject, this, _dataStore, false, status);
|
||||
deleteThread.start();
|
||||
// first make sure this is a valid object to delete
|
||||
String type = subject.getType();
|
||||
if (IUniversalDataStoreConstants.UNIVERSAL_FOLDER_DESCRIPTOR.equals(type) ||
|
||||
IUniversalDataStoreConstants.UNIVERSAL_FILE_DESCRIPTOR.equals(type) ||
|
||||
IUniversalDataStoreConstants.UNIVERSAL_ARCHIVE_FILE_DESCRIPTOR.equals(type) ||
|
||||
IUniversalDataStoreConstants.UNIVERSAL_VIRTUAL_FILE_DESCRIPTOR.equals(type) ||
|
||||
IUniversalDataStoreConstants.UNIVERSAL_VIRTUAL_FOLDER_DESCRIPTOR.equals(type) ||
|
||||
IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR.equals(type)){
|
||||
|
||||
DeleteThread deleteThread = new DeleteThread(subject, this, _dataStore, false, status);
|
||||
deleteThread.start();
|
||||
|
||||
updateCancellableThreads(status.getParent(), deleteThread);
|
||||
updateCancellableThreads(status.getParent(), deleteThread);
|
||||
}
|
||||
else {
|
||||
UniversalServerUtilities.logWarning(getName(), "illegal deletion type: " + type, _dataStore); //$NON-NLS-1$
|
||||
statusCancelled(status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -659,9 +681,9 @@ public class UniversalFileSystemMiner extends Miner {
|
|||
deleteThread.start();
|
||||
|
||||
updateCancellableThreads(status.getParent(), deleteThread);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to Rename a file or folder.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2011 IBM Corporation and others.
|
||||
* Copyright (c) 2007, 2012 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -16,6 +16,7 @@
|
|||
* David McKnight (IBM) - [264607] Unable to delete a broken symlink
|
||||
* David McKnight (IBM) - [321026][dstore] Broken symbolic link can't be removed
|
||||
* David McKnight (IBM) - [342450][dstore] Real files should not be deleted when deleting a symbolic link
|
||||
* David McKnight (IBM) - [392012] [dstore] make server safer for delete operations
|
||||
*******************************************************************************/
|
||||
package org.eclipse.rse.internal.dstore.universal.miners.filesystem;
|
||||
|
||||
|
@ -119,97 +120,107 @@ public class DeleteThread extends SecuredThread implements ICancellableHandler {
|
|||
}
|
||||
private DataElement handleDelete(DataElement subject, DataElement thisStatus) throws SystemMessageException
|
||||
{
|
||||
|
||||
String type = subject.getType();
|
||||
if (type.equals(IUniversalDataStoreConstants.UNIVERSAL_VIRTUAL_FILE_DESCRIPTOR)
|
||||
|| type.equals(IUniversalDataStoreConstants.UNIVERSAL_VIRTUAL_FOLDER_DESCRIPTOR)) {
|
||||
return handleDeleteFromArchive(subject, thisStatus);
|
||||
}
|
||||
|
||||
File deleteObj = new File(subject.getAttribute(DE.A_VALUE)
|
||||
+ File.separatorChar + subject.getName());
|
||||
DataElement deObj = null;
|
||||
|
||||
String attributes = subject.getSource();
|
||||
String classification = "file"; //$NON-NLS-1$
|
||||
String[] str = attributes.split("\\"+IServiceConstants.TOKEN_SEPARATOR); //$NON-NLS-1$
|
||||
if (str.length > 11){ // 11 is classification index
|
||||
classification = str[11];
|
||||
}
|
||||
boolean exists = deleteObj.exists();
|
||||
if (!exists){
|
||||
// special case for broken symbolic link
|
||||
if (classification.startsWith("broken symbolic link")){ //$NON-NLS-1$
|
||||
exists = true;
|
||||
else if (IUniversalDataStoreConstants.UNIVERSAL_FOLDER_DESCRIPTOR.equals(type) ||
|
||||
IUniversalDataStoreConstants.UNIVERSAL_FILE_DESCRIPTOR.equals(type) ||
|
||||
IUniversalDataStoreConstants.UNIVERSAL_ARCHIVE_FILE_DESCRIPTOR.equals(type) ||
|
||||
IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR.equals(type)){
|
||||
|
||||
String path = subject.getAttribute(DE.A_VALUE)+ File.separatorChar + subject.getName();
|
||||
if (path.equals(""+File.separatorChar)){ // no path provided //$NON-NLS-1$
|
||||
return _miner.statusCancelled(_status);
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED_WITH_DOES_NOT_EXIST + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
UniversalServerUtilities.logError(CLASSNAME,
|
||||
"The object to delete does not exist", null, _dataStore); //$NON-NLS-1$
|
||||
} else {
|
||||
try {
|
||||
if (classification != null && classification.startsWith("symbolic link")){ //$NON-NLS-1$
|
||||
// only delete the link - no the actual file or folder contents
|
||||
deleteObj.delete();
|
||||
File deleteObj = new File(path);
|
||||
DataElement deObj = null;
|
||||
|
||||
String attributes = subject.getSource();
|
||||
String classification = "file"; //$NON-NLS-1$
|
||||
String[] str = attributes.split("\\"+IServiceConstants.TOKEN_SEPARATOR); //$NON-NLS-1$
|
||||
if (str.length > 11){ // 11 is classification index
|
||||
classification = str[11];
|
||||
}
|
||||
boolean exists = deleteObj.exists();
|
||||
if (!exists){
|
||||
// special case for broken symbolic link
|
||||
if (classification.startsWith("broken symbolic link")){ //$NON-NLS-1$
|
||||
exists = true;
|
||||
}
|
||||
else if (deleteObj.isFile()) {
|
||||
if (deleteObj.delete() == false) {
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
} else {
|
||||
// delete was successful and delete the object from the
|
||||
// datastore
|
||||
deObj = _dataStore.find(subject, DE.A_NAME, subject
|
||||
.getName(), 1);
|
||||
_dataStore.deleteObject(subject, deObj);
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.SUCCESS + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
}
|
||||
_dataStore.refresh(subject);
|
||||
} else if (deleteObj.isDirectory()) { // it is directory and
|
||||
// need to delete the
|
||||
// entire directory +
|
||||
// children
|
||||
deleteDir(deleteObj, thisStatus);
|
||||
if (deleteObj.delete() == false) {
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
UniversalServerUtilities.logError(CLASSNAME,
|
||||
"Deletion of dir fialed", null, _dataStore); //$NON-NLS-1$
|
||||
} else {
|
||||
_dataStore.deleteObjects(subject);
|
||||
DataElement parent = subject.getParent();
|
||||
_dataStore.deleteObject(parent, subject);
|
||||
_dataStore.refresh(parent);
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.SUCCESS + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
}
|
||||
} else {
|
||||
// try to treat this as a file
|
||||
if (deleteObj.delete() == false) {
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
UniversalServerUtilities
|
||||
.logError(
|
||||
CLASSNAME,
|
||||
"The object to delete is neither a File or Folder! in handleDelete", //$NON-NLS-1$
|
||||
null, _dataStore);
|
||||
} else {
|
||||
// delete was successful and delete the object from the
|
||||
// datastore
|
||||
deObj = _dataStore.find(subject, DE.A_NAME, subject
|
||||
.getName(), 1);
|
||||
_dataStore.deleteObject(subject, deObj);
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.SUCCESS + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
}
|
||||
_dataStore.refresh(subject);
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED_WITH_EXCEPTION + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
thisStatus.setAttribute(DE.A_VALUE, e.getLocalizedMessage());
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED_WITH_DOES_NOT_EXIST + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
UniversalServerUtilities.logError(CLASSNAME,
|
||||
"Delete of the object failed", e, _dataStore); //$NON-NLS-1$
|
||||
"The object to delete does not exist", null, _dataStore); //$NON-NLS-1$
|
||||
} else {
|
||||
try {
|
||||
if (classification != null && classification.startsWith("symbolic link")){ //$NON-NLS-1$
|
||||
// only delete the link - no the actual file or folder contents
|
||||
deleteObj.delete();
|
||||
}
|
||||
else if (deleteObj.isFile()) {
|
||||
if (deleteObj.delete() == false) {
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
} else {
|
||||
// delete was successful and delete the object from the
|
||||
// datastore
|
||||
deObj = _dataStore.find(subject, DE.A_NAME, subject
|
||||
.getName(), 1);
|
||||
_dataStore.deleteObject(subject, deObj);
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.SUCCESS + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
}
|
||||
_dataStore.refresh(subject);
|
||||
} else if (deleteObj.isDirectory()) { // it is directory and
|
||||
// need to delete the
|
||||
// entire directory +
|
||||
// children
|
||||
deleteDir(deleteObj, thisStatus);
|
||||
if (deleteObj.delete() == false) {
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
UniversalServerUtilities.logError(CLASSNAME,
|
||||
"Deletion of dir fialed", null, _dataStore); //$NON-NLS-1$
|
||||
} else {
|
||||
_dataStore.deleteObjects(subject);
|
||||
DataElement parent = subject.getParent();
|
||||
_dataStore.deleteObject(parent, subject);
|
||||
_dataStore.refresh(parent);
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.SUCCESS + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
}
|
||||
} else {
|
||||
// try to treat this as a file
|
||||
if (deleteObj.delete() == false) {
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
UniversalServerUtilities
|
||||
.logError(
|
||||
CLASSNAME,
|
||||
"The object to delete is neither a File or Folder! in handleDelete", //$NON-NLS-1$
|
||||
null, _dataStore);
|
||||
} else {
|
||||
// delete was successful and delete the object from the
|
||||
// datastore
|
||||
deObj = _dataStore.find(subject, DE.A_NAME, subject
|
||||
.getName(), 1);
|
||||
_dataStore.deleteObject(subject, deObj);
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.SUCCESS + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
}
|
||||
_dataStore.refresh(subject);
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
thisStatus.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED_WITH_EXCEPTION + "|" + deleteObj.getAbsolutePath()); //$NON-NLS-1$
|
||||
thisStatus.setAttribute(DE.A_VALUE, e.getLocalizedMessage());
|
||||
UniversalServerUtilities.logError(CLASSNAME,
|
||||
"Delete of the object failed", e, _dataStore); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
_dataStore.refresh(subject);
|
||||
}
|
||||
else {
|
||||
_dataStore.trace("attempt to delete "+subject + " prevented"); //$NON-NLS-1$//$NON-NLS-2$
|
||||
}
|
||||
_dataStore.refresh(subject);
|
||||
return _miner.statusDone(_status);
|
||||
|
||||
}
|
||||
|
@ -254,7 +265,7 @@ public class DeleteThread extends SecuredThread implements ICancellableHandler {
|
|||
public void deleteDir(File fileObj, DataElement status) {
|
||||
try {
|
||||
File list[] = fileObj.listFiles();
|
||||
for (int i = 0; i < list.length; ++i) {
|
||||
for (int i = 0; i < list.length && !_isCancelled; ++i) {
|
||||
if (list[i].isFile()) {
|
||||
if (!(list[i].delete())) {
|
||||
status.setAttribute(DE.A_SOURCE, IServiceConstants.FAILED);
|
||||
|
|
|
@ -1524,7 +1524,12 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer
|
|||
public void delete(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException
|
||||
{
|
||||
String remotePath = remoteParent + getSeparator(remoteParent) + fileName;
|
||||
DataElement de = getElementFor(remotePath);
|
||||
|
||||
// always get a fresh element for deletions (spiriting could cause issues on server-side)
|
||||
DataElement universaltemp = getMinerElement();
|
||||
String normalizedPath = PathUtility.normalizeUnknown(remotePath);
|
||||
DataElement de = universaltemp.getDataStore().createObject(universaltemp, IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR, normalizedPath, normalizedPath, "", false); //$NON-NLS-1$
|
||||
|
||||
// if we don't have a proper element, we won't have a command descriptor
|
||||
if (de.getType().equals(IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR)){
|
||||
// need to fetch
|
||||
|
@ -1568,12 +1573,16 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer
|
|||
delete(remoteParents[0], fileNames[0], monitor);
|
||||
return;
|
||||
}
|
||||
|
||||
DataElement universaltemp = getMinerElement();
|
||||
ArrayList dataElements = new ArrayList(remoteParents.length);
|
||||
for (int i = 0; i < remoteParents.length; i++)
|
||||
{
|
||||
String remotePath = remoteParents[i] + getSeparator(remoteParents[i]) + fileNames[i];
|
||||
DataElement de = getElementFor(remotePath);
|
||||
|
||||
// always get a fresh element for deletions (spiriting could cause issues on server-side)
|
||||
String normalizedPath = PathUtility.normalizeUnknown(remotePath);
|
||||
DataElement de = universaltemp.getDataStore().createObject(universaltemp, IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR, normalizedPath, normalizedPath, "", false); //$NON-NLS-1$
|
||||
|
||||
// if we don't have a proper element, we won't have a command descriptor
|
||||
if (de.getType().equals(IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR)){
|
||||
// need to fetch
|
||||
|
@ -1633,7 +1642,11 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer
|
|||
newPath = remoteParent + getSeparator(remoteParent) + newName;
|
||||
}
|
||||
|
||||
DataElement de = getElementFor(oldPath);
|
||||
// always get a fresh element for renames (spiriting could cause issues on server-side)
|
||||
DataElement universaltemp = getMinerElement();
|
||||
String normalizedPath = PathUtility.normalizeUnknown(oldPath);
|
||||
DataElement de = universaltemp.getDataStore().createObject(universaltemp, IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR, normalizedPath, normalizedPath, "", false); //$NON-NLS-1$
|
||||
|
||||
// if we don't have a proper element, we won't have a command descriptor
|
||||
if (de.getType().equals(IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR)){
|
||||
// need to fetch
|
||||
|
|
Loading…
Add table
Reference in a new issue