about summary refs log tree commit diff
path: root/lr.c
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2016-02-25 14:59:50 +0100
committerChristian Neukirchen <chneukirchen@gmail.com>2016-02-25 14:59:50 +0100
commit52342f5f4c2a9562b28d74f2c016b19beaef8fbc (patch)
tree5ac1fbe75fe13d5a0bd9bba479b8d3d0d08807d2 /lr.c
parente6e48c7f6c77ed0001684507285d809c30c37611 (diff)
downloadlr-52342f5f4c2a9562b28d74f2c016b19beaef8fbc.tar.gz
lr-52342f5f4c2a9562b28d74f2c016b19beaef8fbc.tar.xz
lr-52342f5f4c2a9562b28d74f2c016b19beaef8fbc.zip
add %x for xattr metadata
Diffstat (limited to 'lr.c')
-rw-r--r--lr.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/lr.c b/lr.c
index de451fa..d9edc95 100644
--- a/lr.c
+++ b/lr.c
@@ -35,6 +35,10 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#ifdef __linux__
+#include <attr/xattr.h>
+#endif
+
 #include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
@@ -1337,6 +1341,39 @@ color_name_on(const char *f, mode_t m)
 		fg256(154);
 }
 
+static char
+xattr_char(const char *f)
+{
+#ifdef __linux__
+	char xattr[1024];
+	int c, i, r;
+
+	if (Lflag)
+		r = listxattr(f, xattr, sizeof xattr);
+	else
+		r = llistxattr(f, xattr, sizeof xattr);
+	if (r < 0 && errno == ERANGE) {
+		/* just look at prefix */
+		r = sizeof xattr;
+		xattr[r-1] = 0;
+	}
+	// ignoring ENOTSUP or r == 0
+
+	for (i = 0, c = 0; i < r; i += strlen(xattr+i) + 1)
+		if (strcmp(xattr+i, "security.capability") == 0) {
+			if (c < 3) c = 3;
+		} else if (strcmp(xattr+i, "system.posix_acl_access") == 0) {
+			if (c < 2) c = 2;
+		} else {
+			if (c < 1) c = 1;
+		}
+
+	return " @+#"[c];
+#else
+	return ' ';		// No support for xattrs on this platform.
+#endif
+}
+
 void
 print_format(struct fileinfo *fi)
 {
@@ -1466,6 +1503,7 @@ print_format(struct fileinfo *fi)
 		case 'e': printf("%ld", (long)fi->entries); break;
 		case 't': printf("%jd", (intmax_t)fi->total); break;
 		case 'Y': printf("%*s", -fwid, fstype(fi->sb.st_dev)); break;
+		case 'x': putchar(xattr_char(fi->fpath)); break;
 		default:
 			putchar('%');
 			putchar(*s);