doc: add new document quick-tutorial
[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 #include <stdlib.h>
24
25 #include "verbose.h"
26 #include "wgtpkg-permissions.h"
27
28 struct permission {
29         char *name;
30         unsigned granted: 1;
31         unsigned requested: 1;
32         unsigned level: 3;
33 };
34
35 static const char prefix_of_permissions[] = FWK_PREFIX_PERMISSION;
36
37 static unsigned int nrpermissions = 0;
38 static struct permission *permissions = NULL;
39 static unsigned int indexiter = 0;
40
41 /* check is the name has the correct prefix for permissions */
42 int is_standard_permission(const char *name)
43 {
44         return 0 == memcmp(name, prefix_of_permissions, sizeof(prefix_of_permissions) - 1);
45 }
46
47 /* retrieves the permission of name */
48 static struct permission *get_permission(const char *name)
49 {
50         unsigned int i;
51
52         for (i = 0 ; i < nrpermissions ; i++)
53                 if (0 == strcmp(permissions[i].name, name))
54                         return permissions+i;
55         return NULL;
56 }
57
58 /* add a permission of name */
59 static struct permission *add_permission(const char *name)
60 {
61         struct permission *p = get_permission(name);
62         if (!p) {
63                 p = realloc(permissions,
64                         ((nrpermissions + 8) & ~(unsigned)7) * sizeof(*p));
65                 if (p) {
66                         permissions = p;
67                         p = permissions + nrpermissions;
68                         memset(p, 0, sizeof(*p));
69                         p->name = strdup(name);
70                         if (!p->name)
71                                 p = NULL;
72                         else
73                                 nrpermissions++;
74                 }
75         }
76         return p;
77 }
78
79 /* remove any granting */
80 void reset_permissions()
81 {
82         unsigned int i;
83         for (i = 0 ; i < nrpermissions ; i++)
84                 permissions[i].granted = 0;
85 }
86
87 /* remove any granting */
88 void crop_permissions(unsigned level)
89 {
90         unsigned int i;
91         for (i = 0 ; i < nrpermissions ; i++)
92                 if (permissions[i].level < level)
93                         permissions[i].granted = 0;
94 }
95
96 /* add permissions granted for installation */
97 void grant_permission_list(const char *list)
98 {
99         struct permission *p;
100         char *iter, c;
101         unsigned int n;
102         static const char separators[] = " \t\n\r,";
103
104         iter = strdupa(list);
105         iter += strspn(iter, separators);
106         while(*iter) {
107                 n = (unsigned)strcspn(iter, separators);
108                 c = iter[n];
109                 iter[n] = 0;
110                 p = add_permission(iter);
111                 if (!p) {
112                         ERROR("Can't allocate permission");
113                         exit(1);
114                 }
115                 p->granted = 1;
116                 iter += n;
117                 *iter =c;
118                 iter += strspn(iter, separators);
119         }
120 }
121
122 /* checks if the permission 'name' is recorded */
123 int permission_exists(const char *name)
124 {
125         return !!get_permission(name);
126 }
127
128 /* request the permission, returns 1 if granted or 0 otherwise */
129 int request_permission(const char *name)
130 {
131         struct permission *p = get_permission(name);
132         if (p) {
133                 p->requested = 1;
134                 if (p->granted)
135                         return 1;
136         }
137         return 0;
138 }
139
140 /* iteration over granted and requested permissions */
141 const char *first_usable_permission()
142 {
143         indexiter = 0;
144         return next_usable_permission();
145 }
146
147 const char *next_usable_permission()
148 {
149         while(indexiter < nrpermissions) {
150                 struct permission *p = &permissions[indexiter++];
151                 if (p->granted && p->requested)
152                         return p->name;
153         }
154         return NULL;
155 }
156