imagetag_cmdline.c 42 KB

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