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