support --long options with getopt_long()

This commit is contained in:
Hartmut Holzgraefe
2014-09-03 01:03:10 +02:00
parent 85c88dbd6b
commit 6a03976e4f
3 changed files with 96 additions and 113 deletions

View File

@ -33,7 +33,7 @@ endif
CC=cc CC=cc
CFLAGS=-c -Wall -g $(HISTFLAG) CFLAGS=-c -Wall -g $(HISTFLAG) -I ../server/include
SRCS= maxadmin.c SRCS= maxadmin.c

View File

@ -47,6 +47,9 @@
#include <dirent.h> #include <dirent.h>
#include <locale.h> #include <locale.h>
#include <errno.h> #include <errno.h>
#include <getopt.h>
#include <version.h>
#ifdef HISTORY #ifdef HISTORY
#include <histedit.h> #include <histedit.h>
@ -57,7 +60,8 @@ 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(); static void PrintVersion(const char *progname);
static void DoUsage(const char *progname);
#ifdef HISTORY #ifdef HISTORY
static char * static char *
@ -69,6 +73,16 @@ prompt(EditLine *el __attribute__((__unused__)))
} }
#endif #endif
static struct option long_options[] = {
{"host", required_argument, 0, 'h'},
{"user", required_argument, 0, 'u'},
{"password", required_argument, 0, 'p'},
{"port", required_argument, 0, 'P'},
{"version", no_argument, 0, 'v'},
{"help", no_argument, 0, '?'},
{0, 0, 0, 0}
};
/** /**
* The main for the maxadmin client * The main for the maxadmin client
* *
@ -78,7 +92,7 @@ prompt(EditLine *el __attribute__((__unused__)))
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int i, num, rv, fatal = 0; int i, num, rv;
#ifdef HISTORY #ifdef HISTORY
char *buf; char *buf;
EditLine *el = NULL; EditLine *el = NULL;
@ -95,107 +109,39 @@ char *user = "admin";
char *passwd = NULL; char *passwd = NULL;
int so, cmdlen; int so, cmdlen;
char *cmd; char *cmd;
int argno = 0; int option_index = 0;
char c;
cmd = malloc(1); cmd = malloc(1);
*cmd = 0; *cmd = 0;
cmdlen = 1; cmdlen = 1;
for (i = 1; i < argc; i++) while ((c = getopt_long(argc, argv, "h:p:P:u:v?",
{ long_options, &option_index))
if (argv[i][0] == '-') >= 0)
{ {
switch (argv[i][1]) switch (c) {
{ case 'h':
case 'u': /* User */ hostname = strdup(optarg);
if (argv[i][2]) break;
user = &(argv[i][2]); case 'p':
else if (i + 1 < argc) passwd = strdup(optarg);
user = argv[++i]; break;
else case 'P':
{ port = strdup(optarg);
fprintf(stderr, "Missing username" break;
"in -u option.\n"); case 'u':
fatal = 1; user = strdup(optarg);
} break;
break; case 'v':
case 'p': /* Password */ PrintVersion(*argv);
if (argv[i][2]) exit(EXIT_SUCCESS);
passwd = &(argv[i][2]); case '?':
else if (i + 1 < argc) DoUsage(*argv);
passwd = argv[++i]; exit(optopt ? EXIT_FAILURE : EXIT_SUCCESS);
else }
{
fprintf(stderr, "Missing password "
"in -p option.\n");
fatal = 1;
}
break;
case 'h': /* hostname */
if (argv[i][2])
hostname = &(argv[i][2]);
else if (i + 1 < argc)
hostname = argv[++i];
else
{
fprintf(stderr, "Missing hostname value "
"in -h option.\n");
fatal = 1;
}
break;
case 'P': /* Port */
if (argv[i][2])
port = &(argv[i][2]);
else if (i + 1 < argc)
port = argv[++i];
else
{
fprintf(stderr, "Missing Port value "
"in -P option.\n");
fatal = 1;
}
break;
case '-':
{
char *word;
word = &argv[i][2];
if (strcmp(word, "help") == 0)
{
DoUsage();
exit(0);
}
break;
}
}
}
else
{
/* Arguments after the second argument are quoted
* to allow for quoted names on the command line
* to be passed on in quotes.
*/
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, " ");
}
}
} }
if (fatal)
exit(1);
if (passwd == NULL) if (passwd == NULL)
{ {
struct termios tty_attr; struct termios tty_attr;
@ -532,23 +478,34 @@ FILE *fp;
return; return;
} }
/**
* Print version information
*/
static void
PrintVersion(const char *progname)
{
printf("%s Version %s\n", progname, MAXSCALE_VERSION);
}
/** /**
* Display the --help text. * Display the --help text.
*/ */
static void static void
DoUsage() DoUsage(const char *progname)
{ {
printf("maxadmin: The MaxScale administrative and monitor client.\n\n"); PrintVersion(progname);
printf("Usage: maxadmin [-u user] [-p password] [-h hostname] [-P port] [<command file> | <command>]\n\n"); printf("The MaxScale administrative and monitor client.\n\n");
printf(" -u user The user name to use for the connection, default\n"); printf("Usage: %s [-u user] [-p password] [-h hostname] [-P port] [<command file> | <command>]\n\n", progname);
printf(" -u|--user=... The user name to use for the connection, default\n");
printf(" is admin.\n"); printf(" is admin.\n");
printf(" -p password The user password, if not given the password will\n"); printf(" -p|--password=... The user password, if not given the password will\n");
printf(" be prompted for interactively\n"); printf(" be prompted for interactively\n");
printf(" -h hostname The maxscale host to connecto to. The default is\n"); printf(" -h|--hostname=... The maxscale host to connecto to. The default is\n");
printf(" localhost\n"); printf(" localhost\n");
printf(" -P port The port to use for the connection, the default\n"); printf(" -P|--port=... The port to use for the connection, the default\n");
printf(" port is 6603.\n"); printf(" port is 6603.\n");
printf(" --help Print this help text.\n"); printf(" -v|--version print version information and exit\n");
printf(" -?|--help Print this help text.\n");
printf("Any remaining arguments are treated as MaxScale commands or a file\n"); printf("Any remaining arguments are treated as MaxScale commands or a file\n");
printf("containing commands to execute.\n"); printf("containing commands to execute.\n");
} }

View File

@ -44,6 +44,7 @@
#include <string.h> #include <string.h>
#include <gw.h> #include <gw.h>
#include <unistd.h> #include <unistd.h>
#include <getopt.h>
#include <service.h> #include <service.h>
#include <server.h> #include <server.h>
#include <dcb.h> #include <dcb.h>
@ -128,6 +129,16 @@ static bool libmysqld_started = FALSE;
*/ */
static bool daemon_mode = true; static bool daemon_mode = true;
const char *progname = NULL;
static struct option long_options[] = {
{"homedir", required_argument, 0, 'c'},
{"config", required_argument, 0, 'f'},
{"nodeamon", required_argument, 0, 'd'},
{"version", no_argument, 0, 'v'},
{"help", no_argument, 0, '?'},
{0, 0, 0, 0}
};
static void log_flush_shutdown(void); static void log_flush_shutdown(void);
static void log_flush_cb(void* arg); static void log_flush_cb(void* arg);
static int write_pid_file(char *); /* write MaxScale pidfile */ static int write_pid_file(char *); /* write MaxScale pidfile */
@ -828,15 +839,17 @@ return_cnf_file_buf:
return cnf_file_buf; return cnf_file_buf;
} }
static void usage(void) static void usage(void)
{ {
fprintf(stderr, fprintf(stderr,
"*\n* Usage : maxscale [-h] | [-d] [-c <home " "\nUsage : %s [-h] | [-d] [-c <home directory>] [-f <config file name>]\n\n"
"directory>] [-f <config file name>]\n* where:\n* " " -d|--nodaemon enable running in terminal process (default:disabled)\n"
"-h help\n* -d enable running in terminal process (default:disabled)\n* " " -c|--homedir=... relative|absolute MaxScale home directory\n"
"-c relative|absolute MaxScale home directory\n* " " -f|--config=... relative|absolute pathname of MaxScale configuration file\n"
"-f relative|absolute pathname of MaxScale configuration file (default:MAXSCALE_HOME/etc/MaxScale.cnf)\n*\n"); " (default: $MAXSCALE_HOME/etc/MaxScale.cnf)\n"
" -v|--version print version info and exit\n"
" -?|--help show this help\n"
, progname);
} }
/** /**
@ -893,6 +906,7 @@ int main(int argc, char **argv)
char* cnf_file_path = NULL; /*< conf file, to be freed */ char* cnf_file_path = NULL; /*< conf file, to be freed */
char* cnf_file_arg = NULL; /*< conf filename from cmd-line arg */ char* cnf_file_arg = NULL; /*< conf filename from cmd-line arg */
void* log_flush_thr = NULL; void* log_flush_thr = NULL;
int option_index;
ssize_t log_flush_timeout_ms = 0; ssize_t log_flush_timeout_ms = 0;
sigset_t sigset; sigset_t sigset;
sigset_t sigpipe_mask; sigset_t sigpipe_mask;
@ -904,6 +918,8 @@ int main(int argc, char **argv)
sigemptyset(&sigpipe_mask); sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE); sigaddset(&sigpipe_mask, SIGPIPE);
progname = *argv;
#if defined(SS_DEBUG) #if defined(SS_DEBUG)
memset(conn_open, 0, sizeof(bool)*10240); memset(conn_open, 0, sizeof(bool)*10240);
memset(dcb_fake_write_errno, 0, sizeof(unsigned char)*10240); memset(dcb_fake_write_errno, 0, sizeof(unsigned char)*10240);
@ -930,7 +946,8 @@ int main(int argc, char **argv)
goto return_main; goto return_main;
} }
} }
while ((opt = getopt(argc, argv, "dc:f:h")) != -1) while ((opt = getopt_long(argc, argv, "dc:f:v?",
long_options, &option_index)) != -1)
{ {
bool succp = true; bool succp = true;
@ -1012,8 +1029,17 @@ int main(int argc, char **argv)
} }
break; break;
case 'v':
rc = EXIT_SUCCESS;
goto return_main;
case '?':
usage();
rc = EXIT_SUCCESS;
goto return_main;
default: default:
usage(); usage();
succp = false; succp = false;
break; break;
} }