xref: /haiku/src/tools/fixup_amiga_boot_checksum/fixup_amiga_boot_checksum.c (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <netinet/in.h>
6 
7 #define BB_SIZE (2*512)
8 
9 int main(int argc, char **argv)
10 {
11 	int fd;
12 	unsigned int i;
13 	uint32_t sum;
14 	uint8_t bootblock[BB_SIZE];
15 	uint32_t *p = (uint32_t *)bootblock;
16 	fd = open(argv[1], O_RDWR);
17 	if (fd < 0) {
18 		return 1;
19 	}
20 	if (read(fd, bootblock, BB_SIZE) < BB_SIZE) {
21 		perror("read");
22 		return 1;
23 	}
24 	if (ntohl(p[0]) != 'DOS\0') {
25 		fprintf(stderr, "bad bootblock signature!\n");
26 		return 1;
27 	}
28 	p[1] = 0;
29 	for (sum = 0, i = 0; i < (BB_SIZE)/sizeof(uint32_t); i++) {
30 		uint32_t old = sum;
31 		// big endian
32 		sum += ntohl(*p++);
33 		// overflow
34 		if (sum < old)
35 			sum++;
36 	}
37 	sum = ~sum;
38 	//fprintf(stderr, "checksum: 0x%lx\n", (long)sum);
39 	// big endian
40 	((uint32_t *)bootblock)[1] = htonl(sum);
41 	lseek(fd, 0LL, SEEK_SET);
42 	write(fd, bootblock, BB_SIZE);
43 	return 0;
44 }
45