daemon: debug segv correct use of dereferencing NULL.
[libguestfs.git] / fish / inspect.c
index cc3916b..f93367b 100644 (file)
@@ -13,7 +13,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #include <config.h>
@@ -28,8 +28,6 @@
 
 #include "options.h"
 
-static void do_decrypt (void);
-
 /* Global that saves the root device between inspect_mount and
  * print_inspect_prompt.
  */
@@ -45,14 +43,14 @@ free_strings (char **argv)
   free (argv);
 }
 
-static int
+static size_t
 count_strings (char *const *argv)
 {
-  int c;
+  size_t i;
 
-  for (c = 0; argv[c]; ++c)
+  for (i = 0; argv[i]; ++i)
     ;
-  return c;
+  return i;
 }
 
 static int
@@ -75,27 +73,69 @@ compare_keys (const void *p1, const void *p2)
 void
 inspect_mount (void)
 {
-  do_decrypt ();
+  if (live) {
+    fprintf (stderr, _("%s: don't use --live and -i options together\n"),
+             program_name);
+    exit (EXIT_FAILURE);
+  }
+
+  inspect_do_decrypt ();
 
   char **roots = guestfs_inspect_os (g);
   if (roots == NULL)
     exit (EXIT_FAILURE);
 
   if (roots[0] == NULL) {
-    fprintf (stderr, _("%s: no operating system was found on this disk\n"),
+    fprintf (stderr,
+      _("%s: no operating system was found on this disk\n"
+        "\n"
+        "If using guestfish '-i' option, remove this option and instead\n"
+        "use the commands 'run' followed by 'list-filesystems'.\n"
+        "You can then mount filesystems you want by hand using the\n"
+        "'mount' or 'mount-ro' command.\n"
+        "\n"
+        "If using guestmount '-i', remove this option and choose the\n"
+        "filesystem(s) you want to see by manually adding '-m' option(s).\n"
+        "Use 'virt-filesystems' to see what filesystems are available.\n"
+        "\n"
+        "If using other virt tools, this disk image won't work\n"
+        "with these tools.  Use the guestfish equivalent commands\n"
+        "(see the virt tool manual page).\n"),
              program_name);
+    free_strings (roots);
     exit (EXIT_FAILURE);
   }
 
   if (roots[1] != NULL) {
-    fprintf (stderr, _("%s: multi-boot operating systems are not supported by the -i option\n"),
+    fprintf (stderr,
+      _("%s: multi-boot operating systems are not supported\n"
+        "\n"
+        "If using guestfish '-i' option, remove this option and instead\n"
+        "use the commands 'run' followed by 'list-filesystems'.\n"
+        "You can then mount filesystems you want by hand using the\n"
+        "'mount' or 'mount-ro' command.\n"
+        "\n"
+        "If using guestmount '-i', remove this option and choose the\n"
+        "filesystem(s) you want to see by manually adding '-m' option(s).\n"
+        "Use 'virt-filesystems' to see what filesystems are available.\n"
+        "\n"
+        "If using other virt tools, multi-boot operating systems won't work\n"
+        "with these tools.  Use the guestfish equivalent commands\n"
+        "(see the virt tool manual page).\n"),
              program_name);
+    free_strings (roots);
     exit (EXIT_FAILURE);
   }
 
   root = roots[0];
   free (roots);
 
+  inspect_mount_root (root);
+}
+
+void
+inspect_mount_root (const char *root)
+{
   char **mountpoints = guestfs_inspect_get_mountpoints (g, root);
   if (mountpoints == NULL)
     exit (EXIT_FAILURE);
@@ -107,17 +147,28 @@ inspect_mount (void)
          compare_keys_len);
 
   size_t i;
+  size_t mount_errors = 0;
   for (i = 0; mountpoints[i] != NULL; i += 2) {
     int r;
     if (!read_only)
       r = guestfs_mount_options (g, "", mountpoints[i+1], mountpoints[i]);
     else
       r = guestfs_mount_ro (g, mountpoints[i+1], mountpoints[i]);
-    if (r == -1)
-      exit (EXIT_FAILURE);
+    if (r == -1) {
+      /* If the "/" filesystem could not be mounted, give up, else
+       * just count the errors and print a warning.
+       */
+      if (STREQ (mountpoints[i], "/"))
+        exit (EXIT_FAILURE);
+      mount_errors++;
+    }
   }
 
   free_strings (mountpoints);
+
+  if (mount_errors)
+    fprintf (stderr, _("%s: some filesystems could not be mounted (ignored)\n"),
+             program_name);
 }
 
 /* This function is called only if the above function was called,
@@ -127,7 +178,7 @@ void
 print_inspect_prompt (void)
 {
   char *name = guestfs_inspect_get_product_name (g, root);
-  if (STRNEQ (name, "unknown"))
+  if (name && STRNEQ (name, "unknown"))
     printf (_("Operating system: %s\n"), name);
   free (name);
 
@@ -178,8 +229,8 @@ make_mapname (const char *device, char *mapname, size_t len)
  * for Fedora whole-disk encryption.  WIP to make this work for other
  * encryption schemes.
  */
-static void
-do_decrypt (void)
+void
+inspect_do_decrypt (void)
 {
   char **partitions = guestfs_list_partitions (g);
   if (partitions == NULL)
@@ -204,6 +255,7 @@ do_decrypt (void)
 
       need_rescan = 1;
     }
+    free (type);
   }
 
   free_strings (partitions);