Home | History | Annotate | Download | only in pending
      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, "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 */
     21 
     22 #define FOR_getfattr
     23 #include "toys.h"
     24 
     25 GLOBALS(
     26   char *n;
     27 )
     28 
     29 // TODO: factor out the lister and getter loops and use them in cp too.
     30 static 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 
     90 void getfattr_main(void)
     91 {
     92   char **s;
     93 
     94   for (s=toys.optargs; *s; s++) do_getfattr(*s);
     95 }
     96