static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs,
const char *spec, const char *mp);
static char *resolve_fstab_device (guestfs_h *g, const char *spec);
+static void check_package_format (guestfs_h *g, struct inspect_fs *fs);
+static void check_package_management (guestfs_h *g, struct inspect_fs *fs);
static int
check_for_filesystem_on (guestfs_h *g, const char *device)
fs->device = safe_strdup (g, device);
fs->is_mountable = 1;
+ /* Optimize some of the tests by avoiding multiple tests of the same thing. */
+ int is_dir_etc = guestfs_is_dir (g, "/etc") > 0;
+ int is_dir_bin = guestfs_is_dir (g, "/bin") > 0;
+ int is_dir_share = guestfs_is_dir (g, "/share") > 0;
+
/* Grub /boot? */
if (guestfs_is_file (g, "/grub/menu.lst") > 0 ||
guestfs_is_file (g, "/grub/grub.conf") > 0)
fs->content = FS_CONTENT_LINUX_BOOT;
/* Linux root? */
- else if (guestfs_is_dir (g, "/etc") > 0 &&
- guestfs_is_dir (g, "/bin") > 0 &&
+ else if (is_dir_etc &&
+ is_dir_bin &&
guestfs_is_file (g, "/etc/fstab") > 0) {
fs->is_root = 1;
fs->content = FS_CONTENT_LINUX_ROOT;
return -1;
}
/* Linux /usr/local? */
- else if (guestfs_is_dir (g, "/etc") > 0 &&
- guestfs_is_dir (g, "/bin") > 0 &&
- guestfs_is_dir (g, "/share") > 0 &&
+ else if (is_dir_etc &&
+ is_dir_bin &&
+ is_dir_share &&
guestfs_exists (g, "/local") == 0 &&
guestfs_is_file (g, "/etc/fstab") == 0)
fs->content = FS_CONTENT_LINUX_USR_LOCAL;
/* Linux /usr? */
- else if (guestfs_is_dir (g, "/etc") > 0 &&
- guestfs_is_dir (g, "/bin") > 0 &&
- guestfs_is_dir (g, "/share") > 0 &&
+ else if (is_dir_etc &&
+ is_dir_bin &&
+ is_dir_share &&
guestfs_exists (g, "/local") > 0 &&
guestfs_is_file (g, "/etc/fstab") == 0)
fs->content = FS_CONTENT_LINUX_USR;
skip_release_checks:;
+ /* If distro test above was successful, work out the package format. */
+ check_package_format (g, fs);
+ check_package_management (g, fs);
+
/* Determine the architecture. */
const char *binaries[] =
{ "/bin/bash", "/bin/ls", "/bin/echo", "/bin/rm", "/bin/sh" };
if (check_windows_registry (g, fs) == -1)
return -1;
+ check_package_format (g, fs);
+ check_package_management (g, fs);
+
return 0;
}
return ret;
}
+/* At the moment, package format and package management is just a
+ * simple function of the distro and major_version fields, so these
+ * can never return an error. We might be cleverer in future.
+ */
+static void
+check_package_format (guestfs_h *g, struct inspect_fs *fs)
+{
+ switch (fs->distro) {
+ case OS_DISTRO_FEDORA:
+ case OS_DISTRO_MEEGO:
+ case OS_DISTRO_REDHAT_BASED:
+ case OS_DISTRO_RHEL:
+ fs->package_format = OS_PACKAGE_FORMAT_RPM;
+ break;
+
+ case OS_DISTRO_DEBIAN:
+ case OS_DISTRO_UBUNTU:
+ fs->package_format = OS_PACKAGE_FORMAT_DEB;
+ break;
+
+ case OS_DISTRO_ARCHLINUX:
+ fs->package_format = OS_PACKAGE_FORMAT_PACMAN;
+ break;
+ case OS_DISTRO_GENTOO:
+ fs->package_format = OS_PACKAGE_FORMAT_EBUILD;
+ break;
+ case OS_DISTRO_PARDUS:
+ fs->package_format = OS_PACKAGE_FORMAT_PISI;
+ break;
+
+ case OS_DISTRO_WINDOWS:
+ case OS_DISTRO_UNKNOWN:
+ default:
+ fs->package_format = OS_PACKAGE_FORMAT_UNKNOWN;
+ break;
+ }
+}
+
+static void
+check_package_management (guestfs_h *g, struct inspect_fs *fs)
+{
+ switch (fs->distro) {
+ case OS_DISTRO_FEDORA:
+ case OS_DISTRO_MEEGO:
+ fs->package_management = OS_PACKAGE_MANAGEMENT_YUM;
+ break;
+
+ case OS_DISTRO_REDHAT_BASED:
+ case OS_DISTRO_RHEL:
+ if (fs->major_version >= 5)
+ fs->package_management = OS_PACKAGE_MANAGEMENT_YUM;
+ else
+ fs->package_management = OS_PACKAGE_MANAGEMENT_UP2DATE;
+ break;
+
+ case OS_DISTRO_DEBIAN:
+ case OS_DISTRO_UBUNTU:
+ fs->package_management = OS_PACKAGE_MANAGEMENT_APT;
+ break;
+
+ case OS_DISTRO_ARCHLINUX:
+ fs->package_management = OS_PACKAGE_MANAGEMENT_PACMAN;
+ break;
+ case OS_DISTRO_GENTOO:
+ fs->package_management = OS_PACKAGE_MANAGEMENT_PORTAGE;
+ break;
+ case OS_DISTRO_PARDUS:
+ fs->package_management = OS_PACKAGE_MANAGEMENT_PISI;
+ break;
+
+ case OS_DISTRO_WINDOWS:
+ case OS_DISTRO_UNKNOWN:
+ default:
+ fs->package_management = OS_PACKAGE_MANAGEMENT_UNKNOWN;
+ break;
+ }
+}
+
static struct inspect_fs *
search_for_root (guestfs_h *g, const char *root)
{
return ret;
}
+char *
+guestfs__inspect_get_package_format (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = search_for_root (g, root);
+ if (!fs)
+ return NULL;
+
+ char *ret;
+ switch (fs->package_format) {
+ case OS_PACKAGE_FORMAT_RPM: ret = safe_strdup (g, "rpm"); break;
+ case OS_PACKAGE_FORMAT_DEB: ret = safe_strdup (g, "deb"); break;
+ case OS_PACKAGE_FORMAT_PACMAN: ret = safe_strdup (g, "pacman"); break;
+ case OS_PACKAGE_FORMAT_EBUILD: ret = safe_strdup (g, "ebuild"); break;
+ case OS_PACKAGE_FORMAT_PISI: ret = safe_strdup (g, "pisi"); break;
+ case OS_PACKAGE_FORMAT_UNKNOWN:
+ default:
+ ret = safe_strdup (g, "unknown");
+ break;
+ }
+
+ return ret;
+}
+
+char *
+guestfs__inspect_get_package_management (guestfs_h *g, const char *root)
+{
+ struct inspect_fs *fs = search_for_root (g, root);
+ if (!fs)
+ return NULL;
+
+ char *ret;
+ switch (fs->package_management) {
+ case OS_PACKAGE_MANAGEMENT_YUM: ret = safe_strdup (g, "yum"); break;
+ case OS_PACKAGE_MANAGEMENT_UP2DATE: ret = safe_strdup (g, "up2date"); break;
+ case OS_PACKAGE_MANAGEMENT_APT: ret = safe_strdup (g, "apt"); break;
+ case OS_PACKAGE_MANAGEMENT_PACMAN: ret = safe_strdup (g, "pacman"); break;
+ case OS_PACKAGE_MANAGEMENT_PORTAGE: ret = safe_strdup (g, "portage"); break;
+ case OS_PACKAGE_MANAGEMENT_PISI: ret = safe_strdup (g, "pisi"); break;
+ case OS_PACKAGE_MANAGEMENT_UNKNOWN:
+ default:
+ ret = safe_strdup (g, "unknown");
+ break;
+ }
+
+ return ret;
+}
+
#else /* no PCRE or hivex at compile time */
/* XXX These functions should be in an optgroup. */
NOT_IMPL(NULL);
}
+char *
+guestfs__inspect_get_package_format (guestfs_h *g, const char *root)
+{
+ NOT_IMPL(NULL);
+}
+
+char *
+guestfs__inspect_get_package_management (guestfs_h *g, const char *root)
+{
+ NOT_IMPL(NULL);
+}
+
#endif /* no PCRE or hivex at compile time */
void
return 1;
}
+/* Match a regular expression which contains exactly three captures. */
+int
+guestfs___match3 (guestfs_h *g, const char *str, const pcre *re,
+ char **ret1, char **ret2, char **ret3)
+{
+ size_t len = strlen (str);
+ int vec[30], r;
+
+ r = pcre_exec (re, NULL, str, len, 0, 0, vec, 30);
+ if (r == PCRE_ERROR_NOMATCH)
+ 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",
+ __FILE__, __func__, r, str);
+ return 0;
+ }
+
+ *ret1 = safe_strndup (g, &str[vec[2]], vec[3]-vec[2]);
+ *ret2 = safe_strndup (g, &str[vec[4]], vec[5]-vec[4]);
+ *ret3 = safe_strndup (g, &str[vec[6]], vec[7]-vec[6]);
+
+ return 1;
+}
+
#endif /* HAVE_PCRE */