Add support for #!../maxadmin scripts
Add the --help option Add quoting for executing command with arguments that contain whitespace
This commit is contained in:
@ -55,6 +55,7 @@ static int setipaddress(struct in_addr *a, char *p);
|
|||||||
static int authMaxScale(int so, char *user, char *password);
|
static int authMaxScale(int so, char *user, char *password);
|
||||||
static int sendCommand(int so, char *cmd);
|
static int sendCommand(int so, char *cmd);
|
||||||
static void DoSource(int so, char *cmd);
|
static void DoSource(int so, char *cmd);
|
||||||
|
static void DoUsage();
|
||||||
|
|
||||||
#ifdef HISTORY
|
#ifdef HISTORY
|
||||||
static char *
|
static char *
|
||||||
@ -66,6 +67,12 @@ prompt(EditLine *el __attribute__((__unused__)))
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main for the maxadmin client
|
||||||
|
*
|
||||||
|
* @param argc Number of arguments
|
||||||
|
* @param argv The command line arguments
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -86,6 +93,7 @@ char *user = "admin";
|
|||||||
char *passwd = NULL;
|
char *passwd = NULL;
|
||||||
int so, cmdlen;
|
int so, cmdlen;
|
||||||
char *cmd;
|
char *cmd;
|
||||||
|
int argno = 0;
|
||||||
|
|
||||||
cmd = malloc(1);
|
cmd = malloc(1);
|
||||||
*cmd = 0;
|
*cmd = 0;
|
||||||
@ -145,14 +153,41 @@ char *cmd;
|
|||||||
fatal = 1;
|
fatal = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case '-':
|
||||||
|
{
|
||||||
|
char *word;
|
||||||
|
|
||||||
|
word = &argv[i][2];
|
||||||
|
if (strcmp(word, "help") == 0)
|
||||||
|
{
|
||||||
|
DoUsage();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cmdlen += strlen(argv[i]) + 1;
|
/* Arguments after the second argument are quoted
|
||||||
cmd = realloc(cmd, cmdlen);
|
* to allow for quoted names on the command line
|
||||||
strcat(cmd, argv[i]);
|
* to be passed on in quotes.
|
||||||
strcat(cmd, " ");
|
*/
|
||||||
|
if (argno++ > 1)
|
||||||
|
{
|
||||||
|
cmdlen += strlen(argv[i]) + 3;
|
||||||
|
cmd = realloc(cmd, cmdlen);
|
||||||
|
strcat(cmd, "\"");
|
||||||
|
strcat(cmd, argv[i]);
|
||||||
|
strcat(cmd, "\" ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmdlen += strlen(argv[i]) + 1;
|
||||||
|
cmd = realloc(cmd, cmdlen);
|
||||||
|
strcat(cmd, argv[i]);
|
||||||
|
strcat(cmd, " ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,8 +233,11 @@ char *cmd;
|
|||||||
|
|
||||||
if (cmdlen > 1)
|
if (cmdlen > 1)
|
||||||
{
|
{
|
||||||
cmd[cmdlen - 2] = '\0';
|
cmd[cmdlen - 2] = '\0'; /* Remove trailing space */
|
||||||
sendCommand(so, cmd);
|
if (access(cmd, R_OK) == 0)
|
||||||
|
DoSource(so, cmd);
|
||||||
|
else
|
||||||
|
sendCommand(so, cmd);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +304,14 @@ char *cmd;
|
|||||||
}
|
}
|
||||||
else if (!strncasecmp(buf, "source", 6))
|
else if (!strncasecmp(buf, "source", 6))
|
||||||
{
|
{
|
||||||
DoSource(so, buf);
|
char *ptr;
|
||||||
|
|
||||||
|
/* Find the filename */
|
||||||
|
ptr = &buf[strlen("source")];
|
||||||
|
while (*ptr && isspace(*ptr))
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
DoSource(so, ptr);
|
||||||
}
|
}
|
||||||
else if (*buf)
|
else if (*buf)
|
||||||
{
|
{
|
||||||
@ -283,6 +328,13 @@ char *cmd;
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to the MaxScale server
|
||||||
|
*
|
||||||
|
* @param hostname The hostname to connect to
|
||||||
|
* @param port The port to use for the connection
|
||||||
|
* @return The connected socket or -1 on error
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
connectMaxScale(char *hostname, char *port)
|
connectMaxScale(char *hostname, char *port)
|
||||||
{
|
{
|
||||||
@ -310,7 +362,7 @@ int so;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Set IP address in socket structure in_addr
|
* Set IP address in socket structure in_addr
|
||||||
*
|
*
|
||||||
* @param a Pointer to a struct in_addr into which the address is written
|
* @param a Pointer to a struct in_addr into which the address is written
|
||||||
@ -364,6 +416,14 @@ setipaddress(struct in_addr *a, char *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform authentication using the maxscaled protocol conventions
|
||||||
|
*
|
||||||
|
* @param so The socket connected to MaxScale
|
||||||
|
* @param user The username to authenticate
|
||||||
|
* @param password The password to authenticate with
|
||||||
|
* @return Non-zero of succesful authentication
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
authMaxScale(int so, char *user, char *password)
|
authMaxScale(int so, char *user, char *password)
|
||||||
{
|
{
|
||||||
@ -378,6 +438,14 @@ char buf[20];
|
|||||||
return strncmp(buf, "FAILED", 6);
|
return strncmp(buf, "FAILED", 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a comamnd using the MaxScaled protocol, display the return data
|
||||||
|
* on standard output
|
||||||
|
*
|
||||||
|
* @param so The socket connect to MaxScale
|
||||||
|
* @param cmd The command to send
|
||||||
|
* @return 0 if the connection was closed
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
sendCommand(int so, char *cmd)
|
sendCommand(int so, char *cmd)
|
||||||
{
|
{
|
||||||
@ -399,22 +467,23 @@ int i;
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a file of commands and send them to MaxScale
|
||||||
|
*
|
||||||
|
* @param so The socket connected to MaxScale
|
||||||
|
* @param file The filename
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
DoSource(int so, char *buf)
|
DoSource(int so, char *file)
|
||||||
{
|
{
|
||||||
char *ptr, *pe;
|
char *ptr, *pe;
|
||||||
char line[132];
|
char line[132];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
/* Find the filename */
|
if ((fp = fopen(file, "r")) == NULL)
|
||||||
ptr = &buf[strlen("source")];
|
|
||||||
while (*ptr && isspace(*ptr))
|
|
||||||
ptr++;
|
|
||||||
|
|
||||||
if ((fp = fopen(ptr, "r")) == NULL)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unable to open command file '%s'.\n",
|
fprintf(stderr, "Unable to open command file '%s'.\n",
|
||||||
ptr);
|
file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,3 +508,24 @@ FILE *fp;
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the --help text.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
DoUsage()
|
||||||
|
{
|
||||||
|
printf("maxadmin: The MaxScale administrative and monitor client.\n\n");
|
||||||
|
printf("Usage: maxadmin [-u user] [-p password] [-h hostname] [-P port] [<command file> | <command>]\n\n");
|
||||||
|
printf(" -u user The user name to use for the connection, default\n");
|
||||||
|
printf(" is admin.\n");
|
||||||
|
printf(" -p password The user password, if not given the password will\n");
|
||||||
|
printf(" be prompted for interactively\n");
|
||||||
|
printf(" -h hostname The maxscale host to connecto to. The default is\n");
|
||||||
|
printf(" localhost\n");
|
||||||
|
printf(" -P port The port to use for the connection, the default\n");
|
||||||
|
printf(" port is 6603.\n");
|
||||||
|
printf(" --help Print this help text.\n");
|
||||||
|
printf("Any remaining arguments are treated as MaxScale commands or a file\n");
|
||||||
|
printf("containing commands to execute.\n");
|
||||||
|
}
|
||||||
|
@ -222,13 +222,13 @@ int i;
|
|||||||
{
|
{
|
||||||
dcb_printf(dcb, "Filters\n");
|
dcb_printf(dcb, "Filters\n");
|
||||||
dcb_printf(dcb, "--------------------+-----------------+----------------------------------------\n");
|
dcb_printf(dcb, "--------------------+-----------------+----------------------------------------\n");
|
||||||
dcb_printf(dcb, "%-18s | %-15s | Options\n",
|
dcb_printf(dcb, "%-19s | %-15s | Options\n",
|
||||||
"Filter", "Module");
|
"Filter", "Module");
|
||||||
dcb_printf(dcb, "--------------------+-----------------+----------------------------------------\n");
|
dcb_printf(dcb, "--------------------+-----------------+----------------------------------------\n");
|
||||||
}
|
}
|
||||||
while (ptr)
|
while (ptr)
|
||||||
{
|
{
|
||||||
dcb_printf(dcb, "%-18s | %-15s | ",
|
dcb_printf(dcb, "%-19s | %-15s | ",
|
||||||
ptr->name, ptr->module);
|
ptr->name, ptr->module);
|
||||||
for (i = 0; ptr->options && ptr->options[i]; i++)
|
for (i = 0; ptr->options && ptr->options[i]; i++)
|
||||||
dcb_printf(dcb, "%s ", ptr->options[i]);
|
dcb_printf(dcb, "%s ", ptr->options[i]);
|
||||||
|
@ -87,8 +87,6 @@ static GWPROTOCOL MyObject = {
|
|||||||
NULL /**< Session */
|
NULL /**< Session */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void maxscaled_command(DCB *, unsigned char *cmd);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the mandatory version entry point
|
* Implementation of the mandatory version entry point
|
||||||
*
|
*
|
||||||
|
@ -83,17 +83,17 @@ static int telnetd_listen(DCB *dcb, char *config);
|
|||||||
* The "module object" for the telnetd protocol module.
|
* The "module object" for the telnetd protocol module.
|
||||||
*/
|
*/
|
||||||
static GWPROTOCOL MyObject = {
|
static GWPROTOCOL MyObject = {
|
||||||
telnetd_read_event, /**< Read - EPOLLIN handler */
|
telnetd_read_event, /**< Read - EPOLLIN handler */
|
||||||
telnetd_write, /**< Write - data from gateway */
|
telnetd_write, /**< Write - data from gateway */
|
||||||
telnetd_write_event, /**< WriteReady - EPOLLOUT handler */
|
telnetd_write_event, /**< WriteReady - EPOLLOUT handler */
|
||||||
telnetd_error, /**< Error - EPOLLERR handler */
|
telnetd_error, /**< Error - EPOLLERR handler */
|
||||||
telnetd_hangup, /**< HangUp - EPOLLHUP handler */
|
telnetd_hangup, /**< HangUp - EPOLLHUP handler */
|
||||||
telnetd_accept, /**< Accept */
|
telnetd_accept, /**< Accept */
|
||||||
NULL, /**< Connect */
|
NULL, /**< Connect */
|
||||||
telnetd_close, /**< Close */
|
telnetd_close, /**< Close */
|
||||||
telnetd_listen, /**< Create a listener */
|
telnetd_listen, /**< Create a listener */
|
||||||
NULL, /**< Authentication */
|
NULL, /**< Authentication */
|
||||||
NULL /**< Session */
|
NULL /**< Session */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void telnetd_command(DCB *, unsigned char *cmd);
|
static void telnetd_command(DCB *, unsigned char *cmd);
|
||||||
|
Reference in New Issue
Block a user