summary refs log tree commit diff
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2016-02-25 16:04:15 +0100
committerChristian Neukirchen <chneukirchen@gmail.com>2016-02-25 16:04:15 +0100
commit6f112f6a33bf78b5d27e823fa5cbbabf7998085e (patch)
tree40bafc82a0020ef49afbab01f4312a730472149d
parentecef4a24f29755ec7c98f55067a41643362e9a89 (diff)
downloadlr-6f112f6a33bf78b5d27e823fa5cbbabf7998085e.tar.gz
lr-6f112f6a33bf78b5d27e823fa5cbbabf7998085e.tar.xz
lr-6f112f6a33bf78b5d27e823fa5cbbabf7998085e.zip
allow querying for xattr (= %x)
-rw-r--r--README.md2
-rw-r--r--lr.12
-rw-r--r--lr.c92
3 files changed, 50 insertions, 46 deletions
diff --git a/README.md b/README.md
index eecdfe6..7bb4083 100644
--- a/README.md
+++ b/README.md
@@ -162,7 +162,7 @@ Default: `n`.
 	                      | G        -- *1024*1024*1024
 	                      | T )?     -- *1024*1024*1024*1024
 	
-	<strprop>  ::= fstype | group | name | path | target | user
+	<strprop>  ::= fstype | group | name | path | target | user | xattr
 	
 	<strop>    ::= == | =            -- string equality
 	             | ===               -- case insensitive string equality
diff --git a/lr.1 b/lr.1
index 9c6a3ab..de8a56b 100644
--- a/lr.1
+++ b/lr.1
@@ -254,7 +254,7 @@ tests are given by the following EBNF:
                       | G        -- *1024*1024*1024
                       | T )?     -- *1024*1024*1024*1024
 
-<strprop>  ::= fstype | group | name | path | target | user
+<strprop>  ::= fstype | group | name | path | target | user | xattr
 
 <strop>    ::= == | =            -- string equality
              | ===               -- case insensitive string equality
diff --git a/lr.c b/lr.c
index 707000e..9ff06f6 100644
--- a/lr.c
+++ b/lr.c
@@ -172,6 +172,7 @@ enum prop {
 	PROP_TOTAL,
 	PROP_UID,
 	PROP_USER,
+	PROP_XATTR,
 };
 
 enum filetype {
@@ -524,6 +525,8 @@ parse_strcmp()
 		prop = PROP_TARGET;
 	else if (token("user"))
 		prop = PROP_USER;
+	else if (token("xattr"))
+		prop = PROP_XATTR;
 	else
 		return parse_type();
 
@@ -962,6 +965,50 @@ fstype(dev_t devid)
 	return result ? (*result)->name : strid(devid);
 }
 
+static char*
+xattr_string(const char *f)
+{
+#ifdef __linux__
+	char xattr[1024];
+	int i, r;
+	int have_xattr = 0, have_cap = 0, have_acl = 0;
+
+	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; i < r; i += strlen(xattr+i) + 1)
+		if (strcmp(xattr+i, "security.capability") == 0)
+			have_cap = 1;
+		else if (strcmp(xattr+i, "system.posix_acl_access") == 0 ||
+		    strcmp(xattr+i, "system.posix_acl_default") == 0)
+			have_acl = 1;
+		else
+			have_xattr = 1;
+
+	static char buf[4];
+	char *c = buf;
+	if (have_cap)
+		*c++ = '#';
+	if (have_acl)
+		*c++ = '+';
+	if (have_xattr)
+		*c++ = '@';
+	*c = 0;
+
+	return buf;
+#else
+	return "";		// No support for xattrs on this platform.
+#endif
+}
+
 int
 eval(struct expr *e, struct fileinfo *fi)
 {
@@ -1041,6 +1088,7 @@ eval(struct expr *e, struct fileinfo *fi)
 		case PROP_PATH: s = fi->fpath; break;
 		case PROP_TARGET: s = readlin(fi->fpath, ""); break;
 		case PROP_USER: s = username(fi->sb.st_uid); break;
+		case PROP_XATTR: s = xattr_string(fi->fpath); break;
 		}
 		switch (e->op) {
 		case EXPR_STREQ: return strcmp(e->b.string, s) == 0;
@@ -1346,50 +1394,6 @@ color_name_on(const char *f, mode_t m)
 		fg256(154);
 }
 
-static char*
-xattr_string(const char *f)
-{
-#ifdef __linux__
-	char xattr[1024];
-	int i, r;
-	int have_xattr = 0, have_cap = 0, have_acl = 0;
-
-	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; i < r; i += strlen(xattr+i) + 1)
-		if (strcmp(xattr+i, "security.capability") == 0)
-			have_cap = 1;
-		else if (strcmp(xattr+i, "system.posix_acl_access") == 0 ||
-		    strcmp(xattr+i, "system.posix_acl_default") == 0)
-			have_acl = 1;
-		else
-			have_xattr = 1;
-
-	static char buf[4];
-	char *c = buf;
-	if (have_cap)
-		*c++ = '#';
-	if (have_acl)
-		*c++ = '+';
-	if (have_xattr)
-		*c++ = '@';
-	*c = 0;
-
-	return buf;
-#else
-	return "";		// No support for xattrs on this platform.
-#endif
-}
-
 void
 print_format(struct fileinfo *fi)
 {