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