1/* getfattr.c - Read POSIX extended attributes. 2 * 3 * Copyright 2016 Android Open Source Project. 4 * 5 * No standard 6 7USE_GETFATTR(NEWTOY(getfattr, "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*/ 21 22#define FOR_getfattr 23#include "toys.h" 24 25GLOBALS( 26 char *n; 27) 28 29// TODO: factor out the lister and getter loops and use them in cp too. 30static void do_getfattr(char *file) 31{ 32 ssize_t (*getter)(const char *, const char *, void *, size_t) = getxattr; 33 ssize_t (*lister)(const char *, char *, size_t) = listxattr; 34 char **sorted_keys; 35 ssize_t keys_len; 36 char *keys, *key; 37 int i, key_count; 38 39 if (toys.optflags&FLAG_h) { 40 getter = lgetxattr; 41 lister = llistxattr; 42 } 43 44 // Collect the keys. 45 while ((keys_len = lister(file, NULL, 0))) { 46 if (keys_len == -1) perror_msg("listxattr failed"); 47 keys = xmalloc(keys_len); 48 if (lister(file, keys, keys_len) == keys_len) break; 49 free(keys); 50 } 51 52 if (keys_len == 0) return; 53 54 // Sort the keys. 55 for (key = keys, key_count = 0; key-keys < keys_len; key += strlen(key)+1) 56 key_count++; 57 sorted_keys = xmalloc(key_count * sizeof(char *)); 58 for (key = keys, i = 0; key-keys < keys_len; key += strlen(key)+1) 59 sorted_keys[i++] = key; 60 qsort(sorted_keys, key_count, sizeof(char *), qstrcmp); 61 62 printf("# file: %s\n", file); 63 64 for (i = 0; i < key_count; i++) { 65 key = sorted_keys[i]; 66 67 if (TT.n && strcmp(TT.n, key)) continue; 68 69 if (toys.optflags&FLAG_d) { 70 ssize_t value_len; 71 char *value = NULL; 72 73 while ((value_len = getter(file, key, NULL, 0))) { 74 if (value_len == -1) perror_msg("getxattr failed"); 75 value = xzalloc(value_len+1); 76 if (getter(file, key, value, value_len) == value_len) break; 77 free(value); 78 } 79 80 if (!value) puts(key); 81 else printf("%s=\"%s\"\n", key, value); 82 free(value); 83 } else puts(key); // Just list names. 84 } 85 86 xputc('\n'); 87 free(sorted_keys); 88} 89 90void getfattr_main(void) 91{ 92 char **s; 93 94 for (s=toys.optargs; *s; s++) do_getfattr(*s); 95} 96