Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 79249 Details for
Bug 203500
[ssh][ftp][encodings] Error creating a folder or file with non-ASCII characters (converted to ?)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Updated patch warning about encoding problems
patch203500_sshFtpEncodings.diff.txt (text/plain), 34.39 KB, created by
Martin Oberhuber
on 2007-09-26 18:49:46 EDT
(
hide
)
Description:
Updated patch warning about encoding problems
Filename:
MIME Type:
Creator:
Martin Oberhuber
Created:
2007-09-26 18:49:46 EDT
Size:
34.39 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.rse.connectorservice.ssh >Index: src/org/eclipse/rse/internal/connectorservice/ssh/SshConnectorService.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.tm.rse/plugins/org.eclipse.rse.connectorservice.ssh/src/org/eclipse/rse/internal/connectorservice/ssh/SshConnectorService.java,v >retrieving revision 1.15 >diff -u -r1.15 SshConnectorService.java >--- src/org/eclipse/rse/internal/connectorservice/ssh/SshConnectorService.java 3 Aug 2007 10:37:42 -0000 1.15 >+++ src/org/eclipse/rse/internal/connectorservice/ssh/SshConnectorService.java 26 Sep 2007 22:45:24 -0000 >@@ -13,6 +13,7 @@ > * Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry > * Martin Oberhuber (Wind River) - [186761] make the port setting configurable > * Martin Oberhuber (Wind River) - [198790] make SSH createSession() protected >+ * Martin Oberhuber (Wind River) - [203500] Support encodings for SSH Sftp paths > *******************************************************************************/ > > package org.eclipse.rse.internal.connectorservice.ssh; >@@ -61,6 +62,8 @@ > private static final int CONNECT_DEFAULT_TIMEOUT = 60; //seconds > private Session session; > private SessionLostHandler fSessionLostHandler; >+ /** Indicates the default string encoding on this platform */ >+ private static String _defaultEncoding = new java.io.InputStreamReader(new java.io.ByteArrayInputStream(new byte[0])).getEncoding(); > > public SshConnectorService(IHost host) { > super(SshConnectorResources.SshConnectorService_Name, SshConnectorResources.SshConnectorService_Description, host, SSH_DEFAULT_PORT); >@@ -209,6 +212,15 @@ > public Session getSession() { > return session; > } >+ >+ public String getControlEncoding() { >+ //TODO this code should be in IHost >+ String encoding = getHost().getDefaultEncoding(false); >+ if (encoding==null) encoding = getHost().getDefaultEncoding(true); >+ if (encoding==null) encoding = _defaultEncoding; >+ //</code to be in IHost> >+ return encoding; >+ } > > /** > * Handle session-lost events. >#P org.eclipse.rse.services.ssh >Index: src/org/eclipse/rse/internal/services/ssh/ISshSessionProvider.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.tm.rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/ISshSessionProvider.java,v >retrieving revision 1.2 >diff -u -r1.2 ISshSessionProvider.java >--- src/org/eclipse/rse/internal/services/ssh/ISshSessionProvider.java 15 Feb 2007 09:57:05 -0000 1.2 >+++ src/org/eclipse/rse/internal/services/ssh/ISshSessionProvider.java 26 Sep 2007 22:45:25 -0000 >@@ -12,7 +12,7 @@ > * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley. > * > * Contributors: >- * {Name} (company) - description of contribution. >+ * Martin Oberhuber (Wind River) - [203500] Support encodings for SSH Sftp paths > *******************************************************************************/ > package org.eclipse.rse.internal.services.ssh; > >@@ -26,4 +26,7 @@ > /* Inform the connectorService that a session has been lost. */ > public void handleSessionLost(); > >+ /* Return the encoding to be used for file and directory names */ >+ public String getControlEncoding(); >+ > } >Index: src/org/eclipse/rse/internal/services/ssh/files/SftpFileService.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.tm.rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/files/SftpFileService.java,v >retrieving revision 1.23 >diff -u -r1.23 SftpFileService.java >--- src/org/eclipse/rse/internal/services/ssh/files/SftpFileService.java 26 Sep 2007 21:14:47 -0000 1.23 >+++ src/org/eclipse/rse/internal/services/ssh/files/SftpFileService.java 26 Sep 2007 22:45:26 -0000 >@@ -14,6 +14,7 @@ > * Martin Oberhuber (Wind River) - [199548] Avoid touching files on setReadOnly() if unnecessary > * Benjamin Muskalla (b.muskalla@gmx.net) - [174690][ssh] cannot delete symbolic links on remote systems > * Martin Oberhuber (Wind River) - [203490] Fix NPE in SftpService.getUserHome() >+ * Martin Oberhuber (Wind River) - [203500] Support encodings for SSH Sftp paths > *******************************************************************************/ > > package org.eclipse.rse.internal.services.ssh.files; >@@ -26,10 +27,12 @@ > import java.io.IOException; > import java.io.InputStream; > import java.io.OutputStream; >+import java.io.UnsupportedEncodingException; > import java.text.MessageFormat; > import java.util.ArrayList; > import java.util.List; > import java.util.Vector; >+import java.util.regex.Pattern; > > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.core.runtime.NullProgressMonitor; >@@ -53,6 +56,8 @@ > import org.eclipse.rse.services.clientserver.IMatcher; > import org.eclipse.rse.services.clientserver.NamePatternMatcher; > import org.eclipse.rse.services.clientserver.PathUtility; >+import org.eclipse.rse.services.clientserver.messages.IndicatorException; >+import org.eclipse.rse.services.clientserver.messages.SystemMessage; > import org.eclipse.rse.services.clientserver.messages.SystemMessageException; > import org.eclipse.rse.services.files.AbstractFileService; > import org.eclipse.rse.services.files.IFileService; >@@ -139,7 +144,11 @@ > private ChannelSftp fChannelSftp; > private String fUserHome; > private Mutex fDirChannelMutex = new Mutex(); >- private long fDirChannelTimeout = 5000; //max.5 seconds to obtain dir channel >+ private long fDirChannelTimeout = 5000; //max.5 seconds to obtain dir channel >+ /** Client-desired encoding for file and path names */ >+ private String fControlEncoding = null; >+ /** Indicates the default string encoding on this platform */ >+ private static String defaultEncoding = new java.io.InputStreamReader(new java.io.ByteArrayInputStream(new byte[0])).getEncoding(); > > // public SftpFileService(SshConnectorService conn) { > // fConnector = conn; >@@ -149,6 +158,121 @@ > fSessionProvider = sessionProvider; > } > >+ public void setControlEncoding(String encoding) { >+ fControlEncoding = encoding; >+ } >+ >+ /** >+ * Encode String with requested user encoding, in case it differs from Platform default encoding. >+ * @param s String to encode >+ * @return encoded String >+ * @throws SystemMessageException >+ */ >+ protected String recode(String s) throws SystemMessageException { >+ if (fControlEncoding==null) { >+ return s; >+ } else if (fControlEncoding.equals(defaultEncoding)) { >+ return s; >+ } >+ try { >+ byte[] bytes = s.getBytes(fControlEncoding); //what we want on the wire >+ return new String(bytes); //what we need to tell Jsch to get this on the wire >+ } catch(UnsupportedEncodingException e) { >+ throw makeSystemMessageException(e); >+ } >+ } >+ >+ /** >+ * Recode String, and check that no information is lost. >+ * Throw an exception in case the desired Unicode String can not be expressed >+ * by the current encodings. Also enquotes result characters '?' and '*' for >+ * Jsch if necessary. >+ * @param s String to recode >+ * @return recoded String >+ * @throws SystemMessageException if information is lost >+ */ >+ protected String recodeSafe(String s) throws SystemMessageException { >+ try { >+ String recoded = recode(s); >+ byte[] bytes = recoded.getBytes(defaultEncoding); >+ String decoded = decode(new String(bytes)); >+ if (!s.equals(decoded)) { >+ int i=0; >+ int lmax = Math.min(s.length(), decoded.length()); >+ while( (i<lmax) && (s.charAt(i)==decoded.charAt(i))) { >+ i++; >+ } >+ //String sbad=s.substring(Math.max(i-2,0), Math.min(i+2,lmax)); >+ char sbad = s.charAt(i); >+ String msg = "Cannot express character \'"+sbad+"\'(0x"+Integer.toHexString(sbad) +") with "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ if (fControlEncoding==null || fControlEncoding.equals(defaultEncoding)) { >+ msg += "default encoding \""+defaultEncoding+"\". "; //$NON-NLS-1$ //$NON-NLS-2$ >+ } else { >+ msg += "encoding \""+fControlEncoding+"\" over local default encoding \""+defaultEncoding+"\". "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ } >+ msg += "Please specify a different encoding in host properties."; //$NON-NLS-1$ >+ throw new UnsupportedEncodingException(msg); >+ } >+ //Quote ? and * characters for Jsch >+ //FIXME bug 204705: this does not work properly for commands like ls(), due to a Jsch bug >+ return quoteForJsch(recoded); >+ } catch(UnsupportedEncodingException e) { >+ try { >+ //SystemMessage msg = new SystemMessage("RSE","F","9999",'E',e.getMessage(),"Please specify a different encoding in host properties."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ >+ SystemMessage msg = new SystemMessage("RSE","F","9999",'E',e.getMessage(),""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ >+ //throw new RemoteFileIOException(new SystemMessageException(msg)); >+ throw new SystemMessageException(msg); >+ } catch(IndicatorException ind) { >+ throw makeSystemMessageException(e); >+ } >+ } >+ } >+ >+ /** >+ * Decode String (sftp result) with requested user encoding, in case it differs from Platform default encoding. >+ * @param s String to decode >+ * @return decoded String >+ * @throws SystemMessageException >+ */ >+ protected String decode(String s) throws SystemMessageException { >+ if (fControlEncoding==null) { >+ return s; >+ } else if (fControlEncoding.equals(defaultEncoding)) { >+ return s; >+ } >+ try { >+ byte[] bytes = s.getBytes(); //original bytes sent by SSH >+ return new String(bytes, fControlEncoding); >+ } catch(UnsupportedEncodingException e) { >+ throw makeSystemMessageException(e); >+ } >+ } >+ >+ /** Regular expression pattern to know when Jsch needs quoting. */ >+ private static Pattern quoteForJschPattern = Pattern.compile("[*?\\\\]"); //$NON-NLS-1$ >+ >+ /** >+ * Quote characters '?' and '*' for Jsch because it would otherwise >+ * use them as patterns for globbing. >+ * @param s String to enquote >+ * @return String with '?' and '*' quoted. >+ */ >+ protected String quoteForJsch(String s) { >+ if(quoteForJschPattern.matcher(s).find()) { >+ StringBuffer buf = new StringBuffer(s.length()+8); >+ for(int i=0; i<s.length(); i++) { >+ char c = s.charAt(i); >+// if(c=='?' || c=='*' || c=='\\') { >+ if(c=='?' || c=='*') { >+ buf.append('\\'); >+ } >+ buf.append(c); >+ } >+ s = buf.toString(); >+ } >+ return s; >+ } >+ > public String getName() { > return SshServiceResources.SftpFileService_Name; > } >@@ -164,7 +288,8 @@ > Channel channel=session.openChannel("sftp"); //$NON-NLS-1$ > channel.connect(); > fChannelSftp=(ChannelSftp)channel; >- fUserHome = fChannelSftp.pwd(); >+ setControlEncoding(fSessionProvider.getControlEncoding()); >+ fUserHome = decode(fChannelSftp.pwd()); > Activator.trace("SftpFileService.connected"); //$NON-NLS-1$ > } catch(Exception e) { > Activator.trace("SftpFileService.connecting failed: "+e.toString()); //$NON-NLS-1$ >@@ -256,7 +381,7 @@ > SftpATTRS attrs = null; > if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) { > try { >- attrs = getChannel("SftpFileService.getFile: "+fileName).stat(remoteParent+'/'+fileName); //$NON-NLS-1$ >+ attrs = getChannel("SftpFileService.getFile: "+fileName).stat(recodeSafe(remoteParent+'/'+fileName)); //$NON-NLS-1$ > Activator.trace("SftpFileService.getFile <--"); //$NON-NLS-1$ > node = makeHostFile(remoteParent, fileName, attrs); > } catch(Exception e) { >@@ -304,12 +429,12 @@ > List results = new ArrayList(); > if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) { > try { >- Vector vv=getChannel("SftpFileService.internalFetch: "+parentPath).ls(parentPath); //$NON-NLS-1$ >+ Vector vv=getChannel("SftpFileService.internalFetch: "+parentPath).ls(recodeSafe(parentPath)); //$NON-NLS-1$ > for(int ii=0; ii<vv.size(); ii++) { > Object obj=vv.elementAt(ii); > if(obj instanceof ChannelSftp.LsEntry){ > ChannelSftp.LsEntry lsEntry = (ChannelSftp.LsEntry)obj; >- String fileName = lsEntry.getFilename(); >+ String fileName = decode(lsEntry.getFilename()); > if (".".equals(fileName) || "..".equals(fileName)) { //$NON-NLS-1$ //$NON-NLS-2$ > //don't show the trivial names > continue; >@@ -353,15 +478,15 @@ > // 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$ >+ // linkTarget=getChannel("makeHostFile.readlink").readlink(recode(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$ >+ getChannel("makeHostFile.chdir").cd(recode(parentPath+'/'+fileName)); //$NON-NLS-1$ >+ linkTarget=decode(getChannel("makeHostFile.chdir").pwd()); //$NON-NLS-1$ > if (linkTarget!=null && !linkTarget.equals(parentPath+'/'+fileName)) { >- attrsTarget = getChannel("SftpFileService.getFile").stat(linkTarget); //$NON-NLS-1$ >+ attrsTarget = getChannel("SftpFileService.getFile").stat(recode(linkTarget)); //$NON-NLS-1$ > } else { > linkTarget=null; > } >@@ -421,6 +546,7 @@ > } > dst += remoteFile; > } >+ dst = recodeSafe(dst); > getChannel("SftpFileService.upload "+remoteFile); //check the session is healthy //$NON-NLS-1$ > channel=(ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$ > channel.connect(); >@@ -439,7 +565,7 @@ > if (attr.getSize() != localFile.length()) { > //Error: file truncated? - Inform the user!! > //TODO test if this works >- throw makeSystemMessageException(new IOException(NLS.bind(SshServiceResources.SftpFileService_Error_upload_size,dst))); >+ throw makeSystemMessageException(new IOException(NLS.bind(SshServiceResources.SftpFileService_Error_upload_size,remoteFile))); > //return false; > } > } >@@ -532,7 +658,7 @@ > //localFile.createNewFile(); > } > //TODO Ascii/binary? >- String remotePath = remoteParent+'/'+remoteFile; >+ String remotePath = recode(remoteParent+'/'+remoteFile); > int mode=ChannelSftp.OVERWRITE; > MyProgressMonitor sftpMonitor = new MyProgressMonitor(monitor); > getChannel("SftpFileService.download "+remoteFile); //check the session is healthy //$NON-NLS-1$ >@@ -550,7 +676,7 @@ > if (attr.getSize() != localFile.length()) { > //Error: file truncated? - Inform the user!! > //TODO test if this works >- throw makeSystemMessageException(new IOException(NLS.bind(SshServiceResources.SftpFileService_Error_download_size,remotePath))); >+ throw makeSystemMessageException(new IOException(NLS.bind(SshServiceResources.SftpFileService_Error_download_size,remoteFile))); > //return false; > } > } >@@ -603,7 +729,7 @@ > IHostFile result = null; > if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) { > try { >- String fullPath = remoteParent + '/' + fileName; >+ String fullPath = recodeSafe(remoteParent + '/' + fileName); > OutputStream os = getChannel("SftpFileService.createFile").put(fullPath); //$NON-NLS-1$ > //TODO workaround bug 153118: write a single space > //since jsch hangs when trying to close the stream without writing >@@ -629,7 +755,7 @@ > IHostFile result = null; > if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) { > try { >- String fullPath = remoteParent + '/' + folderName; >+ String fullPath = recodeSafe(remoteParent + '/' + folderName); > getChannel("SftpFileService.createFolder").mkdir(fullPath); //$NON-NLS-1$ > SftpATTRS attrs = getChannel("SftpFileService.createFolder.stat").stat(fullPath); //$NON-NLS-1$ > result = makeHostFile(remoteParent, folderName, attrs); >@@ -652,7 +778,7 @@ > Activator.trace("SftpFileService.delete.waitForLock"); //$NON-NLS-1$ > if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) { > try { >- String fullPath = remoteParent + '/' + fileName; >+ String fullPath = recodeSafe(remoteParent + '/' + fileName); > SftpATTRS attrs = null; > try { > attrs = getChannel("SftpFileService.delete").lstat(fullPath); //$NON-NLS-1$ >@@ -705,7 +831,7 @@ > try { > String fullPathOld = remoteParent + '/' + oldName; > String fullPathNew = remoteParent + '/' + newName; >- getChannel("SftpFileService.rename").rename(fullPathOld, fullPathNew); //$NON-NLS-1$ >+ getChannel("SftpFileService.rename").rename(recode(fullPathOld), recodeSafe(fullPathNew)); //$NON-NLS-1$ > ok=true; > Activator.trace("SftpFileService.rename ok"); //$NON-NLS-1$ > } catch (Exception e) { >@@ -794,8 +920,8 @@ > // TODO Interpret some error messages like "command not found" (use ren instead of mv on windows) > // TODO mimic by copy if the remote does not support copying between file systems? > Activator.trace("SftpFileService.move "+srcName); //$NON-NLS-1$ >- String fullPathOld = PathUtility.enQuoteUnix(srcParent + '/' + srcName); >- String fullPathNew = PathUtility.enQuoteUnix(tgtParent + '/' + tgtName); >+ String fullPathOld = PathUtility.enQuoteUnix(recode(srcParent + '/' + srcName)); >+ String fullPathNew = PathUtility.enQuoteUnix(recodeSafe(tgtParent + '/' + tgtName)); > int rv = runCommand("mv "+fullPathOld+' '+fullPathNew, monitor); //$NON-NLS-1$ > return (rv==0); > } >@@ -805,8 +931,8 @@ > // TODO check if newer versions of sftp support copy directly > // TODO Interpret some error messages like "command not found" (use (x)copy instead of cp on windows) > Activator.trace("SftpFileService.copy "+srcName); //$NON-NLS-1$ >- String fullPathOld = PathUtility.enQuoteUnix(srcParent + '/' + srcName); >- String fullPathNew = PathUtility.enQuoteUnix(tgtParent + '/' + tgtName); >+ String fullPathOld = PathUtility.enQuoteUnix(recode(srcParent + '/' + srcName)); >+ String fullPathNew = PathUtility.enQuoteUnix(recodeSafe(tgtParent + '/' + tgtName)); > int rv = runCommand("cp -Rp "+fullPathOld+' '+fullPathNew, monitor); //$NON-NLS-1$ > return (rv==0); > } >@@ -852,7 +978,7 @@ > if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) { > try { > String path = parent + '/' + name; >- getChannel("SftpFileService.setLastModified").setMtime(path, (int)(timestamp/1000)); //$NON-NLS-1$ >+ getChannel("SftpFileService.setLastModified").setMtime(recode(path), (int)(timestamp/1000)); //$NON-NLS-1$ > ok=true; > Activator.trace("SftpFileService.setLastModified ok"); //$NON-NLS-1$ > } catch (Exception e) { >@@ -871,7 +997,7 @@ > if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) { > try { > String path = parent + '/' + name; >- SftpATTRS attr = getChannel("SftpFileService.setReadOnly").stat(path); //$NON-NLS-1$ >+ SftpATTRS attr = getChannel("SftpFileService.setReadOnly").stat(recode(path)); //$NON-NLS-1$ > int permOld = attr.getPermissions(); > int permNew = permOld; > if (readOnly) { >@@ -882,7 +1008,7 @@ > if (permNew != permOld) { > //getChannel("SftpFileService.setReadOnly").chmod(permNew, path); //$NON-NLS-1$ > attr.setPERMISSIONS(permNew); >- getChannel("SftpFileService.setReadOnly").setStat(path, attr); //$NON-NLS-1$ >+ getChannel("SftpFileService.setReadOnly").setStat(recode(path), attr); //$NON-NLS-1$ > ok=true; > Activator.trace("SftpFileService.setReadOnly ok"); //$NON-NLS-1$ > } else { >@@ -909,7 +1035,7 @@ > InputStream stream = null; > > try { >- String remotePath = remoteParent + '/' + remoteFile; >+ String remotePath = recode(remoteParent + '/' + remoteFile); > getChannel("SftpFileService.getInputStream " + remoteFile); //check the session is healthy //$NON-NLS-1$ > ChannelSftp channel = (ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$ > channel.connect(); >@@ -954,7 +1080,7 @@ > getChannel("SftpFileService.getOutputStream " + remoteFile); //check the session is healthy //$NON-NLS-1$ > ChannelSftp channel = (ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$ > channel.connect(); >- stream = new SftpBufferedOutputStream(channel.put(dst, sftpMonitor, mode), channel); >+ stream = new SftpBufferedOutputStream(channel.put(recodeSafe(dst), sftpMonitor, mode), channel); > Activator.trace("SftpFileService.getOutputStream " + remoteFile + " ok"); //$NON-NLS-1$ //$NON-NLS-2$ > } > catch (Exception e) { >@@ -966,4 +1092,4 @@ > } > return stream; > } >-} >\ No newline at end of file >+} >#P org.eclipse.rse.services.files.ftp >Index: src/org/eclipse/rse/internal/services/files/ftp/FTPService.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.tm.rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPService.java,v >retrieving revision 1.39 >diff -u -r1.39 FTPService.java >--- src/org/eclipse/rse/internal/services/files/ftp/FTPService.java 26 Sep 2007 21:14:52 -0000 1.39 >+++ src/org/eclipse/rse/internal/services/files/ftp/FTPService.java 26 Sep 2007 22:45:27 -0000 >@@ -37,7 +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 >+ * Javier Montalvo Orus (Symbian) - Fixing 176216 - [api] FTP should provide API to allow clients register their own FTPListingParser > * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API > * Javier Montalvo Orus (Symbian) - improved autodetection of FTPListingParser > * Javier Montalvo Orus (Symbian) - [187096] Drag&Drop + Copy&Paste shows error message on FTP connection >@@ -61,6 +61,7 @@ > * Martin Oberhuber (Wind River) - [203306] Fix Deadlock comparing two files on FTP > * Martin Oberhuber (Wind River) - [204669] Fix ftp path concatenation on systems using backslash separator > * Martin Oberhuber (Wind River) - [203490] Fix NPE in FTPService.getUserHome() >+ * Martin Oberhuber (Wind River) - [203500] Support encodings for FTP paths > ********************************************************************************/ > > package org.eclipse.rse.internal.services.files.ftp; >@@ -74,6 +75,7 @@ > import java.io.IOException; > import java.io.InputStream; > import java.io.OutputStream; >+import java.io.UnsupportedEncodingException; > import java.text.MessageFormat; > import java.util.ArrayList; > import java.util.HashMap; >@@ -96,6 +98,8 @@ > import org.eclipse.rse.services.clientserver.IMatcher; > import org.eclipse.rse.services.clientserver.NamePatternMatcher; > import org.eclipse.rse.services.clientserver.PathUtility; >+import org.eclipse.rse.services.clientserver.messages.IndicatorException; >+import org.eclipse.rse.services.clientserver.messages.SystemMessage; > import org.eclipse.rse.services.clientserver.messages.SystemMessageException; > import org.eclipse.rse.services.files.AbstractFileService; > import org.eclipse.rse.services.files.IFileService; >@@ -117,6 +121,7 @@ > private transient String _userId; > private transient String _password; > private transient int _portNumber; >+ private transient String _controlEncoding; //Encoding to be used for file and path names > > private OutputStream _ftpLoggingOutputStream; > private IPropertySet _ftpPropertySet; >@@ -273,13 +278,69 @@ > { > _entryParserFactory = entryParserFactory; > } >+ >+ /** >+ * Set the character encoding to be used on the FTP command channel. >+ * The encoding must be compatible with ASCII since FTP commands will >+ * be sent with the same encoding. Therefore, wide >+ * (16-bit) encodings are not supported. >+ * @param encoding Encoding to set >+ */ >+ public void setControlEncoding(String encoding) >+ { >+ _controlEncoding = encoding; >+ } > >+ /** >+ * Check whether the given Unicode String can be properly represented with the >+ * specified control encoding. Throw a SystemMessageException if it turns out >+ * that information would be lost. >+ * @param s String to check >+ * @return the original String or a quoted or re-coded version if possible >+ * @throws SystemMessageException if information is lost >+ */ >+ protected String checkEncoding(String s) throws SystemMessageException { >+ String encoding = _controlEncoding!=null ? _controlEncoding : getFTPClient().getControlEncoding(); >+ try { >+ byte[] bytes = s.getBytes(encoding); >+ String decoded = new String(bytes, encoding); >+ if (!s.equals(decoded)) { >+ int i=0; >+ int lmax = Math.min(s.length(), decoded.length()); >+ while( (i<lmax) && (s.charAt(i)==decoded.charAt(i))) { >+ i++; >+ } >+ //String sbad=s.substring(Math.max(i-2,0), Math.min(i+2,lmax)); >+ char sbad = s.charAt(i); >+ //FIXME Need to externalize this message in 3.0 >+ String msg = "Cannot express character \'"+sbad+"\'(0x"+Integer.toHexString(sbad) +") with " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ + "encoding \""+encoding+"\". "; //$NON-NLS-1$ //$NON-NLS-2$ >+ msg += "Please specify a different encoding in host properties."; //$NON-NLS-1$ >+ throw new UnsupportedEncodingException(msg); >+ } >+ return s; >+ } catch(UnsupportedEncodingException e) { >+ try { >+ //SystemMessage msg = new SystemMessage("RSE","F","9999",'E',e.getMessage(),"Please specify a different encoding in host properties."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ >+ SystemMessage msg = new SystemMessage("RSE","F","9999",'E',e.getMessage(),""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ >+ //throw new RemoteFileIOException(new SystemMessageException(msg)); >+ throw new SystemMessageException(msg); >+ } catch(IndicatorException ind) { >+ throw new RemoteFileIOException(e); >+ } >+ } >+ } >+ > public void connect() throws RemoteFileSecurityException,IOException > { > > if (_ftpClient == null) > { > _ftpClient = new FTPClient(); >+ // Encoding of control connection >+ if(_controlEncoding!=null) { >+ _ftpClient.setControlEncoding(_controlEncoding); >+ } > } > > if(_ftpLoggingOutputStream!=null) >@@ -403,6 +464,10 @@ > if (_ftpClient == null) > { > _ftpClient = new FTPClient(); >+ // Encoding of control connection >+ if(_controlEncoding!=null) { >+ _ftpClient.setControlEncoding(_controlEncoding); >+ } > } > > if(_hostName!=null) >@@ -433,6 +498,7 @@ > FTPClient ftpClient = new FTPClient(); > boolean ok=false; > try { >+ ftpClient.setControlEncoding(_ftpClient.getControlEncoding()); > ftpClient.connect(_ftpClient.getRemoteAddress()); > ftpClient.login(_userId,_password); > >@@ -485,6 +551,8 @@ > */ > protected FTPHostFile getFileInternal(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException > { >+ remoteParent = checkEncoding(remoteParent); >+ fileName = checkEncoding(fileName); > if (monitor!=null){ > if (monitor.isCanceled()) { > throw new RemoteFileCancelledException(); >@@ -584,6 +652,7 @@ > */ > protected IHostFile[] internalFetch(String parentPath, String fileFilter, int fileType, IProgressMonitor monitor) throws SystemMessageException > { >+ parentPath = checkEncoding(parentPath); > if (monitor!=null){ > if (monitor.isCanceled()) { > throw new RemoteFileCancelledException(); >@@ -676,6 +745,8 @@ > public boolean upload(File localFile, String remoteParent, String remoteFile, boolean isBinary, String srcEncoding, String hostEncoding, IProgressMonitor monitor) throws SystemMessageException > { > boolean retValue = true; >+ remoteParent = checkEncoding(remoteParent); >+ remoteFile = checkEncoding(remoteFile); > > if (monitor!=null){ > if (monitor.isCanceled()) { >@@ -758,6 +829,8 @@ > public boolean upload(InputStream stream, String remoteParent, String remoteFile, boolean isBinary, String hostEncoding, IProgressMonitor monitor) throws SystemMessageException > { > boolean retValue = true; >+ remoteParent = checkEncoding(remoteParent); >+ remoteFile = checkEncoding(remoteFile); > > try > { >@@ -897,7 +970,6 @@ > return new FTPHostFile("",_userHome,true,true,0,0,true); //$NON-NLS-1$ > } > >- > /* > * (non-Javadoc) > * @see org.eclipse.rse.services.files.IFileService#getRoots(org.eclipse.core.runtime.IProgressMonitor) >@@ -924,7 +996,9 @@ > */ > public boolean delete(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException { > boolean hasSucceeded = false; >- >+ remoteParent = checkEncoding(remoteParent); >+ fileName = checkEncoding(fileName); >+ > MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor); > progressMonitor.init(FTPServiceResources.FTP_File_Service_Deleting_Task+fileName, 1); > >@@ -980,8 +1054,10 @@ > * @see org.eclipse.rse.services.files.IFileService#rename(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String, java.lang.String) > */ > public boolean rename(String remoteParent, String oldName, String newName, IProgressMonitor monitor) throws SystemMessageException { >- > boolean success = false; >+ remoteParent = checkEncoding(remoteParent); >+ oldName = checkEncoding(oldName); >+ newName = checkEncoding(newName); > > if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) > { >@@ -1026,8 +1102,11 @@ > * @see org.eclipse.rse.services.files.IFileService#move(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String, java.lang.String, java.lang.String) > */ > public boolean move(String srcParent, String srcName, String tgtParent, String tgtName, IProgressMonitor monitor) throws SystemMessageException{ >- > boolean success = false; >+ srcParent = checkEncoding(srcParent); >+ srcName = checkEncoding(srcName); >+ tgtParent = checkEncoding(tgtParent); >+ tgtName = checkEncoding(tgtName); > > if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) > { >@@ -1061,6 +1140,8 @@ > */ > public IHostFile createFolder(String remoteParent, String folderName, IProgressMonitor monitor) throws SystemMessageException > { >+ remoteParent = checkEncoding(remoteParent); >+ folderName = checkEncoding(folderName); > if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) > { > try >@@ -1093,7 +1174,8 @@ > * @see org.eclipse.rse.services.files.IFileService#createFile(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String) > */ > public IHostFile createFile(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException{ >- >+ remoteParent = checkEncoding(remoteParent); >+ fileName = checkEncoding(fileName); > try { > File tempFile = File.createTempFile("ftp", "temp"); //$NON-NLS-1$ //$NON-NLS-2$ > tempFile.deleteOnExit(); >@@ -1385,7 +1467,9 @@ > * @see org.eclipse.rse.services.files.AbstractFileService#getOutputStream(java.lang.String, java.lang.String, boolean, org.eclipse.core.runtime.IProgressMonitor) > */ > public OutputStream getOutputStream(String remoteParent, String remoteFile, boolean isBinary, IProgressMonitor monitor) throws SystemMessageException { >- >+ remoteParent = checkEncoding(remoteParent); >+ remoteFile = checkEncoding(remoteFile); >+ > if (monitor != null && monitor.isCanceled()){ > throw new RemoteFileCancelledException(); > } >@@ -1435,4 +1519,4 @@ > } > } > >-} >\ No newline at end of file >+} >#P org.eclipse.rse.subsystems.files.ftp >Index: src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java >=================================================================== >RCS file: /cvsroot/dsdp/org.eclipse.tm.rse/plugins/org.eclipse.rse.subsystems.files.ftp/src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java,v >retrieving revision 1.17 >diff -u -r1.17 FTPConnectorService.java >--- src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java 26 Sep 2007 13:24:53 -0000 1.17 >+++ src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java 26 Sep 2007 22:45:28 -0000 >@@ -21,6 +21,7 @@ > * David Dykstal (IBM) - added RESID_FTP_SETTINGS_LABEL > * David McKnight (IBM) - [196632] [ftp] Passive mode setting does not work > * Martin Oberhuber (Wind River) - [204669] Fix ftp path concatenation on systems using backslash separator >+ * Martin Oberhuber (Wind River) - [203500] Support encodings for FTP paths > ********************************************************************************/ > > package org.eclipse.rse.internal.subsystems.files.ftp.connectorservice; >@@ -52,6 +53,9 @@ > { > protected FTPService _ftpService; > >+ /** Indicates the default string encoding on this platform */ >+ private static String _defaultEncoding = new java.io.InputStreamReader(new java.io.ByteArrayInputStream(new byte[0])).getEncoding(); >+ > public FTPConnectorService(IHost host, int port) > { > super(FTPSubsystemResources.RESID_FTP_CONNECTORSERVICE_NAME,FTPSubsystemResources.RESID_FTP_CONNECTORSERVICE_DESCRIPTION, host, port); >@@ -105,11 +109,17 @@ > _ftpService.setLoggingStream(getLoggingStream(info.getHostname(),getPort())); > _ftpService.setPropertySet(propertySet); > _ftpService.setFTPClientConfigFactory(FTPClientConfigFactory.getParserFactory()); >- >+ //TODO this code should be in IHost >+ String encoding = getHost().getDefaultEncoding(false); >+ if (encoding==null) encoding = getHost().getDefaultEncoding(true); >+ //TODO Here, we set the FTP default encoding same as the local encoding. >+ //Another alternative would be to set ISO-8859-1, which is the >+ //default-default internal to FTP, or keep it "null". >+ if (encoding==null) encoding = _defaultEncoding; >+ //</code to be in IHost> >+ _ftpService.setControlEncoding(encoding); > > _ftpService.connect(); >- >- > } > > /* (non-Javadoc) >@@ -163,4 +173,4 @@ > return (_ftpService != null && _ftpService.isConnected()); > } > >-} >\ No newline at end of file >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 203500
:
78634
|
78636
| 79249