FreeCalypso > hg > fc-pcsc-tools
comparison simtool/dispatch.c @ 104:4709cff90a58
fc-simtool: infrastructure for output redirection
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Fri, 19 Feb 2021 05:58:00 +0000 |
| parents | 9b2cb2b9c910 |
| children | dcfec53643c5 |
comparison
equal
deleted
inserted
replaced
| 103:9b2cb2b9c910 | 104:4709cff90a58 |
|---|---|
| 87 | 87 |
| 88 static struct cmdtab { | 88 static struct cmdtab { |
| 89 char *cmd; | 89 char *cmd; |
| 90 int minargs; | 90 int minargs; |
| 91 int maxargs; | 91 int maxargs; |
| 92 int allow_redir; | |
| 92 int (*func)(); | 93 int (*func)(); |
| 93 } cmdtab[] = { | 94 } cmdtab[] = { |
| 94 {"a38", 1, 1, cmd_a38}, | 95 {"a38", 1, 1, 0, cmd_a38}, |
| 95 {"atr", 0, 0, retrieve_atr}, | 96 {"atr", 0, 0, 0, retrieve_atr}, |
| 96 {"change-chv1", 2, 2, cmd_change_chv}, | 97 {"change-chv1", 2, 2, 0, cmd_change_chv}, |
| 97 {"change-chv2", 2, 2, cmd_change_chv}, | 98 {"change-chv2", 2, 2, 0, cmd_change_chv}, |
| 98 {"change-pin1", 2, 2, cmd_change_chv}, | 99 {"change-pin1", 2, 2, 0, cmd_change_chv}, |
| 99 {"change-pin2", 2, 2, cmd_change_chv}, | 100 {"change-pin2", 2, 2, 0, cmd_change_chv}, |
| 100 {"disable-chv", 1, 1, cmd_disable_chv}, | 101 {"disable-chv", 1, 1, 0, cmd_disable_chv}, |
| 101 {"disable-chv1", 1, 1, cmd_disable_chv}, | 102 {"disable-chv1", 1, 1, 0, cmd_disable_chv}, |
| 102 {"disable-pin", 1, 1, cmd_disable_chv}, | 103 {"disable-pin", 1, 1, 0, cmd_disable_chv}, |
| 103 {"disable-pin1", 1, 1, cmd_disable_chv}, | 104 {"disable-pin1", 1, 1, 0, cmd_disable_chv}, |
| 104 {"enable-chv", 1, 1, cmd_enable_chv}, | 105 {"enable-chv", 1, 1, 0, cmd_enable_chv}, |
| 105 {"enable-chv1", 1, 1, cmd_enable_chv}, | 106 {"enable-chv1", 1, 1, 0, cmd_enable_chv}, |
| 106 {"enable-pin", 1, 1, cmd_enable_chv}, | 107 {"enable-pin", 1, 1, 0, cmd_enable_chv}, |
| 107 {"enable-pin1", 1, 1, cmd_enable_chv}, | 108 {"enable-pin1", 1, 1, 0, cmd_enable_chv}, |
| 108 {"exec", 1, 1, cmd_exec}, | 109 {"exec", 1, 1, 0, cmd_exec}, |
| 109 {"exit", 0, 0, good_exit}, | 110 {"exit", 0, 0, 0, good_exit}, |
| 110 {"fix-sysmo-msisdn", 0, 0, cmd_fix_sysmo_msisdn}, | 111 {"fix-sysmo-msisdn", 0, 0, 0, cmd_fix_sysmo_msisdn}, |
| 111 {"fplmn-dump", 0, 0, cmd_fplmn_dump}, | 112 {"fplmn-dump", 0, 0, 0, cmd_fplmn_dump}, |
| 112 {"fplmn-erase", 1, 2, cmd_fplmn_erase}, | 113 {"fplmn-erase", 1, 2, 0, cmd_fplmn_erase}, |
| 113 {"fplmn-erase-all", 0, 0, cmd_fplmn_erase_all}, | 114 {"fplmn-erase-all", 0, 0, 0, cmd_fplmn_erase_all}, |
| 114 {"fplmn-write", 2, 2, cmd_fplmn_write}, | 115 {"fplmn-write", 2, 2, 0, cmd_fplmn_write}, |
| 115 {"grcard1-set-adm1", 2, 2, cmd_grcard1_set_adm}, | 116 {"grcard1-set-adm1", 2, 2, 0, cmd_grcard1_set_adm}, |
| 116 {"grcard1-set-adm2", 2, 2, cmd_grcard1_set_adm}, | 117 {"grcard1-set-adm2", 2, 2, 0, cmd_grcard1_set_adm}, |
| 117 {"grcard1-set-ki", 1, 1, cmd_grcard1_set_ki}, | 118 {"grcard1-set-ki", 1, 1, 0, cmd_grcard1_set_ki}, |
| 118 {"grcard1-set-pin1", 2, 2, cmd_grcard1_set_pin}, | 119 {"grcard1-set-pin1", 2, 2, 0, cmd_grcard1_set_pin}, |
| 119 {"grcard1-set-pin2", 2, 2, cmd_grcard1_set_pin}, | 120 {"grcard1-set-pin2", 2, 2, 0, cmd_grcard1_set_pin}, |
| 120 {"grcard2-set-adm", 1, 1, cmd_grcard2_set_adm}, | 121 {"grcard2-set-adm", 1, 1, 0, cmd_grcard2_set_adm}, |
| 121 {"grcard2-set-adm-hex", 1, 1, cmd_grcard2_set_adm_hex}, | 122 {"grcard2-set-adm-hex", 1, 1, 0, cmd_grcard2_set_adm_hex}, |
| 122 {"grcard2-set-pin1", 1, 1, cmd_grcard2_set_pin}, | 123 {"grcard2-set-pin1", 1, 1, 0, cmd_grcard2_set_pin}, |
| 123 {"grcard2-set-pin2", 1, 1, cmd_grcard2_set_pin}, | 124 {"grcard2-set-pin2", 1, 1, 0, cmd_grcard2_set_pin}, |
| 124 {"grcard2-set-puk1", 1, 1, cmd_grcard2_set_puk}, | 125 {"grcard2-set-puk1", 1, 1, 0, cmd_grcard2_set_puk}, |
| 125 {"grcard2-set-puk2", 1, 1, cmd_grcard2_set_puk}, | 126 {"grcard2-set-puk2", 1, 1, 0, cmd_grcard2_set_puk}, |
| 126 {"grcard2-set-super", 1, 1, cmd_grcard2_set_super}, | 127 {"grcard2-set-super", 1, 1, 0, cmd_grcard2_set_super}, |
| 127 {"grcard2-set-super-hex", 1, 1, cmd_grcard2_set_super_hex}, | 128 {"grcard2-set-super-hex", 1, 1, 0, cmd_grcard2_set_super_hex}, |
| 128 {"iccid", 0, 0, cmd_iccid}, | 129 {"iccid", 0, 0, 0, cmd_iccid}, |
| 129 {"imsi", 0, 0, cmd_imsi}, | 130 {"imsi", 0, 0, 0, cmd_imsi}, |
| 130 {"lnd-dump", 0, 1, cmd_lnd_dump}, | 131 {"lnd-dump", 0, 1, 0, cmd_lnd_dump}, |
| 131 {"lnd-erase", 0, 0, cmd_lnd_erase}, | 132 {"lnd-erase", 0, 0, 0, cmd_lnd_erase}, |
| 132 {"lnd-restore", 1, 1, cmd_lnd_restore}, | 133 {"lnd-restore", 1, 1, 0, cmd_lnd_restore}, |
| 133 {"lnd-write", 1, 2, cmd_lnd_write}, | 134 {"lnd-write", 1, 2, 0, cmd_lnd_write}, |
| 134 {"opl-dump", 0, 0, cmd_opl_dump}, | 135 {"opl-dump", 0, 0, 0, cmd_opl_dump}, |
| 135 {"pb-dump", 1, 2, cmd_pb_dump}, | 136 {"pb-dump", 1, 2, 0, cmd_pb_dump}, |
| 136 {"pb-dump-rec", 2, 3, cmd_pb_dump_rec}, | 137 {"pb-dump-rec", 2, 3, 0, cmd_pb_dump_rec}, |
| 137 {"pb-erase", 1, 1, cmd_pb_erase}, | 138 {"pb-erase", 1, 1, 0, cmd_pb_erase}, |
| 138 {"pb-erase-one", 2, 2, cmd_pb_erase_one}, | 139 {"pb-erase-one", 2, 2, 0, cmd_pb_erase_one}, |
| 139 {"pb-erase-range", 3, 3, cmd_pb_erase_range}, | 140 {"pb-erase-range", 3, 3, 0, cmd_pb_erase_range}, |
| 140 {"pb-restore", 2, 2, cmd_pb_restore}, | 141 {"pb-restore", 2, 2, 0, cmd_pb_restore}, |
| 141 {"pb-update", 2, 2, cmd_pb_update}, | 142 {"pb-update", 2, 2, 0, cmd_pb_update}, |
| 142 {"pb-update-imm", 3, 4, cmd_pb_update_imm}, | 143 {"pb-update-imm", 3, 4, 0, cmd_pb_update_imm}, |
| 143 {"pb-update-imm-hex", 4, 4, cmd_pb_update_imm_hex}, | 144 {"pb-update-imm-hex", 4, 4, 0, cmd_pb_update_imm_hex}, |
| 144 {"plmnsel-dump", 0, 1, cmd_plmnsel_dump}, | 145 {"plmnsel-dump", 0, 1, 0, cmd_plmnsel_dump}, |
| 145 {"plmnsel-erase", 1, 2, cmd_plmnsel_erase}, | 146 {"plmnsel-erase", 1, 2, 0, cmd_plmnsel_erase}, |
| 146 {"plmnsel-erase-all", 0, 0, cmd_plmnsel_erase_all}, | 147 {"plmnsel-erase-all", 0, 0, 0, cmd_plmnsel_erase_all}, |
| 147 {"plmnsel-write", 2, 2, cmd_plmnsel_write}, | 148 {"plmnsel-write", 2, 2, 0, cmd_plmnsel_write}, |
| 148 {"pnn-dump", 0, 0, cmd_pnn_dump}, | 149 {"pnn-dump", 0, 0, 0, cmd_pnn_dump}, |
| 149 {"quit", 0, 0, good_exit}, | 150 {"quit", 0, 0, 0, good_exit}, |
| 150 {"readbin", 2, 2, cmd_readbin}, | 151 {"readbin", 2, 2, 0, cmd_readbin}, |
| 151 {"readef", 1, 1, cmd_readef}, | 152 {"readef", 1, 1, 0, cmd_readef}, |
| 152 {"readrec", 1, 2, cmd_readrec}, | 153 {"readrec", 1, 2, 0, cmd_readrec}, |
| 153 {"restore-file", 2, 2, cmd_restore_file}, | 154 {"restore-file", 2, 2, 0, cmd_restore_file}, |
| 154 {"savebin", 2, 2, cmd_savebin}, | 155 {"savebin", 2, 2, 0, cmd_savebin}, |
| 155 {"save-sms-bin", 1, 1, cmd_save_sms_bin}, | 156 {"save-sms-bin", 1, 1, 0, cmd_save_sms_bin}, |
| 156 {"select", 1, 1, cmd_select}, | 157 {"select", 1, 1, 0, cmd_select}, |
| 157 {"sim-resp", 0, 0, display_sim_resp_in_hex}, | 158 {"sim-resp", 0, 0, 0, display_sim_resp_in_hex}, |
| 158 {"sms-erase-all", 0, 0, cmd_sms_erase_all}, | 159 {"sms-erase-all", 0, 0, 0, cmd_sms_erase_all}, |
| 159 {"sms-erase-one", 1, 1, cmd_sms_erase_one}, | 160 {"sms-erase-one", 1, 1, 0, cmd_sms_erase_one}, |
| 160 {"sms-erase-range", 2, 2, cmd_sms_erase_range}, | 161 {"sms-erase-range", 2, 2, 0, cmd_sms_erase_range}, |
| 161 {"smsp-dump", 0, 1, cmd_smsp_dump}, | 162 {"smsp-dump", 0, 1, 0, cmd_smsp_dump}, |
| 162 {"smsp-erase-all", 0, 0, cmd_smsp_erase_all}, | 163 {"smsp-erase-all", 0, 0, 0, cmd_smsp_erase_all}, |
| 163 {"smsp-erase-one", 1, 1, cmd_smsp_erase_one}, | 164 {"smsp-erase-one", 1, 1, 0, cmd_smsp_erase_one}, |
| 164 {"smsp-erase-range", 2, 2, cmd_smsp_erase_range}, | 165 {"smsp-erase-range", 2, 2, 0, cmd_smsp_erase_range}, |
| 165 {"smsp-restore", 1, 1, cmd_smsp_restore}, | 166 {"smsp-restore", 1, 1, 0, cmd_smsp_restore}, |
| 166 {"smsp-set", 2, 6, cmd_smsp_set}, | 167 {"smsp-set", 2, 6, 0, cmd_smsp_set}, |
| 167 {"smsp-set-tag", 3, 7, cmd_smsp_set_tag}, | 168 {"smsp-set-tag", 3, 7, 0, cmd_smsp_set_tag}, |
| 168 {"spn", 0, 0, cmd_spn}, | 169 {"spn", 0, 0, 0, cmd_spn}, |
| 169 {"sst", 0, 0, cmd_sst}, | 170 {"sst", 0, 0, 0, cmd_sst}, |
| 170 {"telecom-sum", 0, 0, cmd_telecom_sum}, | 171 {"telecom-sum", 0, 0, 0, cmd_telecom_sum}, |
| 171 {"uicc-dir", 0, 0, cmd_uicc_dir}, | 172 {"uicc-dir", 0, 0, 0, cmd_uicc_dir}, |
| 172 {"unblock-chv1", 2, 2, cmd_unblock_chv}, | 173 {"unblock-chv1", 2, 2, 0, cmd_unblock_chv}, |
| 173 {"unblock-chv2", 2, 2, cmd_unblock_chv}, | 174 {"unblock-chv2", 2, 2, 0, cmd_unblock_chv}, |
| 174 {"unblock-pin1", 2, 2, cmd_unblock_chv}, | 175 {"unblock-pin1", 2, 2, 0, cmd_unblock_chv}, |
| 175 {"unblock-pin2", 2, 2, cmd_unblock_chv}, | 176 {"unblock-pin2", 2, 2, 0, cmd_unblock_chv}, |
| 176 {"update-bin", 2, 2, cmd_update_bin}, | 177 {"update-bin", 2, 2, 0, cmd_update_bin}, |
| 177 {"update-bin-imm", 2, 2, cmd_update_bin_imm}, | 178 {"update-bin-imm", 2, 2, 0, cmd_update_bin_imm}, |
| 178 {"update-rec", 2, 2, cmd_update_rec}, | 179 {"update-rec", 2, 2, 0, cmd_update_rec}, |
| 179 {"update-rec-prev", 1, 1, cmd_update_rec_prev}, | 180 {"update-rec-prev", 1, 1, 0, cmd_update_rec_prev}, |
| 180 {"user-sum", 0, 0, cmd_user_sum}, | 181 {"user-sum", 0, 0, 0, cmd_user_sum}, |
| 181 {"verify-chv1", 1, 1, cmd_verify_chv}, | 182 {"verify-chv1", 1, 1, 0, cmd_verify_chv}, |
| 182 {"verify-chv2", 1, 1, cmd_verify_chv}, | 183 {"verify-chv2", 1, 1, 0, cmd_verify_chv}, |
| 183 {"verify-ext", 2, 2, cmd_verify_ext}, | 184 {"verify-ext", 2, 2, 0, cmd_verify_ext}, |
| 184 {"verify-hex", 2, 2, cmd_verify_hex}, | 185 {"verify-hex", 2, 2, 0, cmd_verify_hex}, |
| 185 {"verify-pin1", 1, 1, cmd_verify_chv}, | 186 {"verify-pin1", 1, 1, 0, cmd_verify_chv}, |
| 186 {"verify-pin2", 1, 1, cmd_verify_chv}, | 187 {"verify-pin2", 1, 1, 0, cmd_verify_chv}, |
| 187 {"write-iccid", 1, 1, cmd_write_iccid}, | 188 {"write-iccid", 1, 1, 0, cmd_write_iccid}, |
| 188 {"write-imsi", 1, 1, cmd_write_imsi}, | 189 {"write-imsi", 1, 1, 0, cmd_write_imsi}, |
| 189 {0, 0, 0, 0} | 190 {0, 0, 0, 0, 0} |
| 190 }; | 191 }; |
| 192 | |
| 193 static FILE * | |
| 194 handle_output_redir(str) | |
| 195 char *str; | |
| 196 { | |
| 197 char *cp, *fn; | |
| 198 FILE *outf; | |
| 199 | |
| 200 for (cp = str; isspace(*cp); cp++) | |
| 201 ; | |
| 202 if (!*cp || *cp == '#') { | |
| 203 fprintf(stderr, "error: no filename after '>'\n"); | |
| 204 return(0); | |
| 205 } | |
| 206 for (fn = cp; *cp && !isspace(*cp); cp++) | |
| 207 ; | |
| 208 if (*cp) | |
| 209 *cp++ = '\0'; | |
| 210 while (isspace(*cp)) | |
| 211 cp++; | |
| 212 if (*cp && *cp != '#') { | |
| 213 fprintf(stderr, "error: invalid syntax after '>'\n"); | |
| 214 return(0); | |
| 215 } | |
| 216 outf = fopen(fn, "w"); | |
| 217 if (!outf) | |
| 218 perror(fn); | |
| 219 return outf; | |
| 220 } | |
| 191 | 221 |
| 192 simtool_dispatch_cmd(cmd, is_script) | 222 simtool_dispatch_cmd(cmd, is_script) |
| 193 char *cmd; | 223 char *cmd; |
| 194 { | 224 { |
| 195 char *argv[10]; | 225 char *argv[10]; |
| 196 char *cp, **ap; | 226 char *cp, **ap; |
| 197 struct cmdtab *tp; | 227 struct cmdtab *tp; |
| 228 FILE *outf; | |
| 229 int rc; | |
| 198 | 230 |
| 199 for (cp = cmd; isspace(*cp); cp++) | 231 for (cp = cmd; isspace(*cp); cp++) |
| 200 ; | 232 ; |
| 201 if (!*cp || *cp == '#') | 233 if (!*cp || *cp == '#') |
| 202 return(0); | 234 return(0); |
| 215 return(-1); | 247 return(-1); |
| 216 } | 248 } |
| 217 for (ap = argv + 1; ; ) { | 249 for (ap = argv + 1; ; ) { |
| 218 while (isspace(*cp)) | 250 while (isspace(*cp)) |
| 219 cp++; | 251 cp++; |
| 220 if (!*cp || *cp == '#') | 252 if (!*cp || *cp == '#' || *cp == '>') |
| 221 break; | 253 break; |
| 222 if (ap - argv - 1 >= tp->maxargs) { | 254 if (ap - argv - 1 >= tp->maxargs) { |
| 223 fprintf(stderr, "error: too many arguments\n"); | 255 fprintf(stderr, "error: too many arguments\n"); |
| 224 return(-1); | 256 return(-1); |
| 225 } | 257 } |
| 251 if (ap - argv - 1 < tp->minargs) { | 283 if (ap - argv - 1 < tp->minargs) { |
| 252 fprintf(stderr, "error: too few arguments\n"); | 284 fprintf(stderr, "error: too few arguments\n"); |
| 253 return(-1); | 285 return(-1); |
| 254 } | 286 } |
| 255 *ap = 0; | 287 *ap = 0; |
| 256 return tp->func(ap - argv, argv); | 288 if (*cp == '>') { |
| 289 if (!tp->allow_redir) { | |
| 290 fprintf(stderr, | |
| 291 "error: command does not support output redirection\n"); | |
| 292 return(-1); | |
| 293 } | |
| 294 outf = handle_output_redir(cp + 1); | |
| 295 if (!outf) | |
| 296 return(-1); | |
| 297 } else | |
| 298 outf = stdout; | |
| 299 rc = tp->func(ap - argv, argv, outf); | |
| 300 if (outf != stdout) | |
| 301 fclose(outf); | |
| 302 return rc; | |
| 257 } | 303 } |
| 258 | 304 |
| 259 dispatch_ready_argv(argc, argv) | 305 dispatch_ready_argv(argc, argv) |
| 260 char **argv; | 306 char **argv; |
| 261 { | 307 { |
| 274 } | 320 } |
| 275 if (argc - 1 < tp->minargs) { | 321 if (argc - 1 < tp->minargs) { |
| 276 fprintf(stderr, "error: too few arguments\n"); | 322 fprintf(stderr, "error: too few arguments\n"); |
| 277 return(-1); | 323 return(-1); |
| 278 } | 324 } |
| 279 return tp->func(argc, argv); | 325 return tp->func(argc, argv, stdout); |
| 280 } | 326 } |
