• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GLOBALS(size_t size;char ** nv;struct selabel_handle * handle;)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 
add_property(char * name,char * value,void * unused)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
selinux_log_callback(int type,const char * fmt,...)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 
getprop_main(void)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 
getprop_main(void)107 void getprop_main(void)
108 {
109 }
110 
111 #endif
112