diff --git a/README.md b/README.md index 4602d332f75b04daf049e0d8206c43a0aa3ab39b..6fd8175c0a09969055781104f24cf1e55d285df1 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ calls iopupgrade. ./iopupgrade [OPTION].. Options: -f, --file=NAME image file to use. If not specified stdin is used. - -b, --board=name name of the board + -M, --match=key=val,.... image headers needs to have this value -q, --force do not do board name check -u, --ubivol=NAME UBI volume device file to write rootfs to. -U, --ubifs=NAME Extract ubifs image to file. @@ -54,7 +54,7 @@ Options: |----|-------| |Help|`iopupgrade -h`| |Print headers|`iopupgrade -f last.y3 -p`| - +|match board name|`iopupgrade -f last.y3 -M "board=DG400,dsl=A" `| ### Broadcom target related examples ### |task|command| diff --git a/src/board.c b/src/board.c index 34c4a3ecaf337118d8d87d45f6e788db6d5d4fdb..a2102953ede43fdf966eef9d44ef360abc8cdeb8 100644 --- a/src/board.c +++ b/src/board.c @@ -27,41 +27,119 @@ #include "consumer.h" #include "cmd.h" -static char *board; static int force; +#define MAX_KEYS 20 +static char * key_name[MAX_KEYS]; +static char * key_value[MAX_KEYS]; +static int keys; + static int init(struct img_header *hdr) { char *p; + int index; /* skip snity check ? */ if (force) return 0; - if (!board){ - fprintf(stderr, "Board name needs to be given with -b or to skip test give -q (unsafe)\n"); - exit(EXIT_FAILURE); + /* Loop over all headers and compare values */ + for(index=0; index<keys; index++) { + p = get_str_val(hdr, key_name[index]); + if (p == NULL){ + fprintf(stderr, "Could not find header [%s] in y3 image\n",key_name[index]); + fprintf(stderr, "To skip test give -q (unsafe)\n"); + exit(EXIT_FAILURE); + } + if (strcmp(p,key_value[index])){ + fprintf(stderr, "Wrong value of header [%s] in y3 image, got [%s] wanted [%s]\n", + key_name[index],p,key_value[index]); + fprintf(stderr, "To skip test give -q (unsafe)\n"); + exit(EXIT_FAILURE); + } + } + return 0; +} + +static void usage(void) +{ + printf(" -M, --match=key=val,.... image headers needs to have this value\n"); + printf(" -q, --force\tdo not do header check\n"); +} + + +static void parse_match(char *s) +{ + int tot_len= strlen(s); + int index=0; + char *p=s,tmp; + + /* find number of keys = 1 + number of , chars in string */ + keys = 1; + for (int i=0; i<tot_len; i++){ + if (',' == s[i] ) + keys++; } - p = get_str_val(hdr, "board"); + if (keys > MAX_KEYS ) { + fprintf(stderr, "To many header values to match, max %d allowed wanted %d\n", MAX_KEYS, keys); + exit (EXIT_FAILURE); + } - if (p) { - if (0 == strncmp(p, board,strlen(board))){ - return 0; - }else { - fprintf(stderr, "Board header not matching board name \n"); - fprintf(stderr, "header [%s] but wanted [%s]\n",p,board); + while (1){ + char *e; + char *c; + + /* copy key to index */ + e = strstr(p, "="); + c = strstr(p, ","); + if (e == NULL) { + if (c) { + fprintf(stderr, "Header match error: expected = found , instread\n"); + goto error_print; + }else + break; + + fprintf(stderr, "Header match error: expected = found end of string\n"); + goto error_print; + + } else if ( c != NULL && e > c) { + fprintf(stderr, "Header match error: Found , before = . missing a = ??\n"); + goto error_print; } - } else - fprintf(stderr, "Board header not found in image data. Aborting!\n"); + tmp=*e;*e=0; + key_name[index] = strdup(p); + *e=tmp; - exit(EXIT_FAILURE); - return 1; -} + /* copy value */ + p=e+1; + e = strstr(p, "="); + c = strstr(p, ","); -static void usage(void) -{ - printf(" -b, --board=name\tname of the board\n"); - printf(" -q, --force\tdo not do board name check\n"); + /* last value ?*/ + if (c == NULL ) { + key_value[index] = strdup(p); + index++; + break; + } + tmp=*c;*c=0; + key_value[index] = strdup(p); + *c=tmp; + + p=c+1; + index++; + } + + keys=index; + +#if 0 + for (int i=0; i<keys;i++){ + printf("%s=%s\n",key_name[i],key_value[i]); + } +#endif + return; +error_print: + fprintf(stderr, "Trying to parse string [%s]\n",s); + exit (EXIT_FAILURE); } static void opt( int argc, char **argv) @@ -71,19 +149,19 @@ static void opt( int argc, char **argv) while (1) { int option_index = 0; static struct option long_options[] = { - {"board", required_argument, 0, 'b'}, + {"match", required_argument, 0, 'M'}, {"force", no_argument, 0, 'q'}, {0, 0, 0, 0} }; - ch = getopt_long(argc, argv, "b:q", + ch = getopt_long(argc, argv, "M:q", long_options, &option_index); if (ch == -1) break; switch (ch) { - case 'b': - board = optarg; + case 'M': + parse_match(optarg); break; case 'q': force = 1;