From 6cbbf1426193459a5efa9d667cd6915941e96f2f Mon Sep 17 00:00:00 2001 From: Martin Oberhuber < martin.oberhuber@windriver.com> Date: Fri, 18 Aug 2006 23:22:41 +0000 Subject: [PATCH] Fix ssh file classification, symlink reading and permission handling --- .../services/ssh/files/SftpFileService.java | 57 ++++++++++++++----- .../rse/services/ssh/files/SftpHostFile.java | 42 +++++++++++--- 2 files changed, 76 insertions(+), 23 deletions(-) diff --git a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/services/ssh/files/SftpFileService.java b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/services/ssh/files/SftpFileService.java index 23966b05097..8beccf051de 100644 --- a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/services/ssh/files/SftpFileService.java +++ b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/services/ssh/files/SftpFileService.java @@ -175,6 +175,7 @@ public class SftpFileService extends AbstractFileService implements IFileService try { attrs = getChannel("SftpFileService.getFile").stat(remoteParent+'/'+fileName); //$NON-NLS-1$ Activator.trace("SftpFileService.getFile done"); //$NON-NLS-1$ + node = makeHostFile(remoteParent, fileName, attrs); } catch(Exception e) { Activator.trace("SftpFileService.getFile failed: "+e.toString()); //$NON-NLS-1$ if ( (e instanceof SftpException) && ((SftpException)e).id==ChannelSftp.SSH_FX_NO_SUCH_FILE) { @@ -187,9 +188,7 @@ public class SftpFileService extends AbstractFileService implements IFileService fDirChannelMutex.release(); } } - if (attrs!=null) { - node = makeHostFile(remoteParent, fileName, attrs); - } else { + if (node==null) { node = new SftpHostFile(remoteParent, fileName, false, false, false, 0, 0); node.setExists(false); } @@ -253,20 +252,50 @@ public class SftpFileService extends AbstractFileService implements IFileService } private SftpHostFile makeHostFile(String parentPath, String fileName, SftpATTRS attrs) { - SftpHostFile node = new SftpHostFile(parentPath, fileName, attrs.isDir(), false, attrs.isLink(), 1000L * attrs.getMTime(), attrs.getSize()); + SftpATTRS attrsTarget = attrs; + String linkTarget=null; + if (attrs.isLink()) { + //TODO remove comments as soon as jsch-0.1.29 is available + // try { + // //Note: readlink() is supported only with jsch-0.1.29 or higher. + // //By catching the exception we remain backward compatible. + // linkTarget=getChannel("makeHostFile.readlink").readlink(node.getAbsolutePath()); //$NON-NLS-1$ + // //TODO: Classify the type of resource linked to as file, folder or broken link + // } catch(Exception e) {} + //check if the link points to a directory + try { + getChannel("makeHostFile.chdir").cd(parentPath+'/'+fileName); //$NON-NLS-1$ + linkTarget=getChannel("makeHostFile.chdir").pwd(); //$NON-NLS-1$ + if (linkTarget!=null && !linkTarget.equals(parentPath+'/'+fileName)) { + attrsTarget = getChannel("SftpFileService.getFile").stat(linkTarget); //$NON-NLS-1$ + } else { + linkTarget=null; + } + } catch(Exception e) { + //dangling link? + if (e instanceof SftpException && ((SftpException)e).id==ChannelSftp.SSH_FX_NO_SUCH_FILE) { + linkTarget=":dangling link"; //$NON-NLS-1$ + } + } + } + SftpHostFile node = new SftpHostFile(parentPath, fileName, attrsTarget.isDir(), false, attrs.isLink(), 1000L * attrs.getMTime(), attrs.getSize()); + if (linkTarget!=null) { + node.setLinkTarget(linkTarget); + } + //Permissions: expect the current user to be the owner + String perms = attrsTarget.getPermissionsString(); + if (perms.indexOf('r',1)<=0) { + node.setReadable(false); //not readable by anyone + } + if (perms.indexOf('w',1)<=0) { + node.setWritable(false); //not writable by anyone + } + if (perms.indexOf('x',1)>0) { + node.setExecutable(true); //executable by someone + } if (attrs.getExtended()!=null) { node.setExtendedData(attrs.getExtended()); } - //TODO remove comments as soon as jsch-0.1.29 is available - //if (node.isLink()) { - // try { - // //Note: readlink() is supported only with jsch-0.1.29 or higher. - // //By catching the exception we remain backward compatible. - // String linkTarget=getChannel("makeHostFile.readlink").readlink(node.getAbsolutePath()); //$NON-NLS-1$ - // node.setLinkTarget(linkTarget); - // //TODO: Classify the type of resource linked to as file, folder or broken link - // } catch(Exception e) {} - //} return node; } diff --git a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/services/ssh/files/SftpHostFile.java b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/services/ssh/files/SftpHostFile.java index a4d4fce380d..f7a3b8282e4 100644 --- a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/services/ssh/files/SftpHostFile.java +++ b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/services/ssh/files/SftpHostFile.java @@ -28,6 +28,9 @@ public class SftpHostFile implements IHostFile { private boolean fIsDirectory = false; private boolean fIsRoot = false; private boolean fIsArchive = false; + private boolean fIsReadable = true; + private boolean fIsWritable = true; + private boolean fIsExecutable = false; private boolean fExists = true; private long fLastModified = 0; private long fSize = 0; @@ -65,7 +68,7 @@ public class SftpHostFile implements IHostFile { } public boolean isFile() { - return !(fIsDirectory || fIsRoot || fIsLink); + return !(fIsDirectory || fIsRoot); } public boolean isRoot() { @@ -166,13 +169,24 @@ public class SftpHostFile implements IHostFile { //TODO: isExecutable(), shellscript vs. binary String result; if (isLink()) { - //TODO: read symbolic link target and its type to provide e.g. "symbolic link(directory):/export4/opt result = "symbolic link"; //$NON-NLS-1$ if (fLinkTarget!=null) { - result += "(unknown):" + fLinkTarget; //$NON-NLS-1$ + if (fLinkTarget.equals(":dangling link")) { + result = "broken symbolic link to `unknown'"; //$NON-NLS-1$ + } else if(isDirectory()) { + result += "(directory):" + fLinkTarget; //$NON-NLS-1$ + } else if(canExecute()) { + result += "(executable):" + fLinkTarget; //$NON-NLS-1$ + } else { + result += "(file):" + fLinkTarget; //$NON-NLS-1$ + } } } else if (isFile()) { - result = "file"; //$NON-NLS-1$ + if (canExecute()) { + result = "executable"; //$NON-NLS-1$ + } else { + result = "file"; //$NON-NLS-1$ + } } else if (isDirectory()) { result = "directory"; //$NON-NLS-1$ } else { @@ -181,13 +195,23 @@ public class SftpHostFile implements IHostFile { return result; } - //TODO implement this - public boolean canRead() { - return true; + public void setReadable(boolean b) { + fIsReadable=b; + } + public void setWritable(boolean b) { + fIsWritable=b; + } + public void setExecutable(boolean b) { + fIsExecutable=b; } - //TODO implement this + public boolean canRead() { + return fIsReadable; + } public boolean canWrite() { - return true; + return fIsWritable; + } + public boolean canExecute() { + return fIsExecutable; } }