# HG changeset patch # User Mychaela Falconia # Date 1618116274 0 # Node ID abef3d5668b95bbc88baee6c56a19028b1afc55b # Parent 3afa61d98961ae236fb3f78cc1c8bef8c047d286 fc-uicc-tool: restore-file ported over from fc-simtool diff -r 3afa61d98961 -r abef3d5668b9 uicc/Makefile --- a/uicc/Makefile Sun Apr 11 04:32:26 2021 +0000 +++ b/uicc/Makefile Sun Apr 11 04:44:34 2021 +0000 @@ -3,8 +3,8 @@ CPPFLAGS=-I../libcommon PROG= fc-uicc-tool OBJS= bfsearch.o cmdtab.o createfile.o dumpdir.o getresp.o hlread.o main.o \ - pins.o readcmd.o readef.o readops.o savebin.o select.o sws.o writecmd.o\ - writeops.o + pins.o readcmd.o readef.o readops.o restorebin.o savebin.o select.o \ + sws.o writecmd.o writeops.o LIBS= ../libcommon/libcommon.a ../libutil/libutil.a INSTALL_PREFIX= /opt/freecalypso diff -r 3afa61d98961 -r abef3d5668b9 uicc/cmdtab.c --- a/uicc/cmdtab.c Sun Apr 11 04:32:26 2021 +0000 +++ b/uicc/cmdtab.c Sun Apr 11 04:44:34 2021 +0000 @@ -25,6 +25,7 @@ extern int cmd_readbin(); extern int cmd_readef(); extern int cmd_readrec(); +extern int cmd_restore_file(); extern int cmd_savebin(); extern int cmd_select(); extern int cmd_select_aid(); @@ -67,6 +68,7 @@ {"readbin", 2, 2, 1, cmd_readbin}, {"readef", 1, 1, 1, cmd_readef}, {"readrec", 1, 2, 1, cmd_readrec}, + {"restore-file", 2, 2, 0, cmd_restore_file}, {"savebin", 2, 2, 0, cmd_savebin}, {"select", 1, 1, 1, cmd_select}, {"select-aid", 1, 1, 1, cmd_select_aid}, diff -r 3afa61d98961 -r abef3d5668b9 uicc/restorebin.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uicc/restorebin.c Sun Apr 11 04:44:34 2021 +0000 @@ -0,0 +1,143 @@ +/* + * This module implements the restore-file command; this command + * reads binary files previously saved with the savebin command + * and writes the backed-up bits back to the SIM. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "efstruct.h" + +static +restore_bin_transparent(efs, data) + struct ef_struct *efs; + u_char *data; +{ + unsigned off, cc; + int rc; + + for (off = 0; off < efs->total_size; off += cc) { + cc = efs->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_bin_records(efs, data) + struct ef_struct *efs; + u_char *data; +{ + unsigned recno; + u_char *dp; + int rc; + + dp = data; + for (recno = 1; recno <= efs->record_count; recno++) { + rc = update_rec_op(recno, 0x04, dp, efs->record_len); + if (rc < 0) + return(rc); + dp += efs->record_len; + } + return(0); +} + +static +restore_bin_cyclic(efs, data) + struct ef_struct *efs; + u_char *data; +{ + unsigned count; + u_char *dp; + int rc; + + dp = data + efs->total_size; + for (count = 0; count < efs->record_count; count++) { + dp -= efs->record_len; + rc = update_rec_op(0, 0x03, dp, efs->record_len); + if (rc < 0) + return(rc); + } + return(0); +} + +cmd_restore_file(argc, argv) + char **argv; +{ + int file_id, rc, fd; + struct ef_struct efs; + 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 = select_resp_get_ef_struct(&efs); + if (rc < 0) + return(rc); + if (!efs.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 != efs.total_size) { + fprintf(stderr, + "error: length of %s does not match SIM EF length of %u bytes\n", + argv[2], efs.total_size); + close(fd); + return(-1); + } + databuf = malloc(efs.total_size); + if (!databuf) { + perror("malloc for file data"); + close(fd); + return(-1); + } + read(fd, databuf, efs.total_size); + close(fd); + switch (efs.structure) { + case 0x01: + /* transparent */ + rc = restore_bin_transparent(&efs, databuf); + break; + case 0x02: + /* record-based */ + rc = restore_bin_records(&efs, databuf); + break; + case 0x06: + /* cyclic */ + rc = restore_bin_cyclic(&efs, databuf); + break; + } + free(databuf); + return(rc); +}