diff uicc/dispatch.c @ 105:16481db543e8

fc-uicc-tool: infrastructure for output redirection
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 19 Feb 2021 06:07:49 +0000
parents d368051576d0
children dcfec53643c5
line wrap: on
line diff
--- a/uicc/dispatch.c	Fri Feb 19 05:58:00 2021 +0000
+++ b/uicc/dispatch.c	Fri Feb 19 06:07:49 2021 +0000
@@ -30,34 +30,66 @@
 	char *cmd;
 	int minargs;
 	int maxargs;
+	int allow_redir;
 	int (*func)();
 } cmdtab[] = {
-	{"atr", 0, 0, retrieve_atr},
-	{"dir", 0, 0, cmd_dir},
-	{"exec", 1, 1, cmd_exec},
-	{"exit", 0, 0, good_exit},
-	{"iccid", 0, 0, cmd_iccid},
-	{"quit", 0, 0, good_exit},
-	{"readbin", 2, 2, cmd_readbin},
-	{"readef", 1, 1, cmd_readef},
-	{"readrec", 1, 2, cmd_readrec},
-	{"select", 1, 1, cmd_select},
-	{"select-aid", 1, 1, cmd_select_aid},
-	{"select-isim", 0, 0, cmd_select_isim},
-	{"select-usim", 0, 0, cmd_select_usim},
-	{"sim-resp", 0, 0, display_sim_resp_in_hex},
-	{"update-bin", 2, 2, cmd_update_bin},
-	{"update-bin-imm", 2, 2, cmd_update_bin_imm},
-	{"update-rec", 2, 2, cmd_update_rec},
-	{0, 0, 0, 0}
+	{"atr", 0, 0, 0, retrieve_atr},
+	{"dir", 0, 0, 0, cmd_dir},
+	{"exec", 1, 1, 0, cmd_exec},
+	{"exit", 0, 0, 0, good_exit},
+	{"iccid", 0, 0, 0, cmd_iccid},
+	{"quit", 0, 0, 0, good_exit},
+	{"readbin", 2, 2, 0, cmd_readbin},
+	{"readef", 1, 1, 0, cmd_readef},
+	{"readrec", 1, 2, 0, cmd_readrec},
+	{"select", 1, 1, 0, cmd_select},
+	{"select-aid", 1, 1, 0, cmd_select_aid},
+	{"select-isim", 0, 0, 0, cmd_select_isim},
+	{"select-usim", 0, 0, 0, cmd_select_usim},
+	{"sim-resp", 0, 0, 0, display_sim_resp_in_hex},
+	{"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},
+	{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++)
 		;
@@ -80,7 +112,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");
@@ -116,7 +148,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)
@@ -139,5 +185,5 @@
 		fprintf(stderr, "error: too few arguments\n");
 		return(-1);
 	}
-	return tp->func(argc, argv);
+	return tp->func(argc, argv, stdout);
 }