1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#define FOR_getprop
18#include "toys.h"
19
20#include <sys/system_properties.h>
21
22#include <selinux/android.h>
23#include <selinux/label.h>
24#include <selinux/selinux.h>
25
26GLOBALS(
27 size_t size;
28 char **nv;
29 struct selabel_handle *handle;
30)
31
32static char *get_property_context(const char *property)
33{
34 char *context = NULL;
35
36 if (selabel_lookup(TT.handle, &context, property, 1)) {
37 perror_exit("unable to lookup label for \"%s\"", property);
38 }
39 return context;
40}
41
42static void read_callback(void *unused, const char *name, const char *value,
43 unsigned serial)
44{
45 if (!(TT.size&31)) TT.nv = xrealloc(TT.nv, (TT.size+32)*2*sizeof(char *));
46
47 TT.nv[2*TT.size] = xstrdup((char *)name);
48 if (toys.optflags & FLAG_Z) {
49 TT.nv[1+2*TT.size++] = get_property_context(name);
50 } else {
51 TT.nv[1+2*TT.size++] = xstrdup((char *)value);
52 }
53}
54
55static void add_property(const prop_info *pi, void *unused)
56{
57 __system_property_read_callback(pi, read_callback, NULL);
58}
59
60static void print_callback(void *unused, const char *unused_name, const char *value,
61 unsigned unused_serial)
62{
63 puts(value);
64}
65
66
67static int selinux_log_callback_local(int type, const char *fmt, ...)
68{
69 va_list ap;
70
71 if (type == SELINUX_INFO) return 0;
72 va_start(ap, fmt);
73 verror_msg((char *)fmt, 0, ap);
74 va_end(ap);
75 return 0;
76}
77
78void getprop_main(void)
79{
80 if (toys.optflags & FLAG_Z) {
81 union selinux_callback cb;
82
83 cb.func_log = selinux_log_callback_local;
84 selinux_set_callback(SELINUX_CB_LOG, cb);
85 TT.handle = selinux_android_prop_context_handle();
86 if (!TT.handle) error_exit("unable to get selinux property context handle");
87 }
88
89 if (*toys.optargs) {
90 if (toys.optflags & FLAG_Z) {
91 char *context = get_property_context(*toys.optargs);
92
93 puts(context);
94 if (CFG_TOYBOX_FREE) free(context);
95 } else {
96 const prop_info* pi = __system_property_find(*toys.optargs);
97 if (pi == NULL) {
98 puts(toys.optargs[1] ? toys.optargs[1] : "");
99 } else {
100 __system_property_read_callback(pi, print_callback, NULL);
101 }
102 }
103 } else {
104 size_t i;
105
106 if (__system_property_foreach(add_property, NULL))
107 error_exit("property_list");
108 qsort(TT.nv, TT.size, 2*sizeof(char *), qstrcmp);
109 for (i = 0; i<TT.size; i++) printf("[%s]: [%s]\n", TT.nv[i*2],TT.nv[1+i*2]);
110 if (CFG_TOYBOX_FREE) {
111 for (i = 0; i<TT.size; i++) {
112 free(TT.nv[i*2]);
113 free(TT.nv[1+i*2]);
114 }
115 free(TT.nv);
116 }
117 }
118 if (CFG_TOYBOX_FREE && (toys.optflags & FLAG_Z)) selabel_close(TT.handle);
119}
120