diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.services.files.ftp/META-INF/MANIFEST.MF index aa8f8990a1f..85b3162b3d2 100644 --- a/rse/plugins/org.eclipse.rse.services.files.ftp/META-INF/MANIFEST.MF +++ b/rse/plugins/org.eclipse.rse.services.files.ftp/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName -Bundle-SymbolicName: org.eclipse.rse.services.files.ftp +Bundle-SymbolicName: org.eclipse.rse.services.files.ftp;singleton:=true Bundle-Version: 2.0.0.qualifier Bundle-Activator: org.eclipse.rse.internal.services.files.ftp.Activator Bundle-Vendor: %providerName @@ -9,7 +9,9 @@ Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, org.eclipse.rse.services, org.apache.commons.net, - org.eclipse.rse.core + org.eclipse.rse.core, + org.eclipse.core.resources Eclipse-LazyStart: true -Export-Package: org.eclipse.rse.internal.services.files.ftp;x-friends:="org.eclipse.rse.subsystems.files.ftp" +Export-Package: org.eclipse.rse.internal.services.files.ftp;x-friends:="org.eclipse.rse.subsystems.files.ftp", + org.eclipse.rse.internal.services.files.ftp.parser;x-friends:="org.eclipse.rse.subsystems.files.ftp" Bundle-RequiredExecutionEnvironment: J2SE-1.4 diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/plugin.xml b/rse/plugins/org.eclipse.rse.services.files.ftp/plugin.xml new file mode 100644 index 00000000000..a34a1a69b91 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services.files.ftp/plugin.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/schema/ftpFileEntryParser.exsd b/rse/plugins/org.eclipse.rse.services.files.ftp/schema/ftpFileEntryParser.exsd new file mode 100644 index 00000000000..6cca44b1f52 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services.files.ftp/schema/ftpFileEntryParser.exsd @@ -0,0 +1,189 @@ + + + + + + + + + Extension point that allows providing extra parsers for the FTP LIST command output. +Apache commons net provides some APIs and factories to costumize the parser and this extension +provides an easy way to setup a custom parser and integrate it into RSE. +The provided extension points will be available as a list in the property "FTP Settings", +allowing the user to select them overriding the default parser. +The string attributes <code>defaultDateFormatStr</code> <code>recentDateFormatStr</code> + <code>serverLanguageCode</code> <code>serverTimeZoneId</code> <code>shortMonthNames</code> have to + follow the format described by <code>org.apache.commons.net.ftp.FTPClientConfig</code> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Name that will be displayed in the UI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RSE 2.0 + + + + + + + + + <!-- Default UNIX parser provided by Apache commons net package --> +<parser + class="org.apache.commons.net.ftp.parser.UnixFTPEntryParser" + name="UNIX"> +</parser> + +<!-- Custom parser implementing org.apache.commons.net.ftp.Configurable and org.apache.commons.net.ftp.FTPFileEntryParser --> +<parser + class="com.mycompany.MyParser" + name="MyParser"> +</parser> + +<!-- UNIX server that uses Danish month names and "European" date formatting in Denmark's time zone --> +<parser + class="org.apache.commons.net.ftp.parser.UnixFTPEntryParser" + name="UNIX_Danish" + defaultDateFormatStr = "d MMM yyyy" + recentDateFormatStr = "d MMM HH:mm" + serverLanguageCode = "da" + serverTimeZoneId = "Europe/Copenhagen" + > +</parser> + +<!-- VMS server that uses month names in a language not supported but uses the standard date formatting --> +<parser + class="org.apache.commons.net.ftp.parser.VMSFTPEntryParser" + name="VMS_custom" + shortMonthNames="jan|feb|mar|apr|ma\u00ED|j\u00FAn|j\u00FAl|\u00e1g\u00FA|sep|okt|n\u00F3v|des" + > +</parser> + + + + + + + + + The provider of a new FTPEntryParser must implement <samp>org.apache.commons.net.ftp.Configurable</samp> and <samp>org.apache.commons.net.ftp.FTPFileEntryParser</samp> + + + + + + + + + Customized VMS and WinNT implementations are supplied in the <code>org.eclipse.rse.services.files.ftp</code> plug-in. + + + + + + + + + Copyright (c) 2007 Symbian Software Ltd. 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 http://www.eclipse.org/legal/epl-v10.html + +Contributors: + Javier Montalvo Orus (Symbian) - initial API and implementation + + + + diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPHostFile.java b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPHostFile.java index 6d03607b453..30746a06f54 100644 --- a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPHostFile.java +++ b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPHostFile.java @@ -15,7 +15,8 @@ * Javier Montalvo OrĂºs (Symbian) - Migrate to jakarta commons net FTP client * Javier Montalvo Orus (Symbian) - Fixing 161211 - Cannot expand /pub folder as * anonymous on ftp.wacom.com - * Javier Montalvo Orus (Symbian) - Fixing 161238 - [ftp] connections to VMS servers are not usable + * Javier Montalvo Orus (Symbian) - Fixing 161238 - [ftp] connections to VMS servers are not usable + * Javier Montalvo Orus (Symbian) - Fixing 176216 - [api] FTP sould provide API to allow clients register their own FTPListingParser ********************************************************************************/ package org.eclipse.rse.internal.services.files.ftp; @@ -23,7 +24,6 @@ package org.eclipse.rse.internal.services.files.ftp; import java.io.File; -import org.apache.commons.net.ftp.FTPClientConfig; import org.apache.commons.net.ftp.FTPFile; import org.eclipse.rse.services.clientserver.archiveutils.ArchiveHandlerManager; import org.eclipse.rse.services.files.IHostFile; @@ -56,46 +56,27 @@ public class FTPHostFile implements IHostFile _isRoot = isRoot; _exists = exists; } - - public FTPHostFile(String parentPath, FTPFile ftpFile, String systemName) + + public FTPHostFile(String parentPath, FTPFile ftpFile) { _parentPath = parentPath; _ftpFile = ftpFile; - if(systemName.equals(FTPClientConfig.SYST_VMS)) - { - _name = ftpFile.getName(); - if(_name.indexOf(".DIR")!=-1) //$NON-NLS-1$ - { - _name = _name.substring(0,_name.indexOf(".DIR")); //$NON-NLS-1$ - } - else - { - _name = _name.substring(0,_name.indexOf(";")); //$NON-NLS-1$ - } - } - else - { - _name = ftpFile.getName(); - } + _name = ftpFile.getName(); _isDirectory = ftpFile.isDirectory(); _lastModified = ftpFile.getTimestamp().getTimeInMillis(); _size = ftpFile.getSize(); _isArchive = internalIsArchive(); - //In Windows r/w is not listed - //In VMS it is not implemented in the Jakarta parser - if(!systemName.equals(FTPClientConfig.SYST_NT) && !systemName.equals(FTPClientConfig.SYST_VMS)) - { - _canRead = ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION); - _canWrite = ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION); - } + _canRead = ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION); + _canWrite = ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION); _isRoot = false; _exists = true; } + public long getSize() { return _size; @@ -188,30 +169,58 @@ public class FTPHostFile implements IHostFile public int getUserPermissions() { + int userRead = 0; + int userWrite = 0; + int userExec = 0; + //user - int userRead = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION) || _canRead ? 1 : 0; - int userWrite = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION) || _canWrite ? 1 : 0; - int userExec = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0; + if(_ftpFile!=null) + { + userRead = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION) ? 1 : 0; + userWrite = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION) ? 1 : 0; + userExec = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0; + } + else + { + userRead = _canRead ? 1 : 0; + userWrite = _canWrite ? 1 : 0; + userExec = 0; + + } return userRead << 2 | userWrite << 1 | userExec; } public int getGroupPermissions() { + int groupRead = 0; + int groupWrite = 0; + int groupExec = 0; + //group - int groupRead = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION) ? 1 : 0; - int groupWrite = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION) ? 1 : 0; - int groupExec = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0; + if(_ftpFile!=null) + { + groupRead = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION) ? 1 : 0; + groupWrite = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION) ? 1 : 0; + groupExec = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0; + } return groupRead << 2 | groupWrite << 1 | groupExec; } public int getOtherPermissions() { + int otherRead = 0; + int otherWrite = 0; + int otherExec = 0; + //other - int otherRead = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION) ? 1 : 0; - int otherWrite = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION) ? 1 : 0; - int otherExec = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0; + if(_ftpFile!=null) + { + otherRead = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION) ? 1 : 0; + otherWrite = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION) ? 1 : 0; + otherExec = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0; + } return otherRead << 2 | otherWrite << 1 | otherExec; } diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPService.java b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPService.java index b60771cda8b..b128435468c 100644 --- a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPService.java +++ b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPService.java @@ -37,6 +37,7 @@ * Javier Montalvo Orus (Symbian) - Fixing 168120 - [ftp] root filter resolves to home dir * Javier Montalvo Orus (Symbian) - Fixing 169680 - [ftp] FTP files subsystem and service should use passive mode * Javier Montalvo Orus (Symbian) - Fixing 174828 - [ftp] Folders are attempted to be removed as files + * Javier Montalvo Orus (Symbian) - Fixing 176216 - [api] FTP sould provide API to allow clients register their own FTPListingParser ********************************************************************************/ package org.eclipse.rse.internal.services.files.ftp; @@ -52,8 +53,6 @@ import java.io.OutputStream; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; @@ -63,6 +62,7 @@ import org.apache.commons.net.ftp.FTPReply; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.rse.core.model.IPropertySet; +import org.eclipse.rse.internal.services.files.ftp.parser.FTPClientConfigFactory; import org.eclipse.rse.services.Mutex; import org.eclipse.rse.services.clientserver.FileTypeMatcher; import org.eclipse.rse.services.clientserver.IMatcher; @@ -80,9 +80,9 @@ public class FTPService extends AbstractFileService implements IFileService, IFT private FTPClient _ftpClient; private FTPFile[] _ftpFiles; - private Mutex _downloadMutex = new Mutex(); + private Mutex _commandMutex = new Mutex(); - private String _systemName; + private String _parser; private String _userHome; private transient String _hostName; private transient String _userId; @@ -93,6 +93,9 @@ public class FTPService extends AbstractFileService implements IFileService, IFT private IPropertySet _ftpPropertySet; private Exception _exception; + private boolean _isBinaryFileType = true; + private boolean _isPassiveDataConnectionMode = false; + private class FTPBufferedInputStream extends BufferedInputStream { private FTPClient client; @@ -224,10 +227,10 @@ public class FTPService extends AbstractFileService implements IFileService, IFT public void connect() throws Exception { + if (_ftpClient == null) { _ftpClient = new FTPClient(); - } if(_ftpLoggingOutputStream!=null) @@ -274,75 +277,85 @@ public class FTPService extends AbstractFileService implements IFileService, IFT throw new Exception(lastMessage); } - //SYSTEM PARSER + //System parser - FTPClientConfig ftpClientConfig; + _parser = _ftpPropertySet.getPropertyValue("parser"); //$NON-NLS-1$ - _systemName = _ftpClient.getSystemName().toUpperCase(); - if(_systemName.indexOf(' ')!=-1) + if(!_parser.equalsIgnoreCase("AUTO")) //$NON-NLS-1$ { - _systemName = _systemName.substring(0,_systemName.indexOf(' ')); + _ftpClient.setParserFactory(FTPClientConfigFactory.getParserFactory()); + _ftpClient.configure(FTPClientConfigFactory.getParserFactory().getFTPClientConfig(_parser)); + } + else + { + //try to guess + + String systemName = _ftpClient.getSystemName().toUpperCase(); + if(systemName.indexOf(' ')!=-1) + { + systemName = systemName.substring(0,systemName.indexOf(' ')); + } + + //FTPClientConfig.SYST_NT = "WINDOWS" + if(systemName.startsWith(FTPClientConfig.SYST_NT)) + { + _ftpClient.setParserFactory(FTPClientConfigFactory.getParserFactory()); + _ftpClient.configure(FTPClientConfigFactory.getParserFactory().getFTPClientConfig("WinNT")); //$NON-NLS-1$ + }else + //FTPClientConfig.SYST_MVS = "MVS" + if(systemName.startsWith(FTPClientConfig.SYST_MVS)) + { + _ftpClient.configure(new FTPClientConfig(FTPClientConfig.SYST_MVS)); + }else + //FTPClientConfig.SYST_OS2 = "OS/2" + if(systemName.startsWith(FTPClientConfig.SYST_OS2)) + { + _ftpClient.configure(new FTPClientConfig(FTPClientConfig.SYST_OS2)); + }else + //FTPClientConfig.SYST_OS400 = "OS/400" + if(systemName.startsWith(FTPClientConfig.SYST_OS400)) + { + _ftpClient.configure(new FTPClientConfig(FTPClientConfig.SYST_OS400)); + }else + //FTPClientConfig.SYST_VMS = "VMS" + if(systemName.startsWith(FTPClientConfig.SYST_VMS)) + { + _ftpClient.setParserFactory(FTPClientConfigFactory.getParserFactory()); + _ftpClient.configure(FTPClientConfigFactory.getParserFactory().getFTPClientConfig("VMS_improved")); //$NON-NLS-1$ + }else + //Default UNIX-like parsing + //FTPClientConfig.SYST_UNIX = "UNIX" + { + _ftpClient.configure(new FTPClientConfig(FTPClientConfig.SYST_UNIX)); + } + } + + // Initial active/passive mode. This action will be refreshed later using setDataConnectionMode() + + if(_ftpPropertySet.getPropertyValue("passive").equalsIgnoreCase("true")) //$NON-NLS-1$ //$NON-NLS-2$ + { + _ftpClient.enterLocalPassiveMode(); + _isPassiveDataConnectionMode = true; + } + else + { + _ftpClient.enterLocalActiveMode(); + _isPassiveDataConnectionMode = false; } - //FTPClientConfig.SYST_NT = "WINDOWS" - if(_systemName.startsWith(FTPClientConfig.SYST_NT)) - { - _systemName = FTPClientConfig.SYST_NT; - ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_NT); - }else - //FTPClientConfig.SYST_MVS = "MVS" - if(_systemName.startsWith(FTPClientConfig.SYST_MVS)) - { - _systemName = FTPClientConfig.SYST_MVS; - ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_MVS); - }else - //FTPClientConfig.SYST_OS2 = "OS/2" - if(_systemName.startsWith(FTPClientConfig.SYST_OS2)) - { - _systemName = FTPClientConfig.SYST_OS2; - ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_OS2); - }else - //FTPClientConfig.SYST_OS400 = "OS/400" - if(_systemName.startsWith(FTPClientConfig.SYST_OS400)) - { - _systemName = FTPClientConfig.SYST_OS400; - ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_OS400); - }else - //FTPClientConfig.SYST_VMS = "VMS" - if(_systemName.startsWith(FTPClientConfig.SYST_VMS)) - { - _systemName = FTPClientConfig.SYST_VMS; - ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_VMS); - }else - //Default UNIX-like parsing - //FTPClientConfig.SYST_UNIX = "UNIX" - { - _systemName = FTPClientConfig.SYST_UNIX; - ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_UNIX); - } - - _ftpClient.configure(ftpClientConfig); + // Initial ASCII/Binary mode. This action will be refreshed later using setFileType() + _ftpClient.setFileType(FTP.BINARY_FILE_TYPE); + _isBinaryFileType = true; _userHome = _ftpClient.printWorkingDirectory(); //For VMS, normalize the home location - if(_systemName.equals(FTPClientConfig.SYST_VMS)) + if(_userHome.indexOf(':')!=-1) { _userHome = _userHome.replaceAll(":\\[", "/"); //$NON-NLS-1$ //$NON-NLS-2$ _userHome = '/'+_userHome.substring(0,_userHome.lastIndexOf(']')); } - if(_ftpPropertySet != null) - { - if(_ftpPropertySet.getPropertyValue("passive").equalsIgnoreCase("true")) //$NON-NLS-1$ //$NON-NLS-2$ - { - _ftpClient.enterLocalPassiveMode(); - } - else - { - _ftpClient.enterLocalActiveMode(); - } - } } public void disconnect() @@ -352,10 +365,11 @@ public class FTPService extends AbstractFileService implements IFileService, IFT getFTPClient().logout(); _ftpClient = null; } - catch (Exception e) + catch (IOException e) { _ftpClient = null; } + } /** @@ -372,19 +386,6 @@ public class FTPService extends AbstractFileService implements IFileService, IFT if (_ftpClient == null) { _ftpClient = new FTPClient(); - - } - - if(_ftpPropertySet != null) - { - if(_ftpPropertySet.getPropertyValue("passive").equalsIgnoreCase("true")) //$NON-NLS-1$ //$NON-NLS-2$ - { - _ftpClient.enterLocalPassiveMode(); - } - else - { - _ftpClient.enterLocalActiveMode(); - } } if(_hostName!=null) @@ -397,7 +398,8 @@ public class FTPService extends AbstractFileService implements IFileService, IFT } catch (Exception e1) {} } } - + + setDataConnectionMode(); return _ftpClient; } @@ -416,43 +418,47 @@ public class FTPService extends AbstractFileService implements IFileService, IFT FTPHostFile file = null; - try{ + if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) + { - //try to retrieve the file - _ftpClient = getFTPClient(); + try{ - remoteParent = adaptPath(remoteParent); - - if(!_ftpClient.changeWorkingDirectory(remoteParent)) - { - throw new RemoteFileIOException(new Exception(_ftpClient.getReplyString())); - } - - if(!listFiles(monitor)) - { - throw new RemoteFileCancelledException(); - } - - for (int i = 0; i < _ftpFiles.length; i++) - { - FTPHostFile tempFile = new FTPHostFile(remoteParent,_ftpFiles[i],_systemName); + //try to retrieve the file + _ftpClient = getFTPClient(); - if(tempFile.getName().equalsIgnoreCase(fileName)) + if(!_ftpClient.changeWorkingDirectory(remoteParent)) { - file = tempFile; - break; + throw new RemoteFileIOException(new Exception(_ftpClient.getReplyString())); + } + + if(!listFiles(monitor)) + { + throw new RemoteFileCancelledException(); + } + + for (int i = 0; i < _ftpFiles.length; i++) + { + FTPHostFile tempFile = new FTPHostFile(remoteParent,_ftpFiles[i]); + + if(tempFile.getName().equalsIgnoreCase(fileName)) + { + file = tempFile; + break; + } + } + + // if not found, create new object with non-existing flag + if(file == null) + { + file = new FTPHostFile(remoteParent,fileName, false, false, 0, 0, false); } - } - // if not found, create new object with non-existing flag - if(file == null) - { - file = new FTPHostFile(remoteParent,fileName, false, false, 0, 0, false); - } - - - }catch (Exception e){ - throw new RemoteFileIOException(e); + + }catch (Exception e){ + throw new RemoteFileIOException(e); + } finally { + _commandMutex.release(); + } } return file; @@ -481,48 +487,54 @@ public class FTPService extends AbstractFileService implements IFileService, IFT } } - - if (fileFilter == null) - { - fileFilter = "*"; //$NON-NLS-1$ - } - IMatcher filematcher = null; - if (fileFilter.endsWith(",")) { //$NON-NLS-1$ - String[] types = fileFilter.split(","); //$NON-NLS-1$ - filematcher = new FileTypeMatcher(types, true); - } else { - filematcher = new NamePatternMatcher(fileFilter, true, true); - } List results = new ArrayList(); - try + if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) { - _ftpClient = getFTPClient(); - - parentPath = adaptPath(parentPath); - - if(!_ftpClient.changeWorkingDirectory(parentPath)) + + if (fileFilter == null) { - throw new RemoteFileIOException(new Exception(_ftpClient.getReplyString())); + fileFilter = "*"; //$NON-NLS-1$ + } + IMatcher filematcher = null; + if (fileFilter.endsWith(",")) { //$NON-NLS-1$ + String[] types = fileFilter.split(","); //$NON-NLS-1$ + filematcher = new FileTypeMatcher(types, true); + } else { + filematcher = new NamePatternMatcher(fileFilter, true, true); } - if(!listFiles(monitor)) - { - throw new RemoteFileCancelledException(); - } - for(int i=0; i<_ftpFiles.length; i++) + try { - FTPHostFile f = new FTPHostFile(parentPath,_ftpFiles[i],_systemName); - if((filematcher.matches(f.getName()) || f.isDirectory()) && !(f.getName().equals(".") || f.getName().equals(".."))) //$NON-NLS-1$ //$NON-NLS-2$ + _ftpClient = getFTPClient(); + + if(!_ftpClient.changeWorkingDirectory(parentPath)) { - results.add(f); + throw new RemoteFileIOException(new Exception(_ftpClient.getReplyString())); + } + + if(!listFiles(monitor)) + { + throw new RemoteFileCancelledException(); + } + + for(int i=0; i<_ftpFiles.length; i++) + { + FTPHostFile f = new FTPHostFile(parentPath, _ftpFiles[i]); + + if((filematcher.matches(f.getName()) || f.isDirectory()) && !(f.getName().equals(".") || f.getName().equals(".."))) //$NON-NLS-1$ //$NON-NLS-2$ + { + results.add(f); + } } } - } - catch (Exception e) - { - throw new RemoteFileIOException(e); + catch (Exception e) + { + throw new RemoteFileIOException(e); + } finally { + _commandMutex.release(); + } } return (IHostFile[])results.toArray(new IHostFile[results.size()]); @@ -533,7 +545,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT { char separator = '/'; - if((_systemName.equals(FTPClientConfig.SYST_NT) || _userHome.indexOf('\\')!=-1) && _userHome.indexOf('/')==-1) + if(_userHome.indexOf('\\')!=-1 && _userHome.indexOf('/')==-1) { separator = '\\'; } @@ -556,58 +568,59 @@ public class FTPService extends AbstractFileService implements IFileService, IFT } } - FTPClient ftpClient = getFTPClient(); - - MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor); - - try + if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) { + + FTPClient ftpClient = getFTPClient(); - remoteParent = adaptPath(remoteParent); + MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor); - ftpClient.changeWorkingDirectory(remoteParent); - - if (isBinary) - ftpClient.setFileType(FTP.BINARY_FILE_TYPE); - else - ftpClient.setFileType(FTP.ASCII_FILE_TYPE); - - FileInputStream input = new FileInputStream(localFile); - OutputStream output = ftpClient.storeFileStream(remoteFile); - - progressMonitor.init(0, localFile.getName(), remoteFile, localFile.length()); - long bytes=0; - byte[] buffer = new byte[4096]; - - int readCount; - while((readCount = input.read(buffer)) > 0) + try { - bytes+=readCount; - output.write(buffer, 0, readCount); - progressMonitor.count(readCount); - if (monitor!=null){ - if (monitor.isCanceled()) { - retValue = false; - break; - } + + ftpClient.changeWorkingDirectory(remoteParent); + + setFileType(isBinary); + + FileInputStream input = new FileInputStream(localFile); + OutputStream output = ftpClient.storeFileStream(remoteFile); + + progressMonitor.init(0, localFile.getName(), remoteFile, localFile.length()); + long bytes=0; + byte[] buffer = new byte[4096]; + + int readCount; + while((readCount = input.read(buffer)) > 0) + { + bytes+=readCount; + output.write(buffer, 0, readCount); + progressMonitor.count(readCount); + if (monitor!=null){ + if (monitor.isCanceled()) { + retValue = false; + break; + } + } } + + input.close(); + output.flush(); + output.close(); + + ftpClient.completePendingCommand(); + + if(retValue==false) { + ftpClient.deleteFile(remoteFile); + } + + progressMonitor.end(); } - - input.close(); - output.flush(); - output.close(); - - ftpClient.completePendingCommand(); - - if(retValue==false) { - ftpClient.deleteFile(remoteFile); - } - - progressMonitor.end(); - } - catch (Exception e) - { - throw new RemoteFileIOException(e); + catch (Exception e) + { + throw new RemoteFileIOException(e); + } finally { + _commandMutex.release(); + } } return retValue; @@ -623,6 +636,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT try { + BufferedInputStream bis = new BufferedInputStream(stream); File tempFile = File.createTempFile("ftpup", "temp"); //$NON-NLS-1$ //$NON-NLS-2$ FileOutputStream os = new FileOutputStream(tempFile); @@ -643,16 +657,18 @@ public class FTPService extends AbstractFileService implements IFileService, IFT bos.close(); if(retValue == true){ - retValue = upload(monitor, tempFile, remoteParent, remoteFile, isBinary, "", hostEncoding); //$NON-NLS-1$ + setFileType(isBinary); + retValue = upload(monitor, tempFile, remoteParent, remoteFile, isBinary, "", hostEncoding); //$NON-NLS-1$ } } catch (Exception e) { throw new RemoteFileIOException(e); - } - return retValue; + } + + return retValue; - } + } /* * (non-Javadoc) @@ -660,7 +676,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT */ public boolean download(IProgressMonitor monitor, String remoteParent, String remoteFile, File localFile, boolean isBinary, String hostEncoding) throws SystemMessageException { - boolean retValue = false; + boolean retValue = true; if (monitor!=null){ if (monitor.isCanceled()) { @@ -668,21 +684,22 @@ public class FTPService extends AbstractFileService implements IFileService, IFT } } - if(_downloadMutex.waitForLock(monitor, Long.MAX_VALUE)) + IHostFile remoteHostFile = getFile(null,remoteParent,remoteFile); + + FTPClient ftpClient = getFTPClient(); + + if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) { + MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor); + //IHostFile remoteHostFile = null; + OutputStream output = null; + InputStream input = null; + try { - MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor); - IHostFile remoteHostFile = getFile(null,remoteParent,remoteFile); - FTPClient ftpClient = getFTPClient(); - - remoteParent = adaptPath(remoteParent); ftpClient.changeWorkingDirectory(remoteParent); - if (isBinary) - ftpClient.setFileType(FTP.BINARY_FILE_TYPE); - else - ftpClient.setFileType(FTP.ASCII_FILE_TYPE); + setFileType(isBinary); if (!localFile.exists()) { @@ -694,40 +711,55 @@ public class FTPService extends AbstractFileService implements IFileService, IFT localFile.createNewFile(); } - OutputStream output = new FileOutputStream(localFile); - InputStream input = ftpClient.retrieveFileStream(remoteFile); + output = new FileOutputStream(localFile); + input = ftpClient.retrieveFileStream(remoteFile); - progressMonitor.init(0, remoteFile, localFile.getName(), remoteHostFile.getSize()); - - byte[] buffer = new byte[4096]; - - int readCount; - while((readCount = input.read(buffer)) > 0) - { - output.write(buffer, 0, readCount); - progressMonitor.count(readCount); - if (monitor!=null){ - if (monitor.isCanceled()) { - retValue = false; - break; - } - } - } - - progressMonitor.end(); - - output.flush(); - input.close(); - output.close(); - - ftpClient.completePendingCommand(); } catch (Exception e) { throw new RemoteFileIOException(e); - } finally { - _downloadMutex.release(); - } + } + + + if(remoteHostFile != null && input != null) + { + progressMonitor.init(0, remoteFile, localFile.getName(), remoteHostFile.getSize()); + + byte[] buffer = new byte[4096]; + + int readCount; + + try{ + + while((readCount = input.read(buffer)) > 0) + { + output.write(buffer, 0, readCount); + progressMonitor.count(readCount); + if (monitor!=null){ + if (monitor.isCanceled()) { + retValue = false; + break; + } + } + } + + progressMonitor.end(); + + output.flush(); + input.close(); + output.close(); + + ftpClient.completePendingCommand(); + + }catch(IOException e) + { + e.printStackTrace(); + } + finally { + _commandMutex.release(); + } + } + } return retValue; } @@ -890,9 +922,6 @@ public class FTPService extends AbstractFileService implements IFileService, IFT try { - - remoteParent = adaptPath(remoteParent); - if(!ftpClient.changeWorkingDirectory(remoteParent)) { throw new Exception(ftpClient.getReplyString()+" ("+remoteParent+")"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -919,7 +948,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT try { File tempFile = File.createTempFile("ftp", "temp"); //$NON-NLS-1$ //$NON-NLS-2$ tempFile.deleteOnExit(); - boolean success = upload(monitor, tempFile, remoteParent, fileName, true, null, null); + boolean success = upload(monitor, tempFile, remoteParent, fileName, _isBinaryFileType, null, null); if(!success) { @@ -968,7 +997,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT } - private synchronized boolean listFiles(IProgressMonitor monitor) throws Exception + private boolean listFiles(IProgressMonitor monitor) throws Exception { boolean result = true; @@ -1028,25 +1057,6 @@ public class FTPService extends AbstractFileService implements IFileService, IFT return result; } - private String adaptPath(String path) - { - Matcher matcher = Pattern.compile("[\\\\/](\\w:.*)").matcher(path); //$NON-NLS-1$ - - if(matcher.matches()) - { - path = matcher.group(1); - } - - - if(path.length()>1) - { - path = getSeparator() == '/' ? path.replace('\\', getSeparator()) : path.replace('/', getSeparator()); - } - - return path; - } - - private class MyProgressMonitor { @@ -1163,16 +1173,8 @@ public class FTPService extends AbstractFileService implements IFileService, IFT InputStream stream = null; try { - remoteParent = adaptPath(remoteParent); - ftpClient.changeWorkingDirectory(remoteParent); - - if (isBinary) { - ftpClient.setFileType(FTP.BINARY_FILE_TYPE); - } - else { - ftpClient.setFileType(FTP.ASCII_FILE_TYPE); - } + setFileType(isBinary); stream = new FTPBufferedInputStream(ftpClient.retrieveFileStream(remoteFile), ftpClient); } @@ -1203,16 +1205,9 @@ public class FTPService extends AbstractFileService implements IFileService, IFT try { - remoteParent = adaptPath(remoteParent); - ftpClient.changeWorkingDirectory(remoteParent); - - if (isBinary) { - ftpClient.setFileType(FTP.BINARY_FILE_TYPE); - } - else { - ftpClient.setFileType(FTP.ASCII_FILE_TYPE); - } + + setFileType(isBinary); stream = new FTPBufferedOutputStream(ftpClient.storeFileStream(remoteFile), ftpClient); } @@ -1222,4 +1217,38 @@ public class FTPService extends AbstractFileService implements IFileService, IFT return stream; } + + private void setDataConnectionMode() + { + if(_ftpPropertySet != null) + { + if(_ftpPropertySet.getPropertyValue("passive").equalsIgnoreCase("true") && !_isPassiveDataConnectionMode) //$NON-NLS-1$ //$NON-NLS-2$ + { + _ftpClient.enterLocalPassiveMode(); + _isPassiveDataConnectionMode = true; + } + else if(_ftpPropertySet.getPropertyValue("passive").equalsIgnoreCase("false") && _isPassiveDataConnectionMode) //$NON-NLS-1$ //$NON-NLS-2$ + { + _ftpClient.enterLocalActiveMode(); + _isPassiveDataConnectionMode = false; + } + } + } + + private void setFileType(boolean isBinaryFileType) throws IOException + { + if(!isBinaryFileType && _isBinaryFileType) + { + _ftpClient.setFileType(FTP.ASCII_FILE_TYPE); + _isBinaryFileType = isBinaryFileType; + } else if(isBinaryFileType && !_isBinaryFileType) + { + _ftpClient.setFileType(FTP.BINARY_FILE_TYPE); + _isBinaryFileType = isBinaryFileType; + } + } + + + + } \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/FTPClientConfigFactory.java b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/FTPClientConfigFactory.java new file mode 100644 index 00000000000..7ee4f7076e1 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/FTPClientConfigFactory.java @@ -0,0 +1,128 @@ +/******************************************************************************** + * Copyright (c) 2007 Symbian Software Ltd. 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 http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Javier Montalvo Orus (Symbian) - initial API and implementation + ********************************************************************************/ + +package org.eclipse.rse.internal.services.files.ftp.parser; + +import java.util.Hashtable; +import java.util.Set; + +import org.apache.commons.net.ftp.FTPClientConfig; +import org.apache.commons.net.ftp.FTPFileEntryParser; +import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory; +import org.apache.commons.net.ftp.parser.ParserInitializationException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; + +public class FTPClientConfigFactory implements FTPFileEntryParserFactory { + +private static FTPClientConfigFactory factory = null; + + private Hashtable ftpConfig = new Hashtable(); + private Hashtable ftpFileEntryParser = new Hashtable(); + + /** + * Constructor of the parser factory + * @return an instance of the factory + */ + public static FTPClientConfigFactory getParserFactory() + { + if(factory==null) + { + factory = new FTPClientConfigFactory(); + } + + return factory; + } + + private FTPClientConfigFactory() { + + FTPClientConfig config = null; + + IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint("org.eclipse.rse.services.files.ftp","ftpFileEntryParser"); //$NON-NLS-1$ //$NON-NLS-2$ + IConfigurationElement[] ce = ep.getConfigurationElements(); + for (int i = 0; i < ce.length; i++) { + + config = null; + + String name = ce[i].getAttribute("name"); //$NON-NLS-1$ + String clas = ce[i].getAttribute("class"); //$NON-NLS-1$ + + FTPFileEntryParser entryParser=null; + try { + entryParser = (FTPFileEntryParser)ce[i].createExecutableExtension("class"); //$NON-NLS-1$ + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + ftpFileEntryParser.put(clas, entryParser); + + String defaultDateFormatStr = ce[i].getAttribute("defaultDateFormatStr"); //$NON-NLS-1$ + String recentDateFormatStr = ce[i].getAttribute("recentDateFormatStr"); //$NON-NLS-1$ + String serverLanguageCode = ce[i].getAttribute("serverLanguageCode"); //$NON-NLS-1$ + String shortMonthNames = ce[i].getAttribute("shortMonthNames"); //$NON-NLS-1$ + String serverTimeZoneId = ce[i].getAttribute("serverTimeZoneId"); //$NON-NLS-1$ + + config = new FTPClientConfig(clas); + + //not necessary checking for null, as null is valid input + config.setDefaultDateFormatStr(defaultDateFormatStr); + config.setRecentDateFormatStr(recentDateFormatStr); + config.setServerLanguageCode(serverLanguageCode); + config.setShortMonthNames(shortMonthNames); + config.setServerTimeZoneId(serverTimeZoneId); + + ftpConfig.put(name, config); + + } + } + + /** + * + * @param key name attribute of the extension point to be returned + * @return FTPClientConfig instance created from the attributes passed in the extension point + */ + public FTPClientConfig getFTPClientConfig(String key) + { + return (FTPClientConfig)ftpConfig.get(key); + } + + /** + * Returns a Set of key names + * @return a Set containing the name attribute of the extension points + */ + public Set getKeySet() + { + return ftpConfig.keySet(); + } + + /* + * (non-Javadoc) + * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory#createFileEntryParser(java.lang.String) + */ + public FTPFileEntryParser createFileEntryParser(String key) throws ParserInitializationException { + return (FTPFileEntryParser)ftpFileEntryParser.get(key); + } + + /* + * (non-Javadoc) + * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory#createFileEntryParser(org.apache.commons.net.ftp.FTPClientConfig) + */ + public FTPFileEntryParser createFileEntryParser(FTPClientConfig config) + throws ParserInitializationException { + + String key = config.getServerSystemKey(); + return createFileEntryParser(key); + + } + +} diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSENTFTPEntryParser.java b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSENTFTPEntryParser.java new file mode 100644 index 00000000000..61d1e99fac6 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSENTFTPEntryParser.java @@ -0,0 +1,82 @@ +/******************************************************************************** + * Copyright (c) 2007 Symbian Software Ltd. 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 http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Javier Montalvo Orus (Symbian) - initial API and implementation + ********************************************************************************/ + +package org.eclipse.rse.internal.services.files.ftp.parser; + +import java.text.ParseException; + +import org.apache.commons.net.ftp.FTPFile; +import org.apache.commons.net.ftp.parser.NTFTPEntryParser; + +public class RSENTFTPEntryParser extends NTFTPEntryParser { + + /** + * Parses a line of an NT FTP server file listing and converts it into a + * usable format in the form of an FTPFile instance. If the + * file listing line doesn't describe a file, null is + * returned, otherwise a FTPFile instance representing the + * files in the directory is returned. This extension enables the R/W permission + * for NT parsing, setting it as true by default. + *

+ * @param entry A line of text from the file listing + * @return An FTPFile instance corresponding to the supplied entry + */ + public FTPFile parseFTPEntry(String entry) + { + FTPFile f = new FTPFile(); + f.setRawListing(entry); + + if (matches(entry)) + { + String datestr = group(1)+" "+group(2); //$NON-NLS-1$ + String dirString = group(3); + String size = group(4); + String name = group(5); + try + { + f.setTimestamp(super.parseTimestamp(datestr)); + } + catch (ParseException e) + { + return null; // this is a parsing failure too. + } + + if (null == name || name.equals(".") || name.equals("..")) //$NON-NLS-1$//$NON-NLS-2$ + { + return (null); + } + f.setName(name); + + + if ("

".equals(dirString)) //$NON-NLS-1$ + { + f.setType(FTPFile.DIRECTORY_TYPE); + f.setSize(0); + } + else + { + f.setType(FTPFile.FILE_TYPE); + if (null != size) + { + f.setSize(Long.parseLong(size)); + } + } + + // only USER permission is shown in RSE + f.setPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION, true); + f.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION, true); + f.setPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION, true); + + return (f); + } + return null; + } + +} diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSEVMSFTPEntryParser.java b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSEVMSFTPEntryParser.java new file mode 100644 index 00000000000..b49b3adc553 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSEVMSFTPEntryParser.java @@ -0,0 +1,224 @@ +/******************************************************************************** + * Copyright (c) 2007 Symbian Software Ltd. 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 http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Javier Montalvo Orus (Symbian) - initial API and implementation + ********************************************************************************/ + +package org.eclipse.rse.internal.services.files.ftp.parser; + +import java.io.BufferedReader; +import java.io.IOException; +import java.text.ParseException; +import java.util.StringTokenizer; + +import org.apache.commons.net.ftp.FTPClientConfig; +import org.apache.commons.net.ftp.FTPFile; +import org.apache.commons.net.ftp.parser.ConfigurableFTPFileEntryParserImpl; + +public class RSEVMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl { + + private static final String DEFAULT_DATE_FORMAT + = "d-MMM-yyyy HH:mm:ss"; //9-NOV-2001 12:30:24 //$NON-NLS-1$ + + private static final String REGEX = + "(.*;[0-9]+)\\s*" //$NON-NLS-1$ + + "(\\d+)/\\d+\\s*" //$NON-NLS-1$ + +"(\\S+)\\s+(\\S+)\\s+" //$NON-NLS-1$ + + "\\[(([0-9$A-Za-z_]+)|([0-9$A-Za-z_]+),([0-9$a-zA-Z_]+))\\]?\\s*" //$NON-NLS-1$ + + "(\\([a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*\\))"; //$NON-NLS-1$ + + /** + * Constructor for a VMSFTPEntryParser object. + * + * @exception IllegalArgumentException + * Thrown if the regular expression is unparseable. Should not be seen + * under normal conditions. It it is seen, this is a sign that + * REGEX is not a valid regular expression. + */ + public RSEVMSFTPEntryParser() + { + this(null); + } + + /** + * This constructor allows the creation of a VMSFTPEntryParser object with + * something other than the default configuration. + * + * @param config The {@link FTPClientConfig configuration} object used to + * configure this parser. + * @exception IllegalArgumentException + * Thrown if the regular expression is unparseable. Should not be seen + * under normal conditions. It it is seen, this is a sign that + * REGEX is not a valid regular expression. + * @since 1.4 + */ + public RSEVMSFTPEntryParser(FTPClientConfig config) + { + super(REGEX); + configure(config); + } + + /** + * Parses a line of a VMS FTP server file listing and converts it into a + * usable format in the form of an FTPFile instance. If the + * file listing line doesn't describe a file, null is + * returned, otherwise a FTPFile instance representing the + * files in the directory is returned. + *

+ * @param entry A line of text from the file listing + * @return An FTPFile instance corresponding to the supplied entry + */ + public FTPFile parseFTPEntry(String entry) + { + //one block in VMS equals 512 bytes + long longBlock = 512; + + if (matches(entry)) + { + FTPFile f = new FTPFile(); + f.setRawListing(entry); + String name = group(1); + String size = group(2); + String datestr = group(3)+" "+group(4); //$NON-NLS-1$ + String owner = group(5); + String permissions = group(9); + try + { + f.setTimestamp(super.parseTimestamp(datestr)); + } + catch (ParseException e) + { + return null; // this is a parsing failure too. + } + + + String grp; + String user; + StringTokenizer t = new StringTokenizer(owner, ","); //$NON-NLS-1$ + switch (t.countTokens()) { + case 1: + grp = null; + user = t.nextToken(); + break; + case 2: + grp = t.nextToken(); + user = t.nextToken(); + break; + default: + grp = null; + user = null; + } + + if (name.lastIndexOf(".DIR") != -1) //$NON-NLS-1$ + { + f.setType(FTPFile.DIRECTORY_TYPE); + } + else + { + f.setType(FTPFile.FILE_TYPE); + } + //set FTPFile name + //Check also for versions to be returned or not + if (isVersioning()) + { + f.setName(name); + } + else + { + name = name.substring(0, name.lastIndexOf(";")); //$NON-NLS-1$ + if(name.lastIndexOf(".DIR")!=-1) //$NON-NLS-1$ + { + name = name.substring(0, name.lastIndexOf(".DIR")); //$NON-NLS-1$ + } + f.setName(name); + } + //size is retreived in blocks and needs to be put in bytes + //for us humans and added to the FTPFile array + long sizeInBytes = Long.parseLong(size) * longBlock; + f.setSize(sizeInBytes); + + f.setGroup(grp); + f.setUser(user); + //set group and owner + + //Set file permission. + //VMS has (SYSTEM,OWNER,GROUP,WORLD) users that can contain + //R (read) W (write) E (execute) D (delete) + + t = new StringTokenizer(permissions, ","); //$NON-NLS-1$ + + //discard SYSTEM permission + t.nextElement(); + + //iterate for OWNER GROUP WORLD permissions + for (int access = 0; access < 3; access++) + { + String token = t.nextToken(); + + f.setPermission(access, FTPFile.READ_PERMISSION, token.indexOf('R')!=-1); + f.setPermission(access, FTPFile.WRITE_PERMISSION, token.indexOf('W')!=-1); + f.setPermission(access, FTPFile.EXECUTE_PERMISSION, token.indexOf('E')!=-1); + } + + return f; + } + return null; + } + + + /** + * Reads the next entry using the supplied BufferedReader object up to + * whatever delemits one entry from the next. This parser cannot use + * the default implementation of simply calling BufferedReader.readLine(), + * because one entry may span multiple lines. + * + * @param reader The BufferedReader object from which entries are to be + * read. + * + * @return A string representing the next ftp entry or null if none found. + * @exception IOException thrown on any IO Error reading from the reader. + */ + public String readNextEntry(BufferedReader reader) throws IOException + { + String line = reader.readLine(); + StringBuffer entry = new StringBuffer(); + while (line != null) + { + if (line.startsWith("Directory") || line.startsWith("Total")) { //$NON-NLS-1$//$NON-NLS-2$ + line = reader.readLine(); + continue; + } + + entry.append(line); + if (line.trim().endsWith(")")) //$NON-NLS-1$ + { + break; + } + line = reader.readLine(); + } + return (entry.length() == 0 ? null : entry.toString()); + } + + protected boolean isVersioning() { + return false; + } + + /** + * Defines a default configuration to be used when this class is + * instantiated without a {@link FTPClientConfig FTPClientConfig} + * parameter being specified. + * @return the default configuration for this parser. + */ +protected FTPClientConfig getDefaultConfiguration() { + return new FTPClientConfig( + FTPClientConfig.SYST_VMS, + DEFAULT_DATE_FORMAT, + null, null, null, null); + } + + +} diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/META-INF/MANIFEST.MF index 57b521d33f4..6457914d2d5 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/META-INF/MANIFEST.MF +++ b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/META-INF/MANIFEST.MF @@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.rse.subsystems.files.core, org.eclipse.rse.core, org.eclipse.rse.ui, - org.eclipse.ui.console + org.eclipse.ui.console, + org.apache.commons.net Eclipse-LazyStart: true Export-Package: org.eclipse.rse.internal.subsystems.files.ftp;x-internal:=true, org.eclipse.rse.internal.subsystems.files.ftp.connectorservice;x-internal:=true, diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/plugin.xml b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/plugin.xml index 403c1c9af3b..a0da901b16d 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/plugin.xml +++ b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/plugin.xml @@ -42,5 +42,5 @@ Javier Montalvo Orus (Symbian) - [plan] Improve Discovery and Autodetect in RSE serviceType="_ftp._tcp"> - + diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java index e14cb5d5d75..d76ad052a4d 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java +++ b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java @@ -16,11 +16,14 @@ * Javier Montalvo Orus (Symbian) - Bug 169680 - [ftp] FTP files subsystem and service should use passive mode * David Dykstal (IBM) - 168977: refactoring IConnectorService and ServerLauncher hierarchies * Martin Oberhuber (Wind River) - [cleanup] move FTPSubsystemResources out of core + * Javier Montalvo Orus (Symbian) - Fixing 176216 - [api] FTP sould provide API to allow clients register their own FTPListingParser ********************************************************************************/ package org.eclipse.rse.internal.subsystems.files.ftp.connectorservice; import java.io.OutputStream; +import java.util.Arrays; +import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.rse.core.model.IHost; @@ -28,6 +31,7 @@ import org.eclipse.rse.core.model.IPropertySet; import org.eclipse.rse.core.model.PropertyType; import org.eclipse.rse.core.model.SystemSignonInformation; import org.eclipse.rse.internal.services.files.ftp.FTPService; +import org.eclipse.rse.internal.services.files.ftp.parser.FTPClientConfigFactory; import org.eclipse.rse.internal.subsystems.files.ftp.FTPSubsystemResources; import org.eclipse.rse.services.files.IFileService; import org.eclipse.rse.ui.subsystems.StandardConnectorService; @@ -51,8 +55,21 @@ public class FTPConnectorService extends StandardConnectorService if(_propertySet==null) { + + //Active - passive mode _propertySet = createPropertySet("FTP Settings"); //$NON-NLS-1$ _propertySet.addProperty("passive","false",PropertyType.getEnumPropertyType(new String[]{"true","false"})); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + + // FTP List parser + Set keys = FTPClientConfigFactory.getParserFactory().getKeySet(); + String[] keysArray = new String[keys.size()+1]; + + keys.toArray(keysArray); + keysArray[keysArray.length-1]="AUTO"; //$NON-NLS-1$ + + Arrays.sort(keysArray); + + _propertySet.addProperty("parser","AUTO",PropertyType.getEnumPropertyType(keysArray)); //$NON-NLS-1$ //$NON-NLS-2$ } } @@ -63,14 +80,7 @@ public class FTPConnectorService extends StandardConnectorService private void internalConnect() throws Exception { - _propertySet = getPropertySet("FTP Settings"); //$NON-NLS-1$ - - if(_propertySet==null) - { - _propertySet = createPropertySet("FTP Settings"); //$NON-NLS-1$ - _propertySet.addProperty("passive","false",PropertyType.getEnumPropertyType(new String[]{"true","false"})); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } - + SystemSignonInformation info = getSignonInformation(); _ftpService.setHostName(info.getHostname()); _ftpService.setUserId(info.getUserId());