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