leak: Free list of drives and mountpoints in guestfish.
[libguestfs.git] / fish / fish.c
index 8851831..de11b2f 100644 (file)
@@ -73,6 +73,8 @@ static void set_up_terminal (void);
 static char add_drives (struct drv *drv, char next_drive);
 static void prepare_drives (struct drv *drv);
 static void mount_mps (struct mp *mp);
 static char add_drives (struct drv *drv, char next_drive);
 static void prepare_drives (struct drv *drv);
 static void mount_mps (struct mp *mp);
+static void free_drives (struct drv *drv);
+static void free_mps (struct mp *mp);
 static int launch (void);
 static void interactive (void);
 static void shell_script (void);
 static int launch (void);
 static void interactive (void);
 static void shell_script (void);
@@ -97,6 +99,7 @@ int remote_control = 0;
 int exit_on_error = 1;
 int command_num = 0;
 int keys_from_stdin = 0;
 int exit_on_error = 1;
 int command_num = 0;
 int keys_from_stdin = 0;
+int echo_keys = 0;
 const char *libvirt_uri = NULL;
 int inspector = 0;
 int utf8_mode = 0;
 const char *libvirt_uri = NULL;
 int inspector = 0;
 int utf8_mode = 0;
@@ -132,6 +135,7 @@ usage (int status)
              "  -c|--connect uri     Specify libvirt URI for -d option\n"
              "  -d|--domain guest    Add disks from libvirt guest\n"
              "  -D|--no-dest-paths   Don't tab-complete paths from guest fs\n"
              "  -c|--connect uri     Specify libvirt URI for -d option\n"
              "  -d|--domain guest    Add disks from libvirt guest\n"
              "  -D|--no-dest-paths   Don't tab-complete paths from guest fs\n"
+             "  --echo-keys          Don't turn off echo for passphrases\n"
              "  -f|--file file       Read commands from file\n"
              "  -i|--inspector       Automatically mount filesystems\n"
              "  --keys-from-stdin    Read passphrases from stdin\n"
              "  -f|--file file       Read commands from file\n"
              "  -i|--inspector       Automatically mount filesystems\n"
              "  --keys-from-stdin    Read passphrases from stdin\n"
@@ -177,6 +181,7 @@ main (int argc, char *argv[])
     { "cmd-help", 2, 0, 'h' },
     { "connect", 1, 0, 'c' },
     { "domain", 1, 0, 'd' },
     { "cmd-help", 2, 0, 'h' },
     { "connect", 1, 0, 'c' },
     { "domain", 1, 0, 'd' },
+    { "echo-keys", 0, 0, 0 },
     { "file", 1, 0, 'f' },
     { "help", 0, 0, HELP_OPTION },
     { "inspector", 0, 0, 'i' },
     { "file", 1, 0, 'f' },
     { "help", 0, 0, HELP_OPTION },
     { "inspector", 0, 0, 'i' },
@@ -277,6 +282,8 @@ main (int argc, char *argv[])
         override_progress_bars = 1;
       } else if (STREQ (long_options[option_index].name, "no-progress-bars")) {
         override_progress_bars = 0;
         override_progress_bars = 1;
       } else if (STREQ (long_options[option_index].name, "no-progress-bars")) {
         override_progress_bars = 0;
+      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
+        echo_keys = 1;
       } else {
         fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                  program_name, long_options[option_index].name, option_index);
       } else {
         fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                  program_name, long_options[option_index].name, option_index);
@@ -480,6 +487,10 @@ main (int argc, char *argv[])
     mount_mps (mps);
   }
 
     mount_mps (mps);
   }
 
+  /* Free up data structures, no longer needed after this point. */
+  free_drives (drvs);
+  free_mps (mps);
+
   /* Remote control? */
   if (remote_control_listen && remote_control) {
     fprintf (stderr,
   /* Remote control? */
   if (remote_control_listen && remote_control) {
     fprintf (stderr,
@@ -683,6 +694,38 @@ prepare_drives (struct drv *drv)
   }
 }
 
   }
 }
 
+static void
+free_drives (struct drv *drv)
+{
+  if (!drv) return;
+  free_drives (drv->next);
+
+  switch (drv->type) {
+  case drv_a: free (drv->a.filename); break;
+  case drv_d: free (drv->d.guest); break;
+  case drv_N:
+    free (drv->N.filename);
+    free (drv->N.device);
+    free_prep_data (drv->N.data);
+    break;
+  default: ;                    /* keep GCC happy */
+  }
+  free (drv);
+}
+
+static void
+free_mps (struct mp *mp)
+{
+  if (!mp) return;
+  free_mps (mp->next);
+
+  /* The drive and mountpoint fields are not allocated
+   * from the heap, so we should not free them here.
+   */
+
+  free (mp);
+}
+
 static int
 launch (void)
 {
 static int
 launch (void)
 {
@@ -1638,15 +1681,17 @@ read_key (const char *param)
   if (tty) {
     fprintf (outfp, _("Enter key or passphrase (\"%s\"): "), param);
 
   if (tty) {
     fprintf (outfp, _("Enter key or passphrase (\"%s\"): "), param);
 
-    if (tcgetattr (fileno (infp), &orig) == -1) {
-      perror ("tcgetattr");
-      goto error;
-    }
-    memcpy (&temp, &orig, sizeof temp);
-    temp.c_lflag &= ~ECHO;
+    if (!echo_keys) {
+      if (tcgetattr (fileno (infp), &orig) == -1) {
+        perror ("tcgetattr");
+        goto error;
+      }
+      memcpy (&temp, &orig, sizeof temp);
+      temp.c_lflag &= ~ECHO;
 
 
-    tcsetattr (fileno (infp), TCSAFLUSH, &temp);
-    tcset = 1;
+      tcsetattr (fileno (infp), TCSAFLUSH, &temp);
+      tcset = 1;
+    }
   }
 
   size_t n = 0;
   }
 
   size_t n = 0;