diff options
-rw-r--r-- | generator/actions.ml | 8 | ||||
-rw-r--r-- | src/guestfs-internal.h | 2 | ||||
-rw-r--r-- | src/inspect-fs-unix.c | 100 | ||||
-rw-r--r-- | src/inspect-fs.c | 4 | ||||
-rw-r--r-- | src/inspect-icon.c | 2 | ||||
-rw-r--r-- | src/inspect.c | 2 |
6 files changed, 114 insertions, 4 deletions
diff --git a/generator/actions.ml b/generator/actions.ml index a17fed0d..438b3165 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -1000,6 +1000,14 @@ Scientific Linux. Slackware. +=item \"sles\" + +SuSE Linux Enterprise Server or Desktop. + +=item \"suse-based\" + +Some openSuSE-derived distro. + =item \"ttylinux\" ttylinux. diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index 88afb814..42bf05d7 100644 --- a/src/guestfs-internal.h +++ b/src/guestfs-internal.h @@ -346,6 +346,8 @@ enum inspect_os_distro { OS_DISTRO_BUILDROOT, OS_DISTRO_CIRROS, OS_DISTRO_FREEDOS, + OS_DISTRO_SUSE_BASED, + OS_DISTRO_SLES, }; enum inspect_os_package_format { diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c index 6d4b46c7..2152484f 100644 --- a/src/inspect-fs-unix.c +++ b/src/inspect-fs-unix.c @@ -67,6 +67,12 @@ static pcre *re_mdN; static pcre *re_freebsd; static pcre *re_diskbyid; static pcre *re_netbsd; +static pcre *re_opensuse; +static pcre *re_sles; +static pcre *re_nld; +static pcre *re_opensuse_version; +static pcre *re_sles_version; +static pcre *re_sles_patchlevel; static void compile_regexps (void) __attribute__((constructor)); static void free_regexps (void) __attribute__((destructor)); @@ -112,6 +118,12 @@ compile_regexps (void) COMPILE (re_freebsd, "^/dev/ad(\\d+)s(\\d+)([a-z])$", 0); COMPILE (re_diskbyid, "^/dev/disk/by-id/.*-part(\\d+)$", 0); COMPILE (re_netbsd, "^NetBSD (\\d+)\\.(\\d+)", 0); + COMPILE (re_opensuse, "^(openSUSE|SuSE Linux|SUSE LINUX) ", 0); + COMPILE (re_sles, "^SUSE (Linux|LINUX) Enterprise ", 0); + COMPILE (re_nld, "^Novell Linux Desktop ", 0); + COMPILE (re_opensuse_version, "^VERSION = (\\d+)\\.(\\d+)", 0); + COMPILE (re_sles_version, "^VERSION = (\\d+)", 0); + COMPILE (re_sles_patchlevel, "^PATCHLEVEL = (\\d+)", 0); } static void @@ -134,6 +146,12 @@ free_regexps (void) pcre_free (re_freebsd); pcre_free (re_diskbyid); pcre_free (re_netbsd); + pcre_free (re_opensuse); + pcre_free (re_sles); + pcre_free (re_nld); + pcre_free (re_opensuse_version); + pcre_free (re_sles_version); + pcre_free (re_sles_patchlevel); } static void check_architecture (guestfs_h *g, struct inspect_fs *fs); @@ -301,6 +319,82 @@ parse_lsb_release (guestfs_h *g, struct inspect_fs *fs) return r ? 1 : 0; } +static int +parse_suse_release (guestfs_h *g, struct inspect_fs *fs, const char *filename) +{ + int64_t size; + char *major, *minor; + char **lines; + int r = -1; + + /* Don't trust guestfs_head_n not to break with very large files. + * Check the file size is something reasonable first. + */ + size = guestfs_filesize (g, filename); + if (size == -1) + /* guestfs_filesize failed and has already set error in handle */ + return -1; + if (size > MAX_SMALL_FILE_SIZE) { + error (g, _("size of %s is unreasonably large (%" PRIi64 " bytes)"), + filename, size); + return -1; + } + + lines = guestfs_head_n (g, 10, filename); + if (lines == NULL) + return -1; + + /* First line is dist release name */ + fs->product_name = safe_strdup (g, lines[0]); + if (fs->product_name == NULL) + goto out; + + /* Match SLES first because openSuSE regex overlaps some SLES release strings */ + if (match (g, fs->product_name, re_sles) || match (g, fs->product_name, re_nld)) { + fs->distro = OS_DISTRO_SLES; + + /* Second line contains version string */ + if (lines[1] == NULL) + goto out; + major = match1 (g, lines[1], re_sles_version); + fs->major_version = guestfs___parse_unsigned_int (g, major); + free (major); + if (fs->major_version == -1) + goto out; + + /* Third line contains service pack string */ + if (lines[2] == NULL) + goto out; + minor = match1 (g, lines[2], re_sles_patchlevel); + fs->minor_version = guestfs___parse_unsigned_int (g, minor); + free (minor); + if (fs->minor_version == -1) + goto out; + } + else if (match (g, fs->product_name, re_opensuse)) { + fs->distro = OS_DISTRO_OPENSUSE; + + /* Second line contains version string */ + if (lines[1] == NULL) + goto out; + if (match2 (g, lines[1], re_opensuse_version, &major, &minor)) { + fs->major_version = guestfs___parse_unsigned_int (g, major); + fs->minor_version = guestfs___parse_unsigned_int (g, minor); + free (major); + free (minor); + if (fs->major_version == -1 || fs->minor_version == -1) + goto out; + } + } + + r = 0; + +out: + guestfs___free_string_list (lines); + + return r; +} + /* The currently mounted device is known to be a Linux root. Try to * determine from this the distro, version, etc. Also parse * /etc/fstab to determine the arrangement of mountpoints and @@ -464,13 +558,11 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs *fs) return -1; } else if (guestfs_exists (g, "/etc/SuSE-release") > 0) { - fs->distro = OS_DISTRO_OPENSUSE; + fs->distro = OS_DISTRO_SUSE_BASED; - if (parse_release_file (g, fs, "/etc/SuSE-release") == -1) + if (parse_suse_release (g, fs, "/etc/SuSE-release") == -1) return -1; - if (guestfs___parse_major_minor (g, fs) == -1) - return -1; } /* Buildroot (http://buildroot.net) is an embedded Linux distro * toolkit. It is used by specific distros such as Cirros. diff --git a/src/inspect-fs.c b/src/inspect-fs.c index 7354029b..2dbafb5d 100644 --- a/src/inspect-fs.c +++ b/src/inspect-fs.c @@ -410,7 +410,9 @@ check_package_format (guestfs_h *g, struct inspect_fs *fs) case OS_DISTRO_RHEL: case OS_DISTRO_MAGEIA: case OS_DISTRO_MANDRIVA: + case OS_DISTRO_SUSE_BASED: case OS_DISTRO_OPENSUSE: + case OS_DISTRO_SLES: case OS_DISTRO_CENTOS: case OS_DISTRO_SCIENTIFIC_LINUX: fs->package_format = OS_PACKAGE_FORMAT_RPM; @@ -484,7 +486,9 @@ check_package_management (guestfs_h *g, struct inspect_fs *fs) fs->package_management = OS_PACKAGE_MANAGEMENT_URPMI; break; + case OS_DISTRO_SUSE_BASED: case OS_DISTRO_OPENSUSE: + case OS_DISTRO_SLES: fs->package_management = OS_PACKAGE_MANAGEMENT_ZYPPER; break; diff --git a/src/inspect-icon.c b/src/inspect-icon.c index 19acfb9c..531ba61f 100644 --- a/src/inspect-icon.c +++ b/src/inspect-icon.c @@ -152,7 +152,9 @@ guestfs__inspect_get_icon (guestfs_h *g, const char *root, size_t *size_r, r = icon_mageia (g, fs, &size); break; + case OS_DISTRO_SUSE_BASED: case OS_DISTRO_OPENSUSE: + case OS_DISTRO_SLES: r = icon_opensuse (g, fs, &size); break; diff --git a/src/inspect.c b/src/inspect.c index 5dd92663..f16aea10 100644 --- a/src/inspect.c +++ b/src/inspect.c @@ -232,6 +232,8 @@ guestfs__inspect_get_distro (guestfs_h *g, const char *root) case OS_DISTRO_RHEL: ret = safe_strdup (g, "rhel"); break; case OS_DISTRO_SCIENTIFIC_LINUX: ret = safe_strdup (g, "scientificlinux"); break; case OS_DISTRO_SLACKWARE: ret = safe_strdup (g, "slackware"); break; + case OS_DISTRO_SLES: ret = safe_strdup (g, "sles"); break; + case OS_DISTRO_SUSE_BASED: ret = safe_strdup (g, "suse-based"); break; case OS_DISTRO_TTYLINUX: ret = safe_strdup (g, "ttylinux"); break; case OS_DISTRO_WINDOWS: ret = safe_strdup (g, "windows"); break; case OS_DISTRO_UBUNTU: ret = safe_strdup (g, "ubuntu"); break; |