xref: /third_party/toybox/toys/pending/getfattr.c (revision 0f66f451)
1/* getfattr.c - Read POSIX extended attributes.
2 *
3 * Copyright 2016 Android Open Source Project.
4 *
5 * No standard
6
7USE_GETFATTR(NEWTOY(getfattr, "(only-values)dhn:", TOYFLAG_USR|TOYFLAG_BIN))
8
9config GETFATTR
10  bool "getfattr"
11  default n
12  help
13    usage: getfattr [-d] [-h] [-n NAME] FILE...
14
15    Read POSIX extended attributes.
16
17    -d	Show values as well as names
18    -h	Do not dereference symbolic links
19    -n	Show only attributes with the given name
20    --only-values	Don't show names
21*/
22
23#define FOR_getfattr
24#include "toys.h"
25
26GLOBALS(
27  char *n;
28)
29
30// TODO: factor out the lister and getter loops and use them in cp too.
31static void do_getfattr(char *file)
32{
33  ssize_t (*getter)(const char *, const char *, void *, size_t) = getxattr;
34  ssize_t (*lister)(const char *, char *, size_t) = listxattr;
35  char **sorted_keys;
36  ssize_t keys_len;
37  char *keys, *key;
38  int i, key_count;
39
40  if (FLAG(h)) {
41    getter = lgetxattr;
42    lister = llistxattr;
43  }
44
45  // Collect the keys.
46  while ((keys_len = lister(file, NULL, 0))) {
47    if (keys_len == -1) perror_msg("listxattr failed");
48    keys = xmalloc(keys_len);
49    if (lister(file, keys, keys_len) == keys_len) break;
50    free(keys);
51  }
52
53  if (keys_len == 0) return;
54
55  // Sort the keys.
56  for (key = keys, key_count = 0; key-keys < keys_len; key += strlen(key)+1)
57    key_count++;
58  sorted_keys = xmalloc(key_count * sizeof(char *));
59  for (key = keys, i = 0; key-keys < keys_len; key += strlen(key)+1)
60    sorted_keys[i++] = key;
61  qsort(sorted_keys, key_count, sizeof(char *), qstrcmp);
62
63  if (!FLAG(only_values)) printf("# file: %s\n", file);
64
65  for (i = 0; i < key_count; i++) {
66    key = sorted_keys[i];
67
68    if (TT.n && strcmp(TT.n, key)) continue;
69
70    if (FLAG(d) || FLAG(only_values)) {
71      ssize_t value_len;
72      char *value = NULL;
73
74      while ((value_len = getter(file, key, NULL, 0))) {
75        if (value_len == -1) perror_msg("getxattr failed");
76        value = xzalloc(value_len+1);
77        if (getter(file, key, value, value_len) == value_len) break;
78        free(value);
79      }
80
81      if (FLAG(only_values)) {
82        if (value) printf("%s", value);
83      } else if (!value) puts(key);
84      else printf("%s=\"%s\"\n", key, value);
85      free(value);
86    } else puts(key); // Just list names.
87  }
88
89  if (!FLAG(only_values)) xputc('\n');
90  free(sorted_keys);
91}
92
93void getfattr_main(void)
94{
95  char **s;
96
97  for (s=toys.optargs; *s; s++) do_getfattr(*s);
98}
99