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