xref: /openbmc/u-boot/tools/imagetool.c (revision 14453fbfadc2f98ca35d6033140466c7a4b4947a)
1  // SPDX-License-Identifier: GPL-2.0+
2  /*
3   * (C) Copyright 2013
4   *
5   * Written by Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
6   */
7  
8  #include "imagetool.h"
9  
10  #include <image.h>
11  
12  struct image_type_params *imagetool_get_type(int type)
13  {
14  	struct image_type_params **curr;
15  	INIT_SECTION(image_type);
16  
17  	struct image_type_params **start = __start_image_type;
18  	struct image_type_params **end = __stop_image_type;
19  
20  	for (curr = start; curr != end; curr++) {
21  		if ((*curr)->check_image_type) {
22  			if (!(*curr)->check_image_type(type))
23  				return *curr;
24  		}
25  	}
26  	return NULL;
27  }
28  
29  int imagetool_verify_print_header(
30  	void *ptr,
31  	struct stat *sbuf,
32  	struct image_type_params *tparams,
33  	struct image_tool_params *params)
34  {
35  	int retval = -1;
36  	struct image_type_params **curr;
37  	INIT_SECTION(image_type);
38  
39  	struct image_type_params **start = __start_image_type;
40  	struct image_type_params **end = __stop_image_type;
41  
42  	for (curr = start; curr != end; curr++) {
43  		if ((*curr)->verify_header) {
44  			retval = (*curr)->verify_header((unsigned char *)ptr,
45  						     sbuf->st_size, params);
46  
47  			if (retval == 0) {
48  				/*
49  				 * Print the image information if verify is
50  				 * successful
51  				 */
52  				if ((*curr)->print_header) {
53  					if (!params->quiet)
54  						(*curr)->print_header(ptr);
55  				} else {
56  					fprintf(stderr,
57  						"%s: print_header undefined for %s\n",
58  						params->cmdname, (*curr)->name);
59  				}
60  				break;
61  			}
62  		}
63  	}
64  
65  	return retval;
66  }
67  
68  int imagetool_verify_print_header_by_type(
69  	void *ptr,
70  	struct stat *sbuf,
71  	struct image_type_params *tparams,
72  	struct image_tool_params *params)
73  {
74  	int retval;
75  
76  	retval = tparams->verify_header((unsigned char *)ptr, sbuf->st_size,
77  			params);
78  
79  	if (retval == 0) {
80  		/*
81  		 * Print the image information if verify is successful
82  		 */
83  		if (tparams->print_header) {
84  			if (!params->quiet)
85  				tparams->print_header(ptr);
86  		} else {
87  			fprintf(stderr,
88  				"%s: print_header undefined for %s\n",
89  				params->cmdname, tparams->name);
90  		}
91  	} else {
92  		fprintf(stderr,
93  			"%s: verify_header failed for %s with exit code %d\n",
94  			params->cmdname, tparams->name, retval);
95  	}
96  
97  	return retval;
98  }
99  
100  int imagetool_save_subimage(
101  	const char *file_name,
102  	ulong file_data,
103  	ulong file_len)
104  {
105  	int dfd;
106  
107  	dfd = open(file_name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
108  		   S_IRUSR | S_IWUSR);
109  	if (dfd < 0) {
110  		fprintf(stderr, "Can't open \"%s\": %s\n",
111  			file_name, strerror(errno));
112  		return -1;
113  	}
114  
115  	if (write(dfd, (void *)file_data, file_len) != (ssize_t)file_len) {
116  		fprintf(stderr, "Write error on \"%s\": %s\n",
117  			file_name, strerror(errno));
118  		close(dfd);
119  		return -1;
120  	}
121  
122  	close(dfd);
123  
124  	return 0;
125  }
126  
127  int imagetool_get_filesize(struct image_tool_params *params, const char *fname)
128  {
129  	struct stat sbuf;
130  	int fd;
131  
132  	fd = open(fname, O_RDONLY | O_BINARY);
133  	if (fd < 0) {
134  		fprintf(stderr, "%s: Can't open %s: %s\n",
135  			params->cmdname, fname, strerror(errno));
136  		return -1;
137  	}
138  
139  	if (fstat(fd, &sbuf) < 0) {
140  		fprintf(stderr, "%s: Can't stat %s: %s\n",
141  			params->cmdname, fname, strerror(errno));
142  		close(fd);
143  		return -1;
144  	}
145  	close(fd);
146  
147  	return sbuf.st_size;
148  }
149  
150  time_t imagetool_get_source_date(
151  	 const char *cmdname,
152  	 time_t fallback)
153  {
154  	char *source_date_epoch = getenv("SOURCE_DATE_EPOCH");
155  
156  	if (source_date_epoch == NULL)
157  		return fallback;
158  
159  	time_t time = (time_t) strtol(source_date_epoch, NULL, 10);
160  
161  	if (gmtime(&time) == NULL) {
162  		fprintf(stderr, "%s: SOURCE_DATE_EPOCH is not valid\n",
163  			cmdname);
164  		time = 0;
165  	}
166  
167  	return time;
168  }
169