From f76fee63ed9cb3a30d3c0c092d860b1cb93a481b Mon Sep 17 00:00:00 2001
From: Gerard Smyth <gerard.smyth@gmail.com>
Date: Thu, 08 May 2014 13:09:30 -0400
Subject: [PATCH] Updated the SyndicationServlet to provide an additional option to return details of the tags in the repository instead of the commits. This uses a new 'ot' request parameter to indicate the object type of the content to return, which can be ither TAG or COMMIT. If this is not provided, then COMMIT is assumed to maintain backwards compatability. If tags are returned, then the paging parameters, 'l' and 'pg' are still supported, but searching options are currently ignored.
---
src/main/java/com/gitblit/utils/JnaUtils.java | 204 ++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 171 insertions(+), 33 deletions(-)
diff --git a/src/main/java/com/gitblit/utils/JnaUtils.java b/src/main/java/com/gitblit/utils/JnaUtils.java
index b7d7209..2b80719 100644
--- a/src/main/java/com/gitblit/utils/JnaUtils.java
+++ b/src/main/java/com/gitblit/utils/JnaUtils.java
@@ -15,9 +15,6 @@
*/
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;
@@ -28,37 +25,40 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+
/**
* 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; // set user id on execution
+ public static final int S_ISGID = 0002000; // set group id on execution
+ public static final int S_ISVTX = 0001000; // sticky bit, save swapped text even after use
- 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; // RWX mask for owner
+ public static final int S_IRUSR = 0000400; // read permission for owner
+ public static final int S_IWUSR = 0000200; // write permission for owner
+ public static final int S_IXUSR = 0000100; // execute/search permission for owner
+ public static final int S_IRWXG = 0000070; // RWX mask for group
+ public static final int S_IRGRP = 0000040; // read permission for group
+ public static final int S_IWGRP = 0000020; // write permission for group
+ public static final int S_IXGRP = 0000010; // execute/search permission for group
+ public static final int S_IRWXO = 0000007; // RWX mask for other
+ public static final int S_IROTH = 0000004; // read permission for other
+ public static final int S_IWOTH = 0000002; // write permission for other
+ public static final int S_IXOTH = 0000001; // execute/search permission for other
- 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;
+ public static final int S_IFMT = 0170000; // type of file mask
+ public static final int S_IFIFO = 0010000; // named pipe (fifo)
+ public static final int S_IFCHR = 0020000; // character special device
+ public static final int S_IFDIR = 0040000; // directory
+ public static final int S_IFBLK = 0060000; // block special device
+ public static final int S_IFREG = 0100000; // regular file
+ public static final int S_IFLNK = 0120000; // symbolic link
+ public static final int S_IFSOCK = 0140000; // socket
private static final Logger LOGGER = LoggerFactory.getLogger(JGitUtils.class);
@@ -66,6 +66,11 @@
private static UnixCLibrary unixlibc = null;
+ /**
+ * Utility method to check if the JVM is running on a Windows OS.
+ *
+ * @return true, if the system property 'os.name' starts with 'Windows'.
+ */
public static boolean isWindows()
{
return System.getProperty("os.name").toLowerCase().startsWith("windows");
@@ -74,14 +79,62 @@
private interface UnixCLibrary extends Library {
public int chmod(String path, int mode);
+ public int getgid();
+ public int getegid();
}
- public static int setFilemode(File path, int mode)
+ public static int getgid()
{
- return setFilemode(path.getAbsolutePath(), mode);
+ if (isWindows()) {
+ throw new UnsupportedOperationException("The method JnaUtils.getgid is not supported under Windows.");
+ }
+
+ return getUnixCLibrary().getgid();
}
+
+ public static int getegid()
+ {
+ if (isWindows()) {
+ throw new UnsupportedOperationException("The method JnaUtils.getegid is not supported under Windows.");
+ }
+
+ return getUnixCLibrary().getegid();
+ }
+
+
+ /**
+ * Set the permission bits of a file.
+ *
+ * The permission bits are set to the provided mode. This method is only
+ * implemented for OSes of the Unix family and makes use of the 'chmod'
+ * function of the native C library. See 'man 2 chmod' for more information.
+ *
+ * @param path
+ * File/directory to set the permission bits for.
+ * @param mode
+ * A mode created from or'd permission bit masks S_I*
+ * @return Upon successful completion, a value of 0 returned. Otherwise, a value of -1 is returned.
+ */
+ public static int setFilemode(File file, int mode)
+ {
+ return setFilemode(file.getAbsolutePath(), mode);
+ }
+
+ /**
+ * Set the permission bits of a file.
+ *
+ * The permission bits are set to the provided mode. This method is only
+ * implemented for OSes of the Unix family and makes use of the 'chmod'
+ * function of the native C library. See 'man 2 chmod' for more information.
+ *
+ * @param path
+ * Path to a file/directory to set the permission bits for.
+ * @param mode
+ * A mode created from or'd permission bit masks S_I*
+ * @return Upon successful completion, a value of 0 returned. Otherwise, a value of -1 is returned.
+ */
public static int setFilemode(String path, int mode)
{
if (isWindows()) {
@@ -93,32 +146,110 @@
+ /**
+ * Get the file mode bits of a file.
+ *
+ * This method is only implemented for OSes of the Unix family. It returns the file mode
+ * information as available in the st_mode member of the resulting struct stat when calling
+ * 'lstat' on a file.
+ *
+ * @param path
+ * File/directory to get the file mode from.
+ * @return Upon successful completion, the file mode bits are returned. Otherwise, a value of -1 is returned.
+ */
public static int getFilemode(File path)
{
return getFilemode(path.getAbsolutePath());
}
+ /**
+ * Get the file mode bits of a file.
+ *
+ * This method is only implemented for OSes of the Unix family. It returns the file mode
+ * information as available in the st_mode member of the resulting struct stat when calling
+ * 'lstat' on a file.
+ *
+ * @param path
+ * Path to a file/directory to get the file mode from.
+ * @return Upon successful completion, the file mode bits are returned. Otherwise, a value of -1 is returned.
+ */
public static int getFilemode(String path)
{
if (isWindows()) {
throw new UnsupportedOperationException("The method JnaUtils.getFilemode is not supported under Windows.");
}
+ Filestat stat = getFilestat(path);
+ if ( stat == null ) return -1;
+ return stat.mode;
+ }
+
+
+ /**
+ * Status information of a file.
+ */
+ public static class Filestat
+ {
+ public int mode; // file mode, permissions, type
+ public int uid; // user Id of owner
+ public int gid; // group Id of owner
+
+ Filestat(int mode, int uid, int gid) {
+ this.mode = mode; this.uid = uid; this.gid = gid;
+ }
+ }
+
+
+ /**
+ * Get Unix file status information for a file.
+ *
+ * This method is only implemented for OSes of the Unix family. It returns file status
+ * information for a file. Currently this is the file mode, the user id and group id of the owner.
+ *
+ * @param path
+ * File/directory to get the file status from.
+ * @return Upon successful completion, a Filestat object containing the file information is returned.
+ * Otherwise, null is returned.
+ */
+ public static Filestat getFilestat(File path)
+ {
+ return getFilestat(path.getAbsolutePath());
+ }
+
+
+ /**
+ * Get Unix file status information for a file.
+ *
+ * This method is only implemented for OSes of the Unix family. It returns file status
+ * information for a file. Currently this is the file mode, the user id and group id of the owner.
+ *
+ * @param path
+ * Path to a file/directory to get the file status from.
+ * @return Upon successful completion, a Filestat object containing the file information is returned.
+ * Otherwise, null is returned.
+ */
+ public static Filestat getFilestat(String path)
+ {
+ if (isWindows()) {
+ throw new UnsupportedOperationException("The method JnaUtils.getFilestat is not supported under Windows.");
+ }
+
int mode = 0;
// Use a Runtime, because implementing stat() via JNA is just too much trouble.
+ // This could be done with the 'stat' command, too. But that may have a shell specific implementation, so we use 'ls' instead.
String lsLine = runProcessLs(path);
if (lsLine == null) {
LOGGER.debug("Could not get file information for path " + path);
- return -1;
+ return null;
}
- Pattern p = Pattern.compile("^(([-bcdlsp])([-r][-w][-xSs])([-r][-w][-xSs])([-r][-w][-xTt])) ");
+ Pattern p = Pattern.compile("^(([-bcdlspCDMnP?])([-r][-w][-xSs])([-r][-w][-xSs])([-r][-w][-xTt]))[@+.]? +[0-9]+ +([0-9]+) +([0-9]+) ");
Matcher m = p.matcher(lsLine);
if ( !m.lookingAt() ) {
LOGGER.debug("Could not parse valid file mode information for path " + path);
- return -1;
+ return null;
}
// Parse mode string to mode bits
@@ -174,13 +305,20 @@
}
}
- return mode;
+ return new Filestat(mode, Integer.parseInt(m.group(6)), Integer.parseInt(m.group(7)));
}
+ /**
+ * Run the unix command 'ls -ldn' on a single file and return the resulting output line.
+ *
+ * @param path
+ * Path to a single file or directory.
+ * @return The first line of output from the 'ls' command. Null, if an error occurred and no line could be read.
+ */
private static String runProcessLs(String path)
{
- String cmd = "ls -ldO " + path;
+ String cmd = "ls -ldn " + path;
Runtime rt = Runtime.getRuntime();
Process pr = null;
InputStreamReader ir = null;
--
Gitblit v1.9.1