1 /* Append a boot table section to the end of a boot table
2 * usage: bfaddsect infile addr byte1 [bytes2 [byte3 [...]]]
3 * The output is to stdout
4 *
5 * All values are taken to be btye values */
8 #include <stdio.h>
9 #include <malloc.h>
13 int asciiByte (unsigned char c)
14 {
15 if ((c >= '0') && (c <= '9'))
16 return (1);
18 if ((c >= 'A') && (c <= 'F'))
19 return (1);
21 return (0);
22 }
24 int toNum (unsigned char c)
25 {
26 if ((c >= '0') && (c <= '9'))
27 return (c - '0');
29 return (c - 'A' + 10);
31 }
34 /* Copy a line from s to stdout */
35 void lineCpy (FILE *s)
36 {
37 char iline[132];
39 fgets (iline, 131, s);
40 fputs (iline, stdout);
42 }
44 /* Read a .b file. */
45 int readBFile (FILE *s, unsigned char *data, unsigned maxSize)
46 {
47 unsigned char x, y;
48 int byteCount = 0;
50 for (;;) {
52 /* read the 1st ascii char */
53 do {
54 x = fgetc (s);
55 if (x == (unsigned char)EOF)
56 return (byteCount);
58 } while (!asciiByte(x));
60 /* Read the next ascii char */
61 y = fgetc (s);
62 if (y == (unsigned char)EOF)
63 return (byteCount);
64 if (asciiByte(y))
65 data[byteCount++] = (toNum(x) << 4) | toNum (y);
67 if (byteCount >= maxSize) {
68 fprintf (stderr, "Max input array size exceeded\n");
69 return (-1);
70 }
72 }
74 }
76 unsigned dwordConvert (unsigned char *data)
77 {
78 unsigned value;
79 unsigned char c[4];
80 int i;
82 c[0] = c[1] = c[2] = c[3] = 0;
84 for (i = 0; i < 4; i++) {
85 c[i] = data[i];
86 }
88 value = c[3] | (c[2] << 8) | (c[1] << 16) | (c[0] << 24);
90 return (value);
92 }
94 #define SIZE 0x100000 /* max number of bytes in the array */
95 #define MAX_BYTES 64 /* max size of the boot table */
97 int main (int argc, char *argv[])
98 {
99 FILE *strin;
100 unsigned char *dataSet;
101 unsigned int addr;
102 unsigned int secsize;
103 unsigned char newchars[MAX_BYTES];
104 int i;
105 int nbytes;
106 int asize;
107 int p;
110 /* get the args */
111 if (argc < 4) {
112 fprintf (stderr, "usage: %s infile hex_addr byte1 [byte2 [byte3 [ ...byte64]]]\n", argv[0]);
113 return (-1);
114 }
116 /* input file */
117 strin = fopen (argv[1], "r");
118 if (strin == NULL) {
119 fprintf (stderr, "%s: Could not open file %s\n", argv[0], argv[1]);
120 return (-1);
121 }
123 /* Address */
124 sscanf (argv[2], "%x", &addr);
126 /* Number of bytes */
127 nbytes = argc - 3;
128 for (i = 0; i < nbytes; i++)
129 sscanf (argv[i+3], "%x", &newchars[i]);
132 /* Allocate memory for the data set */
133 dataSet = malloc (SIZE * sizeof (unsigned char));
134 if (dataSet == NULL) {
135 fprintf (stderr, "%s: malloc failure\n", argv[0]);
136 return (-1);
137 }
139 /* Copy the first two lines of the input file to stdout */
140 lineCpy (strin);
141 lineCpy (strin);
143 /* Read the data into the byte stream */
144 asize = readBFile (strin, dataSet, SIZE);
145 fclose (strin);
147 /* Parse the input file. Prepend the new section at the end */
149 /* Just skip the entry address */
150 p = 4;
152 do {
153 secsize = dwordConvert (&dataSet[p]);
154 secsize = (secsize + 3) & 0xfffffffc; /* segment pad */
155 p = p + secsize + 8; /* 4 bytes length, 4 bytes address */
156 } while (secsize);
158 /* back up to the zero section size */
159 p = p - 8;
161 /* p now points to the 0 length entry. Put the new data here */
162 /* The section size */
163 dataSet[p++] = (nbytes >> 24) & 0xff;
164 dataSet[p++] = (nbytes >> 16) & 0xff;
165 dataSet[p++] = (nbytes >> 8) & 0xff;
166 dataSet[p++] = (nbytes >> 0) & 0xff;
168 /* Put the section address */
169 dataSet[p++] = (addr >> 24) & 0xff;
170 dataSet[p++] = (addr >> 16) & 0xff;
171 dataSet[p++] = (addr >> 8) & 0xff;
172 dataSet[p++] = (addr >> 0) & 0xff;
174 /* Put the data */
175 for (i = 0; i < nbytes; i++)
176 dataSet[p++] = newchars[i];
178 while (p % 4)
179 dataSet[p++] = 0;
181 /* Add the 0 length section */
182 for (i = 0; i < 4; i++)
183 dataSet[p++] = 0;
186 /* Write out the data */
187 for (i = 0; i < p; i++) {
188 fprintf (stdout, "%02X", dataSet[i]);
190 if ( ((i+1) % 24) )
191 fprintf (stdout, " ");
192 else
193 fprintf (stdout, "\n");
195 }
197 /* Write the trailing character */
198 fprintf (stdout, "\n%c",3);
200 free (dataSet);
202 return (0);
204 }