[PATCH] Enable bundling for dbclient.
Matt Johnston
matt at ucc.asn.au
Mon Nov 23 23:04:19 AWST 2015
Hi,
Thanks for the patch, I've applied it slight changes. I had
to re-add the undocumented support for extra arguments after
the hostname - that's in the manpage now.
Cheers,
Matt
On Wed, Nov 11, 2015 at 07:02:36PM +0100, Guilhem Moulin wrote:
> ---
> cli-runopts.c | 202 ++++++++++++++++++++++++++--------------------------------
> 1 file changed, 92 insertions(+), 110 deletions(-)
>
> diff --git a/cli-runopts.c b/cli-runopts.c
> index 2b0cb7d..59ebb5a 100644
> --- a/cli-runopts.c
> +++ b/cli-runopts.c
> @@ -105,25 +105,30 @@ static void printhelp() {
> void cli_getopts(int argc, char ** argv) {
> unsigned int i, j;
> char ** next = 0;
> - unsigned int cmdlen;
> + enum {
> #ifdef ENABLE_CLI_PUBKEY_AUTH
> - int nextiskey = 0; /* A flag if the next argument is a keyfile */
> + OPT_AUTHKEY,
> #endif
> #ifdef ENABLE_CLI_LOCALTCPFWD
> - int nextislocal = 0;
> + OPT_LOCALTCPFWD,
> #endif
> #ifdef ENABLE_CLI_REMOTETCPFWD
> - int nextisremote = 0;
> + OPT_REMOTETCPFWD,
> #endif
> #ifdef ENABLE_CLI_NETCAT
> - int nextisnetcat = 0;
> + OPT_NETCAT,
> #endif
> + /* a flag (no arg) if 'next' is NULL, a string-valued option otherwise */
> + OPT_OTHER
> + } opt;
> + unsigned int cmdlen;
> char* dummy = NULL; /* Not used for anything real */
>
> char* recv_window_arg = NULL;
> char* keepalive_arg = NULL;
> char* idle_timeout_arg = NULL;
> char *host_arg = NULL;
> + char c;
>
> /* see printhelp() for options */
> cli_opts.progname = argv[0];
> @@ -172,58 +177,8 @@ void cli_getopts(int argc, char ** argv) {
>
> fill_own_user();
>
> - /* Iterate all the arguments */
> - for (i = 1; i < (unsigned int)argc; i++) {
> -#ifdef ENABLE_CLI_PUBKEY_AUTH
> - if (nextiskey) {
> - /* Load a hostkey since the previous argument was "-i" */
> - loadidentityfile(argv[i], 1);
> - nextiskey = 0;
> - continue;
> - }
> -#endif
> -#ifdef ENABLE_CLI_REMOTETCPFWD
> - if (nextisremote) {
> - TRACE(("nextisremote true"))
> - addforward(argv[i], cli_opts.remotefwds);
> - nextisremote = 0;
> - continue;
> - }
> -#endif
> -#ifdef ENABLE_CLI_LOCALTCPFWD
> - if (nextislocal) {
> - TRACE(("nextislocal true"))
> - addforward(argv[i], cli_opts.localfwds);
> - nextislocal = 0;
> - continue;
> - }
> -#endif
> -#ifdef ENABLE_CLI_NETCAT
> - if (nextisnetcat) {
> - TRACE(("nextisnetcat true"))
> - add_netcat(argv[i]);
> - nextisnetcat = 0;
> - continue;
> - }
> -#endif
> - if (next) {
> - /* The previous flag set a value to assign */
> - *next = argv[i];
> - if (*next == NULL) {
> - dropbear_exit("Invalid null argument");
> - }
> - next = NULL;
> - continue;
> - }
> -
> - if (argv[i][0] == '-') {
> - /* A flag *waves* */
> - char c = argv[i][1];
> - if (strlen(argv[i]) != 2) {
> - /* We only handle one flag per hyphen */
> - fprintf(stderr, "Warning, trailing '%s' of '%s' is ignored.\n",
> - &argv[i][2], argv[i]);
> - }
> + for (i = 1; i < (unsigned int)argc && argv[i][0] == '-'; i++) {
> + for (j = 1; (c = argv[i][j]) != '\0' && !next && opt == OPT_OTHER; j++) {
> switch (c) {
> case 'y': /* always accept the remote hostkey */
> if (cli_opts.always_accept_key) {
> @@ -237,12 +192,7 @@ void cli_getopts(int argc, char ** argv) {
> break;
> #ifdef ENABLE_CLI_PUBKEY_AUTH
> case 'i': /* an identityfile */
> - /* Keep scp happy when it changes "-i file" to "-ifile" */
> - if (strlen(argv[i]) > 2) {
> - loadidentityfile(&argv[i][2], 1);
> - } else {
> - nextiskey = 1;
> - }
> + opt = OPT_AUTHKEY;
> break;
> #endif
> case 't': /* we want a pty */
> @@ -262,7 +212,7 @@ void cli_getopts(int argc, char ** argv) {
> break;
> #ifdef ENABLE_CLI_LOCALTCPFWD
> case 'L':
> - nextislocal = 1;
> + opt = OPT_LOCALTCPFWD;
> break;
> case 'g':
> opts.listen_fwd_all = 1;
> @@ -270,12 +220,12 @@ void cli_getopts(int argc, char ** argv) {
> #endif
> #ifdef ENABLE_CLI_REMOTETCPFWD
> case 'R':
> - nextisremote = 1;
> + opt = OPT_REMOTETCPFWD;
> break;
> #endif
> #ifdef ENABLE_CLI_NETCAT
> case 'B':
> - nextisnetcat = 1;
> + opt = OPT_NETCAT;
> break;
> #endif
> #ifdef ENABLE_CLI_PROXYCMD
> @@ -341,50 +291,87 @@ void cli_getopts(int argc, char ** argv) {
> case 'b':
> next = &dummy;
> default:
> - fprintf(stderr,
> - "WARNING: Ignoring unknown argument '%s'\n", argv[i]);
> + fprintf(stderr,
> + "WARNING: Ignoring unknown option -%c\n", c);
> break;
> } /* Switch */
> -
> - /* Now we handle args where they might be "-luser" (no spaces)*/
> - if (next && strlen(argv[i]) > 2) {
> - *next = &argv[i][2];
> - next = NULL;
> - }
> + }
>
> - continue; /* next argument */
> + if (!next && opt == OPT_OTHER) /* got a flag */
> + continue;
>
> - } else {
> - TRACE(("non-flag arg: '%s'", argv[i]))
> -
> - /* Either the hostname or commands */
> -
> - if (host_arg == NULL) {
> - host_arg = argv[i];
> - } else {
> -
> - /* this is part of the commands to send - after this we
> - * don't parse any more options, and flags are sent as the
> - * command */
> - cmdlen = 0;
> - for (j = i; j < (unsigned int)argc; j++) {
> - cmdlen += strlen(argv[j]) + 1; /* +1 for spaces */
> - }
> - /* Allocate the space */
> - cli_opts.cmd = (char*)m_malloc(cmdlen);
> - cli_opts.cmd[0] = '\0';
> -
> - /* Append all the bits */
> - for (j = i; j < (unsigned int)argc; j++) {
> - strlcat(cli_opts.cmd, argv[j], cmdlen);
> - strlcat(cli_opts.cmd, " ", cmdlen);
> - }
> - /* It'll be null-terminated here */
> -
> - /* We've eaten all the options and flags */
> - break;
> - }
> + if (c == '\0') {
> + i++;
> + j = 0;
> + if (!argv[i])
> + dropbear_exit("Missing argument");
> }
> +
> +#ifdef ENABLE_CLI_PUBKEY_AUTH
> + if (opt == OPT_AUTHKEY) {
> + TRACE(("opt authkey"))
> + loadidentityfile(&argv[i][j], 1);
> + }
> + else
> +#endif
> +#ifdef ENABLE_CLI_REMOTETCPFWD
> + if (opt == OPT_REMOTETCPFWD) {
> + TRACE(("opt remotetcpfwd"))
> + addforward(&argv[i][j], cli_opts.remotefwds);
> + }
> + else
> +#endif
> +#ifdef ENABLE_CLI_LOCALTCPFWD
> + if (opt == OPT_LOCALTCPFWD) {
> + TRACE(("opt localtcpfwd"))
> + addforward(&argv[i][j], cli_opts.localfwds);
> + }
> + else
> +#endif
> +#ifdef ENABLE_CLI_NETCAT
> + if (opt == OPT_NETCAT) {
> + TRACE(("opt netcat"))
> + add_netcat(&argv[i][j]);
> + }
> + else
> +#endif
> + if (next) {
> + /* The previous flag set a value to assign */
> + *next = &argv[i][j];
> + if (*next == NULL)
> + dropbear_exit("Invalid null argument");
> + next = NULL;
> + }
> + opt = OPT_OTHER;
> + }
> +
> + /* Done with options/flags; now handle the hostname (which may not
> + * start with a hyphen) and optional command */
> +
> + if (i >= (unsigned int)argc) { /* missing hostname */
> + printhelp();
> + exit(EXIT_FAILURE);
> + }
> + host_arg = argv[i++];
> + TRACE(("host is: %s", host_arg))
> +
> + if (i < (unsigned int)argc) {
> + /* Build the command to send */
> + cmdlen = 0;
> + for (j = i; j < (unsigned int)argc; j++)
> + cmdlen += strlen(argv[j]) + 1; /* +1 for spaces */
> +
> + /* Allocate the space */
> + cli_opts.cmd = (char*)m_malloc(cmdlen);
> + cli_opts.cmd[0] = '\0';
> +
> + /* Append all the bits */
> + for (j = i; j < (unsigned int)argc; j++) {
> + strlcat(cli_opts.cmd, argv[j], cmdlen);
> + strlcat(cli_opts.cmd, " ", cmdlen);
> + }
> + /* It'll be null-terminated here */
> + TRACE(("cmd is: %s", cli_opts.cmd))
> }
>
> /* And now a few sanity checks and setup */
> @@ -393,11 +380,6 @@ void cli_getopts(int argc, char ** argv) {
> parse_ciphers_macs();
> #endif
>
> - if (host_arg == NULL) {
> - printhelp();
> - exit(EXIT_FAILURE);
> - }
> -
> #ifdef ENABLE_CLI_PROXYCMD
> if (cli_opts.proxycmd) {
> /* To match the common path of m_freeing it */
> --
> 2.6.2
>
More information about the Dropbear
mailing list