Plus basic tests.
---
 tests/getfattr.test     | 21 +++++++++++
 tests/setfattr.test     | 21 +++++++++++
 toys/pending/getfattr.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++
 toys/pending/setfattr.c | 56 +++++++++++++++++++++++++++++
 4 files changed, 193 insertions(+)
 create mode 100755 tests/getfattr.test
 create mode 100755 tests/setfattr.test
 create mode 100644 toys/pending/getfattr.c
 create mode 100644 toys/pending/setfattr.c
From 1e190af90c732cfad2316ca03220af0b9b8d47b9 Mon Sep 17 00:00:00 2001
From: Elliott Hughes <[email protected]>
Date: Sun, 17 Jul 2016 10:42:31 -0700
Subject: [PATCH] Add getfattr(1) and setfattr(1).

Plus basic tests.
---
 tests/getfattr.test     | 21 +++++++++++
 tests/setfattr.test     | 21 +++++++++++
 toys/pending/getfattr.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++
 toys/pending/setfattr.c | 56 +++++++++++++++++++++++++++++
 4 files changed, 193 insertions(+)
 create mode 100755 tests/getfattr.test
 create mode 100755 tests/setfattr.test
 create mode 100644 toys/pending/getfattr.c
 create mode 100644 toys/pending/setfattr.c

diff --git a/tests/getfattr.test b/tests/getfattr.test
new file mode 100755
index 0000000..cb0f947
--- /dev/null
+++ b/tests/getfattr.test
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+[ -f testing.sh ] && . testing.sh
+
+#testing "name" "command" "result" "infile" "stdin"
+
+mkdir attrs
+touch attrs/file
+setfattr -n user.empty attrs/file
+setfattr -n user.data -v hello attrs/file
+
+testing "" "getfattr attrs/file" \
+    "# file: attrs/file\nuser.data\nuser.empty\n\n" "" ""
+testing "-d" "getfattr -d attrs/file" \
+    "# file: attrs/file\nuser.data=\"hello\"\nuser.empty\n\n" "" ""
+testing "-n" "getfattr -n user.empty attrs/file" \
+    "# file: attrs/file\nuser.empty\n\n" "" ""
+testing "-d -n" "getfattr -d -n user.data attrs/file" \
+    "# file: attrs/file\nuser.data=\"hello\"\n\n" "" ""
+
+rm -rf attrs
diff --git a/tests/setfattr.test b/tests/setfattr.test
new file mode 100755
index 0000000..6a044ea
--- /dev/null
+++ b/tests/setfattr.test
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+[ -f testing.sh ] && . testing.sh
+
+#testing "name" "command" "result" "infile" "stdin"
+
+mkdir attrs
+touch attrs/file
+setfattr -n user.empty attrs/file
+setfattr -n user.data -v hello attrs/file
+setfattr -n user.delete-me -v hello attrs/file
+
+testing "-x" \
+    "setfattr -x user.delete-me attrs/file && getfattr attrs/file" \
+    "# file: attrs/file\nuser.data\nuser.empty\n\n" "" ""
+testing "-n" "setfattr -n user.new attrs/file && getfattr -d attrs/file" \
+    "# file: attrs/file\nuser.data=\"hello\"\nuser.empty\nuser.new\n\n" "" ""
+testing "-n -v" "setfattr -n user.new -v data attrs/file && getfattr -d attrs/file" \
+    "# file: attrs/file\nuser.data=\"hello\"\nuser.empty\nuser.new=\"data\"\n\n" "" ""
+
+rm -rf attrs
diff --git a/toys/pending/getfattr.c b/toys/pending/getfattr.c
new file mode 100644
index 0000000..efec53a
--- /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);
+}
diff --git a/toys/pending/setfattr.c b/toys/pending/setfattr.c
new file mode 100644
index 0000000..9f17ce0
--- /dev/null
+++ b/toys/pending/setfattr.c
@@ -0,0 +1,56 @@
+/* setfattr.c - Write POSIX extended attributes.
+ *
+ * Copyright 2016 Android Open Source Project.
+ *
+ * No standard
+
+USE_SETFATTR(NEWTOY(setfattr, "hn:v:x:[!xv]", TOYFLAG_USR|TOYFLAG_BIN))
+
+config SETFATTR
+  bool "setfattr"
+  default y
+  help
+    usage: setfattr [-h] -n NAME [-v VALUE] FILE...
+    usage: setfattr [-h] -x NAME FILE...
+
+    Write POSIX extended attributes.
+
+    -h	Do not dereference symbolic links.
+    -n	Set value of given attribute.
+    -x	Remove value of given attribute.
+    -v	Value to use with -n (default is empty).
+*/
+
+#define FOR_setfattr
+#include "toys.h"
+
+GLOBALS(
+  char *x, *v, *n;
+)
+
+static void do_setfattr(char *file)
+{
+  int (*setter)(const char *, const char *, const void *, size_t, int) =
+      setxattr;
+  int (*remover)(const char *, const char *) = removexattr;
+
+  if (toys.optflags&FLAG_h) {
+    setter = lsetxattr;
+    remover = lremovexattr;
+  }
+
+  if (toys.optflags&FLAG_x) {
+    if (remover(file, TT.x)) perror_msg("removexattr failed");
+  } else {
+    if (setter(file, TT.n, TT.v, TT.v ? strlen(TT.v) : 0, 0))
+      perror_msg("setxattr failed");
+  }
+}
+
+void setfattr_main(void)
+{
+  char **s;
+
+  if (!(toys.optflags&(FLAG_n|FLAG_x))) error_exit("need 'n' or 'x'");
+  for (s=toys.optargs; *s; s++) do_setfattr(*s);
+}
-- 
2.8.0.rc3.226.g39d4020

_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to