• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* getfattr.c - Read POSIX extended attributes.
2  *
3  * Copyright 2016 Android Open Source Project.
4  *
5  * No standard
6 
7 USE_GETFATTR(NEWTOY(getfattr, "(only-values)dhn:", TOYFLAG_USR|TOYFLAG_BIN))
8 
9 config 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 
GLOBALS(char * n;)26 GLOBALS(
27   char *n;
28 )
29 
30 // TODO: factor out the lister and getter loops and use them in cp too.
31 static 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 
getfattr_main(void)93 void getfattr_main(void)
94 {
95   char **s;
96 
97   for (s=toys.optargs; *s; s++) do_getfattr(*s);
98 }
99