extra tests: Absolute path for 'run' command.
[libguestfs.git] / src / inspect_fs_unix.c
index 3046e02..b68dde1 100644 (file)
@@ -107,7 +107,6 @@ compile_regexps (void)
   COMPILE (re_scientific_linux_no_minor,
            "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);
   COMPILE (re_cciss, "^/dev/(cciss/c\\d+d\\d+)(?:p(\\d+))?$", 0);
   COMPILE (re_freebsd, "^/dev/ad(\\d+)s(\\d+)([a-z])$", 0);
@@ -128,7 +127,6 @@ free_regexps (void)
   pcre_free (re_scientific_linux);
   pcre_free (re_scientific_linux_no_minor);
   pcre_free (re_major_minor);
-  pcre_free (re_aug_seq);
   pcre_free (re_xdev);
   pcre_free (re_cciss);
   pcre_free (re_freebsd);
@@ -533,6 +531,41 @@ guestfs___check_netbsd_root (guestfs_h *g, struct inspect_fs *fs)
   return 0;
 }
 
+/* The currently mounted device may be a Hurd root.  Hurd has distros
+ * just like Linux.
+ */
+int
+guestfs___check_hurd_root (guestfs_h *g, struct inspect_fs *fs)
+{
+  int r;
+
+  fs->type = OS_TYPE_HURD;
+
+  if (guestfs_exists (g, "/etc/debian_version") > 0) {
+    fs->distro = OS_DISTRO_DEBIAN;
+
+    if (parse_release_file (g, fs, "/etc/debian_version") == -1)
+      return -1;
+
+    if (guestfs___parse_major_minor (g, fs) == -1)
+      return -1;
+  }
+
+  /* Arch Hurd also exists, but inconveniently it doesn't have
+   * the normal /etc/arch-release file.  XXX
+   */
+
+  /* Determine the architecture. */
+  check_architecture (g, fs);
+
+  /* XXX Check for /etc/fstab. */
+
+  /* Determine hostname. */
+  if (check_hostname_unix (g, fs) == -1)
+    return -1;
+
+  return 0;
+}
 
 static void
 check_architecture (guestfs_h *g, struct inspect_fs *fs)
@@ -569,6 +602,7 @@ check_hostname_unix (guestfs_h *g, struct inspect_fs *fs)
 {
   switch (fs->type) {
   case OS_TYPE_LINUX:
+  case OS_TYPE_HURD:
     /* Red Hat-derived would be in /etc/sysconfig/network, and
      * Debian-derived in the file /etc/hostname.  Very old Debian and
      * SUSE use /etc/HOSTNAME.  It's best to just look for each of
@@ -688,45 +722,43 @@ check_hostname_freebsd (guestfs_h *g, struct inspect_fs *fs)
 static int
 check_fstab (guestfs_h *g, struct inspect_fs *fs)
 {
-  char **lines = guestfs_aug_ls (g, "/files/etc/fstab");
-  if (lines == NULL) goto error;
+  char **entries, **entry;
+  char augpath[256];
+  char *spec, *mp;
+  int r;
+
+  entries = guestfs_aug_match (g, "/files/etc/fstab/*[label() != '#comment']");
+  if (entries == NULL) goto error;
 
-  if (lines[0] == NULL) {
+  if (entries[0] == NULL) {
     error (g, _("could not parse /etc/fstab or empty file"));
     goto error;
   }
 
-  size_t i;
-  char augpath[256];
-  for (i = 0; lines[i] != NULL; ++i) {
-    /* Ignore comments.  Only care about sequence lines which
-     * match m{/\d+$}.
-     */
-    if (match (g, lines[i], re_aug_seq)) {
-      snprintf (augpath, sizeof augpath, "%s/spec", lines[i]);
-      char *spec = guestfs_aug_get (g, augpath);
-      if (spec == NULL) goto error;
-
-      snprintf (augpath, sizeof augpath, "%s/file", lines[i]);
-      char *mp = guestfs_aug_get (g, augpath);
-      if (mp == NULL) {
-        free (spec);
-        goto error;
-      }
+  for (entry = entries; *entry != NULL; entry++) {
+    snprintf (augpath, sizeof augpath, "%s/spec", *entry);
+    spec = guestfs_aug_get (g, augpath);
+    if (spec == NULL) goto error;
 
-      int r = add_fstab_entry (g, fs, spec, mp);
+    snprintf (augpath, sizeof augpath, "%s/file", *entry);
+    mp = guestfs_aug_get (g, augpath);
+    if (mp == NULL) {
       free (spec);
-      free (mp);
-
-      if (r == -1) goto error;
+      goto error;
     }
+
+    r = add_fstab_entry (g, fs, spec, mp);
+    free (spec);
+    free (mp);
+
+    if (r == -1) goto error;
   }
 
-  guestfs___free_string_list (lines);
+  guestfs___free_string_list (entries);
   return 0;
 
 error:
-  if (lines) guestfs___free_string_list (lines);
+  if (entries) guestfs___free_string_list (entries);
   return -1;
 }