Skip to content

Commit

Permalink
[FIXED JENKINS-9577] Apply file permissions from zip archives
Browse files Browse the repository at this point in the history
Using the zip support classes just like Ant does in order to apply
permissions. As a side-effect, remote streams need to be stored in a
temporary file before actually unzipping them.
  • Loading branch information
CMoH authored and kohsuke committed Sep 13, 2011
1 parent 649e62c commit 37a22a1
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
3 changes: 3 additions & 0 deletions changelog.html
Expand Up @@ -63,6 +63,9 @@
<div id="rc" style="display:none;"><!--=BEGIN=-->
<h3><a name=v1.431>What's new in 1.431</a> <!--=DATE=--></h3>
<ul class=image>
<li class=rfe>
Fixed a file permission handling in the unzip code.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-9577">issue 9577</a>)
<li class=>rfe>
Add "un/check all" buttons on matrix-based security.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-7565">issue 7565</a>)
Expand Down
47 changes: 36 additions & 11 deletions core/src/main/java/hudson/FilePath.java
Expand Up @@ -63,7 +63,6 @@
import org.kohsuke.stapler.Stapler;
import org.jvnet.robust_http_client.RetryableHttpStream;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
Expand Down Expand Up @@ -94,12 +93,15 @@
import java.util.concurrent.TimeoutException;
import java.util.zip.GZIPOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipInputStream;

import com.sun.jna.Native;
import java.util.Enumeration;
import java.util.logging.Logger;
import org.apache.tools.ant.taskdefs.Chmod;

import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipEntry;

/**
* {@link File} like object with remoting support.
*
Expand Down Expand Up @@ -418,8 +420,12 @@ private int archive(final ArchiverFactory factory, OutputStream os, final String
*/
public void unzip(final FilePath target) throws IOException, InterruptedException {
target.act(new FileCallable<Void>() {

public Void invoke(File dir, VirtualChannel channel) throws IOException {
unzip(dir,FilePath.this.read());
if (FilePath.this.isRemote())
unzip(dir, FilePath.this.read()); // use streams
else
unzip(dir, new File(FilePath.this.getRemote())); // shortcut to local file
return null;
}
private static final long serialVersionUID = 1L;
Expand Down Expand Up @@ -466,21 +472,40 @@ public Void invoke(File dir, VirtualChannel channel) throws IOException {
}

private void unzip(File dir, InputStream in) throws IOException {
File tmpFile = File.createTempFile("tmpzip", null); // uses java.io.tmpdir
try {
IOUtils.copy(in, tmpFile);
unzip(dir,tmpFile);
}
finally {
tmpFile.delete();
}
}

private void unzip(File dir, File zipFile) throws IOException {
dir = dir.getAbsoluteFile(); // without absolutization, getParentFile below seems to fail
ZipInputStream zip = new ZipInputStream(new BufferedInputStream(in));
java.util.zip.ZipEntry e;
ZipFile zip = new ZipFile(zipFile);
Enumeration<ZipEntry> entries = zip.getEntries();

try {
while((e=zip.getNextEntry())!=null) {
File f = new File(dir,e.getName());
if(e.isDirectory()) {
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
File f = new File(dir, e.getName());
if (e.isDirectory()) {
f.mkdirs();
} else {
File p = f.getParentFile();
if(p!=null) p.mkdirs();
IOUtils.copy(zip, f);
if (p != null) {
p.mkdirs();
}
IOUtils.copy(zip.getInputStream(e), f);
f.setLastModified(e.getTime());
zip.closeEntry();
try {
FilePath target = new FilePath(f);
target.chmod(e.getUnixMode());
} catch (InterruptedException ex) {
LOGGER.log(Level.WARNING, "unable to set permissions", ex);
}
}
}
} finally {
Expand Down

0 comments on commit 37a22a1

Please sign in to comment.