toybox/toys/pending/getfattr.c
<<
>>
Prefs
   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