1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-18 13:45:45 +02:00

[224799] Fix JSch encoding problems with arabic UTF-8 file names

This commit is contained in:
Martin Oberhuber 2008-04-02 21:00:03 +00:00
parent 94f38246c5
commit 69c14379e8
2 changed files with 441 additions and 419 deletions

View file

@ -78,8 +78,8 @@ public class SshConnectorService extends StandardConnectorService implements ISs
private static final String PROPERTY_KEY_TIMEOUT = "timeout(sec)"; //$NON-NLS-1$
private static final String PROPERTY_KEY_KEEPALIVE = "keepalive(sec)"; //$NON-NLS-1$
private Session session;
private SessionLostHandler fSessionLostHandler;
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();
@ -100,46 +100,46 @@ public class SshConnectorService extends StandardConnectorService implements ISs
* the Jsch config (for instance, in order to switch off strict
* host key checking or in order to add specific ciphers).
*/
protected Session createSession(String username, String password, String hostname, int port, UserInfo wrapperUI, IProgressMonitor monitor) throws JSchException {
IJSchService service = Activator.getDefault().getJSchService();
if (service == null)
return null;
Session session = service.createSession(hostname, port, username);
protected Session createSession(String username, String password, String hostname, int port, UserInfo wrapperUI, IProgressMonitor monitor) throws JSchException {
IJSchService service = Activator.getDefault().getJSchService();
if (service == null)
return null;
Session session = service.createSession(hostname, port, username);
IPropertySet propertySet = getPropertySet();
IPropertySet propertySet = getPropertySet();
String timeoutStr = propertySet.getPropertyValue(PROPERTY_KEY_TIMEOUT);
int timeout = 0; //default is never timeout
try {
int value = Integer.parseInt(timeoutStr);
if (value > 0) {
timeout = value * 1000;
}
} catch (NumberFormatException e) {
//wrong input - should never happen because property type is Integer
}
session.setTimeout(timeout);
int value = Integer.parseInt(timeoutStr);
if (value > 0) {
timeout = value * 1000;
}
} catch (NumberFormatException e) {
//wrong input - should never happen because property type is Integer
}
session.setTimeout(timeout);
int keepalive = 300000; //default is 5 minutes
String keepaliveStr = propertySet.getPropertyValue(PROPERTY_KEY_KEEPALIVE);
try {
int value = Integer.parseInt(keepaliveStr);
if (value >= 0) {
keepalive = value * 1000;
}
} catch (NumberFormatException e) {
//wrong input - should never happen because property type is Integer
}
if (keepalive > 0) {
session.setServerAliveInterval(keepalive);
}
int keepalive = 300000; //default is 5 minutes
String keepaliveStr = propertySet.getPropertyValue(PROPERTY_KEY_KEEPALIVE);
try {
int value = Integer.parseInt(keepaliveStr);
if (value >= 0) {
keepalive = value * 1000;
}
} catch (NumberFormatException e) {
//wrong input - should never happen because property type is Integer
}
if (keepalive > 0) {
session.setServerAliveInterval(keepalive);
}
session.setServerAliveCountMax(6); //give up after 6 tries (remote will be dead after 30 min)
if (password != null)
session.setServerAliveCountMax(6); //give up after 6 tries (remote will be dead after 30 min)
if (password != null)
session.setPassword(password);
session.setUserInfo(wrapperUI);
return session;
}
session.setUserInfo(wrapperUI);
return session;
}
static void shutdown() {
//TODO: Store all Jsch sessions in a pool and disconnect them on shutdown
@ -159,45 +159,45 @@ public class SshConnectorService extends StandardConnectorService implements ISs
}
protected void internalConnect(IProgressMonitor monitor) throws Exception
{
{
// Fire comm event to signal state about to change
fireCommunicationsEvent(CommunicationsEvent.BEFORE_CONNECT);
String host = getHostName();
String user = getUserId();
String password=""; //$NON-NLS-1$
SystemSignonInformation ssi = getSignonInformation();
if (ssi!=null) {
password = getSignonInformation().getPassword();
}
MyUserInfo userInfo = new MyUserInfo(user, password);
userInfo.aboutToConnect();
String host = getHostName();
String user = getUserId();
String password=""; //$NON-NLS-1$
SystemSignonInformation ssi = getSignonInformation();
if (ssi!=null) {
password = getSignonInformation().getPassword();
}
MyUserInfo userInfo = new MyUserInfo(user, password);
userInfo.aboutToConnect();
try {
session = createSession(user, password, host, getSshPort(),
userInfo, monitor);
try {
session = createSession(user, password, host, getSshPort(),
userInfo, monitor);
//java.util.Hashtable config=new java.util.Hashtable();
//config.put("StrictHostKeyChecking", "no");
//session.setConfig(config);
userInfo.aboutToConnect();
//java.util.Hashtable config=new java.util.Hashtable();
//config.put("StrictHostKeyChecking", "no");
//session.setConfig(config);
userInfo.aboutToConnect();
Activator.trace("SshConnectorService.connecting..."); //$NON-NLS-1$
//wait for 60 sec maximum during connect
session.connect(CONNECT_DEFAULT_TIMEOUT * 1000);
Activator.trace("SshConnectorService.connected"); //$NON-NLS-1$
} catch (JSchException e) {
Activator.trace("SshConnectorService.connect failed: "+e.toString()); //$NON-NLS-1$
sessionDisconnect();
Activator.trace("SshConnectorService.connecting..."); //$NON-NLS-1$
//wait for 60 sec maximum during connect
session.connect(CONNECT_DEFAULT_TIMEOUT * 1000);
Activator.trace("SshConnectorService.connected"); //$NON-NLS-1$
} catch (JSchException e) {
Activator.trace("SshConnectorService.connect failed: "+e.toString()); //$NON-NLS-1$
sessionDisconnect();
if(e.toString().indexOf("Auth cancel")>=0) { //$NON-NLS-1$
throw new OperationCanceledException();
}
throw e;
}
userInfo.connectionMade();
fSessionLostHandler = new SessionLostHandler(this);
notifyConnection();
}
throw e;
}
userInfo.connectionMade();
fSessionLostHandler = new SessionLostHandler(this);
notifyConnection();
}
/**
* Disconnect the ssh session.
@ -205,21 +205,21 @@ public class SshConnectorService extends StandardConnectorService implements ISs
* quickly in succession.
*/
private synchronized void sessionDisconnect() {
Activator.trace("SshConnectorService.sessionDisconnect"); //$NON-NLS-1$
try {
if (session.isConnected())
session.disconnect();
} catch(Exception e) {
//Bug 175328: NPE on disconnect shown in UI
//This is a non-critical exception so print only in debug mode
if (Activator.isTracingOn()) e.printStackTrace();
}
Activator.trace("SshConnectorService.sessionDisconnect"); //$NON-NLS-1$
try {
if (session.isConnected())
session.disconnect();
} catch(Exception e) {
//Bug 175328: NPE on disconnect shown in UI
//This is a non-critical exception so print only in debug mode
if (Activator.isTracingOn()) e.printStackTrace();
}
}
protected void internalDisconnect(IProgressMonitor monitor) throws Exception
{
//TODO Will services like the sftp service be disconnected too? Or notified?
Activator.trace("SshConnectorService.disconnect"); //$NON-NLS-1$
Activator.trace("SshConnectorService.disconnect"); //$NON-NLS-1$
try
{
if (session != null) {
@ -253,30 +253,29 @@ public class SshConnectorService extends StandardConnectorService implements ISs
}
//TODO avoid having jsch type "Session" in the API.
//Could be done by instanciating SshShellService and SshFileService here,
// Could be done by instantiating SshShellService and SshFileService here,
//and implementing IShellService getShellService()
//and IFileService getFileService().
public Session getSession() {
return session;
}
public Session getSession() {
return session;
}
public String getControlEncoding() {
public String getControlEncoding() {
//TODO this code should be in IHost
String encoding = getHost().getDefaultEncoding(false);
if (encoding==null) encoding = getHost().getDefaultEncoding(true);
String encoding = getHost().getDefaultEncoding(true);
if (encoding==null) encoding = _defaultEncoding;
//</code to be in IHost>
return encoding;
}
}
/**
* Handle session-lost events.
* This is generic for any sort of connector service.
* Most of this is extracted from dstore's ConnectionStatusListener.
*
* TODO should be refactored to make it generally available, and allow
* dstore to derive from it.
*/
/**
* Handle session-lost events.
* This is generic for any sort of connector service.
* Most of this is extracted from dstore's ConnectionStatusListener.
*
* TODO should be refactored to make it generally available, and allow
* dstore to derive from it.
*/
public static class SessionLostHandler implements Runnable, IRunnableWithProgress
{
private IConnectorService _connection;
@ -334,23 +333,23 @@ public class SshConnectorService extends StandardConnectorService implements ISs
//But what about error messages?
IRunnableContext runnableContext = getRunnableContext(getShell());
// will do this.run(IProgressMonitor mon)
//runnableContext.run(false,true,this); // inthread, cancellable, IRunnableWithProgress
runnableContext.run(true,true,this); // fork, cancellable, IRunnableWithProgress
_connection.reset();
//runnableContext.run(false,true,this); // inthread, cancellable, IRunnableWithProgress
runnableContext.run(true,true,this); // fork, cancellable, IRunnableWithProgress
_connection.reset();
ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry();
sr.connectedStatusChange(_connection.getPrimarySubSystem(), false, true, true);
sr.connectedStatusChange(_connection.getPrimarySubSystem(), false, true, true);
}
catch (InterruptedException exc) // user cancelled
{
if (shell != null)
showDisconnectCancelledMessage(shell, _connection.getHostName(), _connection.getPort());
}
catch (java.lang.reflect.InvocationTargetException invokeExc) // unexpected error
{
Exception exc = (Exception)invokeExc.getTargetException();
if (shell != null)
showDisconnectErrorMessage(shell, _connection.getHostName(), _connection.getPort(), exc);
}
catch (InterruptedException exc) // user cancelled
{
if (shell != null)
showDisconnectCancelledMessage(shell, _connection.getHostName(), _connection.getPort());
}
catch (java.lang.reflect.InvocationTargetException invokeExc) // unexpected error
{
Exception exc = (Exception)invokeExc.getTargetException();
if (shell != null)
showDisconnectErrorMessage(shell, _connection.getHostName(), _connection.getPort(), exc);
}
catch (Exception e)
{
SystemBasePlugin.logError(SshConnectorResources.SshConnectorService_ErrorDisconnecting, e);
@ -358,7 +357,7 @@ public class SshConnectorService extends StandardConnectorService implements ISs
}
public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException
throws InvocationTargetException, InterruptedException
{
String message = null;
message = SubSystemConfiguration.getDisconnectingMessage(
@ -391,7 +390,7 @@ public class SshConnectorService extends StandardConnectorService implements ISs
}
if (window == null) {
IWorkbenchWindow[] windows = PlatformUI.getWorkbench()
.getWorkbenchWindows();
.getWorkbenchWindows();
if (windows != null && windows.length > 0) {
return windows[0].getShell();
}
@ -402,7 +401,7 @@ public class SshConnectorService extends StandardConnectorService implements ISs
return null;
}
/**
/**
* Get the progress monitor dialog for this operation. We try to use one
* for all phases of a single operation, such as connecting and
* resolving.
@ -413,11 +412,11 @@ public class SshConnectorService extends StandardConnectorService implements ISs
IWorkbenchWindow win = SystemBasePlugin.getActiveWorkbenchWindow();
if (win != null) {
Shell winShell = RSEUIPlugin.getDefault().getWorkbench()
.getActiveWorkbenchWindow().getShell();
.getActiveWorkbenchWindow().getShell();
if (winShell != null && !winShell.isDisposed()
&& winShell.isVisible()) {
SystemBasePlugin
.logInfo("Using active workbench window as runnable context"); //$NON-NLS-1$
.logInfo("Using active workbench window as runnable context"); //$NON-NLS-1$
shell = winShell;
return win;
} else {
@ -426,69 +425,69 @@ public class SshConnectorService extends StandardConnectorService implements ISs
}
if (shell == null || shell.isDisposed() || !shell.isVisible()) {
SystemBasePlugin
.logInfo("Using progress monitor dialog with given shell as parent"); //$NON-NLS-1$
.logInfo("Using progress monitor dialog with given shell as parent"); //$NON-NLS-1$
shell = rshell;
}
IRunnableContext dlg = new ProgressMonitorDialog(rshell);
return dlg;
}
/**
/**
* Show an error message when the disconnection fails. Shows a common
* message by default. Overridable.
*/
protected void showDisconnectErrorMessage(Shell shell, String hostName, int port, Exception exc)
{
//SystemMessage.displayMessage(SystemMessage.MSGTYPE_ERROR,shell,RSEUIPlugin.getResourceBundle(),
// ISystemMessages.MSG_DISCONNECT_FAILED,
// hostName, exc.getMessage());
//RSEUIPlugin.logError("Disconnect failed",exc); // temporary
SystemMessage msg = new SimpleSystemMessage(Activator.PLUGIN_ID, ICommonMessageIds.MSG_DISCONNECT_FAILED, IStatus.ERROR, NLS.bind(CommonMessages.MSG_DISCONNECT_FAILED, hostName), exc);
SystemMessageDialog msgDlg = new SystemMessageDialog(shell, msg);
msgDlg.setException(exc);
msgDlg.open();
}
protected void showDisconnectErrorMessage(Shell shell, String hostName, int port, Exception exc)
{
//SystemMessage.displayMessage(SystemMessage.MSGTYPE_ERROR,shell,RSEUIPlugin.getResourceBundle(),
// ISystemMessages.MSG_DISCONNECT_FAILED,
// hostName, exc.getMessage());
//RSEUIPlugin.logError("Disconnect failed",exc); // temporary
SystemMessage msg = new SimpleSystemMessage(Activator.PLUGIN_ID, ICommonMessageIds.MSG_DISCONNECT_FAILED, IStatus.ERROR, NLS.bind(CommonMessages.MSG_DISCONNECT_FAILED, hostName), exc);
SystemMessageDialog msgDlg = new SystemMessageDialog(shell, msg);
msgDlg.setException(exc);
msgDlg.open();
}
/**
* Show an error message when the user cancels the disconnection.
* Shows a common message by default.
* Overridable.
*/
protected void showDisconnectCancelledMessage(Shell shell, String hostName, int port)
{
//SystemMessage.displayMessage(SystemMessage.MSGTYPE_ERROR, shell, RSEUIPlugin.getResourceBundle(),
// ISystemMessages.MSG_DISCONNECT_CANCELED, hostName)
SystemMessage msg = new SimpleSystemMessage(Activator.PLUGIN_ID, ICommonMessageIds.MSG_DISCONNECT_CANCELED, IStatus.CANCEL, NLS.bind(CommonMessages.MSG_DISCONNECT_CANCELED, hostName));
SystemMessageDialog msgDlg = new SystemMessageDialog(shell,msg);
msgDlg.open();
}
/**
* Show an error message when the user cancels the disconnection.
* Shows a common message by default.
* Overridable.
*/
protected void showDisconnectCancelledMessage(Shell shell, String hostName, int port)
{
//SystemMessage.displayMessage(SystemMessage.MSGTYPE_ERROR, shell, RSEUIPlugin.getResourceBundle(),
// ISystemMessages.MSG_DISCONNECT_CANCELED, hostName)
SystemMessage msg = new SimpleSystemMessage(Activator.PLUGIN_ID, ICommonMessageIds.MSG_DISCONNECT_CANCELED, IStatus.CANCEL, NLS.bind(CommonMessages.MSG_DISCONNECT_CANCELED, hostName));
SystemMessageDialog msgDlg = new SystemMessageDialog(shell,msg);
msgDlg.open();
}
}
/**
* Notification from sub-services that our session was lost.
* Notify all subsystems properly.
* TODO allow user to try and reconnect?
*/
public void handleSessionLost() {
Activator.trace("SshConnectorService: handleSessionLost"); //$NON-NLS-1$
if (fSessionLostHandler!=null) {
fSessionLostHandler.sessionLost();
}
/**
* Notification from sub-services that our session was lost.
* Notify all subsystems properly.
* TODO allow user to try and reconnect?
*/
public void handleSessionLost() {
Activator.trace("SshConnectorService: handleSessionLost"); //$NON-NLS-1$
if (fSessionLostHandler!=null) {
fSessionLostHandler.sessionLost();
}
}
protected static Display getStandardDisplay() {
Display display = Display.getCurrent();
if( display==null ) {
display = Display.getDefault();
}
return display;
}
Display display = Display.getCurrent();
if( display==null ) {
display = Display.getDefault();
}
return display;
}
private static class MyUserInfo implements UserInfo, UIKeyboardInteractive {
private String fPassphrase;
private String fPassword;
private int fAttemptCount;
private final String fUser;
private static class MyUserInfo implements UserInfo, UIKeyboardInteractive {
private String fPassphrase;
private String fPassword;
private int fAttemptCount;
private final String fUser;
public MyUserInfo(String user, String password) {
fUser = user;
@ -550,50 +549,50 @@ public class SshConnectorService extends StandardConnectorService implements ISs
final String name, final String instruction,
final String[] prompt, final boolean[] echo)
{
if (prompt.length == 0) {
// No need to prompt, just return an empty String array
return new String[0];
}
if (prompt.length == 0) {
// No need to prompt, just return an empty String array
return new String[0];
}
try{
if (fAttemptCount == 0 && fPassword != null && prompt.length == 1 && prompt[0].trim().equalsIgnoreCase("password:")) { //$NON-NLS-1$
// Return the provided password the first time but always prompt on subsequent tries
fAttemptCount++;
return new String[] { fPassword };
}
final String[][] finResult = new String[1][];
getStandardDisplay().syncExec(new Runnable() {
public void run() {
KeyboardInteractiveDialog dialog = new KeyboardInteractiveDialog(null,
null, destination, name, instruction, prompt, echo);
dialog.open();
finResult[0]=dialog.getResult();
}
});
String[] result=finResult[0];
if (result == null)
return null; // canceled
if (result.length == 1 && prompt.length == 1 && prompt[0].trim().equalsIgnoreCase("password:")) { //$NON-NLS-1$
fPassword = result[0];
}
fAttemptCount++;
if (fAttemptCount == 0 && fPassword != null && prompt.length == 1 && prompt[0].trim().equalsIgnoreCase("password:")) { //$NON-NLS-1$
// Return the provided password the first time but always prompt on subsequent tries
fAttemptCount++;
return new String[] { fPassword };
}
final String[][] finResult = new String[1][];
getStandardDisplay().syncExec(new Runnable() {
public void run() {
KeyboardInteractiveDialog dialog = new KeyboardInteractiveDialog(null,
null, destination, name, instruction, prompt, echo);
dialog.open();
finResult[0]=dialog.getResult();
}
});
String[] result=finResult[0];
if (result == null)
return null; // canceled
if (result.length == 1 && prompt.length == 1 && prompt[0].trim().equalsIgnoreCase("password:")) { //$NON-NLS-1$
fPassword = result[0];
}
fAttemptCount++;
return result;
}
catch(OperationCanceledException e){
return null;
}
}
/**
* Callback to indicate that a connection is about to be attempted
*/
public void aboutToConnect() {
fAttemptCount = 0;
}
/**
* Callback to indicate that a connection was made
*/
public void connectionMade() {
fAttemptCount = 0;
}
/**
* Callback to indicate that a connection is about to be attempted
*/
public void aboutToConnect() {
fAttemptCount = 0;
}
/**
* Callback to indicate that a connection was made
*/
public void connectionMade() {
fAttemptCount = 0;
}
}

View file

@ -23,6 +23,7 @@
* David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files
* Martin Oberhuber (Wind River) - [216343] immediate link targets and canonical paths for Sftp
* David McKnight (IBM) - [216252] [api][nls] Resource Strings specific to subsystems should be moved from rse.ui into files.ui / shells.ui / processes.ui where possible
* Martin Oberhuber (Wind River) - [224799] Fix JSch encoding problems with Arabic filenames
*******************************************************************************/
package org.eclipse.rse.internal.services.ssh.files;
@ -161,16 +162,34 @@ public class SftpFileService extends AbstractFileService implements IFileService
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();
/** Indicates the encoding that our JSch channel uses */
private String fJSchChannelEncoding = defaultEncoding;
// public SftpFileService(SshConnectorService conn) {
// fConnector = conn;
// }
// public SftpFileService(SshConnectorService conn) {
// fConnector = conn;
// }
public SftpFileService(ISshSessionProvider sessionProvider) {
fSessionProvider = sessionProvider;
}
public void setControlEncoding(String encoding) {
public void setControlEncoding(String encoding) throws SystemMessageException {
try {
fChannelSftp.setFilenameEncoding(encoding);
fJSchChannelEncoding = encoding;
} catch (NoSuchMethodError e) {
// Fallback for JSch < 0.1.34: use recode() for encoding conversion
fControlEncoding = encoding;
fJSchChannelEncoding = defaultEncoding;
} catch (SftpException e) {
try {
fChannelSftp.setFilenameEncoding("UTF-8"); //$NON-NLS-1$
fJSchChannelEncoding = "UTF-8"; //$NON-NLS-1$
} catch (SftpException enest) {
// should not happen, are we not connected?
throw makeSystemMessageException(enest);
}
}
fControlEncoding = encoding;
}
@ -183,12 +202,14 @@ public class SftpFileService extends AbstractFileService implements IFileService
protected String recode(String s) throws SystemMessageException {
if (fControlEncoding==null) {
return s;
} else if (fControlEncoding.equals(defaultEncoding)) {
} else if (fControlEncoding.equals(fJSchChannelEncoding)) {
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
return new String(bytes, fJSchChannelEncoding); // what we need to
// tell Jsch to get
// this on the wire
} catch(UnsupportedEncodingException e) {
throw makeSystemMessageException(e);
}
@ -206,8 +227,8 @@ public class SftpFileService extends AbstractFileService implements IFileService
protected String recodeSafe(String s) throws SystemMessageException {
try {
String recoded = recode(s);
byte[] bytes = recoded.getBytes(defaultEncoding);
String decoded = decode(new String(bytes));
byte[] bytes = recoded.getBytes(fJSchChannelEncoding);
String decoded = decode(new String(bytes, fJSchChannelEncoding));
if (!s.equals(decoded)) {
int i=0;
int lmax = Math.min(s.length(), decoded.length());
@ -217,10 +238,10 @@ public class SftpFileService extends AbstractFileService implements IFileService
//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$
if (fControlEncoding == null || fControlEncoding.equals(fJSchChannelEncoding)) {
msg += "default encoding \"" + fJSchChannelEncoding + "\". "; //$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 += "encoding \"" + fControlEncoding + "\" over local default encoding \"" + fJSchChannelEncoding + "\". "; //$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);
@ -230,10 +251,10 @@ public class SftpFileService extends AbstractFileService implements IFileService
return quoteForJsch(recoded);
} catch(UnsupportedEncodingException e) {
//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);
//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);
}
}
@ -247,11 +268,13 @@ public class SftpFileService extends AbstractFileService implements IFileService
protected String decode(String s) throws SystemMessageException {
if (fControlEncoding==null) {
return s;
} else if (fControlEncoding.equals(defaultEncoding)) {
} else if (fControlEncoding.equals(fJSchChannelEncoding)) {
return s;
}
try {
byte[] bytes = s.getBytes(); //original bytes sent by SSH
byte[] bytes = s.getBytes(fJSchChannelEncoding); // original
// bytes sent by
// SSH
return new String(bytes, fControlEncoding);
} catch(UnsupportedEncodingException e) {
throw makeSystemMessageException(e);
@ -272,7 +295,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
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=='*' || c=='\\') {
if(c=='?' || c=='*') {
buf.append('\\');
}
@ -295,10 +318,10 @@ public class SftpFileService extends AbstractFileService implements IFileService
Activator.trace("SftpFileService.connecting..."); //$NON-NLS-1$
try {
Session session = fSessionProvider.getSession();
Channel channel=session.openChannel("sftp"); //$NON-NLS-1$
channel.connect();
fChannelSftp=(ChannelSftp)channel;
setControlEncoding(fSessionProvider.getControlEncoding());
Channel channel=session.openChannel("sftp"); //$NON-NLS-1$
channel.connect();
fChannelSftp=(ChannelSftp)channel;
setControlEncoding(fSessionProvider.getControlEncoding());
fUserHome = decode(fChannelSftp.pwd());
Activator.trace("SftpFileService.connected"); //$NON-NLS-1$
} catch(Exception e) {
@ -466,33 +489,33 @@ public class SftpFileService extends AbstractFileService implements IFileService
}
List results = new ArrayList();
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
boolean haveSubMonitor = false;
boolean haveSubMonitor = false;
try {
Vector vv=getChannel("SftpFileService.internalFetch: "+parentPath).ls(recodeSafe(parentPath)); //$NON-NLS-1$
progressTick(monitor, 40);
if (vv.size()>1 && monitor!=null) {
monitor = new SubProgressMonitor(monitor, 40);
monitor.beginTask(null, vv.size());
}
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 = decode(lsEntry.getFilename());
if (".".equals(fileName) || "..".equals(fileName)) { //$NON-NLS-1$ //$NON-NLS-2$
//don't show the trivial names
continue;
}
if (filematcher.matches(fileName) || (lsEntry.getAttrs().isDir() && fileType!=IFileService.FILE_TYPE_FOLDERS)) {
Vector vv=getChannel("SftpFileService.internalFetch: "+parentPath).ls(recodeSafe(parentPath)); //$NON-NLS-1$
progressTick(monitor, 40);
if (vv.size()>1 && monitor!=null) {
monitor = new SubProgressMonitor(monitor, 40);
monitor.beginTask(null, vv.size());
}
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 = decode(lsEntry.getFilename());
if (".".equals(fileName) || "..".equals(fileName)) { //$NON-NLS-1$ //$NON-NLS-2$
//don't show the trivial names
continue;
}
if (filematcher.matches(fileName) || (lsEntry.getAttrs().isDir() && fileType!=IFileService.FILE_TYPE_FOLDERS)) {
//get ALL directory names (unless looking for folders only)
SftpHostFile node = makeHostFile(parentPath, fileName, lsEntry.getAttrs());
progressTick(monitor, 1);
if (isRightType(fileType, node)) {
results.add(node);
}
}
}
}
SftpHostFile node = makeHostFile(parentPath, fileName, lsEntry.getAttrs());
progressTick(monitor, 1);
if (isRightType(fileType, node)) {
results.add(node);
}
}
}
}
Activator.trace("SftpFileService.internalFetch <--"); //$NON-NLS-1$
} catch(Exception e) {
//TODO throw new SystemMessageException.
@ -541,7 +564,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
}
if (linkTarget!=null && !linkTarget.equals(concat(parentPath, fileName))) {
if (readlinkDone) {
//linkTarget may be a relative path name that needs to be resolved for stat() to work properly
//linkTarget may be a relative path name that needs to be resolved for stat() to work properly
String curdir=decode(getChannel("makeHostFile.pwd").pwd()); //$NON-NLS-1$
if (!parentPath.equals(curdir)) {
getChannel("makeHostFile.chdir").cd(recode(parentPath)); //$NON-NLS-1$
@ -627,7 +650,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
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();
channel.connect();
channel.put(localFile.getAbsolutePath(), dst, sftpMonitor, mode);
Activator.trace("SftpFileService.upload "+remoteFile+ " ok"); //$NON-NLS-1$ //$NON-NLS-2$
if (monitor.isCanceled()) {
@ -659,56 +682,56 @@ public class SftpFileService extends AbstractFileService implements IFileService
return true;
}
public static class MyProgressMonitor implements SftpProgressMonitor
{
private IProgressMonitor fMonitor;
private double fWorkPercentFactor;
private Long fMaxWorkKB;
private long fWorkToDate;
public static class MyProgressMonitor implements SftpProgressMonitor
{
private IProgressMonitor fMonitor;
private double fWorkPercentFactor;
private Long fMaxWorkKB;
private long fWorkToDate;
public MyProgressMonitor(IProgressMonitor monitor) {
fMonitor = monitor;
}
public void init(int op, String src, String dest, long max){
fWorkPercentFactor = 1.0 / max;
fMaxWorkKB = new Long(max / 1024L);
fWorkToDate = 0;
String srcFile = new Path(src).lastSegment();
//String desc = ((op==SftpProgressMonitor.PUT)?
// "Uploading " : "Downloading ")+srcFile;
String desc = srcFile;
if (Activator.isTracingOn()) {
Activator.trace("Sftp-monitor: "+max+", "+desc); //$NON-NLS-1$ //$NON-NLS-2$
}
//TODO avoid cast from long to int
fMonitor.beginTask(desc, (int)max);
public MyProgressMonitor(IProgressMonitor monitor) {
fMonitor = monitor;
}
public void init(int op, String src, String dest, long max){
fWorkPercentFactor = 1.0 / max;
fMaxWorkKB = new Long(max / 1024L);
fWorkToDate = 0;
String srcFile = new Path(src).lastSegment();
//String desc = ((op==SftpProgressMonitor.PUT)?
// "Uploading " : "Downloading ")+srcFile;
String desc = srcFile;
if (Activator.isTracingOn()) {
Activator.trace("Sftp-monitor: "+max+", "+desc); //$NON-NLS-1$ //$NON-NLS-2$
}
//TODO avoid cast from long to int
fMonitor.beginTask(desc, (int)max);
}
public boolean count(long count){
fWorkToDate += count;
Long workToDateKB = new Long(fWorkToDate / 1024L);
Double workPercent = new Double(fWorkPercentFactor * fWorkToDate);
String subDesc = MessageFormat.format(
SshServiceResources.SftpFileService_Msg_Progress,
new Object[] {
workToDateKB, fMaxWorkKB, workPercent
});
}
public boolean count(long count){
fWorkToDate += count;
Long workToDateKB = new Long(fWorkToDate / 1024L);
Double workPercent = new Double(fWorkPercentFactor * fWorkToDate);
String subDesc = MessageFormat.format(
SshServiceResources.SftpFileService_Msg_Progress,
new Object[] {
workToDateKB, fMaxWorkKB, workPercent
});
if (Activator.isTracingOn()) {
System.out.print('#');
}
fMonitor.subTask(subDesc);
fMonitor.worked((int)count);
return !(fMonitor.isCanceled());
}
public void end(){
if (Activator.isTracingOn()) {
System.out.println();
System.out.println("Sftp-monitor <--"); //$NON-NLS-1$
System.out.flush();
}
fMonitor.done();
}
if (Activator.isTracingOn()) {
System.out.print('#');
}
fMonitor.subTask(subDesc);
fMonitor.worked((int)count);
return !(fMonitor.isCanceled());
}
public void end(){
if (Activator.isTracingOn()) {
System.out.println();
System.out.println("Sftp-monitor <--"); //$NON-NLS-1$
System.out.flush();
}
fMonitor.done();
}
}
public boolean upload(InputStream stream, String remoteParent, String remoteFile, boolean isBinary, String hostEncoding, IProgressMonitor monitor) throws SystemMessageException
@ -721,14 +744,14 @@ public class SftpFileService extends AbstractFileService implements IFileService
FileOutputStream os = new FileOutputStream(tempFile);
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
int readCount;
while( (readCount = bis.read(buffer)) > 0)
{
bos.write(buffer, 0, readCount);
}
bos.close();
upload(tempFile, remoteParent, remoteFile, isBinary, "", hostEncoding, monitor); //$NON-NLS-1$
byte[] buffer = new byte[1024];
int readCount;
while( (readCount = bis.read(buffer)) > 0)
{
bos.write(buffer, 0, readCount);
}
bos.close();
upload(tempFile, remoteParent, remoteFile, isBinary, "", hostEncoding, monitor); //$NON-NLS-1$
}
catch (Exception e) {
throw makeSystemMessageException(e);
@ -755,7 +778,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
MyProgressMonitor sftpMonitor = new MyProgressMonitor(monitor);
getChannel("SftpFileService.download "+remoteFile); //check the session is healthy //$NON-NLS-1$
channel=(ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$
channel.connect();
channel.connect();
channel.get(remotePathRecoded, localFile.getAbsolutePath(), sftpMonitor, mode);
Activator.trace("SftpFileService.download "+remoteFile+ " ok"); //$NON-NLS-1$ //$NON-NLS-2$
if (monitor.isCanceled()) {
@ -1066,7 +1089,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
public boolean setLastModified(String parent, String name,
long timestamp, IProgressMonitor monitor) throws SystemMessageException
{
{
boolean ok=false;
String path = concat(parent, name);
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
@ -1082,7 +1105,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
}
}
return ok;
}
}
public boolean setReadOnly(String parent, String name,
boolean readOnly, IProgressMonitor monitor) throws SystemMessageException {
@ -1131,7 +1154,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
String remotePathRecoded = recode(remotePath);
getChannel("SftpFileService.getInputStream " + remoteFile); //check the session is healthy //$NON-NLS-1$
ChannelSftp channel = (ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$
channel.connect();
channel.connect();
stream = new SftpBufferedInputStream(channel.get(remotePathRecoded), channel);
Activator.trace("SftpFileService.getInputStream " + remoteFile + " ok"); //$NON-NLS-1$ //$NON-NLS-2$
}
@ -1179,7 +1202,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
}
getChannel("SftpFileService.getOutputStream " + remoteFile); //check the session is healthy //$NON-NLS-1$
ChannelSftp channel = (ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$
channel.connect();
channel.connect();
stream = new SftpBufferedOutputStream(channel.put(recodeSafe(dst), sftpMonitor, mode), channel);
Activator.trace("SftpFileService.getOutputStream " + remoteFile + " ok"); //$NON-NLS-1$ //$NON-NLS-2$
}
@ -1211,7 +1234,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
*/
public void setFilePermissions(IHostFile file,
IHostFilePermissions permissions, IProgressMonitor monitor)
throws SystemMessageException {
throws SystemMessageException {
return;
}