panic() cleanup.
[minix.git] / boot / addaout.c
blob7f9da98e84ee357f85ac76cc84274ee47fdfea69
1 /* A small utility to append an a.out header to an arbitrary file. This allows
2 * inclusion of arbitrary data in the boot image, so that it is magically
3 * loaded as a RAM disk. The a.out header is structured as follows:
5 * a_flags: A_IMG to indicate this is not an executable
7 * Created: April 2005, Jorrit N. Herder
8 */
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <errno.h>
12 #include <a.out.h>
13 #include <sys/types.h>
14 #include <fcntl.h>
15 #include <sys/stat.h>
16 #include <string.h>
17 #include <unistd.h>
19 #define INPUT_FILE 1
20 #define OUTPUT_FILE 2
22 /* Report problems. */
23 static void report(const char *problem, const char *message)
25 fprintf(stderr, "%s:\n", problem);
26 fprintf(stderr, " %s\n\n", message);
30 static int copy_data(int srcfd, int dstfd)
32 char buf[8192];
33 ssize_t n;
34 int total=0;
36 /** FIXME: handle error from read() */
38 /* Copy the little bytes themselves. (Source from cp.c). */
39 while ((n= read(srcfd, buf, sizeof(buf))) > 0) {
40 char *bp = buf;
41 ssize_t r = 0;
43 /** FIXME: handle error from write() */
44 while (n > 0 && (r= write(dstfd, bp, n)) > 0) {
45 bp += r;
46 n -= r;
47 total += r;
49 if (r == 0) {
50 fprintf(stderr, "Warning: EOF writing to output file.\n");
51 return(-1);
54 return(total);
58 /* Main program. */
59 int main(int argc, char **argv)
61 struct exec aout;
62 struct stat stin;
63 int fdin, fdout;
64 char * bp;
65 int n,r;
66 int total_size;
68 /* Check if command line arguments are present, or print usage. */
69 if (argc!=3) {
70 printf("Invalid arguments. Usage:\n");
71 printf(" %s <input_file> <output_file>\n",argv[0]);
72 return(1);
75 /* Check if we can open the input and output file. */
76 if (stat(argv[INPUT_FILE], &stin) != 0) {
77 report("Couldn't get status of input file", strerror(errno));
78 return(1);
80 if ((fdin = open(argv[INPUT_FILE], O_RDONLY)) < 0) {
81 report("Couldn't open input file", strerror(errno));
82 return(1);
84 if ((fdout = open(argv[OUTPUT_FILE], O_WRONLY|O_CREAT|O_TRUNC,
85 stin.st_mode & 0777)) < 0) {
86 report("Couldn't open output file", strerror(errno));
87 return(1);
91 /* Copy input file to output file, but leave space for a.out header. */
92 lseek(fdout, sizeof(aout), SEEK_SET);
93 total_size = copy_data(fdin, fdout);
94 if (total_size < 0) {
95 report("Aborted", "Output file may be truncated.");
96 return(1);
97 } else if (total_size == 0) {
98 report("Aborted without prepending header", "No data in input file.");
99 return(1);
103 /* Build a.out header and write to output file. */
104 memset(&aout, 0, sizeof(struct exec));
105 aout.a_magic[0] = A_MAGIC0;
106 aout.a_magic[1] = A_MAGIC1;
107 aout.a_flags |= A_IMG;
108 aout.a_hdrlen = sizeof(aout);
109 aout.a_text = 0;
110 aout.a_data = total_size;
111 aout.a_bss = 0;
112 aout.a_total = aout.a_hdrlen + aout.a_data;
114 bp = (char *) &aout;
115 n = sizeof(aout);
116 lseek(fdout, 0L, SEEK_SET);
117 while (n > 0 && (r= write(fdout, bp, n)) > 0) {
118 bp += r;
119 n -= r;
122 printf("Prepended data file (%d bytes) with a.out header (%u bytes).\n",
123 total_size, sizeof(aout));
124 printf("Done.\n");
126 return(0);