xref: /aosp_15_r20/external/selinux/libsemanage/src/utilities.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker /* Author: Mark Goldman   <[email protected]>
2*2d543d20SAndroid Build Coastguard Worker  *			Paul Rosenfeld	<[email protected]>
3*2d543d20SAndroid Build Coastguard Worker  *
4*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2007 Tresys Technology, LLC
5*2d543d20SAndroid Build Coastguard Worker  *
6*2d543d20SAndroid Build Coastguard Worker  *  This library is free software; you can redistribute it and/or
7*2d543d20SAndroid Build Coastguard Worker  *  modify it under the terms of the GNU Lesser General Public
8*2d543d20SAndroid Build Coastguard Worker  *  License as published by the Free Software Foundation; either
9*2d543d20SAndroid Build Coastguard Worker  *  version 2.1 of the License, or (at your option) any later version.
10*2d543d20SAndroid Build Coastguard Worker  *
11*2d543d20SAndroid Build Coastguard Worker  *  This library is distributed in the hope that it will be useful,
12*2d543d20SAndroid Build Coastguard Worker  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13*2d543d20SAndroid Build Coastguard Worker  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*2d543d20SAndroid Build Coastguard Worker  *  Lesser General Public License for more details.
15*2d543d20SAndroid Build Coastguard Worker  *
16*2d543d20SAndroid Build Coastguard Worker  *  You should have received a copy of the GNU Lesser General Public
17*2d543d20SAndroid Build Coastguard Worker  *  License along with this library; if not, write to the Free Software
18*2d543d20SAndroid Build Coastguard Worker  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19*2d543d20SAndroid Build Coastguard Worker  */
20*2d543d20SAndroid Build Coastguard Worker #include "utilities.h"
21*2d543d20SAndroid Build Coastguard Worker 
22*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
23*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
24*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
25*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
26*2d543d20SAndroid Build Coastguard Worker #include <string.h>
27*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
28*2d543d20SAndroid Build Coastguard Worker #include <assert.h>
29*2d543d20SAndroid Build Coastguard Worker 
30*2d543d20SAndroid Build Coastguard Worker #define TRUE 1
31*2d543d20SAndroid Build Coastguard Worker #define FALSE 0
32*2d543d20SAndroid Build Coastguard Worker 
semanage_findval(const char * file,const char * var,const char * delim)33*2d543d20SAndroid Build Coastguard Worker char *semanage_findval(const char *file, const char *var, const char *delim)
34*2d543d20SAndroid Build Coastguard Worker {
35*2d543d20SAndroid Build Coastguard Worker 	FILE *fd;
36*2d543d20SAndroid Build Coastguard Worker 	char *buff = NULL;
37*2d543d20SAndroid Build Coastguard Worker 	char *retval = NULL;
38*2d543d20SAndroid Build Coastguard Worker 	size_t buff_len = 0;
39*2d543d20SAndroid Build Coastguard Worker 
40*2d543d20SAndroid Build Coastguard Worker 	assert(file);
41*2d543d20SAndroid Build Coastguard Worker 	assert(var);
42*2d543d20SAndroid Build Coastguard Worker 
43*2d543d20SAndroid Build Coastguard Worker 	if ((fd = fopen(file, "r")) == NULL)
44*2d543d20SAndroid Build Coastguard Worker 		return NULL;
45*2d543d20SAndroid Build Coastguard Worker 
46*2d543d20SAndroid Build Coastguard Worker 	while (getline(&buff, &buff_len, fd) > 0) {
47*2d543d20SAndroid Build Coastguard Worker 		if (semanage_is_prefix(buff, var)) {
48*2d543d20SAndroid Build Coastguard Worker 			retval = semanage_split(buff, delim);
49*2d543d20SAndroid Build Coastguard Worker 			if (retval)
50*2d543d20SAndroid Build Coastguard Worker 				semanage_rtrim(retval, '\n');
51*2d543d20SAndroid Build Coastguard Worker 			break;
52*2d543d20SAndroid Build Coastguard Worker 		}
53*2d543d20SAndroid Build Coastguard Worker 	}
54*2d543d20SAndroid Build Coastguard Worker 	free(buff);
55*2d543d20SAndroid Build Coastguard Worker 	fclose(fd);
56*2d543d20SAndroid Build Coastguard Worker 
57*2d543d20SAndroid Build Coastguard Worker 	return retval;
58*2d543d20SAndroid Build Coastguard Worker }
59*2d543d20SAndroid Build Coastguard Worker 
semanage_is_prefix(const char * str,const char * prefix)60*2d543d20SAndroid Build Coastguard Worker int semanage_is_prefix(const char *str, const char *prefix)
61*2d543d20SAndroid Build Coastguard Worker {
62*2d543d20SAndroid Build Coastguard Worker 	if (!str) {
63*2d543d20SAndroid Build Coastguard Worker 		return FALSE;
64*2d543d20SAndroid Build Coastguard Worker 	}
65*2d543d20SAndroid Build Coastguard Worker 	if (!prefix) {
66*2d543d20SAndroid Build Coastguard Worker 		return TRUE;
67*2d543d20SAndroid Build Coastguard Worker 	}
68*2d543d20SAndroid Build Coastguard Worker 
69*2d543d20SAndroid Build Coastguard Worker 	return strncmp(str, prefix, strlen(prefix)) == 0;
70*2d543d20SAndroid Build Coastguard Worker }
71*2d543d20SAndroid Build Coastguard Worker 
semanage_split_on_space(const char * str)72*2d543d20SAndroid Build Coastguard Worker char *semanage_split_on_space(const char *str)
73*2d543d20SAndroid Build Coastguard Worker {
74*2d543d20SAndroid Build Coastguard Worker 	/* as per the man page, these are the isspace() chars */
75*2d543d20SAndroid Build Coastguard Worker 	const char *seps = "\f\n\r\t\v ";
76*2d543d20SAndroid Build Coastguard Worker 	size_t off = 0;
77*2d543d20SAndroid Build Coastguard Worker 
78*2d543d20SAndroid Build Coastguard Worker 	if (!str)
79*2d543d20SAndroid Build Coastguard Worker 		return NULL;
80*2d543d20SAndroid Build Coastguard Worker 
81*2d543d20SAndroid Build Coastguard Worker 	/* skip one token and the spaces before and after it */
82*2d543d20SAndroid Build Coastguard Worker 	off = strspn(str, seps);
83*2d543d20SAndroid Build Coastguard Worker 	off += strcspn(str + off, seps);
84*2d543d20SAndroid Build Coastguard Worker 	off += strspn(str + off, seps);
85*2d543d20SAndroid Build Coastguard Worker 	return strdup(str + off);
86*2d543d20SAndroid Build Coastguard Worker }
87*2d543d20SAndroid Build Coastguard Worker 
semanage_split(const char * str,const char * delim)88*2d543d20SAndroid Build Coastguard Worker char *semanage_split(const char *str, const char *delim)
89*2d543d20SAndroid Build Coastguard Worker {
90*2d543d20SAndroid Build Coastguard Worker 	char *retval;
91*2d543d20SAndroid Build Coastguard Worker 
92*2d543d20SAndroid Build Coastguard Worker 	if (!str)
93*2d543d20SAndroid Build Coastguard Worker 		return NULL;
94*2d543d20SAndroid Build Coastguard Worker 	if (!delim || !(*delim))
95*2d543d20SAndroid Build Coastguard Worker 		return semanage_split_on_space(str);
96*2d543d20SAndroid Build Coastguard Worker 
97*2d543d20SAndroid Build Coastguard Worker 	retval = strstr(str, delim);
98*2d543d20SAndroid Build Coastguard Worker 	if (retval == NULL)
99*2d543d20SAndroid Build Coastguard Worker 		return NULL;
100*2d543d20SAndroid Build Coastguard Worker 
101*2d543d20SAndroid Build Coastguard Worker 	return strdup(retval + strlen(delim));
102*2d543d20SAndroid Build Coastguard Worker }
103*2d543d20SAndroid Build Coastguard Worker 
semanage_list_push(semanage_list_t ** list,const char * data)104*2d543d20SAndroid Build Coastguard Worker int semanage_list_push(semanage_list_t ** list, const char *data)
105*2d543d20SAndroid Build Coastguard Worker {
106*2d543d20SAndroid Build Coastguard Worker 	semanage_list_t *temp = NULL;
107*2d543d20SAndroid Build Coastguard Worker 
108*2d543d20SAndroid Build Coastguard Worker 	if (!data)
109*2d543d20SAndroid Build Coastguard Worker 		return EINVAL;
110*2d543d20SAndroid Build Coastguard Worker 
111*2d543d20SAndroid Build Coastguard Worker 	if (semanage_list_find(*list, data) != NULL)
112*2d543d20SAndroid Build Coastguard Worker 		return 0;
113*2d543d20SAndroid Build Coastguard Worker 
114*2d543d20SAndroid Build Coastguard Worker 	if (!(temp = malloc(sizeof(semanage_list_t))))
115*2d543d20SAndroid Build Coastguard Worker 		return ENOMEM;
116*2d543d20SAndroid Build Coastguard Worker 
117*2d543d20SAndroid Build Coastguard Worker 	if (!(temp->data = strdup(data))) {
118*2d543d20SAndroid Build Coastguard Worker 		free(temp);
119*2d543d20SAndroid Build Coastguard Worker 		return ENOMEM;
120*2d543d20SAndroid Build Coastguard Worker 	}
121*2d543d20SAndroid Build Coastguard Worker 	temp->next = *list;
122*2d543d20SAndroid Build Coastguard Worker 	*list = temp;
123*2d543d20SAndroid Build Coastguard Worker 
124*2d543d20SAndroid Build Coastguard Worker 	return 0;
125*2d543d20SAndroid Build Coastguard Worker }
126*2d543d20SAndroid Build Coastguard Worker 
semanage_list_pop(semanage_list_t ** list)127*2d543d20SAndroid Build Coastguard Worker char *semanage_list_pop(semanage_list_t ** list)
128*2d543d20SAndroid Build Coastguard Worker {
129*2d543d20SAndroid Build Coastguard Worker 	semanage_list_t *node = NULL;
130*2d543d20SAndroid Build Coastguard Worker 	char *data = NULL;
131*2d543d20SAndroid Build Coastguard Worker 
132*2d543d20SAndroid Build Coastguard Worker 	if (!list || !(*list))
133*2d543d20SAndroid Build Coastguard Worker 		return NULL;
134*2d543d20SAndroid Build Coastguard Worker 
135*2d543d20SAndroid Build Coastguard Worker 	node = (*list);
136*2d543d20SAndroid Build Coastguard Worker 	data = node->data;
137*2d543d20SAndroid Build Coastguard Worker 
138*2d543d20SAndroid Build Coastguard Worker 	(*list) = node->next;
139*2d543d20SAndroid Build Coastguard Worker 	free(node);
140*2d543d20SAndroid Build Coastguard Worker 
141*2d543d20SAndroid Build Coastguard Worker 	return data;
142*2d543d20SAndroid Build Coastguard Worker }
143*2d543d20SAndroid Build Coastguard Worker 
semanage_list_destroy(semanage_list_t ** list)144*2d543d20SAndroid Build Coastguard Worker void semanage_list_destroy(semanage_list_t ** list)
145*2d543d20SAndroid Build Coastguard Worker {
146*2d543d20SAndroid Build Coastguard Worker 	semanage_list_t *temp;
147*2d543d20SAndroid Build Coastguard Worker 
148*2d543d20SAndroid Build Coastguard Worker 	while ((temp = (*list))) {
149*2d543d20SAndroid Build Coastguard Worker 		free(temp->data);
150*2d543d20SAndroid Build Coastguard Worker 		(*list) = temp->next;
151*2d543d20SAndroid Build Coastguard Worker 		free(temp);
152*2d543d20SAndroid Build Coastguard Worker 	}
153*2d543d20SAndroid Build Coastguard Worker }
154*2d543d20SAndroid Build Coastguard Worker 
semanage_list_find(semanage_list_t * l,const char * data)155*2d543d20SAndroid Build Coastguard Worker semanage_list_t *semanage_list_find(semanage_list_t * l, const char *data)
156*2d543d20SAndroid Build Coastguard Worker {
157*2d543d20SAndroid Build Coastguard Worker 	if (!data)
158*2d543d20SAndroid Build Coastguard Worker 		return NULL;
159*2d543d20SAndroid Build Coastguard Worker 	while (l && strcmp(l->data, data))
160*2d543d20SAndroid Build Coastguard Worker 		l = l->next;
161*2d543d20SAndroid Build Coastguard Worker 
162*2d543d20SAndroid Build Coastguard Worker 	return l;
163*2d543d20SAndroid Build Coastguard Worker }
164*2d543d20SAndroid Build Coastguard Worker 
semanage_list_sort(semanage_list_t ** l)165*2d543d20SAndroid Build Coastguard Worker int semanage_list_sort(semanage_list_t ** l)
166*2d543d20SAndroid Build Coastguard Worker {
167*2d543d20SAndroid Build Coastguard Worker 	semanage_list_t **array = NULL;
168*2d543d20SAndroid Build Coastguard Worker 	semanage_list_t *temp = NULL;
169*2d543d20SAndroid Build Coastguard Worker 	size_t count = 0;
170*2d543d20SAndroid Build Coastguard Worker 	size_t i = 0;
171*2d543d20SAndroid Build Coastguard Worker 
172*2d543d20SAndroid Build Coastguard Worker 	if (!l)
173*2d543d20SAndroid Build Coastguard Worker 		return 0;
174*2d543d20SAndroid Build Coastguard Worker 
175*2d543d20SAndroid Build Coastguard Worker 	for (temp = *l; temp; temp = temp->next)
176*2d543d20SAndroid Build Coastguard Worker 		++count;
177*2d543d20SAndroid Build Coastguard Worker 
178*2d543d20SAndroid Build Coastguard Worker 	array = malloc(sizeof(semanage_list_t *) * count);
179*2d543d20SAndroid Build Coastguard Worker 	if (!array)
180*2d543d20SAndroid Build Coastguard Worker 		return ENOMEM;	/* couldn't allocate memory for sort */
181*2d543d20SAndroid Build Coastguard Worker 	for (temp = *l; temp; temp = temp->next) {
182*2d543d20SAndroid Build Coastguard Worker 		array[i++] = temp;
183*2d543d20SAndroid Build Coastguard Worker 	}
184*2d543d20SAndroid Build Coastguard Worker 
185*2d543d20SAndroid Build Coastguard Worker 	qsort(array, count, sizeof(semanage_list_t *),
186*2d543d20SAndroid Build Coastguard Worker 	      (int (*)(const void *, const void *))&semanage_cmp_plist_t);
187*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < (count - 1); ++i) {
188*2d543d20SAndroid Build Coastguard Worker 		array[i]->next = array[i + 1];
189*2d543d20SAndroid Build Coastguard Worker 	}
190*2d543d20SAndroid Build Coastguard Worker 	array[i]->next = NULL;
191*2d543d20SAndroid Build Coastguard Worker 	(*l) = array[0];
192*2d543d20SAndroid Build Coastguard Worker 	free(array);
193*2d543d20SAndroid Build Coastguard Worker 
194*2d543d20SAndroid Build Coastguard Worker 	return 0;
195*2d543d20SAndroid Build Coastguard Worker }
196*2d543d20SAndroid Build Coastguard Worker 
semanage_cmp_plist_t(const semanage_list_t ** x,const semanage_list_t ** y)197*2d543d20SAndroid Build Coastguard Worker int semanage_cmp_plist_t(const semanage_list_t ** x, const semanage_list_t ** y)
198*2d543d20SAndroid Build Coastguard Worker {
199*2d543d20SAndroid Build Coastguard Worker 	return strcmp((*x)->data, (*y)->data);
200*2d543d20SAndroid Build Coastguard Worker }
201*2d543d20SAndroid Build Coastguard Worker 
semanage_str_count(const char * data,char what)202*2d543d20SAndroid Build Coastguard Worker int semanage_str_count(const char *data, char what)
203*2d543d20SAndroid Build Coastguard Worker {
204*2d543d20SAndroid Build Coastguard Worker 	int count = 0;
205*2d543d20SAndroid Build Coastguard Worker 
206*2d543d20SAndroid Build Coastguard Worker 	if (!data)
207*2d543d20SAndroid Build Coastguard Worker 		return 0;
208*2d543d20SAndroid Build Coastguard Worker 	while (*data) {
209*2d543d20SAndroid Build Coastguard Worker 		if (*data == what)
210*2d543d20SAndroid Build Coastguard Worker 			++count;
211*2d543d20SAndroid Build Coastguard Worker 		++data;
212*2d543d20SAndroid Build Coastguard Worker 	}
213*2d543d20SAndroid Build Coastguard Worker 
214*2d543d20SAndroid Build Coastguard Worker 	return count;
215*2d543d20SAndroid Build Coastguard Worker }
216*2d543d20SAndroid Build Coastguard Worker 
semanage_rtrim(char * str,char trim_to)217*2d543d20SAndroid Build Coastguard Worker void semanage_rtrim(char *str, char trim_to)
218*2d543d20SAndroid Build Coastguard Worker {
219*2d543d20SAndroid Build Coastguard Worker 	int len = 0;
220*2d543d20SAndroid Build Coastguard Worker 
221*2d543d20SAndroid Build Coastguard Worker 	if (!str)
222*2d543d20SAndroid Build Coastguard Worker 		return;
223*2d543d20SAndroid Build Coastguard Worker 	len = strlen(str);
224*2d543d20SAndroid Build Coastguard Worker 
225*2d543d20SAndroid Build Coastguard Worker 	while (len > 0) {
226*2d543d20SAndroid Build Coastguard Worker 		if (str[--len] == trim_to) {
227*2d543d20SAndroid Build Coastguard Worker 			str[len] = '\0';
228*2d543d20SAndroid Build Coastguard Worker 			return;
229*2d543d20SAndroid Build Coastguard Worker 		}
230*2d543d20SAndroid Build Coastguard Worker 	}
231*2d543d20SAndroid Build Coastguard Worker }
232*2d543d20SAndroid Build Coastguard Worker 
semanage_str_replace(const char * search,const char * replace,const char * src,size_t lim)233*2d543d20SAndroid Build Coastguard Worker char *semanage_str_replace(const char *search, const char *replace,
234*2d543d20SAndroid Build Coastguard Worker 			   const char *src, size_t lim)
235*2d543d20SAndroid Build Coastguard Worker {
236*2d543d20SAndroid Build Coastguard Worker 	size_t count = 0, slen, rlen, newsize;
237*2d543d20SAndroid Build Coastguard Worker 	char *p, *pres, *result;
238*2d543d20SAndroid Build Coastguard Worker 	const char *psrc;
239*2d543d20SAndroid Build Coastguard Worker 
240*2d543d20SAndroid Build Coastguard Worker 	slen = strlen(search);
241*2d543d20SAndroid Build Coastguard Worker 	rlen = strlen(replace);
242*2d543d20SAndroid Build Coastguard Worker 
243*2d543d20SAndroid Build Coastguard Worker 	/* Do not support empty search strings */
244*2d543d20SAndroid Build Coastguard Worker 	if (slen == 0)
245*2d543d20SAndroid Build Coastguard Worker 		return NULL;
246*2d543d20SAndroid Build Coastguard Worker 
247*2d543d20SAndroid Build Coastguard Worker 	/* Count the occurrences of search in src and compute the new size */
248*2d543d20SAndroid Build Coastguard Worker 	for (p = strstr(src, search); p != NULL; p = strstr(p + slen, search)) {
249*2d543d20SAndroid Build Coastguard Worker 		count++;
250*2d543d20SAndroid Build Coastguard Worker 		if (lim && count >= lim)
251*2d543d20SAndroid Build Coastguard Worker 			break;
252*2d543d20SAndroid Build Coastguard Worker 	}
253*2d543d20SAndroid Build Coastguard Worker 	if (!count)
254*2d543d20SAndroid Build Coastguard Worker 		return strdup(src);
255*2d543d20SAndroid Build Coastguard Worker 
256*2d543d20SAndroid Build Coastguard Worker 	/* Allocate the result string */
257*2d543d20SAndroid Build Coastguard Worker 	newsize = strlen(src) + 1 + count * (rlen - slen);
258*2d543d20SAndroid Build Coastguard Worker 	result = malloc(newsize);
259*2d543d20SAndroid Build Coastguard Worker 	if (!result)
260*2d543d20SAndroid Build Coastguard Worker 		return NULL;
261*2d543d20SAndroid Build Coastguard Worker 
262*2d543d20SAndroid Build Coastguard Worker 	/* Fill the result */
263*2d543d20SAndroid Build Coastguard Worker 	psrc = src;
264*2d543d20SAndroid Build Coastguard Worker 	pres = result;
265*2d543d20SAndroid Build Coastguard Worker 	for (p = strstr(src, search); p != NULL; p = strstr(psrc, search)) {
266*2d543d20SAndroid Build Coastguard Worker 		/* Copy the part which has not been modified */
267*2d543d20SAndroid Build Coastguard Worker 		if (p != psrc) {
268*2d543d20SAndroid Build Coastguard Worker 			size_t length = (size_t)(p - psrc);
269*2d543d20SAndroid Build Coastguard Worker 			memcpy(pres, psrc, length);
270*2d543d20SAndroid Build Coastguard Worker 			pres += length;
271*2d543d20SAndroid Build Coastguard Worker 		}
272*2d543d20SAndroid Build Coastguard Worker 		/* Copy the replacement part */
273*2d543d20SAndroid Build Coastguard Worker 		if (rlen != 0) {
274*2d543d20SAndroid Build Coastguard Worker 			memcpy(pres, replace, rlen);
275*2d543d20SAndroid Build Coastguard Worker 			pres += rlen;
276*2d543d20SAndroid Build Coastguard Worker 		}
277*2d543d20SAndroid Build Coastguard Worker 		psrc = p + slen;
278*2d543d20SAndroid Build Coastguard Worker 		count--;
279*2d543d20SAndroid Build Coastguard Worker 		if (!count)
280*2d543d20SAndroid Build Coastguard Worker 			break;
281*2d543d20SAndroid Build Coastguard Worker 	}
282*2d543d20SAndroid Build Coastguard Worker 	/* Copy the last part, after doing a sanity check */
283*2d543d20SAndroid Build Coastguard Worker 	assert(pres + strlen(psrc) + 1 == result + newsize);
284*2d543d20SAndroid Build Coastguard Worker 	strcpy(pres, psrc);
285*2d543d20SAndroid Build Coastguard Worker 	return result;
286*2d543d20SAndroid Build Coastguard Worker }
287*2d543d20SAndroid Build Coastguard Worker 
288*2d543d20SAndroid Build Coastguard Worker /* list_addafter_controlmem does *NOT* duplicate the data argument
289*2d543d20SAndroid Build Coastguard Worker  * use at your own risk, I am building a list out of malloc'd memory and
290*2d543d20SAndroid Build Coastguard Worker  * it is only going to get stored into this list, thus when I destroy it
291*2d543d20SAndroid Build Coastguard Worker  * later I won't free a ptr twice.
292*2d543d20SAndroid Build Coastguard Worker  *
293*2d543d20SAndroid Build Coastguard Worker  * returns the newly created node or NULL on error
294*2d543d20SAndroid Build Coastguard Worker  */
list_addafter_controlmem(semanage_list_t * item,char * data)295*2d543d20SAndroid Build Coastguard Worker static semanage_list_t *list_addafter_controlmem(semanage_list_t * item, char *data)
296*2d543d20SAndroid Build Coastguard Worker {
297*2d543d20SAndroid Build Coastguard Worker 	semanage_list_t *temp = malloc(sizeof(semanage_list_t));
298*2d543d20SAndroid Build Coastguard Worker 
299*2d543d20SAndroid Build Coastguard Worker 	if (!temp)
300*2d543d20SAndroid Build Coastguard Worker 		return NULL;
301*2d543d20SAndroid Build Coastguard Worker 	temp->data = data;
302*2d543d20SAndroid Build Coastguard Worker 	temp->next = item->next;
303*2d543d20SAndroid Build Coastguard Worker 	item->next = temp;
304*2d543d20SAndroid Build Coastguard Worker 
305*2d543d20SAndroid Build Coastguard Worker 	return temp;
306*2d543d20SAndroid Build Coastguard Worker }
307*2d543d20SAndroid Build Coastguard Worker 
semanage_slurp_file_filter(FILE * file,int (* pred)(const char *))308*2d543d20SAndroid Build Coastguard Worker semanage_list_t *semanage_slurp_file_filter(FILE * file,
309*2d543d20SAndroid Build Coastguard Worker 					    int (*pred) (const char *))
310*2d543d20SAndroid Build Coastguard Worker {
311*2d543d20SAndroid Build Coastguard Worker 	semanage_list_t head;
312*2d543d20SAndroid Build Coastguard Worker 	semanage_list_t *current = &head;
313*2d543d20SAndroid Build Coastguard Worker 	char *line = NULL;
314*2d543d20SAndroid Build Coastguard Worker 	size_t buff_len = 0;
315*2d543d20SAndroid Build Coastguard Worker 
316*2d543d20SAndroid Build Coastguard Worker 	head.next = NULL;	/* initialize head, we aren't going to use the data */
317*2d543d20SAndroid Build Coastguard Worker 	while (getline(&line, &buff_len, file) >= 0) {
318*2d543d20SAndroid Build Coastguard Worker 		if (pred(line)) {
319*2d543d20SAndroid Build Coastguard Worker 			semanage_rtrim(line, '\n');
320*2d543d20SAndroid Build Coastguard Worker 			current = list_addafter_controlmem(current, line);
321*2d543d20SAndroid Build Coastguard Worker 			if (!current)
322*2d543d20SAndroid Build Coastguard Worker 				break;
323*2d543d20SAndroid Build Coastguard Worker 			line = NULL;
324*2d543d20SAndroid Build Coastguard Worker 			buff_len = 0;
325*2d543d20SAndroid Build Coastguard Worker 		}
326*2d543d20SAndroid Build Coastguard Worker 	}
327*2d543d20SAndroid Build Coastguard Worker 	free(line);
328*2d543d20SAndroid Build Coastguard Worker 
329*2d543d20SAndroid Build Coastguard Worker 	return head.next;
330*2d543d20SAndroid Build Coastguard Worker }
331