183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2f86ed6a8SGuilherme Maciel Ferreira /*
3f86ed6a8SGuilherme Maciel Ferreira * (C) Copyright 2013
4f86ed6a8SGuilherme Maciel Ferreira *
5f86ed6a8SGuilherme Maciel Ferreira * Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
6f86ed6a8SGuilherme Maciel Ferreira */
7f86ed6a8SGuilherme Maciel Ferreira
8f86ed6a8SGuilherme Maciel Ferreira #include "imagetool.h"
9f86ed6a8SGuilherme Maciel Ferreira
100ca6691cSGuilherme Maciel Ferreira #include <image.h>
110ca6691cSGuilherme Maciel Ferreira
imagetool_get_type(int type)12a93648d1SGuilherme Maciel Ferreira struct image_type_params *imagetool_get_type(int type)
130ca6691cSGuilherme Maciel Ferreira {
141fddd7b6SAndreas Bießmann struct image_type_params **curr;
151fddd7b6SAndreas Bießmann INIT_SECTION(image_type);
161fddd7b6SAndreas Bießmann
171fddd7b6SAndreas Bießmann struct image_type_params **start = __start_image_type;
181fddd7b6SAndreas Bießmann struct image_type_params **end = __stop_image_type;
190ca6691cSGuilherme Maciel Ferreira
20a93648d1SGuilherme Maciel Ferreira for (curr = start; curr != end; curr++) {
211fddd7b6SAndreas Bießmann if ((*curr)->check_image_type) {
221fddd7b6SAndreas Bießmann if (!(*curr)->check_image_type(type))
231fddd7b6SAndreas Bießmann return *curr;
240ca6691cSGuilherme Maciel Ferreira }
250ca6691cSGuilherme Maciel Ferreira }
260ca6691cSGuilherme Maciel Ferreira return NULL;
270ca6691cSGuilherme Maciel Ferreira }
280ca6691cSGuilherme Maciel Ferreira
imagetool_verify_print_header(void * ptr,struct stat * sbuf,struct image_type_params * tparams,struct image_tool_params * params)290ca6691cSGuilherme Maciel Ferreira int imagetool_verify_print_header(
300ca6691cSGuilherme Maciel Ferreira void *ptr,
310ca6691cSGuilherme Maciel Ferreira struct stat *sbuf,
320ca6691cSGuilherme Maciel Ferreira struct image_type_params *tparams,
330ca6691cSGuilherme Maciel Ferreira struct image_tool_params *params)
340ca6691cSGuilherme Maciel Ferreira {
350ca6691cSGuilherme Maciel Ferreira int retval = -1;
361fddd7b6SAndreas Bießmann struct image_type_params **curr;
371fddd7b6SAndreas Bießmann INIT_SECTION(image_type);
380ca6691cSGuilherme Maciel Ferreira
391fddd7b6SAndreas Bießmann struct image_type_params **start = __start_image_type;
401fddd7b6SAndreas Bießmann struct image_type_params **end = __stop_image_type;
41a93648d1SGuilherme Maciel Ferreira
42a93648d1SGuilherme Maciel Ferreira for (curr = start; curr != end; curr++) {
431fddd7b6SAndreas Bießmann if ((*curr)->verify_header) {
441fddd7b6SAndreas Bießmann retval = (*curr)->verify_header((unsigned char *)ptr,
450ca6691cSGuilherme Maciel Ferreira sbuf->st_size, params);
460ca6691cSGuilherme Maciel Ferreira
470ca6691cSGuilherme Maciel Ferreira if (retval == 0) {
480ca6691cSGuilherme Maciel Ferreira /*
490ca6691cSGuilherme Maciel Ferreira * Print the image information if verify is
500ca6691cSGuilherme Maciel Ferreira * successful
510ca6691cSGuilherme Maciel Ferreira */
521fddd7b6SAndreas Bießmann if ((*curr)->print_header) {
53bd6e1420SSimon Glass if (!params->quiet)
541fddd7b6SAndreas Bießmann (*curr)->print_header(ptr);
550ca6691cSGuilherme Maciel Ferreira } else {
560ca6691cSGuilherme Maciel Ferreira fprintf(stderr,
570ca6691cSGuilherme Maciel Ferreira "%s: print_header undefined for %s\n",
581fddd7b6SAndreas Bießmann params->cmdname, (*curr)->name);
590ca6691cSGuilherme Maciel Ferreira }
600ca6691cSGuilherme Maciel Ferreira break;
610ca6691cSGuilherme Maciel Ferreira }
620ca6691cSGuilherme Maciel Ferreira }
63*d32aa3caSJordan Hand }
64*d32aa3caSJordan Hand
65*d32aa3caSJordan Hand return retval;
66*d32aa3caSJordan Hand }
67*d32aa3caSJordan Hand
imagetool_verify_print_header_by_type(void * ptr,struct stat * sbuf,struct image_type_params * tparams,struct image_tool_params * params)68*d32aa3caSJordan Hand int imagetool_verify_print_header_by_type(
69*d32aa3caSJordan Hand void *ptr,
70*d32aa3caSJordan Hand struct stat *sbuf,
71*d32aa3caSJordan Hand struct image_type_params *tparams,
72*d32aa3caSJordan Hand struct image_tool_params *params)
73*d32aa3caSJordan Hand {
74*d32aa3caSJordan Hand int retval;
75*d32aa3caSJordan Hand
76*d32aa3caSJordan Hand retval = tparams->verify_header((unsigned char *)ptr, sbuf->st_size,
77*d32aa3caSJordan Hand params);
78*d32aa3caSJordan Hand
79*d32aa3caSJordan Hand if (retval == 0) {
80*d32aa3caSJordan Hand /*
81*d32aa3caSJordan Hand * Print the image information if verify is successful
82*d32aa3caSJordan Hand */
83*d32aa3caSJordan Hand if (tparams->print_header) {
84*d32aa3caSJordan Hand if (!params->quiet)
85*d32aa3caSJordan Hand tparams->print_header(ptr);
86*d32aa3caSJordan Hand } else {
87*d32aa3caSJordan Hand fprintf(stderr,
88*d32aa3caSJordan Hand "%s: print_header undefined for %s\n",
89*d32aa3caSJordan Hand params->cmdname, tparams->name);
90*d32aa3caSJordan Hand }
91*d32aa3caSJordan Hand } else {
92*d32aa3caSJordan Hand fprintf(stderr,
93*d32aa3caSJordan Hand "%s: verify_header failed for %s with exit code %d\n",
94*d32aa3caSJordan Hand params->cmdname, tparams->name, retval);
950ca6691cSGuilherme Maciel Ferreira }
960ca6691cSGuilherme Maciel Ferreira
970ca6691cSGuilherme Maciel Ferreira return retval;
980ca6691cSGuilherme Maciel Ferreira }
99067d1560SGuilherme Maciel Ferreira
imagetool_save_subimage(const char * file_name,ulong file_data,ulong file_len)10067f946cdSGuilherme Maciel Ferreira int imagetool_save_subimage(
101067d1560SGuilherme Maciel Ferreira const char *file_name,
102067d1560SGuilherme Maciel Ferreira ulong file_data,
103067d1560SGuilherme Maciel Ferreira ulong file_len)
104067d1560SGuilherme Maciel Ferreira {
105067d1560SGuilherme Maciel Ferreira int dfd;
106067d1560SGuilherme Maciel Ferreira
107067d1560SGuilherme Maciel Ferreira dfd = open(file_name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
108067d1560SGuilherme Maciel Ferreira S_IRUSR | S_IWUSR);
109067d1560SGuilherme Maciel Ferreira if (dfd < 0) {
110067d1560SGuilherme Maciel Ferreira fprintf(stderr, "Can't open \"%s\": %s\n",
111067d1560SGuilherme Maciel Ferreira file_name, strerror(errno));
112067d1560SGuilherme Maciel Ferreira return -1;
113067d1560SGuilherme Maciel Ferreira }
114067d1560SGuilherme Maciel Ferreira
115067d1560SGuilherme Maciel Ferreira if (write(dfd, (void *)file_data, file_len) != (ssize_t)file_len) {
116067d1560SGuilherme Maciel Ferreira fprintf(stderr, "Write error on \"%s\": %s\n",
117067d1560SGuilherme Maciel Ferreira file_name, strerror(errno));
118067d1560SGuilherme Maciel Ferreira close(dfd);
119067d1560SGuilherme Maciel Ferreira return -1;
120067d1560SGuilherme Maciel Ferreira }
121067d1560SGuilherme Maciel Ferreira
122067d1560SGuilherme Maciel Ferreira close(dfd);
123067d1560SGuilherme Maciel Ferreira
124067d1560SGuilherme Maciel Ferreira return 0;
125067d1560SGuilherme Maciel Ferreira }
1263837ce65SSimon Glass
imagetool_get_filesize(struct image_tool_params * params,const char * fname)1273837ce65SSimon Glass int imagetool_get_filesize(struct image_tool_params *params, const char *fname)
1283837ce65SSimon Glass {
1293837ce65SSimon Glass struct stat sbuf;
1303837ce65SSimon Glass int fd;
1313837ce65SSimon Glass
1323837ce65SSimon Glass fd = open(fname, O_RDONLY | O_BINARY);
1333837ce65SSimon Glass if (fd < 0) {
1343837ce65SSimon Glass fprintf(stderr, "%s: Can't open %s: %s\n",
1353837ce65SSimon Glass params->cmdname, fname, strerror(errno));
1363837ce65SSimon Glass return -1;
1373837ce65SSimon Glass }
1383837ce65SSimon Glass
1393837ce65SSimon Glass if (fstat(fd, &sbuf) < 0) {
1403837ce65SSimon Glass fprintf(stderr, "%s: Can't stat %s: %s\n",
1413837ce65SSimon Glass params->cmdname, fname, strerror(errno));
142b12a81c4SSimon Glass close(fd);
1433837ce65SSimon Glass return -1;
1443837ce65SSimon Glass }
1453837ce65SSimon Glass close(fd);
1463837ce65SSimon Glass
1473837ce65SSimon Glass return sbuf.st_size;
1483837ce65SSimon Glass }
1495847084fSVagrant Cascadian
imagetool_get_source_date(const char * cmdname,time_t fallback)1505847084fSVagrant Cascadian time_t imagetool_get_source_date(
15187925df2SAlex Kiernan const char *cmdname,
1525847084fSVagrant Cascadian time_t fallback)
1535847084fSVagrant Cascadian {
1545847084fSVagrant Cascadian char *source_date_epoch = getenv("SOURCE_DATE_EPOCH");
1555847084fSVagrant Cascadian
1565847084fSVagrant Cascadian if (source_date_epoch == NULL)
1575847084fSVagrant Cascadian return fallback;
1585847084fSVagrant Cascadian
1595847084fSVagrant Cascadian time_t time = (time_t) strtol(source_date_epoch, NULL, 10);
1605847084fSVagrant Cascadian
1615847084fSVagrant Cascadian if (gmtime(&time) == NULL) {
1625847084fSVagrant Cascadian fprintf(stderr, "%s: SOURCE_DATE_EPOCH is not valid\n",
16387925df2SAlex Kiernan cmdname);
1645847084fSVagrant Cascadian time = 0;
1655847084fSVagrant Cascadian }
1665847084fSVagrant Cascadian
1675847084fSVagrant Cascadian return time;
1685847084fSVagrant Cascadian }
169