annotate uicc/restorebin.c @ 91:abef3d5668b9

fc-uicc-tool: restore-file ported over from fc-simtool
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 11 Apr 2021 04:44:34 +0000
parents simtool/restorebin.c@ddd767f6e15b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * This module implements the restore-file command; this command
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * reads binary files previously saved with the savebin command
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 * and writes the backed-up bits back to the SIM.
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 */
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 #include <sys/types.h>
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 #include <sys/file.h>
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <sys/stat.h>
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <ctype.h>
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <stdio.h>
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <stdlib.h>
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include <unistd.h>
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
14 #include "efstruct.h"
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
16 static
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
17 restore_bin_transparent(efs, data)
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
18 struct ef_struct *efs;
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 u_char *data;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 {
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 unsigned off, cc;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 int rc;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
24 for (off = 0; off < efs->total_size; off += cc) {
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
25 cc = efs->total_size - off;
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 if (cc > 255)
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 cc = 255;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 rc = update_bin_op(off, data + off, cc);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 if (rc < 0)
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 return(rc);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 }
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 return(0);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 }
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
35 static
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
36 restore_bin_records(efs, data)
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
37 struct ef_struct *efs;
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 u_char *data;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 {
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 unsigned recno;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 u_char *dp;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 int rc;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 dp = data;
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
45 for (recno = 1; recno <= efs->record_count; recno++) {
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
46 rc = update_rec_op(recno, 0x04, dp, efs->record_len);
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 if (rc < 0)
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 return(rc);
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
49 dp += efs->record_len;
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 }
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 return(0);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 }
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
54 static
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
55 restore_bin_cyclic(efs, data)
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
56 struct ef_struct *efs;
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 u_char *data;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 {
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 unsigned count;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 u_char *dp;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 int rc;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
63 dp = data + efs->total_size;
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
64 for (count = 0; count < efs->record_count; count++) {
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
65 dp -= efs->record_len;
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
66 rc = update_rec_op(0, 0x03, dp, efs->record_len);
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 if (rc < 0)
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 return(rc);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 }
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 return(0);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 }
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 cmd_restore_file(argc, argv)
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 char **argv;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 {
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 int file_id, rc, fd;
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
77 struct ef_struct efs;
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 struct stat st;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 u_char *databuf;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 if (isxdigit(argv[1][0]) && isxdigit(argv[1][1]) &&
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 isxdigit(argv[1][2]) && isxdigit(argv[1][3]) && !argv[1][4])
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 file_id = strtoul(argv[1], 0, 16);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 else
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 file_id = find_symbolic_file_name(argv[1]);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 if (file_id < 0) {
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 fprintf(stderr,
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 "error: file ID argument is not a hex value or a recognized symbolic name\n");
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 return(-1);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 }
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 rc = select_op(file_id);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 if (rc < 0)
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 return(rc);
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
94 rc = select_resp_get_ef_struct(&efs);
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 if (rc < 0)
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 return(rc);
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
97 if (!efs.total_size) {
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 printf("SIM indicates file of zero length, nothing to do\n");
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 return(0);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 }
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 fd = open(argv[2], O_RDONLY);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 if (fd < 0) {
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 perror(argv[2]);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 return(-1);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 }
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 fstat(fd, &st);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 if ((st.st_mode & S_IFMT) != S_IFREG) {
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108 fprintf(stderr, "error: %s is not a regular file\n", argv[2]);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 close(fd);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
110 return(-1);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 }
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
112 if (st.st_size != efs.total_size) {
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113 fprintf(stderr,
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 "error: length of %s does not match SIM EF length of %u bytes\n",
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
115 argv[2], efs.total_size);
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 close(fd);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 return(-1);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
118 }
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
119 databuf = malloc(efs.total_size);
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
120 if (!databuf) {
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
121 perror("malloc for file data");
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
122 close(fd);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
123 return(-1);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
124 }
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
125 read(fd, databuf, efs.total_size);
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
126 close(fd);
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
127 switch (efs.structure) {
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
128 case 0x01:
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
129 /* transparent */
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
130 rc = restore_bin_transparent(&efs, databuf);
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
131 break;
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
132 case 0x02:
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
133 /* record-based */
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
134 rc = restore_bin_records(&efs, databuf);
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
135 break;
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
136 case 0x06:
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
137 /* cyclic */
91
abef3d5668b9 fc-uicc-tool: restore-file ported over from fc-simtool
Mychaela Falconia <falcon@freecalypso.org>
parents: 10
diff changeset
138 rc = restore_bin_cyclic(&efs, databuf);
10
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
139 break;
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
140 }
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
141 free(databuf);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
142 return(rc);
ddd767f6e15b fc-simtool ported over
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
143 }