src/main/java/com/gitblit/utils/JGitUtils.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/com/gitblit/utils/JnaUtils.java | ●●●●● patch | view | raw | blame | history | |
src/test/java/com/gitblit/tests/JGitUtilsTest.java | ●●●●● patch | view | raw | blame | history | |
src/test/java/com/gitblit/tests/JnaUtilsTest.java | ●●●●● patch | view | raw | blame | history |
src/main/java/com/gitblit/utils/JGitUtils.java
@@ -89,8 +89,6 @@ import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.models.RefModel; import com.gitblit.models.SubmoduleModel; import com.sun.jna.Library; import com.sun.jna.Native; /** * Collection of static methods for retrieving information from a repository. @@ -290,8 +288,7 @@ config.setBoolean("receive", null, "denyNonFastforwards", true); config.save(); if (! System.getProperty("os.name").toLowerCase().startsWith("windows")) { final CLibrary libc = (CLibrary) Native.loadLibrary("c", CLibrary.class); if (! JnaUtils.isWindows()) { //libc.chmod("/path/to/file", 0755); } @@ -301,9 +298,6 @@ } catch (IOException e) { throw new RuntimeException(e); } } interface CLibrary extends Library { public int chmod(String path, int mode); } private enum GitConfigSharedRepositoryValue { UMASK("0", 0), FALSE("0", 0), OFF("0", 0), NO("0", 0), src/main/java/com/gitblit/utils/JnaUtils.java
New file @@ -0,0 +1,226 @@ /* * Copyright 2013 gitblit.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gitblit.utils; import com.sun.jna.Library; import com.sun.jna.Native; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Collection of static methods to access native OS library functionality. * * @author Florian Zschocke */ public class JnaUtils { public static final int S_IFMT = 0170000; public static final int S_IFIFO = 0010000; public static final int S_IFCHR = 0020000; public static final int S_IFDIR = 0040000; public static final int S_IFBLK = 0060000; public static final int S_IFREG = 0100000; public static final int S_IFLNK = 0120000; public static final int S_IFSOCK = 0140000; public static final int S_ISUID = 0004000; public static final int S_ISGID = 0002000; public static final int S_ISVTX = 0001000; public static final int S_IRWXU = 0000700; public static final int S_IRUSR = 0000400; public static final int S_IWUSR = 0000200; public static final int S_IXUSR = 0000100; public static final int S_IRWXG = 0000070; public static final int S_IRGRP = 0000040; public static final int S_IWGRP = 0000020; public static final int S_IXGRP = 0000010; public static final int S_IRWXO = 0000007; public static final int S_IROTH = 0000004; public static final int S_IWOTH = 0000002; public static final int S_IXOTH = 0000001; private static final Logger LOGGER = LoggerFactory.getLogger(JGitUtils.class); private static UnixCLibrary unixlibc = null; public static boolean isWindows() { return System.getProperty("os.name").toLowerCase().startsWith("windows"); } private interface UnixCLibrary extends Library { public int chmod(String path, int mode); } public static int setFilemode(File path, int mode) { return setFilemode(path.getAbsolutePath(), mode); } public static int setFilemode(String path, int mode) { if (isWindows()) { throw new UnsupportedOperationException("The method JnaUtils.getFilemode is not supported under Windows."); } return getUnixCLibrary().chmod(path, mode); } public static int getFilemode(File path) { return getFilemode(path.getAbsolutePath()); } public static int getFilemode(String path) { if (isWindows()) { throw new UnsupportedOperationException("The method JnaUtils.getFilemode is not supported under Windows."); } int mode = 0; // Use a Runtime, because implementing stat() via JNA is just too much trouble. String lsLine = runProcessLs(path); if (lsLine == null) { LOGGER.debug("Could not get file information for path " + path); return -1; } Pattern p = Pattern.compile("^(([-bcdlsp])([-r][-w][-xSs])([-r][-w][-xSs])([-r][-w][-xTt])) "); Matcher m = p.matcher(lsLine); if ( !m.lookingAt() ) { LOGGER.debug("Could not parse valid file mode information for path " + path); return -1; } // Parse mode string to mode bits String group = m.group(2); switch (group.charAt(0)) { case 'p' : mode |= 0010000; break; case 'c': mode |= 0020000; break; case 'd': mode |= 0040000; break; case 'b': mode |= 0060000; break; case '-': mode |= 0100000; break; case 'l': mode |= 0120000; break; case 's': mode |= 0140000; break; } for ( int i = 0; i < 3; i++) { group = m.group(3 + i); switch (group.charAt(0)) { case 'r': mode |= (0400 >> i*3); break; case '-': break; } switch (group.charAt(1)) { case 'w': mode |= (0200 >> i*3); break; case '-': break; } switch (group.charAt(2)) { case 'x': mode |= (0100 >> i*3); break; case 'S': mode |= (04000 >> i); break; case 's': mode |= (0100 >> i*3); mode |= (04000 >> i); break; case 'T': mode |= 01000; break; case 't': mode |= (0100 >> i*3); mode |= 01000; break; case '-': break; } } return mode; } private static String runProcessLs(String path) { String cmd = "ls -ldO " + path; Runtime rt = Runtime.getRuntime(); Process pr = null; InputStreamReader ir = null; BufferedReader br = null; String output = null; try { pr = rt.exec(cmd); ir = new InputStreamReader(pr.getInputStream()); br = new BufferedReader(ir); output = br.readLine(); while (br.readLine() != null) ; // Swallow remaining output } catch (IOException e) { LOGGER.debug("Exception while running unix command '" + cmd + "': " + e); } finally { if (pr != null) try { pr.waitFor(); } catch (Exception ignored) {} if (br != null) try { br.close(); } catch (Exception ignored) {} if (ir != null) try { ir.close(); } catch (Exception ignored) {} if (pr != null) try { pr.getOutputStream().close(); } catch (Exception ignored) {} if (pr != null) try { pr.getInputStream().close(); } catch (Exception ignored) {} if (pr != null) try { pr.getErrorStream().close(); } catch (Exception ignored) {} } return output; } private static UnixCLibrary getUnixCLibrary() { if (unixlibc == null) { unixlibc = (UnixCLibrary) Native.loadLibrary("c", UnixCLibrary.class); if (unixlibc == null) throw new RuntimeException("Could not initialize native C library."); } return unixlibc; } } src/test/java/com/gitblit/tests/JGitUtilsTest.java
@@ -149,6 +149,27 @@ } @Test public void testCreateRepositoryShared() throws Exception { String[] repositories = { "NewTestRepository.git", "NewTestRepository" }; for (String repositoryName : repositories) { Repository repository = JGitUtils.createRepository(GitBlitSuite.REPOSITORIES, repositoryName, "group"); File folder = FileKey.resolve(new File(GitBlitSuite.REPOSITORIES, repositoryName), FS.DETECTED); assertNotNull(repository); assertFalse(JGitUtils.hasCommits(repository)); assertNull(JGitUtils.getFirstCommit(repository, null)); assertEquals(folder.lastModified(), JGitUtils.getFirstChange(repository, null) .getTime()); assertEquals(folder.lastModified(), JGitUtils.getLastChange(repository).when.getTime()); assertNull(JGitUtils.getCommit(repository, null)); repository.close(); RepositoryCache.close(repository); // FileUtils.delete(repository.getDirectory(), FileUtils.RECURSIVE); } } @Test public void testRefs() throws Exception { Repository repository = GitBlitSuite.getJGitRepository(); Map<ObjectId, List<RefModel>> map = JGitUtils.getAllRefs(repository); src/test/java/com/gitblit/tests/JnaUtilsTest.java
New file @@ -0,0 +1,100 @@ /* * Copyright 2011 gitblit.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gitblit.tests; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.JnaUtils; import java.io.File; import java.io.IOException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.apache.commons.io.FileUtils; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryCache; import org.eclipse.jgit.lib.RepositoryCache.FileKey; import org.eclipse.jgit.util.FS; import org.junit.Test; /** * * @author Florian Zschocke */ public class JnaUtilsTest { @Test public void testGetFilemode() throws IOException { String repositoryName = "NewJnaTestRepository.git"; Repository repository = JGitUtils.createRepository(GitBlitSuite.REPOSITORIES, repositoryName); File folder = FileKey.resolve(new File(GitBlitSuite.REPOSITORIES, repositoryName), FS.DETECTED); assertTrue(folder.exists()); int mode = JnaUtils.getFilemode(folder); assertTrue(mode > 0); assertEquals(JnaUtils.S_IFDIR, (mode & JnaUtils.S_IFMT)); // directory assertEquals(JnaUtils.S_IRUSR | JnaUtils.S_IWUSR | JnaUtils.S_IXUSR, (mode & JnaUtils.S_IRWXU)); // owner full access mode = JnaUtils.getFilemode(folder.getAbsolutePath() + "/config"); assertTrue(mode > 0); assertEquals(JnaUtils.S_IFREG, (mode & JnaUtils.S_IFMT)); // directory assertEquals(JnaUtils.S_IRUSR | JnaUtils.S_IWUSR, (mode & JnaUtils.S_IRWXU)); // owner full access repository.close(); RepositoryCache.close(repository); FileUtils.deleteDirectory(repository.getDirectory()); } @Test public void testSetFilemode() throws IOException { String repositoryName = "NewJnaTestRepository.git"; Repository repository = JGitUtils.createRepository(GitBlitSuite.REPOSITORIES, repositoryName); File folder = FileKey.resolve(new File(GitBlitSuite.REPOSITORIES, repositoryName), FS.DETECTED); assertTrue(folder.exists()); File path = new File(folder, "refs"); int mode = JnaUtils.getFilemode(path); assertTrue(mode > 0); assertEquals(JnaUtils.S_IFDIR, (mode & JnaUtils.S_IFMT)); // directory assertEquals(JnaUtils.S_IRUSR | JnaUtils.S_IWUSR | JnaUtils.S_IXUSR, (mode & JnaUtils.S_IRWXU)); // owner full access mode |= JnaUtils.S_ISGID; mode |= JnaUtils.S_IRWXG; int ret = JnaUtils.setFilemode(path, mode); assertEquals(0, ret); mode = JnaUtils.getFilemode(path); assertTrue(mode > 0); assertEquals(JnaUtils.S_ISGID, (mode & JnaUtils.S_ISGID)); // set-gid-bit set assertEquals(JnaUtils.S_IRGRP | JnaUtils.S_IWGRP | JnaUtils.S_IXGRP, (mode & JnaUtils.S_IRWXG)); // group full access path = new File(folder, "config"); mode = JnaUtils.getFilemode(path.getAbsolutePath()); assertTrue(mode > 0); assertEquals(JnaUtils.S_IFREG, (mode & JnaUtils.S_IFMT)); // directory assertEquals(JnaUtils.S_IRUSR | JnaUtils.S_IWUSR, (mode & JnaUtils.S_IRWXU)); // owner full access mode |= (JnaUtils.S_IRGRP | JnaUtils.S_IWGRP); ret = JnaUtils.setFilemode(path.getAbsolutePath(), mode); assertEquals(0, ret); mode = JnaUtils.getFilemode(path.getAbsolutePath()); assertTrue(mode > 0); assertEquals(JnaUtils.S_IRGRP | JnaUtils.S_IWGRP, (mode & JnaUtils.S_IRWXG)); // group full access repository.close(); RepositoryCache.close(repository); FileUtils.deleteDirectory(repository.getDirectory()); } }