xref: /openbsd-src/sys/dev/microcode/bwi/extract/extract.c (revision 0ea7e100bde0eee53094d329f727c2d680c34321)
1*0ea7e100Sdoug /*	$OpenBSD: extract.c,v 1.4 2014/09/24 00:13:13 doug 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>
23d1455811Smglocker #include <fcntl.h>
24d1455811Smglocker #include <stdio.h>
25d1455811Smglocker #include <stdlib.h>
26d1455811Smglocker #include <unistd.h>
27d1455811Smglocker 
28d1455811Smglocker struct header {
29d1455811Smglocker 	char	filename[64];
30d1455811Smglocker 	int	filesize;
31d1455811Smglocker 	int	fileoffset;
32d1455811Smglocker };
33d1455811Smglocker 
34d1455811Smglocker int
main(int argc,char * argv[])35d1455811Smglocker main(int argc, char *argv[])
36d1455811Smglocker {
37d1455811Smglocker 	int		  i, fdin, fdout, nfiles;
38d1455811Smglocker 	void		 *p;
39d1455811Smglocker 	struct header	**h;
40d1455811Smglocker 
41d1455811Smglocker 	if (argc < 2) {
42d1455811Smglocker 		printf("%s <firmware file>\n", argv[0]);
43d1455811Smglocker 		exit(1);
44d1455811Smglocker 	}
45d1455811Smglocker 
46d1455811Smglocker 	/* open firmware file */
47d1455811Smglocker 	if ((fdin = open(argv[1], O_RDONLY)) == -1)
48d1455811Smglocker 		err(1, "open of input file failed");
49d1455811Smglocker 
50d1455811Smglocker 	/* read first header */
51d1455811Smglocker 	if (read(fdin, &nfiles, sizeof(nfiles)) < 1)
52d1455811Smglocker 		err(1, "first header parse failed");
53d1455811Smglocker 	nfiles = ntohl(nfiles);
54d1455811Smglocker 
55d1455811Smglocker 	/* allocate space for header struct */
56*0ea7e100Sdoug 	if ((h = reallocarray(NULL, nfiles, sizeof(*h))) == NULL)
57d1455811Smglocker 		err(1, "malloc");
58d1455811Smglocker 	for (i = 0; i < nfiles; i++) {
59d1455811Smglocker 		if ((h[i] = malloc(sizeof(struct header))) == NULL)
60d1455811Smglocker 			err(1, "malloc");
61d1455811Smglocker 	}
62d1455811Smglocker 
63d1455811Smglocker 	/* read header */
64d1455811Smglocker 	for (i = 0; i < nfiles; i++) {
65d1455811Smglocker 		if (read(fdin, h[i]->filename, sizeof(h[i]->filename)) < 1)
66d1455811Smglocker 			err(1, "filename header read failed\n");
67d1455811Smglocker 		if (read(fdin, &h[i]->filesize, sizeof(h[i]->filesize)) < 1)
68d1455811Smglocker 			err(1, "filesize header read failed\n");
69d1455811Smglocker 		h[i]->filesize = htonl(h[i]->filesize);
70d1455811Smglocker 		if (read(fdin, &h[i]->fileoffset, sizeof(h[i]->fileoffset)) < 1)
71d1455811Smglocker 			err(1, "fileoffset header read failed\n");
72d1455811Smglocker 		h[i]->fileoffset = htonl(h[i]->fileoffset);
73d1455811Smglocker 	}
74d1455811Smglocker 
75d1455811Smglocker 	/* write each file */
76d1455811Smglocker 	for (i = 0; i < nfiles; i++) {
77d1455811Smglocker 		if ((fdout = open(h[i]->filename, O_CREAT|O_TRUNC|O_RDWR, 0644))
78d1455811Smglocker 		    == -1)
79d1455811Smglocker 			err(1, "open of output file failed");
80d1455811Smglocker 		if ((p = malloc(h[i]->filesize)) == NULL)
81d1455811Smglocker 			err(1, "malloc");
82d1455811Smglocker 		if (lseek(fdin, h[i]->fileoffset, SEEK_SET) == -1)
83d1455811Smglocker 			err(1, "lseek");
84d1455811Smglocker 		if (read(fdin, p, h[i]->filesize) < 1)
85d1455811Smglocker 			err(1, "read from input file failed");
86d1455811Smglocker 		if (write(fdout, p, h[i]->filesize) < 1)
87d1455811Smglocker 			err(1, "write to output file failed");
884c67e3eeStedu 		free(p);
89d1455811Smglocker 		close(fdout);
90d1455811Smglocker 		printf("extracting %s (filesize %d, fileoffset %d)\n",
91d1455811Smglocker 		    h[i]->filename, h[i]->filesize, h[i]->fileoffset);
92d1455811Smglocker 	}
93d1455811Smglocker 
94d1455811Smglocker 	/* free header space */
95d1455811Smglocker 	for (i = 0; i < nfiles; i++)
964c67e3eeStedu 		free(h[i]);
974c67e3eeStedu 	free(h);
98d1455811Smglocker 
99d1455811Smglocker 	/* game over */
100d1455811Smglocker 	close (fdin);
101d1455811Smglocker 
102d1455811Smglocker 	return (0);
103d1455811Smglocker }
104