summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYU Jincheng2023-07-07 16:44:24 +0800
committerDenys Vlasenko2023-07-16 14:40:44 +0200
commitcf809e2f2dbf699035e4841e45070b947374a989 (patch)
tree503210533acc670cf2628a31a4585bd48b3f1198
parentab755f492599cf595d532f0f240a14c6e5caa435 (diff)
downloadbusybox-cf809e2f2dbf699035e4841e45070b947374a989.zip
busybox-cf809e2f2dbf699035e4841e45070b947374a989.tar.gz
getfattr: new applet
function old new delta getfattr_main - 309 +309 print_attr - 115 +115 packed_usage 34576 34631 +55 .rodata 105349 105395 +46 lgetxattr - 41 +41 getxattr - 41 +41 llistxattr - 35 +35 listxattr - 35 +35 applet_names 2806 2815 +9 applet_main 1620 1624 +4 ------------------------------------------------------------------------------ (add/remove: 7/0 grow/shrink: 4/0 up/down: 690/0) Total: 690 bytes Signed-off-by: YU Jincheng <shana@zju.edu.cn> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/getfattr.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/miscutils/getfattr.c b/miscutils/getfattr.c
new file mode 100644
index 0000000..59b6f6b
--- /dev/null
+++ b/miscutils/getfattr.c
@@ -0,0 +1,131 @@
+/*
+ * getfattr - get extended attributes of filesystem objects.
+ *
+ * Copyright (C) 2023 by LoveSy <lovesykun@gmail.com>
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+//config:config GETFATTR
+//config: bool "getfattr (12.3 kb)"
+//config: default y
+//config: help
+//config: Get extended attributes on files
+
+//applet:IF_GETFATTR(APPLET_NOEXEC(getfattr, getfattr, BB_DIR_USR_BIN, BB_SUID_DROP, getfattr))
+
+//kbuild:lib-$(CONFIG_GETFATTR) += getfattr.o
+
+#include <stdio.h>
+#include <sys/xattr.h>
+#include "libbb.h"
+
+//usage:#define getfattr_trivial_usage
+//usage: "[-h] {-d|-n ATTR} FILE...\n"
+//usage:#define getfattr_full_usage "\n\n"
+//usage: "Get extended attributes"
+//usage: "\n"
+//usage: "\n -h Do not follow symlinks"
+//usage: "\n -d Dump all attributes"
+//usage: "\n -n ATTR Get attribute ATTR"
+
+enum {
+ OPT_h = (1 << 0),
+ OPT_d = (1 << 1),
+};
+
+static int print_attr(const char *file, const char *name, char **buf, size_t *bufsize)
+{
+ ssize_t len;
+
+ if (*bufsize == 0)
+ goto grow;
+ again:
+ len = ((option_mask32 & OPT_h) ? lgetxattr: getxattr)(file, name, *buf, *bufsize);
+ if (len < 0) {
+ if (errno != ERANGE)
+ return len;
+ grow:
+ *bufsize = (*bufsize * 2) + 1024;
+ *buf = xrealloc(*buf, *bufsize);
+ goto again;
+ }
+ printf("%s=\"%.*s\"\n", name, len, *buf);
+ return 0;
+}
+
+static ssize_t list_attr(const char *file, char **list, size_t *listsize)
+{
+ ssize_t len;
+
+ if (*listsize == 0)
+ goto grow;
+ again:
+ len = ((option_mask32 & OPT_h) ? llistxattr : listxattr)(file, *list, *listsize);
+ if (len < 0) {
+ if (errno != ERANGE)
+ return len;
+ grow:
+ *listsize = (*listsize * 2) + 1024;
+ *list = xrealloc(*list, *listsize);
+ goto again;
+ }
+ return len;
+}
+
+int getfattr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int getfattr_main(int argc UNUSED_PARAM, char **argv)
+{
+ const char *name;
+ int status;
+ int opt;
+ char *buf = NULL;
+ size_t bufsize = 0;
+ char *list = NULL;
+ size_t listsize = 0;
+
+ opt = getopt32(argv, "^"
+ "hdn:"
+ /* Min one arg; exactly one of -n or -d is required. */
+ "\0" "-1:d:n:n--d:d--n"
+ , &name
+ );
+ argv += optind;
+ status = EXIT_SUCCESS;
+
+ do {
+ int r;
+ if (opt & OPT_d) {
+ ssize_t len = list_attr(*argv, &list, &listsize);
+ if (len > 0) {
+ char *key;
+ printf("# file: %s\n", *argv);
+ key = list;
+ while (len > 0) {
+ ssize_t keylen;
+ r = print_attr(*argv, key, &buf, &bufsize);
+ if (r)
+ goto err;
+ keylen = strlen(key) + 1;
+ key += keylen;
+ len -= keylen;
+ }
+ bb_putchar('\n');
+ }
+ } else {
+ printf("# file: %s\n", *argv);
+ r = print_attr(*argv, name, &buf, &bufsize);
+ if (r) {
+ err:
+ bb_simple_perror_msg(*argv);
+ status = EXIT_FAILURE;
+ // continue; maybe?
+ }
+ bb_putchar('\n');
+ }
+ } while (*++argv);
+
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(buf);
+
+ fflush_stdout_and_exit(status);
+}