source: trunk/minix/boot/addaout.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 3.0 KB
RevLine 
[9]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:
4 *
5 * a_flags: A_IMG to indicate this is not an executable
6 *
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>
18
19#define INPUT_FILE 1
20#define OUTPUT_FILE 2
21
22/* Report problems. */
23void report(char *problem, char *message)
24{
25 fprintf(stderr, "%s:\n", problem);
26 fprintf(stderr, " %s\n\n", message);
27}
28
29
30int copy_data(int srcfd, int dstfd)
31{
32 char buf[8192];
33 ssize_t n;
34 int total=0;
35
36 /* Copy the little bytes themselves. (Source from cp.c). */
37 while ((n= read(srcfd, buf, sizeof(buf))) > 0) {
38 char *bp = buf;
39 ssize_t r;
40
41 while (n > 0 && (r= write(dstfd, bp, n)) > 0) {
42 bp += r;
43 n -= r;
44 total += r;
45 }
46 if (r <= 0) {
47 if (r == 0) {
48 fprintf(stderr, "Warning: EOF writing to output file.\n");
49 return(-1);
50 }
51 }
52 }
53 return(total);
54}
55
56
57/* Main program. */
58int main(int argc, char **argv)
59{
60 struct exec aout;
61 struct stat stin;
62 int fdin, fdout;
63 char * bp;
64 int n,r;
65 int total_size=0;
66 int result;
67
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);
73 }
74
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);
79 }
80 if ((fdin = open(argv[INPUT_FILE], O_RDONLY)) < 0) {
81 report("Couldn't open input file", strerror(errno));
82 return(1);
83 }
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);
88 }
89
90
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);
100 }
101
102
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;
113
114 bp = (char *) &aout;
115 n = sizeof(aout);
116 lseek(fdout, 0, SEEK_SET);
117 while (n > 0 && (r= write(fdout, bp, n)) > 0) {
118 bp += r;
119 n -= r;
120 }
121
122 printf("Prepended data file (%u bytes) with a.out header (%u bytes).\n",
123 total_size, sizeof(aout));
124 printf("Done.\n");
125
126 return(0);
127}
128
Note: See TracBrowser for help on using the repository browser.