tests: valgrind: Rebuild tests before running them
[miniexpect.git] / example-sshpass.c
index 3449a20..7130ac8 100644 (file)
@@ -1,5 +1,5 @@
 /* miniexpect example.
- * Copyright (C) 2014 Red Hat Inc.
+ * Copyright (C) 2014-2022 Red Hat Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * The remaining arguments are passed to the ssh subprocess.
  *
  * For example:
- *   sshpass 123456 ssh remote.example.com
- *   sshpass 123456 ssh -l root remote.example.com
+ *   sshpass [-d] 123456 ssh remote.example.com
+ *   sshpass [-d] 123456 ssh -l root remote.example.com
+ *
+ * Use the -d flag to enable debugging to stderr.
  */
 
 #include <config.h>
 #include <unistd.h>
 #include <assert.h>
 
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 
 #include "miniexpect.h"
 
-static pcre *compile_re (const char *rex);
+static pcre2_code *compile_re (const char *rex);
+
+static void
+usage (void)
+{
+  fprintf (stderr, "usage: sshpass [-d] PASSWORD ssh [SSH-ARGS...] HOST\n");
+  exit (EXIT_FAILURE);
+}
 
 int
 main (int argc, char *argv[])
 {
+  int opt;
+  int debug = 0;
   mexp_h *h;
   const char *password;
   int status;
-  pcre *password_re, *prompt_re, *hello_re;
-  const int ovecsize = 12;
-  int ovector[ovecsize];
+  pcre2_code *password_re, *prompt_re, *hello_re;
+  pcre2_match_data *match_data;
 
-  if (argc <= 3) {
-    fprintf (stderr, "usage: sshpass PASSWORD ssh [SSH-ARGS...] HOST\n");
-    exit (EXIT_FAILURE);
+  match_data = pcre2_match_data_create (4, NULL);
+
+  while ((opt = getopt (argc, argv, "d")) != -1) {
+    switch (opt) {
+    case 'd':
+      debug = 1;
+      break;
+    default:
+      usage ();
+    }
   }
 
-  password = argv[1];
+  if (argc-optind <= 2)
+    usage ();
+
+  password = argv[optind];
+  optind++;
 
   printf ("starting ssh command ...\n");
 
-  h = mexp_spawnv (argv[2], &argv[2]);
+  h = mexp_spawnv (argv[optind], &argv[optind]);
   if (h == NULL) {
     perror ("mexp_spawnv: ssh");
     exit (EXIT_FAILURE);
   }
+  if (debug)
+    mexp_set_debug_file (h, stderr);
 
   /* Wait for the password prompt. */
   password_re = compile_re ("assword");
@@ -74,7 +98,7 @@ main (int argc, char *argv[])
                          { 100, .re = password_re },
                          { 0 }
                        },
-                       ovector, ovecsize)) {
+                       match_data)) {
   case 100:
     break;
   case MEXP_EOF:
@@ -91,10 +115,16 @@ main (int argc, char *argv[])
     goto error;
   }
 
-  /* Got the password prompt, so send a password. */
+  /* Got the password prompt, so send a password.
+   *
+   * Note use of mexp_printf_password here which is identical to
+   * mexp_printf except that it hides the password in debugging
+   * output.
+   */
   printf ("sending the password ...\n");
 
-  if (mexp_printf (h, "%s\n", password) == -1) {
+  if (mexp_printf_password (h, "%s", password) == -1 ||
+      mexp_printf (h, "\n") == -1) {
     perror ("mexp_printf");
     goto error;
   }
@@ -112,7 +142,7 @@ main (int argc, char *argv[])
                          { 101, .re = prompt_re },
                          { 0 },
                        },
-                       ovector, ovecsize)) {
+                       match_data)) {
   case 100:                     /* Password. */
     fprintf (stderr, "error: ssh asked for password again, probably the password supplied is wrong\n");
     goto error;
@@ -147,7 +177,7 @@ main (int argc, char *argv[])
                          { 100, .re = hello_re },
                          { 0 },
                        },
-                       ovector, ovecsize)) {
+                       match_data)) {
   case 100:
     break;
   case MEXP_EOF:
@@ -172,7 +202,7 @@ main (int argc, char *argv[])
     goto error;
   }
 
-  switch (mexp_expect (h, NULL, NULL, 0)) {
+  switch (mexp_expect (h, NULL, NULL)) {
   case MEXP_EOF:
     /* This is what we're expecting: ssh will close the connection. */
     break;
@@ -197,6 +227,7 @@ main (int argc, char *argv[])
 
   printf ("test was successful\n");
 
+  pcre2_match_data_free (match_data);
   exit (EXIT_SUCCESS);
 
  error:
@@ -205,17 +236,23 @@ main (int argc, char *argv[])
 }
 
 /* Helper function to compile a PCRE regexp. */
-static pcre *
+static pcre2_code *
 compile_re (const char *rex)
 {
-  const char *errptr;
-  int erroffset;
-  pcre *ret;
+  int errorcode;
+  PCRE2_SIZE erroroffset;
+  char errormsg[256];
+  pcre2_code *ret;
 
-  ret = pcre_compile (rex, 0, &errptr, &erroffset, NULL);
+  ret = pcre2_compile ((PCRE2_SPTR) rex, PCRE2_ZERO_TERMINATED,
+                       0, &errorcode, &erroroffset, NULL);
   if (ret == NULL) {
-    fprintf (stderr, "error: failed to compile regular expression '%s': %s at offset %d\n",
-             rex, errptr, erroffset);
+    pcre2_get_error_message (errorcode,
+                             (PCRE2_UCHAR *) errormsg, sizeof errormsg);
+    fprintf (stderr, "error: "
+             "failed to compile regular expression '%s': "
+             "%s at offset %zu\n",
+             rex, errormsg, erroroffset);
     exit (EXIT_FAILURE);
   }
   return ret;