Add a listxattr tool for listing xattrs
Change-Id: Ib80bab2b605ce77cd8fdc717d8bcfa8085516679
diff --git a/attr/Android.mk b/attr/Android.mk
new file mode 100644
index 0000000..2986ab5
--- /dev/null
+++ b/attr/Android.mk
@@ -0,0 +1,22 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := listxattr.c
+LOCAL_CFLAGS := -c -W
+LOCAL_MODULE := listxattr
+LOCAL_MODULE_TAGS := eng
+LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
+LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
+LOCAL_PACK_MODULE_RELOCATIONS := false
+
+ifneq ($(TARGET_ARCH), arm64)
+ ifneq ($(TARGET_ARCH), x86_64)
+ LOCAL_LDFLAGS += -Wl,-dynamic-linker,/sbin/linker
+ else
+ LOCAL_LDFLAGS += -Wl,-dynamic-linker,/sbin/linker64
+ endif
+else
+ LOCAL_LDFLAGS += -Wl,-dynamic-linker,/sbin/linker64
+endif
+
+include $(BUILD_EXECUTABLE)
diff --git a/attr/listxattr.c b/attr/listxattr.c
new file mode 100644
index 0000000..1aa8e14
--- /dev/null
+++ b/attr/listxattr.c
@@ -0,0 +1,202 @@
+/****************************************************************************
+ | (C) Copyright 2008 Novell, Inc. All Rights Reserved.
+ |
+ | GPLv2: This program is free software; you can redistribute it
+ | and/or modify it under the terms of version 2 of the GNU General
+ | Public License as published by the Free Software Foundation.
+ |
+ | This program is distributed in the hope that it will be useful,
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ | GNU General Public License for more details.
+ +-------------------------------------------------------------------------*/
+/*
+ * NOTE from Dees_Troy: modified source to display values along with xattr names
+ * Below code comments about usage are no longer accurate but came from the
+ * original source code from the chromium project and combine features of
+ * listxattr and getfattr:
+ * https://chromium.googlesource.com/chromiumos/platform/punybench/+/factory-1235.B/file.m/listxattr.c
+ * https://chromium.googlesource.com/chromiumos/platform/punybench/+/factory-1235.B/file.m/getxattr.c
+ */
+/*
+ * LISTXATTR(2) Linux Programmer's Manual LISTXATTR(2)
+ *
+ *
+ *
+ * NAME
+ * listxattr, llistxattr, flistxattr - list extended attribute names
+ *
+ * SYNOPSIS
+ * #include <sys/types.h>
+ * #include <attr/xattr.h>
+ *
+ * ssize_t listxattr (const char *path,
+ * char *list, size_t size);
+ * ssize_t llistxattr (const char *path,
+ * char *list, size_t size);
+ * ssize_t flistxattr (int filedes,
+ * char *list, size_t size);
+ *
+ * DESCRIPTION
+ * Extended attributes are name:value pairs associated with inodes
+ * (files, directories, symlinks, etc). They are extensions to the
+ * normal attributes which are associated with all inodes in the sys-
+ * tem (i.e. the stat(2) data). A complete overview of extended
+ * attributes concepts can be found in attr(5).
+ *
+ * listxattr retrieves the list of extended attribute names associated
+ * with the given path in the filesystem. The list is the set of
+ * (NULL-terminated) names, one after the other. Names of extended
+ * attributes to which the calling process does not have access may be
+ * omitted from the list. The length of the attribute name list is
+ * returned.
+ *
+ * llistxattr is identical to listxattr, except in the case of a sym-
+ * bolic link, where the list of names of extended attributes associ-
+ * ated with the link itself is retrieved, not the file that it refers
+ * to.
+ *
+ * flistxattr is identical to listxattr, only the open file pointed to
+ * by filedes (as returned by open(2)) is interrogated in place of
+ * path.
+ *
+ * A single extended attribute name is a simple NULL-terminated
+ * string. The name includes a namespace prefix; there may be sev-
+ * eral, disjoint namespaces associated with an individual inode.
+ *
+ * An empty buffer of size zero can be passed into these calls to
+ * return the current size of the list of extended attribute names,
+ * which can be used to estimate the size of a buffer which is suffi-
+ * ciently large to hold the list of names.
+ *
+ * EXAMPLES
+ * The list of names is returned as an unordered array of NULL-termi-
+ * nated character strings (attribute names are separated by NULL
+ * characters), like this:
+ * user.name1\0system.name1\0user.name2\0
+ *
+ * Filesystems like ext2, ext3 and XFS which implement POSIX ACLs
+ * using extended attributes, might return a list like this:
+ * system.posix_acl_access\0system.posix_acl_default\0
+ *
+ * RETURN VALUE
+ * On success, a positive number is returned indicating the size of
+ * the extended attribute name list. On failure, -1 is returned and
+ * errno is set appropriately.
+ *
+ * If the size of the list buffer is too small to hold the result,
+ * errno is set to ERANGE.
+ *
+ * If extended attributes are not supported by the filesystem, or are
+ * disabled, errno is set to ENOTSUP.
+ *
+ * The errors documented for the stat(2) system call are also applica-
+ * ble here.
+ *
+ * AUTHORS
+ * Andreas Gruenbacher, <a.gruenbacher@computer.org> and the SGI XFS
+ * development team, <linux-xfs@oss.sgi.com>. Please send any bug
+ * reports or comments to these addresses.
+ *
+ * SEE ALSO
+ * getfattr(1), setfattr(1), getxattr(2), open(2), removexattr(2),
+ * setxattr(2), stat(2), attr(5)
+ *
+ *
+ *
+ * Dec 2001 Extended Attributes LISTXATTR(2)
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/xattr.h>
+//#include <eprintf.h>
+//#include <puny.h>
+
+/* dumpmem: dumps an n byte area of memory to screen */
+void dumpmem (const void *mem, unsigned int n)
+{
+ const char *c = mem;
+ unsigned i;
+ int all_text = 1;
+ if (n == 0) {
+ printf("<empty>");
+ return;
+ }
+ for (i = 0; i < n - 1; i++, c++) {
+ if (!isprint(*c)) {
+ all_text = 0;
+ break;
+ }
+ }
+ c = mem;
+ if (all_text) {
+ for (i = 0; i < n - 1; i++, c++) {
+ putchar(*c);
+ }
+ return;
+ } else {
+ char hex[(n * 2) + 1];
+ for(i = 0; i < n; i++, c++)
+ sprintf(hex + (i * 2), "%02X", *c);
+ hex[n] = 0;
+ printf("0x%s", hex);
+ return;
+ }
+}
+
+void dump_list (char *file, char *list, ssize_t size)
+{
+ int c;
+ int i;
+ int first = 1;
+ int j = 0;
+ char xattr[1024];
+ char value[1024];
+ ssize_t size2;
+ for (i = 0; i < size; i++) {
+ c = list[i];
+ if (c) {
+ if (first) {
+ putchar('\t');
+ first = 0;
+ j = 0;
+ }
+ putchar(c);
+ xattr[j++] = list[i];
+ } else {
+ xattr[j] = '\0';
+ size2 = getxattr(file, xattr, value, sizeof(value));
+ if (size2 < 0) {
+ printf("file=%s xattr=%s returned:", file, xattr);
+ } else {
+ putchar('=');
+ dumpmem(value, size2);
+ }
+ putchar('\n');
+ first = 1;
+ }
+ }
+}
+void usage (void)
+{
+ printf("listxattr <file>");
+}
+char List[1<<17];
+int main (int argc, char *argv[])
+{
+ ssize_t size;
+ if (argc < 2) {
+ usage();
+ exit(2);
+ }
+ size = listxattr(argv[1], List, sizeof(List));
+ if (size == -1) {
+ perror(argv[1]);
+ exit(2);
+ }
+ printf("xattrs for %s:\n", argv[1]);
+ dump_list(argv[1], List, size);
+ return 0;
+}