X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Finspect.c;h=3a8ede6007db87572681e61fee1ef49dc6b1b7f7;hb=edb7501d60a03107c21f023b256d2b01cf116437;hp=4986cac775a77eee17a4cc0e26e88864fc63e137;hpb=2b26c7f721fc8ed2e6f64963289981ac286c02aa;p=libguestfs.git diff --git a/src/inspect.c b/src/inspect.c index 4986cac..3a8ede6 100644 --- a/src/inspect.c +++ b/src/inspect.c @@ -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); @@ -230,6 +230,8 @@ 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 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 parse_unsigned_int_ignore_trailing (guestfs_h *g, const char *str); @@ -258,10 +260,9 @@ check_for_filesystem_on (guestfs_h *g, const char *device, int is_swap = vfs_type && STREQ (vfs_type, "swap"); - if (g->verbose) - fprintf (stderr, "check_for_filesystem_on: %s %d %d (%s)\n", - device, is_block, is_partnum, - vfs_type ? vfs_type : "failed to get vfs type"); + debug (g, "check_for_filesystem_on: %s %d %d (%s)", + device, is_block, is_partnum, + vfs_type ? vfs_type : "failed to get vfs type"); if (is_swap) { free (vfs_type); @@ -365,24 +366,31 @@ 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") > 0 || + is_dir_nocase (g, "/WIN32") > 0 || + is_dir_nocase (g, "/WINNT") > 0 || + is_file_nocase (g, "/boot.ini") > 0 || + is_file_nocase (g, "/ntldr") > 0) { fs->is_root = 1; fs->content = FS_CONTENT_WINDOWS_ROOT; fs->format = OS_FORMAT_INSTALLED; 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; /* Install CD/disk? Skip these checks if it's not a whole device * (eg. CD) or the first partition (eg. bootable USB key). */ @@ -637,6 +645,15 @@ check_linux_root (guestfs_h *g, struct inspect_fs *fs) if (parse_major_minor (g, fs) == -1) return -1; } + else if (guestfs_exists (g, "/etc/slackware-version") > 0) { + fs->distro = OS_DISTRO_SLACKWARE; + + if (parse_release_file (g, fs, "/etc/slackware-version") == -1) + return -1; + + if (parse_major_minor (g, fs) == -1) + return -1; + } skip_release_checks:; @@ -1307,8 +1324,7 @@ add_fstab_entry (guestfs_h *g, struct inspect_fs *fs, fs->fstab[n-1].device = device; fs->fstab[n-1].mountpoint = mountpoint; - if (g->verbose) - fprintf (stderr, "fstab: device=%s mountpoint=%s\n", device, mountpoint); + debug (g, "fstab: device=%s mountpoint=%s", device, mountpoint); return 0; } @@ -1414,8 +1430,7 @@ check_windows_root (guestfs_h *g, struct inspect_fs *fs) return -1; } - if (g->verbose) - fprintf (stderr, "windows %%SYSTEMROOT%% = %s", systemroot); + debug (g, "windows %%SYSTEMROOT%% = %s", systemroot); /* Freed by guestfs___free_inspect_info. */ fs->windows_systemroot = systemroot; @@ -1552,6 +1567,14 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs) free (version); } + else if (STRCASEEQ (key, "InstallationType")) { + fs->product_variant = hivex_value_string (h, values[i]); + if (!fs->product_variant) { + perrorf (g, "hivex_value_string"); + free (key); + goto out; + } + } free (key); } @@ -1665,6 +1688,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 = resolve_windows_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 = resolve_windows_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; @@ -1742,6 +1793,7 @@ check_package_format (guestfs_h *g, struct inspect_fs *fs) fs->package_format = OS_PACKAGE_FORMAT_PISI; break; + case OS_DISTRO_SLACKWARE: case OS_DISTRO_WINDOWS: case OS_DISTRO_UNKNOWN: default: @@ -1786,6 +1838,7 @@ check_package_management (guestfs_h *g, struct inspect_fs *fs) fs->package_management = OS_PACKAGE_MANAGEMENT_URPMI; break; + case OS_DISTRO_SLACKWARE: case OS_DISTRO_WINDOWS: case OS_DISTRO_UNKNOWN: default: @@ -1893,6 +1946,7 @@ guestfs__inspect_get_distro (guestfs_h *g, const char *root) case OS_DISTRO_PARDUS: ret = safe_strdup (g, "pardus"); break; case OS_DISTRO_REDHAT_BASED: ret = safe_strdup (g, "redhat-based"); break; case OS_DISTRO_RHEL: ret = safe_strdup (g, "rhel"); break; + case OS_DISTRO_SLACKWARE: ret = safe_strdup (g, "slackware"); break; case OS_DISTRO_WINDOWS: ret = safe_strdup (g, "windows"); break; case OS_DISTRO_UBUNTU: ret = safe_strdup (g, "ubuntu"); break; case OS_DISTRO_UNKNOWN: default: ret = safe_strdup (g, "unknown"); break; @@ -1932,6 +1986,16 @@ guestfs__inspect_get_product_name (guestfs_h *g, const char *root) } char * +guestfs__inspect_get_product_variant (guestfs_h *g, const char *root) +{ + struct inspect_fs *fs = 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 = search_for_root (g, root); @@ -2219,8 +2283,7 @@ list_applications_rpm (guestfs_h *g, struct inspect_fs *fs) snprintf (cmd, cmd_len, DB_DUMP " -p '%s'", tmpfile); - if (g->verbose) - fprintf (stderr, "list_applications_rpm: %s\n", cmd); + debug (g, "list_applications_rpm: %s", cmd); pp = popen (cmd, "r"); if (pp == NULL) { @@ -2817,6 +2880,12 @@ guestfs__inspect_get_product_name (guestfs_h *g, const char *root) } char * +guestfs__inspect_get_product_variant (guestfs_h *g, const char *root) +{ + NOT_IMPL(NULL); +} + +char * guestfs__inspect_get_windows_systemroot (guestfs_h *g, const char *root) { NOT_IMPL(NULL); @@ -2891,6 +2960,7 @@ guestfs___free_inspect_info (guestfs_h *g) for (i = 0; i < g->nr_fses; ++i) { free (g->fses[i].device); free (g->fses[i].product_name); + free (g->fses[i].product_variant); free (g->fses[i].arch); free (g->fses[i].hostname); free (g->fses[i].windows_systemroot); @@ -2940,7 +3010,7 @@ guestfs___match (guestfs_h *g, const char *str, const pcre *re) return 0; if (r != 1) { /* Internal error -- should not happen. */ - fprintf (stderr, "libguestfs: %s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"\n", + warning (g, "%s: %s: pcre_exec returned unexpected error code %d when matching against the string \"%s\"\n", __FILE__, __func__, r, str); return 0; } @@ -2963,7 +3033,7 @@ guestfs___match1 (guestfs_h *g, const char *str, const pcre *re) return NULL; if (r != 2) { /* Internal error -- should not happen. */ - fprintf (stderr, "libguestfs: %s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"\n", + warning (g, "%s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"", __FILE__, __func__, r, str); return NULL; } @@ -2984,7 +3054,7 @@ guestfs___match2 (guestfs_h *g, const char *str, const pcre *re, return 0; if (r != 3) { /* Internal error -- should not happen. */ - fprintf (stderr, "libguestfs: %s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"\n", + warning (g, "%s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"", __FILE__, __func__, r, str); return 0; } @@ -3008,7 +3078,7 @@ guestfs___match3 (guestfs_h *g, const char *str, const pcre *re, return 0; if (r != 4) { /* Internal error -- should not happen. */ - fprintf (stderr, "libguestfs: %s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"\n", + warning (g, "%s: %s: internal error: pcre_exec returned unexpected error code %d when matching against the string \"%s\"", __FILE__, __func__, r, str); return 0; }