1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +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;
import java.io.IOException;
import java.text.CharacterIterator;
import java.text.MessageFormat;
import java.text.StringCharacterIterator;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
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> {
private IProgressMonitor fProgressMonitor;
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 final JSchConnection fConnection;
@ -347,6 +349,10 @@ public abstract class AbstractRemoteCommand<T> {
return fileInfo;
}
public JSchConnection getConnection() {
return fConnection;
}
public int getFinishStatus() {
int code = 0;
@ -429,7 +435,53 @@ public abstract class AbstractRemoteCommand<T> {
protected abstract T getResult(IProgressMonitor monitor) throws RemoteConnectionException;
public JSchConnection getConnection() {
return fConnection;
protected 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

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

View file

@ -1,8 +1,5 @@
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.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
@ -30,53 +27,4 @@ public class DeleteCommand extends AbstractRemoteCommand<Void> {
}
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);
FetchInfoCommand command = new FetchInfoCommand(getConnection(), fRemotePath);
String quotedPath = quote(fRemotePath.toString(), true);
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) {
IFileInfo info = command.getResult(subMon.newChild(10));
long oldMTime = info.getLastModified();
int newMTime = (int) (oldMTime / 1000);
if (oldMTime != newMTime) {
setMTime(newMTime, fRemotePath.toString(), subMon.newChild(10));
setMTime(newMTime, quotedPath, subMon.newChild(10));
}
}
return null;