Coverity: Don't close fd_cwd if fd_cwd == -1.
[libguestfs.git] / src / inspect.c
index 50c4e72..e7408b6 100644 (file)
@@ -1,5 +1,5 @@
 /* libguestfs
- * Copyright (C) 2010 Red Hat Inc.
+ * Copyright (C) 2010-2011 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
@@ -106,11 +106,11 @@ compile_regexps (void)
 
   COMPILE (re_fedora, "Fedora release (\\d+)", 0);
   COMPILE (re_rhel_old,
-           "(?:Red Hat Enterprise Linux|CentOS|Scientific Linux).*release (\\d+).*Update (\\d+)", 0);
+           "(?:Red Hat|CentOS|Scientific Linux).*release (\\d+).*Update (\\d+)", 0);
   COMPILE (re_rhel,
-           "(?:Red Hat Enterprise Linux|CentOS|Scientific Linux).*release (\\d+)\\.(\\d+)", 0);
+           "(?:Red Hat|CentOS|Scientific Linux).*release (\\d+)\\.(\\d+)", 0);
   COMPILE (re_rhel_no_minor,
-           "(?:Red Hat Enterprise Linux|CentOS|Scientific Linux).*release (\\d+)", 0);
+           "(?:Red Hat|CentOS|Scientific Linux).*release (\\d+)", 0);
   COMPILE (re_major_minor, "(\\d+)\\.(\\d+)", 0);
   COMPILE (re_aug_seq, "/\\d+$", 0);
   COMPILE (re_xdev, "^/dev/(?:h|s|v|xv)d([a-z]\\d*)$", 0);
@@ -228,7 +228,9 @@ static int check_windows_root (guestfs_h *g, struct inspect_fs *fs);
 static int check_windows_arch (guestfs_h *g, struct inspect_fs *fs);
 static int check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs);
 static int check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs);
-static char *resolve_windows_path_silently (guestfs_h *g, const char *);
+static char *case_sensitive_path_silently (guestfs_h *g, const char *);
+static int is_file_nocase (guestfs_h *g, const char *);
+static int is_dir_nocase (guestfs_h *g, const char *);
 static int extend_fses (guestfs_h *g);
 static int parse_unsigned_int (guestfs_h *g, const char *str);
 static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
@@ -351,23 +353,30 @@ check_filesystem (guestfs_h *g, const char *device)
            guestfs_is_dir (g, "/run") > 0 &&
            guestfs_is_dir (g, "/spool") > 0)
     fs->content = FS_CONTENT_LINUX_VAR;
-  /* Windows root? */
-  else if (guestfs_is_file (g, "/AUTOEXEC.BAT") > 0 ||
-           guestfs_is_file (g, "/autoexec.bat") > 0 ||
-           guestfs_is_dir (g, "/Program Files") > 0 ||
-           guestfs_is_dir (g, "/WINDOWS") > 0 ||
-           guestfs_is_dir (g, "/Windows") > 0 ||
-           guestfs_is_dir (g, "/windows") > 0 ||
-           guestfs_is_dir (g, "/WIN32") > 0 ||
-           guestfs_is_dir (g, "/Win32") > 0 ||
-           guestfs_is_dir (g, "/WINNT") > 0 ||
-           guestfs_is_file (g, "/boot.ini") > 0 ||
-           guestfs_is_file (g, "/ntldr") > 0) {
+  /* Windows root?
+   * Note that if a Windows guest has multiple disks and applications
+   * are installed on those other disks, then those other disks will
+   * contain "/Program Files" and "/System Volume Information".  Those
+   * would *not* be Windows root disks.  (RHBZ#674130)
+   */
+  else if (is_file_nocase (g, "/AUTOEXEC.BAT") > 0 ||
+           is_dir_nocase (g, "/WINDOWS/SYSTEM32") > 0 ||
+           is_dir_nocase (g, "/WIN32/SYSTEM32") > 0 ||
+           is_dir_nocase (g, "/WINNT/SYSTEM32") > 0 ||
+           is_file_nocase (g, "/boot.ini") > 0 ||
+           is_file_nocase (g, "/ntldr") > 0) {
     fs->is_root = 1;
     fs->content = FS_CONTENT_WINDOWS_ROOT;
     if (check_windows_root (g, fs) == -1)
       return -1;
   }
+  /* Windows volume with installed applications (but not root)? */
+  else if (is_dir_nocase (g, "/System Volume Information") > 0 &&
+           is_dir_nocase (g, "/Program Files") > 0)
+    fs->content = FS_CONTENT_WINDOWS_VOLUME_WITH_APPS;
+  /* Windows volume (but not root)? */
+  else if (is_dir_nocase (g, "/System Volume Information") > 0)
+    fs->content = FS_CONTENT_WINDOWS_VOLUME;
 
   return 0;
 }
@@ -1025,7 +1034,7 @@ check_windows_root (guestfs_h *g, struct inspect_fs *fs)
   for (i = 0;
        systemroot == NULL && i < sizeof systemroots / sizeof systemroots[0];
        ++i) {
-    systemroot = resolve_windows_path_silently (g, systemroots[i]);
+    systemroot = case_sensitive_path_silently (g, systemroots[i]);
   }
 
   if (!systemroot) {
@@ -1063,7 +1072,7 @@ check_windows_arch (guestfs_h *g, struct inspect_fs *fs)
   char cmd_exe[len];
   snprintf (cmd_exe, len, "%s/system32/cmd.exe", fs->windows_systemroot);
 
-  char *cmd_exe_path = resolve_windows_path_silently (g, cmd_exe);
+  char *cmd_exe_path = case_sensitive_path_silently (g, cmd_exe);
   if (!cmd_exe_path)
     return 0;
 
@@ -1090,7 +1099,7 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs)
   snprintf (software, len, "%s/system32/config/software",
             fs->windows_systemroot);
 
-  char *software_path = resolve_windows_path_silently (g, software);
+  char *software_path = case_sensitive_path_silently (g, software);
   if (!software_path)
     /* If the software hive doesn't exist, just accept that we cannot
      * find product_name etc.
@@ -1199,7 +1208,7 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs)
   snprintf (system, len, "%s/system32/config/system",
             fs->windows_systemroot);
 
-  char *system_path = resolve_windows_path_silently (g, system);
+  char *system_path = case_sensitive_path_silently (g, system);
   if (!system_path)
     /* If the system hive doesn't exist, just accept that we cannot
      * find hostname etc.
@@ -1274,7 +1283,7 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs)
 }
 
 static char *
-resolve_windows_path_silently (guestfs_h *g, const char *path)
+case_sensitive_path_silently (guestfs_h *g, const char *path)
 {
   guestfs_error_handler_cb old_error_cb = g->error_cb;
   g->error_cb = NULL;
@@ -1284,6 +1293,34 @@ resolve_windows_path_silently (guestfs_h *g, const char *path)
 }
 
 static int
+is_file_nocase (guestfs_h *g, const char *path)
+{
+  char *p;
+  int r;
+
+  p = case_sensitive_path_silently (g, path);
+  if (!p)
+    return 0;
+  r = guestfs_is_file (g, p);
+  free (p);
+  return r > 0;
+}
+
+static int
+is_dir_nocase (guestfs_h *g, const char *path)
+{
+  char *p;
+  int r;
+
+  p = case_sensitive_path_silently (g, path);
+  if (!p)
+    return 0;
+  r = guestfs_is_dir (g, p);
+  free (p);
+  return r > 0;
+}
+
+static int
 extend_fses (guestfs_h *g)
 {
   size_t n = g->nr_fses + 1;
@@ -1965,12 +2002,12 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs)
   snprintf (software, len, "%s/system32/config/software",
             fs->windows_systemroot);
 
-  char *software_path = resolve_windows_path_silently (g, software);
-  if (!software_path)
-    /* If the software hive doesn't exist, just accept that we cannot
-     * find product_name etc.
-     */
-    return 0;
+  char *software_path = case_sensitive_path_silently (g, software);
+  if (!software_path) {
+    /* Missing software hive is a problem. */
+    error (g, "no HKLM\\SOFTWARE hive found in the guest");
+    return NULL;
+  }
 
   struct guestfs_application_list *apps = NULL, *ret = NULL;
   hive_h *h = NULL;
@@ -2366,6 +2403,30 @@ guestfs__inspect_list_applications (guestfs_h *g, const char *root)
   NOT_IMPL(NULL);
 }
 
+char *
+guestfs__inspect_get_format (guestfs_h *g, const char *root)
+{
+  NOT_IMPL(NULL);
+}
+
+int
+guestfs__inspect_is_live (guestfs_h *g, const char *root)
+{
+  NOT_IMPL(-1);
+}
+
+int
+guestfs__inspect_is_netinst (guestfs_h *g, const char *root)
+{
+  NOT_IMPL(-1);
+}
+
+int
+guestfs__inspect_is_multipart (guestfs_h *g, const char *root)
+{
+  NOT_IMPL(-1);
+}
+
 #endif /* no PCRE or hivex at compile time */
 
 void