Exemplo n.º 1
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)
{
  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;
}
Exemplo n.º 2
0
/* The currently mounted device is known to be a FreeBSD root. */
int
guestfs___check_freebsd_root (guestfs_h *g, struct inspect_fs *fs)
{
  fs->type = OS_TYPE_FREEBSD;

  /* FreeBSD has no authoritative version file.  The version number is
   * in /etc/motd, which the system administrator might edit, but
   * we'll use that anyway.
   */

  if (guestfs_exists (g, "/etc/motd") > 0) {
    if (parse_release_file (g, fs, "/etc/motd") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }

  /* Determine the architecture. */
  check_architecture (g, fs);

  /* We already know /etc/fstab exists because it's part of the test above. */
  const char *configfiles[] = { "/etc/fstab", NULL };
  if (inspect_with_augeas (g, fs, configfiles, check_fstab) == -1)
    return -1;

  /* Determine hostname. */
  if (check_hostname_unix (g, fs) == -1)
    return -1;

  return 0;
}
Exemplo n.º 3
0
static char *
icon_cirros (guestfs_h *g, struct inspect_fs *fs, size_t *size_r)
{
  char *ret = NOT_FOUND;
  char *type = NULL;
  char *local = NULL;
  char *pngfile = NULL;
  struct command *cmd;
  int r;

  r = guestfs_exists (g, CIRROS_LOGO);
  if (r == -1) {
    ret = NULL; /* a real error */
    goto out;
  }
  if (r == 0) goto out;

  /* Check the file type and geometry. */
  type = guestfs_file (g, CIRROS_LOGO);
  if (!type) goto out;

  if (!STRPREFIX (type, "ASCII text")) goto out;

  local = guestfs___download_to_tmp (g, fs, CIRROS_LOGO, "icon", 1024);
  if (!local) goto out;

  /* Use pbmtext to render it. */
  pngfile = safe_asprintf (g, "%s/cirros.png", g->tmpdir);

  cmd = guestfs___new_command (g);
  guestfs___cmd_add_string_unquoted (cmd, PBMTEXT " < ");
  guestfs___cmd_add_string_quoted   (cmd, local);
  guestfs___cmd_add_string_unquoted (cmd, " | " PNMTOPNG " > ");
  guestfs___cmd_add_string_quoted   (cmd, pngfile);
  r = guestfs___cmd_run (cmd);
  guestfs___cmd_close (cmd);
  if (r == -1)
    goto out;
  if (!WIFEXITED (r) || WEXITSTATUS (r) != 0)
    goto out;

  /* Read it into memory. */
  if (read_whole_file (g, pngfile, &ret, size_r) == -1) {
    ret = NULL;
    goto out;
  }

 out:
  free (pngfile);
  free (local);
  free (type);

  return ret;
}
Exemplo n.º 4
0
/* Check that the named file 'filename' is a PNG file and is reasonable.
 * If it is, download and return it.
 */
static char *
get_png (guestfs_h *g, struct inspect_fs *fs, const char *filename,
         size_t *size_r, size_t max_size)
{
  char *ret = NOT_FOUND;
  char *type = NULL;
  char *local = NULL;
  int r, w, h;

  r = guestfs_exists (g, filename);
  if (r == -1) {
    ret = NULL; /* a real error */
    goto out;
  }
  if (r == 0) goto out;

  /* Check the file type and geometry. */
  type = guestfs_file (g, filename);
  if (!type) goto out;

  if (!STRPREFIX (type, "PNG image data, ")) goto out;
  if (sscanf (&type[16], "%d x %d", &w, &h) != 2) goto out;
  if (w < 16 || h < 16 || w > 1024 || h > 1024) goto out;

  /* Define a maximum reasonable size based on the geometry.  This
   * also limits the maximum we allocate below to around 4 MB.
   */
  if (max_size == 0)
    max_size = 4 * w * h;

  local = guestfs___download_to_tmp (g, fs, filename, "icon", max_size);
  if (!local) goto out;

  /* Successfully passed checks and downloaded.  Read it into memory. */
  if (read_whole_file (g, local, &ret, size_r) == -1) {
    ret = NULL;
    goto out;
  }

 out:
  free (local);
  free (type);

  return ret;
}
Exemplo n.º 5
0
int
guestfs_impl_mount_local_run (guestfs_h *g)
{
  int r, mounted;

  gl_lock_lock (mount_local_lock);
  mounted = g->localmountpoint != NULL;
  gl_lock_unlock (mount_local_lock);

  if (!mounted) {
    error (g, _("you must call guestfs_mount_local first"));
    return -1;
  }

  /* Test if root is mounted.  We do this by using a side-effect of
   * guestfs_exists (which is that it calls NEED_ROOT).
   */
  guestfs_push_error_handler (g, NULL, NULL);
  r = guestfs_exists (g, "/");
  guestfs_pop_error_handler (g);
  if (r == -1) {
    error (g, _("you must call 'guestfs_mount' first to mount a filesystem on '/'.\nNote: '%s' is still mounted.  Use 'guestunmount %s' to clean up."),
           g->localmountpoint, g->localmountpoint);
    return -1;
  }

  debug (g, "%s: entering fuse_loop", __func__);

  /* Enter the main loop. */
  r = fuse_loop (g->fuse);
  if (r != 0)
    perrorf (g, _("fuse_loop: %s"), g->localmountpoint);

  debug (g, "%s: leaving fuse_loop", __func__);

  guestfs_int_free_fuse (g);
  gl_lock_lock (mount_local_lock);
  g->localmountpoint = NULL;
  gl_lock_unlock (mount_local_lock);

  /* By inspection, I found that fuse_loop only returns 0 or -1, but
   * don't rely on this in future.
   */
  return r == 0 ? 0 : -1;
}
Exemplo n.º 6
0
/* The currently mounted device is maybe to be a *BSD root. */
int
guestfs___check_netbsd_root (guestfs_h *g, struct inspect_fs *fs)
{

  if (guestfs_exists (g, "/etc/release") > 0) {
    char *major, *minor;
    if (parse_release_file (g, fs, "/etc/release") == -1)
      return -1;

    if (match2 (g, fs->product_name, re_netbsd, &major, &minor)) {
      fs->type = OS_TYPE_NETBSD;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1) {
        free (minor);
        return -1;
      }
      fs->minor_version = guestfs___parse_unsigned_int (g, minor);
      free (minor);
      if (fs->minor_version == -1)
        return -1;
    }
  } else {
    return -1;
  }

  /* Determine the architecture. */
  check_architecture (g, fs);

  /* We already know /etc/fstab exists because it's part of the test above. */
  const char *configfiles[] = { "/etc/fstab", NULL };
  if (inspect_with_augeas (g, fs, configfiles, check_fstab) == -1)
    return -1;

  /* Determine hostname. */
  if (check_hostname_unix (g, fs) == -1)
    return -1;

  return 0;
}
Exemplo n.º 7
0
/* 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
 * associated devices.
 */
int
guestfs___check_linux_root (guestfs_h *g, struct inspect_fs *fs)
{
  int r;

  fs->type = OS_TYPE_LINUX;

  if (guestfs_exists (g, "/etc/lsb-release") > 0) {
    r = parse_lsb_release (g, fs);
    if (r == -1)        /* error */
      return -1;
    if (r == 1)         /* ok - detected the release from this file */
      goto skip_release_checks;
  }

  if (guestfs_exists (g, "/etc/redhat-release") > 0) {
    fs->distro = OS_DISTRO_REDHAT_BASED; /* Something generic Red Hat-like. */

    if (parse_release_file (g, fs, "/etc/redhat-release") == -1)
      return -1;

    char *major, *minor;
    if ((major = match1 (g, fs->product_name, re_fedora)) != NULL) {
      fs->distro = OS_DISTRO_FEDORA;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1)
        return -1;
    }
    else if (match2 (g, fs->product_name, re_rhel_old, &major, &minor) ||
             match2 (g, fs->product_name, re_rhel, &major, &minor)) {
      fs->distro = OS_DISTRO_RHEL;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1) {
        free (minor);
        return -1;
      }
      fs->minor_version = guestfs___parse_unsigned_int (g, minor);
      free (minor);
      if (fs->minor_version == -1)
        return -1;
    }
    else if ((major = match1 (g, fs->product_name, re_rhel_no_minor)) != NULL) {
      fs->distro = OS_DISTRO_RHEL;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1)
        return -1;
      fs->minor_version = 0;
    }
    else if (match2 (g, fs->product_name, re_centos_old, &major, &minor) ||
             match2 (g, fs->product_name, re_centos, &major, &minor)) {
      fs->distro = OS_DISTRO_CENTOS;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1) {
        free (minor);
        return -1;
      }
      fs->minor_version = guestfs___parse_unsigned_int (g, minor);
      free (minor);
      if (fs->minor_version == -1)
        return -1;
    }
    else if ((major = match1 (g, fs->product_name, re_centos_no_minor)) != NULL) {
      fs->distro = OS_DISTRO_CENTOS;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1)
        return -1;
      fs->minor_version = 0;
    }
    else if (match2 (g, fs->product_name, re_scientific_linux_old, &major, &minor) ||
             match2 (g, fs->product_name, re_scientific_linux, &major, &minor)) {
      fs->distro = OS_DISTRO_SCIENTIFIC_LINUX;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1) {
        free (minor);
        return -1;
      }
      fs->minor_version = guestfs___parse_unsigned_int (g, minor);
      free (minor);
      if (fs->minor_version == -1)
        return -1;
    }
    else if ((major = match1 (g, fs->product_name, re_scientific_linux_no_minor)) != NULL) {
      fs->distro = OS_DISTRO_SCIENTIFIC_LINUX;
      fs->major_version = guestfs___parse_unsigned_int (g, major);
      free (major);
      if (fs->major_version == -1)
        return -1;
      fs->minor_version = 0;
    }
  }
  else 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;
  }
  else if (guestfs_exists (g, "/etc/pardus-release") > 0) {
    fs->distro = OS_DISTRO_PARDUS;

    if (parse_release_file (g, fs, "/etc/pardus-release") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }
  else if (guestfs_exists (g, "/etc/arch-release") > 0) {
    fs->distro = OS_DISTRO_ARCHLINUX;

    /* /etc/arch-release file is empty and I can't see a way to
     * determine the actual release or product string.
     */
  }
  else if (guestfs_exists (g, "/etc/gentoo-release") > 0) {
    fs->distro = OS_DISTRO_GENTOO;

    if (parse_release_file (g, fs, "/etc/gentoo-release") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }
  else if (guestfs_exists (g, "/etc/meego-release") > 0) {
    fs->distro = OS_DISTRO_MEEGO;

    if (parse_release_file (g, fs, "/etc/meego-release") == -1)
      return -1;

    if (guestfs___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 (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }
  else if (guestfs_exists (g, "/etc/ttylinux-target") > 0) {
    fs->distro = OS_DISTRO_TTYLINUX;

    if (parse_release_file (g, fs, "/etc/ttylinux-target") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }
  else if (guestfs_exists (g, "/etc/SuSE-release") > 0) {
    fs->distro = OS_DISTRO_SUSE_BASED;

    if (parse_suse_release (g, fs, "/etc/SuSE-release") == -1)
      return -1;

  }
  /* Buildroot (http://buildroot.net) is an embedded Linux distro
   * toolkit.  It is used by specific distros such as Cirros.
   */
  else if (guestfs_exists (g, "/etc/br-version") > 0) {
    if (guestfs_exists (g, "/usr/share/cirros/logo") > 0)
      fs->distro = OS_DISTRO_CIRROS;
    else
      fs->distro = OS_DISTRO_BUILDROOT;

    /* /etc/br-version has the format YYYY.MM[-git/hg/svn release] */
    if (parse_release_file (g, fs, "/etc/br-version") == -1)
      return -1;

    if (guestfs___parse_major_minor (g, fs) == -1)
      return -1;
  }

 skip_release_checks:;

  /* Determine the architecture. */
  check_architecture (g, fs);

  /* We already know /etc/fstab exists because it's part of the test
   * for Linux root above.  We must now parse this file to determine
   * which filesystems are used by the operating system and how they
   * are mounted.
   */
  const char *configfiles[] = { "/etc/fstab", "/etc/mdadm.conf", NULL };
  if (inspect_with_augeas (g, fs, configfiles, check_fstab) == -1)
    return -1;

  /* Determine hostname. */
  if (check_hostname_unix (g, fs) == -1)
    return -1;

  return 0;
}