1 /******************************************************************************
2  * Copyright (c) 2004, 2008 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <string.h>
18 #include <unistd.h>
19 
20 #include <cfgparse.h>
21 
22 static int inbetween_white(char *s, int max, char **start, char **end,
23 			   char **next);
24 static int add_header(struct ffs_chain_t *, struct ffs_header_t *);
25 
26 static int glob_come_from_cr = 0;
27 
28 static int
find_next_entry(int file,struct ffs_chain_t * chain)29 find_next_entry(int file, struct ffs_chain_t *chain)
30 {
31 #define MAX_LINE_SIZE 1024
32 	char lnbuf[MAX_LINE_SIZE], b0 = 0, b1 = 0;
33 	char *start, *end, *next;
34 	struct ffs_header_t *hdr;	//, *hdr2;
35 	int lc, rc;
36 	char c;
37 
38 	/* search for new config line */
39 	if (0 == glob_come_from_cr) {
40 		while (1 == (rc = read(file, &c, 1))) {
41 			//printf("b0=%c b1=%c c=%c\n",
42 			//              b0, b1, c);
43 			b0 = b1;
44 			b1 = c;
45 			/* this looks for starting sign "<CR>[^#]" */
46 			if (((0x0a == b0) || (0x0d == b0)) &&
47 			    (('#' != b1) && (0x0a != b1) && (0x0d != b1))) {
48 				break;
49 			}
50 		}
51 	} else {
52 		/* normalize */
53 		while (1 == (rc = read(file, &c, 1))) {
54 			//printf("read c=%c\n", c);
55 			if ((0x0a != c) && (0x0d != c)) {
56 				break;
57 			}
58 		}
59 		glob_come_from_cr = 0;
60 		//printf("debug: glob_come_from_cr = 0\n");
61 	}
62 	if (1 != rc) {
63 		return 1;
64 	}
65 
66 	/* now buffer it until end of line */
67 	memset((void *) lnbuf, 0, MAX_LINE_SIZE);
68 	lnbuf[0] = c;
69 	lc = 1;
70 	while ((1 == read(file, &(lnbuf[lc]), 1)) && (lc < MAX_LINE_SIZE)) {
71 		//printf("read lnbuf=%c\n", lnbuf[lc]);
72 		if ((0x0a == lnbuf[lc]) || (0x0d == lnbuf[lc])) {
73 			glob_come_from_cr = 1;
74 			//printf("debug: glob_come_from_cr = 1\n");
75 			break;
76 		}
77 		lc++;
78 	}
79 
80 	/* allocate header */
81 	hdr = malloc(sizeof(struct ffs_header_t));
82 	if (NULL == hdr) {
83 		perror("alloc memory");
84 		return 2;
85 	}
86 	memset((void *) hdr, 0, sizeof(struct ffs_header_t));
87 
88 	/* attach header to chain */
89 	if (0 != add_header(chain, hdr)) {
90 		return 2;
91 	}
92 
93 	/**********************************************************/
94 	/* extract token name *********************************** */
95 	start = NULL;
96 	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
97 		printf("parsing error 1");
98 		return 2;
99 	}
100 	/* get memory for it */
101 	hdr->token = malloc(end - start + 1);
102 	if (NULL == hdr->token) {
103 		return 2;
104 	}
105 	/* set string */
106 	strncpy(hdr->token, start, end - start + 1);
107 	hdr->token[end - start] = 0;
108 
109 	/**********************************************************/
110 	/* extract file name *********************************** */
111 	if (NULL == next) {
112 		return 2;
113 	}
114 	start = next;
115 	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
116 		printf("parsing error 1");
117 		return 2;
118 	}
119 
120 	/* get memory for it */
121 	hdr->imagefile = malloc(end - start + 1);
122 	if (NULL == hdr->imagefile) {
123 		return 2;
124 	}
125 
126 	/* check if file is existing */
127 
128 	/* set string */
129 	strncpy(hdr->imagefile, start, end - start + 1);
130 	hdr->imagefile[end - start] = 0;
131 
132 	/* check if entry is linked to another header */
133 	if (':' == *start) {
134 		printf
135 		    ("\nERROR: links are removed as feature in this version\n");
136 		return 2;
137 
138 		/*
139 		   start++;
140 		   if (0 != find_entry_by_token(chain, hdr->imagefile+1, &hdr2)) {
141 		   printf("[%s]: link to [%s] not found\n",
142 		   hdr->token, hdr->imagefile+1);
143 		   dump_fs_contents(chain);
144 		   return 2;
145 		   }
146 		   hdr->linked_to = hdr2;
147 		 */
148 	}
149 
150 	/**********************************************************/
151 	/* extract flags name *********************************** */
152 	if (NULL == next) {
153 		return 2;
154 	}
155 	start = next;
156 	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
157 		printf("parsing error 1");
158 		return 2;
159 	}
160 	hdr->flags = strtoul(start, NULL, 16);
161 
162 	/**********************************************************/
163 	/* extract rom start name *********************************** */
164 	if (NULL == next) {
165 		return 2;
166 	}
167 	start = next;
168 	if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
169 		printf("parsing error 1");
170 		return 2;
171 	}
172 	if ('-' == *start) {
173 		/* this means not specific address request for data */
174 		hdr->romaddr = 0;
175 	} else {
176 		/* data has to begin at specific address */
177 		hdr->romaddr = strtoul(start, NULL, 16);
178 	}
179 
180 	return 0;
181 }
182 
183 int
read_config(int conf_file,struct ffs_chain_t * ffs_chain)184 read_config(int conf_file, struct ffs_chain_t *ffs_chain)
185 {
186 	int rc;
187 
188 	while (1) {
189 		rc = find_next_entry(conf_file, ffs_chain);
190 		if (rc != 0)
191 			break;
192 	}
193 	return rc;
194 }
195 
196 static int
inbetween_white(char * s,int max,char ** start,char ** end,char ** next)197 inbetween_white(char *s, int max, char **start, char **end, char **next)
198 {
199 	int pos = 0, posalt;
200 
201 	if (NULL != *start) {
202 		pos = *start - s;
203 		s = *start;
204 	}
205 
206 	/* wind to first non white */
207 	while (pos < max) {
208 		if ((' ' == *s) || ('	' == *s)) {
209 			s++;
210 			pos++;
211 			continue;
212 		}
213 		break;
214 	}
215 	if (pos >= max) {
216 		/* no non-white found */
217 		return 1;
218 	}
219 
220 	/* assign start */
221 	*start = s;
222 
223 	/* wind to end of non white or end of buffer */
224 	posalt = pos;
225 	while (pos < max) {
226 		if ((' ' == *s) || ('	' == *s) ||
227 		    (0x0a == *s) || (0x0d == *s)) {
228 			break;
229 		}
230 		s++;
231 		pos++;
232 	}
233 
234 	if (pos == posalt) {
235 		return 1;
236 	}
237 
238 	*end = s;
239 
240 	if ((pos + 1) >= max) {
241 		*next = NULL;
242 	} else {
243 		*next = s;
244 	}
245 
246 	return 0;
247 }
248 
249 int
add_header(struct ffs_chain_t * chain,struct ffs_header_t * hdr)250 add_header(struct ffs_chain_t *chain, struct ffs_header_t *hdr)
251 {
252 	struct ffs_header_t *next;
253 
254 	if (NULL == chain->first) {
255 		chain->count = 1;
256 		chain->first = hdr;
257 		return 0;
258 	}
259 	next = chain->first;
260 
261 	/* find last */
262 	while (NULL != next->next) {
263 		next = next->next;
264 	}
265 	next->next = hdr;
266 	chain->count++;
267 
268 	return 0;
269 }
270 
271 void
dump_fs_contents(struct ffs_chain_t * chain)272 dump_fs_contents(struct ffs_chain_t *chain)
273 {
274 	struct ffs_header_t *next;
275 
276 	if (NULL == chain->first) {
277 		printf("no contents in fs\n");
278 		return;
279 	}
280 	next = chain->first;
281 
282 	while (1) {
283 		if (NULL != next->token) {
284 			printf("Token [%s] ", next->token);
285 		} else {
286 			printf(" [not-set], ");
287 		}
288 
289 		if (NULL != next->imagefile) {
290 			printf(" <%s>, ", next->imagefile);
291 		} else {
292 			printf(" file<not-set>, ");
293 		}
294 
295 		printf("flags<%llx>, ", next->flags);
296 		printf("romaddr<%llx>, ", next->romaddr);
297 
298 		if (NULL != next->linked_to) {
299 			printf("linked to [%s]", next->linked_to->token);
300 		}
301 
302 		printf("\n");
303 		if (NULL == next->next) {
304 			break;
305 		}
306 
307 		next = next->next;
308 	}
309 
310 }
311 
312 void
free_chain_memory(struct ffs_chain_t * chain)313 free_chain_memory(struct ffs_chain_t *chain)
314 {
315 	struct ffs_header_t *hdr, *next_hdr;
316 
317 	if (NULL != chain->first) {
318 		hdr = chain->first;
319 		chain->first = NULL;
320 	} else {
321 		return;
322 	}
323 
324 	while (NULL != hdr) {
325 		//printf("%p  ", hdr);
326 		if (NULL != hdr->token) {
327 			//printf("free up %s\n", hdr->token);
328 			free(hdr->token);
329 		}
330 		if (NULL != hdr->imagefile) {
331 			free(hdr->imagefile);
332 		}
333 		next_hdr = hdr->next;
334 		free(hdr);
335 		hdr = next_hdr;
336 	}
337 }
338 
339 
340 /*
341  * Detect duplicate entries in the romfs list
342  */
343 void
find_duplicates(struct ffs_chain_t * chain)344 find_duplicates(struct ffs_chain_t *chain)
345 {
346 	struct ffs_header_t *act, *sub;
347 
348 	if (NULL == chain->first) {
349 		printf("no contents in fs\n");
350 		return;
351 	}
352 	act = chain->first;
353 
354 	do {
355 		sub = act->next;
356 		while (sub != NULL) {
357 
358 			if (act->token == NULL || sub->token == NULL) {
359 				printf("find_duplicates: token not set!\n");
360 			} else if (strcmp(act->token, sub->token) == 0) {
361 				printf("*** NOTE: duplicate romfs file '%s'.\n",
362 				       act->token);
363 			}
364 			sub = sub->next;
365 		}
366 
367 		act = act->next;
368 
369 	} while (act != NULL);
370 
371 }
372