-/* Convert output from 'file' command on ELF files to the canonical
- * architecture string. Caller must free the result.
- */
-static char *
-canonical_elf_arch (guestfs_h *g, const char *elf_arch)
-{
- const char *r;
-
- if (strstr (elf_arch, "Intel 80386"))
- r = "i386";
- else if (strstr (elf_arch, "Intel 80486"))
- r = "i486";
- else if (strstr (elf_arch, "x86-64"))
- r = "x86_64";
- else if (strstr (elf_arch, "AMD x86-64"))
- r = "x86_64";
- else if (strstr (elf_arch, "SPARC32"))
- r = "sparc";
- else if (strstr (elf_arch, "SPARC V9"))
- r = "sparc64";
- else if (strstr (elf_arch, "IA-64"))
- r = "ia64";
- else if (match (g, elf_arch, re_elf_ppc64))
- r = "ppc64";
- else if (strstr (elf_arch, "PowerPC"))
- r = "ppc";
- else
- r = elf_arch;
-
- char *ret = safe_strdup (g, r);
+int
+guestfs__inspect_get_major_version (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return -1;
+
+ return fs->major_version;
+}
+
+int
+guestfs__inspect_get_minor_version (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return -1;
+
+ return fs->minor_version;
+}
+
+char *
+guestfs__inspect_get_product_name (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return NULL;
+
+ return safe_strdup (g, fs->product_name ? : "unknown");
+}
+
+char *
+guestfs__inspect_get_product_variant (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return NULL;
+
+ return safe_strdup (g, fs->product_variant ? : "unknown");
+}
+
+char *
+guestfs__inspect_get_windows_systemroot (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return NULL;
+
+ if (!fs->windows_systemroot) {
+ error (g, _("not a Windows guest, or systemroot could not be determined"));
+ return NULL;
+ }
+
+ return safe_strdup (g, fs->windows_systemroot);
+}
+
+char *
+guestfs__inspect_get_windows_current_control_set (guestfs_h *g,
+ const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return NULL;
+
+ if (!fs->windows_current_control_set) {
+ error (g, _("not a Windows guest, or CurrentControlSet could not be determined"));
+ return NULL;
+ }
+
+ return safe_strdup (g, fs->windows_current_control_set);
+}
+
+char *
+guestfs__inspect_get_format (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return NULL;
+
+ char *ret;
+ switch (fs->format) {
+ case OS_FORMAT_INSTALLED: ret = safe_strdup (g, "installed"); break;
+ case OS_FORMAT_INSTALLER: ret = safe_strdup (g, "installer"); break;
+ case OS_FORMAT_UNKNOWN: default: ret = safe_strdup (g, "unknown"); break;
+ }
+
+ return ret;
+}
+
+int
+guestfs__inspect_is_live (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return -1;
+
+ return fs->is_live_disk;
+}
+
+int
+guestfs__inspect_is_netinst (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return -1;
+
+ return fs->is_netinst_disk;
+}
+
+int
+guestfs__inspect_is_multipart (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return -1;
+
+ return fs->is_multipart_disk;
+}
+
+char **
+guestfs__inspect_get_mountpoints (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return NULL;
+
+ char **ret;
+
+ /* If no fstab information (Windows) return just the root. */
+ if (fs->nr_fstab == 0) {
+ ret = calloc (3, sizeof (char *));
+ ret[0] = safe_strdup (g, "/");
+ ret[1] = safe_strdup (g, root);
+ ret[2] = NULL;
+ return ret;
+ }
+
+#define CRITERION fs->fstab[i].mountpoint[0] == '/'
+ size_t i, count = 0;
+ for (i = 0; i < fs->nr_fstab; ++i)
+ if (CRITERION)
+ count++;
+
+ /* Hashtables have 2N+1 entries. */
+ ret = calloc (2*count+1, sizeof (char *));
+ if (ret == NULL) {
+ perrorf (g, "calloc");
+ return NULL;
+ }
+
+ count = 0;
+ for (i = 0; i < fs->nr_fstab; ++i)
+ if (CRITERION) {
+ ret[2*count] = safe_strdup (g, fs->fstab[i].mountpoint);
+ ret[2*count+1] = safe_strdup (g, fs->fstab[i].device);
+ count++;
+ }
+#undef CRITERION
+
+ return ret;
+}
+
+char **
+guestfs__inspect_get_filesystems (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return NULL;
+
+ char **ret;
+
+ /* If no fstab information (Windows) return just the root. */
+ if (fs->nr_fstab == 0) {
+ ret = calloc (2, sizeof (char *));
+ ret[0] = safe_strdup (g, root);
+ ret[1] = NULL;
+ return ret;
+ }
+
+ ret = calloc (fs->nr_fstab + 1, sizeof (char *));
+ if (ret == NULL) {
+ perrorf (g, "calloc");
+ return NULL;
+ }
+
+ size_t i;
+ for (i = 0; i < fs->nr_fstab; ++i)
+ ret[i] = safe_strdup (g, fs->fstab[i].device);
+
+ return ret;
+}
+
+char **
+guestfs__inspect_get_drive_mappings (guestfs_h *g, const char *root)
+{
+ char **ret;
+ size_t i, count;
+ struct inspect_fs *fs;
+
+ fs = guestfs___search_for_root (g, root);
+ if (!fs)
+ return NULL;
+
+ /* If no drive mappings, return an empty hashtable. */
+ if (!fs->drive_mappings)
+ count = 0;
+ else {
+ for (count = 0; fs->drive_mappings[count] != NULL; count++)
+ ;
+ }
+
+ ret = calloc (count+1, sizeof (char *));
+ if (ret == NULL) {
+ perrorf (g, "calloc");
+ return NULL;
+ }
+
+ /* We need to make a deep copy of the hashtable since the caller
+ * will free it.
+ */
+ for (i = 0; i < count; ++i)
+ ret[i] = safe_strdup (g, fs->drive_mappings[i]);
+
+ ret[count] = NULL;
+