Imported Upstream version 2.4.3
[platform/upstream/audit.git] / src / ausearch-avc.c
1 /*
2 * ausearch-avc.c - Minimal linked list library for avcs
3 * Copyright (c) 2006,2008,2014 Red Hat Inc., Durham, North Carolina.
4 * All Rights Reserved. 
5 *
6 * This software may be freely redistributed and/or modified under the
7 * terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * Authors:
21 *   Steve Grubb <sgrubb@redhat.com>
22 */
23
24 #include "config.h"
25 #include <stdlib.h>
26 #include <string.h>
27 #include "ausearch-avc.h"
28
29
30 void alist_create(alist *l)
31 {
32         l->head = NULL;
33         l->cur = NULL;
34         l->cnt = 0;
35 }
36
37 anode *alist_next(alist *l)
38 {
39         if (l->cur == NULL)
40                 return NULL;
41         l->cur = l->cur->next;
42         return l->cur;
43 }
44
45 static void alist_last(alist *l)
46 {
47         register anode* cur;
48
49         if (l->head == NULL)
50                 return;
51
52         // Start with cur in hopes that we don't start at beginning
53         if (l->cur)
54                 cur = l->cur;
55         else
56                 cur = l->head;
57
58         // Loop until no next value
59         while (cur->next)
60                 cur = cur->next;
61         l->cur = cur;
62 }
63
64 void alist_append(alist *l, anode *node)
65 {
66         anode* newnode;
67
68         newnode = malloc(sizeof(anode));
69
70         if (node->scontext)
71                 newnode->scontext = node->scontext;
72         else
73                 newnode->scontext = NULL;
74
75         if (node->tcontext)
76                 newnode->tcontext = node->tcontext;
77         else
78                 newnode->tcontext = NULL;
79
80         newnode->avc_result = node->avc_result;
81
82         if (node->avc_perm)
83                 newnode->avc_perm = node->avc_perm;
84         else
85                 newnode->avc_perm = NULL;
86
87         if (node->avc_class)
88                 newnode->avc_class = node->avc_class;
89         else
90                 newnode->avc_class = NULL;
91
92         newnode->next = NULL;
93
94         // Make sure cursor is at the end
95         alist_last(l);
96
97         // if we are at top, fix this up
98         if (l->head == NULL)
99                 l->head = newnode;
100         else    // Otherwise add pointer to newnode
101                 l->cur->next = newnode;
102
103         // make newnode current
104         l->cur = newnode;
105         l->cnt++;
106 }
107
108 int alist_find_subj(alist *l)
109 {
110         register anode* window = l->head;
111
112         while (window) {
113                 if (window->scontext) {
114                         l->cur = window;
115                         return 1;
116                 }
117                 else
118                         window = window->next;
119         }
120         return 0;
121 }
122
123 anode *alist_next_subj(alist *l)
124 {
125         if (l->cur == NULL)
126                 return NULL;
127         while (l->cur->next) {
128                 l->cur=l->cur->next;
129                 if (l->cur->scontext)
130                         return l->cur;
131         }
132         return NULL;
133 }
134
135 int alist_find_obj(alist *l)
136 {
137         register anode* window = l->head;
138
139         while (window) {
140                 if (window->tcontext) {
141                         l->cur = window;
142                         return 1;
143                 }
144                 else
145                         window = window->next;
146         }
147         return 0;
148 }
149
150 anode *alist_next_obj(alist *l)
151 {
152         if (l->cur == NULL)
153                 return NULL;
154         while (l->cur->next) {
155                 l->cur=l->cur->next;
156                 if (l->cur->tcontext)
157                         return l->cur;
158         }
159         return NULL;
160 }
161
162 int alist_find_avc(alist *l)
163 {
164         register anode* window = l->head;
165
166         while (window) {
167                 if (window->avc_result != AVC_UNSET) {
168                         l->cur = window;
169                         return 1;
170                 }
171                 else
172                         window = window->next;
173         }
174         return 0;
175 }
176
177 anode *alist_next_avc(alist *l)
178 {
179         if (l->cur == NULL)
180                 return NULL;
181         while (l->cur->next) {
182                 l->cur=l->cur->next;
183                 if (l->cur->avc_result != AVC_UNSET)
184                         return l->cur;
185         }
186         return NULL;
187 }
188
189 void alist_clear(alist* l)
190 {
191         anode* nextnode;
192         register anode* current;
193
194         current = l->head;
195         while (current) {
196                 nextnode=current->next;
197                 anode_clear(current);
198                 free(current);
199                 current=nextnode;
200         }
201         l->head = NULL;
202         l->cur = NULL;
203         l->cnt = 0;
204 }
205
206 void anode_init(anode *an)
207 {
208         an->scontext = NULL;
209         an->tcontext = NULL;
210         an->avc_result = AVC_UNSET;
211         an->avc_perm = NULL;
212         an->avc_class = NULL;
213 }
214
215 void anode_clear(anode *an)
216 {
217         free(an->scontext);
218         free(an->tcontext);
219         free(an->avc_perm);
220         free(an->avc_class);
221 }
222