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

[429271] Fix for special characters in directory names (master branch)

Change-Id: Ib5ff490ec83dd4791cb01f6d1f85f5b0db189f77
Signed-off-by: Greg Watson <g.watson@computer.org>
This commit is contained in:
Greg Watson 2014-02-27 18:55:49 -05:00
parent 28c493cbe7
commit 3faf39df8d
4 changed files with 130 additions and 129 deletions

View file

@ -12,7 +12,9 @@
package org.eclipse.remote.internal.jsch.core.commands; package org.eclipse.remote.internal.jsch.core.commands;
import java.io.IOException; import java.io.IOException;
import java.text.CharacterIterator;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.text.StringCharacterIterator;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -109,6 +111,78 @@ public abstract class AbstractRemoteCommand<T> {
} }
} }
protected abstract class ExecCallable<T1> implements Callable<T1> {
private IProgressMonitor fProgressMonitor;
private ChannelExec fExecChannel;
private Future<T1> asyncCmdInThread() throws RemoteConnectionException {
setChannel(fConnection.getExecChannel());
return fPool.submit(this);
}
/*
* (non-Javadoc)
*
* @see java.util.concurrent.Callable#call()
*/
@Override
public abstract T1 call() throws JSchException, IOException;
private void finalizeCmdInThread() {
setChannel(null);
}
public ChannelExec getChannel() {
return fExecChannel;
}
public IProgressMonitor getProgressMonitor() {
return fProgressMonitor;
}
/**
* Function opens exec channel and then executes the exec operation. If
* run on the main thread it executes it on a separate thread
*/
public T1 getResult(IProgressMonitor monitor) throws RemoteConnectionException {
Future<T1> future = null;
fProgressMonitor = SubMonitor.convert(monitor, 10);
try {
future = asyncCmdInThread();
return waitCmdInThread(future);
} finally {
finalizeCmdInThread();
}
}
public void setChannel(ChannelExec channel) {
fExecChannel = channel;
}
private T1 waitCmdInThread(Future<T1> future) throws RemoteConnectionException {
boolean bInterrupted = Thread.interrupted();
while (!getProgressMonitor().isCanceled()) {
try {
return future.get(100, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
bInterrupted = true;
} catch (TimeoutException e) {
// ignore
} catch (ExecutionException e) {
getChannel().disconnect();
throw new RemoteConnectionException(e.getMessage());
}
getProgressMonitor().worked(1);
}
if (bInterrupted) {
Thread.currentThread().interrupt(); // set current thread flag
}
future.cancel(true);
getChannel().disconnect();
throw new RemoteConnectionException(Messages.AbstractRemoteCommand_Operation_cancelled_by_user);
}
}
protected abstract class SftpCallable<T1> implements Callable<T1> { protected abstract class SftpCallable<T1> implements Callable<T1> {
private IProgressMonitor fProgressMonitor; private IProgressMonitor fProgressMonitor;
private ChannelSftp fSftpChannel; private ChannelSftp fSftpChannel;
@ -184,78 +258,6 @@ public abstract class AbstractRemoteCommand<T> {
} }
} }
protected abstract class ExecCallable<T1> implements Callable<T1> {
private IProgressMonitor fProgressMonitor;
private ChannelExec fExecChannel;
private Future<T1> asyncCmdInThread() throws RemoteConnectionException {
setChannel(fConnection.getExecChannel());
return fPool.submit(this);
}
/*
* (non-Javadoc)
*
* @see java.util.concurrent.Callable#call()
*/
@Override
public abstract T1 call() throws JSchException, IOException;
private void finalizeCmdInThread() {
setChannel(null);
}
public ChannelExec getChannel() {
return fExecChannel;
}
public IProgressMonitor getProgressMonitor() {
return fProgressMonitor;
}
/**
* Function opens exec channel and then executes the exec operation. If
* run on the main thread it executes it on a separate thread
*/
public T1 getResult(IProgressMonitor monitor) throws RemoteConnectionException {
Future<T1> future = null;
fProgressMonitor = SubMonitor.convert(monitor, 10);
try {
future = asyncCmdInThread();
return waitCmdInThread(future);
} finally {
finalizeCmdInThread();
}
}
public void setChannel(ChannelExec channel) {
fExecChannel = channel;
}
private T1 waitCmdInThread(Future<T1> future) throws RemoteConnectionException {
boolean bInterrupted = Thread.interrupted();
while (!getProgressMonitor().isCanceled()) {
try {
return future.get(100, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
bInterrupted = true;
} catch (TimeoutException e) {
// ignore
} catch (ExecutionException e) {
getChannel().disconnect();
throw new RemoteConnectionException(e.getMessage());
}
getProgressMonitor().worked(1);
}
if (bInterrupted) {
Thread.currentThread().interrupt(); // set current thread flag
}
future.cancel(true);
getChannel().disconnect();
throw new RemoteConnectionException(Messages.AbstractRemoteCommand_Operation_cancelled_by_user);
}
}
private static ExecutorService fPool = Executors.newSingleThreadExecutor(); private static ExecutorService fPool = Executors.newSingleThreadExecutor();
private final JSchConnection fConnection; private final JSchConnection fConnection;
@ -347,6 +349,10 @@ public abstract class AbstractRemoteCommand<T> {
return fileInfo; return fileInfo;
} }
public JSchConnection getConnection() {
return fConnection;
}
public int getFinishStatus() { public int getFinishStatus() {
int code = 0; int code = 0;
@ -429,7 +435,53 @@ public abstract class AbstractRemoteCommand<T> {
protected abstract T getResult(IProgressMonitor monitor) throws RemoteConnectionException; protected abstract T getResult(IProgressMonitor monitor) throws RemoteConnectionException;
public JSchConnection getConnection() { protected String quote(String path, boolean full) {
return fConnection; StringBuffer buffer = new StringBuffer();
StringCharacterIterator iter = new StringCharacterIterator(path);
for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
switch (c) {
case '(':
case ')':
case '[':
case ']':
case '{':
case '}':
case '|':
case '\\':
case '*':
case '&':
case '^':
case '%':
case '$':
case '#':
case '@':
case '!':
case '~':
case '`':
case '\'':
case '"':
case ':':
case ';':
case '?':
case '<':
case '>':
case ',':
case '\n':
if (full) {
buffer.append('\\');
}
buffer.append(c);
continue;
case ' ':
buffer.append('\\');
buffer.append(c);
continue;
default:
buffer.append(c);
continue;
}
}
return buffer.toString();
} }
} }

View file

@ -55,7 +55,7 @@ public class ChildInfosCommand extends AbstractRemoteCommand<IFileInfo[]> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public Vector<LsEntry> call() throws JSchException, SftpException { public Vector<LsEntry> call() throws JSchException, SftpException {
return getChannel().ls(fRemotePath.toString()); return getChannel().ls(quote(fRemotePath.toString(), true));
} }
}; };
try { try {

View file

@ -1,8 +1,5 @@
package org.eclipse.remote.internal.jsch.core.commands; package org.eclipse.remote.internal.jsch.core.commands;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.SubMonitor;
@ -30,53 +27,4 @@ public class DeleteCommand extends AbstractRemoteCommand<Void> {
} }
return null; return null;
} }
private String quote(String path, boolean full) {
StringBuffer buffer = new StringBuffer();
StringCharacterIterator iter = new StringCharacterIterator(path);
for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
switch (c) {
case '(':
case ')':
case '[':
case ']':
case '{':
case '}':
case '|':
case '\\':
case '*':
case '&':
case '^':
case '%':
case '$':
case '#':
case '@':
case '!':
case '~':
case '`':
case '\'':
case '"':
case ':':
case ';':
case '?':
case '<':
case '>':
case ',':
case '\n':
if (full) {
buffer.append('\\');
}
buffer.append(c);
continue;
case ' ':
buffer.append('\\');
buffer.append(c);
continue;
default:
buffer.append(c);
continue;
}
}
return buffer.toString();
}
} }

View file

@ -38,15 +38,16 @@ public class PutInfoCommand extends AbstractRemoteCommand<Void> {
final SubMonitor subMon = SubMonitor.convert(monitor, 30); final SubMonitor subMon = SubMonitor.convert(monitor, 30);
FetchInfoCommand command = new FetchInfoCommand(getConnection(), fRemotePath); FetchInfoCommand command = new FetchInfoCommand(getConnection(), fRemotePath);
String quotedPath = quote(fRemotePath.toString(), true);
if ((fOptions & EFS.SET_ATTRIBUTES) != 0) { if ((fOptions & EFS.SET_ATTRIBUTES) != 0) {
chmod(getPermissions(fFileInfo), fRemotePath.toString(), subMon.newChild(10)); chmod(getPermissions(fFileInfo), quotedPath, subMon.newChild(10));
} }
if ((fOptions & EFS.SET_LAST_MODIFIED) != 0) { if ((fOptions & EFS.SET_LAST_MODIFIED) != 0) {
IFileInfo info = command.getResult(subMon.newChild(10)); IFileInfo info = command.getResult(subMon.newChild(10));
long oldMTime = info.getLastModified(); long oldMTime = info.getLastModified();
int newMTime = (int) (oldMTime / 1000); int newMTime = (int) (oldMTime / 1000);
if (oldMTime != newMTime) { if (oldMTime != newMTime) {
setMTime(newMTime, fRemotePath.toString(), subMon.newChild(10)); setMTime(newMTime, quotedPath, subMon.newChild(10));
} }
} }
return null; return null;