diff 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
line wrap: on
line diff
--- a/simtool/dispatch.c	Thu Feb 18 00:17:14 2021 +0000
+++ b/simtool/dispatch.c	Fri Feb 19 05:58:00 2021 +0000
@@ -89,112 +89,144 @@
 	char *cmd;
 	int minargs;
 	int maxargs;
+	int allow_redir;
 	int (*func)();
 } cmdtab[] = {
-	{"a38", 1, 1, cmd_a38},
-	{"atr", 0, 0, retrieve_atr},
-	{"change-chv1", 2, 2, cmd_change_chv},
-	{"change-chv2", 2, 2, cmd_change_chv},
-	{"change-pin1", 2, 2, cmd_change_chv},
-	{"change-pin2", 2, 2, cmd_change_chv},
-	{"disable-chv", 1, 1, cmd_disable_chv},
-	{"disable-chv1", 1, 1, cmd_disable_chv},
-	{"disable-pin", 1, 1, cmd_disable_chv},
-	{"disable-pin1", 1, 1, cmd_disable_chv},
-	{"enable-chv", 1, 1, cmd_enable_chv},
-	{"enable-chv1", 1, 1, cmd_enable_chv},
-	{"enable-pin", 1, 1, cmd_enable_chv},
-	{"enable-pin1", 1, 1, cmd_enable_chv},
-	{"exec", 1, 1, cmd_exec},
-	{"exit", 0, 0, good_exit},
-	{"fix-sysmo-msisdn", 0, 0, cmd_fix_sysmo_msisdn},
-	{"fplmn-dump", 0, 0, cmd_fplmn_dump},
-	{"fplmn-erase", 1, 2, cmd_fplmn_erase},
-	{"fplmn-erase-all", 0, 0, cmd_fplmn_erase_all},
-	{"fplmn-write", 2, 2, cmd_fplmn_write},
-	{"grcard1-set-adm1", 2, 2, cmd_grcard1_set_adm},
-	{"grcard1-set-adm2", 2, 2, cmd_grcard1_set_adm},
-	{"grcard1-set-ki", 1, 1, cmd_grcard1_set_ki},
-	{"grcard1-set-pin1", 2, 2, cmd_grcard1_set_pin},
-	{"grcard1-set-pin2", 2, 2, cmd_grcard1_set_pin},
-	{"grcard2-set-adm", 1, 1, cmd_grcard2_set_adm},
-	{"grcard2-set-adm-hex", 1, 1, cmd_grcard2_set_adm_hex},
-	{"grcard2-set-pin1", 1, 1, cmd_grcard2_set_pin},
-	{"grcard2-set-pin2", 1, 1, cmd_grcard2_set_pin},
-	{"grcard2-set-puk1", 1, 1, cmd_grcard2_set_puk},
-	{"grcard2-set-puk2", 1, 1, cmd_grcard2_set_puk},
-	{"grcard2-set-super", 1, 1, cmd_grcard2_set_super},
-	{"grcard2-set-super-hex", 1, 1, cmd_grcard2_set_super_hex},
-	{"iccid", 0, 0, cmd_iccid},
-	{"imsi", 0, 0, cmd_imsi},
-	{"lnd-dump", 0, 1, cmd_lnd_dump},
-	{"lnd-erase", 0, 0, cmd_lnd_erase},
-	{"lnd-restore", 1, 1, cmd_lnd_restore},
-	{"lnd-write", 1, 2, cmd_lnd_write},
-	{"opl-dump", 0, 0, cmd_opl_dump},
-	{"pb-dump", 1, 2, cmd_pb_dump},
-	{"pb-dump-rec", 2, 3, cmd_pb_dump_rec},
-	{"pb-erase", 1, 1, cmd_pb_erase},
-	{"pb-erase-one", 2, 2, cmd_pb_erase_one},
-	{"pb-erase-range", 3, 3, cmd_pb_erase_range},
-	{"pb-restore", 2, 2, cmd_pb_restore},
-	{"pb-update", 2, 2, cmd_pb_update},
-	{"pb-update-imm", 3, 4, cmd_pb_update_imm},
-	{"pb-update-imm-hex", 4, 4, cmd_pb_update_imm_hex},
-	{"plmnsel-dump", 0, 1, cmd_plmnsel_dump},
-	{"plmnsel-erase", 1, 2, cmd_plmnsel_erase},
-	{"plmnsel-erase-all", 0, 0, cmd_plmnsel_erase_all},
-	{"plmnsel-write", 2, 2, cmd_plmnsel_write},
-	{"pnn-dump", 0, 0, cmd_pnn_dump},
-	{"quit", 0, 0, good_exit},
-	{"readbin", 2, 2, cmd_readbin},
-	{"readef", 1, 1, cmd_readef},
-	{"readrec", 1, 2, cmd_readrec},
-	{"restore-file", 2, 2, cmd_restore_file},
-	{"savebin", 2, 2, cmd_savebin},
-	{"save-sms-bin", 1, 1, cmd_save_sms_bin},
-	{"select", 1, 1, cmd_select},
-	{"sim-resp", 0, 0, display_sim_resp_in_hex},
-	{"sms-erase-all", 0, 0, cmd_sms_erase_all},
-	{"sms-erase-one", 1, 1, cmd_sms_erase_one},
-	{"sms-erase-range", 2, 2, cmd_sms_erase_range},
-	{"smsp-dump", 0, 1, cmd_smsp_dump},
-	{"smsp-erase-all", 0, 0, cmd_smsp_erase_all},
-	{"smsp-erase-one", 1, 1, cmd_smsp_erase_one},
-	{"smsp-erase-range", 2, 2, cmd_smsp_erase_range},
-	{"smsp-restore", 1, 1, cmd_smsp_restore},
-	{"smsp-set", 2, 6, cmd_smsp_set},
-	{"smsp-set-tag", 3, 7, cmd_smsp_set_tag},
-	{"spn", 0, 0, cmd_spn},
-	{"sst", 0, 0, cmd_sst},
-	{"telecom-sum", 0, 0, cmd_telecom_sum},
-	{"uicc-dir", 0, 0, cmd_uicc_dir},
-	{"unblock-chv1", 2, 2, cmd_unblock_chv},
-	{"unblock-chv2", 2, 2, cmd_unblock_chv},
-	{"unblock-pin1", 2, 2, cmd_unblock_chv},
-	{"unblock-pin2", 2, 2, cmd_unblock_chv},
-	{"update-bin", 2, 2, cmd_update_bin},
-	{"update-bin-imm", 2, 2, cmd_update_bin_imm},
-	{"update-rec", 2, 2, cmd_update_rec},
-	{"update-rec-prev", 1, 1, cmd_update_rec_prev},
-	{"user-sum", 0, 0, cmd_user_sum},
-	{"verify-chv1", 1, 1, cmd_verify_chv},
-	{"verify-chv2", 1, 1, cmd_verify_chv},
-	{"verify-ext", 2, 2, cmd_verify_ext},
-	{"verify-hex", 2, 2, cmd_verify_hex},
-	{"verify-pin1", 1, 1, cmd_verify_chv},
-	{"verify-pin2", 1, 1, cmd_verify_chv},
-	{"write-iccid", 1, 1, cmd_write_iccid},
-	{"write-imsi", 1, 1, cmd_write_imsi},
-	{0, 0, 0, 0}
+	{"a38", 1, 1, 0, cmd_a38},
+	{"atr", 0, 0, 0, retrieve_atr},
+	{"change-chv1", 2, 2, 0, cmd_change_chv},
+	{"change-chv2", 2, 2, 0, cmd_change_chv},
+	{"change-pin1", 2, 2, 0, cmd_change_chv},
+	{"change-pin2", 2, 2, 0, cmd_change_chv},
+	{"disable-chv", 1, 1, 0, cmd_disable_chv},
+	{"disable-chv1", 1, 1, 0, cmd_disable_chv},
+	{"disable-pin", 1, 1, 0, cmd_disable_chv},
+	{"disable-pin1", 1, 1, 0, cmd_disable_chv},
+	{"enable-chv", 1, 1, 0, cmd_enable_chv},
+	{"enable-chv1", 1, 1, 0, cmd_enable_chv},
+	{"enable-pin", 1, 1, 0, cmd_enable_chv},
+	{"enable-pin1", 1, 1, 0, cmd_enable_chv},
+	{"exec", 1, 1, 0, cmd_exec},
+	{"exit", 0, 0, 0, good_exit},
+	{"fix-sysmo-msisdn", 0, 0, 0, cmd_fix_sysmo_msisdn},
+	{"fplmn-dump", 0, 0, 0, cmd_fplmn_dump},
+	{"fplmn-erase", 1, 2, 0, cmd_fplmn_erase},
+	{"fplmn-erase-all", 0, 0, 0, cmd_fplmn_erase_all},
+	{"fplmn-write", 2, 2, 0, cmd_fplmn_write},
+	{"grcard1-set-adm1", 2, 2, 0, cmd_grcard1_set_adm},
+	{"grcard1-set-adm2", 2, 2, 0, cmd_grcard1_set_adm},
+	{"grcard1-set-ki", 1, 1, 0, cmd_grcard1_set_ki},
+	{"grcard1-set-pin1", 2, 2, 0, cmd_grcard1_set_pin},
+	{"grcard1-set-pin2", 2, 2, 0, cmd_grcard1_set_pin},
+	{"grcard2-set-adm", 1, 1, 0, cmd_grcard2_set_adm},
+	{"grcard2-set-adm-hex", 1, 1, 0, cmd_grcard2_set_adm_hex},
+	{"grcard2-set-pin1", 1, 1, 0, cmd_grcard2_set_pin},
+	{"grcard2-set-pin2", 1, 1, 0, cmd_grcard2_set_pin},
+	{"grcard2-set-puk1", 1, 1, 0, cmd_grcard2_set_puk},
+	{"grcard2-set-puk2", 1, 1, 0, cmd_grcard2_set_puk},
+	{"grcard2-set-super", 1, 1, 0, cmd_grcard2_set_super},
+	{"grcard2-set-super-hex", 1, 1, 0, cmd_grcard2_set_super_hex},
+	{"iccid", 0, 0, 0, cmd_iccid},
+	{"imsi", 0, 0, 0, cmd_imsi},
+	{"lnd-dump", 0, 1, 0, cmd_lnd_dump},
+	{"lnd-erase", 0, 0, 0, cmd_lnd_erase},
+	{"lnd-restore", 1, 1, 0, cmd_lnd_restore},
+	{"lnd-write", 1, 2, 0, cmd_lnd_write},
+	{"opl-dump", 0, 0, 0, cmd_opl_dump},
+	{"pb-dump", 1, 2, 0, cmd_pb_dump},
+	{"pb-dump-rec", 2, 3, 0, cmd_pb_dump_rec},
+	{"pb-erase", 1, 1, 0, cmd_pb_erase},
+	{"pb-erase-one", 2, 2, 0, cmd_pb_erase_one},
+	{"pb-erase-range", 3, 3, 0, cmd_pb_erase_range},
+	{"pb-restore", 2, 2, 0, cmd_pb_restore},
+	{"pb-update", 2, 2, 0, cmd_pb_update},
+	{"pb-update-imm", 3, 4, 0, cmd_pb_update_imm},
+	{"pb-update-imm-hex", 4, 4, 0, cmd_pb_update_imm_hex},
+	{"plmnsel-dump", 0, 1, 0, cmd_plmnsel_dump},
+	{"plmnsel-erase", 1, 2, 0, cmd_plmnsel_erase},
+	{"plmnsel-erase-all", 0, 0, 0, cmd_plmnsel_erase_all},
+	{"plmnsel-write", 2, 2, 0, cmd_plmnsel_write},
+	{"pnn-dump", 0, 0, 0, cmd_pnn_dump},
+	{"quit", 0, 0, 0, good_exit},
+	{"readbin", 2, 2, 0, cmd_readbin},
+	{"readef", 1, 1, 0, cmd_readef},
+	{"readrec", 1, 2, 0, cmd_readrec},
+	{"restore-file", 2, 2, 0, cmd_restore_file},
+	{"savebin", 2, 2, 0, cmd_savebin},
+	{"save-sms-bin", 1, 1, 0, cmd_save_sms_bin},
+	{"select", 1, 1, 0, cmd_select},
+	{"sim-resp", 0, 0, 0, display_sim_resp_in_hex},
+	{"sms-erase-all", 0, 0, 0, cmd_sms_erase_all},
+	{"sms-erase-one", 1, 1, 0, cmd_sms_erase_one},
+	{"sms-erase-range", 2, 2, 0, cmd_sms_erase_range},
+	{"smsp-dump", 0, 1, 0, cmd_smsp_dump},
+	{"smsp-erase-all", 0, 0, 0, cmd_smsp_erase_all},
+	{"smsp-erase-one", 1, 1, 0, cmd_smsp_erase_one},
+	{"smsp-erase-range", 2, 2, 0, cmd_smsp_erase_range},
+	{"smsp-restore", 1, 1, 0, cmd_smsp_restore},
+	{"smsp-set", 2, 6, 0, cmd_smsp_set},
+	{"smsp-set-tag", 3, 7, 0, cmd_smsp_set_tag},
+	{"spn", 0, 0, 0, cmd_spn},
+	{"sst", 0, 0, 0, cmd_sst},
+	{"telecom-sum", 0, 0, 0, cmd_telecom_sum},
+	{"uicc-dir", 0, 0, 0, cmd_uicc_dir},
+	{"unblock-chv1", 2, 2, 0, cmd_unblock_chv},
+	{"unblock-chv2", 2, 2, 0, cmd_unblock_chv},
+	{"unblock-pin1", 2, 2, 0, cmd_unblock_chv},
+	{"unblock-pin2", 2, 2, 0, cmd_unblock_chv},
+	{"update-bin", 2, 2, 0, cmd_update_bin},
+	{"update-bin-imm", 2, 2, 0, cmd_update_bin_imm},
+	{"update-rec", 2, 2, 0, cmd_update_rec},
+	{"update-rec-prev", 1, 1, 0, cmd_update_rec_prev},
+	{"user-sum", 0, 0, 0, cmd_user_sum},
+	{"verify-chv1", 1, 1, 0, cmd_verify_chv},
+	{"verify-chv2", 1, 1, 0, cmd_verify_chv},
+	{"verify-ext", 2, 2, 0, cmd_verify_ext},
+	{"verify-hex", 2, 2, 0, cmd_verify_hex},
+	{"verify-pin1", 1, 1, 0, cmd_verify_chv},
+	{"verify-pin2", 1, 1, 0, cmd_verify_chv},
+	{"write-iccid", 1, 1, 0, cmd_write_iccid},
+	{"write-imsi", 1, 1, 0, cmd_write_imsi},
+	{0, 0, 0, 0, 0}
 };
 
+static FILE *
+handle_output_redir(str)
+	char *str;
+{
+	char *cp, *fn;
+	FILE *outf;
+
+	for (cp = str; isspace(*cp); cp++)
+		;
+	if (!*cp || *cp == '#') {
+		fprintf(stderr, "error: no filename after '>'\n");
+		return(0);
+	}
+	for (fn = cp; *cp && !isspace(*cp); cp++)
+		;
+	if (*cp)
+		*cp++ = '\0';
+	while (isspace(*cp))
+		cp++;
+	if (*cp && *cp != '#') {
+		fprintf(stderr, "error: invalid syntax after '>'\n");
+		return(0);
+	}
+	outf = fopen(fn, "w");
+	if (!outf)
+		perror(fn);
+	return outf;
+}
+
 simtool_dispatch_cmd(cmd, is_script)
 	char *cmd;
 {
 	char *argv[10];
 	char *cp, **ap;
 	struct cmdtab *tp;
+	FILE *outf;
+	int rc;
 
 	for (cp = cmd; isspace(*cp); cp++)
 		;
@@ -217,7 +249,7 @@
 	for (ap = argv + 1; ; ) {
 		while (isspace(*cp))
 			cp++;
-		if (!*cp || *cp == '#')
+		if (!*cp || *cp == '#' || *cp == '>')
 			break;
 		if (ap - argv - 1 >= tp->maxargs) {
 			fprintf(stderr, "error: too many arguments\n");
@@ -253,7 +285,21 @@
 		return(-1);
 	}
 	*ap = 0;
-	return tp->func(ap - argv, argv);
+	if (*cp == '>') {
+		if (!tp->allow_redir) {
+			fprintf(stderr,
+			"error: command does not support output redirection\n");
+			return(-1);
+		}
+		outf = handle_output_redir(cp + 1);
+		if (!outf)
+			return(-1);
+	} else
+		outf = stdout;
+	rc = tp->func(ap - argv, argv, outf);
+	if (outf != stdout)
+		fclose(outf);
+	return rc;
 }
 
 dispatch_ready_argv(argc, argv)
@@ -276,5 +322,5 @@
 		fprintf(stderr, "error: too few arguments\n");
 		return(-1);
 	}
-	return tp->func(argc, argv);
+	return tp->func(argc, argv, stdout);
 }