getfattr.c 2.4 KB

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