comparison 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
comparison
equal deleted inserted replaced
99:2e35070d289f 100:fa7005185b84
2 * This module implements commands for saving SIM file content in UNIX host 2 * This module implements commands for saving SIM file content in UNIX host
3 * files and restoring these backups back to the SIM. 3 * files and restoring these backups back to the SIM.
4 */ 4 */
5 5
6 #include <sys/types.h> 6 #include <sys/types.h>
7 #include <sys/file.h>
8 #include <sys/stat.h>
7 #include <stdio.h> 9 #include <stdio.h>
8 #include <stdlib.h> 10 #include <stdlib.h>
11 #include <unistd.h>
9 #include <pcsclite.h> 12 #include <pcsclite.h>
10 #include <winscard.h> 13 #include <winscard.h>
11 #include "globals.h" 14 #include "globals.h"
12 15
13 static 16 static
85 break; 88 break;
86 } 89 }
87 fclose(of); 90 fclose(of);
88 return(rc); 91 return(rc);
89 } 92 }
93
94 static
95 restore_transparent(data)
96 u_char *data;
97 {
98 unsigned off, cc;
99 int rc;
100
101 for (off = 0; off < curfile_total_size; off += cc) {
102 cc = curfile_total_size - off;
103 if (cc > 255)
104 cc = 255;
105 rc = update_bin_op(off, data + off, cc);
106 if (rc < 0)
107 return(rc);
108 }
109 return(0);
110 }
111
112 static
113 restore_records(data)
114 u_char *data;
115 {
116 unsigned recno;
117 u_char *dp;
118 int rc;
119
120 dp = data;
121 for (recno = 1; recno <= curfile_record_count; recno++) {
122 rc = update_rec_op(recno, 0x04, dp, curfile_record_len);
123 if (rc < 0)
124 return(rc);
125 dp += curfile_record_len;
126 }
127 return(0);
128 }
129
130 cmd_restore_file(argc, argv)
131 char **argv;
132 {
133 int file_id, rc, fd;
134 struct stat st;
135 u_char *databuf;
136
137 if (isxdigit(argv[1][0]) && isxdigit(argv[1][1]) &&
138 isxdigit(argv[1][2]) && isxdigit(argv[1][3]) && !argv[1][4])
139 file_id = strtoul(argv[1], 0, 16);
140 else
141 file_id = find_symbolic_file_name(argv[1]);
142 if (file_id < 0) {
143 fprintf(stderr,
144 "error: file ID argument is not a hex value or a recognized symbolic name\n");
145 return(-1);
146 }
147 rc = select_op(file_id);
148 if (rc < 0)
149 return(rc);
150 rc = parse_ef_select_response();
151 if (rc < 0)
152 return(rc);
153 if (!curfile_total_size) {
154 printf("SIM indicates file of zero length, nothing to do\n");
155 return(0);
156 }
157 fd = open(argv[2], O_RDONLY);
158 if (fd < 0) {
159 perror(argv[2]);
160 return(-1);
161 }
162 fstat(fd, &st);
163 if ((st.st_mode & S_IFMT) != S_IFREG) {
164 fprintf(stderr, "error: %s is not a regular file\n", argv[2]);
165 close(fd);
166 return(-1);
167 }
168 if (st.st_size != curfile_total_size) {
169 fprintf(stderr,
170 "error: length of %s does not match SIM EF length of %u bytes\n",
171 argv[2], curfile_total_size);
172 close(fd);
173 return(-1);
174 }
175 databuf = malloc(curfile_total_size);
176 if (!databuf) {
177 perror("malloc for file data");
178 close(fd);
179 return(-1);
180 }
181 read(fd, databuf, curfile_total_size);
182 close(fd);
183 switch (curfile_structure) {
184 case 0x00:
185 /* transparent */
186 rc = restore_transparent(databuf);
187 break;
188 case 0x01:
189 /* record-based */
190 rc = restore_records(databuf);
191 break;
192 case 0x03:
193 fprintf(stderr, "error: cyclic files are not supported\n");
194 rc = -1;
195 }
196 free(databuf);
197 return(rc);
198 }