/****************************************************************************** * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License * which accompanies this distribution, and is available at * http://www.opensource.org/licenses/bsd-license.php * * Contributors: * IBM Corporation - initial implementation *****************************************************************************/ #include #include #include #include #include #include #include #include static int inbetween_white(char *s, int max, char **start, char **end, char **next); static int add_header(struct ffs_chain_t *, struct ffs_header_t *); static int glob_come_from_cr = 0; static int find_next_entry(int file, struct ffs_chain_t *chain) { #define MAX_LINE_SIZE 1024 char lnbuf[MAX_LINE_SIZE], b0 = 0, b1 = 0; char *start, *end, *next; struct ffs_header_t *hdr; //, *hdr2; int lc, rc; char c; /* search for new config line */ if (0 == glob_come_from_cr) { while (1 == (rc = read(file, &c, 1))) { //printf("b0=%c b1=%c c=%c\n", // b0, b1, c); b0 = b1; b1 = c; /* this looks for starting sign "[^#]" */ if (((0x0a == b0) || (0x0d == b0)) && (('#' != b1) && (0x0a != b1) && (0x0d != b1))) { break; } } } else { /* normalize */ while (1 == (rc = read(file, &c, 1))) { //printf("read c=%c\n", c); if ((0x0a != c) && (0x0d != c)) { break; } } glob_come_from_cr = 0; //printf("debug: glob_come_from_cr = 0\n"); } if (1 != rc) { return 1; } /* now buffer it until end of line */ memset((void *) lnbuf, 0, MAX_LINE_SIZE); lnbuf[0] = c; lc = 1; while ((1 == read(file, &(lnbuf[lc]), 1)) && (lc < MAX_LINE_SIZE)) { //printf("read lnbuf=%c\n", lnbuf[lc]); if ((0x0a == lnbuf[lc]) || (0x0d == lnbuf[lc])) { glob_come_from_cr = 1; //printf("debug: glob_come_from_cr = 1\n"); break; } lc++; } /* allocate header */ hdr = malloc(sizeof(struct ffs_header_t)); if (NULL == hdr) { perror("alloc memory"); return 2; } memset((void *) hdr, 0, sizeof(struct ffs_header_t)); /* attach header to chain */ if (0 != add_header(chain, hdr)) { return 2; } /**********************************************************/ /* extract token name *********************************** */ start = NULL; if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) { printf("parsing error 1"); return 2; } /* get memory for it */ hdr->token = malloc(end - start + 1); if (NULL == hdr->token) { return 2; } /* set string */ strncpy(hdr->token, start, end - start + 1); hdr->token[end - start] = 0; /**********************************************************/ /* extract file name *********************************** */ if (NULL == next) { return 2; } start = next; if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) { printf("parsing error 1"); return 2; } /* get memory for it */ hdr->imagefile = malloc(end - start + 1); if (NULL == hdr->imagefile) { return 2; } /* check if file is existing */ /* set string */ strncpy(hdr->imagefile, start, end - start + 1); hdr->imagefile[end - start] = 0; /* check if entry is linked to another header */ if (':' == *start) { printf ("\nERROR: links are removed as feature in this version\n"); return 2; /* start++; if (0 != find_entry_by_token(chain, hdr->imagefile+1, &hdr2)) { printf("[%s]: link to [%s] not found\n", hdr->token, hdr->imagefile+1); dump_fs_contents(chain); return 2; } hdr->linked_to = hdr2; */ } /**********************************************************/ /* extract flags name *********************************** */ if (NULL == next) { return 2; } start = next; if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) { printf("parsing error 1"); return 2; } hdr->flags = strtoul(start, NULL, 16); /**********************************************************/ /* extract rom start name *********************************** */ if (NULL == next) { return 2; } start = next; if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) { printf("parsing error 1"); return 2; } if ('-' == *start) { /* this means not specific address request for data */ hdr->romaddr = 0; } else { /* data has to begin at specific address */ hdr->romaddr = strtoul(start, NULL, 16); } return 0; } int read_config(int conf_file, struct ffs_chain_t *ffs_chain) { int rc; while (1) { rc = find_next_entry(conf_file, ffs_chain); if (rc != 0) break; } return rc; } static int inbetween_white(char *s, int max, char **start, char **end, char **next) { int pos = 0, posalt; if (NULL != *start) { pos = *start - s; s = *start; } /* wind to first non white */ while (pos < max) { if ((' ' == *s) || (' ' == *s)) { s++; pos++; continue; } break; } if (pos >= max) { /* no non-white found */ return 1; } /* assign start */ *start = s; /* wind to end of non white or end of buffer */ posalt = pos; while (pos < max) { if ((' ' == *s) || (' ' == *s) || (0x0a == *s) || (0x0d == *s)) { break; } s++; pos++; } if (pos == posalt) { return 1; } *end = s; if ((pos + 1) >= max) { *next = NULL; } else { *next = s; } return 0; } int add_header(struct ffs_chain_t *chain, struct ffs_header_t *hdr) { struct ffs_header_t *next; if (NULL == chain->first) { chain->count = 1; chain->first = hdr; return 0; } next = chain->first; /* find last */ while (NULL != next->next) { next = next->next; } next->next = hdr; chain->count++; return 0; } void dump_fs_contents(struct ffs_chain_t *chain) { struct ffs_header_t *next; if (NULL == chain->first) { printf("no contents in fs\n"); return; } next = chain->first; while (1) { if (NULL != next->token) { printf("Token [%s] ", next->token); } else { printf(" [not-set], "); } if (NULL != next->imagefile) { printf(" <%s>, ", next->imagefile); } else { printf(" file, "); } printf("flags<%llx>, ", next->flags); printf("romaddr<%llx>, ", next->romaddr); if (NULL != next->linked_to) { printf("linked to [%s]", next->linked_to->token); } printf("\n"); if (NULL == next->next) { break; } next = next->next; } } void free_chain_memory(struct ffs_chain_t *chain) { struct ffs_header_t *hdr, *next_hdr; if (NULL != chain->first) { hdr = chain->first; chain->first = NULL; } else { return; } while (NULL != hdr) { //printf("%p ", hdr); if (NULL != hdr->token) { //printf("free up %s\n", hdr->token); free(hdr->token); } if (NULL != hdr->imagefile) { free(hdr->imagefile); } next_hdr = hdr->next; free(hdr); hdr = next_hdr; } } /* * Detect duplicate entries in the romfs list */ void find_duplicates(struct ffs_chain_t *chain) { struct ffs_header_t *act, *sub; if (NULL == chain->first) { printf("no contents in fs\n"); return; } act = chain->first; do { sub = act->next; while (sub != NULL) { if (act->token == NULL || sub->token == NULL) { printf("find_duplicates: token not set!\n"); } else if (strcmp(act->token, sub->token) == 0) { printf("*** NOTE: duplicate romfs file '%s'.\n", act->token); } sub = sub->next; } act = act->next; } while (act != NULL); }