2002-07-09 16:24:59 +04:00
|
|
|
/*
|
|
|
|
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
|
|
|
** Distributed under the terms of the NewOS License.
|
|
|
|
*/
|
2002-07-17 23:42:44 +04:00
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
#include <stdio.h>
|
2002-07-17 23:42:44 +04:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2002-07-09 16:24:59 +04:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
#ifndef O_BINARY
|
2002-07-17 23:42:44 +04:00
|
|
|
# define O_BINARY 0
|
2002-07-09 16:24:59 +04:00
|
|
|
#endif
|
|
|
|
|
2002-07-17 23:42:44 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
usage(char *progName)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-07-17 23:42:44 +04:00
|
|
|
printf("usage: %s [-p #padding] bootblock payload outfile\n", progName);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
2002-07-17 23:42:44 +04:00
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
|
|
|
struct stat st;
|
|
|
|
unsigned int blocks;
|
|
|
|
unsigned char bootsector[1024];
|
|
|
|
unsigned char buf[512];
|
|
|
|
size_t read_size;
|
2002-07-17 23:42:44 +04:00
|
|
|
size_t written_bytes;
|
|
|
|
int padding = 0;
|
2002-07-09 16:24:59 +04:00
|
|
|
int infd;
|
|
|
|
int outfd;
|
2003-05-03 21:24:23 +04:00
|
|
|
signed char opt;
|
2002-07-17 23:42:44 +04:00
|
|
|
int err;
|
|
|
|
|
|
|
|
char *progName = argv[0];
|
|
|
|
if (strrchr(progName,'/'))
|
|
|
|
progName = strrchr(progName,'/') + 1;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-07-17 23:42:44 +04:00
|
|
|
while ((opt = getopt(argc, argv, "p:")) != -1) {
|
|
|
|
switch (opt) {
|
|
|
|
case 'p':
|
|
|
|
padding = atoi(optarg);
|
|
|
|
if (padding < 0) {
|
|
|
|
usage(progName);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
usage(progName);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
argc -= optind - 1;
|
|
|
|
argv += optind - 1;
|
|
|
|
|
|
|
|
if (argc < 4) {
|
2002-07-09 16:24:59 +04:00
|
|
|
printf("insufficient args\n");
|
2002-07-17 23:42:44 +04:00
|
|
|
usage(progName);
|
2002-07-09 16:24:59 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = stat(argv[2], &st);
|
2002-07-17 23:42:44 +04:00
|
|
|
if (err < 0) {
|
2002-07-09 16:24:59 +04:00
|
|
|
printf("error stating file '%s'\n", argv[2]);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
outfd = open(argv[3], O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0666);
|
2002-07-17 23:42:44 +04:00
|
|
|
if (outfd < 0) {
|
2002-07-09 16:24:59 +04:00
|
|
|
printf("error: cannot open output file '%s'\n", argv[3]);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// first read the bootblock
|
|
|
|
infd = open(argv[1], O_BINARY|O_RDONLY);
|
2002-07-17 23:42:44 +04:00
|
|
|
if (infd < 0) {
|
2002-07-09 16:24:59 +04:00
|
|
|
printf("error: cannot open bootblock file '%s'\n", argv[1]);
|
|
|
|
return -1;
|
|
|
|
}
|
2002-07-17 23:42:44 +04:00
|
|
|
if (read(infd, bootsector, sizeof(bootsector)) < sizeof(bootsector)
|
|
|
|
|| lseek(infd, 0, SEEK_END) != sizeof(bootsector)) {
|
2002-07-09 16:24:59 +04:00
|
|
|
printf ("error: size of bootblock file '%s' must match %d bytes.\n", argv[1], sizeof(bootsector));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
close(infd);
|
|
|
|
|
|
|
|
// patch the size of the output into bytes 3 & 4 of the bootblock
|
|
|
|
blocks = st.st_size / 512;
|
2002-07-18 17:31:55 +04:00
|
|
|
if ((st.st_size % 512) != 0)
|
|
|
|
blocks++;
|
|
|
|
printf("size %d, blocks %d (size %d)\n", (unsigned long)st.st_size, blocks, blocks * 512);
|
2002-07-09 16:24:59 +04:00
|
|
|
bootsector[2] = (blocks & 0x00ff);
|
|
|
|
bootsector[3] = (blocks & 0xff00) >> 8;
|
|
|
|
|
|
|
|
write(outfd, bootsector, sizeof(bootsector));
|
2002-07-17 23:42:44 +04:00
|
|
|
written_bytes = sizeof(bootsector);
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
infd = open(argv[2], O_BINARY|O_RDONLY);
|
2002-07-17 23:42:44 +04:00
|
|
|
if (infd < 0) {
|
2002-07-09 16:24:59 +04:00
|
|
|
printf("error: cannot open input file '%s'\n", argv[1]);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-07-17 23:42:44 +04:00
|
|
|
while ((read_size = read(infd, buf, sizeof(buf))) > 0) {
|
2002-07-09 16:24:59 +04:00
|
|
|
write(outfd, buf, read_size);
|
2002-07-17 23:42:44 +04:00
|
|
|
written_bytes += read_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (padding) {
|
|
|
|
if (written_bytes % padding) {
|
|
|
|
size_t towrite = padding - written_bytes % padding;
|
|
|
|
unsigned char *buf = malloc(towrite);
|
|
|
|
|
|
|
|
memset(buf, 0, towrite);
|
|
|
|
write(outfd, buf, towrite);
|
|
|
|
written_bytes += towrite;
|
|
|
|
|
|
|
|
printf("output file padded to %ld\n", (unsigned long)written_bytes);
|
|
|
|
}
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
close(outfd);
|
|
|
|
close(infd);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|