Esempio n. 1
0
/* Parse the hostname from /etc/rc.conf.  On FreeBSD this file
 * contains comments, blank lines and:
 *   hostname="freebsd8.example.com"
 *   ifconfig_re0="DHCP"
 *   keymap="uk.iso"
 *   sshd_enable="YES"
 */
static int
check_hostname_freebsd (guestfs_h *g, struct inspect_fs *fs)
{
  const char *filename = "/etc/rc.conf";
  int64_t size;
  CLEANUP_FREE_STRING_LIST char **lines = NULL;
  size_t i;

  /* Don't trust guestfs_read_lines 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_read_lines (g, filename);
  if (lines == NULL)
    return -1;

  for (i = 0; lines[i] != NULL; ++i) {
    if (STRPREFIX (lines[i], "hostname=\"") ||
        STRPREFIX (lines[i], "hostname='")) {
      size_t len = strlen (lines[i]) - 10 - 1;
      fs->hostname = safe_strndup (g, &lines[i][10], len);
      break;
    } else if (STRPREFIX (lines[i], "hostname=")) {
      size_t len = strlen (lines[i]) - 9;
      fs->hostname = safe_strndup (g, &lines[i][9], len);
      break;
    }
  }

  return 0;
}
char *
guestfs___get_windows_systemroot (guestfs_h *g)
{
  /* Check a predefined list of common windows system root locations */
  static const char *systemroots[] =
    { "/windows", "/winnt", "/win32", "/win", NULL };

  for (size_t i = 0; i < sizeof systemroots / sizeof systemroots[0]; ++i) {
    char *systemroot =
      guestfs___case_sensitive_path_silently (g, systemroots[i]);
    if (!systemroot)
      continue;

    if (is_systemroot (g, systemroot)) {
      debug (g, "windows %%SYSTEMROOT%% = %s", systemroot);

      return systemroot;
    } else {
      free (systemroot);
    }
  }

  /* If the fs contains boot.ini, check it for non-standard
   * systemroot locations */
  CLEANUP_FREE char *boot_ini_path =
    guestfs___case_sensitive_path_silently (g, "/boot.ini");
  if (boot_ini_path && guestfs_is_file (g, boot_ini_path) > 0) {
    CLEANUP_FREE_STRING_LIST char **boot_ini =
      guestfs_read_lines (g, boot_ini_path);
    if (!boot_ini) {
      debug (g, "error reading %s", boot_ini_path);
      return NULL;
    }

    int found_os = 0;
    for (char **i = boot_ini; *i != NULL; i++) {
      CLEANUP_FREE char *controller_type = NULL;
      CLEANUP_FREE char *controller = NULL;
      CLEANUP_FREE char *disk = NULL;
      CLEANUP_FREE char *rdisk = NULL;
      CLEANUP_FREE char *partition = NULL;
      CLEANUP_FREE char *path = NULL;

      char *line = *i;

      if (!found_os) {
        if (match (g, line, re_boot_ini_os_header)) {
          found_os = 1;
          continue;
        }
      }

      /* See http://support.microsoft.com/kb/102873 for a discussion
       * of what this line means */
      if (match6 (g, line, re_boot_ini_os, &controller_type,
                  &controller, &disk, &rdisk, &partition, &path))
      {
        /* The Windows system root may be on any disk. However, there
         * are currently (at least) 2 practical problems preventing us
         * from locating it on another disk:
         *
         * 1. We don't have enough metadata about the disks we were
         * given to know if what controller they were on and what
         * index they had.
         *
         * 2. The way inspection of filesystems currently works, we
         * can't mark another filesystem, which we may have already
         * inspected, to be inspected for a specific Windows system
         * root.
         *
         * Solving 1 properly would require a new API at a minimum. We
         * might be able to fudge something practical without this,
         * though, e.g. by looking at the <partition>th partition of
         * every disk for the specific windows root.
         *
         * Solving 2 would probably require a significant refactoring
         * of the way filesystems are inspected. We should probably do
         * this some time.
         *
         * For the moment, we ignore all partition information and
         * assume the system root is on the current partition. In
         * practice, this will normally be correct.
         */

        /* Swap backslashes for forward slashes in the system root
         * path */
        for (char *j = path; *j != '\0'; j++) {
          if (*j == '\\') *j = '/';
        }

        char *systemroot = guestfs___case_sensitive_path_silently (g, path);
        if (systemroot && is_systemroot (g, systemroot)) {
          debug (g, "windows %%SYSTEMROOT%% = %s", systemroot);

          return systemroot;
        } else {
          free (systemroot);
        }
      }
    }
  }

  return NULL; /* not found */
}