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