You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.4 KiB
99 lines
2.4 KiB
4 months ago
|
/* getfattr.c - Read POSIX extended attributes.
|
||
|
*
|
||
|
* Copyright 2016 Android Open Source Project.
|
||
|
*
|
||
|
* No standard
|
||
|
|
||
|
USE_GETFATTR(NEWTOY(getfattr, "(only-values)dhn:", TOYFLAG_USR|TOYFLAG_BIN))
|
||
|
|
||
|
config GETFATTR
|
||
|
bool "getfattr"
|
||
|
default n
|
||
|
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
|
||
|
--only-values Don't show names
|
||
|
*/
|
||
|
|
||
|
#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 (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);
|
||
|
|
||
|
if (!FLAG(only_values)) 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 (FLAG(d) || FLAG(only_values)) {
|
||
|
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 (FLAG(only_values)) {
|
||
|
if (value) printf("%s", value);
|
||
|
} else if (!value) puts(key);
|
||
|
else printf("%s=\"%s\"\n", key, value);
|
||
|
free(value);
|
||
|
} else puts(key); // Just list names.
|
||
|
}
|
||
|
|
||
|
if (!FLAG(only_values)) xputc('\n');
|
||
|
free(sorted_keys);
|
||
|
}
|
||
|
|
||
|
void getfattr_main(void)
|
||
|
{
|
||
|
char **s;
|
||
|
|
||
|
for (s=toys.optargs; *s; s++) do_getfattr(*s);
|
||
|
}
|