Merge branch 'blr' into cenh
Conflicts: Documentation/MaxScale Configuration And Usage Scenarios.pdf server/core/config.c server/core/dcb.c server/core/service.c server/modules/routing/Makefile server/modules/routing/debugcmd.c server/modules/routing/readwritesplit/readwritesplit.c server/modules/routing/readwritesplit/test/rwsplit.sh
This commit is contained in:
@ -36,7 +36,10 @@
|
||||
* Date Who Description
|
||||
* 20/06/13 Mark Riddoch Initial implementation
|
||||
* 17/07/13 Mark Riddoch Additional commands
|
||||
* 09/08/2013 Massimiliano Pinto Addes enable/disable commands (now only for log)
|
||||
* 09/08/2013 Massimiliano Pinto Added enable/disable commands (now only for log)
|
||||
* 20/05/14 Mark Riddoch Added ability to give server and service names rather
|
||||
* than simply addresses
|
||||
* 23/05/14 Mark Riddoch Added support for developer and user modes
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -69,6 +72,12 @@
|
||||
#define ARG_TYPE_ADDRESS 1
|
||||
#define ARG_TYPE_STRING 2
|
||||
#define ARG_TYPE_SERVICE 3
|
||||
#define ARG_TYPE_SERVER 4
|
||||
#define ARG_TYPE_DBUSERS 5
|
||||
#define ARG_TYPE_SESSION 6
|
||||
#define ARG_TYPE_DCB 7
|
||||
#define ARG_TYPE_MONITOR 8
|
||||
|
||||
/**
|
||||
* The subcommand structure
|
||||
*
|
||||
@ -79,6 +88,7 @@ struct subcommand {
|
||||
int n_args;
|
||||
void (*fn)();
|
||||
char *help;
|
||||
char *devhelp;
|
||||
int arg_types[3];
|
||||
};
|
||||
|
||||
@ -87,33 +97,59 @@ static void telnetdShowUsers(DCB *);
|
||||
* The subcommands of the show command
|
||||
*/
|
||||
struct subcommand showoptions[] = {
|
||||
{ "dcbs", 0, dprintAllDCBs, "Show all descriptor control blocks (network connections)",
|
||||
{ "dcbs", 0, dprintAllDCBs,
|
||||
"Show all descriptor control blocks (network connections)",
|
||||
"Show all descriptor control blocks (network connections)",
|
||||
{0, 0, 0} },
|
||||
{ "dcb", 1, dprintDCB, "Show a single descriptor control block e.g. show dcb 0x493340",
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ "dbusers", 1, dcb_usersPrint, "Show statistics and user names for a service's user table.\n\t\tExample : show dbusers <ptr of 'User's data' from services list>",
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ "epoll", 0, dprintPollStats, "Show the poll statistics",
|
||||
{ "dcb", 1, dprintDCB,
|
||||
"Show a single descriptor control block e.g. show dcb 0x493340",
|
||||
"Show a single descriptor control block e.g. show dcb 0x493340",
|
||||
{ARG_TYPE_DCB, 0, 0} },
|
||||
{ "dbusers", 1, dcb_usersPrint,
|
||||
"Show statistics and user names for a service's user table.\n\t\tExample : show dbusers <service name>",
|
||||
"Show statistics and user names for a service's user table.\n\t\tExample : show dbusers <ptr of 'User's data' from services list>|<service name>",
|
||||
{ARG_TYPE_DBUSERS, 0, 0} },
|
||||
{ "epoll", 0, dprintPollStats,
|
||||
"Show the poll statistics",
|
||||
"Show the poll statistics",
|
||||
{0, 0, 0} },
|
||||
{ "modules", 0, dprintAllModules, "Show all currently loaded modules",
|
||||
{ "modules", 0, dprintAllModules,
|
||||
"Show all currently loaded modules",
|
||||
"Show all currently loaded modules",
|
||||
{0, 0, 0} },
|
||||
{ "monitors", 0, monitorShowAll, "Show the monitors that are configured",
|
||||
{ "monitors", 0, monitorShowAll,
|
||||
"Show the monitors that are configured",
|
||||
"Show the monitors that are configured",
|
||||
{0, 0, 0} },
|
||||
{ "server", 1, dprintServer, "Show details for a server, e.g. show server 0x485390",
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ "servers", 0, dprintAllServers, "Show all configured servers",
|
||||
{ "server", 1, dprintServer,
|
||||
"Show details for a named server, e.g. show server dbnode1",
|
||||
"Show details for a server, e.g. show server 0x485390. The address may also be repalced with the server name from the configuration file",
|
||||
{ARG_TYPE_SERVER, 0, 0} },
|
||||
{ "servers", 0, dprintAllServers,
|
||||
"Show all configured servers",
|
||||
"Show all configured servers",
|
||||
{0, 0, 0} },
|
||||
{ "services", 0, dprintAllServices, "Show all configured services in MaxScale",
|
||||
{ "services", 0, dprintAllServices,
|
||||
"Show all configured services in MaxScale",
|
||||
"Show all configured services in MaxScale",
|
||||
{0, 0, 0} },
|
||||
{ "service", 1, dprintService, "Show single service in MaxScale",
|
||||
{ "service", 1, dprintService,
|
||||
"Show a single service in MaxScale, may be passed a service name",
|
||||
"Show a single service in MaxScale, may be passed a service name or address of a service object",
|
||||
{ARG_TYPE_SERVICE, 0, 0} },
|
||||
{ "session", 1, dprintSession, "Show a single session in MaxScale, e.g. show session 0x284830",
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ "sessions", 0, dprintAllSessions, "Show all active sessions in MaxScale",
|
||||
{ "session", 1, dprintSession,
|
||||
"Show a single session in MaxScale, e.g. show session 0x284830",
|
||||
"Show a single session in MaxScale, e.g. show session 0x284830",
|
||||
{ARG_TYPE_SESSION, 0, 0} },
|
||||
{ "sessions", 0, dprintAllSessions,
|
||||
"Show all active sessions in MaxScale",
|
||||
"Show all active sessions in MaxScale",
|
||||
{0, 0, 0} },
|
||||
{ "users", 0, telnetdShowUsers, "Show statistics and user names for the debug interface",
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ NULL, 0, NULL, NULL,
|
||||
{ "users", 0, telnetdShowUsers,
|
||||
"Show statistics and user names for the debug interface",
|
||||
"Show statistics and user names for the debug interface",
|
||||
{0, 0, 0} },
|
||||
{ NULL, 0, NULL, NULL, NULL,
|
||||
{0, 0, 0} }
|
||||
};
|
||||
|
||||
@ -129,7 +165,7 @@ struct subcommand shutdownoptions[] = {
|
||||
0,
|
||||
shutdown_server,
|
||||
"Shutdown MaxScale",
|
||||
|
||||
"Shutdown MaxScale",
|
||||
{0, 0, 0}
|
||||
},
|
||||
{
|
||||
@ -137,13 +173,15 @@ struct subcommand shutdownoptions[] = {
|
||||
1,
|
||||
shutdown_monitor,
|
||||
"Shutdown a monitor, e.g. shutdown monitor 0x48381e0",
|
||||
{ARG_TYPE_ADDRESS, 0, 0}
|
||||
"Shutdown a monitor, e.g. shutdown monitor 0x48381e0",
|
||||
{ARG_TYPE_MONITOR, 0, 0}
|
||||
},
|
||||
{
|
||||
"service",
|
||||
1,
|
||||
shutdown_service,
|
||||
"Shutdown a service, e.g. shutdown service 0x4838320",
|
||||
"Shutdown a service, e.g. shutdown service \"Sales Database\"",
|
||||
"Shutdown a service, e.g. shutdown service 0x4838320 or shutdown service \"Sales Database\"",
|
||||
{ARG_TYPE_SERVICE, 0, 0}
|
||||
},
|
||||
{
|
||||
@ -151,6 +189,7 @@ struct subcommand shutdownoptions[] = {
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
{0, 0, 0}
|
||||
}
|
||||
};
|
||||
@ -162,11 +201,15 @@ static void restart_monitor(DCB *dcb, MONITOR *monitor);
|
||||
* The subcommands of the restart command
|
||||
*/
|
||||
struct subcommand restartoptions[] = {
|
||||
{ "monitor", 1, restart_monitor, "Restart a monitor, e.g. restart monitor 0x48181e0",
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ "service", 1, restart_service, "Restart a service, e.g. restart service name",
|
||||
{ "monitor", 1, restart_monitor,
|
||||
"Restart a monitor, e.g. restart monitor 0x48181e0",
|
||||
"Restart a monitor, e.g. restart monitor 0x48181e0",
|
||||
{ARG_TYPE_MONITOR, 0, 0} },
|
||||
{ "service", 1, restart_service,
|
||||
"Restart a service, e.g. restart service \"Test Service\"",
|
||||
"Restart a service, e.g. restart service 0x4838320",
|
||||
{ARG_TYPE_SERVICE, 0, 0} },
|
||||
{ NULL, 0, NULL, NULL,
|
||||
{ NULL, 0, NULL, NULL, NULL,
|
||||
{0, 0, 0} }
|
||||
};
|
||||
|
||||
@ -175,9 +218,11 @@ static void set_server(DCB *dcb, SERVER *server, char *bit);
|
||||
* The subcommands of the set command
|
||||
*/
|
||||
struct subcommand setoptions[] = {
|
||||
{ "server", 2, set_server, "Set the status of a server. E.g. set server 0x4838320 master",
|
||||
{ARG_TYPE_ADDRESS, ARG_TYPE_STRING, 0} },
|
||||
{ NULL, 0, NULL, NULL,
|
||||
{ "server", 2, set_server,
|
||||
"Set the status of a server. E.g. set server dbnode4 master",
|
||||
"Set the status of a server. E.g. set server 0x4838320 master",
|
||||
{ARG_TYPE_SERVER, ARG_TYPE_STRING, 0} },
|
||||
{ NULL, 0, NULL, NULL, NULL,
|
||||
{0, 0, 0} }
|
||||
};
|
||||
|
||||
@ -186,9 +231,11 @@ static void clear_server(DCB *dcb, SERVER *server, char *bit);
|
||||
* The subcommands of the clear command
|
||||
*/
|
||||
struct subcommand clearoptions[] = {
|
||||
{ "server", 2, clear_server, "Clear the status of a server. E.g. clear server 0x4838320 master",
|
||||
{ARG_TYPE_ADDRESS, ARG_TYPE_STRING, 0} },
|
||||
{ NULL, 0, NULL, NULL,
|
||||
{ "server", 2, clear_server,
|
||||
"Clear the status of a server. E.g. clear server dbnode2 master",
|
||||
"Clear the status of a server. E.g. clear server 0x4838320 master",
|
||||
{ARG_TYPE_SERVER, ARG_TYPE_STRING, 0} },
|
||||
{ NULL, 0, NULL, NULL, NULL,
|
||||
{0, 0, 0} }
|
||||
};
|
||||
|
||||
@ -199,11 +246,15 @@ static void reload_config(DCB *dcb);
|
||||
* The subcommands of the reload command
|
||||
*/
|
||||
struct subcommand reloadoptions[] = {
|
||||
{ "config", 0, reload_config, "Reload the configuration data for MaxScale.",
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ "dbusers", 1, reload_dbusers, "Reload the dbuser data for a service. E.g. reload dbusers 0x849420",
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ NULL, 0, NULL, NULL,
|
||||
{ "config", 0, reload_config,
|
||||
"Reload the configuration data for MaxScale.",
|
||||
"Reload the configuration data for MaxScale.",
|
||||
{0, 0, 0} },
|
||||
{ "dbusers", 1, reload_dbusers,
|
||||
"Reload the dbuser data for a service. E.g. reload dbusers \"splitter service\"",
|
||||
"Reload the dbuser data for a service. E.g. reload dbusers 0x849420",
|
||||
{ARG_TYPE_DBUSERS, 0, 0} },
|
||||
{ NULL, 0, NULL, NULL, NULL,
|
||||
{0, 0, 0} }
|
||||
};
|
||||
|
||||
@ -220,6 +271,8 @@ struct subcommand enableoptions[] = {
|
||||
enable_log_action,
|
||||
"Enable Log options for MaxScale, options trace | error | "
|
||||
"message E.g. enable log message.",
|
||||
"Enable Log options for MaxScale, options trace | error | "
|
||||
"message E.g. enable log message.",
|
||||
{ARG_TYPE_STRING, 0, 0}
|
||||
},
|
||||
{
|
||||
@ -227,6 +280,7 @@ struct subcommand enableoptions[] = {
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
{0, 0, 0}
|
||||
}
|
||||
};
|
||||
@ -242,6 +296,8 @@ struct subcommand disableoptions[] = {
|
||||
disable_log_action,
|
||||
"Disable Log for MaxScale, Options: debug | trace | error | message "
|
||||
"E.g. disable log debug",
|
||||
"Disable Log for MaxScale, Options: debug | trace | error | message "
|
||||
"E.g. disable log debug",
|
||||
{ARG_TYPE_STRING, 0, 0}
|
||||
},
|
||||
{
|
||||
@ -249,6 +305,7 @@ struct subcommand disableoptions[] = {
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
{0, 0, 0}
|
||||
}
|
||||
};
|
||||
@ -267,6 +324,7 @@ struct subcommand failoptions[] = {
|
||||
0,
|
||||
fail_backendfd,
|
||||
"Fail backend socket for next operation.",
|
||||
"Fail backend socket for next operation.",
|
||||
{ARG_TYPE_STRING, 0, 0}
|
||||
},
|
||||
{
|
||||
@ -274,6 +332,7 @@ struct subcommand failoptions[] = {
|
||||
0,
|
||||
fail_clientfd,
|
||||
"Fail client socket for next operation.",
|
||||
"Fail client socket for next operation.",
|
||||
{ARG_TYPE_STRING, 0, 0}
|
||||
},
|
||||
{
|
||||
@ -281,6 +340,7 @@ struct subcommand failoptions[] = {
|
||||
2,
|
||||
fail_accept,
|
||||
"Fail to accept next client connection.",
|
||||
"Fail to accept next client connection.",
|
||||
{ARG_TYPE_STRING, ARG_TYPE_STRING, 0}
|
||||
},
|
||||
{
|
||||
@ -288,6 +348,7 @@ struct subcommand failoptions[] = {
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
{0, 0, 0}
|
||||
}
|
||||
};
|
||||
@ -298,9 +359,11 @@ static void telnetdAddUser(DCB *, char *, char *);
|
||||
* The subcommands of the add command
|
||||
*/
|
||||
struct subcommand addoptions[] = {
|
||||
{ "user", 2, telnetdAddUser, "Add a new user for the debug interface. E.g. add user john today",
|
||||
{ "user", 2, telnetdAddUser,
|
||||
"Add a new user for the debug interface. E.g. add user john today",
|
||||
"Add a new user for the debug interface. E.g. add user john today",
|
||||
{ARG_TYPE_STRING, ARG_TYPE_STRING, 0} },
|
||||
{ NULL, 0, NULL, NULL,
|
||||
{ NULL, 0, NULL, NULL, NULL,
|
||||
{0, 0, 0} }
|
||||
};
|
||||
|
||||
@ -315,10 +378,11 @@ struct subcommand removeoptions[] = {
|
||||
2,
|
||||
telnetdRemoveUser,
|
||||
"Remove existing maxscale user. Example : remove user john johnpwd",
|
||||
"Remove existing maxscale user. Example : remove user john johnpwd",
|
||||
{ARG_TYPE_STRING, ARG_TYPE_STRING, 0}
|
||||
},
|
||||
{
|
||||
NULL, 0, NULL, NULL, {0, 0, 0}
|
||||
NULL, 0, NULL, NULL, NULL, {0, 0, 0}
|
||||
}
|
||||
};
|
||||
|
||||
@ -351,14 +415,16 @@ static struct {
|
||||
* Convert a string argument to a numeric, observing prefixes
|
||||
* for number bases, e.g. 0x for hex, 0 for octal
|
||||
*
|
||||
* @param mode The CLI mode
|
||||
* @param arg The string representation of the argument
|
||||
* @param arg_type The target type for the argument
|
||||
* @return The argument as a long integer
|
||||
*/
|
||||
static unsigned long
|
||||
convert_arg(char *arg, int arg_type)
|
||||
convert_arg(int mode, char *arg, int arg_type)
|
||||
{
|
||||
unsigned long rval;
|
||||
SERVICE *service;
|
||||
|
||||
switch (arg_type)
|
||||
{
|
||||
@ -370,6 +436,38 @@ unsigned long rval;
|
||||
return (unsigned long)strtol(arg, NULL, 0);
|
||||
case ARG_TYPE_STRING:
|
||||
return (unsigned long)arg;
|
||||
case ARG_TYPE_SERVICE:
|
||||
if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0)
|
||||
rval = (unsigned long)service_find(arg);
|
||||
return rval;
|
||||
case ARG_TYPE_SERVER:
|
||||
if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0)
|
||||
rval = (unsigned long)server_find_by_unique_name(arg);
|
||||
return rval;
|
||||
case ARG_TYPE_DBUSERS:
|
||||
if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0)
|
||||
{
|
||||
service = service_find(arg);
|
||||
if (service)
|
||||
return (unsigned long)(service->users);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return rval;
|
||||
case ARG_TYPE_DCB:
|
||||
rval = (unsigned long)strtol(arg, NULL, 0);
|
||||
if (mode == CLIM_USER && dcb_isvalid((DCB *)rval) == 0)
|
||||
rval = 0;
|
||||
return rval;
|
||||
case ARG_TYPE_SESSION:
|
||||
rval = (unsigned long)strtol(arg, NULL, 0);
|
||||
if (mode == CLIM_USER && session_isvalid((SESSION *)rval) == 0)
|
||||
rval = 0;
|
||||
return rval;
|
||||
case ARG_TYPE_MONITOR:
|
||||
if (mode == CLIM_USER || (rval = (unsigned long)strtol(arg, NULL, 0)) == 0)
|
||||
rval = (unsigned long)monitor_find(arg);
|
||||
return rval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -396,33 +494,94 @@ int argc, i, j, found = 0;
|
||||
char *args[MAXARGS];
|
||||
char *saveptr, *delim = " \t\r\n";
|
||||
unsigned long arg1, arg2, arg3;
|
||||
int in_quotes = 0, escape_next = 0;
|
||||
char *ptr, *lptr;
|
||||
|
||||
/* Tokenize the input string */
|
||||
args[0] = strtok_r(cli->cmdbuf, delim, &saveptr);
|
||||
args[0] = cli->cmdbuf;
|
||||
ptr = args[0];
|
||||
lptr = ptr;
|
||||
i = 0;
|
||||
do {
|
||||
i++;
|
||||
args[i] = strtok_r(NULL, delim, &saveptr);
|
||||
} while (args[i] != NULL && i < MAXARGS);
|
||||
/*
|
||||
* Break the command line into a number of words. Whitespace is used
|
||||
* to delimit words and may be escaped by use of the \ character or
|
||||
* the use of double quotes.
|
||||
* The array args contains the broken down words, one per index.
|
||||
*/
|
||||
while (*ptr)
|
||||
{
|
||||
if (escape_next)
|
||||
{
|
||||
*lptr++ = *ptr++;
|
||||
escape_next = 0;
|
||||
}
|
||||
else if (*ptr == '\\')
|
||||
{
|
||||
escape_next = 1;
|
||||
ptr++;
|
||||
}
|
||||
else if (in_quotes == 0 && (*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n'))
|
||||
{
|
||||
*lptr = 0;
|
||||
if (args[i] == ptr)
|
||||
args[i] = ptr + 1;
|
||||
else
|
||||
{
|
||||
i++;
|
||||
if (i >= MAXARGS)
|
||||
break;
|
||||
args[i] = ptr + 1;
|
||||
}
|
||||
ptr++;
|
||||
lptr++;
|
||||
}
|
||||
else if (*ptr == '\"' && in_quotes == 0)
|
||||
{
|
||||
in_quotes = 1;
|
||||
ptr++;
|
||||
}
|
||||
else if (*ptr == '\"' && in_quotes == 1)
|
||||
{
|
||||
in_quotes = 0;
|
||||
ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*lptr++ = *ptr++;
|
||||
}
|
||||
}
|
||||
*lptr = 0;
|
||||
args[i+1] = NULL;
|
||||
|
||||
if (args[0] == NULL)
|
||||
if (args[0] == NULL || *args[0] == 0)
|
||||
return 1;
|
||||
argc = i - 2; /* The number of extra arguments to commands */
|
||||
|
||||
|
||||
if (!strcasecmp(args[0], "help"))
|
||||
{
|
||||
if (args[1] == NULL)
|
||||
if (args[1] == NULL || *args[1] == 0)
|
||||
{
|
||||
found = 1;
|
||||
dcb_printf(dcb, "Available commands:\n");
|
||||
for (i = 0; cmds[i].cmd; i++)
|
||||
{
|
||||
for (j = 0; cmds[i].options[j].arg1; j++)
|
||||
if (cmds[i].options[1].arg1 == NULL)
|
||||
dcb_printf(dcb, " %s %s\n", cmds[i].cmd, cmds[i].options[0].arg1);
|
||||
else
|
||||
{
|
||||
dcb_printf(dcb, " %s %s\n", cmds[i].cmd, cmds[i].options[j].arg1);
|
||||
dcb_printf(dcb, " %s [", cmds[i].cmd);
|
||||
for (j = 0; cmds[i].options[j].arg1; j++)
|
||||
{
|
||||
dcb_printf(dcb, "%s%s", cmds[i].options[j].arg1,
|
||||
cmds[i].options[j+1].arg1 ? "|" : "");
|
||||
}
|
||||
dcb_printf(dcb, "]\n");
|
||||
}
|
||||
}
|
||||
dcb_printf(dcb, "\nType help command to see details of each command.\n");
|
||||
dcb_printf(dcb, "Where commands require names as arguments and these names contain\n");
|
||||
dcb_printf(dcb, "whitespace either the \\ character may be used to escape the whitespace\n");
|
||||
dcb_printf(dcb, "or the name may be enclosed in double quotes \".\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -458,9 +617,9 @@ unsigned long arg1, arg2, arg3;
|
||||
{
|
||||
for (j = 0; cmds[i].options[j].arg1; j++)
|
||||
{
|
||||
found = 1; /**< command and sub-command match */
|
||||
if (strcasecmp(args[1], cmds[i].options[j].arg1) == 0)
|
||||
{
|
||||
found = 1; /**< command and sub-command match */
|
||||
if (argc != cmds[i].options[j].n_args)
|
||||
{
|
||||
dcb_printf(dcb, "Incorrect number of arguments: %s %s expects %d arguments\n",
|
||||
@ -476,7 +635,7 @@ unsigned long arg1, arg2, arg3;
|
||||
cmds[i].options[j].fn(dcb);
|
||||
break;
|
||||
case 1:
|
||||
arg1 = convert_arg(args[2],cmds[i].options[j].arg_types[0]);
|
||||
arg1 = convert_arg(cli->mode, args[2],cmds[i].options[j].arg_types[0]);
|
||||
if (arg1)
|
||||
cmds[i].options[j].fn(dcb, arg1);
|
||||
else
|
||||
@ -484,8 +643,8 @@ unsigned long arg1, arg2, arg3;
|
||||
args[2]);
|
||||
break;
|
||||
case 2:
|
||||
arg1 = convert_arg(args[2],cmds[i].options[j].arg_types[0]);
|
||||
arg2 = convert_arg(args[3],cmds[i].options[j].arg_types[1]);
|
||||
arg1 = convert_arg(cli->mode, args[2],cmds[i].options[j].arg_types[0]);
|
||||
arg2 = convert_arg(cli->mode, args[3],cmds[i].options[j].arg_types[1]);
|
||||
if (arg1 && arg2)
|
||||
cmds[i].options[j].fn(dcb, arg1, arg2);
|
||||
else if (arg1 == 0)
|
||||
@ -496,9 +655,9 @@ unsigned long arg1, arg2, arg3;
|
||||
args[3]);
|
||||
break;
|
||||
case 3:
|
||||
arg1 = convert_arg(args[2],cmds[i].options[j].arg_types[0]);
|
||||
arg2 = convert_arg(args[3],cmds[i].options[j].arg_types[1]);
|
||||
arg3 = convert_arg(args[4],cmds[i].options[j].arg_types[2]);
|
||||
arg1 = convert_arg(cli->mode, args[2],cmds[i].options[j].arg_types[0]);
|
||||
arg2 = convert_arg(cli->mode, args[3],cmds[i].options[j].arg_types[1]);
|
||||
arg3 = convert_arg(cli->mode, args[4],cmds[i].options[j].arg_types[2]);
|
||||
if (arg1 && arg2 && arg3)
|
||||
cmds[i].options[j].fn(dcb, arg1, arg2, arg3);
|
||||
else if (arg1 == 0)
|
||||
|
Reference in New Issue
Block a user