/* McPhail's Tip-Top TAP Top-Tailer * Takes a raw code file as input * Prepends data length and appends xor checksum * Outputs to new file with .block suffix */ #include #include #include #include #include int main(int argc, char *argv[]) { int fdin, fdout; char outfilename[PATH_MAX]; unsigned int count = 0; unsigned char tally = 0; unsigned char next = 0; if (argc!=2) { printf("Please specify file to read.\n"); return -1; } fdin = open(argv[1], O_RDONLY); if (fdin<0) { printf("Couldn't open %s. for reading\n", argv[1]); return -1; } snprintf(outfilename, PATH_MAX, "%s.block", argv[1]); outfilename[PATH_MAX - 1] = '\0'; if (! strcmp(argv[1], outfilename)) { printf("Filename too long - would clobber existing.\n"); close(fdin); return -1; } fdout = open(outfilename, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); if (fdout<0) { printf("Couldn't open %s for writing.\n", outfilename); close(fdin); return -1; } while (read(fdin, &next, 1)) { tally ^= next; count ++; }; lseek(fdin, 0, SEEK_SET); char lsb = (count+1)&255; char msb = ((count+1)>>8)&255; write(fdout, &lsb, 1); write(fdout, &msb, 1); while (read(fdin, &next, 1)) { write(fdout, &next, 1); } write(fdout, &tally, 1); close(fdout); close(fdin); printf("File %s written.\n", outfilename); printf("Code length including first byte is %d (0x%.4X).\n", count, count); printf("Removing first byte gives 0x%.4X.\n", count-1); return 0; }