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:
parent
94f38246c5
commit
69c14379e8
2 changed files with 441 additions and 419 deletions
|
@ -1,14 +1,14 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
|
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Martin Oberhuber (Wind River) - initial API and implementation
|
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||||
* David Dykstal (IBM) - 168977: refactoring IConnectorService and ServerLauncher hierarchies
|
* David Dykstal (IBM) - 168977: refactoring IConnectorService and ServerLauncher hierarchies
|
||||||
* Martin Oberhuber (Wind River) - [175686] Adapted to new IJSchService API
|
* Martin Oberhuber (Wind River) - [175686] Adapted to new IJSchService API
|
||||||
* - copied code from org.eclipse.team.cvs.ssh2/JSchSession (Copyright IBM)
|
* - copied code from org.eclipse.team.cvs.ssh2/JSchSession (Copyright IBM)
|
||||||
* Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry
|
* Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry
|
||||||
* Martin Oberhuber (Wind River) - [186761] make the port setting configurable
|
* Martin Oberhuber (Wind River) - [186761] make the port setting configurable
|
||||||
|
@ -65,21 +65,21 @@ import org.eclipse.rse.ui.SystemBasePlugin;
|
||||||
import org.eclipse.rse.ui.messages.SystemMessageDialog;
|
import org.eclipse.rse.ui.messages.SystemMessageDialog;
|
||||||
import org.eclipse.rse.ui.subsystems.StandardConnectorService;
|
import org.eclipse.rse.ui.subsystems.StandardConnectorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create SSH connections.
|
* Create SSH connections.
|
||||||
*/
|
*/
|
||||||
public class SshConnectorService extends StandardConnectorService implements ISshSessionProvider
|
public class SshConnectorService extends StandardConnectorService implements ISshSessionProvider
|
||||||
{
|
{
|
||||||
private static final int SSH_DEFAULT_PORT = 22;
|
private static final int SSH_DEFAULT_PORT = 22;
|
||||||
private static final int CONNECT_DEFAULT_TIMEOUT = 60; //seconds
|
private static final int CONNECT_DEFAULT_TIMEOUT = 60; //seconds
|
||||||
|
|
||||||
/** Property Keys. These are API because they are stored persistently. */
|
/** Property Keys. These are API because they are stored persistently. */
|
||||||
private static final String PROPERTY_SET_SSH_SETTINGS = "SSH Settings"; //$NON-NLS-1$
|
private static final String PROPERTY_SET_SSH_SETTINGS = "SSH Settings"; //$NON-NLS-1$
|
||||||
private static final String PROPERTY_KEY_TIMEOUT = "timeout(sec)"; //$NON-NLS-1$
|
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 static final String PROPERTY_KEY_KEEPALIVE = "keepalive(sec)"; //$NON-NLS-1$
|
||||||
|
|
||||||
private Session session;
|
private Session session;
|
||||||
private SessionLostHandler fSessionLostHandler;
|
private SessionLostHandler fSessionLostHandler;
|
||||||
/** Indicates the default string encoding on this platform */
|
/** Indicates the default string encoding on this platform */
|
||||||
private static String _defaultEncoding = new java.io.InputStreamReader(new java.io.ByteArrayInputStream(new byte[0])).getEncoding();
|
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
|
* the Jsch config (for instance, in order to switch off strict
|
||||||
* host key checking or in order to add specific ciphers).
|
* 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 {
|
protected Session createSession(String username, String password, String hostname, int port, UserInfo wrapperUI, IProgressMonitor monitor) throws JSchException {
|
||||||
IJSchService service = Activator.getDefault().getJSchService();
|
IJSchService service = Activator.getDefault().getJSchService();
|
||||||
if (service == null)
|
if (service == null)
|
||||||
return null;
|
return null;
|
||||||
Session session = service.createSession(hostname, port, username);
|
Session session = service.createSession(hostname, port, username);
|
||||||
|
|
||||||
IPropertySet propertySet = getPropertySet();
|
IPropertySet propertySet = getPropertySet();
|
||||||
String timeoutStr = propertySet.getPropertyValue(PROPERTY_KEY_TIMEOUT);
|
String timeoutStr = propertySet.getPropertyValue(PROPERTY_KEY_TIMEOUT);
|
||||||
int timeout = 0; //default is never timeout
|
int timeout = 0; //default is never timeout
|
||||||
try {
|
try {
|
||||||
int value = Integer.parseInt(timeoutStr);
|
int value = Integer.parseInt(timeoutStr);
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
timeout = value * 1000;
|
timeout = value * 1000;
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
//wrong input - should never happen because property type is Integer
|
//wrong input - should never happen because property type is Integer
|
||||||
}
|
}
|
||||||
session.setTimeout(timeout);
|
session.setTimeout(timeout);
|
||||||
|
|
||||||
int keepalive = 300000; //default is 5 minutes
|
int keepalive = 300000; //default is 5 minutes
|
||||||
String keepaliveStr = propertySet.getPropertyValue(PROPERTY_KEY_KEEPALIVE);
|
String keepaliveStr = propertySet.getPropertyValue(PROPERTY_KEY_KEEPALIVE);
|
||||||
try {
|
try {
|
||||||
int value = Integer.parseInt(keepaliveStr);
|
int value = Integer.parseInt(keepaliveStr);
|
||||||
if (value >= 0) {
|
if (value >= 0) {
|
||||||
keepalive = value * 1000;
|
keepalive = value * 1000;
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
//wrong input - should never happen because property type is Integer
|
//wrong input - should never happen because property type is Integer
|
||||||
}
|
}
|
||||||
if (keepalive > 0) {
|
if (keepalive > 0) {
|
||||||
session.setServerAliveInterval(keepalive);
|
session.setServerAliveInterval(keepalive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
session.setServerAliveCountMax(6); //give up after 6 tries (remote will be dead after 30 min)
|
session.setServerAliveCountMax(6); //give up after 6 tries (remote will be dead after 30 min)
|
||||||
if (password != null)
|
if (password != null)
|
||||||
session.setPassword(password);
|
session.setPassword(password);
|
||||||
session.setUserInfo(wrapperUI);
|
session.setUserInfo(wrapperUI);
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shutdown() {
|
static void shutdown() {
|
||||||
//TODO: Store all Jsch sessions in a pool and disconnect them on 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
|
protected void internalConnect(IProgressMonitor monitor) throws Exception
|
||||||
{
|
{
|
||||||
// Fire comm event to signal state about to change
|
// Fire comm event to signal state about to change
|
||||||
fireCommunicationsEvent(CommunicationsEvent.BEFORE_CONNECT);
|
fireCommunicationsEvent(CommunicationsEvent.BEFORE_CONNECT);
|
||||||
|
|
||||||
String host = getHostName();
|
String host = getHostName();
|
||||||
String user = getUserId();
|
String user = getUserId();
|
||||||
String password=""; //$NON-NLS-1$
|
String password=""; //$NON-NLS-1$
|
||||||
SystemSignonInformation ssi = getSignonInformation();
|
SystemSignonInformation ssi = getSignonInformation();
|
||||||
if (ssi!=null) {
|
if (ssi!=null) {
|
||||||
password = getSignonInformation().getPassword();
|
password = getSignonInformation().getPassword();
|
||||||
}
|
}
|
||||||
MyUserInfo userInfo = new MyUserInfo(user, password);
|
MyUserInfo userInfo = new MyUserInfo(user, password);
|
||||||
userInfo.aboutToConnect();
|
userInfo.aboutToConnect();
|
||||||
|
|
||||||
try {
|
|
||||||
session = createSession(user, password, host, getSshPort(),
|
|
||||||
userInfo, monitor);
|
|
||||||
|
|
||||||
//java.util.Hashtable config=new java.util.Hashtable();
|
try {
|
||||||
//config.put("StrictHostKeyChecking", "no");
|
session = createSession(user, password, host, getSshPort(),
|
||||||
//session.setConfig(config);
|
userInfo, monitor);
|
||||||
userInfo.aboutToConnect();
|
|
||||||
|
|
||||||
Activator.trace("SshConnectorService.connecting..."); //$NON-NLS-1$
|
//java.util.Hashtable config=new java.util.Hashtable();
|
||||||
//wait for 60 sec maximum during connect
|
//config.put("StrictHostKeyChecking", "no");
|
||||||
session.connect(CONNECT_DEFAULT_TIMEOUT * 1000);
|
//session.setConfig(config);
|
||||||
Activator.trace("SshConnectorService.connected"); //$NON-NLS-1$
|
userInfo.aboutToConnect();
|
||||||
} catch (JSchException e) {
|
|
||||||
Activator.trace("SshConnectorService.connect failed: "+e.toString()); //$NON-NLS-1$
|
Activator.trace("SshConnectorService.connecting..."); //$NON-NLS-1$
|
||||||
sessionDisconnect();
|
//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$
|
if(e.toString().indexOf("Auth cancel")>=0) { //$NON-NLS-1$
|
||||||
throw new OperationCanceledException();
|
throw new OperationCanceledException();
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
userInfo.connectionMade();
|
userInfo.connectionMade();
|
||||||
fSessionLostHandler = new SessionLostHandler(this);
|
fSessionLostHandler = new SessionLostHandler(this);
|
||||||
notifyConnection();
|
notifyConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnect the ssh session.
|
* Disconnect the ssh session.
|
||||||
|
@ -205,21 +205,21 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
* quickly in succession.
|
* quickly in succession.
|
||||||
*/
|
*/
|
||||||
private synchronized void sessionDisconnect() {
|
private synchronized void sessionDisconnect() {
|
||||||
Activator.trace("SshConnectorService.sessionDisconnect"); //$NON-NLS-1$
|
Activator.trace("SshConnectorService.sessionDisconnect"); //$NON-NLS-1$
|
||||||
try {
|
try {
|
||||||
if (session.isConnected())
|
if (session.isConnected())
|
||||||
session.disconnect();
|
session.disconnect();
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
//Bug 175328: NPE on disconnect shown in UI
|
//Bug 175328: NPE on disconnect shown in UI
|
||||||
//This is a non-critical exception so print only in debug mode
|
//This is a non-critical exception so print only in debug mode
|
||||||
if (Activator.isTracingOn()) e.printStackTrace();
|
if (Activator.isTracingOn()) e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void internalDisconnect(IProgressMonitor monitor) throws Exception
|
protected void internalDisconnect(IProgressMonitor monitor) throws Exception
|
||||||
{
|
{
|
||||||
//TODO Will services like the sftp service be disconnected too? Or notified?
|
//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
|
try
|
||||||
{
|
{
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
|
@ -230,13 +230,13 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
// handle events
|
// handle events
|
||||||
if (sessionLost) {
|
if (sessionLost) {
|
||||||
notifyError();
|
notifyError();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Fire comm event to signal state about to change
|
// Fire comm event to signal state about to change
|
||||||
fireCommunicationsEvent(CommunicationsEvent.BEFORE_DISCONNECT);
|
fireCommunicationsEvent(CommunicationsEvent.BEFORE_DISCONNECT);
|
||||||
}
|
}
|
||||||
sessionDisconnect();
|
sessionDisconnect();
|
||||||
|
|
||||||
// Fire comm event to signal state changed
|
// Fire comm event to signal state changed
|
||||||
notifyDisconnection();
|
notifyDisconnection();
|
||||||
//TODO MOB - keep the session to avoid NPEs in services (disables gc for the session!)
|
//TODO MOB - keep the session to avoid NPEs in services (disables gc for the session!)
|
||||||
|
@ -253,43 +253,42 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO avoid having jsch type "Session" in the API.
|
//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 implementing IShellService getShellService()
|
||||||
//and IFileService getFileService().
|
//and IFileService getFileService().
|
||||||
public Session getSession() {
|
public Session getSession() {
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getControlEncoding() {
|
public String getControlEncoding() {
|
||||||
//TODO this code should be in IHost
|
//TODO this code should be in IHost
|
||||||
String encoding = getHost().getDefaultEncoding(false);
|
String encoding = getHost().getDefaultEncoding(true);
|
||||||
if (encoding==null) encoding = getHost().getDefaultEncoding(true);
|
|
||||||
if (encoding==null) encoding = _defaultEncoding;
|
if (encoding==null) encoding = _defaultEncoding;
|
||||||
//</code to be in IHost>
|
//</code to be in IHost>
|
||||||
return encoding;
|
return encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle session-lost events.
|
* Handle session-lost events.
|
||||||
* This is generic for any sort of connector service.
|
* This is generic for any sort of connector service.
|
||||||
* Most of this is extracted from dstore's ConnectionStatusListener.
|
* Most of this is extracted from dstore's ConnectionStatusListener.
|
||||||
*
|
*
|
||||||
* TODO should be refactored to make it generally available, and allow
|
* TODO should be refactored to make it generally available, and allow
|
||||||
* dstore to derive from it.
|
* dstore to derive from it.
|
||||||
*/
|
*/
|
||||||
public static class SessionLostHandler implements Runnable, IRunnableWithProgress
|
public static class SessionLostHandler implements Runnable, IRunnableWithProgress
|
||||||
{
|
{
|
||||||
private IConnectorService _connection;
|
private IConnectorService _connection;
|
||||||
private boolean fSessionLost;
|
private boolean fSessionLost;
|
||||||
|
|
||||||
public SessionLostHandler(IConnectorService cs)
|
public SessionLostHandler(IConnectorService cs)
|
||||||
{
|
{
|
||||||
_connection = cs;
|
_connection = cs;
|
||||||
fSessionLost = false;
|
fSessionLost = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify that the connection has been lost. This may be called
|
* Notify that the connection has been lost. This may be called
|
||||||
* multiple times from multiple subsystems. The SessionLostHandler
|
* multiple times from multiple subsystems. The SessionLostHandler
|
||||||
* ensures that actual user feedback and disconnect actions are
|
* ensures that actual user feedback and disconnect actions are
|
||||||
* done only once, on the first invocation.
|
* done only once, on the first invocation.
|
||||||
|
@ -309,11 +308,11 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
Display.getDefault().asyncExec(this);
|
Display.getDefault().asyncExec(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean isSessionLost() {
|
public synchronized boolean isSessionLost() {
|
||||||
return fSessionLost;
|
return fSessionLost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
Shell shell = getShell();
|
Shell shell = getShell();
|
||||||
|
@ -321,9 +320,9 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
//TODO allow users to reconnect from this dialog
|
//TODO allow users to reconnect from this dialog
|
||||||
//SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_CONNECT_UNKNOWNHOST);
|
//SystemMessage msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_CONNECT_UNKNOWNHOST);
|
||||||
|
|
||||||
SystemMessage msg = new SimpleSystemMessage(Activator.PLUGIN_ID,
|
SystemMessage msg = new SimpleSystemMessage(Activator.PLUGIN_ID,
|
||||||
ICommonMessageIds.MSG_CONNECT_CANCELED, IStatus.CANCEL,
|
ICommonMessageIds.MSG_CONNECT_CANCELED, IStatus.CANCEL,
|
||||||
NLS.bind(CommonMessages.MSG_CONNECT_CANCELED,
|
NLS.bind(CommonMessages.MSG_CONNECT_CANCELED,
|
||||||
_connection.getHost().getAliasName()));
|
_connection.getHost().getAliasName()));
|
||||||
|
|
||||||
SystemMessageDialog dialog = new SystemMessageDialog(getShell(), msg);
|
SystemMessageDialog dialog = new SystemMessageDialog(getShell(), msg);
|
||||||
|
@ -334,23 +333,23 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
//But what about error messages?
|
//But what about error messages?
|
||||||
IRunnableContext runnableContext = getRunnableContext(getShell());
|
IRunnableContext runnableContext = getRunnableContext(getShell());
|
||||||
// will do this.run(IProgressMonitor mon)
|
// will do this.run(IProgressMonitor mon)
|
||||||
//runnableContext.run(false,true,this); // inthread, cancellable, IRunnableWithProgress
|
//runnableContext.run(false,true,this); // inthread, cancellable, IRunnableWithProgress
|
||||||
runnableContext.run(true,true,this); // fork, cancellable, IRunnableWithProgress
|
runnableContext.run(true,true,this); // fork, cancellable, IRunnableWithProgress
|
||||||
_connection.reset();
|
_connection.reset();
|
||||||
ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry();
|
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)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
SystemBasePlugin.logError(SshConnectorResources.SshConnectorService_ErrorDisconnecting, e);
|
SystemBasePlugin.logError(SshConnectorResources.SshConnectorService_ErrorDisconnecting, e);
|
||||||
|
@ -358,7 +357,7 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run(IProgressMonitor monitor)
|
public void run(IProgressMonitor monitor)
|
||||||
throws InvocationTargetException, InterruptedException
|
throws InvocationTargetException, InterruptedException
|
||||||
{
|
{
|
||||||
String message = null;
|
String message = null;
|
||||||
message = SubSystemConfiguration.getDisconnectingMessage(
|
message = SubSystemConfiguration.getDisconnectingMessage(
|
||||||
|
@ -391,7 +390,7 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
}
|
}
|
||||||
if (window == null) {
|
if (window == null) {
|
||||||
IWorkbenchWindow[] windows = PlatformUI.getWorkbench()
|
IWorkbenchWindow[] windows = PlatformUI.getWorkbench()
|
||||||
.getWorkbenchWindows();
|
.getWorkbenchWindows();
|
||||||
if (windows != null && windows.length > 0) {
|
if (windows != null && windows.length > 0) {
|
||||||
return windows[0].getShell();
|
return windows[0].getShell();
|
||||||
}
|
}
|
||||||
|
@ -402,7 +401,7 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the progress monitor dialog for this operation. We try to use one
|
* Get the progress monitor dialog for this operation. We try to use one
|
||||||
* for all phases of a single operation, such as connecting and
|
* for all phases of a single operation, such as connecting and
|
||||||
* resolving.
|
* resolving.
|
||||||
|
@ -413,11 +412,11 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
IWorkbenchWindow win = SystemBasePlugin.getActiveWorkbenchWindow();
|
IWorkbenchWindow win = SystemBasePlugin.getActiveWorkbenchWindow();
|
||||||
if (win != null) {
|
if (win != null) {
|
||||||
Shell winShell = RSEUIPlugin.getDefault().getWorkbench()
|
Shell winShell = RSEUIPlugin.getDefault().getWorkbench()
|
||||||
.getActiveWorkbenchWindow().getShell();
|
.getActiveWorkbenchWindow().getShell();
|
||||||
if (winShell != null && !winShell.isDisposed()
|
if (winShell != null && !winShell.isDisposed()
|
||||||
&& winShell.isVisible()) {
|
&& winShell.isVisible()) {
|
||||||
SystemBasePlugin
|
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;
|
shell = winShell;
|
||||||
return win;
|
return win;
|
||||||
} else {
|
} else {
|
||||||
|
@ -426,69 +425,69 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
}
|
}
|
||||||
if (shell == null || shell.isDisposed() || !shell.isVisible()) {
|
if (shell == null || shell.isDisposed() || !shell.isVisible()) {
|
||||||
SystemBasePlugin
|
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;
|
shell = rshell;
|
||||||
}
|
}
|
||||||
IRunnableContext dlg = new ProgressMonitorDialog(rshell);
|
IRunnableContext dlg = new ProgressMonitorDialog(rshell);
|
||||||
return dlg;
|
return dlg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show an error message when the disconnection fails. Shows a common
|
* Show an error message when the disconnection fails. Shows a common
|
||||||
* message by default. Overridable.
|
* message by default. Overridable.
|
||||||
*/
|
*/
|
||||||
protected void showDisconnectErrorMessage(Shell shell, String hostName, int port, Exception exc)
|
protected void showDisconnectErrorMessage(Shell shell, String hostName, int port, Exception exc)
|
||||||
{
|
{
|
||||||
//SystemMessage.displayMessage(SystemMessage.MSGTYPE_ERROR,shell,RSEUIPlugin.getResourceBundle(),
|
//SystemMessage.displayMessage(SystemMessage.MSGTYPE_ERROR,shell,RSEUIPlugin.getResourceBundle(),
|
||||||
// ISystemMessages.MSG_DISCONNECT_FAILED,
|
// ISystemMessages.MSG_DISCONNECT_FAILED,
|
||||||
// hostName, exc.getMessage());
|
// hostName, exc.getMessage());
|
||||||
//RSEUIPlugin.logError("Disconnect failed",exc); // temporary
|
//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);
|
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);
|
SystemMessageDialog msgDlg = new SystemMessageDialog(shell, msg);
|
||||||
msgDlg.setException(exc);
|
msgDlg.setException(exc);
|
||||||
msgDlg.open();
|
msgDlg.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show an error message when the user cancels the disconnection.
|
* Show an error message when the user cancels the disconnection.
|
||||||
* Shows a common message by default.
|
* Shows a common message by default.
|
||||||
* Overridable.
|
* Overridable.
|
||||||
*/
|
*/
|
||||||
protected void showDisconnectCancelledMessage(Shell shell, String hostName, int port)
|
protected void showDisconnectCancelledMessage(Shell shell, String hostName, int port)
|
||||||
{
|
{
|
||||||
//SystemMessage.displayMessage(SystemMessage.MSGTYPE_ERROR, shell, RSEUIPlugin.getResourceBundle(),
|
//SystemMessage.displayMessage(SystemMessage.MSGTYPE_ERROR, shell, RSEUIPlugin.getResourceBundle(),
|
||||||
// ISystemMessages.MSG_DISCONNECT_CANCELED, hostName)
|
// 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));
|
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);
|
SystemMessageDialog msgDlg = new SystemMessageDialog(shell,msg);
|
||||||
msgDlg.open();
|
msgDlg.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification from sub-services that our session was lost.
|
* Notification from sub-services that our session was lost.
|
||||||
* Notify all subsystems properly.
|
* Notify all subsystems properly.
|
||||||
* TODO allow user to try and reconnect?
|
* TODO allow user to try and reconnect?
|
||||||
*/
|
*/
|
||||||
public void handleSessionLost() {
|
public void handleSessionLost() {
|
||||||
Activator.trace("SshConnectorService: handleSessionLost"); //$NON-NLS-1$
|
Activator.trace("SshConnectorService: handleSessionLost"); //$NON-NLS-1$
|
||||||
if (fSessionLostHandler!=null) {
|
if (fSessionLostHandler!=null) {
|
||||||
fSessionLostHandler.sessionLost();
|
fSessionLostHandler.sessionLost();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Display getStandardDisplay() {
|
protected static Display getStandardDisplay() {
|
||||||
Display display = Display.getCurrent();
|
Display display = Display.getCurrent();
|
||||||
if( display==null ) {
|
if( display==null ) {
|
||||||
display = Display.getDefault();
|
display = Display.getDefault();
|
||||||
}
|
}
|
||||||
return display;
|
return display;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MyUserInfo implements UserInfo, UIKeyboardInteractive {
|
private static class MyUserInfo implements UserInfo, UIKeyboardInteractive {
|
||||||
private String fPassphrase;
|
private String fPassphrase;
|
||||||
private String fPassword;
|
private String fPassword;
|
||||||
private int fAttemptCount;
|
private int fAttemptCount;
|
||||||
private final String fUser;
|
private final String fUser;
|
||||||
|
|
||||||
public MyUserInfo(String user, String password) {
|
public MyUserInfo(String user, String password) {
|
||||||
fUser = user;
|
fUser = user;
|
||||||
|
@ -502,10 +501,10 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
final boolean[] retval = new boolean[1];
|
final boolean[] retval = new boolean[1];
|
||||||
getStandardDisplay().syncExec(new Runnable() {
|
getStandardDisplay().syncExec(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
retval[0] = MessageDialog.openQuestion(null, SshConnectorResources.SshConnectorService_Warning, str);
|
retval[0] = MessageDialog.openQuestion(null, SshConnectorResources.SshConnectorService_Warning, str);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return retval[0];
|
return retval[0];
|
||||||
}
|
}
|
||||||
private String promptSecret(final String message) {
|
private String promptSecret(final String message) {
|
||||||
final String[] retval = new String[1];
|
final String[] retval = new String[1];
|
||||||
|
@ -546,57 +545,57 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public String[] promptKeyboardInteractive(final String destination,
|
public String[] promptKeyboardInteractive(final String destination,
|
||||||
final String name, final String instruction,
|
final String name, final String instruction,
|
||||||
final String[] prompt, final boolean[] echo)
|
final String[] prompt, final boolean[] echo)
|
||||||
{
|
{
|
||||||
if (prompt.length == 0) {
|
if (prompt.length == 0) {
|
||||||
// No need to prompt, just return an empty String array
|
// No need to prompt, just return an empty String array
|
||||||
return new String[0];
|
return new String[0];
|
||||||
}
|
}
|
||||||
try{
|
try{
|
||||||
if (fAttemptCount == 0 && fPassword != null && prompt.length == 1 && prompt[0].trim().equalsIgnoreCase("password:")) { //$NON-NLS-1$
|
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
|
// Return the provided password the first time but always prompt on subsequent tries
|
||||||
fAttemptCount++;
|
fAttemptCount++;
|
||||||
return new String[] { fPassword };
|
return new String[] { fPassword };
|
||||||
}
|
}
|
||||||
final String[][] finResult = new String[1][];
|
final String[][] finResult = new String[1][];
|
||||||
getStandardDisplay().syncExec(new Runnable() {
|
getStandardDisplay().syncExec(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
KeyboardInteractiveDialog dialog = new KeyboardInteractiveDialog(null,
|
KeyboardInteractiveDialog dialog = new KeyboardInteractiveDialog(null,
|
||||||
null, destination, name, instruction, prompt, echo);
|
null, destination, name, instruction, prompt, echo);
|
||||||
dialog.open();
|
dialog.open();
|
||||||
finResult[0]=dialog.getResult();
|
finResult[0]=dialog.getResult();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
String[] result=finResult[0];
|
String[] result=finResult[0];
|
||||||
if (result == null)
|
if (result == null)
|
||||||
return null; // canceled
|
return null; // canceled
|
||||||
if (result.length == 1 && prompt.length == 1 && prompt[0].trim().equalsIgnoreCase("password:")) { //$NON-NLS-1$
|
if (result.length == 1 && prompt.length == 1 && prompt[0].trim().equalsIgnoreCase("password:")) { //$NON-NLS-1$
|
||||||
fPassword = result[0];
|
fPassword = result[0];
|
||||||
}
|
}
|
||||||
fAttemptCount++;
|
fAttemptCount++;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch(OperationCanceledException e){
|
catch(OperationCanceledException e){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Callback to indicate that a connection is about to be attempted
|
* Callback to indicate that a connection is about to be attempted
|
||||||
*/
|
*/
|
||||||
public void aboutToConnect() {
|
public void aboutToConnect() {
|
||||||
fAttemptCount = 0;
|
fAttemptCount = 0;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Callback to indicate that a connection was made
|
* Callback to indicate that a connection was made
|
||||||
*/
|
*/
|
||||||
public void connectionMade() {
|
public void connectionMade() {
|
||||||
fAttemptCount = 0;
|
fAttemptCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isConnected() {
|
public boolean isConnected() {
|
||||||
if (session!=null) {
|
if (session!=null) {
|
||||||
if (session.isConnected()) {
|
if (session.isConnected()) {
|
||||||
|
@ -608,15 +607,15 @@ public class SshConnectorService extends StandardConnectorService implements ISs
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requiresPassword() {
|
public boolean requiresPassword() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requiresUserId() {
|
public boolean requiresUserId() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IPropertySet getPropertySet()
|
private IPropertySet getPropertySet()
|
||||||
{
|
{
|
||||||
IPropertySet propertySet = getPropertySet(PROPERTY_SET_SSH_SETTINGS);
|
IPropertySet propertySet = getPropertySet(PROPERTY_SET_SSH_SETTINGS);
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
|
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Martin Oberhuber (Wind River) - initial API and implementation
|
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||||
* David Dykstal (IBM) - fixing bug 162510: correctly process filter strings
|
* David Dykstal (IBM) - fixing bug 162510: correctly process filter strings
|
||||||
* Kushal Munir (IBM) - for API bug
|
* Kushal Munir (IBM) - for API bug
|
||||||
* Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API
|
* Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API
|
||||||
* Martin Oberhuber (Wind River) - [192724] Fixed logic to filter folders if FILE_TYPE_FOLDERS
|
* Martin Oberhuber (Wind River) - [192724] Fixed logic to filter folders if FILE_TYPE_FOLDERS
|
||||||
* Martin Oberhuber (Wind River) - [199548] Avoid touching files on setReadOnly() if unnecessary
|
* Martin Oberhuber (Wind River) - [199548] Avoid touching files on setReadOnly() if unnecessary
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
* David McKnight (IBM) - [209593] [api] add support for "file permissions" and "owner" properties for unix files
|
* 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
|
* 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
|
* 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;
|
package org.eclipse.rse.internal.services.ssh.files;
|
||||||
|
@ -82,9 +83,9 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
{
|
{
|
||||||
|
|
||||||
private static class SftpBufferedInputStream extends BufferedInputStream {
|
private static class SftpBufferedInputStream extends BufferedInputStream {
|
||||||
|
|
||||||
private ChannelSftp channel;
|
private ChannelSftp channel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a BufferedInputStream and saves its argument, the input stream, for later use. An internal buffer array is created.
|
* Creates a BufferedInputStream and saves its argument, the input stream, for later use. An internal buffer array is created.
|
||||||
* @param in the underlying input stream.
|
* @param in the underlying input stream.
|
||||||
|
@ -115,11 +116,11 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
channel.disconnect();
|
channel.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SftpBufferedOutputStream extends BufferedOutputStream {
|
private static class SftpBufferedOutputStream extends BufferedOutputStream {
|
||||||
|
|
||||||
private ChannelSftp channel;
|
private ChannelSftp channel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new buffered output stream to write data to the specified underlying output stream with a default 512-byte buffer size.
|
* Creates a new buffered output stream to write data to the specified underlying output stream with a default 512-byte buffer size.
|
||||||
* @param out the underlying output stream.
|
* @param out the underlying output stream.
|
||||||
|
@ -150,7 +151,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
channel.disconnect();
|
channel.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//private SshConnectorService fConnector;
|
//private SshConnectorService fConnector;
|
||||||
private ISshSessionProvider fSessionProvider;
|
private ISshSessionProvider fSessionProvider;
|
||||||
private ChannelSftp fChannelSftp;
|
private ChannelSftp fChannelSftp;
|
||||||
|
@ -161,19 +162,37 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
private String fControlEncoding = null;
|
private String fControlEncoding = null;
|
||||||
/** Indicates the default string encoding on this platform */
|
/** Indicates the default string encoding on this platform */
|
||||||
private static String defaultEncoding = new java.io.InputStreamReader(new java.io.ByteArrayInputStream(new byte[0])).getEncoding();
|
private static String defaultEncoding = new java.io.InputStreamReader(new java.io.ByteArrayInputStream(new byte[0])).getEncoding();
|
||||||
|
/** Indicates the encoding that our JSch channel uses */
|
||||||
// public SftpFileService(SshConnectorService conn) {
|
private String fJSchChannelEncoding = defaultEncoding;
|
||||||
// fConnector = conn;
|
|
||||||
// }
|
// public SftpFileService(SshConnectorService conn) {
|
||||||
|
// fConnector = conn;
|
||||||
|
// }
|
||||||
|
|
||||||
public SftpFileService(ISshSessionProvider sessionProvider) {
|
public SftpFileService(ISshSessionProvider sessionProvider) {
|
||||||
fSessionProvider = 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;
|
fControlEncoding = encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode String with requested user encoding, in case it differs from Platform default encoding.
|
* Encode String with requested user encoding, in case it differs from Platform default encoding.
|
||||||
* @param s String to encode
|
* @param s String to encode
|
||||||
|
@ -183,22 +202,24 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
protected String recode(String s) throws SystemMessageException {
|
protected String recode(String s) throws SystemMessageException {
|
||||||
if (fControlEncoding==null) {
|
if (fControlEncoding==null) {
|
||||||
return s;
|
return s;
|
||||||
} else if (fControlEncoding.equals(defaultEncoding)) {
|
} else if (fControlEncoding.equals(fJSchChannelEncoding)) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
byte[] bytes = s.getBytes(fControlEncoding); //what we want on the wire
|
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) {
|
} catch(UnsupportedEncodingException e) {
|
||||||
throw makeSystemMessageException(e);
|
throw makeSystemMessageException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recode String, and check that no information is lost.
|
* Recode String, and check that no information is lost.
|
||||||
* Throw an exception in case the desired Unicode String can not be expressed
|
* Throw an exception in case the desired Unicode String can not be expressed
|
||||||
* by the current encodings. Also enquotes result characters '?' and '*' for
|
* by the current encodings. Also enquotes result characters '?' and '*' for
|
||||||
* Jsch if necessary.
|
* Jsch if necessary.
|
||||||
* @param s String to recode
|
* @param s String to recode
|
||||||
* @return recoded String
|
* @return recoded String
|
||||||
* @throws SystemMessageException if information is lost
|
* @throws SystemMessageException if information is lost
|
||||||
|
@ -206,38 +227,38 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
protected String recodeSafe(String s) throws SystemMessageException {
|
protected String recodeSafe(String s) throws SystemMessageException {
|
||||||
try {
|
try {
|
||||||
String recoded = recode(s);
|
String recoded = recode(s);
|
||||||
byte[] bytes = recoded.getBytes(defaultEncoding);
|
byte[] bytes = recoded.getBytes(fJSchChannelEncoding);
|
||||||
String decoded = decode(new String(bytes));
|
String decoded = decode(new String(bytes, fJSchChannelEncoding));
|
||||||
if (!s.equals(decoded)) {
|
if (!s.equals(decoded)) {
|
||||||
int i=0;
|
int i=0;
|
||||||
int lmax = Math.min(s.length(), decoded.length());
|
int lmax = Math.min(s.length(), decoded.length());
|
||||||
while( (i<lmax) && (s.charAt(i)==decoded.charAt(i))) {
|
while( (i<lmax) && (s.charAt(i)==decoded.charAt(i))) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
//String sbad=s.substring(Math.max(i-2,0), Math.min(i+2,lmax));
|
//String sbad=s.substring(Math.max(i-2,0), Math.min(i+2,lmax));
|
||||||
char sbad = s.charAt(i);
|
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$
|
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)) {
|
if (fControlEncoding == null || fControlEncoding.equals(fJSchChannelEncoding)) {
|
||||||
msg += "default encoding \""+defaultEncoding+"\". "; //$NON-NLS-1$ //$NON-NLS-2$
|
msg += "default encoding \"" + fJSchChannelEncoding + "\". "; //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
} else {
|
} 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$
|
msg += "Please specify a different encoding in host properties."; //$NON-NLS-1$
|
||||||
throw new UnsupportedEncodingException(msg);
|
throw new UnsupportedEncodingException(msg);
|
||||||
}
|
}
|
||||||
//Quote ? and * characters for Jsch
|
//Quote ? and * characters for Jsch
|
||||||
//FIXME bug 204705: this does not work properly for commands like ls(), due to a Jsch bug
|
//FIXME bug 204705: this does not work properly for commands like ls(), due to a Jsch bug
|
||||||
return quoteForJsch(recoded);
|
return quoteForJsch(recoded);
|
||||||
} catch(UnsupportedEncodingException e) {
|
} 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(),"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$
|
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 RemoteFileIOException(new SystemMessageException(msg));
|
||||||
throw new SystemMessageException(msg);
|
throw new SystemMessageException(msg);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode String (sftp result) with requested user encoding, in case it differs from Platform default encoding.
|
* Decode String (sftp result) with requested user encoding, in case it differs from Platform default encoding.
|
||||||
* @param s String to decode
|
* @param s String to decode
|
||||||
|
@ -247,11 +268,13 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
protected String decode(String s) throws SystemMessageException {
|
protected String decode(String s) throws SystemMessageException {
|
||||||
if (fControlEncoding==null) {
|
if (fControlEncoding==null) {
|
||||||
return s;
|
return s;
|
||||||
} else if (fControlEncoding.equals(defaultEncoding)) {
|
} else if (fControlEncoding.equals(fJSchChannelEncoding)) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
try {
|
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);
|
return new String(bytes, fControlEncoding);
|
||||||
} catch(UnsupportedEncodingException e) {
|
} catch(UnsupportedEncodingException e) {
|
||||||
throw makeSystemMessageException(e);
|
throw makeSystemMessageException(e);
|
||||||
|
@ -260,7 +283,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
|
|
||||||
/** Regular expression pattern to know when Jsch needs quoting. */
|
/** Regular expression pattern to know when Jsch needs quoting. */
|
||||||
private static Pattern quoteForJschPattern = Pattern.compile("[*?\\\\]"); //$NON-NLS-1$
|
private static Pattern quoteForJschPattern = Pattern.compile("[*?\\\\]"); //$NON-NLS-1$
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quote characters '?' and '*' for Jsch because it would otherwise
|
* Quote characters '?' and '*' for Jsch because it would otherwise
|
||||||
* use them as patterns for globbing.
|
* use them as patterns for globbing.
|
||||||
|
@ -272,7 +295,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
StringBuffer buf = new StringBuffer(s.length()+8);
|
StringBuffer buf = new StringBuffer(s.length()+8);
|
||||||
for(int i=0; i<s.length(); i++) {
|
for(int i=0; i<s.length(); i++) {
|
||||||
char c = s.charAt(i);
|
char c = s.charAt(i);
|
||||||
// if(c=='?' || c=='*' || c=='\\') {
|
// if(c=='?' || c=='*' || c=='\\') {
|
||||||
if(c=='?' || c=='*') {
|
if(c=='?' || c=='*') {
|
||||||
buf.append('\\');
|
buf.append('\\');
|
||||||
}
|
}
|
||||||
|
@ -282,23 +305,23 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return SshServiceResources.SftpFileService_Name;
|
return SshServiceResources.SftpFileService_Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return SshServiceResources.SftpFileService_Description;
|
return SshServiceResources.SftpFileService_Description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect() throws SystemMessageException {
|
public void connect() throws SystemMessageException {
|
||||||
Activator.trace("SftpFileService.connecting..."); //$NON-NLS-1$
|
Activator.trace("SftpFileService.connecting..."); //$NON-NLS-1$
|
||||||
try {
|
try {
|
||||||
Session session = fSessionProvider.getSession();
|
Session session = fSessionProvider.getSession();
|
||||||
Channel channel=session.openChannel("sftp"); //$NON-NLS-1$
|
Channel channel=session.openChannel("sftp"); //$NON-NLS-1$
|
||||||
channel.connect();
|
channel.connect();
|
||||||
fChannelSftp=(ChannelSftp)channel;
|
fChannelSftp=(ChannelSftp)channel;
|
||||||
setControlEncoding(fSessionProvider.getControlEncoding());
|
setControlEncoding(fSessionProvider.getControlEncoding());
|
||||||
fUserHome = decode(fChannelSftp.pwd());
|
fUserHome = decode(fChannelSftp.pwd());
|
||||||
Activator.trace("SftpFileService.connected"); //$NON-NLS-1$
|
Activator.trace("SftpFileService.connected"); //$NON-NLS-1$
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
|
@ -306,7 +329,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
throw makeSystemMessageException(e);
|
throw makeSystemMessageException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the main ssh session is still connected.
|
* Check if the main ssh session is still connected.
|
||||||
* Notify ConnectorService of lost session if necessary.
|
* Notify ConnectorService of lost session if necessary.
|
||||||
|
@ -327,7 +350,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ChannelSftp getChannel(String task) throws SystemMessageException
|
protected ChannelSftp getChannel(String task) throws SystemMessageException
|
||||||
{
|
{
|
||||||
Activator.trace(task);
|
Activator.trace(task);
|
||||||
|
@ -347,7 +370,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
return fChannelSftp;
|
return fChannelSftp;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void progressTick(IProgressMonitor monitor, int ticks) throws RemoteFileCanceledException {
|
protected void progressTick(IProgressMonitor monitor, int ticks) throws RemoteFileCanceledException {
|
||||||
if (monitor!=null) {
|
if (monitor!=null) {
|
||||||
if (monitor.isCanceled()) {
|
if (monitor.isCanceled()) {
|
||||||
|
@ -356,7 +379,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
monitor.worked(ticks);
|
monitor.worked(ticks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
//disconnect-service may be called after the session is already
|
//disconnect-service may be called after the session is already
|
||||||
//disconnected (due to event handling). Therefore, don't try to
|
//disconnected (due to event handling). Therefore, don't try to
|
||||||
|
@ -368,8 +391,8 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
fDirChannelMutex.interruptAll();
|
fDirChannelMutex.interruptAll();
|
||||||
fChannelSftp = null;
|
fChannelSftp = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private SystemMessageException makeSystemMessageException(Exception e) {
|
private SystemMessageException makeSystemMessageException(Exception e) {
|
||||||
if (e instanceof SystemMessageException) {
|
if (e instanceof SystemMessageException) {
|
||||||
//dont wrap SystemMessageException again
|
//dont wrap SystemMessageException again
|
||||||
|
@ -390,7 +413,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
return new RemoteFileIOException(e);
|
return new RemoteFileIOException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concatenate a parent directory with a file name to form a new proper path name.
|
* Concatenate a parent directory with a file name to form a new proper path name.
|
||||||
* @param parentDir path name of the parent directory.
|
* @param parentDir path name of the parent directory.
|
||||||
|
@ -408,11 +431,11 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
path.append(fileName);
|
path.append(fileName);
|
||||||
return path.toString();
|
return path.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHostFile getFile(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException
|
public IHostFile getFile(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException
|
||||||
{
|
{
|
||||||
//getFile() must return a dummy even for non-existent files,
|
//getFile() must return a dummy even for non-existent files,
|
||||||
//or the move() operation will fail. This is described in
|
//or the move() operation will fail. This is described in
|
||||||
//the API docs.
|
//the API docs.
|
||||||
SftpHostFile node = null;
|
SftpHostFile node = null;
|
||||||
SftpATTRS attrs = null;
|
SftpATTRS attrs = null;
|
||||||
|
@ -442,7 +465,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isConnected() {
|
public boolean isConnected() {
|
||||||
try {
|
try {
|
||||||
return getChannel("SftpFileService.isConnected()").isConnected(); //$NON-NLS-1$
|
return getChannel("SftpFileService.isConnected()").isConnected(); //$NON-NLS-1$
|
||||||
|
@ -451,7 +474,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IHostFile[] internalFetch(String parentPath, String fileFilter, int fileType, IProgressMonitor monitor) throws SystemMessageException
|
protected IHostFile[] internalFetch(String parentPath, String fileFilter, int fileType, IProgressMonitor monitor) throws SystemMessageException
|
||||||
{
|
{
|
||||||
if (fileFilter == null) {
|
if (fileFilter == null) {
|
||||||
|
@ -466,33 +489,33 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
List results = new ArrayList();
|
List results = new ArrayList();
|
||||||
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
|
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
|
||||||
boolean haveSubMonitor = false;
|
boolean haveSubMonitor = false;
|
||||||
try {
|
try {
|
||||||
Vector vv=getChannel("SftpFileService.internalFetch: "+parentPath).ls(recodeSafe(parentPath)); //$NON-NLS-1$
|
Vector vv=getChannel("SftpFileService.internalFetch: "+parentPath).ls(recodeSafe(parentPath)); //$NON-NLS-1$
|
||||||
progressTick(monitor, 40);
|
progressTick(monitor, 40);
|
||||||
if (vv.size()>1 && monitor!=null) {
|
if (vv.size()>1 && monitor!=null) {
|
||||||
monitor = new SubProgressMonitor(monitor, 40);
|
monitor = new SubProgressMonitor(monitor, 40);
|
||||||
monitor.beginTask(null, vv.size());
|
monitor.beginTask(null, vv.size());
|
||||||
}
|
}
|
||||||
for(int ii=0; ii<vv.size(); ii++) {
|
for(int ii=0; ii<vv.size(); ii++) {
|
||||||
Object obj=vv.elementAt(ii);
|
Object obj=vv.elementAt(ii);
|
||||||
if(obj instanceof ChannelSftp.LsEntry){
|
if(obj instanceof ChannelSftp.LsEntry){
|
||||||
ChannelSftp.LsEntry lsEntry = (ChannelSftp.LsEntry)obj;
|
ChannelSftp.LsEntry lsEntry = (ChannelSftp.LsEntry)obj;
|
||||||
String fileName = decode(lsEntry.getFilename());
|
String fileName = decode(lsEntry.getFilename());
|
||||||
if (".".equals(fileName) || "..".equals(fileName)) { //$NON-NLS-1$ //$NON-NLS-2$
|
if (".".equals(fileName) || "..".equals(fileName)) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
//don't show the trivial names
|
//don't show the trivial names
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (filematcher.matches(fileName) || (lsEntry.getAttrs().isDir() && fileType!=IFileService.FILE_TYPE_FOLDERS)) {
|
if (filematcher.matches(fileName) || (lsEntry.getAttrs().isDir() && fileType!=IFileService.FILE_TYPE_FOLDERS)) {
|
||||||
//get ALL directory names (unless looking for folders only)
|
//get ALL directory names (unless looking for folders only)
|
||||||
SftpHostFile node = makeHostFile(parentPath, fileName, lsEntry.getAttrs());
|
SftpHostFile node = makeHostFile(parentPath, fileName, lsEntry.getAttrs());
|
||||||
progressTick(monitor, 1);
|
progressTick(monitor, 1);
|
||||||
if (isRightType(fileType, node)) {
|
if (isRightType(fileType, node)) {
|
||||||
results.add(node);
|
results.add(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Activator.trace("SftpFileService.internalFetch <--"); //$NON-NLS-1$
|
Activator.trace("SftpFileService.internalFetch <--"); //$NON-NLS-1$
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
//TODO throw new SystemMessageException.
|
//TODO throw new SystemMessageException.
|
||||||
|
@ -505,7 +528,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
throw makeSystemMessageException(e);
|
throw makeSystemMessageException(e);
|
||||||
}
|
}
|
||||||
//TODO if not session connected, do we need to throw?
|
//TODO if not session connected, do we need to throw?
|
||||||
//Probably not, since the session is going down anyways.
|
//Probably not, since the session is going down anyways.
|
||||||
} finally {
|
} finally {
|
||||||
fDirChannelMutex.release();
|
fDirChannelMutex.release();
|
||||||
if (haveSubMonitor) monitor.done(); else progressTick(monitor, 40);
|
if (haveSubMonitor) monitor.done(); else progressTick(monitor, 40);
|
||||||
|
@ -533,7 +556,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
//Disadvantages of the cd/pwd approach:
|
//Disadvantages of the cd/pwd approach:
|
||||||
// * _realpath() followed by _stat() might be one extra roundtrip compared to the readlink() approach
|
// * _realpath() followed by _stat() might be one extra roundtrip compared to the readlink() approach
|
||||||
// * Immediate link target is not available, only the fully resolved link target (might be an advantage too!)
|
// * Immediate link target is not available, only the fully resolved link target (might be an advantage too!)
|
||||||
// * -- but clients can also resolve the path with the
|
// * -- but clients can also resolve the path with the
|
||||||
// * Immediate link target is not available for broken symbolic links
|
// * Immediate link target is not available for broken symbolic links
|
||||||
getChannel("makeHostFile.chdir").cd(recode(concat(parentPath, fileName))); //$NON-NLS-1$
|
getChannel("makeHostFile.chdir").cd(recode(concat(parentPath, fileName))); //$NON-NLS-1$
|
||||||
linkTarget=decode(getChannel("makeHostFile.pwd").pwd()); //$NON-NLS-1$
|
linkTarget=decode(getChannel("makeHostFile.pwd").pwd()); //$NON-NLS-1$
|
||||||
|
@ -541,7 +564,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
if (linkTarget!=null && !linkTarget.equals(concat(parentPath, fileName))) {
|
if (linkTarget!=null && !linkTarget.equals(concat(parentPath, fileName))) {
|
||||||
if (readlinkDone) {
|
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$
|
String curdir=decode(getChannel("makeHostFile.pwd").pwd()); //$NON-NLS-1$
|
||||||
if (!parentPath.equals(curdir)) {
|
if (!parentPath.equals(curdir)) {
|
||||||
getChannel("makeHostFile.chdir").cd(recode(parentPath)); //$NON-NLS-1$
|
getChannel("makeHostFile.chdir").cd(recode(parentPath)); //$NON-NLS-1$
|
||||||
|
@ -567,7 +590,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SftpHostFile node = new SftpHostFile(parentPath, fileName, attrsTarget.isDir(), false, attrs.isLink(), 1000L * attrs.getMTime(), attrs.getSize());
|
SftpHostFile node = new SftpHostFile(parentPath, fileName, attrsTarget.isDir(), false, attrs.isLink(), 1000L * attrs.getMTime(), attrs.getSize());
|
||||||
if (linkTarget!=null) {
|
if (linkTarget!=null) {
|
||||||
|
@ -596,19 +619,19 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
if (attrs.getExtended()!=null) {
|
if (attrs.getExtended()!=null) {
|
||||||
node.setExtendedData(attrs.getExtended());
|
node.setExtendedData(attrs.getExtended());
|
||||||
}
|
}
|
||||||
|
|
||||||
// permissions
|
// permissions
|
||||||
// TODO get the user and owner from the uid and gid
|
// TODO get the user and owner from the uid and gid
|
||||||
HostFilePermissions permissions = new HostFilePermissions(perms, "" + attrs.getUId(), "" + attrs.getGId()); //$NON-NLS-1$ //$NON-NLS-2$
|
HostFilePermissions permissions = new HostFilePermissions(perms, "" + attrs.getUId(), "" + attrs.getGId()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
node.setPermissions(permissions);
|
node.setPermissions(permissions);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSeparator() {
|
public String getSeparator() {
|
||||||
return "/"; //$NON-NLS-1$
|
return "/"; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean upload(File localFile, String remoteParent, String remoteFile, boolean isBinary, String srcEncoding, String hostEncoding, IProgressMonitor monitor) throws SystemMessageException
|
public boolean upload(File localFile, String remoteParent, String remoteFile, boolean isBinary, String srcEncoding, String hostEncoding, IProgressMonitor monitor) throws SystemMessageException
|
||||||
{
|
{
|
||||||
String dst = remoteParent;
|
String dst = remoteParent;
|
||||||
|
@ -625,10 +648,10 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
SftpProgressMonitor sftpMonitor=new MyProgressMonitor(monitor);
|
SftpProgressMonitor sftpMonitor=new MyProgressMonitor(monitor);
|
||||||
int mode=ChannelSftp.OVERWRITE;
|
int mode=ChannelSftp.OVERWRITE;
|
||||||
dst = recodeSafe(dst);
|
dst = recodeSafe(dst);
|
||||||
getChannel("SftpFileService.upload "+remoteFile); //check the session is healthy //$NON-NLS-1$
|
getChannel("SftpFileService.upload "+remoteFile); //check the session is healthy //$NON-NLS-1$
|
||||||
channel=(ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$
|
channel=(ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$
|
||||||
channel.connect();
|
channel.connect();
|
||||||
channel.put(localFile.getAbsolutePath(), dst, sftpMonitor, mode);
|
channel.put(localFile.getAbsolutePath(), dst, sftpMonitor, mode);
|
||||||
Activator.trace("SftpFileService.upload "+remoteFile+ " ok"); //$NON-NLS-1$ //$NON-NLS-2$
|
Activator.trace("SftpFileService.upload "+remoteFile+ " ok"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
if (monitor.isCanceled()) {
|
if (monitor.isCanceled()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -659,56 +682,56 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MyProgressMonitor implements SftpProgressMonitor
|
public static class MyProgressMonitor implements SftpProgressMonitor
|
||||||
{
|
{
|
||||||
private IProgressMonitor fMonitor;
|
private IProgressMonitor fMonitor;
|
||||||
private double fWorkPercentFactor;
|
private double fWorkPercentFactor;
|
||||||
private Long fMaxWorkKB;
|
private Long fMaxWorkKB;
|
||||||
private long fWorkToDate;
|
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 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()) {
|
public MyProgressMonitor(IProgressMonitor monitor) {
|
||||||
System.out.print('#');
|
fMonitor = monitor;
|
||||||
}
|
}
|
||||||
fMonitor.subTask(subDesc);
|
public void init(int op, String src, String dest, long max){
|
||||||
fMonitor.worked((int)count);
|
fWorkPercentFactor = 1.0 / max;
|
||||||
return !(fMonitor.isCanceled());
|
fMaxWorkKB = new Long(max / 1024L);
|
||||||
}
|
fWorkToDate = 0;
|
||||||
public void end(){
|
String srcFile = new Path(src).lastSegment();
|
||||||
if (Activator.isTracingOn()) {
|
//String desc = ((op==SftpProgressMonitor.PUT)?
|
||||||
System.out.println();
|
// "Uploading " : "Downloading ")+srcFile;
|
||||||
System.out.println("Sftp-monitor <--"); //$NON-NLS-1$
|
String desc = srcFile;
|
||||||
System.out.flush();
|
if (Activator.isTracingOn()) {
|
||||||
}
|
Activator.trace("Sftp-monitor: "+max+", "+desc); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
fMonitor.done();
|
}
|
||||||
}
|
//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
|
||||||
|
});
|
||||||
|
|
||||||
|
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
|
public boolean upload(InputStream stream, String remoteParent, String remoteFile, boolean isBinary, String hostEncoding, IProgressMonitor monitor) throws SystemMessageException
|
||||||
|
@ -720,15 +743,15 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
File tempFile = File.createTempFile("sftp", "temp"); //$NON-NLS-1$ //$NON-NLS-2$
|
File tempFile = File.createTempFile("sftp", "temp"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
FileOutputStream os = new FileOutputStream(tempFile);
|
FileOutputStream os = new FileOutputStream(tempFile);
|
||||||
BufferedOutputStream bos = new BufferedOutputStream(os);
|
BufferedOutputStream bos = new BufferedOutputStream(os);
|
||||||
|
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
int readCount;
|
int readCount;
|
||||||
while( (readCount = bis.read(buffer)) > 0)
|
while( (readCount = bis.read(buffer)) > 0)
|
||||||
{
|
{
|
||||||
bos.write(buffer, 0, readCount);
|
bos.write(buffer, 0, readCount);
|
||||||
}
|
}
|
||||||
bos.close();
|
bos.close();
|
||||||
upload(tempFile, remoteParent, remoteFile, isBinary, "", hostEncoding, monitor); //$NON-NLS-1$
|
upload(tempFile, remoteParent, remoteFile, isBinary, "", hostEncoding, monitor); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw makeSystemMessageException(e);
|
throw makeSystemMessageException(e);
|
||||||
|
@ -736,7 +759,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean download(String remoteParent, String remoteFile, File localFile, boolean isBinary, String hostEncoding, IProgressMonitor monitor) throws SystemMessageException
|
public boolean download(String remoteParent, String remoteFile, File localFile, boolean isBinary, String hostEncoding, IProgressMonitor monitor) throws SystemMessageException
|
||||||
{
|
{
|
||||||
ChannelSftp channel = null;
|
ChannelSftp channel = null;
|
||||||
|
@ -755,7 +778,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
MyProgressMonitor sftpMonitor = new MyProgressMonitor(monitor);
|
MyProgressMonitor sftpMonitor = new MyProgressMonitor(monitor);
|
||||||
getChannel("SftpFileService.download "+remoteFile); //check the session is healthy //$NON-NLS-1$
|
getChannel("SftpFileService.download "+remoteFile); //check the session is healthy //$NON-NLS-1$
|
||||||
channel=(ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$
|
channel=(ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$
|
||||||
channel.connect();
|
channel.connect();
|
||||||
channel.get(remotePathRecoded, localFile.getAbsolutePath(), sftpMonitor, mode);
|
channel.get(remotePathRecoded, localFile.getAbsolutePath(), sftpMonitor, mode);
|
||||||
Activator.trace("SftpFileService.download "+remoteFile+ " ok"); //$NON-NLS-1$ //$NON-NLS-2$
|
Activator.trace("SftpFileService.download "+remoteFile+ " ok"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
if (monitor.isCanceled()) {
|
if (monitor.isCanceled()) {
|
||||||
|
@ -778,7 +801,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
Activator.trace("SftpFileService.download "+remotePath+" failed: "+e.toString()); //$NON-NLS-1$ //$NON-NLS-2$
|
Activator.trace("SftpFileService.download "+remotePath+" failed: "+e.toString()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
throw makeSystemMessageException(e);
|
throw makeSystemMessageException(e);
|
||||||
//Note: In case of an exception, the caller needs to ensure that in case
|
//Note: In case of an exception, the caller needs to ensure that in case
|
||||||
//we downloaded to a temp file, the temp file is deleted again, or a
|
//we downloaded to a temp file, the temp file is deleted again, or a
|
||||||
//broken incorrect file might be synchronized back to the source, thus
|
//broken incorrect file might be synchronized back to the source, thus
|
||||||
//destroying the original file!!
|
//destroying the original file!!
|
||||||
//return false;
|
//return false;
|
||||||
|
@ -790,12 +813,12 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHostFile getUserHome() {
|
public IHostFile getUserHome() {
|
||||||
//As per bug 204710, this may be called before we are connected
|
//As per bug 204710, this may be called before we are connected
|
||||||
if (fUserHome!=null) {
|
if (fUserHome!=null) {
|
||||||
int lastSlash = fUserHome.lastIndexOf('/');
|
int lastSlash = fUserHome.lastIndexOf('/');
|
||||||
String name = fUserHome.substring(lastSlash + 1);
|
String name = fUserHome.substring(lastSlash + 1);
|
||||||
String parent = fUserHome.substring(0, lastSlash);
|
String parent = fUserHome.substring(0, lastSlash);
|
||||||
try {
|
try {
|
||||||
return getFile(parent, name, null);
|
return getFile(parent, name, null);
|
||||||
|
@ -815,8 +838,8 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
IHostFile root = new SftpHostFile("/", "/", true, true, false, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$
|
IHostFile root = new SftpHostFile("/", "/", true, true, false, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
return new IHostFile[] { root };
|
return new IHostFile[] { root };
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHostFile createFile(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException
|
public IHostFile createFile(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException
|
||||||
{
|
{
|
||||||
IHostFile result = null;
|
IHostFile result = null;
|
||||||
String fullPath = concat(remoteParent, fileName);
|
String fullPath = concat(remoteParent, fileName);
|
||||||
|
@ -875,7 +898,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
try {
|
try {
|
||||||
attrs = getChannel("SftpFileService.delete").lstat(fullPathRecoded); //$NON-NLS-1$
|
attrs = getChannel("SftpFileService.delete").lstat(fullPathRecoded); //$NON-NLS-1$
|
||||||
} catch (SftpException e) {
|
} catch (SftpException e) {
|
||||||
//bug 154419: test for dangling symbolic link
|
//bug 154419: test for dangling symbolic link
|
||||||
if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
|
if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
|
||||||
//simply try to delete --> if it really doesnt exist, this will throw an exception
|
//simply try to delete --> if it really doesnt exist, this will throw an exception
|
||||||
getChannel("SftpFileService.delete.rm").rm(fullPathRecoded); //$NON-NLS-1$
|
getChannel("SftpFileService.delete.rm").rm(fullPathRecoded); //$NON-NLS-1$
|
||||||
|
@ -935,7 +958,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean rename(String remoteParent, String oldName, String newName, IHostFile oldFile, IProgressMonitor monitor) throws SystemMessageException {
|
public boolean rename(String remoteParent, String oldName, String newName, IHostFile oldFile, IProgressMonitor monitor) throws SystemMessageException {
|
||||||
// TODO dont know how to update
|
// TODO dont know how to update
|
||||||
return rename(remoteParent, oldName, newName, monitor);
|
return rename(remoteParent, oldName, newName, monitor);
|
||||||
|
@ -949,7 +972,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
return cancelRequested;
|
return cancelRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int runCommand(String command, IProgressMonitor monitor) throws SystemMessageException
|
public int runCommand(String command, IProgressMonitor monitor) throws SystemMessageException
|
||||||
{
|
{
|
||||||
Activator.trace("SftpFileService.runCommand "+command); //$NON-NLS-1$
|
Activator.trace("SftpFileService.runCommand "+command); //$NON-NLS-1$
|
||||||
|
@ -1005,7 +1028,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean move(String srcParent, String srcName, String tgtParent, String tgtName, IProgressMonitor monitor) throws SystemMessageException
|
public boolean move(String srcParent, String srcName, String tgtParent, String tgtName, IProgressMonitor monitor) throws SystemMessageException
|
||||||
{
|
{
|
||||||
// move is not supported by sftp directly. Use the ssh shell instead.
|
// move is not supported by sftp directly. Use the ssh shell instead.
|
||||||
|
@ -1029,15 +1052,15 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
int rv = runCommand("cp -Rp "+fullPathOld+' '+fullPathNew, monitor); //$NON-NLS-1$
|
int rv = runCommand("cp -Rp "+fullPathOld+' '+fullPathNew, monitor); //$NON-NLS-1$
|
||||||
return (rv==0);
|
return (rv==0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean copyBatch(String[] srcParents, String[] srcNames, String tgtParent, IProgressMonitor monitor) throws SystemMessageException
|
public boolean copyBatch(String[] srcParents, String[] srcNames, String tgtParent, IProgressMonitor monitor) throws SystemMessageException
|
||||||
{
|
{
|
||||||
Activator.trace("SftpFileService.copyBatch "+srcNames); //$NON-NLS-1$
|
Activator.trace("SftpFileService.copyBatch "+srcNames); //$NON-NLS-1$
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
for (int i = 0; i < srcParents.length; i++)
|
for (int i = 0; i < srcParents.length; i++)
|
||||||
{
|
{
|
||||||
//TODO check what should happen if one file throws an Exception
|
//TODO check what should happen if one file throws an Exception
|
||||||
//should the batch job continue?
|
//should the batch job continue?
|
||||||
ok = ok && copy(srcParents[i], srcNames[i], tgtParent, srcNames[i], monitor);
|
ok = ok && copy(srcParents[i], srcNames[i], tgtParent, srcNames[i], monitor);
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
|
@ -1050,10 +1073,10 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
connect();
|
connect();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uninitService(IProgressMonitor monitor) {
|
public void uninitService(IProgressMonitor monitor) {
|
||||||
Activator.trace("SftpFileService.uninitService"); //$NON-NLS-1$
|
Activator.trace("SftpFileService.uninitService"); //$NON-NLS-1$
|
||||||
disconnect();
|
disconnect();
|
||||||
|
@ -1065,8 +1088,8 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setLastModified(String parent, String name,
|
public boolean setLastModified(String parent, String name,
|
||||||
long timestamp, IProgressMonitor monitor) throws SystemMessageException
|
long timestamp, IProgressMonitor monitor) throws SystemMessageException
|
||||||
{
|
{
|
||||||
boolean ok=false;
|
boolean ok=false;
|
||||||
String path = concat(parent, name);
|
String path = concat(parent, name);
|
||||||
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
|
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
|
||||||
|
@ -1082,7 +1105,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setReadOnly(String parent, String name,
|
public boolean setReadOnly(String parent, String name,
|
||||||
boolean readOnly, IProgressMonitor monitor) throws SystemMessageException {
|
boolean readOnly, IProgressMonitor monitor) throws SystemMessageException {
|
||||||
|
@ -1100,7 +1123,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
if (permNew != permOld) {
|
if (permNew != permOld) {
|
||||||
//getChannel("SftpFileService.setReadOnly").chmod(permNew, path); //$NON-NLS-1$
|
//getChannel("SftpFileService.setReadOnly").chmod(permNew, path); //$NON-NLS-1$
|
||||||
attr.setPERMISSIONS(permNew);
|
attr.setPERMISSIONS(permNew);
|
||||||
getChannel("SftpFileService.setReadOnly").setStat(recode(path), attr); //$NON-NLS-1$ ok=true;
|
getChannel("SftpFileService.setReadOnly").setStat(recode(path), attr); //$NON-NLS-1$ ok=true;
|
||||||
Activator.trace("SftpFileService.setReadOnly ok"); //$NON-NLS-1$
|
Activator.trace("SftpFileService.setReadOnly ok"); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
|
@ -1120,18 +1143,18 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
/**
|
/**
|
||||||
* Gets the input stream to access the contents of a remote file.
|
* Gets the input stream to access the contents of a remote file.
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @see org.eclipse.rse.services.files.AbstractFileService#getInputStream(String, String, boolean, IProgressMonitor)
|
* @see org.eclipse.rse.services.files.AbstractFileService#getInputStream(String, String, boolean, IProgressMonitor)
|
||||||
*/
|
*/
|
||||||
public InputStream getInputStream(String remoteParent, String remoteFile, boolean isBinary, IProgressMonitor monitor) throws SystemMessageException {
|
public InputStream getInputStream(String remoteParent, String remoteFile, boolean isBinary, IProgressMonitor monitor) throws SystemMessageException {
|
||||||
|
|
||||||
InputStream stream = null;
|
InputStream stream = null;
|
||||||
|
|
||||||
String remotePath = concat(remoteParent, remoteFile);
|
String remotePath = concat(remoteParent, remoteFile);
|
||||||
try {
|
try {
|
||||||
String remotePathRecoded = recode(remotePath);
|
String remotePathRecoded = recode(remotePath);
|
||||||
getChannel("SftpFileService.getInputStream " + remoteFile); //check the session is healthy //$NON-NLS-1$
|
getChannel("SftpFileService.getInputStream " + remoteFile); //check the session is healthy //$NON-NLS-1$
|
||||||
ChannelSftp channel = (ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$
|
ChannelSftp channel = (ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$NON-NLS-1$
|
||||||
channel.connect();
|
channel.connect();
|
||||||
stream = new SftpBufferedInputStream(channel.get(remotePathRecoded), channel);
|
stream = new SftpBufferedInputStream(channel.get(remotePathRecoded), channel);
|
||||||
Activator.trace("SftpFileService.getInputStream " + remoteFile + " ok"); //$NON-NLS-1$ //$NON-NLS-2$
|
Activator.trace("SftpFileService.getInputStream " + remoteFile + " ok"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
}
|
}
|
||||||
|
@ -1139,7 +1162,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
Activator.trace("SftpFileService.getInputStream " + remotePath + " failed: " + e.toString()); //$NON-NLS-1$ //$NON-NLS-2$
|
Activator.trace("SftpFileService.getInputStream " + remotePath + " failed: " + e.toString()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
throw makeSystemMessageException(e);
|
throw makeSystemMessageException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1152,23 +1175,23 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
int options = isBinary ? IFileService.NONE : IFileService.TEXT_MODE;
|
int options = isBinary ? IFileService.NONE : IFileService.TEXT_MODE;
|
||||||
return getOutputStream(remoteParent, remoteFile, options, monitor);
|
return getOutputStream(remoteParent, remoteFile, options, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.files.AbstractFileService#getOutputStream(java.lang.String, java.lang.String, boolean, int, org.eclipse.core.runtime.IProgressMonitor)
|
* @see org.eclipse.rse.services.files.AbstractFileService#getOutputStream(java.lang.String, java.lang.String, boolean, int, org.eclipse.core.runtime.IProgressMonitor)
|
||||||
*/
|
*/
|
||||||
public OutputStream getOutputStream(String remoteParent, String remoteFile, int options, IProgressMonitor monitor) throws SystemMessageException {
|
public OutputStream getOutputStream(String remoteParent, String remoteFile, int options, IProgressMonitor monitor) throws SystemMessageException {
|
||||||
|
|
||||||
if (monitor == null) {
|
if (monitor == null) {
|
||||||
monitor = new NullProgressMonitor();
|
monitor = new NullProgressMonitor();
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputStream stream = null;
|
OutputStream stream = null;
|
||||||
String dst = remoteParent;
|
String dst = remoteParent;
|
||||||
if (remoteFile!=null) {
|
if (remoteFile!=null) {
|
||||||
dst = concat(remoteParent, remoteFile);
|
dst = concat(remoteParent, remoteFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SftpProgressMonitor sftpMonitor = new MyProgressMonitor(monitor);
|
SftpProgressMonitor sftpMonitor = new MyProgressMonitor(monitor);
|
||||||
int mode;
|
int mode;
|
||||||
|
@ -1179,8 +1202,8 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
getChannel("SftpFileService.getOutputStream " + remoteFile); //check the session is healthy //$NON-NLS-1$
|
getChannel("SftpFileService.getOutputStream " + remoteFile); //check the session is healthy //$NON-NLS-1$
|
||||||
ChannelSftp channel = (ChannelSftp)fSessionProvider.getSession().openChannel("sftp"); //$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);
|
stream = new SftpBufferedOutputStream(channel.put(recodeSafe(dst), sftpMonitor, mode), channel);
|
||||||
Activator.trace("SftpFileService.getOutputStream " + remoteFile + " ok"); //$NON-NLS-1$ //$NON-NLS-2$
|
Activator.trace("SftpFileService.getOutputStream " + remoteFile + " ok"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
|
@ -1199,7 +1222,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
*/
|
*/
|
||||||
public IHostFilePermissions getFilePermissions(IHostFile file,
|
public IHostFilePermissions getFilePermissions(IHostFile file,
|
||||||
IProgressMonitor monitor) throws SystemMessageException {
|
IProgressMonitor monitor) throws SystemMessageException {
|
||||||
if (file instanceof IHostFilePermissionsContainer){
|
if (file instanceof IHostFilePermissionsContainer){
|
||||||
return ((IHostFilePermissionsContainer)file).getPermissions();
|
return ((IHostFilePermissionsContainer)file).getPermissions();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1211,10 +1234,10 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
*/
|
*/
|
||||||
public void setFilePermissions(IHostFile file,
|
public void setFilePermissions(IHostFile file,
|
||||||
IHostFilePermissions permissions, IProgressMonitor monitor)
|
IHostFilePermissions permissions, IProgressMonitor monitor)
|
||||||
throws SystemMessageException {
|
throws SystemMessageException {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCapabilities(IHostFile file) {
|
public int getCapabilities(IHostFile file) {
|
||||||
return IFilePermissionsService.FS_CAN_GET_ALL;
|
return IFilePermissionsService.FS_CAN_GET_ALL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue