FreeCalypso > hg > freecalypso-hwlab
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 } |