9dabdd0322548dfa8821ca94feec3ea0af9fc74d
[src/app-framework-main.git] / src / wgtpkg-permissions.c
1 /*
2  Copyright 2015 IoT.bzh
3
4  author: José Bollo <jose.bollo@iot.bzh>
5
6  Licensed under the Apache License, Version 2.0 (the "License");
7  you may not use this file except in compliance with the License.
8  You may obtain a copy of the License at
9
10      http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  See the License for the specific language governing permissions and
16  limitations under the License.
17 */
18
19 #define _GNU_SOURCE
20
21 #include <errno.h>
22 #include <string.h>
23
24 #include "verbose.h"
25 #include "wgtpkg.h"
26
27 struct permission {
28         char *name;
29         unsigned granted: 1;
30         unsigned requested: 1;
31         unsigned level: 3;
32 };
33
34 static const char prefix_of_permissions[] = FWK_PREFIX_PERMISSION;
35
36 static int nrpermissions = 0;
37 static struct permission *permissions = NULL;
38 static int indexiter = 0;
39
40 /* check is the name has the correct prefix for permissions */
41 int is_standard_permission(const char *name)
42 {
43         return 0 == memcmp(name, prefix_of_permissions, sizeof(prefix_of_permissions) - 1);
44 }
45
46 /* retrieves the permission of name */
47 static struct permission *get_permission(const char *name)
48 {
49         int i;
50
51         for (i = 0 ; i < nrpermissions ; i++)
52                 if (0 == strcmp(permissions[i].name, name))
53                         return permissions+i;
54         return NULL;
55 }
56
57 /* add a permission of name */
58 static struct permission *add_permission(const char *name)
59 {
60         struct permission *p = get_permission(name);
61         if (!p) {
62                 p = realloc(permissions, ((nrpermissions + 8) & ~7) * sizeof(*p));
63                 if (p) {
64                         permissions = p;
65                         p = permissions + nrpermissions;
66                         memset(p, 0, sizeof(*p));
67                         p->name = strdup(name);
68                         if (!p->name)
69                                 p = NULL;
70                 }
71         }
72         return p;
73 }
74
75 /* remove any granting */
76 void reset_permissions()
77 {
78         int i;
79         for (i = 0 ; i < nrpermissions ; i++)
80                 permissions[i].granted = 0;
81 }
82
83 /* remove any granting */
84 void crop_permissions(unsigned level)
85 {
86         int i;
87         for (i = 0 ; i < nrpermissions ; i++)
88                 if (permissions[i].level < level)
89                         permissions[i].granted = 0;
90 }
91
92 /* add permissions granted for installation */
93 void grant_permission_list(const char *list)
94 {
95         struct permission *p;
96         char *iter, c;
97         int n;
98         static const char separators[] = " \t\n\r,";
99
100         iter = strdupa(list);
101         iter += strspn(iter, separators);
102         while(*iter) {
103                 n = strcspn(iter, separators);
104                 c = iter[n];
105                 iter[n] = 0;
106                 p = add_permission(iter);
107                 if (!p) {
108                         ERROR("Can't allocate permission");
109                         exit(1);
110                 }
111                 p->granted = 1;
112                 iter += n;
113                 *iter =c;
114                 iter += strspn(iter, separators);
115         }
116 }
117
118 /* checks if the permission 'name' is recorded */
119 int permission_exists(const char *name)
120 {
121         return !!get_permission(name);
122 }
123
124 /* request the permission, returns 1 if granted or 0 otherwise */
125 int request_permission(const char *name)
126 {
127         struct permission *p = get_permission(name);
128         if (p) {
129                 p->requested = 1;
130                 if (p->granted)
131                         return 1;
132         }
133         return 0;
134 }
135
136 /* iteration over granted and requested permissions */
137 const char *first_usable_permission()
138 {
139         indexiter = 0;
140         return next_usable_permission();
141 }
142
143 const char *next_usable_permission()
144 {
145         while(indexiter < nrpermissions) {
146                 struct permission *p = &permissions[indexiter++];
147                 if (p->granted && p->requested)
148                         return p->name;
149         }
150         return NULL;
151 }
152