xref: /openbsd-src/sys/dev/microcode/bwi/build/build.c (revision 0976a62eed9efa8a56fe08c0e6111f8914501630)
1*0976a62eSguenther /*	$OpenBSD: build.c,v 1.4 2014/07/20 02:03:21 guenther Exp $ */
2d1455811Smglocker 
3d1455811Smglocker /*
4d1455811Smglocker  * Copyright (c) 2006 Marcus Glocker <mglocker@openbsd.org>
5d1455811Smglocker  *
6d1455811Smglocker  * Permission to use, copy, modify, and distribute this software for any
7d1455811Smglocker  * purpose with or without fee is hereby granted, provided that the above
8d1455811Smglocker  * copyright notice and this permission notice appear in all copies.
9d1455811Smglocker  *
10d1455811Smglocker  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11d1455811Smglocker  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12d1455811Smglocker  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13d1455811Smglocker  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14d1455811Smglocker  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15d1455811Smglocker  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16d1455811Smglocker  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17d1455811Smglocker  */
18d1455811Smglocker 
19d1455811Smglocker #include <sys/types.h>
20d1455811Smglocker #include <sys/stat.h>
21d1455811Smglocker 
22d1455811Smglocker #include <err.h>
23*0976a62eSguenther #include <errno.h>
24d1455811Smglocker #include <fcntl.h>
25d1455811Smglocker #include <stdio.h>
26d1455811Smglocker #include <stdlib.h>
27d1455811Smglocker #include <string.h>
28d1455811Smglocker #include <unistd.h>
29d1455811Smglocker 
30d1455811Smglocker //#define VERBOSE		1
31d1455811Smglocker #define FILENAME	"bwi-airforce"
32d1455811Smglocker 
33d1455811Smglocker struct header {
34d1455811Smglocker 	char	filename[64];
35d1455811Smglocker 	int	filesize;
36d1455811Smglocker 	int	fileoffset;
37d1455811Smglocker };
38d1455811Smglocker 
39d1455811Smglocker int
main(int argc,char * argv[])40d1455811Smglocker main(int argc, char *argv[])
41d1455811Smglocker {
42d1455811Smglocker 	void		*p;
43d1455811Smglocker 	int		 i, j, offset;
44d1455811Smglocker 	int		 fdout, fdin;
45d1455811Smglocker 	int		 nfiles, headersize;
46d1455811Smglocker 	int		 fwsize, totalsize;
47d1455811Smglocker 	struct header	 h[argc - 1];
48d1455811Smglocker 	struct stat	 s;
49d1455811Smglocker 
50d1455811Smglocker 	if (argc < 2) {
51d1455811Smglocker 		printf("%s <firmware files>\n", argv[0]);
52d1455811Smglocker 		exit(1);
53d1455811Smglocker 	}
54d1455811Smglocker 
55d1455811Smglocker 	nfiles = argc - 1; /* number of firmware files */
56d1455811Smglocker 	headersize = sizeof(h) + sizeof(nfiles); /* size of file header */
57d1455811Smglocker 
58d1455811Smglocker 	/* initialize header struct */
59d1455811Smglocker 	for (i = 1, j = 0, fwsize = 0; i < argc; i++, j++) {
60d1455811Smglocker 		bzero(h[j].filename, sizeof(h[j].filename));
61d1455811Smglocker 		strlcpy(h[j].filename, argv[i], sizeof(h[j].filename));
62d1455811Smglocker 
63d1455811Smglocker 		if (stat(h[j].filename, &s) == -1)
64d1455811Smglocker 			err(1, "header initialization failed");
65d1455811Smglocker 
66d1455811Smglocker 		h[j].filesize = s.st_size;
67d1455811Smglocker 		h[j].fileoffset = 0;
68d1455811Smglocker 
69d1455811Smglocker 		fwsize += h[j].filesize;
70d1455811Smglocker #ifdef VERBOSE
71d1455811Smglocker 		printf("create header entry for %s (%d bytes)\n",
72d1455811Smglocker 		    h[j].filename, h[j].filesize);
73d1455811Smglocker #endif
74d1455811Smglocker 	}
75d1455811Smglocker 
76d1455811Smglocker 	/* calculate total file size */
77d1455811Smglocker 	totalsize = headersize + fwsize;
78d1455811Smglocker #if VERBOSE
79d1455811Smglocker 	printf("\n");
80d1455811Smglocker 	printf("header size = %d bytes, ", headersize);
81d1455811Smglocker 	printf("fw size = %d bytes, ", fwsize);
82d1455811Smglocker 	printf("total file size = %d bytes\n", totalsize);
83d1455811Smglocker 	printf("\n");
84d1455811Smglocker #endif
85d1455811Smglocker 
86d1455811Smglocker 	/* calculating firmware offsets */
87d1455811Smglocker 	for (i = 0, offset = headersize; i < nfiles; i++) {
88d1455811Smglocker 		h[i].fileoffset = offset;
89d1455811Smglocker 		offset += h[i].filesize;
90d1455811Smglocker #ifdef VERBOSE
91d1455811Smglocker 		printf("offset of %s = %d\n", h[i].filename, h[i].fileoffset);
92d1455811Smglocker #endif
93d1455811Smglocker 	}
94d1455811Smglocker 
95d1455811Smglocker 	/* open output file */
96d1455811Smglocker 	if ((fdout = open(FILENAME, O_CREAT|O_TRUNC|O_RDWR, 0644)) == -1)
97d1455811Smglocker 		err(1, "open output file failed");
98d1455811Smglocker 
99d1455811Smglocker 	/* host to network byte order */
100d1455811Smglocker 	for (i = 0; i < nfiles; i++) {
101d1455811Smglocker 		h[i].filesize = htonl(h[i].filesize);
102d1455811Smglocker 		h[i].fileoffset = htonl(h[i].fileoffset);
103d1455811Smglocker 	}
104d1455811Smglocker 	nfiles = htonl(nfiles);
105d1455811Smglocker 
106d1455811Smglocker 	/* write header */
107d1455811Smglocker 	if (write(fdout, &nfiles, sizeof(nfiles)) < 1) {
108*0976a62eSguenther 		int saved_errno = errno;
109d1455811Smglocker 		close(fdout);
110*0976a62eSguenther 		errc(1, saved_errno, "write header 1 to output file failed");
111d1455811Smglocker 	}
112d1455811Smglocker 	if (write(fdout, h, headersize - sizeof(nfiles)) < 1) {
113*0976a62eSguenther 		int saved_errno = errno;
114d1455811Smglocker 		close(fdout);
115*0976a62eSguenther 		errc(1, saved_errno, "write header 2 to output file failed");
116d1455811Smglocker 	}
117d1455811Smglocker 
118d1455811Smglocker 	/* network to host byte order */
119d1455811Smglocker 	nfiles = ntohl(nfiles);
120d1455811Smglocker 	for (i = 0; i < nfiles; i++) {
121d1455811Smglocker 		h[i].filesize = ntohl(h[i].filesize);
122d1455811Smglocker 		h[i].fileoffset = ntohl(h[i].fileoffset);
123d1455811Smglocker 	}
124d1455811Smglocker 
125d1455811Smglocker 	/* write each file */
126d1455811Smglocker 	for (i = 0; i < nfiles; i++) {
127d1455811Smglocker 		if ((fdin = open(h[i].filename, O_RDONLY)) == -1) {
128*0976a62eSguenther 			int saved_errno = errno;
129d1455811Smglocker 			close(fdout);
130*0976a62eSguenther 			errc(1, saved_errno, "open input file failed");
131d1455811Smglocker 		}
132d1455811Smglocker 		if ((p = malloc(h[i].filesize)) == NULL) {
133*0976a62eSguenther 			int saved_errno = errno;
134d1455811Smglocker 			close(fdout);
135d1455811Smglocker 			close(fdin);
136*0976a62eSguenther 			errc(1, saved_errno, "malloc");
137d1455811Smglocker 		}
138d1455811Smglocker 		if (read(fdin, p, h[i].filesize) < 1) {
139*0976a62eSguenther 			int saved_errno = errno;
1404c67e3eeStedu 			free(p);
141d1455811Smglocker 			close(fdout);
142d1455811Smglocker 			close(fdin);
143*0976a62eSguenther 			errc(1, saved_errno, "read input file failed");
144d1455811Smglocker 		}
145d1455811Smglocker 		if (write(fdout, p, h[i].filesize) < 1) {
146*0976a62eSguenther 			int saved_errno = errno;
1474c67e3eeStedu 			free(p);
148d1455811Smglocker 			close(fdout);
149d1455811Smglocker 			close(fdin);
150*0976a62eSguenther 			errc(1, saved_errno, "write to output file failed");
151d1455811Smglocker 		}
1524c67e3eeStedu 		free(p);
153d1455811Smglocker 		close(fdin);
154d1455811Smglocker 	}
155d1455811Smglocker 
156d1455811Smglocker 	close(fdout);
157d1455811Smglocker 
158d1455811Smglocker #ifdef VERBOSE
159d1455811Smglocker 	printf("\n");
160d1455811Smglocker #endif
161d1455811Smglocker 
162d1455811Smglocker 	/* game over */
163d1455811Smglocker 	printf("wrote %d files to %s (%d bytes).\n",
164d1455811Smglocker 	    nfiles, FILENAME, totalsize);
165d1455811Smglocker 
166d1455811Smglocker 	return (0);
167d1455811Smglocker }
168