371 lines
7.4 KiB
C
371 lines
7.4 KiB
C
/******************************************************************************
|
|
* 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 <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <cfgparse.h>
|
|
|
|
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 "<CR>[^#]" */
|
|
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<not-set>, ");
|
|
}
|
|
|
|
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);
|
|
|
|
}
|