FreeCalypso > hg > freecalypso-hwlab
diff simtool/saverestore.c @ 100:fa7005185b84
fc-simtool: restore-file command implemented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 25 Jan 2021 01:23:54 +0000 |
parents | 2e35070d289f |
children | b563ff1c1a2a |
line wrap: on
line diff
--- a/simtool/saverestore.c Mon Jan 25 00:14:19 2021 +0000 +++ b/simtool/saverestore.c Mon Jan 25 01:23:54 2021 +0000 @@ -4,8 +4,11 @@ */ #include <sys/types.h> +#include <sys/file.h> +#include <sys/stat.h> #include <stdio.h> #include <stdlib.h> +#include <unistd.h> #include <pcsclite.h> #include <winscard.h> #include "globals.h" @@ -87,3 +90,109 @@ fclose(of); return(rc); } + +static +restore_transparent(data) + u_char *data; +{ + unsigned off, cc; + int rc; + + for (off = 0; off < curfile_total_size; off += cc) { + cc = curfile_total_size - off; + if (cc > 255) + cc = 255; + rc = update_bin_op(off, data + off, cc); + if (rc < 0) + return(rc); + } + return(0); +} + +static +restore_records(data) + u_char *data; +{ + unsigned recno; + u_char *dp; + int rc; + + dp = data; + for (recno = 1; recno <= curfile_record_count; recno++) { + rc = update_rec_op(recno, 0x04, dp, curfile_record_len); + if (rc < 0) + return(rc); + dp += curfile_record_len; + } + return(0); +} + +cmd_restore_file(argc, argv) + char **argv; +{ + int file_id, rc, fd; + struct stat st; + u_char *databuf; + + if (isxdigit(argv[1][0]) && isxdigit(argv[1][1]) && + isxdigit(argv[1][2]) && isxdigit(argv[1][3]) && !argv[1][4]) + file_id = strtoul(argv[1], 0, 16); + else + file_id = find_symbolic_file_name(argv[1]); + if (file_id < 0) { + fprintf(stderr, +"error: file ID argument is not a hex value or a recognized symbolic name\n"); + return(-1); + } + rc = select_op(file_id); + if (rc < 0) + return(rc); + rc = parse_ef_select_response(); + if (rc < 0) + return(rc); + if (!curfile_total_size) { + printf("SIM indicates file of zero length, nothing to do\n"); + return(0); + } + fd = open(argv[2], O_RDONLY); + if (fd < 0) { + perror(argv[2]); + return(-1); + } + fstat(fd, &st); + if ((st.st_mode & S_IFMT) != S_IFREG) { + fprintf(stderr, "error: %s is not a regular file\n", argv[2]); + close(fd); + return(-1); + } + if (st.st_size != curfile_total_size) { + fprintf(stderr, + "error: length of %s does not match SIM EF length of %u bytes\n", + argv[2], curfile_total_size); + close(fd); + return(-1); + } + databuf = malloc(curfile_total_size); + if (!databuf) { + perror("malloc for file data"); + close(fd); + return(-1); + } + read(fd, databuf, curfile_total_size); + close(fd); + switch (curfile_structure) { + case 0x00: + /* transparent */ + rc = restore_transparent(databuf); + break; + case 0x01: + /* record-based */ + rc = restore_records(databuf); + break; + case 0x03: + fprintf(stderr, "error: cyclic files are not supported\n"); + rc = -1; + } + free(databuf); + return(rc); +}