diff --git a/tools/Makefile b/tools/Makefile index 853a681..a32b7a0 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -6,9 +6,10 @@ EXEC_TGT = exec BLKPACK_TGT = blkpack BLKUNPACK_TGT = blkunpack BLKUP_TGT = blkup +BLKDOWN_TGT = blkdown TARGETS = $(MEMDUMP_TGT) $(UPLOAD_TGT) \ $(TTYSAFE_TGT) $(PINGPONG_TGT) $(EXEC_TGT) $(BLKPACK_TGT) \ - $(BLKUNPACK_TGT) $(BLKUP_TGT) + $(BLKUNPACK_TGT) $(BLKUP_TGT) $(BLKDOWN_TGT) OBJS = common.o all: $(TARGETS) @@ -25,6 +26,7 @@ $(EXEC_TGT): $(EXEC_TGT).c $(BLKPACK_TGT): $(BLKPACK_TGT).c $(BLKUNPACK_TGT): $(BLKUNPACK_TGT).c $(BLKUP_TGT): $(BLKUP_TGT).c +$(BLKDOWN_TGT): $(BLKDOWN_TGT).c $(TARGETS): $(OBJS) $(CC) $(CFLAGS) $@.c $(OBJS) -o $@ diff --git a/tools/blkdown.c b/tools/blkdown.c new file mode 100644 index 0000000..a1b79fe --- /dev/null +++ b/tools/blkdown.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include + +#include "common.h" + +/* Pull specified block no "srcblk" from "device" into block no "dstblk" in + * local "blkfs". If "dstblk" is omitted, it is the same as "srcblk" + */ + +int main(int argc, char **argv) +{ + if ((argc != 5) && (argc != 4)) { + fprintf(stderr, "Usage: ./blkdown device srcblk blkfs [dstblk]\n"); + return 1; + } + unsigned int srcblk = strtol(argv[2], NULL, 10); + unsigned int dstblk = srcblk; + if (argc == 5) { + dstblk = strtol(argv[4], NULL, 10); + } + FILE *fp = fopen(argv[3], "r+"); + if (!fp) { + fprintf(stderr, "Can't open %s.\n", argv[3]); + return 1; + } + int fd = ttyopen(argv[1]); + if (fd < 0) { + fprintf(stderr, "Could not open %s\n", argv[1]); + return 1; + } + fseek(fp, 1024 * dstblk, SEEK_SET); + char s[0x40]; + sprintf(s, ": _ %d BLK@ 1024 0 DO I BLK( + C@ .x LOOP ; _", srcblk); + sendcmd(fd, s); + + int returncode = 0; + for (int i=0; i<1024; i++) { + usleep(1000); // let it breathe + mread(fd, s, 2); // read hex pair + s[2] = 0; // null terminate + char *endptr = NULL; + unsigned char c = strtol(s, &endptr, 16); + if (endptr != &s[2]) { + fprintf(stderr, "Non-hex value (%s) at index %d.\n", s, i); + // we don't exit now because we need to "consume" our whole program. + returncode = 1; + } + if (returncode == 0) { + fwrite(&c, 1, 1, fp); + } + } + readprompt(fd); + sendcmdp(fd, "FORGET _"); + printf("Done!\n"); + fclose(fp); + return returncode; +}