1 /* Combine two boot tables.
2 * usage bfmerge file1 file2 [file3 [file4 [...]]]
3 * The output is to stdout
4 *
5 * */
7 #include <stdio.h>
8 #include <malloc.h>
10 int asciiByte (unsigned char c)
11 {
12 if ((c >= '0') && (c <= '9'))
13 return (1);
15 if ((c >= 'A') && (c <= 'F'))
16 return (1);
18 return (0);
19 }
21 int toNum (unsigned char c)
22 {
23 if ((c >= '0') && (c <= '9'))
24 return (c - '0');
26 return (c - 'A' + 10);
28 }
31 /* Copy a line from s to stdout */
32 void lineCpy (FILE *s)
33 {
34 char iline[132];
36 fgets (iline, 131, s);
37 fputs (iline, stdout);
39 }
41 /* Toss a line */
42 void lineToss (FILE *s)
43 {
44 char iline[132];
46 fgets (iline, 131, s);
48 }
50 /* Read a .b file. */
51 int readBFile (FILE *s, unsigned char *data, unsigned maxSize)
52 {
53 unsigned char x, y;
54 int byteCount = 0;
56 for (;;) {
58 /* read the 1st ascii char */
59 do {
60 x = fgetc (s);
61 if (x == (unsigned char)EOF)
62 return (byteCount);
64 } while (!asciiByte(x));
66 /* Read the next ascii char */
67 y = fgetc (s);
68 if (y == (unsigned char)EOF)
69 return (byteCount);
70 if (asciiByte(y))
71 data[byteCount++] = (toNum(x) << 4) | toNum (y);
73 if (byteCount >= maxSize) {
74 fprintf (stderr, "Max input array size exceeded\n");
75 return (-1);
76 }
78 }
80 }
82 unsigned dwordConvert (unsigned char *data)
83 {
84 unsigned value;
85 unsigned char c[4];
86 int i;
88 c[0] = c[1] = c[2] = c[3] = 0;
90 for (i = 0; i < 4; i++) {
91 c[i] = data[i];
92 }
94 value = c[3] | (c[2] << 8) | (c[1] << 16) | (c[0] << 24);
96 return (value);
98 }
101 int bparse (unsigned char *dataSet, int l)
102 {
103 unsigned int secsize;
105 do {
107 secsize = dwordConvert (&dataSet[l]);
108 secsize = (secsize + 3) & 0xfffffffc; /* segment pad */
109 l = l + secsize + 8; /* 4 bytes length, 4 bytes address */
111 } while (secsize);
113 /* Back up to the zero section size */
114 l = l - 8;
116 return (l);
118 }
121 #define SIZE 1000000
122 #define APPEND 100000
124 int main (int argc, char *argv[])
125 {
126 FILE *strin;
127 unsigned char *dataSet;
128 unsigned char *appSet;
129 unsigned int addr;
130 unsigned int secsize;
131 int asize;
132 int i, j;
133 int nbytes;
134 int p;
136 /* Must have at least two input files */
137 if (argc < 3) {
138 fprintf (stderr, "usage: %s file1 file2 [file3 [file4 [...]]]\n", argv[0]);
139 return (-1);
140 }
142 /* Allocate memory for the data set */
143 dataSet = malloc (SIZE * sizeof (unsigned char));
144 if (dataSet == NULL) {
145 fprintf (stderr, "%s: malloc failure\n", argv[0]);
146 return (-1);
147 }
149 appSet = malloc (APPEND * sizeof (unsigned char ));
150 if (appSet == NULL) {
151 fprintf (stderr, "%s malloc failure\n", argv[0]);
152 return (-1);
153 }
156 /* The first data file is handled seperately */
157 strin = fopen (argv[1], "r");
158 if (strin == NULL) {
159 fprintf (stderr, "%s: Could not open file %s\n", argv[0], argv[1]);
160 free (dataSet);
161 return (-1);
162 }
164 /* Copy the first two lines of the input file to stdout */
165 lineCpy (strin);
166 lineCpy (strin);
168 /* Read in the first data set */
169 asize = readBFile (strin, dataSet, SIZE);
170 fclose (strin);
172 /* Parse the file, skipping the entry symbol */
173 p = 4;
174 p = bparse (dataSet, p);
177 /* Add the remaining data sets */
179 for (i = 2; i < argc; i++) {
181 strin = fopen (argv[i], "r");
182 if (strin == NULL) {
183 fprintf (stderr, "%s: Could not open file %s\n", argv[0], argv[i]);
184 free (dataSet);
185 return (-1);
186 }
188 /* Toss the first two lines */
189 lineToss (strin);
190 lineToss (strin);
192 asize = readBFile (strin, appSet, APPEND);
193 fclose (strin);
195 /* Append the new data set, skip the 4 bytes of entry symbol */
196 for (j = 0; j < asize-4; j++)
197 dataSet[p+j] = appSet[j+4];
199 /* reparse from the current point */
200 p = bparse (dataSet, p);
202 }
204 /* Add the 0 section size */
205 for (i = 0; i < 4; i++)
206 dataSet[p++] = 0;
209 /* Write out the data */
210 for (i = 0; i < p; i++) {
211 fprintf (stdout, "%02X", dataSet[i]);
213 if ( ((i+1) % 24) )
214 fprintf (stdout, " ");
215 else
216 fprintf (stdout, "\n");
218 }
220 /* Write the trailing character */
221 fprintf (stdout, "\n%c",3);
223 free (dataSet);
225 return (0);
227 }