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