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:
parent
28c493cbe7
commit
3faf39df8d
4 changed files with 130 additions and 129 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue