1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-26 02:15:31 +02:00

[285226] Empty directory shown as an error message

This commit is contained in:
Martin Oberhuber 2009-08-06 21:37:50 +00:00
parent ccb3160638
commit cbbb53e06e
6 changed files with 243 additions and 17 deletions

View file

@ -596,7 +596,7 @@
<feature url="features/org.eclipse.rse.sdk_3.1.1.qualifier.jar" id="org.eclipse.rse.sdk" version="3.1.1.qualifier">
<category name="TM and RSE 3.1.1"/>
</feature>
<feature url="features/org.eclipse.rse.ssh_3.0.0.qualifier.jar" id="org.eclipse.rse.ssh" version="3.0.0.qualifier">
<feature url="features/org.eclipse.rse.ssh_3.0.1.qualifier.jar" id="org.eclipse.rse.ssh" version="3.0.1.qualifier">
<category name="TM and RSE 3.1.1"/>
</feature>
<feature url="features/org.eclipse.rse.telnet_2.2.1.qualifier.jar" id="org.eclipse.rse.telnet" version="2.2.1.qualifier">
@ -608,7 +608,7 @@
<feature url="features/org.eclipse.rse.terminals_1.0.1.qualifier.jar" id="org.eclipse.rse.terminals" version="1.0.1.qualifier">
<category name="TM and RSE 3.1.1"/>
</feature>
<feature url="features/org.eclipse.rse.tests_3.1.0.qualifier.jar" id="org.eclipse.rse.tests" version="3.1.0.qualifier">
<feature url="features/org.eclipse.rse.tests_3.1.1.qualifier.jar" id="org.eclipse.rse.tests" version="3.1.1.qualifier">
<category name="TM and RSE 3.1.1"/>
</feature>
<feature url="features/org.eclipse.rse.useractions_1.1.100.qualifier.jar" id="org.eclipse.rse.useractions" version="1.1.100.qualifier">

View file

@ -12,7 +12,7 @@
<feature
id="org.eclipse.rse.ssh"
label="%featureName"
version="3.0.0.qualifier"
version="3.0.1.qualifier"
provider-name="%providerName"
plugin="org.eclipse.rse.services.ssh">

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.rse.services.ssh;singleton:=true
Bundle-Version: 3.0.0.qualifier
Bundle-Version: 3.0.1.qualifier
Bundle-Activator: org.eclipse.rse.internal.services.ssh.Activator
Bundle-Vendor: %providerName
Bundle-Localization: plugin

View file

@ -39,6 +39,7 @@
* David McKnight (IBM) - [271244] [sftp files] "My Home" filter not working
* David McKnight (IBM) - [272882] [api] Handle exceptions in IService.initService()
* Martin Oberhuber (Wind River) - [274568] Dont use SftpMonitor for Streams transfer
* Patrick Tassé (Ericsson) - [285226] Empty directory shown as an error message
*******************************************************************************/
package org.eclipse.rse.internal.services.ssh.files;
@ -87,6 +88,7 @@ import org.eclipse.rse.services.clientserver.messages.SystemMessage;
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
import org.eclipse.rse.services.clientserver.messages.SystemOperationCancelledException;
import org.eclipse.rse.services.clientserver.messages.SystemOperationFailedException;
import org.eclipse.rse.services.clientserver.messages.SystemRemoteSecurityException;
import org.eclipse.rse.services.clientserver.messages.SystemUnexpectedErrorException;
import org.eclipse.rse.services.files.AbstractFileService;
import org.eclipse.rse.services.files.HostFilePermissions;
@ -95,8 +97,8 @@ import org.eclipse.rse.services.files.IFileService;
import org.eclipse.rse.services.files.IHostFile;
import org.eclipse.rse.services.files.IHostFilePermissions;
import org.eclipse.rse.services.files.IHostFilePermissionsContainer;
import org.eclipse.rse.services.files.RemoteFileException;
import org.eclipse.rse.services.files.RemoteFileIOException;
import org.eclipse.rse.services.files.RemoteFileSecurityException;
public class SftpFileService extends AbstractFileService implements ISshService, IFilePermissionsService
{
@ -438,7 +440,7 @@ public class SftpFileService extends AbstractFileService implements ISshService,
SystemMessageException messageException;
SftpException sftpe = (SftpException)e;
if (sftpe.id == ChannelSftp.SSH_FX_PERMISSION_DENIED) {
messageException = new RemoteFileSecurityException(e);
messageException = new SystemRemoteSecurityException(Activator.PLUGIN_ID, e.getLocalizedMessage(), e);
} else if (sftpe.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
//TODO better throw SENFE at the place where we know what element and operation is done
messageException = new SystemElementNotFoundException("", ""); //$NON-NLS-1$ //$NON-NLS-2$
@ -548,6 +550,15 @@ public class SftpFileService extends AbstractFileService implements ISshService,
//don't show the trivial names
continue;
}
if (vv.size() == 1 && fileName.equals(parentPath.substring(parentPath.lastIndexOf('/') + 1))) {
//If there is only one entry and it has the same name as the parent path, the parentPath could be a file.
//Check if the parentPath is a directory.
SftpATTRS attrs = getChannel("SftpFileService.internalFetch: " + parentPath).stat(parentPath); //$NON-NLS-1$
if (!attrs.isDir()) {
// parent was a file and not a folder
throw new RemoteFileException("Not a folder: " + parentPath); //$NON-NLS-1$
}
}
if (filematcher.matches(fileName) || (lsEntry.getAttrs().isDir() && fileType!=IFileService.FILE_TYPE_FOLDERS)) {
//get ALL directory names (unless looking for folders only)
SftpHostFile node = makeHostFile(parentPath, fileName, lsEntry.getAttrs());
@ -560,6 +571,22 @@ public class SftpFileService extends AbstractFileService implements ISshService,
}
Activator.trace("SftpFileService.internalFetch <--"); //$NON-NLS-1$
} catch(Exception e) {
if ( (e instanceof SftpException) && ((SftpException)e).id==ChannelSftp.SSH_FX_NO_SUCH_FILE) {
//We can get a "2: No such file" exception when the directory is empty.
try {
// Check if the parentPath exists and is a folder
SftpATTRS attrs = getChannel("SftpFileService.internalFetch: " + parentPath).stat(parentPath); //$NON-NLS-1$
if (attrs.isDir()) {
// We MUST NOT throw an exception here. Just return
// an empty IHostFile array.
return new IHostFile[0];
}
// else, fall through to exception handling -- will send
// SystemRemoteFileIOException
} catch (Exception ee) {
//Can't get the folder attributes so let the first exception be handled.
}
}
//TODO throw new SystemMessageException.
//We get a "2: No such file" exception when we try to get contents
//of a symbolic link that turns out to point to a file rather than
@ -881,7 +908,7 @@ public class SftpFileService extends AbstractFileService implements ISshService,
public IHostFile[] getRoots(IProgressMonitor monitor) {
IHostFile root = null;
try {
root = getFile(null, "/", monitor);
root = getFile(null, "/", monitor); //$NON-NLS-1$
}
catch (SystemMessageException e){
}
@ -957,7 +984,7 @@ public class SftpFileService extends AbstractFileService implements ISshService,
try {
getChannel("SftpFileService.delete.rm").rm(fullPathRecoded); //$NON-NLS-1$
} catch (Exception e2) {
throw new SystemElementNotFoundException(Activator.PLUGIN_ID, fullPath, "delete");
throw new SystemElementNotFoundException(Activator.PLUGIN_ID, fullPath, "delete"); //$NON-NLS-1$
}
} else {
//Security exception, or similar: will be wrapped in makeSystemMessageException()
@ -1184,7 +1211,7 @@ public class SftpFileService extends AbstractFileService implements ISshService,
} catch (Exception e) {
Activator.trace("SftpFileService.setReadOnly "+path+" failed: "+e.toString()); //$NON-NLS-1$ //$NON-NLS-2$
if ((e instanceof SftpException) && ((SftpException) e).id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
throw new SystemElementNotFoundException(Activator.PLUGIN_ID, path, "setReadOnly");
throw new SystemElementNotFoundException(Activator.PLUGIN_ID, path, "setReadOnly"); //$NON-NLS-1$
}
throw makeSystemMessageException(e);
} finally {
@ -1298,7 +1325,7 @@ public class SftpFileService extends AbstractFileService implements ISshService,
} catch (Exception e) {
Activator.trace("SftpFileService.setFilePermissions " + path + " failed: " + e.toString()); //$NON-NLS-1$ //$NON-NLS-2$
if ((e instanceof SftpException) && ((SftpException) e).id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
throw new SystemElementNotFoundException(Activator.PLUGIN_ID, path, "setFilePermissions");
throw new SystemElementNotFoundException(Activator.PLUGIN_ID, path, "setFilePermissions"); //$NON-NLS-1$
}
throw makeSystemMessageException(e);
} finally {

View file

@ -12,7 +12,7 @@
<feature
id="org.eclipse.rse.tests"
label="%featureName"
version="3.1.0.qualifier"
version="3.1.1.qualifier"
provider-name="%providerName">
<description>

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2009 Wind River Systems, Inc. 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
@ -12,6 +12,7 @@
* Martin Oberhuber (Wind River) - [186640] Add IRSESystemType.testProperty()
* Martin Oberhuber (Wind River) - organize, enable and tag test cases
* Martin Oberhuber (Wind River) - [235360][ftp][ssh] Return proper "Root" IHostFile
* Patrick Tassé (Ericsson) - [285226] Empty directory shown as an error message
*******************************************************************************/
package org.eclipse.rse.tests.subsystems.files;
@ -24,13 +25,22 @@ import junit.framework.TestSuite;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.rse.core.model.IHost;
import org.eclipse.rse.core.subsystems.ISubSystem;
import org.eclipse.rse.services.IService;
import org.eclipse.rse.services.clientserver.PathUtility;
import org.eclipse.rse.services.clientserver.messages.SystemElementNotFoundException;
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
import org.eclipse.rse.services.files.IFileService;
import org.eclipse.rse.services.files.IHostFile;
import org.eclipse.rse.services.files.RemoteFileException;
import org.eclipse.rse.services.shells.IHostOutput;
import org.eclipse.rse.services.shells.IHostShell;
import org.eclipse.rse.services.shells.IShellService;
import org.eclipse.rse.subsystems.files.core.model.RemoteFileUtility;
import org.eclipse.rse.subsystems.files.core.servicesubsystem.IFileServiceSubSystem;
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
import org.eclipse.rse.tests.core.connection.RSEBaseConnectionTestCase;
import org.eclipse.rse.tests.subsystems.shells.ShellOutputListener;
public class FileServiceTest extends RSEBaseConnectionTestCase {
@ -75,7 +85,8 @@ public class FileServiceTest extends RSEBaseConnectionTestCase {
TestSuite suite = new TestSuite(baseName);
// // Add a test suite for each connection type
String[] connTypes = { "local", "ssh", "ftpWindows", "ftp", "linux", "windows" };
String[] connTypes = { "local", "ssh", "ftpWindows", "ftpSsh", "linux", "windows", "unix" };
//String[] connTypes = { "unix" };
//String[] connTypes = { "local" };
// String[] connTypes = { "ssh" };
@ -121,7 +132,12 @@ public class FileServiceTest extends RSEBaseConnectionTestCase {
//Return a filename for testing that exposes all characters valid on the file system
if (!isWindows()) {
//UNIX TODO: test embedded newlines
return "a !@#${a}\"\' fi\tle\b\\%^&*()?_ =[]~+-'`;:,.|<>"; //$NON-NLS-1$
String testName = "a !@#${a}\"\' fi\tle\b\\%^&*()?_ =[]~+-'`;:,.|<>"; //$NON-NLS-1$
// Bug 235492: DStore is designed to treat '\' and '/' the same way, so do not
// test this.
if (fss.getSubSystemConfiguration().getServiceImplType().getName().equals("org.eclipse.rse.services.dstore.IDStoreService")) { //$NON-NLS-1$
testName.replace('\\', ' ');
}
}
//Fallback: Windows TODO: test unicode
//Note: The trailing dot ('.') is really unfair on Windows because the file
@ -130,6 +146,32 @@ public class FileServiceTest extends RSEBaseConnectionTestCase {
return "a !@#${a}'` file%^&()_ =[]~+-;.,"; //$NON-NLS-1$
}
/**
* Find the first IShellServiceSubSystem service associated with the host.
*
* @return shell service subsystem, or <code>null</code> if not found.
*/
public IShellService getRelatedShellService() {
IHost host = fss.getHost();
ISubSystem[] subSystems = host.getSubSystems();
IShellService ssvc = null;
for (int i = 0; subSystems != null && i < subSystems.length; i++) {
IService svc = subSystems[i].getSubSystemConfiguration().getService(host);
if (svc != null) {
ssvc = (IShellService) svc.getAdapter(IShellService.class);
if (ssvc != null) {
try {
subSystems[i].checkIsConnected(getDefaultProgressMonitor());
return ssvc;
} catch (SystemMessageException e) {
e.printStackTrace();
}
}
}
}
return null;
}
public void testGetRootProperties() throws Exception {
//-test-author-:MartinOberhuber
if (isTestDisabled()) return;
@ -139,11 +181,10 @@ public class FileServiceTest extends RSEBaseConnectionTestCase {
for (int i = 0; i < roots.length; i++) {
assertTrue(roots[i].isRoot());
assertTrue(roots[i].exists());
assertNull(roots[i].getParentPath()); //dstore: bug 235471
assertNull(roots[i].getParentPath());
String rootName = roots[i].getName();
assertNotNull(rootName);
System.out.println(rootName);
// DStore: NPE, bug 240710
IHostFile newHf = fs.getFile(null, rootName, new NullProgressMonitor());
assertTrue(newHf.isRoot());
assertTrue(newHf.exists());
@ -175,7 +216,7 @@ public class FileServiceTest extends RSEBaseConnectionTestCase {
if (isTestDisabled()) return;
String testName = getTestFileName();
IHostFile hf = fs.createFile(tempDirPath, testName, mon); //dstore-linux: bug 235492
IHostFile hf = fs.createFile(tempDirPath, testName, mon);
assertTrue(hf.exists());
assertTrue(hf.canRead());
assertTrue(hf.canWrite());
@ -231,4 +272,162 @@ public class FileServiceTest extends RSEBaseConnectionTestCase {
}
}
public String[] runRemoteCommand(IShellService shellService, String workingDirectory, String cmd) throws SystemMessageException, InterruptedException {
IHostShell hostShell = null;
hostShell = shellService.runCommand(workingDirectory, cmd, null, mon);
ShellOutputListener outputListener = new ShellOutputListener();
hostShell.addOutputListener(outputListener);
hostShell.writeToShell("exit");
assertNotNull(hostShell);
assertNotNull(hostShell.getStandardOutputReader());
while (hostShell.isActive()) {
Thread.sleep(1000);
}
Object[] allOutput = outputListener.getAllOutput();
if (allOutput!=null) {
String[] sOutput = new String[allOutput.length];
for (int i = 0; i < allOutput.length; i++) {
if (allOutput[i] instanceof IHostOutput) {
sOutput[i] = ((IHostOutput) allOutput[i]).getString();
} else {
sOutput[i] = allOutput[i].toString();
}
}
return sOutput;
}
return null;
}
/**
* Create a symbolic link in the context of tempDirPath.
*
* @param source source file to link from
* @param target target file to link to
* @return <code>true</code> if link was successfully created.
*/
public boolean mkSymLink(String source, String target) {
if (!fss.getHost().getSystemType().isWindows()) {
IShellService ss = getRelatedShellService();
if (ss != null) {
String[] allOutput;
try {
String src = PathUtility.enQuoteUnix(source);
String tgt = PathUtility.enQuoteUnix(target);
String cmd = "ln -s " + src + " " + tgt;
allOutput = runRemoteCommand(ss, tempDirPath, cmd);
IHostFile hf = fs.getFile(tempDirPath, target, mon);
if (hf.exists()) {
return true;
}
allOutput = new String[] { "Failed to symlink: " + cmd };
} catch (Exception e) {
allOutput = new String[] { "Exception thrown: " + e };
}
System.out.println("WARNING: Could not create symlink");
if (allOutput != null) {
for (int i = 0; i < allOutput.length; i++) {
System.out.println(allOutput[i]);
}
}
}
}
return false;
}
public void testListEmptyFolder() throws SystemMessageException {
// -test-author-:PatrickTassé
if (isTestDisabled()) return;
String testName = "empty";
IHostFile hf = fs.createFolder(tempDirPath, testName, mon);
assertTrue(hf.exists());
assertTrue(hf.isDirectory());
assertTrue(hf.canRead());
assertTrue(hf.canWrite());
assertEquals(testName, hf.getName());
assertEquals(tempDirPath, hf.getParentPath());
long modDate = hf.getModifiedDate();
assertTrue(modDate > 0);
if (fss.getHost().getSystemType().isLocal()) {
File theFile = new File(remoteTempDir.getAbsolutePath(), testName);
assertTrue(theFile.exists());
assertTrue(modDate == theFile.lastModified());
}
IHostFile[] hfa = fs.list(hf.getAbsolutePath(), "*", IFileService.FILE_TYPE_FILES_AND_FOLDERS, mon);
assertEquals(0, hfa.length);
// check for symlink-to-empty-folder case
if (mkSymLink(testName, "lto" + testName)) {
IHostFile hf2 = fs.getFile(tempDirPath, "lto" + testName, mon);
assertTrue(hf2.isDirectory());
hfa = fs.list(hf2.getAbsolutePath(), "*", IFileService.FILE_TYPE_FILES_AND_FOLDERS, mon);
assertEquals(0, hfa.length);
}
}
public void testListNonExistentFolder() throws SystemMessageException, InterruptedException {
// -test-author-:PatrickTassé
if (isTestDisabled()) return;
String testPath = tempDirPath + "/non/existent";
try {
IHostFile[] hfa = fs.list(testPath, "*", IFileService.FILE_TYPE_FILES_AND_FOLDERS, mon);
// Bug 285942: LocalFileService and DStoreFileService return empty array today
// Assert something impossible since an exception is expected
assertEquals("Exception expected on list nonexistent", -1, hfa.length);
} catch (SystemMessageException e) {
assertTrue(e instanceof SystemElementNotFoundException);
}
// check for symlink-to-non-existent case
if (mkSymLink("non/existent", "ltononex")) {
IHostFile hf2 = fs.getFile(tempDirPath, "ltononex", mon);
try {
IHostFile[] hfa = fs.list(hf2.getAbsolutePath(), "*", IFileService.FILE_TYPE_FILES_AND_FOLDERS, mon);
assertEquals("Exception expected on list broken symlink", -1, hfa.length);
} catch (SystemMessageException e) {
assertTrue(e instanceof SystemElementNotFoundException);
}
}
}
public void testListNotAFolder() throws SystemMessageException {
// -test-author-:PatrickTassé
if (isTestDisabled()) return;
String testName = getTestFileName();
IHostFile hf = fs.createFile(tempDirPath, testName, mon);
assertTrue(hf.exists());
assertTrue(hf.canRead());
assertTrue(hf.canWrite());
assertEquals(hf.getName(), testName);
assertEquals(hf.getParentPath(), tempDirPath);
assertEquals(hf.getSize(), 0);
long modDate = hf.getModifiedDate();
assertTrue(modDate > 0);
if (fss.getHost().getSystemType().isLocal()) {
File theFile = new File(remoteTempDir.getAbsolutePath(), testName);
assertTrue(theFile.exists());
assertTrue(modDate == theFile.lastModified());
}
try {
IHostFile[] hfa = fs.list(hf.getAbsolutePath(), "*", IFileService.FILE_TYPE_FILES_AND_FOLDERS, mon);
// Bug 285942: LocalFileService and DStoreFileService return empty array today
// Assert something impossible since an exception is expected
assertEquals("Exception expected on list not-a-folder", -1, hfa.length);
} catch (SystemMessageException e) {
assertTrue(e instanceof RemoteFileException);
}
// check for symlink-to-not-a-folder case
if (mkSymLink(testName, "lto" + testName)) {
try {
IHostFile hf2 = fs.getFile(tempDirPath, "lto" + testName, mon);
assertTrue(hf2.isFile());
IHostFile[] hfa = fs.list(hf2.getAbsolutePath(), "*", IFileService.FILE_TYPE_FILES_AND_FOLDERS, mon);
// Assert something impossible since an exception is expected
assertEquals("Exception expected on list symlink-to-folder", -1, hfa.length);
} catch (SystemMessageException e) {
assertTrue(e instanceof RemoteFileException);
}
}
}
}