/* 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 flagopt = 0; unsigned char tally = 0; unsigned char next = 0; if ((argc<2) || (argc>3)) { printf("Please specify file to read.\n"); return -1; } if (3==argc) { if (!strcmp(argv[2], "header")) flagopt = 1; if (!strcmp(argv[2], "data")) flagopt = 2; if (!flagopt) { printf("Optional flags are \"header\" or \"data\"\n"); return -1; } } if (! flagopt) { printf("*** WARNING ***\n"); printf("*** ttttt is running in RAW mode.\n"); printf("*** Have you manually included the format flag as the first byte of the block?\n"); printf("*** If not, run again passing 'header' or 'data' as the second parameter.\n"); printf("*** WARNING ***\n\n"); } 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); if (flagopt) count++; char lsb = (count+1)&255; char msb = ((count+1)>>8)&255; write(fdout, &lsb, 1); write(fdout, &msb, 1); next = 0; if (flagopt == 2) next = 255; if (flagopt) { write(fdout, &next, 1); tally ^= next; } while (read(fdin, &next, 1)) { write(fdout, &next, 1); } write(fdout, &tally, 1); close(fdout); close(fdin); printf("File %s written.\n", outfilename); count--; printf("Code length is %d (0x%.4X).\n", count, count); return 0; }