[Libguestfs] [PATCH 2/4] p2v: Use the ADD_ARG macro to simplify ssh/scp parameters.

Richard W.M. Jones rjones at redhat.com
Sat Feb 4 14:59:07 UTC 2017


No functional change.
---
 p2v/ssh.c | 134 +++++++++++++++++++++++++++++---------------------------------
 1 file changed, 62 insertions(+), 72 deletions(-)

diff --git a/p2v/ssh.c b/p2v/ssh.c
index 4c1d64c..817048c 100644
--- a/p2v/ssh.c
+++ b/p2v/ssh.c
@@ -306,6 +306,15 @@ cache_ssh_identity (struct config *config)
   return 0;
 }
 
+/* GCC complains about the argv array in the next function which it
+ * thinks might grow to an unbounded size.  Since we control
+ * extra_args, this is not in fact a problem.
+ */
+#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstack-usage="
+#endif
+
 /**
  * Start ssh subprocess with the standard arguments and possibly some
  * optional arguments.  Also handles authentication.
@@ -314,15 +323,18 @@ static mexp_h *
 start_ssh (unsigned spawn_flags, struct config *config,
            char **extra_args, int wait_prompt)
 {
-  size_t i, j, nr_args, count;
+  size_t i = 0;
+  const size_t MAX_ARGS =
+    64 + (extra_args != NULL ? guestfs_int_count_strings (extra_args) : 0);
+  const char *argv[MAX_ARGS];
   char port_str[64];
   char connect_timeout_str[128];
-  CLEANUP_FREE /* [sic] */ const char **args = NULL;
   mexp_h *h;
   const int ovecsize = 12;
   int ovector[ovecsize];
   int saved_timeout;
   int using_password_auth;
+  size_t count;
 
   if (cache_ssh_identity (config) == -1)
     return NULL;
@@ -330,63 +342,48 @@ start_ssh (unsigned spawn_flags, struct config *config,
   /* Are we using password or identity authentication? */
   using_password_auth = config->identity_file == NULL;
 
-  /* Create the ssh argument array. */
-  nr_args = 0;
-  if (extra_args != NULL)
-    nr_args = guestfs_int_count_strings (extra_args);
-
-  if (using_password_auth)
-    nr_args += 13;
-  else
-    nr_args += 15;
-  args = malloc (sizeof (char *) * nr_args);
-  if (args == NULL)
-    error (EXIT_FAILURE, errno, "malloc");
-
-  j = 0;
-  args[j++] = "ssh";
-  args[j++] = "-p";             /* Port. */
+  ADD_ARG (argv, i, "ssh");
+  ADD_ARG (argv, i, "-p");      /* Port. */
   snprintf (port_str, sizeof port_str, "%d", config->port);
-  args[j++] = port_str;
-  args[j++] = "-l";             /* Username. */
-  args[j++] = config->username ? config->username : "root";
-  args[j++] = "-o";             /* Host key will always be novel. */
-  args[j++] = "StrictHostKeyChecking=no";
-  args[j++] = "-o";             /* ConnectTimeout */
+  ADD_ARG (argv, i, port_str);
+  ADD_ARG (argv, i, "-l");      /* Username. */
+  ADD_ARG (argv, i, config->username ? config->username : "root");
+  ADD_ARG (argv, i, "-o");      /* Host key will always be novel. */
+  ADD_ARG (argv, i, "StrictHostKeyChecking=no");
+  ADD_ARG (argv, i, "-o");      /* ConnectTimeout */
   snprintf (connect_timeout_str, sizeof connect_timeout_str,
             "ConnectTimeout=%d", SSH_TIMEOUT);
-  args[j++] = connect_timeout_str;
+  ADD_ARG (argv, i, connect_timeout_str);
   if (using_password_auth) {
     /* Only use password authentication. */
-    args[j++] = "-o";
-    args[j++] = "PreferredAuthentications=keyboard-interactive,password";
+    ADD_ARG (argv, i, "-o");
+    ADD_ARG (argv, i, "PreferredAuthentications=keyboard-interactive,password");
   }
   else {
     /* Use identity file (private key). */
-    args[j++] = "-o";
-    args[j++] = "PreferredAuthentications=publickey";
-    args[j++] = "-i";
-    args[j++] = config->identity_file;
+    ADD_ARG (argv, i, "-o");
+    ADD_ARG (argv, i, "PreferredAuthentications=publickey");
+    ADD_ARG (argv, i, "-i");
+    ADD_ARG (argv, i, config->identity_file);
   }
   if (extra_args != NULL) {
-    for (i = 0; extra_args[i] != NULL; ++i)
-      args[j++] = extra_args[i];
+    for (size_t j = 0; extra_args[j] != NULL; ++j)
+      ADD_ARG (argv, i, extra_args[j]);
   }
-  args[j++] = config->server;   /* Conversion server. */
-  args[j++] = NULL;
-  assert (j == nr_args);
+  ADD_ARG (argv, i, config->server); /* Conversion server. */
+  ADD_ARG (argv, i, NULL);
 
 #if DEBUG_STDERR
   fputs ("ssh command: ", stderr);
-  for (i = 0; i < nr_args - 1; ++i) {
+  for (i = 0; argv[i] != NULL; ++i) {
     if (i > 0) fputc (' ', stderr);
-    fputs (args[i], stderr);
+    fputs (argv[i], stderr);
   }
   fputc ('\n', stderr);
 #endif
 
   /* Create the miniexpect handle. */
-  h = mexp_spawnvf (spawn_flags, "ssh", (char **) args);
+  h = mexp_spawnvf (spawn_flags, "ssh", (char **) argv);
   if (h == NULL) {
     set_ssh_internal_error ("ssh: mexp_spawnvf: %m");
     return NULL;
@@ -566,6 +563,10 @@ start_ssh (unsigned spawn_flags, struct config *config,
   return h;
 }
 
+#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */
+#pragma GCC diagnostic pop
+#endif
+
 /**
  * Upload a file to remote using L<scp(1)>.
  *
@@ -574,16 +575,16 @@ start_ssh (unsigned spawn_flags, struct config *config,
 int
 scp_file (struct config *config, const char *localfile, const char *remotefile)
 {
-  size_t j, nr_args;
+  size_t i = 0;
+  const size_t MAX_ARGS = 64;
+  const char *argv[MAX_ARGS];
   char port_str[64];
   char connect_timeout_str[128];
   CLEANUP_FREE char *remote = NULL;
-  CLEANUP_FREE /* [sic] */ const char **args = NULL;
   mexp_h *h;
   const int ovecsize = 12;
   int ovector[ovecsize];
   int using_password_auth;
-  size_t i;
 
   if (cache_ssh_identity (config) == -1)
     return -1;
@@ -591,58 +592,47 @@ scp_file (struct config *config, const char *localfile, const char *remotefile)
   /* Are we using password or identity authentication? */
   using_password_auth = config->identity_file == NULL;
 
-  /* Create the scp argument array. */
-  if (using_password_auth)
-    nr_args = 12;
-  else
-    nr_args = 14;
-  args = malloc (sizeof (char *) * nr_args);
-  if (args == NULL)
-    error (EXIT_FAILURE, errno, "malloc");
-
-  j = 0;
-  args[j++] = "scp";
-  args[j++] = "-P";             /* Port. */
+  ADD_ARG (argv, i, "scp");
+  ADD_ARG (argv, i, "-P");      /* Port. */
   snprintf (port_str, sizeof port_str, "%d", config->port);
-  args[j++] = port_str;
-  args[j++] = "-o";             /* Host key will always be novel. */
-  args[j++] = "StrictHostKeyChecking=no";
-  args[j++] = "-o";             /* ConnectTimeout */
+  ADD_ARG (argv, i, port_str);
+  ADD_ARG (argv, i, "-o");      /* Host key will always be novel. */
+  ADD_ARG (argv, i, "StrictHostKeyChecking=no");
+  ADD_ARG (argv, i, "-o");      /* ConnectTimeout */
   snprintf (connect_timeout_str, sizeof connect_timeout_str,
             "ConnectTimeout=%d", SSH_TIMEOUT);
-  args[j++] = connect_timeout_str;
+  ADD_ARG (argv, i, connect_timeout_str);
   if (using_password_auth) {
     /* Only use password authentication. */
-    args[j++] = "-o";
-    args[j++] = "PreferredAuthentications=keyboard-interactive,password";
+    ADD_ARG (argv, i, "-o");
+    ADD_ARG (argv, i, "PreferredAuthentications=keyboard-interactive,password");
   }
   else {
     /* Use identity file (private key). */
-    args[j++] = "-o";
-    args[j++] = "PreferredAuthentications=publickey";
-    args[j++] = "-i";
-    args[j++] = config->identity_file;
+    ADD_ARG (argv, i, "-o");
+    ADD_ARG (argv, i, "PreferredAuthentications=publickey");
+    ADD_ARG (argv, i, "-i");
+    ADD_ARG (argv, i, config->identity_file);
   }
-  args[j++] = localfile;
+  ADD_ARG (argv, i, localfile);
   if (asprintf (&remote, "%s@%s:%s",
                 config->username ? config->username : "root",
                 config->server, remotefile) == -1)
     error (EXIT_FAILURE, errno, "asprintf");
-  args[j++] = remote;
-  args[j++] = NULL;
-  assert (j == nr_args);
+  ADD_ARG (argv, i, remote);
+  ADD_ARG (argv, i, NULL);
 
 #if DEBUG_STDERR
   fputs ("scp command: ", stderr);
-  for (i = 0; i < nr_args - 1; ++i) {
+  for (i = 0; argv[i] != NULL; ++i) {
     if (i > 0) fputc (' ', stderr);
-    fputs (args[i], stderr);
+    fputs (argv[i], stderr);
   }
   fputc ('\n', stderr);
 #endif
 
   /* Create the miniexpect handle. */
-  h = mexp_spawnv ("scp", (char **) args);
+  h = mexp_spawnv ("scp", (char **) argv);
   if (h == NULL) {
     set_ssh_internal_error ("scp: mexp_spawnv: %m");
     return -1;
-- 
2.10.2




More information about the Libguestfs mailing list