Home | History | Annotate | Download | only in android
      1 /* getprop.c - Get an Android system property
      2  *
      3  * Copyright 2015 The Android Open Source Project
      4 
      5 USE_GETPROP(NEWTOY(getprop, ">2Z", TOYFLAG_USR|TOYFLAG_SBIN))
      6 
      7 config GETPROP
      8   bool "getprop"
      9   default y
     10   depends on TOYBOX_ON_ANDROID
     11   help
     12     usage: getprop [NAME [DEFAULT]]
     13 
     14     Gets an Android system property, or lists them all.
     15 */
     16 
     17 #define FOR_getprop
     18 #include "toys.h"
     19 
     20 #if defined(__ANDROID__)
     21 
     22 #include <cutils/properties.h>
     23 
     24 #include <selinux/android.h>
     25 #include <selinux/label.h>
     26 #include <selinux/selinux.h>
     27 
     28 GLOBALS(
     29   size_t size;
     30   char **nv; // name/value pairs: even=name, odd=value
     31   struct selabel_handle *handle;
     32 )
     33 
     34 static char *get_property_context(char *property)
     35 {
     36   char *context = NULL;
     37 
     38   if (selabel_lookup(TT.handle, &context, property, 1)) {
     39     perror_exit("unable to lookup label for \"%s\"", property);
     40   }
     41   return context;
     42 }
     43 
     44 static void add_property(char *name, char *value, void *unused)
     45 {
     46   if (!(TT.size&31)) TT.nv = xrealloc(TT.nv, (TT.size+32)*2*sizeof(char *));
     47 
     48   TT.nv[2*TT.size] = xstrdup(name);
     49   if (toys.optflags & FLAG_Z) {
     50     TT.nv[1+2*TT.size++] = get_property_context(name);
     51   } else {
     52     TT.nv[1+2*TT.size++] = xstrdup(value);
     53   }
     54 }
     55 
     56 // Needed to supress extraneous "Loaded property_contexts from" message
     57 int selinux_log_callback(int type, const char *fmt, ...) {
     58   va_list ap;
     59 
     60   if (type == SELINUX_INFO) return 0;
     61   va_start(ap, fmt);
     62   verror_msg(fmt, 0, ap);
     63   va_end(ap);
     64   return 0;
     65 }
     66 
     67 void getprop_main(void)
     68 {
     69   if (toys.optflags & FLAG_Z) {
     70     union selinux_callback cb;
     71 
     72     cb.func_log = selinux_log_callback;
     73     selinux_set_callback(SELINUX_CB_LOG, cb);
     74     TT.handle = selinux_android_prop_context_handle();
     75     if (!TT.handle) error_exit("unable to get selinux property context handle");
     76   }
     77 
     78   if (*toys.optargs) {
     79     if (toys.optflags & FLAG_Z) {
     80       char *context = get_property_context(*toys.optargs);
     81 
     82       puts(context);
     83       if (CFG_TOYBOX_FREE) free(context);
     84     } else {
     85       property_get(*toys.optargs, toybuf, toys.optargs[1] ? toys.optargs[1] : "");
     86       puts(toybuf);
     87     }
     88   } else {
     89     size_t i;
     90 
     91     if (property_list((void *)add_property, 0)) error_exit("property_list");
     92     qsort(TT.nv, TT.size, 2*sizeof(char *), qstrcmp);
     93     for (i = 0; i<TT.size; i++) printf("[%s]: [%s]\n", TT.nv[i*2],TT.nv[1+i*2]);
     94     if (CFG_TOYBOX_FREE) {
     95       for (i = 0; i<TT.size; i++) {
     96         free(TT.nv[i*2]);
     97         free(TT.nv[1+i*2]);
     98       }
     99       free(TT.nv);
    100     }
    101   }
    102   if (CFG_TOYBOX_FREE && (toys.optflags & FLAG_Z)) selabel_close(TT.handle);
    103 }
    104 
    105 #else
    106 
    107 void getprop_main(void)
    108 {
    109 }
    110 
    111 #endif
    112