1/* 2 File autogenerated by gengetopt version 2.22.4 3 generated with the following command: 4 gengetopt --file-name=imagetag_cmdline --file-name=imagetag_cmdline 5 6 The developers of gengetopt consider the fixed text that goes in all 7 gengetopt output files to be in the public domain: 8 we make no copyright claims on it. 9*/ 10 11/* If we use autoconf. */ 12#ifdef HAVE_CONFIG_H 13#include "config.h" 14#endif 15 16#include <stdio.h> 17#include <stdlib.h> 18#include <string.h> 19 20#ifndef FIX_UNUSED 21#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ 22#endif 23 24#include <getopt.h> 25 26#include "imagetag_cmdline.h" 27 28const char *gengetopt_args_info_purpose = "Generate image with CFE imagetag for Broadcom 63xx routers."; 29 30const char *gengetopt_args_info_usage = "Usage: imagetag [OPTIONS]..."; 31 32const char *gengetopt_args_info_description = "Copyright (C) 2008 Axel Gembe\nCopyright (C) 2009-2010 Daniel Dickinson\nLicensed unter the terms of the Gnu General Public License.\n\nGiven a root filesystem, a linux kernel, and an optional CFE, generates an \nimage with an imagetag for a Broadcom 63xx-based router. Additional parameters \nto be specified depend on the specfic brand and model of router."; 33 34const char *gengetopt_args_info_help[] = { 35 " -h, --help Print help and exit", 36 " -V, --version Print version and exit", 37 " -i, --kernel=filename File with LZMA compressed kernel to include in \n the image.", 38 " -f, --rootfs=filename File with RootFS to include in the image.", 39 " -o, --output=filename Name of output file.", 40 " --cfe=filename File with CFE to include in the image.", 41 " -b, --boardid=STRING Board ID to set in the image (must match what \n router expects, e.g. \"96345GW2\").", 42 " -c, --chipid=STRING Chip ID to set in the image (must match the \n actual hardware, e.g. \"6345\").", 43 " -s, --flash-start=address Flash start address. (default=`0xBFC00000')", 44 " -n, --image-offset=offset Offset from start address for the first byte \n after the CFE (in memory). \n (default=`0x10000')", 45 " -v, --tag-version=STRING Version number for imagetag format. \n (default=`6')", 46 " -a, --signature=STRING Magic string (signature), for boards that need \n it. (default=`Broadcom Corporatio')", 47 " -m, --signature2=STRING Second magic string (signature2). \n (default=`ver. 2.0')", 48 " -k, --block-size=STRING Flash erase block size. (default=`0x10000')", 49 " -l, --load-addr=address Kernel load address.", 50 " -e, --entry=address Address where the kernel entry point will be \n for booting.", 51 " -y, --layoutver=STRING Flash layout version (version 2.2x of the \n Broadcom code requires this).", 52 " -1, --info1=STRING String for first vendor information section.", 53 " --altinfo=STRING String for vendor information section \n (alternate/pirelli).", 54 " -2, --info2=STRING String for second vendor information section.", 55 " --root-first Put the rootfs before the kernel (only for \n stock images, e.g. captured from the router's \n flash memory). (default=off)", 56 " -r, --rsa-signature=STRING String for RSA Signature section.", 57 " --second-image-flag=flag-value\n Dual Image Flag (2=not-specified). (possible \n values=\"0\", \"1\", \"2\" default=`2')", 58 " --inactive=flag-value Inactive Flag (2=not-specified). (possible \n values=\"0\", \"1\", \"2\" default=`2')", 59 " --reserved2=STRING String for second reserved section.", 60 " --kernel-file-has-header Indicates that the kernel file includes the \n kernel header with correct load address and \n entry point, so no changes are needed \n (default=off)", 61 " -p, --pad=size (in MiB) Pad the image to this size if smaller (in MiB)", 62 0 63}; 64 65typedef enum {ARG_NO 66 , ARG_FLAG 67 , ARG_STRING 68 , ARG_INT 69} cmdline_parser_arg_type; 70 71static 72void clear_given (struct gengetopt_args_info *args_info); 73static 74void clear_args (struct gengetopt_args_info *args_info); 75 76static int 77cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, 78 struct cmdline_parser_params *params, const char *additional_error); 79 80static int 81cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error); 82 83const char *cmdline_parser_second_image_flag_values[] = {"0", "1", "2", 0}; /*< Possible values for second-image-flag. */ 84const char *cmdline_parser_inactive_values[] = {"0", "1", "2", 0}; /*< Possible values for inactive. */ 85 86static char * 87gengetopt_strdup (const char *s); 88 89static 90void clear_given (struct gengetopt_args_info *args_info) 91{ 92 args_info->help_given = 0 ; 93 args_info->version_given = 0 ; 94 args_info->kernel_given = 0 ; 95 args_info->rootfs_given = 0 ; 96 args_info->output_given = 0 ; 97 args_info->cfe_given = 0 ; 98 args_info->boardid_given = 0 ; 99 args_info->chipid_given = 0 ; 100 args_info->flash_start_given = 0 ; 101 args_info->image_offset_given = 0 ; 102 args_info->tag_version_given = 0 ; 103 args_info->signature_given = 0 ; 104 args_info->signature2_given = 0 ; 105 args_info->block_size_given = 0 ; 106 args_info->load_addr_given = 0 ; 107 args_info->entry_given = 0 ; 108 args_info->layoutver_given = 0 ; 109 args_info->info1_given = 0 ; 110 args_info->altinfo_given = 0 ; 111 args_info->info2_given = 0 ; 112 args_info->root_first_given = 0 ; 113 args_info->rsa_signature_given = 0 ; 114 args_info->second_image_flag_given = 0 ; 115 args_info->inactive_given = 0 ; 116 args_info->reserved2_given = 0 ; 117 args_info->kernel_file_has_header_given = 0 ; 118 args_info->pad_given = 0 ; 119} 120 121static 122void clear_args (struct gengetopt_args_info *args_info) 123{ 124 FIX_UNUSED (args_info); 125 args_info->kernel_arg = NULL; 126 args_info->kernel_orig = NULL; 127 args_info->rootfs_arg = NULL; 128 args_info->rootfs_orig = NULL; 129 args_info->output_arg = NULL; 130 args_info->output_orig = NULL; 131 args_info->cfe_arg = NULL; 132 args_info->cfe_orig = NULL; 133 args_info->boardid_arg = NULL; 134 args_info->boardid_orig = NULL; 135 args_info->chipid_arg = NULL; 136 args_info->chipid_orig = NULL; 137 args_info->flash_start_arg = gengetopt_strdup ("0xBFC00000"); 138 args_info->flash_start_orig = NULL; 139 args_info->image_offset_arg = gengetopt_strdup ("0x10000"); 140 args_info->image_offset_orig = NULL; 141 args_info->tag_version_arg = gengetopt_strdup ("6"); 142 args_info->tag_version_orig = NULL; 143 args_info->signature_arg = gengetopt_strdup ("Broadcom Corporatio"); 144 args_info->signature_orig = NULL; 145 args_info->signature2_arg = gengetopt_strdup ("ver. 2.0"); 146 args_info->signature2_orig = NULL; 147 args_info->block_size_arg = gengetopt_strdup ("0x10000"); 148 args_info->block_size_orig = NULL; 149 args_info->load_addr_arg = NULL; 150 args_info->load_addr_orig = NULL; 151 args_info->entry_arg = NULL; 152 args_info->entry_orig = NULL; 153 args_info->layoutver_arg = NULL; 154 args_info->layoutver_orig = NULL; 155 args_info->info1_arg = NULL; 156 args_info->info1_orig = NULL; 157 args_info->altinfo_arg = NULL; 158 args_info->altinfo_orig = NULL; 159 args_info->info2_arg = NULL; 160 args_info->info2_orig = NULL; 161 args_info->root_first_flag = 0; 162 args_info->rsa_signature_arg = NULL; 163 args_info->rsa_signature_orig = NULL; 164 args_info->second_image_flag_arg = gengetopt_strdup ("2"); 165 args_info->second_image_flag_orig = NULL; 166 args_info->inactive_arg = gengetopt_strdup ("2"); 167 args_info->inactive_orig = NULL; 168 args_info->reserved2_arg = NULL; 169 args_info->reserved2_orig = NULL; 170 args_info->kernel_file_has_header_flag = 0; 171 args_info->pad_orig = NULL; 172 173} 174 175static 176void init_args_info(struct gengetopt_args_info *args_info) 177{ 178 179 180 args_info->help_help = gengetopt_args_info_help[0] ; 181 args_info->version_help = gengetopt_args_info_help[1] ; 182 args_info->kernel_help = gengetopt_args_info_help[2] ; 183 args_info->rootfs_help = gengetopt_args_info_help[3] ; 184 args_info->output_help = gengetopt_args_info_help[4] ; 185 args_info->cfe_help = gengetopt_args_info_help[5] ; 186 args_info->boardid_help = gengetopt_args_info_help[6] ; 187 args_info->chipid_help = gengetopt_args_info_help[7] ; 188 args_info->flash_start_help = gengetopt_args_info_help[8] ; 189 args_info->image_offset_help = gengetopt_args_info_help[9] ; 190 args_info->tag_version_help = gengetopt_args_info_help[10] ; 191 args_info->signature_help = gengetopt_args_info_help[11] ; 192 args_info->signature2_help = gengetopt_args_info_help[12] ; 193 args_info->block_size_help = gengetopt_args_info_help[13] ; 194 args_info->load_addr_help = gengetopt_args_info_help[14] ; 195 args_info->entry_help = gengetopt_args_info_help[15] ; 196 args_info->layoutver_help = gengetopt_args_info_help[16] ; 197 args_info->info1_help = gengetopt_args_info_help[17] ; 198 args_info->altinfo_help = gengetopt_args_info_help[18] ; 199 args_info->info2_help = gengetopt_args_info_help[19] ; 200 args_info->root_first_help = gengetopt_args_info_help[20] ; 201 args_info->rsa_signature_help = gengetopt_args_info_help[21] ; 202 args_info->second_image_flag_help = gengetopt_args_info_help[22] ; 203 args_info->inactive_help = gengetopt_args_info_help[23] ; 204 args_info->reserved2_help = gengetopt_args_info_help[24] ; 205 args_info->kernel_file_has_header_help = gengetopt_args_info_help[25] ; 206 args_info->pad_help = gengetopt_args_info_help[26] ; 207 208} 209 210void 211cmdline_parser_print_version (void) 212{ 213 printf ("%s %s\n", 214 (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), 215 CMDLINE_PARSER_VERSION); 216} 217 218static void print_help_common(void) { 219 cmdline_parser_print_version (); 220 221 if (strlen(gengetopt_args_info_purpose) > 0) 222 printf("\n%s\n", gengetopt_args_info_purpose); 223 224 if (strlen(gengetopt_args_info_usage) > 0) 225 printf("\n%s\n", gengetopt_args_info_usage); 226 227 printf("\n"); 228 229 if (strlen(gengetopt_args_info_description) > 0) 230 printf("%s\n\n", gengetopt_args_info_description); 231} 232 233void 234cmdline_parser_print_help (void) 235{ 236 int i = 0; 237 print_help_common(); 238 while (gengetopt_args_info_help[i]) 239 printf("%s\n", gengetopt_args_info_help[i++]); 240} 241 242void 243cmdline_parser_init (struct gengetopt_args_info *args_info) 244{ 245 clear_given (args_info); 246 clear_args (args_info); 247 init_args_info (args_info); 248} 249 250void 251cmdline_parser_params_init(struct cmdline_parser_params *params) 252{ 253 if (params) 254 { 255 params->override = 0; 256 params->initialize = 1; 257 params->check_required = 1; 258 params->check_ambiguity = 0; 259 params->print_errors = 1; 260 } 261} 262 263struct cmdline_parser_params * 264cmdline_parser_params_create(void) 265{ 266 struct cmdline_parser_params *params = 267 (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); 268 cmdline_parser_params_init(params); 269 return params; 270} 271 272static void 273free_string_field (char **s) 274{ 275 if (*s) 276 { 277 free (*s); 278 *s = 0; 279 } 280} 281 282 283static void 284cmdline_parser_release (struct gengetopt_args_info *args_info) 285{ 286 287 free_string_field (&(args_info->kernel_arg)); 288 free_string_field (&(args_info->kernel_orig)); 289 free_string_field (&(args_info->rootfs_arg)); 290 free_string_field (&(args_info->rootfs_orig)); 291 free_string_field (&(args_info->output_arg)); 292 free_string_field (&(args_info->output_orig)); 293 free_string_field (&(args_info->cfe_arg)); 294 free_string_field (&(args_info->cfe_orig)); 295 free_string_field (&(args_info->boardid_arg)); 296 free_string_field (&(args_info->boardid_orig)); 297 free_string_field (&(args_info->chipid_arg)); 298 free_string_field (&(args_info->chipid_orig)); 299 free_string_field (&(args_info->flash_start_arg)); 300 free_string_field (&(args_info->flash_start_orig)); 301 free_string_field (&(args_info->image_offset_arg)); 302 free_string_field (&(args_info->image_offset_orig)); 303 free_string_field (&(args_info->tag_version_arg)); 304 free_string_field (&(args_info->tag_version_orig)); 305 free_string_field (&(args_info->signature_arg)); 306 free_string_field (&(args_info->signature_orig)); 307 free_string_field (&(args_info->signature2_arg)); 308 free_string_field (&(args_info->signature2_orig)); 309 free_string_field (&(args_info->block_size_arg)); 310 free_string_field (&(args_info->block_size_orig)); 311 free_string_field (&(args_info->load_addr_arg)); 312 free_string_field (&(args_info->load_addr_orig)); 313 free_string_field (&(args_info->entry_arg)); 314 free_string_field (&(args_info->entry_orig)); 315 free_string_field (&(args_info->layoutver_arg)); 316 free_string_field (&(args_info->layoutver_orig)); 317 free_string_field (&(args_info->info1_arg)); 318 free_string_field (&(args_info->info1_orig)); 319 free_string_field (&(args_info->altinfo_arg)); 320 free_string_field (&(args_info->altinfo_orig)); 321 free_string_field (&(args_info->info2_arg)); 322 free_string_field (&(args_info->info2_orig)); 323 free_string_field (&(args_info->rsa_signature_arg)); 324 free_string_field (&(args_info->rsa_signature_orig)); 325 free_string_field (&(args_info->second_image_flag_arg)); 326 free_string_field (&(args_info->second_image_flag_orig)); 327 free_string_field (&(args_info->inactive_arg)); 328 free_string_field (&(args_info->inactive_orig)); 329 free_string_field (&(args_info->reserved2_arg)); 330 free_string_field (&(args_info->reserved2_orig)); 331 free_string_field (&(args_info->pad_orig)); 332 333 334 335 clear_given (args_info); 336} 337 338/** 339 * @param val the value to check 340 * @param values the possible values 341 * @return the index of the matched value: 342 * -1 if no value matched, 343 * -2 if more than one value has matched 344 */ 345static int 346check_possible_values(const char *val, const char *values[]) 347{ 348 int i, found, last; 349 size_t len; 350 351 if (!val) /* otherwise strlen() crashes below */ 352 return -1; /* -1 means no argument for the option */ 353 354 found = last = 0; 355 356 for (i = 0, len = strlen(val); values[i]; ++i) 357 { 358 if (strncmp(val, values[i], len) == 0) 359 { 360 ++found; 361 last = i; 362 if (strlen(values[i]) == len) 363 return i; /* exact macth no need to check more */ 364 } 365 } 366 367 if (found == 1) /* one match: OK */ 368 return last; 369 370 return (found ? -2 : -1); /* return many values or none matched */ 371} 372 373 374static void 375write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) 376{ 377 int found = -1; 378 if (arg) { 379 if (values) { 380 found = check_possible_values(arg, values); 381 } 382 if (found >= 0) 383 fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]); 384 else 385 fprintf(outfile, "%s=\"%s\"\n", opt, arg); 386 } else { 387 fprintf(outfile, "%s\n", opt); 388 } 389} 390 391 392int 393cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) 394{ 395 int i = 0; 396 397 if (!outfile) 398 { 399 fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); 400 return EXIT_FAILURE; 401 } 402 403 if (args_info->help_given) 404 write_into_file(outfile, "help", 0, 0 ); 405 if (args_info->version_given) 406 write_into_file(outfile, "version", 0, 0 ); 407 if (args_info->kernel_given) 408 write_into_file(outfile, "kernel", args_info->kernel_orig, 0); 409 if (args_info->rootfs_given) 410 write_into_file(outfile, "rootfs", args_info->rootfs_orig, 0); 411 if (args_info->output_given) 412 write_into_file(outfile, "output", args_info->output_orig, 0); 413 if (args_info->cfe_given) 414 write_into_file(outfile, "cfe", args_info->cfe_orig, 0); 415 if (args_info->boardid_given) 416 write_into_file(outfile, "boardid", args_info->boardid_orig, 0); 417 if (args_info->chipid_given) 418 write_into_file(outfile, "chipid", args_info->chipid_orig, 0); 419 if (args_info->flash_start_given) 420 write_into_file(outfile, "flash-start", args_info->flash_start_orig, 0); 421 if (args_info->image_offset_given) 422 write_into_file(outfile, "image-offset", args_info->image_offset_orig, 0); 423 if (args_info->tag_version_given) 424 write_into_file(outfile, "tag-version", args_info->tag_version_orig, 0); 425 if (args_info->signature_given) 426 write_into_file(outfile, "signature", args_info->signature_orig, 0); 427 if (args_info->signature2_given) 428 write_into_file(outfile, "signature2", args_info->signature2_orig, 0); 429 if (args_info->block_size_given) 430 write_into_file(outfile, "block-size", args_info->block_size_orig, 0); 431 if (args_info->load_addr_given) 432 write_into_file(outfile, "load-addr", args_info->load_addr_orig, 0); 433 if (args_info->entry_given) 434 write_into_file(outfile, "entry", args_info->entry_orig, 0); 435 if (args_info->layoutver_given) 436 write_into_file(outfile, "layoutver", args_info->layoutver_orig, 0); 437 if (args_info->info1_given) 438 write_into_file(outfile, "info1", args_info->info1_orig, 0); 439 if (args_info->altinfo_given) 440 write_into_file(outfile, "altinfo", args_info->altinfo_orig, 0); 441 if (args_info->info2_given) 442 write_into_file(outfile, "info2", args_info->info2_orig, 0); 443 if (args_info->root_first_given) 444 write_into_file(outfile, "root-first", 0, 0 ); 445 if (args_info->rsa_signature_given) 446 write_into_file(outfile, "rsa-signature", args_info->rsa_signature_orig, 0); 447 if (args_info->second_image_flag_given) 448 write_into_file(outfile, "second-image-flag", args_info->second_image_flag_orig, cmdline_parser_second_image_flag_values); 449 if (args_info->inactive_given) 450 write_into_file(outfile, "inactive", args_info->inactive_orig, cmdline_parser_inactive_values); 451 if (args_info->reserved2_given) 452 write_into_file(outfile, "reserved2", args_info->reserved2_orig, 0); 453 if (args_info->kernel_file_has_header_given) 454 write_into_file(outfile, "kernel-file-has-header", 0, 0 ); 455 if (args_info->pad_given) 456 write_into_file(outfile, "pad", args_info->pad_orig, 0); 457 458 459 i = EXIT_SUCCESS; 460 return i; 461} 462 463int 464cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) 465{ 466 FILE *outfile; 467 int i = 0; 468 469 outfile = fopen(filename, "w"); 470 471 if (!outfile) 472 { 473 fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); 474 return EXIT_FAILURE; 475 } 476 477 i = cmdline_parser_dump(outfile, args_info); 478 fclose (outfile); 479 480 return i; 481} 482 483void 484cmdline_parser_free (struct gengetopt_args_info *args_info) 485{ 486 cmdline_parser_release (args_info); 487} 488 489/** @brief replacement of strdup, which is not standard */ 490char * 491gengetopt_strdup (const char *s) 492{ 493 char *result = 0; 494 if (!s) 495 return result; 496 497 result = (char*)malloc(strlen(s) + 1); 498 if (result == (char*)0) 499 return (char*)0; 500 strcpy(result, s); 501 return result; 502} 503 504int 505cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) 506{ 507 return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); 508} 509 510int 511cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, 512 struct cmdline_parser_params *params) 513{ 514 int result; 515 result = cmdline_parser_internal (argc, argv, args_info, params, 0); 516 517 if (result == EXIT_FAILURE) 518 { 519 cmdline_parser_free (args_info); 520 exit (EXIT_FAILURE); 521 } 522 523 return result; 524} 525 526int 527cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) 528{ 529 int result; 530 struct cmdline_parser_params params; 531 532 params.override = override; 533 params.initialize = initialize; 534 params.check_required = check_required; 535 params.check_ambiguity = 0; 536 params.print_errors = 1; 537 538 result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); 539 540 if (result == EXIT_FAILURE) 541 { 542 cmdline_parser_free (args_info); 543 exit (EXIT_FAILURE); 544 } 545 546 return result; 547} 548 549int 550cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) 551{ 552 int result = EXIT_SUCCESS; 553 554 if (cmdline_parser_required2(args_info, prog_name, 0) > 0) 555 result = EXIT_FAILURE; 556 557 if (result == EXIT_FAILURE) 558 { 559 cmdline_parser_free (args_info); 560 exit (EXIT_FAILURE); 561 } 562 563 return result; 564} 565 566int 567cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error) 568{ 569 int error = 0; 570 FIX_UNUSED (additional_error); 571 572 /* checks for required options */ 573 if (! args_info->kernel_given) 574 { 575 fprintf (stderr, "%s: '--kernel' ('-i') option required%s\n", prog_name, (additional_error ? additional_error : "")); 576 error = 1; 577 } 578 579 if (! args_info->rootfs_given) 580 { 581 fprintf (stderr, "%s: '--rootfs' ('-f') option required%s\n", prog_name, (additional_error ? additional_error : "")); 582 error = 1; 583 } 584 585 if (! args_info->output_given) 586 { 587 fprintf (stderr, "%s: '--output' ('-o') option required%s\n", prog_name, (additional_error ? additional_error : "")); 588 error = 1; 589 } 590 591 if (! args_info->boardid_given) 592 { 593 fprintf (stderr, "%s: '--boardid' ('-b') option required%s\n", prog_name, (additional_error ? additional_error : "")); 594 error = 1; 595 } 596 597 if (! args_info->chipid_given) 598 { 599 fprintf (stderr, "%s: '--chipid' ('-c') option required%s\n", prog_name, (additional_error ? additional_error : "")); 600 error = 1; 601 } 602 603 if (! args_info->load_addr_given) 604 { 605 fprintf (stderr, "%s: '--load-addr' ('-l') option required%s\n", prog_name, (additional_error ? additional_error : "")); 606 error = 1; 607 } 608 609 if (! args_info->entry_given) 610 { 611 fprintf (stderr, "%s: '--entry' ('-e') option required%s\n", prog_name, (additional_error ? additional_error : "")); 612 error = 1; 613 } 614 615 616 /* checks for dependences among options */ 617 618 return error; 619} 620 621 622static char *package_name = 0; 623 624/** 625 * @brief updates an option 626 * @param field the generic pointer to the field to update 627 * @param orig_field the pointer to the orig field 628 * @param field_given the pointer to the number of occurrence of this option 629 * @param prev_given the pointer to the number of occurrence already seen 630 * @param value the argument for this option (if null no arg was specified) 631 * @param possible_values the possible values for this option (if specified) 632 * @param default_value the default value (in case the option only accepts fixed values) 633 * @param arg_type the type of this option 634 * @param check_ambiguity @see cmdline_parser_params.check_ambiguity 635 * @param override @see cmdline_parser_params.override 636 * @param no_free whether to free a possible previous value 637 * @param multiple_option whether this is a multiple option 638 * @param long_opt the corresponding long option 639 * @param short_opt the corresponding short option (or '-' if none) 640 * @param additional_error possible further error specification 641 */ 642static 643int update_arg(void *field, char **orig_field, 644 unsigned int *field_given, unsigned int *prev_given, 645 char *value, const char *possible_values[], 646 const char *default_value, 647 cmdline_parser_arg_type arg_type, 648 int check_ambiguity, int override, 649 int no_free, int multiple_option, 650 const char *long_opt, char short_opt, 651 const char *additional_error) 652{ 653 char *stop_char = 0; 654 const char *val = value; 655 int found; 656 char **string_field; 657 FIX_UNUSED (field); 658 659 stop_char = 0; 660 found = 0; 661 662 if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) 663 { 664 if (short_opt != '-') 665 fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", 666 package_name, long_opt, short_opt, 667 (additional_error ? additional_error : "")); 668 else 669 fprintf (stderr, "%s: `--%s' option given more than once%s\n", 670 package_name, long_opt, 671 (additional_error ? additional_error : "")); 672 return 1; /* failure */ 673 } 674 675 if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0) 676 { 677 if (short_opt != '-') 678 fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n", 679 package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt, 680 (additional_error ? additional_error : "")); 681 else 682 fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n", 683 package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, 684 (additional_error ? additional_error : "")); 685 return 1; /* failure */ 686 } 687 688 if (field_given && *field_given && ! override) 689 return 0; 690 if (prev_given) 691 (*prev_given)++; 692 if (field_given) 693 (*field_given)++; 694 if (possible_values) 695 val = possible_values[found]; 696 697 switch(arg_type) { 698 case ARG_FLAG: 699 *((int *)field) = !*((int *)field); 700 break; 701 case ARG_INT: 702 if (val) *((int *)field) = strtol (val, &stop_char, 0); 703 break; 704 case ARG_STRING: 705 if (val) { 706 string_field = (char **)field; 707 if (!no_free && *string_field) 708 free (*string_field); /* free previous string */ 709 *string_field = gengetopt_strdup (val); 710 } 711 break; 712 default: 713 break; 714 }; 715 716 /* check numeric conversion */ 717 switch(arg_type) { 718 case ARG_INT: 719 if (val && !(stop_char && *stop_char == '\0')) { 720 fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); 721 return 1; /* failure */ 722 } 723 break; 724 default: 725 ; 726 }; 727 728 /* store the original value */ 729 switch(arg_type) { 730 case ARG_NO: 731 case ARG_FLAG: 732 break; 733 default: 734 if (value && orig_field) { 735 if (no_free) { 736 *orig_field = value; 737 } else { 738 if (*orig_field) 739 free (*orig_field); /* free previous string */ 740 *orig_field = gengetopt_strdup (value); 741 } 742 } 743 }; 744 745 return 0; /* OK */ 746} 747 748 749int 750cmdline_parser_internal ( 751 int argc, char **argv, struct gengetopt_args_info *args_info, 752 struct cmdline_parser_params *params, const char *additional_error) 753{ 754 int c; /* Character of the parsed option. */ 755 756 int error = 0; 757 struct gengetopt_args_info local_args_info; 758 759 int override; 760 int initialize; 761 int check_required; 762 int check_ambiguity; 763 764 package_name = argv[0]; 765 766 override = params->override; 767 initialize = params->initialize; 768 check_required = params->check_required; 769 check_ambiguity = params->check_ambiguity; 770 771 if (initialize) 772 cmdline_parser_init (args_info); 773 774 cmdline_parser_init (&local_args_info); 775 776 optarg = 0; 777 optind = 0; 778 opterr = params->print_errors; 779 optopt = '?'; 780 781 while (1) 782 { 783 int option_index = 0; 784 785 static struct option long_options[] = { 786 { "help", 0, NULL, 'h' }, 787 { "version", 0, NULL, 'V' }, 788 { "kernel", 1, NULL, 'i' }, 789 { "rootfs", 1, NULL, 'f' }, 790 { "output", 1, NULL, 'o' }, 791 { "cfe", 1, NULL, 0 }, 792 { "boardid", 1, NULL, 'b' }, 793 { "chipid", 1, NULL, 'c' }, 794 { "flash-start", 1, NULL, 's' }, 795 { "image-offset", 1, NULL, 'n' }, 796 { "tag-version", 1, NULL, 'v' }, 797 { "signature", 1, NULL, 'a' }, 798 { "signature2", 1, NULL, 'm' }, 799 { "block-size", 1, NULL, 'k' }, 800 { "load-addr", 1, NULL, 'l' }, 801 { "entry", 1, NULL, 'e' }, 802 { "layoutver", 1, NULL, 'y' }, 803 { "info1", 1, NULL, '1' }, 804 { "altinfo", 1, NULL, 0 }, 805 { "info2", 1, NULL, '2' }, 806 { "root-first", 0, NULL, 0 }, 807 { "rsa-signature", 1, NULL, 'r' }, 808 { "second-image-flag", 1, NULL, 0 }, 809 { "inactive", 1, NULL, 0 }, 810 { "reserved2", 1, NULL, 0 }, 811 { "kernel-file-has-header", 0, NULL, 0 }, 812 { "pad", 1, NULL, 'p' }, 813 { 0, 0, 0, 0 } 814 }; 815 816 c = getopt_long (argc, argv, "hVi:f:o:b:c:s:n:v:a:m:k:l:e:y:1:2:r:p:", long_options, &option_index); 817 818 if (c == -1) break; /* Exit from `while (1)' loop. */ 819 820 switch (c) 821 { 822 case 'h': /* Print help and exit. */ 823 cmdline_parser_print_help (); 824 cmdline_parser_free (&local_args_info); 825 exit (EXIT_SUCCESS); 826 827 case 'V': /* Print version and exit. */ 828 cmdline_parser_print_version (); 829 cmdline_parser_free (&local_args_info); 830 exit (EXIT_SUCCESS); 831 832 case 'i': /* File with LZMA compressed kernel to include in the image.. */ 833 834 835 if (update_arg( (void *)&(args_info->kernel_arg), 836 &(args_info->kernel_orig), &(args_info->kernel_given), 837 &(local_args_info.kernel_given), optarg, 0, 0, ARG_STRING, 838 check_ambiguity, override, 0, 0, 839 "kernel", 'i', 840 additional_error)) 841 goto failure; 842 843 break; 844 case 'f': /* File with RootFS to include in the image.. */ 845 846 847 if (update_arg( (void *)&(args_info->rootfs_arg), 848 &(args_info->rootfs_orig), &(args_info->rootfs_given), 849 &(local_args_info.rootfs_given), optarg, 0, 0, ARG_STRING, 850 check_ambiguity, override, 0, 0, 851 "rootfs", 'f', 852 additional_error)) 853 goto failure; 854 855 break; 856 case 'o': /* Name of output file.. */ 857 858 859 if (update_arg( (void *)&(args_info->output_arg), 860 &(args_info->output_orig), &(args_info->output_given), 861 &(local_args_info.output_given), optarg, 0, 0, ARG_STRING, 862 check_ambiguity, override, 0, 0, 863 "output", 'o', 864 additional_error)) 865 goto failure; 866 867 break; 868 case 'b': /* Board ID to set in the image (must match what router expects, e.g. \"96345GW2\").. */ 869 870 871 if (update_arg( (void *)&(args_info->boardid_arg), 872 &(args_info->boardid_orig), &(args_info->boardid_given), 873 &(local_args_info.boardid_given), optarg, 0, 0, ARG_STRING, 874 check_ambiguity, override, 0, 0, 875 "boardid", 'b', 876 additional_error)) 877 goto failure; 878 879 break; 880 case 'c': /* Chip ID to set in the image (must match the actual hardware, e.g. \"6345\").. */ 881 882 883 if (update_arg( (void *)&(args_info->chipid_arg), 884 &(args_info->chipid_orig), &(args_info->chipid_given), 885 &(local_args_info.chipid_given), optarg, 0, 0, ARG_STRING, 886 check_ambiguity, override, 0, 0, 887 "chipid", 'c', 888 additional_error)) 889 goto failure; 890 891 break; 892 case 's': /* Flash start address.. */ 893 894 895 if (update_arg( (void *)&(args_info->flash_start_arg), 896 &(args_info->flash_start_orig), &(args_info->flash_start_given), 897 &(local_args_info.flash_start_given), optarg, 0, "0xBFC00000", ARG_STRING, 898 check_ambiguity, override, 0, 0, 899 "flash-start", 's', 900 additional_error)) 901 goto failure; 902 903 break; 904 case 'n': /* Offset from start address for the first byte after the CFE (in memory).. */ 905 906 907 if (update_arg( (void *)&(args_info->image_offset_arg), 908 &(args_info->image_offset_orig), &(args_info->image_offset_given), 909 &(local_args_info.image_offset_given), optarg, 0, "0x10000", ARG_STRING, 910 check_ambiguity, override, 0, 0, 911 "image-offset", 'n', 912 additional_error)) 913 goto failure; 914 915 break; 916 case 'v': /* Version number for imagetag format.. */ 917 918 919 if (update_arg( (void *)&(args_info->tag_version_arg), 920 &(args_info->tag_version_orig), &(args_info->tag_version_given), 921 &(local_args_info.tag_version_given), optarg, 0, "6", ARG_STRING, 922 check_ambiguity, override, 0, 0, 923 "tag-version", 'v', 924 additional_error)) 925 goto failure; 926 927 break; 928 case 'a': /* Magic string (signature), for boards that need it.. */ 929 930 931 if (update_arg( (void *)&(args_info->signature_arg), 932 &(args_info->signature_orig), &(args_info->signature_given), 933 &(local_args_info.signature_given), optarg, 0, "Broadcom Corporatio", ARG_STRING, 934 check_ambiguity, override, 0, 0, 935 "signature", 'a', 936 additional_error)) 937 goto failure; 938 939 break; 940 case 'm': /* Second magic string (signature2).. */ 941 942 943 if (update_arg( (void *)&(args_info->signature2_arg), 944 &(args_info->signature2_orig), &(args_info->signature2_given), 945 &(local_args_info.signature2_given), optarg, 0, "ver. 2.0", ARG_STRING, 946 check_ambiguity, override, 0, 0, 947 "signature2", 'm', 948 additional_error)) 949 goto failure; 950 951 break; 952 case 'k': /* Flash erase block size.. */ 953 954 955 if (update_arg( (void *)&(args_info->block_size_arg), 956 &(args_info->block_size_orig), &(args_info->block_size_given), 957 &(local_args_info.block_size_given), optarg, 0, "0x10000", ARG_STRING, 958 check_ambiguity, override, 0, 0, 959 "block-size", 'k', 960 additional_error)) 961 goto failure; 962 963 break; 964 case 'l': /* Kernel load address.. */ 965 966 967 if (update_arg( (void *)&(args_info->load_addr_arg), 968 &(args_info->load_addr_orig), &(args_info->load_addr_given), 969 &(local_args_info.load_addr_given), optarg, 0, 0, ARG_STRING, 970 check_ambiguity, override, 0, 0, 971 "load-addr", 'l', 972 additional_error)) 973 goto failure; 974 975 break; 976 case 'e': /* Address where the kernel entry point will be for booting.. */ 977 978 979 if (update_arg( (void *)&(args_info->entry_arg), 980 &(args_info->entry_orig), &(args_info->entry_given), 981 &(local_args_info.entry_given), optarg, 0, 0, ARG_STRING, 982 check_ambiguity, override, 0, 0, 983 "entry", 'e', 984 additional_error)) 985 goto failure; 986 987 break; 988 case 'y': /* Flash layout version (version 2.2x of the Broadcom code requires this).. */ 989 990 991 if (update_arg( (void *)&(args_info->layoutver_arg), 992 &(args_info->layoutver_orig), &(args_info->layoutver_given), 993 &(local_args_info.layoutver_given), optarg, 0, 0, ARG_STRING, 994 check_ambiguity, override, 0, 0, 995 "layoutver", 'y', 996 additional_error)) 997 goto failure; 998 999 break; 1000 case '1': /* String for first vendor information section.. */ 1001 1002 1003 if (update_arg( (void *)&(args_info->info1_arg), 1004 &(args_info->info1_orig), &(args_info->info1_given), 1005 &(local_args_info.info1_given), optarg, 0, 0, ARG_STRING, 1006 check_ambiguity, override, 0, 0, 1007 "info1", '1', 1008 additional_error)) 1009 goto failure; 1010 1011 break; 1012 case '2': /* String for second vendor information section.. */ 1013 1014 1015 if (update_arg( (void *)&(args_info->info2_arg), 1016 &(args_info->info2_orig), &(args_info->info2_given), 1017 &(local_args_info.info2_given), optarg, 0, 0, ARG_STRING, 1018 check_ambiguity, override, 0, 0, 1019 "info2", '2', 1020 additional_error)) 1021 goto failure; 1022 1023 break; 1024 case 'r': /* String for RSA Signature section.. */ 1025 1026 1027 if (update_arg( (void *)&(args_info->rsa_signature_arg), 1028 &(args_info->rsa_signature_orig), &(args_info->rsa_signature_given), 1029 &(local_args_info.rsa_signature_given), optarg, 0, 0, ARG_STRING, 1030 check_ambiguity, override, 0, 0, 1031 "rsa-signature", 'r', 1032 additional_error)) 1033 goto failure; 1034 1035 break; 1036 case 'p': /* Pad the image to this size if smaller (in MiB). */ 1037 1038 1039 if (update_arg( (void *)&(args_info->pad_arg), 1040 &(args_info->pad_orig), &(args_info->pad_given), 1041 &(local_args_info.pad_given), optarg, 0, 0, ARG_INT, 1042 check_ambiguity, override, 0, 0, 1043 "pad", 'p', 1044 additional_error)) 1045 goto failure; 1046 1047 break; 1048 1049 case 0: /* Long option with no short option */ 1050 /* File with CFE to include in the image.. */ 1051 if (strcmp (long_options[option_index].name, "cfe") == 0) 1052 { 1053 1054 1055 if (update_arg( (void *)&(args_info->cfe_arg), 1056 &(args_info->cfe_orig), &(args_info->cfe_given), 1057 &(local_args_info.cfe_given), optarg, 0, 0, ARG_STRING, 1058 check_ambiguity, override, 0, 0, 1059 "cfe", '-', 1060 additional_error)) 1061 goto failure; 1062 1063 } 1064 /* String for vendor information section (alternate/pirelli).. */ 1065 else if (strcmp (long_options[option_index].name, "altinfo") == 0) 1066 { 1067 1068 1069 if (update_arg( (void *)&(args_info->altinfo_arg), 1070 &(args_info->altinfo_orig), &(args_info->altinfo_given), 1071 &(local_args_info.altinfo_given), optarg, 0, 0, ARG_STRING, 1072 check_ambiguity, override, 0, 0, 1073 "altinfo", '-', 1074 additional_error)) 1075 goto failure; 1076 1077 } 1078 /* Put the rootfs before the kernel (only for stock images, e.g. captured from the router's flash memory).. */ 1079 else if (strcmp (long_options[option_index].name, "root-first") == 0) 1080 { 1081 1082 1083 if (update_arg((void *)&(args_info->root_first_flag), 0, &(args_info->root_first_given), 1084 &(local_args_info.root_first_given), optarg, 0, 0, ARG_FLAG, 1085 check_ambiguity, override, 1, 0, "root-first", '-', 1086 additional_error)) 1087 goto failure; 1088 1089 } 1090 /* Dual Image Flag (2=not-specified).. */ 1091 else if (strcmp (long_options[option_index].name, "second-image-flag") == 0) 1092 { 1093 1094 1095 if (update_arg( (void *)&(args_info->second_image_flag_arg), 1096 &(args_info->second_image_flag_orig), &(args_info->second_image_flag_given), 1097 &(local_args_info.second_image_flag_given), optarg, cmdline_parser_second_image_flag_values, "2", ARG_STRING, 1098 check_ambiguity, override, 0, 0, 1099 "second-image-flag", '-', 1100 additional_error)) 1101 goto failure; 1102 1103 } 1104 /* Inactive Flag (2=not-specified).. */ 1105 else if (strcmp (long_options[option_index].name, "inactive") == 0) 1106 { 1107 1108 1109 if (update_arg( (void *)&(args_info->inactive_arg), 1110 &(args_info->inactive_orig), &(args_info->inactive_given), 1111 &(local_args_info.inactive_given), optarg, cmdline_parser_inactive_values, "2", ARG_STRING, 1112 check_ambiguity, override, 0, 0, 1113 "inactive", '-', 1114 additional_error)) 1115 goto failure; 1116 1117 } 1118 /* String for second reserved section.. */ 1119 else if (strcmp (long_options[option_index].name, "reserved2") == 0) 1120 { 1121 1122 1123 if (update_arg( (void *)&(args_info->reserved2_arg), 1124 &(args_info->reserved2_orig), &(args_info->reserved2_given), 1125 &(local_args_info.reserved2_given), optarg, 0, 0, ARG_STRING, 1126 check_ambiguity, override, 0, 0, 1127 "reserved2", '-', 1128 additional_error)) 1129 goto failure; 1130 1131 } 1132 /* Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed. */ 1133 else if (strcmp (long_options[option_index].name, "kernel-file-has-header") == 0) 1134 { 1135 1136 1137 if (update_arg((void *)&(args_info->kernel_file_has_header_flag), 0, &(args_info->kernel_file_has_header_given), 1138 &(local_args_info.kernel_file_has_header_given), optarg, 0, 0, ARG_FLAG, 1139 check_ambiguity, override, 1, 0, "kernel-file-has-header", '-', 1140 additional_error)) 1141 goto failure; 1142 1143 } 1144 1145 break; 1146 case '?': /* Invalid option. */ 1147 /* `getopt_long' already printed an error message. */ 1148 goto failure; 1149 1150 default: /* bug: option not considered. */ 1151 fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); 1152 abort (); 1153 } /* switch */ 1154 } /* while */ 1155 1156 1157 1158 if (check_required) 1159 { 1160 error += cmdline_parser_required2 (args_info, argv[0], additional_error); 1161 } 1162 1163 cmdline_parser_release (&local_args_info); 1164 1165 if ( error ) 1166 return (EXIT_FAILURE); 1167 1168 return 0; 1169 1170failure: 1171 1172 cmdline_parser_release (&local_args_info); 1173 return (EXIT_FAILURE); 1174} 1175