1*e4a36f41SAndroid Build Coastguard Worker #include <getopt.h>
2*e4a36f41SAndroid Build Coastguard Worker
3*e4a36f41SAndroid Build Coastguard Worker #include "attribute.h"
4*e4a36f41SAndroid Build Coastguard Worker
attribute_usage()5*e4a36f41SAndroid Build Coastguard Worker void attribute_usage() {
6*e4a36f41SAndroid Build Coastguard Worker fprintf(stderr, "\tattribute [-l|--list] [-r|--reverse] <name>\n");
7*e4a36f41SAndroid Build Coastguard Worker }
8*e4a36f41SAndroid Build Coastguard Worker
retrieve_mapping(policydb_t * policydb,struct type_datum * dat,char * name,int reverse)9*e4a36f41SAndroid Build Coastguard Worker static void retrieve_mapping(policydb_t *policydb, struct type_datum *dat, char *name, int reverse) {
10*e4a36f41SAndroid Build Coastguard Worker struct ebitmap_node *n;
11*e4a36f41SAndroid Build Coastguard Worker unsigned int bit;
12*e4a36f41SAndroid Build Coastguard Worker
13*e4a36f41SAndroid Build Coastguard Worker if (reverse) {
14*e4a36f41SAndroid Build Coastguard Worker ebitmap_for_each_bit(&policydb->type_attr_map[dat->s.value - 1], n, bit) {
15*e4a36f41SAndroid Build Coastguard Worker if (!ebitmap_node_get_bit(n, bit))
16*e4a36f41SAndroid Build Coastguard Worker continue;
17*e4a36f41SAndroid Build Coastguard Worker if (!strcmp(policydb->p_type_val_to_name[bit], name))
18*e4a36f41SAndroid Build Coastguard Worker continue;
19*e4a36f41SAndroid Build Coastguard Worker printf("%s\n", policydb->p_type_val_to_name[bit]);
20*e4a36f41SAndroid Build Coastguard Worker }
21*e4a36f41SAndroid Build Coastguard Worker } else {
22*e4a36f41SAndroid Build Coastguard Worker ebitmap_for_each_bit(&policydb->attr_type_map[dat->s.value - 1], n, bit) {
23*e4a36f41SAndroid Build Coastguard Worker if (!ebitmap_node_get_bit(n, bit))
24*e4a36f41SAndroid Build Coastguard Worker continue;
25*e4a36f41SAndroid Build Coastguard Worker printf("%s\n", policydb->p_type_val_to_name[bit]);
26*e4a36f41SAndroid Build Coastguard Worker }
27*e4a36f41SAndroid Build Coastguard Worker }
28*e4a36f41SAndroid Build Coastguard Worker }
29*e4a36f41SAndroid Build Coastguard Worker
list_attribute(policydb_t * policydb,char * name,int reverse)30*e4a36f41SAndroid Build Coastguard Worker static int list_attribute(policydb_t *policydb, char *name, int reverse)
31*e4a36f41SAndroid Build Coastguard Worker {
32*e4a36f41SAndroid Build Coastguard Worker struct type_datum *dat;
33*e4a36f41SAndroid Build Coastguard Worker
34*e4a36f41SAndroid Build Coastguard Worker dat = hashtab_search(policydb->p_types.table, name);
35*e4a36f41SAndroid Build Coastguard Worker if (!dat) {
36*e4a36f41SAndroid Build Coastguard Worker fprintf(stderr, "%s is not defined in this policy.\n", name);
37*e4a36f41SAndroid Build Coastguard Worker return -1;
38*e4a36f41SAndroid Build Coastguard Worker }
39*e4a36f41SAndroid Build Coastguard Worker
40*e4a36f41SAndroid Build Coastguard Worker if (reverse) {
41*e4a36f41SAndroid Build Coastguard Worker if (dat->flavor != TYPE_TYPE) {
42*e4a36f41SAndroid Build Coastguard Worker fprintf(stderr, "%s is an attribute not a type in this policy.\n", name);
43*e4a36f41SAndroid Build Coastguard Worker return -1;
44*e4a36f41SAndroid Build Coastguard Worker }
45*e4a36f41SAndroid Build Coastguard Worker } else {
46*e4a36f41SAndroid Build Coastguard Worker if (dat->flavor != TYPE_ATTRIB) {
47*e4a36f41SAndroid Build Coastguard Worker fprintf(stderr, "%s is a type not an attribute in this policy.\n", name);
48*e4a36f41SAndroid Build Coastguard Worker return -1;
49*e4a36f41SAndroid Build Coastguard Worker }
50*e4a36f41SAndroid Build Coastguard Worker }
51*e4a36f41SAndroid Build Coastguard Worker retrieve_mapping(policydb, dat, name, reverse);
52*e4a36f41SAndroid Build Coastguard Worker
53*e4a36f41SAndroid Build Coastguard Worker return 0;
54*e4a36f41SAndroid Build Coastguard Worker }
55*e4a36f41SAndroid Build Coastguard Worker
print_attr(hashtab_key_t k,hashtab_datum_t d,void * args)56*e4a36f41SAndroid Build Coastguard Worker static int print_attr(__attribute__ ((unused)) hashtab_key_t k,
57*e4a36f41SAndroid Build Coastguard Worker hashtab_datum_t d, void *args) {
58*e4a36f41SAndroid Build Coastguard Worker struct type_datum *dat = (struct type_datum *)d;
59*e4a36f41SAndroid Build Coastguard Worker policydb_t *pdb = (policydb_t *)args;
60*e4a36f41SAndroid Build Coastguard Worker if (!dat) {
61*e4a36f41SAndroid Build Coastguard Worker fprintf(stderr, "type encountered without datum!\n");
62*e4a36f41SAndroid Build Coastguard Worker return -1;
63*e4a36f41SAndroid Build Coastguard Worker }
64*e4a36f41SAndroid Build Coastguard Worker if (dat->flavor == TYPE_ATTRIB) {
65*e4a36f41SAndroid Build Coastguard Worker printf("%s\n", pdb->p_type_val_to_name[dat->s.value - 1]);
66*e4a36f41SAndroid Build Coastguard Worker }
67*e4a36f41SAndroid Build Coastguard Worker return 0;
68*e4a36f41SAndroid Build Coastguard Worker }
69*e4a36f41SAndroid Build Coastguard Worker
list_all_attributes(policydb_t * policydb)70*e4a36f41SAndroid Build Coastguard Worker static int list_all_attributes(policydb_t *policydb) {
71*e4a36f41SAndroid Build Coastguard Worker return hashtab_map(policydb->p_types.table, print_attr, policydb);
72*e4a36f41SAndroid Build Coastguard Worker }
73*e4a36f41SAndroid Build Coastguard Worker
attribute_func(int argc,char ** argv,policydb_t * policydb)74*e4a36f41SAndroid Build Coastguard Worker int attribute_func (int argc, char **argv, policydb_t *policydb) {
75*e4a36f41SAndroid Build Coastguard Worker int rc = -1;
76*e4a36f41SAndroid Build Coastguard Worker int list = 0;
77*e4a36f41SAndroid Build Coastguard Worker int reverse = 0;
78*e4a36f41SAndroid Build Coastguard Worker char ch;
79*e4a36f41SAndroid Build Coastguard Worker
80*e4a36f41SAndroid Build Coastguard Worker struct option attribute_options[] = {
81*e4a36f41SAndroid Build Coastguard Worker {"list", no_argument, NULL, 'l'},
82*e4a36f41SAndroid Build Coastguard Worker {"reverse", no_argument, NULL, 'r'},
83*e4a36f41SAndroid Build Coastguard Worker {NULL, 0, NULL, 0}
84*e4a36f41SAndroid Build Coastguard Worker };
85*e4a36f41SAndroid Build Coastguard Worker
86*e4a36f41SAndroid Build Coastguard Worker while ((ch = getopt_long(argc, argv, "lr", attribute_options, NULL)) != -1) {
87*e4a36f41SAndroid Build Coastguard Worker switch (ch) {
88*e4a36f41SAndroid Build Coastguard Worker case 'l':
89*e4a36f41SAndroid Build Coastguard Worker list = 1;
90*e4a36f41SAndroid Build Coastguard Worker break;
91*e4a36f41SAndroid Build Coastguard Worker case 'r':
92*e4a36f41SAndroid Build Coastguard Worker reverse = 1;
93*e4a36f41SAndroid Build Coastguard Worker break;
94*e4a36f41SAndroid Build Coastguard Worker default:
95*e4a36f41SAndroid Build Coastguard Worker USAGE_ERROR = true;
96*e4a36f41SAndroid Build Coastguard Worker goto out;
97*e4a36f41SAndroid Build Coastguard Worker }
98*e4a36f41SAndroid Build Coastguard Worker }
99*e4a36f41SAndroid Build Coastguard Worker
100*e4a36f41SAndroid Build Coastguard Worker if ((argc != 2 && !(reverse && argc == 3)) || (list && reverse)) {
101*e4a36f41SAndroid Build Coastguard Worker USAGE_ERROR = true;
102*e4a36f41SAndroid Build Coastguard Worker goto out;
103*e4a36f41SAndroid Build Coastguard Worker }
104*e4a36f41SAndroid Build Coastguard Worker if (list)
105*e4a36f41SAndroid Build Coastguard Worker rc = list_all_attributes(policydb);
106*e4a36f41SAndroid Build Coastguard Worker else
107*e4a36f41SAndroid Build Coastguard Worker rc = list_attribute(policydb, argv[optind], reverse);
108*e4a36f41SAndroid Build Coastguard Worker out:
109*e4a36f41SAndroid Build Coastguard Worker return rc;
110*e4a36f41SAndroid Build Coastguard Worker }
111