aboutsummaryrefslogtreecommitdiff
path: root/toys/pending/getfattr.c
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2016-07-17 10:42:31 -0700
committerRob Landley <rob@landley.net>2016-07-18 14:14:22 -0500
commitbd471f67cc6eff4abf47f027edbace707065bc6b (patch)
tree2c7e2c3edcca3a588b650d33c115d9335c09b163 /toys/pending/getfattr.c
parent48ea55969907286d1a125fcd655be9d8307a3449 (diff)
downloadtoybox-bd471f67cc6eff4abf47f027edbace707065bc6b.tar.gz
Add getfattr(1) and setfattr(1).
Plus basic tests.
Diffstat (limited to 'toys/pending/getfattr.c')
-rw-r--r--toys/pending/getfattr.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/toys/pending/getfattr.c b/toys/pending/getfattr.c
new file mode 100644
index 00000000..efec53a8
--- /dev/null
+++ b/toys/pending/getfattr.c
@@ -0,0 +1,95 @@
+/* getfattr.c - Read POSIX extended attributes.
+ *
+ * Copyright 2016 Android Open Source Project.
+ *
+ * No standard
+
+USE_GETFATTR(NEWTOY(getfattr, "dhn:", TOYFLAG_USR|TOYFLAG_BIN))
+
+config GETFATTR
+ bool "getfattr"
+ default y
+ help
+ usage: getfattr [-d] [-h] [-n NAME] FILE...
+
+ Read POSIX extended attributes.
+
+ -d Show values as well as names.
+ -h Do not dereference symbolic links.
+ -n Show only attributes with the given name.
+*/
+
+#define FOR_getfattr
+#include "toys.h"
+
+GLOBALS(
+ char *n;
+)
+
+// TODO: factor out the lister and getter loops and use them in cp too.
+static void do_getfattr(char *file)
+{
+ ssize_t (*getter)(const char *, const char *, void *, size_t) = getxattr;
+ ssize_t (*lister)(const char *, char *, size_t) = listxattr;
+ char **sorted_keys;
+ ssize_t keys_len;
+ char *keys, *key;
+ int i, key_count;
+
+ if (toys.optflags&FLAG_h) {
+ getter = lgetxattr;
+ lister = llistxattr;
+ }
+
+ // Collect the keys.
+ while ((keys_len = lister(file, NULL, 0))) {
+ if (keys_len == -1) perror_msg("listxattr failed");
+ keys = xmalloc(keys_len);
+ if (lister(file, keys, keys_len) == keys_len) break;
+ free(keys);
+ }
+
+ if (keys_len == 0) return;
+
+ // Sort the keys.
+ for (key = keys, key_count = 0; key-keys < keys_len; key += strlen(key)+1)
+ key_count++;
+ sorted_keys = xmalloc(key_count * sizeof(char *));
+ for (key = keys, i = 0; key-keys < keys_len; key += strlen(key)+1)
+ sorted_keys[i++] = key;
+ qsort(sorted_keys, key_count, sizeof(char *), qstrcmp);
+
+ printf("# file: %s\n", file);
+
+ for (i = 0; i < key_count; i++) {
+ key = sorted_keys[i];
+
+ if (TT.n && strcmp(TT.n, key)) continue;
+
+ if (toys.optflags&FLAG_d) {
+ ssize_t value_len;
+ char *value = NULL;
+
+ while ((value_len = getter(file, key, NULL, 0))) {
+ if (value_len == -1) perror_msg("getxattr failed");
+ value = xzalloc(value_len+1);
+ if (getter(file, key, value, value_len) == value_len) break;
+ free(value);
+ }
+
+ if (!value) puts(key);
+ else printf("%s=\"%s\"\n", key, value);
+ free(value);
+ } else puts(key); // Just list names.
+ }
+
+ xputc('\n');
+ free(sorted_keys);
+}
+
+void getfattr_main(void)
+{
+ char **s;
+
+ for (s=toys.optargs; *s; s++) do_getfattr(*s);
+}