[dvblast-devel] [PATCH 4/6] dvblastctl: Add better command parameter handling.
Georgi Chorbadzhiyski
gf at unixsol.org
Mon Sep 12 22:40:01 CEST 2011
Switch dvblastctl to use table describing all commands. Also
report verbose errors when user have not supplied enough
arguments or unknown command.
Signed-off-by: Georgi Chorbadzhiyski <gf at unixsol.org>
---
dvblastctl.c | 122 ++++++++++++++++++++++++++++++++++++----------------------
1 files changed, 76 insertions(+), 46 deletions(-)
diff --git a/dvblastctl.c b/dvblastctl.c
index 607d3b1..c4f0f68 100644
--- a/dvblastctl.c
+++ b/dvblastctl.c
@@ -132,6 +132,38 @@ void print_pids( uint8_t *p_data )
print_pids_footer();
}
+struct dvblastctl_option {
+ char * opt;
+ int nparams;
+ ctl_cmd_t cmd;
+};
+
+static const struct dvblastctl_option options[] =
+{
+ { "reload", 0, CMD_RELOAD },
+ { "shutdown", 0, CMD_SHUTDOWN },
+
+ { "fe_status", 0, CMD_FRONTEND_STATUS },
+ { "mmi_status", 0, CMD_MMI_STATUS },
+
+ { "mmi_slot_status", 1, CMD_MMI_SLOT_STATUS }, /* arg: slot */
+ { "mmi_open", 1, CMD_MMI_OPEN }, /* arg: slot */
+ { "mmi_close", 1, CMD_MMI_CLOSE }, /* arg: slot */
+ { "mmi_get", 1, CMD_MMI_RECV }, /* arg: slot */
+ { "mmi_send_text", 1, CMD_MMI_SEND }, /* arg: slot, en50221_mmi_object_t */
+ { "mmi_send_choice", 2, CMD_MMI_SEND }, /* arg: slot, en50221_mmi_object_t */
+
+ { "get_pat", 0, CMD_GET_PAT },
+ { "get_cat", 0, CMD_GET_CAT },
+ { "get_nit", 0, CMD_GET_NIT },
+ { "get_sdt", 0, CMD_GET_SDT },
+ { "get_pmt", 1, CMD_GET_PMT }, /* arg: service_id (uint16_t) */
+ { "get_pids", 0, CMD_RELOAD },
+ { "get_pid", 1, CMD_RELOAD }, /* arg: pid (uint16_t) */
+
+ { NULL, 0, 0 }
+};
+
void usage()
{
printf("DVBlastctl %d.%d.%d (%s)\n", VERSION_MAJOR, VERSION_MINOR,
@@ -170,13 +202,14 @@ int main( int i_argc, char **ppsz_argv )
char psz_client_socket[PATH_MAX] = {0};
char *client_socket_tmpl = "dvblastctl.clientsock.XXXXXX";
char *psz_srv_socket = NULL;
- int i_fd;
- int i = COMM_MAX_MSG_CHUNK;
+ int i_fd, i;
+ char *p_cmd, *p_arg1 = NULL, *p_arg2 = NULL;
ssize_t i_size;
struct sockaddr_un sun_client, sun_server;
uint8_t p_buffer[COMM_BUFFER_SIZE];
uint8_t *p_data = p_buffer + COMM_HEADER_SIZE;
uint16_t i_pid = 0;
+ struct dvblastctl_option opt = { 0, 0, 0 };
for ( ; ; )
{
@@ -216,42 +249,40 @@ int main( int i_argc, char **ppsz_argv )
}
}
- if ( ppsz_argv[optind] == NULL || psz_srv_socket == NULL )
- usage();
-
- if ( strcmp(ppsz_argv[optind], "reload")
- && strcmp(ppsz_argv[optind], "shutdown")
- && strcmp(ppsz_argv[optind], "fe_status")
- && strcmp(ppsz_argv[optind], "get_pat")
- && strcmp(ppsz_argv[optind], "get_cat")
- && strcmp(ppsz_argv[optind], "get_nit")
- && strcmp(ppsz_argv[optind], "get_sdt")
- && strcmp(ppsz_argv[optind], "get_pmt")
- && strcmp(ppsz_argv[optind], "get_pid")
- && strcmp(ppsz_argv[optind], "get_pids")
- && strcmp(ppsz_argv[optind], "mmi_status")
- && strcmp(ppsz_argv[optind], "mmi_slot_status")
- && strcmp(ppsz_argv[optind], "mmi_open")
- && strcmp(ppsz_argv[optind], "mmi_close")
- && strcmp(ppsz_argv[optind], "mmi_get")
- && strcmp(ppsz_argv[optind], "mmi_send_text")
- && strcmp(ppsz_argv[optind], "mmi_send_choice") )
- usage();
-
- if ( (!strcmp(ppsz_argv[optind], "mmi_slot_status")
- || !strcmp(ppsz_argv[optind], "get_pmt")
- || !strcmp(ppsz_argv[optind], "get_pid")
- || !strcmp(ppsz_argv[optind], "mmi_open")
- || !strcmp(ppsz_argv[optind], "mmi_close")
- || !strcmp(ppsz_argv[optind], "mmi_get")
- || !strcmp(ppsz_argv[optind], "mmi_send_text")
- || !strcmp(ppsz_argv[optind], "mmi_send_choice"))
- && ppsz_argv[optind + 1] == NULL )
- usage();
-
- if ( !strcmp(ppsz_argv[optind], "mmi_send_choice")
- && ppsz_argv[optind + 2] == NULL )
- usage();
+ /* Validate commands */
+#define usage_error(msg, ...) \
+ do { \
+ msg_Err( NULL, msg, ##__VA_ARGS__ ); \
+ usage(); \
+ } while(0)
+ p_cmd = ppsz_argv[optind];
+ p_arg1 = ppsz_argv[optind + 1];
+ p_arg2 = ppsz_argv[optind + 2];
+
+ if ( !psz_srv_socket )
+ usage_error( "Remote socket is not set.\n" );
+
+ if ( !p_cmd )
+ usage_error( "Command is not set.\n" );
+
+ i = 0;
+ do {
+ if ( streq(ppsz_argv[optind], options[i].opt) )
+ {
+ opt = options[i];
+ break;
+ }
+ } while ( options[++i].opt );
+
+ if ( !opt.opt )
+ usage_error( "Unknown command: %s\n", p_cmd );
+
+ if ( opt.nparams == 1 && !p_arg1 )
+ usage_error( "%s option needs parameter.\n", opt.opt );
+
+ if ( opt.nparams == 2 && (!p_arg1 || !p_arg2) )
+ usage_error( "%s option needs two parameters.\n", opt.opt );
+#undef usage_error
/* Create client socket name */
char *tmpdir = getenv("TMPDIR");
@@ -274,6 +305,7 @@ int main( int i_argc, char **ppsz_argv )
return -1;
}
+ i = COMM_MAX_MSG_CHUNK;
setsockopt( i_fd, SOL_SOCKET, SO_RCVBUF, &i, sizeof(i) );
memset( &sun_client, 0, sizeof(sun_client) );
@@ -315,7 +347,7 @@ int main( int i_argc, char **ppsz_argv )
else if ( !strcmp(ppsz_argv[optind], "get_sdt") )
p_buffer[1] = CMD_GET_SDT;
else if ( !strcmp(ppsz_argv[optind], "get_pmt") ) {
- uint16_t i_sid = atoi(ppsz_argv[optind + 1]);
+ uint16_t i_sid = atoi(p_arg1);
p_buffer[1] = CMD_GET_PMT;
i_size = COMM_HEADER_SIZE + 2;
p_data[0] = (uint8_t)((i_sid >> 8) & 0xff);
@@ -323,7 +355,7 @@ int main( int i_argc, char **ppsz_argv )
} else if ( !strcmp(ppsz_argv[optind], "get_pids") )
p_buffer[1] = CMD_GET_PIDS;
else if ( !strcmp(ppsz_argv[optind], "get_pid") ) {
- i_pid = (uint16_t)atoi(ppsz_argv[optind + 1]);
+ i_pid = (uint16_t)atoi(p_arg1);
p_buffer[1] = CMD_GET_PID;
i_size = COMM_HEADER_SIZE + 2;
p_data[0] = (uint8_t)((i_pid >> 8) & 0xff);
@@ -332,7 +364,7 @@ int main( int i_argc, char **ppsz_argv )
p_buffer[1] = CMD_MMI_STATUS;
else
{
- p_buffer[4] = atoi(ppsz_argv[optind + 1]);
+ p_buffer[4] = atoi(p_arg1);
i_size = COMM_HEADER_SIZE + 1;
if ( !strcmp(ppsz_argv[optind], "mmi_slot_status") )
@@ -353,8 +385,7 @@ int main( int i_argc, char **ppsz_argv )
en50221_mmi_object_t object;
object.i_object_type = EN50221_MMI_ANSW;
- if ( ppsz_argv[optind + 2] == NULL
- || ppsz_argv[optind + 2][0] == '\0' )
+ if ( !p_arg2 || p_arg2[0] == '\0' )
{
object.u.answ.b_ok = 0;
object.u.answ.psz_answ = "";
@@ -362,7 +393,7 @@ int main( int i_argc, char **ppsz_argv )
else
{
object.u.answ.b_ok = 1;
- object.u.answ.psz_answ = ppsz_argv[optind + 2];
+ object.u.answ.psz_answ = p_arg2;
}
i_size = COMM_BUFFER_SIZE - COMM_HEADER_SIZE
- ((void *)&p_cmd->object - (void *)p_cmd);
@@ -385,8 +416,7 @@ int main( int i_argc, char **ppsz_argv )
i_size = COMM_HEADER_SIZE + sizeof(struct cmd_mmi_send);
p_cmd->object.i_object_type = EN50221_MMI_MENU_ANSW;
- p_cmd->object.u.menu_answ.i_choice
- = atoi(ppsz_argv[optind + 2]);
+ p_cmd->object.u.menu_answ.i_choice = atoi(p_arg2);
}
}
}
--
1.7.5.1
More information about the dvblast-devel
mailing list