#if 0 /* Magic self-executing C source code. Run "sh cmpoffsets.c" -dnelson set -ex gcc -g -Wall -O2 -march=i686 $0 -o cmpoffsets exit 0 */ #endif #include #include #include unsigned int boundarycheck(unsigned int number); int main(int argc, char **argv) { unsigned int i; FILE *in; int tosmall = 0; unsigned int firstbad = -1, lastbad = -1; unsigned int firstbadoff = 0, lastbadoff = 0; int failed = 0; if (argc != 2) { printf("Usage: cmpoffsets file.copy\n"); exit(1); } in = fopen(argv[1], "rb"); if (!in) { perror("cannot open file"); exit(1); } setvbuf(in, malloc(65536), _IOFBF, 65536); for (i = 0; i < 1536 * 1024 * 1024 && !tosmall; i += 4) { unsigned int o; if (fread(&o, 4, 1, in) != 1) { o = htonl(i); tosmall = 1; } o = ntohl(o); if (o != i) { failed = 1; if (lastbad != i - 4) { firstbad = i; firstbadoff = o; } lastbad = i; lastbadoff = o; } else { if (lastbad == i - 4) { if (firstbad == lastbad) { /* range of one */ printf("%u (4) (held data from %u)\n", firstbad, firstbadoff); } else { /* range > 1 */ printf("%u-%u (%u) (held data from %u-%u)\n", firstbad, lastbad + 3, lastbad + 4 - firstbad, firstbadoff, lastbadoff + 3); if (boundarycheck(firstbadoff) > 2048) printf(" starts at a %u-byte block\n", boundarycheck(firstbadoff)); if (boundarycheck(lastbadoff + 4) > 2048) printf(" ends at a %u-byte block\n", boundarycheck(lastbadoff + 4)); } firstbad = lastbad = -1; } } } if (tosmall) { printf("file is truncated\n"); failed = 1; } return failed; } unsigned int boundarycheck(unsigned int number) { long long block = 1; while (block < number) { block *= 2; if (number / block * block != number) break; } return block; }