Bug 566705 Docker: readContainerDirectory: Fix reading symlinks
"ls -L" reads info of linked file, not the link itself -> Links are
never marked as such -> Removed
The link target is now taken from ls and not normalized. The previous
solution also broke when links contained absolute paths. Normalizing
links also broke the PLA as, for example, extracting a Tar also does not
normalize symlinks. File names and links with blanks in their names
are supported now by tokenizing properly.
ContainerFileProxy is updated to return the actual link via getLink()
and to return the actual target via getTarget()
CopyFromContainerCommandHandler is updated to create symbolic links
for relative links if copying a folder, otherwise, for individual files
and absolute links, the link is followed and the file/dir is copied. Up
to 10 links are followed to avoid a possible circular link situation.
ContainerLauncher copy from container logic is updated similarly.
Fix API issue in DockerException caused by removal of getMessage().
Change-Id: Ie740e30ff1fbbf170e46d54eab134a82dc36c38b
Reviewed-on: https://git.eclipse.org/r/c/linuxtools/org.eclipse.linuxtools/+/173149
Tested-by: Linux Tools Bot <linuxtools-bot@eclipse.org>
Tested-by: Jeff Johnston <jjohnstn@redhat.com>
Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
Reviewed-on: https://git.eclipse.org/r/c/linuxtools/org.eclipse.linuxtools/+/168426
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerException.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerException.java
index b28a911..12fad3b 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerException.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerException.java
@@ -1,6 +1,6 @@
/*******************************************************************************
* Copyright (c) 2014, 2020 Red Hat and others.
- *
+ *
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -33,6 +33,11 @@
super(calculateMessage(null, cause), cause);
}
+ @Override
+ public String getMessage() {
+ return super.getMessage();
+ }
+
static private String calculateMessage(final String message, final Throwable cause) {
Throwable dre = cause;
// Search for DockerRequestException
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/ContainerFileProxy.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/ContainerFileProxy.java
index 207625f..95d1246 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/ContainerFileProxy.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/ContainerFileProxy.java
@@ -1,6 +1,6 @@
/*******************************************************************************
- * Copyright (c) 2016, 2018 Red Hat.
- *
+ * Copyright (c) 2016, 2020 Red Hat.
+ *
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -12,11 +12,14 @@
*******************************************************************************/
package org.eclipse.linuxtools.internal.docker.core;
+import org.eclipse.core.runtime.Path;
+
public class ContainerFileProxy {
private final String path;
private final String name;
private final String link;
+ private final String target;
private final boolean isFolder;
private final boolean isLink;
@@ -26,7 +29,8 @@
this.name = name;
this.isFolder = isFolder;
this.isLink = false;
- this.link = this.path;
+ this.link = null;
+ this.target = this.path;
}
public ContainerFileProxy(String directory, String name, boolean isFolder,
@@ -35,7 +39,10 @@
this.name = name;
this.isFolder = isFolder;
this.isLink = isLink;
- this.link = (link == null ? this.path : link);
+ this.link = link;
+ this.target = (link.startsWith("/") ? link
+ : new Path(this.path).removeLastSegments(1).append(link)
+ .toPortableString());
}
public String getFullPath() {
@@ -60,6 +67,10 @@
return link;
}
+ public String getTarget() {
+ return target;
+ }
+
public String getName() {
return name;
}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java
index bb5daaa..26a159c 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java
@@ -35,6 +35,8 @@
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.ws.rs.ProcessingException;
@@ -42,7 +44,6 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
-import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
@@ -396,10 +397,9 @@
}
@Override
- protected void finalize() throws Throwable {
+ protected void finalize() {
this.finalizing = true;
close();
- super.finalize();
}
@Override
@@ -2263,7 +2263,7 @@
try {
DockerClient copyClient = getClientCopy();
final ExecCreation execCreation = copyClient.execCreate(id,
- new String[] { "/bin/sh", "-c", "ls -l -F -L -Q " + path }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ new String[] { "/bin/sh", "-c", "ls -l -F -Q " + path }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
ExecCreateParam.attachStdout(),
ExecCreateParam.attachStderr());
final String execId = execCreation.id();
@@ -2306,33 +2306,47 @@
return childList;
}
+ private String[] tokenize(String line) {
+ String regex = "(\"[^\"]*\"/?)|(\\S+)";
+ List<String> result = new ArrayList<>();
+
+ Matcher m = Pattern.compile(regex).matcher(line);
+ while (m.find()) {
+ if (m.group(1) != null) {
+ result.add(m.group(1));
+ } else {
+ result.add(m.group(2));
+ }
+ }
+ return result.toArray(new String[0]);
+ }
+
private void processDirectoryLine(String line, String path,
List<ContainerFileProxy> childList) {
if (line.trim().startsWith("total")) //$NON-NLS-1$
return; // ignore the total line
- String[] token = line.split("\\s+"); //$NON-NLS-1$
+ String[] token = tokenize(line);
boolean isDirectory = token[0].startsWith("d"); //$NON-NLS-1$
boolean isLink = token[0].startsWith("l"); //$NON-NLS-1$
if (token.length > 8) {
- // last token depends on whether we have a link or not
- String link = null;
+ // Non-Link ends with "filename"
+ // Link ends with "filename" -> "Target"
+ String name = token[token.length - (isLink ? 3 : 1)];
+ // remove quotes and any indicator char
+ name = name.substring(1,
+ name.length() - (name.endsWith("\"") ? 1 : 2));
+
if (isLink) {
String linkname = token[token.length - 1];
if (linkname.endsWith("/")) { //$NON-NLS-1$
- linkname = linkname.substring(0, linkname.length() - 1);
isDirectory = true;
}
- IPath linkPath = new Path(path);
- linkPath = linkPath.append(linkname);
- link = linkPath.toString();
- String name = token[token.length - 3];
+ linkname = linkname.substring(1,
+ linkname.length() - (linkname.endsWith("\"") ? 1 : 2));
+
childList.add(new ContainerFileProxy(path, name, isDirectory,
- isLink, link));
+ isLink, linkname));
} else {
- String name = token[token.length - 1];
- // remove quotes and any indicator char
- name = name.substring(1,
- name.length() - (name.endsWith("\"") ? 1 : 2));
childList.add(new ContainerFileProxy(path, name, isDirectory));
}
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java
index 36ea020..5a967b8 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java
@@ -451,9 +451,28 @@
path = path.append(te.getName());
File f = new File(path.toOSString());
int mode = te.getMode();
+ if (te.isSymbolicLink()) {
+ IPath linkPath = new Path(te.getLinkName());
+ if (!linkPath.isAbsolute()) {
+ if (!isWin) {
+ java.nio.file.Path p = Paths.get(path.toPortableString());
+ java.nio.file.Path link = Paths.get(te.getLinkName());
+ if (f.exists()) {
+ f.delete();
+ }
+ Files.createSymbolicLink(p, link);
+ } else {
+ linkPath = new Path(volume).append(te.getLinkName());
+ links.put(path.toPortableString(), linkPath.toPortableString());
+ }
+ } else {
+ links.put(path.toPortableString(), linkPath.toPortableString());
+ }
+ continue;
+ }
if (te.isDirectory()) {
f.mkdir();
- if (!isWin && !te.isSymbolicLink()) {
+ if (!isWin) {
Files.setPosixFilePermissions(Paths.get(path.toOSString()), toPerms(mode));
}
continue;
@@ -462,7 +481,7 @@
continue;
}
f.createNewFile();
- if (!isWin && !te.isSymbolicLink()) {
+ if (!isWin) {
Files.setPosixFilePermissions(Paths.get(path.toOSString()), toPerms(mode));
}
}
@@ -470,22 +489,14 @@
int bufferSize = ((int) size > 4096 ? 4096 : (int) size);
byte[] barray = new byte[bufferSize];
int result = -1;
- if (size == 0 && te.isSymbolicLink()) {
- IPath linkPath = new Path(te.getLinkName());
- if (!linkPath.isAbsolute()) {
- linkPath = new Path(volume).append(te.getLinkName());
+ while ((result = k.read(barray, 0, bufferSize)) > -1) {
+ if (monitor.isCanceled()) {
+ monitor.done();
+ k.close();
+ os.close();
+ return Status.CANCEL_STATUS;
}
- links.put(te.getName(), linkPath.toPortableString());
- } else {
- while ((result = k.read(barray, 0, bufferSize)) > -1) {
- if (monitor.isCanceled()) {
- monitor.done();
- k.close();
- os.close();
- return Status.CANCEL_STATUS;
- }
- os.write(barray, 0, result);
- }
+ os.write(barray, 0, result);
}
}
}
@@ -495,36 +506,83 @@
// is fully copied
for (String name : links.keySet()) {
String link = links.get(name);
- InputStream in2 = ((DockerConnection) connection).copyContainer(token, containerId,
- link);
- /*
- * The input stream from copyContainer might be incomplete or non-blocking so we
- * should wrap it in a stream that is guaranteed to block until data is
- * available.
- */
- try (TarArchiveInputStream k = new TarArchiveInputStream(
- new BlockingInputStream(in2))) {
- TarArchiveEntry te = k.getNextTarEntry();
- if (te != null) {
- long size = te.getSize();
- IPath currDir = target.append(volume).removeLastSegments(1);
- IPath path = currDir.append(name);
- File f = new File(path.toOSString());
- f.createNewFile();
- try (FileOutputStream os = new FileOutputStream(f)) {
- int bufferSize = ((int) size > 4096 ? 4096 : (int) size);
- byte[] barray = new byte[bufferSize];
- int result = -1;
- while ((result = k.read(barray, 0, bufferSize)) > -1) {
- if (monitor.isCanceled()) {
- monitor.done();
- k.close();
- os.close();
- return Status.CANCEL_STATUS;
+ boolean resolved = false;
+ int i = 0; // prevent infinite loop if there is a circular link
+ while (!resolved && ++i < 10) {
+ InputStream in2 = ((DockerConnection) connection).copyContainer(token, containerId,
+ link);
+ /*
+ * The input stream from copyContainer might be incomplete or non-blocking so we
+ * should wrap it in a stream that is guaranteed to block until data is
+ * available.
+ */
+ try (TarArchiveInputStream k = new TarArchiveInputStream(
+ new BlockingInputStream(in2))) {
+ TarArchiveEntry te = k.getNextTarEntry();
+ if (te != null && te.isSymbolicLink()) {
+ IPath linkPath = new Path(te.getLinkName());
+ if (!linkPath.isAbsolute()) {
+ linkPath = new Path(link).removeLastSegments(1)
+ .append(te.getLinkName());
+ }
+ link = linkPath.toPortableString();
+ continue;
+ }
+ while (te != null) {
+ long size = te.getSize();
+ IPath currDir = target.append(volume).removeLastSegments(1);
+ IPath path = currDir.append(name);
+ File f = new File(path.toOSString());
+ if (te.isSymbolicLink()) {
+ IPath linkPath = new Path(te.getLinkName());
+ if (!linkPath.isAbsolute()) {
+ if (!isWin) {
+ java.nio.file.Path p = Paths.get(path.toPortableString());
+ java.nio.file.Path linkp = Paths.get(te.getLinkName());
+ if (f.exists()) {
+ f.delete();
+ }
+ Files.createSymbolicLink(p, linkp);
+ } else {
+ // we don't follow nested links
+ }
+ } else {
+ // we don't follow nested absolute links
}
- os.write(barray, 0, result);
+ te = k.getNextTarEntry();
+ continue;
+ }
+ int mode = te.getMode();
+ if (te.isDirectory()) {
+ f.mkdir();
+ if (!isWin) {
+ Files.setPosixFilePermissions(Paths.get(path.toOSString()),
+ toPerms(mode));
+ }
+ te = k.getNextTarEntry();
+ continue;
+ }
+ f.createNewFile();
+ if (!isWin) {
+ Files.setPosixFilePermissions(Paths.get(path.toOSString()),
+ toPerms(mode));
+ }
+ try (FileOutputStream os = new FileOutputStream(f)) {
+ int bufferSize = ((int) size > 4096 ? 4096 : (int) size);
+ byte[] barray = new byte[bufferSize];
+ int result = -1;
+ while ((result = k.read(barray, 0, bufferSize)) > -1) {
+ if (monitor.isCanceled()) {
+ monitor.done();
+ k.close();
+ os.close();
+ return Status.CANCEL_STATUS;
+ }
+ os.write(barray, 0, result);
+ }
}
}
+ resolved = true;
}
}
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandMessages.properties b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandMessages.properties
index f5e3b96..e90044f 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandMessages.properties
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandMessages.properties
@@ -16,6 +16,7 @@
command.pullImage.failure.no_connection=Unable to pull an image: no connection was found in the selection.
command.copyfromcontainer.failure.no_connection=Unable to copy from container: no connection was found.
+command.copyfromcontainer.failure.possible_circular_links=More than 9 links followed: possible circular links.
command.copyfromcontainer.job.title=Copying files from {0}
command.copyfromcontainer.job.task=Copying files
command.copyfromcontainer.job.subtask=Copying {0}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java
index 7c85c2e..22aa3ab 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CopyFromContainerCommandHandler.java
@@ -59,6 +59,7 @@
public class CopyFromContainerCommandHandler extends AbstractHandler {
private static final String ERROR_COPYING_FROM_CONTAINER_NO_CONNECTION = "command.copyfromcontainer.failure.no_connection"; //$NON-NLS-1$
+ private static final String ERROR_POSSIBLE_CIRCULAR_LINKS = "command.copyfromcontainer.failure.possible_circular_links"; //$NON-NLS-1$
private static final String MISSING_CONNECTION = "missing_connection"; //$NON-NLS-1$
private static final String ERROR_COPYING_FROM_CONTAINER = "command.copyfromcontainer.error.msg"; //$NON-NLS-1$
private static final String COPY_FROM_CONTAINER_JOB_TASK = "command.copyfromcontainer.job.task"; //$NON-NLS-1$
@@ -166,7 +167,7 @@
proxy.getFullPath()));
monitor.worked(1);
InputStream in = ((DockerConnection) connection).copyContainer(token, container.id(),
- proxy.getLink());
+ proxy.getFullPath());
/*
* The input stream from copyContainer might be incomplete or non-blocking so we
* should wrap it in a stream that is guaranteed to block until data is
@@ -180,75 +181,40 @@
path = path.append(te.getName());
File f = new File(path.toOSString());
int mode = te.getMode();
+ if (te.isSymbolicLink()) {
+ IPath linkPath = new Path(te.getLinkName());
+ if (!linkPath.isAbsolute()) {
+ // for relative links, we will create a symbolic link if
+ // we are copying a folder, otherwise, we will follow the
+ // link and copy the file it points to
+ if (!isWin && proxy.isFolder()) {
+ java.nio.file.Path p = Paths.get(path.toPortableString());
+ java.nio.file.Path link = Paths.get(te.getLinkName());
+ if (f.exists()) {
+ f.delete();
+ }
+ Files.createSymbolicLink(p, link);
+ } else {
+ linkPath = new Path(proxy.getFullPath()).removeLastSegments(1)
+ .append(te.getLinkName());
+ links.put(path.toPortableString(), linkPath.toPortableString());
+ }
+ } else {
+ links.put(path.toPortableString(), linkPath.toPortableString());
+ }
+ continue;
+ }
if (te.isDirectory()) {
f.mkdir();
- if (!isWin && !te.isSymbolicLink()) {
+ if (!isWin) {
Files.setPosixFilePermissions(Paths.get(path.toOSString()), toPerms(mode));
}
continue;
- } else {
- f.createNewFile();
- if (!isWin && !te.isSymbolicLink()) {
- Files.setPosixFilePermissions(Paths.get(path.toOSString()), toPerms(mode));
- }
}
- try (FileOutputStream os = new FileOutputStream(f)) {
- int bufferSize = ((int) size > 4096 ? 4096 : (int) size);
- byte[] barray = new byte[bufferSize];
- int result = -1;
- if (size == 0 && te.isSymbolicLink()) {
- IPath linkPath = new Path(te.getLinkName());
- if (!linkPath.isAbsolute()) {
- if (proxy.isFolder()) {
- linkPath = new Path(proxy.getFullPath()).append(te.getLinkName());
- } else {
- linkPath = new Path(proxy.getFullPath()).removeLastSegments(1)
- .append(te.getLinkName());
- }
-
- }
- links.put(te.getName(), linkPath.toPortableString());
- } else {
- while ((result = k.read(barray, 0, bufferSize)) > -1) {
- if (monitor.isCanceled()) {
- monitor.done();
- k.close();
- os.close();
- return Status.CANCEL_STATUS;
- }
- os.write(barray, 0, result);
- }
- }
- }
- }
- }
- } catch (final DockerException e) {
- Display.getDefault()
- .syncExec(() -> MessageDialog.openError(
- PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
- CommandMessages.getFormattedString(ERROR_COPYING_FROM_CONTAINER,
- proxy.getLink(), container.name()),
- e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
- }
- }
- for (String name : links.keySet()) {
- String link = links.get(name);
- try {
- InputStream in = ((DockerConnection) connection).copyContainer(token, container.id(),
- link);
- /*
- * The input stream from copyContainer might be incomplete or non-blocking so we
- * should wrap it in a stream that is guaranteed to block until data is
- * available.
- */
- try (TarArchiveInputStream k = new TarArchiveInputStream(new BlockingInputStream(in))) {
- TarArchiveEntry te = k.getNextTarEntry();
- if (te != null) {
- long size = te.getSize();
- IPath path = new Path(target);
- path = path.append(name);
- File f = new File(path.toOSString());
f.createNewFile();
+ if (!isWin) {
+ Files.setPosixFilePermissions(Paths.get(path.toOSString()), toPerms(mode));
+ }
try (FileOutputStream os = new FileOutputStream(f)) {
int bufferSize = ((int) size > 4096 ? 4096 : (int) size);
byte[] barray = new byte[bufferSize];
@@ -270,10 +236,105 @@
.syncExec(() -> MessageDialog.openError(
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
CommandMessages.getFormattedString(ERROR_COPYING_FROM_CONTAINER,
- name, container.name()),
+ proxy.getTarget(), container.name()),
e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
}
}
+ // resolve absolute links by copying the files
+ for (String name : links.keySet()) {
+ String link = links.get(name);
+ boolean resolved = false;
+ int i = 0; // prevent infinite loop if there is a circular link
+ while (!resolved && ++i < 10) {
+ try {
+ InputStream in = ((DockerConnection) connection).copyContainer(token, container.id(),
+ link);
+ /*
+ * The input stream from copyContainer might be incomplete or non-blocking so we
+ * should wrap it in a stream that is guaranteed to block until data is
+ * available.
+ */
+ try (TarArchiveInputStream k = new TarArchiveInputStream(new BlockingInputStream(in))) {
+ TarArchiveEntry te = k.getNextTarEntry();
+ if (te != null && te.isSymbolicLink()) {
+ IPath linkPath = new Path(te.getLinkName());
+ if (!linkPath.isAbsolute()) {
+ linkPath = new Path(link).removeLastSegments(1).append(te.getLinkName());
+ }
+ link = linkPath.toPortableString();
+ continue;
+ }
+ while (te != null) {
+ long size = te.getSize();
+ IPath path = new Path(name)
+ .append(new Path(te.getName()).removeFirstSegments(1));
+ File f = new File(path.toOSString());
+ if (te.isSymbolicLink()) {
+ IPath linkPath = new Path(te.getLinkName());
+ if (!isWin && !linkPath.isAbsolute()) {
+ java.nio.file.Path p = Paths.get(path.toPortableString());
+ java.nio.file.Path linkp = Paths.get(te.getLinkName());
+ if (f.exists()) {
+ f.delete();
+ }
+ Files.createSymbolicLink(p, linkp);
+ } else {
+ // we don't follow nested links
+ }
+ te = k.getNextTarEntry();
+ continue;
+ }
+ int mode = te.getMode();
+ if (te.isDirectory()) {
+ f.mkdir();
+ if (!isWin) {
+ Files.setPosixFilePermissions(Paths.get(path.toOSString()),
+ toPerms(mode));
+ }
+ te = k.getNextTarEntry();
+ continue;
+ }
+ f.createNewFile();
+ if (!isWin) {
+ Files.setPosixFilePermissions(Paths.get(path.toOSString()), toPerms(mode));
+ }
+ try (FileOutputStream os = new FileOutputStream(f)) {
+ int bufferSize = ((int) size > 4096 ? 4096 : (int) size);
+ byte[] barray = new byte[bufferSize];
+ int result = -1;
+ while ((result = k.read(barray, 0, bufferSize)) > -1) {
+ if (monitor.isCanceled()) {
+ monitor.done();
+ k.close();
+ os.close();
+ return Status.CANCEL_STATUS;
+ }
+ os.write(barray, 0, result);
+ }
+ }
+ te = k.getNextTarEntry();
+ }
+ resolved = true;
+ }
+ } catch (final DockerException e) {
+ Display.getDefault()
+ .syncExec(() -> MessageDialog.openError(
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
+ CommandMessages.getFormattedString(ERROR_COPYING_FROM_CONTAINER, name,
+ container.name()),
+ e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
+ }
+ }
+ if (i == 10) {
+ Display.getDefault()
+ .syncExec(() -> MessageDialog.openError(
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
+ CommandMessages.getFormattedString(ERROR_COPYING_FROM_CONTAINER, name,
+ container.name()),
+ CommandMessages.getString(ERROR_POSSIBLE_CIRCULAR_LINKS)));
+
+ }
+ }
} catch (InterruptedException e) {
// do nothing
} catch (IOException e) {