./PaxHeaders/virt-p2v-1.42.3 0000644 0000000 0000000 00000000132 14321270274 012432 x ustar 00 30 mtime=1665495228.521332068
30 atime=1665495228.547331902
30 ctime=1665495228.521332068
virt-p2v-1.42.3/ 0000755 0001750 0001750 00000000000 14321270274 014156 5 ustar 00rjones rjones 0000000 0000000 virt-p2v-1.42.3/PaxHeaders/ssh.c 0000644 0000000 0000000 00000000132 14321267767 013330 x ustar 00 30 mtime=1665495031.276573678
30 atime=1665495044.541493365
30 ctime=1665495228.436332611
virt-p2v-1.42.3/ssh.c 0000644 0001750 0001750 00000106206 14321267767 015141 0 ustar 00rjones rjones 0000000 0000000 /* virt-p2v
* Copyright (C) 2009-2022 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/**
* This file handles the ssh connections to the conversion server.
*
* virt-p2v will open several connections over the lifetime of
* the conversion process.
*
* In C, it will first open a connection (to check it
* is possible) and query virt-v2v on the server to ensure it exists,
* it is the right version, and so on. This connection is then
* closed, because in the GUI case we don't want to deal with keeping
* it alive in case the administrator has set up an autologout.
*
* Once we start conversion, we will open a control connection to send
* the libvirt configuration data and to start up virt-v2v, and we
* will open up one data connection per local hard disk. The data
* connection(s) have a reverse port forward to the local NBD server
* which is serving the content of that hard disk. The remote port
* for each data connection is assigned by ssh. See
* C and C.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "ignore-value.h"
#include "miniexpect.h"
#include "p2v.h"
#define SSH_TIMEOUT 60 /* seconds */
char *v2v_version = NULL;
char **input_drivers = NULL;
char **output_drivers = NULL;
static void free_globals (void) __attribute__((destructor));
static void
free_globals (void)
{
pcre2_substring_free ((PCRE2_UCHAR *)v2v_version);
}
static char *ssh_error;
static void set_ssh_error (const char *fs, ...)
__attribute__((format(printf,1,2)));
static void
set_ssh_error (const char *fs, ...)
{
va_list args;
char *msg;
int len;
va_start (args, fs);
len = vasprintf (&msg, fs, args);
va_end (args);
if (len < 0)
error (EXIT_FAILURE, errno,
"vasprintf (original error format string: %s)", fs);
free (ssh_error);
ssh_error = msg;
}
const char *
get_ssh_error (void)
{
return ssh_error;
}
/* Like set_ssh_error, but for errors that aren't supposed to happen. */
#define set_ssh_internal_error(fs, ...) \
set_ssh_error ("%s:%d: internal error: " fs, __FILE__, __LINE__, \
##__VA_ARGS__)
#define set_ssh_mexp_error(fn) \
set_ssh_internal_error ("%s: %m", fn)
#define set_ssh_pcre_error() \
set_ssh_internal_error ("pcre error: %d\n", mexp_get_pcre_error (h))
#define set_ssh_unexpected_eof(fs, ...) \
set_ssh_error ("remote server closed the connection unexpectedly, " \
"waiting for: " fs, ##__VA_ARGS__)
#define set_ssh_unexpected_timeout(fs, ...) \
set_ssh_error ("remote server timed out unexpectedly, " \
"waiting for: " fs, ##__VA_ARGS__)
static void compile_regexps (void) __attribute__((constructor));
static void free_regexps (void) __attribute__((destructor));
static pcre2_code *password_re;
static pcre2_code *ssh_message_re;
static pcre2_code *sudo_password_re;
static pcre2_code *prompt_re;
static pcre2_code *version_re;
static pcre2_code *feature_libguestfs_rewrite_re;
static pcre2_code *feature_colours_option_re;
static pcre2_code *feature_input_re;
static pcre2_code *feature_output_re;
static pcre2_code *portfwd_re;
static void
compile_regexps (void)
{
int errorcode;
PCRE2_SIZE offset;
char errormsg[256];
#define COMPILE(re,pattern) \
do { \
re = pcre2_compile ((PCRE2_SPTR) (pattern), \
PCRE2_ZERO_TERMINATED, \
0, &errorcode, &offset, NULL); \
if (re == NULL) { \
pcre2_get_error_message (errorcode, \
(PCRE2_UCHAR *) errormsg, sizeof errormsg); \
ignore_value (write (2, errormsg, strlen (errormsg))); \
abort (); \
} \
} while (0)
COMPILE (password_re, "password:");
/* Note that (?:.)* is required in order to work around a problem
* with partial matching and PCRE in RHEL 5.
*/
COMPILE (ssh_message_re, "(ssh: (?:.)*)");
COMPILE (sudo_password_re, "sudo: a password is required");
/* The magic synchronization strings all match this expression. See
* start_ssh function below.
*/
COMPILE (prompt_re,
"###((?:[0123456789abcdefghijklmnopqrstuvwxyz]){8})### ");
/* Note that (?:.)* is required in order to work around a problem
* with partial matching and PCRE in RHEL 5.
*/
COMPILE (version_re, "virt-v2v ([1-9](?:.)*)");
COMPILE (feature_libguestfs_rewrite_re, "libguestfs-rewrite");
COMPILE (feature_colours_option_re, "colours-option");
/* The input and output regexps must match the same pattern in
* v2v/modules_list.ml.
*/
COMPILE (feature_input_re, "input:((?:[-\\w])+)");
COMPILE (feature_output_re, "output:((?:[-\\w])+)");
COMPILE (portfwd_re, "Allocated port ((?:\\d)+) for remote forward");
}
static void
free_regexps (void)
{
pcre2_code_free (password_re);
pcre2_code_free (ssh_message_re);
pcre2_code_free (sudo_password_re);
pcre2_code_free (prompt_re);
pcre2_code_free (version_re);
pcre2_code_free (feature_libguestfs_rewrite_re);
pcre2_code_free (feature_colours_option_re);
pcre2_code_free (feature_input_re);
pcre2_code_free (feature_output_re);
pcre2_code_free (portfwd_re);
}
/**
* Download URL to local file using the external 'curl' command.
*/
static int
curl_download (const char *url, const char *local_file)
{
char curl_config_file[] = "/tmp/curl.XXXXXX";
int fd;
size_t i, len;
FILE *fp;
gboolean ret;
const char *argv[] = { "curl", "-f", "-s", "-S", "-o", local_file,
"-K", curl_config_file, NULL };
CLEANUP_FREE char *stderr = NULL;
gint exit_status;
GError *gerror = NULL;
/* Use a secure curl config file because escaping is easier. */
fd = mkstemp (curl_config_file);
if (fd == -1)
error (EXIT_FAILURE, errno, "mkstemp: %s", curl_config_file);
fp = fdopen (fd, "w");
if (fp == NULL)
error (EXIT_FAILURE, errno, "fdopen: %s", curl_config_file);
fprintf (fp, "url = \"");
len = strlen (url);
for (i = 0; i < len; ++i) {
switch (url[i]) {
case '\\': fprintf (fp, "\\\\"); break;
case '"': fprintf (fp, "\\\""); break;
case '\t': fprintf (fp, "\\t"); break;
case '\n': fprintf (fp, "\\n"); break;
case '\r': fprintf (fp, "\\r"); break;
case '\v': fprintf (fp, "\\v"); break;
default: fputc (url[i], fp);
}
}
fprintf (fp, "\"\n");
fclose (fp);
/* Run curl to download the URL to a file. */
ret = g_spawn_sync (NULL, /* working directory; inherit */
(gchar **) argv,
NULL, /* environment; inherit */
G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL,
NULL, NULL, /* no child setup */
NULL, &stderr, &exit_status, &gerror);
/* unlink (curl_config_file); - useful for debugging */
if (!ret) {
set_ssh_error ("g_spawn_sync: %s: %s", url, gerror->message);
g_error_free (gerror);
return -1;
}
/* Did curl subprocess fail? */
if (WIFEXITED (exit_status) && WEXITSTATUS (exit_status) != 0) {
set_ssh_error ("%s: %s", url, stderr);
return -1;
}
else if (!WIFEXITED (exit_status)) {
set_ssh_internal_error ("curl subprocess got a signal (%d)", exit_status);
return -1;
}
return 0;
}
/**
* Re-cache the Cidentity.url> if needed.
*/
static int
cache_ssh_identity (struct config *config)
{
int fd;
/* If it doesn't need downloading, return. */
if (config->auth.identity.url == NULL ||
!config->auth.identity.file_needs_update)
return 0;
/* Generate a random filename. */
free (config->auth.identity.file);
config->auth.identity.file = strdup ("/tmp/id.XXXXXX");
if (config->auth.identity.file == NULL)
error (EXIT_FAILURE, errno, "strdup");
fd = mkstemp (config->auth.identity.file);
if (fd == -1)
error (EXIT_FAILURE, errno, "mkstemp");
close (fd);
/* Curl download URL to file. */
if (curl_download (config->auth.identity.url, config->auth.identity.file) == -1) {
free (config->auth.identity.file);
config->auth.identity.file = NULL;
config->auth.identity.file_needs_update = 1;
return -1;
}
return 0;
}
/* GCC complains about the argv array in the next function which it
* thinks might grow to an unbounded size. Since we control
* extra_args, this is not in fact a problem.
*/
#if P2V_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstack-usage="
#endif
/**
* Start ssh subprocess with the standard arguments and possibly some
* optional arguments. Also handles authentication.
*/
static mexp_h *
start_ssh (unsigned spawn_flags, struct config *config,
char **extra_args, int wait_prompt)
{
size_t i = 0;
const size_t MAX_ARGS =
64 + (extra_args != NULL ? guestfs_int_count_strings (extra_args) : 0);
const char *argv[MAX_ARGS];
char port_str[64];
char connect_timeout_str[128];
mexp_h *h;
CLEANUP_PCRE2_MATCH_DATA pcre2_match_data *match_data =
pcre2_match_data_create (4, NULL);
int saved_timeout;
int using_password_auth;
size_t count;
if (cache_ssh_identity (config) == -1)
return NULL;
/* Are we using password or identity authentication? */
using_password_auth = config->auth.identity.file == NULL;
ADD_ARG (argv, i, "ssh");
ADD_ARG (argv, i, "-p"); /* Port. */
snprintf (port_str, sizeof port_str, "%d", config->remote.port);
ADD_ARG (argv, i, port_str);
ADD_ARG (argv, i, "-l"); /* Username. */
ADD_ARG (argv, i, config->auth.username ? config->auth.username : "root");
ADD_ARG (argv, i, "-o"); /* Host key will always be novel. */
ADD_ARG (argv, i, "StrictHostKeyChecking=no");
ADD_ARG (argv, i, "-o"); /* ConnectTimeout */
snprintf (connect_timeout_str, sizeof connect_timeout_str,
"ConnectTimeout=%d", SSH_TIMEOUT);
ADD_ARG (argv, i, connect_timeout_str);
ADD_ARG (argv, i, "-o"); /* Send ping packets every 5 mins to sshd. */
ADD_ARG (argv, i, "ServerAliveInterval=300");
ADD_ARG (argv, i, "-o");
ADD_ARG (argv, i, "ServerAliveCountMax=6");
if (using_password_auth) {
/* Only use password authentication. */
ADD_ARG (argv, i, "-o");
ADD_ARG (argv, i, "PreferredAuthentications=keyboard-interactive,password");
}
else {
/* Use identity file (private key). */
ADD_ARG (argv, i, "-o");
ADD_ARG (argv, i, "PreferredAuthentications=publickey");
ADD_ARG (argv, i, "-i");
ADD_ARG (argv, i, config->auth.identity.file);
}
if (extra_args != NULL) {
for (size_t j = 0; extra_args[j] != NULL; ++j)
ADD_ARG (argv, i, extra_args[j]);
}
ADD_ARG (argv, i, config->remote.server); /* Conversion server. */
ADD_ARG (argv, i, NULL);
#if DEBUG_STDERR
fputs ("ssh command: ", stderr);
for (i = 0; argv[i] != NULL; ++i) {
if (i > 0) fputc (' ', stderr);
fputs (argv[i], stderr);
}
fputc ('\n', stderr);
#endif
/* Create the miniexpect handle. */
h = mexp_spawnvf (spawn_flags, "ssh", (char **) argv);
if (h == NULL) {
set_ssh_internal_error ("ssh: mexp_spawnvf: %m");
return NULL;
}
#if DEBUG_STDERR
mexp_set_debug_file (h, stderr);
#endif
/* We want the ssh ConnectTimeout to be less than the miniexpect
* timeout, so that if the server is completely unresponsive we
* still see the error from ssh, not a timeout from miniexpect. The
* obvious solution to this is to set ConnectTimeout (above) and to
* set the miniexpect timeout to be a little bit larger.
*/
mexp_set_timeout (h, SSH_TIMEOUT + 20);
if (using_password_auth &&
config->auth.password && strlen (config->auth.password) > 0) {
CLEANUP_PCRE2_SUBSTRING_FREE PCRE2_UCHAR *ssh_message = NULL;
PCRE2_SIZE ssh_msglen;
/* Wait for the password prompt. */
wait_password_again:
switch (mexp_expect (h,
(mexp_regexp[]) {
{ 100, .re = password_re },
{ 101, .re = ssh_message_re },
{ 0 }
}, match_data)) {
case 100: /* Got password prompt. */
if (mexp_printf_password (h, "%s", config->auth.password) == -1 ||
mexp_printf (h, "\n") == -1) {
set_ssh_mexp_error ("mexp_printf");
mexp_close (h);
return NULL;
}
break;
case 101:
pcre2_substring_free (ssh_message);
pcre2_substring_get_bynumber (match_data, 1, &ssh_message, &ssh_msglen);
goto wait_password_again;
case MEXP_EOF:
/* This is where we get to if the user enters an incorrect or
* impossible hostname or port number. Hopefully ssh printed an
* error message, and we picked it up and put it in
* 'ssh_message' in case 101 above. If not we have to print a
* generic error instead.
*/
if (ssh_message)
set_ssh_error ("%s", (char *) ssh_message);
else
set_ssh_error ("ssh closed the connection without printing an error.");
mexp_close (h);
return NULL;
case MEXP_TIMEOUT:
set_ssh_unexpected_timeout ("password prompt");
mexp_close (h);
return NULL;
case MEXP_ERROR:
set_ssh_mexp_error ("mexp_expect");
mexp_close (h);
return NULL;
case MEXP_PCRE_ERROR:
set_ssh_pcre_error ();
mexp_close (h);
return NULL;
}
}
if (!wait_prompt)
return h;
/* Ensure we are running bash, set environment variables, and
* synchronize with the command prompt and set it to a known
* string. There are multiple issues being solved here:
*
* We cannot control the initial shell prompt. It would involve
* changing the remote SSH configuration (AcceptEnv). However what
* we can do is to repeatedly send 'export PS1=' commands
* until we synchronize with the remote shell.
*
* Since we parse error messages, we must set LANG=C.
*
* We don't know if the user is using a Bourne-like shell (eg sh,
* bash) or csh/tcsh. Setting environment variables works
* differently.
*
* We don't know how command line editing is set up
* (https://bugzilla.redhat.com/1314244#c9).
*/
if (mexp_printf (h, "exec bash --noediting --noprofile\n") == -1) {
set_ssh_mexp_error ("mexp_printf");
mexp_close (h);
return NULL;
}
saved_timeout = mexp_get_timeout_ms (h);
mexp_set_timeout (h, 2);
for (count = 0; count < 30; ++count) {
char magic[9];
PCRE2_UCHAR *matched;
PCRE2_SIZE matchlen;
int r;
if (guestfs_int_random_string (magic, 8) == -1) {
set_ssh_internal_error ("random_string: %m");
mexp_close (h);
return NULL;
}
/* The purpose of the '' inside the string is to ensure we don't
* mistake the command echo for the prompt.
*/
if (mexp_printf (h, "export LANG=C PS1='###''%s''### '\n", magic) == -1) {
set_ssh_mexp_error ("mexp_printf");
mexp_close (h);
return NULL;
}
/* Wait for the prompt. */
wait_again:
switch (mexp_expect (h,
(mexp_regexp[]) {
{ 100, .re = password_re },
{ 101, .re = prompt_re },
{ 0 }
}, match_data)) {
case 100: /* Got password prompt unexpectedly. */
set_ssh_error ("Login failed. Probably the username and/or password is wrong.");
mexp_close (h);
return NULL;
case 101:
/* Got a prompt. However it might be an earlier prompt. If it
* doesn't match the PS1 string we sent, then repeat the expect.
*/
r = pcre2_substring_get_bynumber (match_data, 1, &matched, &matchlen);
if (r < 0)
error (EXIT_FAILURE, 0, "pcre error reading substring (%d)", r);
r = STREQ (magic, (char *) matched);
pcre2_substring_free (matched);
if (!r)
goto wait_again;
goto got_prompt;
case MEXP_EOF:
set_ssh_unexpected_eof ("the command prompt");
mexp_close (h);
return NULL;
case MEXP_TIMEOUT:
/* Timeout here is not an error, since ssh may "eat" commands that
* we send before the shell at the other end is ready. Just loop.
*/
break;
case MEXP_ERROR:
set_ssh_mexp_error ("mexp_expect");
mexp_close (h);
return NULL;
case MEXP_PCRE_ERROR:
set_ssh_pcre_error ();
mexp_close (h);
return NULL;
}
}
set_ssh_error ("Failed to synchronize with remote shell after 60 seconds.");
mexp_close (h);
return NULL;
got_prompt:
mexp_set_timeout_ms (h, saved_timeout);
return h;
}
#if P2V_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */
#pragma GCC diagnostic pop
#endif
/**
* Upload file(s) to remote using L.
*
* Note that the target (directory or file) comes before the list of
* local files, because the list of local files is a varargs list.
*
* This is a simplified version of L above.
*/
int
scp_file (struct config *config, const char *target, const char *local, ...)
{
size_t i = 0;
va_list args;
const size_t MAX_ARGS = 64;
const char *argv[MAX_ARGS];
char port_str[64];
char connect_timeout_str[128];
CLEANUP_FREE char *remote = NULL;
mexp_h *h;
CLEANUP_PCRE2_MATCH_DATA pcre2_match_data *match_data =
pcre2_match_data_create (4, NULL);
int using_password_auth;
if (cache_ssh_identity (config) == -1)
return -1;
/* Are we using password or identity authentication? */
using_password_auth = config->auth.identity.file == NULL;
ADD_ARG (argv, i, "scp");
ADD_ARG (argv, i, "-P"); /* Port. */
snprintf (port_str, sizeof port_str, "%d", config->remote.port);
ADD_ARG (argv, i, port_str);
ADD_ARG (argv, i, "-o"); /* Host key will always be novel. */
ADD_ARG (argv, i, "StrictHostKeyChecking=no");
ADD_ARG (argv, i, "-o"); /* ConnectTimeout */
snprintf (connect_timeout_str, sizeof connect_timeout_str,
"ConnectTimeout=%d", SSH_TIMEOUT);
ADD_ARG (argv, i, connect_timeout_str);
if (using_password_auth) {
/* Only use password authentication. */
ADD_ARG (argv, i, "-o");
ADD_ARG (argv, i, "PreferredAuthentications=keyboard-interactive,password");
}
else {
/* Use identity file (private key). */
ADD_ARG (argv, i, "-o");
ADD_ARG (argv, i, "PreferredAuthentications=publickey");
ADD_ARG (argv, i, "-i");
ADD_ARG (argv, i, config->auth.identity.file);
}
/* Source files or directories.
* Strictly speaking this could abort() if the list of files is
* too long, but that never happens in virt-p2v. XXX
*/
va_start (args, local);
do ADD_ARG (argv, i, local);
while ((local = va_arg (args, const char *)) != NULL);
va_end (args);
/* The target file or directory. We need to rewrite this as
* "username@server:target".
*/
if (asprintf (&remote, "%s@%s:%s",
config->auth.username ? config->auth.username : "root",
config->remote.server, target) == -1)
error (EXIT_FAILURE, errno, "asprintf");
ADD_ARG (argv, i, remote);
ADD_ARG (argv, i, NULL);
#if DEBUG_STDERR
fputs ("scp command: ", stderr);
for (i = 0; argv[i] != NULL; ++i) {
if (i > 0) fputc (' ', stderr);
fputs (argv[i], stderr);
}
fputc ('\n', stderr);
#endif
/* Create the miniexpect handle. */
h = mexp_spawnv ("scp", (char **) argv);
if (h == NULL) {
set_ssh_internal_error ("scp: mexp_spawnv: %m");
return -1;
}
#if DEBUG_STDERR
mexp_set_debug_file (h, stderr);
#endif
/* We want the ssh ConnectTimeout to be less than the miniexpect
* timeout, so that if the server is completely unresponsive we
* still see the error from ssh, not a timeout from miniexpect. The
* obvious solution to this is to set ConnectTimeout (above) and to
* set the miniexpect timeout to be a little bit larger.
*/
mexp_set_timeout (h, SSH_TIMEOUT + 20);
if (using_password_auth &&
config->auth.password && strlen (config->auth.password) > 0) {
CLEANUP_PCRE2_SUBSTRING_FREE PCRE2_UCHAR *ssh_message = NULL;
PCRE2_SIZE ssh_msglen;
/* Wait for the password prompt. */
wait_password_again:
switch (mexp_expect (h,
(mexp_regexp[]) {
{ 100, .re = password_re },
{ 101, .re = ssh_message_re },
{ 0 }
}, match_data)) {
case 100: /* Got password prompt. */
if (mexp_printf_password (h, "%s", config->auth.password) == -1 ||
mexp_printf (h, "\n") == -1) {
set_ssh_mexp_error ("mexp_printf");
mexp_close (h);
return -1;
}
break;
case 101:
pcre2_substring_free (ssh_message);
pcre2_substring_get_bynumber (match_data, 1, &ssh_message, &ssh_msglen);
goto wait_password_again;
case MEXP_EOF:
/* This is where we get to if the user enters an incorrect or
* impossible hostname or port number. Hopefully scp printed an
* error message, and we picked it up and put it in
* 'ssh_message' in case 101 above. If not we have to print a
* generic error instead.
*/
if (ssh_message)
set_ssh_error ("%s", (char *) ssh_message);
else
set_ssh_error ("scp closed the connection without printing an error.");
mexp_close (h);
return -1;
case MEXP_TIMEOUT:
set_ssh_unexpected_timeout ("password prompt");
mexp_close (h);
return -1;
case MEXP_ERROR:
set_ssh_mexp_error ("mexp_expect");
mexp_close (h);
return -1;
case MEXP_PCRE_ERROR:
set_ssh_pcre_error ();
mexp_close (h);
return -1;
}
}
/* Wait for the scp subprocess to finish. */
switch (mexp_expect (h, NULL, NULL)) {
case MEXP_EOF:
break;
case MEXP_TIMEOUT:
set_ssh_unexpected_timeout ("copying (scp) file");
mexp_close (h);
return -1;
case MEXP_ERROR:
set_ssh_mexp_error ("mexp_expect");
mexp_close (h);
return -1;
case MEXP_PCRE_ERROR:
set_ssh_pcre_error ();
mexp_close (h);
return -1;
}
if (mexp_close (h) == -1) {
set_ssh_internal_error ("scp: mexp_close: %m");
return -1;
}
return 0;
}
static void add_input_driver (const char *name);
static void add_output_driver (const char *name);
static int compatible_version (const char *v2v_version_p);
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn" /* WTF? */
#endif
int
test_connection (struct config *config)
{
mexp_h *h;
int feature_libguestfs_rewrite = 0;
int status;
CLEANUP_PCRE2_MATCH_DATA pcre2_match_data *match_data =
pcre2_match_data_create (4, NULL);
PCRE2_SIZE verlen;
h = start_ssh (0, config, NULL, 1);
if (h == NULL)
return -1;
/* Clear any previous version information since we may be connecting
* to a different server.
*/
pcre2_substring_free ((PCRE2_UCHAR *)v2v_version);
v2v_version = NULL;
/* Send 'virt-v2v --version' command and hope we get back a version string.
* Note old virt-v2v did not understand -V option.
*/
if (mexp_printf (h,
"%svirt-v2v --version\n",
config->auth.sudo ? "sudo -n " : "") == -1) {
set_ssh_mexp_error ("mexp_printf");
mexp_close (h);
return -1;
}
for (;;) {
switch (mexp_expect (h,
(mexp_regexp[]) {
{ 100, .re = version_re },
{ 101, .re = sudo_password_re },
{ 102, .re = prompt_re },
{ 0 }
}, match_data)) {
case 100: /* Got version string. */
pcre2_substring_free ((PCRE2_UCHAR *)v2v_version);
pcre2_substring_get_bynumber (match_data, 1,
(PCRE2_UCHAR **) &v2v_version, &verlen);
#if DEBUG_STDERR
fprintf (stderr, "%s: remote virt-v2v version: %s\n",
g_get_prgname (), v2v_version);
#endif
break;
case 101:
set_ssh_error ("sudo for user \"%s\" requires a password. Edit /etc/sudoers on the conversion server to ensure the \"NOPASSWD:\" option is set for this user.",
config->auth.username);
mexp_close (h);
return -1;
case 102: /* Got the prompt. */
goto end_of_version;
case MEXP_EOF:
set_ssh_unexpected_eof ("\"virt-v2v --version\" output");
mexp_close (h);
return -1;
case MEXP_TIMEOUT:
set_ssh_unexpected_timeout ("\"virt-v2v --version\" output");
mexp_close (h);
return -1;
case MEXP_ERROR:
set_ssh_mexp_error ("mexp_expect");
mexp_close (h);
return -1;
case MEXP_PCRE_ERROR:
set_ssh_pcre_error ();
mexp_close (h);
return -1;
}
}
end_of_version:
/* Got the prompt but no version number. */
if (v2v_version == NULL) {
set_ssh_error ("virt-v2v is not installed on the conversion server, "
"or it might be a too old version.");
mexp_close (h);
return -1;
}
/* Check the version of virt-v2v is compatible with virt-p2v. */
if (!compatible_version (v2v_version)) {
mexp_close (h);
return -1;
}
/* Clear any previous driver information since we may be connecting
* to a different server.
*/
guestfs_int_free_string_list (input_drivers);
guestfs_int_free_string_list (output_drivers);
input_drivers = output_drivers = NULL;
/* Get virt-v2v features. See: v2v/cmdline.ml */
if (mexp_printf (h, "%svirt-v2v --machine-readable\n",
config->auth.sudo ? "sudo -n " : "") == -1) {
set_ssh_mexp_error ("mexp_printf");
mexp_close (h);
return -1;
}
for (;;) {
PCRE2_UCHAR *driver;
PCRE2_SIZE drvrlen;
switch (mexp_expect (h,
(mexp_regexp[]) {
{ 100, .re = feature_libguestfs_rewrite_re },
{ 101, .re = feature_colours_option_re },
{ 102, .re = feature_input_re },
{ 103, .re = feature_output_re },
{ 104, .re = prompt_re },
{ 0 }
}, match_data)) {
case 100: /* libguestfs-rewrite. */
feature_libguestfs_rewrite = 1;
break;
case 101: /* virt-v2v supports --colours option */
#if DEBUG_STDERR
fprintf (stderr, "%s: remote virt-v2v supports --colours option\n",
g_get_prgname ());
#endif
feature_colours_option = 1;
break;
case 102:
/* input: corresponds to an -i option in virt-v2v. */
pcre2_substring_get_bynumber (match_data, 1, &driver, &drvrlen);
add_input_driver ((char *) driver);
pcre2_substring_free (driver);
break;
case 103:
/* output: corresponds to an -o option in virt-v2v. */
pcre2_substring_get_bynumber (match_data, 1, &driver, &drvrlen);
add_output_driver ((char *) driver);
pcre2_substring_free (driver);
break;
case 104: /* Got prompt, so end of output. */
goto end_of_machine_readable;
case MEXP_EOF:
set_ssh_unexpected_eof ("\"virt-v2v --machine-readable\" output");
mexp_close (h);
return -1;
case MEXP_TIMEOUT:
set_ssh_unexpected_timeout ("\"virt-v2v --machine-readable\" output");
mexp_close (h);
return -1;
case MEXP_ERROR:
set_ssh_mexp_error ("mexp_expect");
mexp_close (h);
return -1;
case MEXP_PCRE_ERROR:
set_ssh_pcre_error ();
mexp_close (h);
return -1;
}
}
end_of_machine_readable:
if (!feature_libguestfs_rewrite) {
set_ssh_error ("Invalid output of \"virt-v2v --machine-readable\" command.");
mexp_close (h);
return -1;
}
/* Test finished, shut down ssh. */
if (mexp_printf (h, "exit\n") == -1) {
set_ssh_mexp_error ("mexp_printf");
mexp_close (h);
return -1;
}
switch (mexp_expect (h, NULL, NULL)) {
case MEXP_EOF:
break;
case MEXP_TIMEOUT:
set_ssh_unexpected_timeout ("end of ssh session");
mexp_close (h);
return -1;
case MEXP_ERROR:
set_ssh_mexp_error ("mexp_expect");
mexp_close (h);
return -1;
case MEXP_PCRE_ERROR:
set_ssh_pcre_error ();
mexp_close (h);
return -1;
}
status = mexp_close (h);
if (status == -1) {
set_ssh_internal_error ("mexp_close: %m");
return -1;
}
if (WIFSIGNALED (status) && WTERMSIG (status) == SIGHUP)
return 0; /* not an error */
if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) {
set_ssh_internal_error ("unexpected close status from ssh subprocess (%d)",
status);
return -1;
}
return 0;
}
static void
add_option (const char *type, char ***drivers, const char *name)
{
size_t n;
if (*drivers == NULL)
n = 0;
else
n = guestfs_int_count_strings (*drivers);
n++;
*drivers = realloc (*drivers, (n+1) * sizeof (char *));
if (*drivers == NULL)
error (EXIT_FAILURE, errno, "malloc");
(*drivers)[n-1] = strdup (name);
if ((*drivers)[n-1] == NULL)
error (EXIT_FAILURE, errno, "strdup");
(*drivers)[n] = NULL;
#if DEBUG_STDERR
fprintf (stderr, "%s: remote virt-v2v supports %s driver %s\n",
g_get_prgname (), type, (*drivers)[n-1]);
#endif
}
static void
add_input_driver (const char *name)
{
add_option ("input", &input_drivers, name);
}
static void
add_output_driver (const char *name)
{
/* Ignore the 'vdsm' driver, since that should only be used by VDSM.
* Ignore the 'openstack' and 'rhv-upload' drivers, since we do not
* support passing all the options for them.
*/
if (STRNEQ (name, "vdsm") &&
STRNEQ (name, "openstack") &&
STRNEQ (name, "rhv-upload"))
add_option ("output", &output_drivers, name);
}
static int
compatible_version (const char *v2v_version_p)
{
unsigned v2v_major, v2v_minor;
/* The major version must always be 1 or 2. */
if (!STRPREFIX (v2v_version_p, "1.") && !STRPREFIX (v2v_version_p, "2.")) {
set_ssh_error ("virt-v2v major version is neither 1 nor 2 (\"%s\"), "
"this version of virt-p2v is not compatible.",
v2v_version_p);
return 0;
}
/* The version of virt-v2v must be >= 1.28, just to make sure
* someone isn't (a) using one of the experimental 1.27 releases
* that we published during development, nor (b) using old virt-v2v.
* We should remain compatible with any virt-v2v after 1.28.
*/
if (sscanf (v2v_version_p, "%u.%u", &v2v_major, &v2v_minor) != 2) {
set_ssh_internal_error ("cannot parse virt-v2v version string (\"%s\")",
v2v_version_p);
return 0;
}
if (v2v_major == 1 && v2v_minor < 28) {
set_ssh_error ("virt-v2v version is < 1.28 (\"%s\"), "
"you must upgrade to virt-v2v >= 1.28 on "
"the conversion server.", v2v_version_p);
return 0;
}
return 1; /* compatible */
}
mexp_h *
open_data_connection (struct config *config, int local_port, int *remote_port)
{
mexp_h *h;
char remote_arg[32];
const char *extra_args[] = {
"-R", remote_arg,
"-N",
NULL
};
PCRE2_UCHAR *port_str;
PCRE2_SIZE portlen;
CLEANUP_PCRE2_MATCH_DATA pcre2_match_data *match_data =
pcre2_match_data_create (4, NULL);
snprintf (remote_arg, sizeof remote_arg, "0:localhost:%d", local_port);
h = start_ssh (0, config, (char **) extra_args, 0);
if (h == NULL)
return NULL;
switch (mexp_expect (h,
(mexp_regexp[]) {
{ 100, .re = portfwd_re },
{ 0 }
}, match_data)) {
case 100: /* Ephemeral port. */
pcre2_substring_get_bynumber (match_data, 1, &port_str, &portlen);
if (port_str == NULL) {
set_ssh_internal_error ("strndup: %m");
mexp_close (h);
return NULL;
}
if (sscanf ((char *) port_str, "%d", remote_port) != 1) {
set_ssh_internal_error ("cannot extract the port number from '%s'",
port_str);
pcre2_substring_free (port_str);
mexp_close (h);
return NULL;
}
pcre2_substring_free (port_str);
break;
case MEXP_EOF:
set_ssh_unexpected_eof ("\"ssh -R\" output");
mexp_close (h);
return NULL;
case MEXP_TIMEOUT:
set_ssh_unexpected_timeout ("\"ssh -R\" output");
mexp_close (h);
return NULL;
case MEXP_ERROR:
set_ssh_mexp_error ("mexp_expect");
mexp_close (h);
return NULL;
case MEXP_PCRE_ERROR:
set_ssh_pcre_error ();
mexp_close (h);
return NULL;
}
return h;
}
/* Wait for the prompt. */
static int
wait_for_prompt (mexp_h *h)
{
CLEANUP_PCRE2_MATCH_DATA pcre2_match_data *match_data =
pcre2_match_data_create (4, NULL);
switch (mexp_expect (h,
(mexp_regexp[]) {
{ 100, .re = prompt_re },
{ 0 }
}, match_data)) {
case 100: /* Got the prompt. */
return 0;
case MEXP_EOF:
set_ssh_unexpected_eof ("command prompt");
return -1;
case MEXP_TIMEOUT:
set_ssh_unexpected_timeout ("command prompt");
return -1;
case MEXP_ERROR:
set_ssh_mexp_error ("mexp_expect");
return -1;
case MEXP_PCRE_ERROR:
set_ssh_pcre_error ();
return -1;
}
return 0;
}
mexp_h *
start_remote_connection (struct config *config, const char *remote_dir)
{
mexp_h *h;
/* This connection is opened in cooked mode so that we can send ^C
* if the conversion needs to be cancelled. However that also means
* we must be careful not to accidentally send any control
* characters over this connection at other times.
*/
h = start_ssh (MEXP_SPAWN_COOKED_MODE, config, NULL, 1);
if (h == NULL)
return NULL;
/* Create the remote directory. */
if (mexp_printf (h, "mkdir %s\n", remote_dir) == -1) {
set_ssh_mexp_error ("mexp_printf");
goto error;
}
if (wait_for_prompt (h) == -1)
goto error;
/* It's simplest to create the remote 'time' file by running the date
* command, as that won't send any special control characters.
*/
if (mexp_printf (h, "date > %s/time\n", remote_dir) == -1) {
set_ssh_mexp_error ("mexp_printf");
goto error;
}
if (wait_for_prompt (h) == -1)
goto error;
return h;
error:
mexp_close (h);
return NULL;
}
virt-p2v-1.42.3/PaxHeaders/virt-p2v-make-disk.in 0000644 0000000 0000000 00000000132 14267535425 016251 x ustar 00 30 mtime=1658764053.832410166
30 atime=1665478155.844244612
30 ctime=1665495228.405332809
virt-p2v-1.42.3/virt-p2v-make-disk.in 0000644 0001750 0001750 00000020624 14267535425 020061 0 ustar 00rjones rjones 0000000 0000000 #!/bin/bash -
# @configure_input@
# virt-p2v-make-disk
# Copyright (C) 2014-2019 Red Hat Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
unset CDPATH
program="virt-p2v-make-disk"
version="@PACKAGE_VERSION@"
prefix="@prefix@"
exec_prefix="@exec_prefix@"
datarootdir="@datarootdir@"
if [ -n "$VIRT_P2V_DATA_DIR" ]; then
datadir="$VIRT_P2V_DATA_DIR"
libdir="$VIRT_P2V_DATA_DIR"
else
datadir="@datadir@/virt-p2v"
libdir="@libdir@/virt-p2v"
fi
# Parse the command line arguments.
shortopts=o:vV
longopts=arch:,help,short-options,inject-ssh-identity:,install:,long-options,no-warn-if-partition,output:,verbose,version
TEMP=`getopt \
-o "$shortopts" \
--long "$longopts" \
-n $program -- "$@"`
if [ $? != 0 ]; then
echo "$program: problem parsing the command line arguments"
exit 1
fi
eval set -- "$TEMP"
output=
upload=
verbose=
declare -a passthru
usage ()
{
echo "Usage:"
echo " $program [--options] -o /dev/sdX [os-version]"
echo
echo "Read $program(1) man page for more information."
exit $1
}
while true; do
case "$1" in
--arch)
arch="$2"
shift 2;;
--inject-ssh-identity)
upload="--upload $2:/var/tmp/id_rsa"
shift 2;;
-o|--output)
output="$2"
shift 2;;
-v|--verbose)
set +x
verbose=1
shift;;
# virt-builder parameters that are passed through.
--install)
passthru[${#passthru[*]}]="$1"
passthru[${#passthru[*]}]="$2"
shift 2;;
--no-warn-if-partition)
passthru[${#passthru[*]}]="$1"
shift;;
# help etc.
--help)
usage 0;;
-V|--version)
echo "$program $version"
exit 0;;
--short-options)
echo -n "$shortopts" |
@SED@ -e 's/://g' -e 's/\(.\)/-\1\n/g'
exit 0;;
--long-options)
echo "$longopts" |
@SED@ -e 's/,/\n/g' -e 's/:$//mg' -e 's/\(.*\)/--\1/mg' |
grep -v -E -- "--(short|long)-options"
exit 0;;
--)
shift
break;;
*)
echo "internal error ($1)"
exit 1;;
esac
done
if [ -z "$output" ]; then
echo "$program: You must set the -o (--output) option."
exit 1
fi
if [ $# -gt 1 ]; then
echo "$program: Too many parameters. See $program(1)."
exit 1
fi
if [ $# -eq 1 ]; then
osversion="$1"
else
# If osversion was not set, then we must guess a good value
# based on the host distro.
if test -f /etc/os-release; then
osversion="`. /etc/os-release && echo ${ID}-${VERSION_ID}`"
fi
if [ "x$osversion" = "x" ]; then
echo "$program: unable to guess a suitable os-version."
echo "You must supply one on the command line and output of 'virt-builder -l'."
echo "See $program(1) for further details."
exit 1
fi
fi
if [ -n "$arch" ]; then
arch_option="--arch $arch"
virt_p2v_xz_binary="$libdir/virt-p2v.$arch.xz"
else
virt_p2v_xz_binary="$libdir/virt-p2v.xz"
fi
if [ ! -f "$virt_p2v_xz_binary" ]; then
echo "$program: cannot find $virt_p2v_xz_binary"
if [ -n "$arch" ]; then
echo "You used the '--arch' option, so it’s likely that you will need to build"
echo "a virt-p2v.$arch binary yourself."
echo "See p2v-building(1) section BUILDING i686 32 BIT VIRT-P2V for help."
fi
exit 1
fi
# Create a temporary directory and clean it up when we finish.
tmpdir="$(mktemp -d)"
cleanup ()
{
rm -rf $tmpdir
}
trap cleanup INT QUIT TERM EXIT ERR
# Uncompress the virt-p2v binary into tmpdir.
virt_p2v_binary="$tmpdir/virt-p2v"
xzcat "$virt_p2v_xz_binary" > "$virt_p2v_binary"
# Variations depending on the target distro. The main difference
# is in the list of distro packages we add to the base appliance.
case "$osversion" in
centos-*|fedora-*|rhel-*|scientificlinux-*|oraclelinux-*)
depsfile="$datadir/dependencies.redhat"
cat > $tmpdir/p2v.conf <<'EOF'
add_drivers+=" usb-storage "
EOF
cat > $tmpdir/post-install <<'EOF'
#!/bin/bash
# Rebuild the initramfs.
latest_version="$(cd /lib/modules; ls -1vr | head -1)"
dracut -v -f --kver $latest_version
EOF
# Double quotes because we want $tmpdir to be expanded:
extra_args="
--selinux-relabel
--upload $tmpdir/p2v.conf:/etc/dracut.conf.d/
--run $tmpdir/post-install
"
;;
debian-*|ubuntu-*)
depsfile="$datadir/dependencies.debian"
cat > $tmpdir/policy-rc.d <<'EOF'
#!/bin/sh
# Avoid running daemons during the upgrade/installation
exit 101
EOF
chmod +x $tmpdir/policy-rc.d
# Double quotes because we want $tmpdir to be expanded:
preinstall_args="
--upload $tmpdir/policy-rc.d:/usr/sbin/policy-rc.d
"
final_args="
--delete /usr/sbin/policy-rc.d
"
;;
archlinux-*)
depsfile="$datadir/dependencies.archlinux"
;;
opensuse-*|suse-*)
depsfile="$datadir/dependencies.suse"
;;
*)
echo "$program: internal error: could not work out the Linux distro from '$osversion'"
exit 1
esac
# Virt-builder requires the dependencies to be comma-separated with
# no spaces. The $depsfile is one dependency per line.
if [ ! -f "$depsfile" ]; then
echo "$program: cannot find dependencies file ($depsfile)"
exit 1
fi
install=
while read line; do
if [ -n "$line" ]; then
if [ -z "$install" ]; then
install="$line"
else
install="$install,$line"
fi
fi
done < $depsfile
# Add -v -x if we're in verbose mode.
if [ "x$verbose" = "x1" ]; then
verbose_option="-v -x"
fi
# Run virt-builder. Note we controversially assume systemd here. We
# could provide a sysvinit fallback if required.
# The manual 'hostname' invocation is needed to set the hostname
# also for the appliance itself, so scriptlets can properly use
# the hostname we want.
virt-builder "$osversion" \
$verbose_option \
--output "$output" \
$arch_option \
$preinstall_args \
--hostname p2v.local \
--run-command 'hostname p2v.local' \
--run-command 'dnf -y update --exclude=kernel\*' \
--install "$install" \
--root-password password:p2v \
--upload "$datadir"/issue:/etc/issue \
--upload "$datadir"/issue:/etc/issue.net \
--mkdir /usr/bin \
--upload "$virt_p2v_binary":/usr/bin/virt-p2v \
--chmod 0755:/usr/bin/virt-p2v \
--upload "$datadir"/launch-virt-p2v:/usr/bin/ \
--chmod 0755:/usr/bin/launch-virt-p2v \
--upload "$datadir"/p2v.service:/etc/systemd/system/ \
--mkdir /etc/systemd/system/multi-user.target.wants \
--link /etc/systemd/system/p2v.service:/etc/systemd/system/multi-user.target.wants/p2v.service \
--edit '/lib/systemd/system/getty@.service:
s/^ExecStart=(.*)/ExecStart=$1 -a root/
' \
--edit '/etc/systemd/logind.conf:
s/^[Login]/[Login]\nReserveVT=1\n/
' \
$upload \
$extra_args \
"${passthru[@]}" \
$final_args
# We have to do this so the cleanup() handler runs.
exit $?
virt-p2v-1.42.3/PaxHeaders/COPYING.LIB 0000644 0000000 0000000 00000000132 14205675260 014017 x ustar 00 30 mtime=1645705904.587187577
30 atime=1665494789.828055985
30 ctime=1665495228.418332726
virt-p2v-1.42.3/COPYING.LIB 0000644 0001750 0001750 00000063642 14205675260 015636 0 ustar 00rjones rjones 0000000 0000000 GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
Copyright (C)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
virt-p2v-1.42.3/PaxHeaders/test-virt-p2v-docs.sh 0000644 0000000 0000000 00000000132 14205675260 016307 x ustar 00 30 mtime=1645705904.595187498
30 atime=1665478273.214549561
30 ctime=1665495228.439332591
virt-p2v-1.42.3/test-virt-p2v-docs.sh 0000755 0001750 0001750 00000001432 14205675260 020116 0 ustar 00rjones rjones 0000000 0000000 #!/bin/bash -
# libguestfs
# Copyright (C) 2016 Red Hat Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
set -e
$TEST_FUNCTIONS
skip_if_skipped
$top_srcdir/podcheck.pl $srcdir/virt-p2v.pod virt-p2v
virt-p2v-1.42.3/PaxHeaders/subdir-rules.mk 0000644 0000000 0000000 00000000132 14205675260 015330 x ustar 00 30 mtime=1645705904.595187498
30 atime=1665478158.826227022
30 ctime=1665495228.415332744
virt-p2v-1.42.3/subdir-rules.mk 0000644 0001750 0001750 00000004125 14205675260 017136 0 ustar 00rjones rjones 0000000 0000000 # libguestfs
# Copyright (C) 2013 Red Hat Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# subdir-rules.mk should be included in every *subdirectory* Makefile.am.
# Editor backup files
CLEANFILES = *~ *.bak
# Patch original and reject files.
CLEANFILES += *.orig *.rej
# Manual pages - these are all generated from *.pod, so the
# pages themselves should all be removed by 'make clean'.
CLEANFILES += *.1 *.3 *.5 *.8
# Stamp files used when generating man pages.
CLEANFILES += stamp-*.pod
# Files that should be universally removed by 'make distclean'.
DISTCLEANFILES = stamp-*
# custom silent rules
guestfs_am_v_podwrapper = $(guestfs_am_v_podwrapper_@AM_V@)
guestfs_am_v_podwrapper_ = $(guestfs_am_v_podwrapper_@AM_DEFAULT_V@)
guestfs_am_v_podwrapper_0 = @echo " POD " $@;
# Test shell scripts should use '$TEST_FUNCTIONS' to get a predefined
# set of helper functions for running tests (see
# tests/test-functions.sh).
#
# Notes:
#
# (1) This is in fact a single command all on one line. The variables
# are evaluated in test-functions.sh.
#
# (2) We use absolute paths here and in test-functions.sh so that the
# test can change directory freely. But we also include the
# non-absolute values so they can be used by the test script itself.
export TEST_FUNCTIONS := \
source $(abs_top_srcdir)/test-functions.sh \
abs_srcdir="$(abs_srcdir)" \
abs_builddir="$(abs_builddir)" \
top_srcdir="$(top_srcdir)" \
top_builddir="$(top_builddir)" \
abs_top_srcdir="$(abs_top_srcdir)" \
abs_top_builddir="$(abs_top_builddir)"
virt-p2v-1.42.3/PaxHeaders/aclocal.m4 0000644 0000000 0000000 00000000132 14321227016 014206 x ustar 00 30 mtime=1665478158.271230296
30 atime=1665478158.371229706
30 ctime=1665495228.401332834
virt-p2v-1.42.3/aclocal.m4 0000644 0001750 0001750 00000153535 14321227016 016026 0 ustar 00rjones rjones 0000000 0000000 # generated automatically by aclocal 1.16.5 -*- Autoconf -*-
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],,
[m4_warning([this file was generated for autoconf 2.71.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 11 (pkg-config-0.29.1)
dnl Copyright © 2004 Scott James Remnant .
dnl Copyright © 2012-2015 Dan Nicholson
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dnl General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
dnl 02111-1307, USA.
dnl
dnl As a special exception to the GNU General Public License, if you
dnl distribute this file as part of a program that contains a
dnl configuration script generated by Autoconf, you may include it under
dnl the same distribution terms that you use for the rest of that
dnl program.
dnl PKG_PREREQ(MIN-VERSION)
dnl -----------------------
dnl Since: 0.29
dnl
dnl Verify that the version of the pkg-config macros are at least
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
dnl installed version of pkg-config, this checks the developer's version
dnl of pkg.m4 when generating configure.
dnl
dnl To ensure that this macro is defined, also add:
dnl m4_ifndef([PKG_PREREQ],
dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.1])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
dnl ----------------------------------
dnl Since: 0.16
dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
dnl first found in the path. Checks that the version of pkg-config found
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
dnl used since that's the first version where most current features of
dnl pkg-config existed.
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=m4_default([$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])dnl PKG_PROG_PKG_CONFIG
dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------------------------------
dnl Since: 0.18
dnl
dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_default([$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
dnl ---------------------------------------------
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
dnl pkg_failed based on the result.
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes ],
[pkg_failed=yes])
else
pkg_failed=untried
fi[]dnl
])dnl _PKG_CONFIG
dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl ---------------------------
dnl Internal check to see if pkg-config supports short errors.
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi[]dnl
])dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl --------------------------------------------------------------
dnl Since: 0.4.0
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
_PKG_TEXT
To get pkg-config, see .])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
fi[]dnl
])dnl PKG_CHECK_MODULES
dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl ---------------------------------------------------------------------
dnl Since: 0.29
dnl
dnl Checks for existence of MODULES and gathers its build flags with
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
dnl and VARIABLE-PREFIX_LIBS from --libs.
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
dnl configure.ac.
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
_save_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
PKG_CHECK_MODULES($@)
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
])dnl PKG_CHECK_MODULES_STATIC
dnl PKG_INSTALLDIR([DIRECTORY])
dnl -------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable pkgconfigdir as the location where a module
dnl should install pkg-config .pc files. By default the directory is
dnl $libdir/pkgconfig, but the default can be changed by passing
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
dnl parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([pkgconfigdir],
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
[with_pkgconfigdir=]pkg_default)
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_INSTALLDIR
dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
dnl --------------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
dnl module should install arch-independent pkg-config .pc files. By
dnl default the directory is $datadir/pkgconfig, but the default can be
dnl changed by passing DIRECTORY. The user can override through the
dnl --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([noarch-pkgconfigdir],
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
[with_noarch_pkgconfigdir=]pkg_default)
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_NOARCH_INSTALLDIR
dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------
dnl Since: 0.28
dnl
dnl Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR
dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
dnl [DESCRIPTION], [DEFAULT])
dnl ------------------------------------------
dnl
dnl Prepare a "--with-" configure option using the lowercase
dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
dnl PKG_CHECK_MODULES in a single macro.
AC_DEFUN([PKG_WITH_MODULES],
[
m4_pushdef([with_arg], m4_tolower([$1]))
m4_pushdef([description],
[m4_default([$5], [build with ]with_arg[ support])])
m4_pushdef([def_arg], [m4_default([$6], [auto])])
m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])
m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])
m4_case(def_arg,
[yes],[m4_pushdef([with_without], [--without-]with_arg)],
[m4_pushdef([with_without],[--with-]with_arg)])
AC_ARG_WITH(with_arg,
AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,
[AS_TR_SH([with_]with_arg)=def_arg])
AS_CASE([$AS_TR_SH([with_]with_arg)],
[yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
[auto],[PKG_CHECK_MODULES([$1],[$2],
[m4_n([def_action_if_found]) $3],
[m4_n([def_action_if_not_found]) $4])])
m4_popdef([with_arg])
m4_popdef([description])
m4_popdef([def_arg])
])dnl PKG_WITH_MODULES
dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [DESCRIPTION], [DEFAULT])
dnl -----------------------------------------------
dnl
dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
dnl check._[VARIABLE-PREFIX] is exported as make variable.
AC_DEFUN([PKG_HAVE_WITH_MODULES],
[
PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
AM_CONDITIONAL([HAVE_][$1],
[test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
])dnl PKG_HAVE_WITH_MODULES
dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [DESCRIPTION], [DEFAULT])
dnl ------------------------------------------------------
dnl
dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
dnl and preprocessor variable.
AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
[
PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
[AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
])dnl PKG_HAVE_DEFINE_WITH_MODULES
# Copyright (C) 2002-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.16'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.16.5], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
# _AM_AUTOCONF_VERSION(VERSION)
# -----------------------------
# aclocal traces this macro to find the Autoconf version.
# This is a private macro too. Using m4_define simplifies
# the logic in aclocal, which can simply ignore this definition.
m4_define([_AM_AUTOCONF_VERSION], [])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.16.5])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
# therefore $ac_aux_dir as well) can be either absolute or relative,
# depending on how configure is run. This is pretty annoying, since
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
# source directory, any form will work fine, but in subdirectories a
# relative path needs to be adjusted first.
#
# $ac_aux_dir/missing
# fails when called from a subdirectory if $ac_aux_dir is relative
# $top_srcdir/$ac_aux_dir/missing
# fails if $ac_aux_dir is absolute,
# fails when called from a subdirectory in a VPATH build with
# a relative $ac_aux_dir
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
# harmless because $srcdir is '.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
# and then we would define $MISSING as
# MISSING="\${SHELL} $am_aux_dir/missing"
# This will work as long as MISSING is not called from configure, because
# unfortunately $(top_srcdir) has no meaning in configure.
# However there are other variables, like CC, which are often used in
# configure, and could therefore not use this "fixed" $ac_aux_dir.
#
# Another solution, used here, is to always expand $ac_aux_dir to an
# absolute PATH. The drawback is that using absolute paths prevent a
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
# Expand $ac_aux_dir to an absolute path.
am_aux_dir=`cd "$ac_aux_dir" && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
[AC_PREREQ([2.52])dnl
m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])dnl
AC_SUBST([$1_FALSE])dnl
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
m4_define([_AM_COND_VALUE_$1], [$2])dnl
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
AC_MSG_ERROR([[conditional "$1" was never defined.
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
[$1], [CXX], [depcc="$CXX" am_compiler_list=],
[$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
[$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
[$1], [UPC], [depcc="$UPC" am_compiler_list=],
[$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
[depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named 'D' -- because '-MD' means "put the output
# in D".
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
# We will build objects and dependencies in a subdirectory because
# it helps to detect inapplicable dependency modes. For instance
# both Tru64's cc and ICC support -MD to output dependencies as a
# side effect of compilation, but ICC will put the dependencies in
# the current directory while Tru64 will put them in the object
# directory.
mkdir sub
am_cv_$1_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
fi
am__universal=false
m4_case([$1], [CC],
[case " $depcc " in #(
*\ -arch\ *\ -arch\ *) am__universal=true ;;
esac],
[CXX],
[case " $depcc " in #(
*\ -arch\ *\ -arch\ *) am__universal=true ;;
esac])
for depmode in $am_compiler_list; do
# Setup a source with many dependencies, because some compilers
# like to wrap large dependency lists on column 80 (with \), and
# we should not choose a depcomp mode which is confused by this.
#
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
# Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
# Solaris 10 /bin/sh.
echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
# We check with '-c' and '-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
# handle '-M -o', and we need to detect this. Also, some Intel
# versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
gcc)
# This depmode causes a compiler race in universal mode.
test "$am__universal" = false || continue
;;
nosideeffect)
# After this tag, mechanisms are not by side-effect, so they'll
# only be used when explicitly requested.
if test "x$enable_dependency_tracking" = xyes; then
continue
else
break
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
# This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
am__minus_obj=
;;
none) break ;;
esac
if depmode=$depmode \
source=sub/conftest.c object=$am__obj \
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
$SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
>/dev/null 2>conftest.err &&
grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
# icc doesn't choke on unknown options, it will just issue warnings
# or remarks (even with -Werror). So we grep stderr for any message
# that says an option was ignored or not supported.
# When given -MP, icc 7.0 and 7.1 complain thusly:
# icc: Command line warning: ignoring option '-M'; no argument required
# The diagnosis changed in icc 8.0:
# icc: Command line remark: option '-MP' not supported
if (grep 'ignoring option' conftest.err ||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
am_cv_$1_dependencies_compiler_type=$depmode
break
fi
fi
done
cd ..
rm -rf conftest.dir
else
am_cv_$1_dependencies_compiler_type=none
fi
])
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
AM_CONDITIONAL([am__fastdep$1], [
test "x$enable_dependency_tracking" != xno \
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
])
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
])
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE([dependency-tracking], [dnl
AS_HELP_STRING(
[--enable-dependency-tracking],
[do not reject slow dependency extractors])
AS_HELP_STRING(
[--disable-dependency-tracking],
[speeds up one-time build])])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
am__nodep='_no'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])dnl
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
AC_SUBST([am__nodep])dnl
_AM_SUBST_NOTMAKE([am__nodep])dnl
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[{
# Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
# TODO: see whether this extra hack can be removed once we start
# requiring Autoconf 2.70 or later.
AS_CASE([$CONFIG_FILES],
[*\'*], [eval set x "$CONFIG_FILES"],
[*], [set x $CONFIG_FILES])
shift
# Used to flag and report bootstrapping failures.
am_rc=0
for am_mf
do
# Strip MF so we end up with the name of the file.
am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile which includes
# dependency-tracking related rules and includes.
# Grep'ing the whole file directly is not great: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
|| continue
am_dirpart=`AS_DIRNAME(["$am_mf"])`
am_filepart=`AS_BASENAME(["$am_mf"])`
AM_RUN_LOG([cd "$am_dirpart" \
&& sed -e '/# am--include-marker/d' "$am_filepart" \
| $MAKE -f - am--depfiles]) || am_rc=$?
done
if test $am_rc -ne 0; then
AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
for automatic dependency tracking. If GNU make was not used, consider
re-running the configure script with MAKE="gmake" (or whatever is
necessary). You can also try re-running configure with the
'--disable-dependency-tracking' option to at least be able to build
the package (albeit without support for automatic dependency tracking).])
fi
AS_UNSET([am_dirpart])
AS_UNSET([am_filepart])
AS_UNSET([am_mf])
AS_UNSET([am_rc])
rm -f conftest-deps.mk
}
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
# AM_OUTPUT_DEPENDENCY_COMMANDS
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking is enabled.
# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
# order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
m4_define([AC_PROG_CC],
m4_defn([AC_PROG_CC])
[_AM_PROG_CC_C_O
])
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
# The call with PACKAGE and VERSION arguments is the old style
# call (pre autoconf-2.50), which is being phased out. PACKAGE
# and VERSION should now be passed to AC_INIT and removed from
# the call to AM_INIT_AUTOMAKE.
# We support both call styles for the transition. After
# the next Automake release, Autoconf can make the AC_INIT
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_PREREQ([2.65])dnl
m4_ifdef([_$0_ALREADY_INIT],
[m4_fatal([$0 expanded multiple times
]m4_defn([_$0_ALREADY_INIT]))],
[m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
if test "`cd $srcdir && pwd`" != "`pwd`"; then
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
# is not polluted with repeated "-I."
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
# test to see if srcdir already configured
if test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
fi
# test whether we have cygpath
if test -z "$CYGPATH_W"; then
if (cygpath --version) >/dev/null 2>/dev/null; then
CYGPATH_W='cygpath -w'
else
CYGPATH_W=echo
fi
fi
AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[AC_DIAGNOSE([obsolete],
[$0: two- and three-arguments forms are deprecated.])
m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
m4_if(
m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]),
[ok:ok],,
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
AM_MISSING_PROG([AUTOCONF], [autoconf])
AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
AM_MISSING_PROG([AUTOHEADER], [autoheader])
AM_MISSING_PROG([MAKEINFO], [makeinfo])
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
# For better backward compatibility. To be removed once Automake 1.9.x
# dies out for good. For more background, see:
#
#
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
# We need awk for the "check" target (and possibly the TAP driver). The
# system "awk" is bad on some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
[_AM_PROG_TAR([v7])])])
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
[_AM_DEPENDENCIES([CC])],
[m4_define([AC_PROG_CC],
m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
[_AM_DEPENDENCIES([CXX])],
[m4_define([AC_PROG_CXX],
m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
[_AM_DEPENDENCIES([OBJC])],
[m4_define([AC_PROG_OBJC],
m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
[_AM_DEPENDENCIES([OBJCXX])],
[m4_define([AC_PROG_OBJCXX],
m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
])
# Variables for tags utilities; see am/tags.am
if test -z "$CTAGS"; then
CTAGS=ctags
fi
AC_SUBST([CTAGS])
if test -z "$ETAGS"; then
ETAGS=etags
fi
AC_SUBST([ETAGS])
if test -z "$CSCOPE"; then
CSCOPE=cscope
fi
AC_SUBST([CSCOPE])
AC_REQUIRE([AM_SILENT_RULES])dnl
dnl The testsuite driver may need to know about EXEEXT, so add the
dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
# POSIX will say in a future version that running "rm -f" with no argument
# is OK; and we want to be able to make that assumption in our Makefile
# recipes. So use an aggressive probe to check that the usage we want is
# actually supported "in the wild" to an acceptable degree.
# See automake bug#10828.
# To make any issue more visible, cause the running configure to be aborted
# by default if the 'rm' program in use doesn't match our expectations; the
# user can still override this though.
if rm -f && rm -fr && rm -rf; then : OK; else
cat >&2 <<'END'
Oops!
Your 'rm' program seems unable to run without file operands specified
on the command line, even when the '-f' option is present. This is contrary
to the behaviour of most rm programs out there, and not conforming with
the upcoming POSIX standard:
Please tell bug-automake@gnu.org about your system, including the value
of your $PATH and any error possibly output before this message. This
can help us improve future automake versions.
END
if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
echo 'Configuration will proceed anyway, since you have set the' >&2
echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
echo >&2
else
cat >&2 <<'END'
Aborting the configuration process, to ensure you take notice of the issue.
You can download and install GNU coreutils to get an 'rm' implementation
that behaves properly: .
If you want to complete the configuration process using your problematic
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
to "yes", and re-run configure.
END
AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
fi
fi
dnl The trailing newline in this macro's definition is deliberate, for
dnl backward compatibility and to allow trailing 'dnl'-style comments
dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
])
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
dnl mangled by Autoconf and run in a shell conditional statement.
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[# Compute $1's index in $config_headers.
_am_arg=$1
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
$_am_arg | $_am_arg:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
if test x"${install_sh+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
*)
install_sh="\${SHELL} $am_aux_dir/install-sh"
esac
fi
AC_SUBST([install_sh])])
# Copyright (C) 2003-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Check whether the underlying file-system supports filenames
# with a leading dot. For instance MS-DOS doesn't.
AC_DEFUN([AM_SET_LEADING_DOT],
[rm -rf .tst 2>/dev/null
mkdir .tst 2>/dev/null
if test -d .tst; then
am__leading_dot=.
else
am__leading_dot=_
fi
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_MAKE_INCLUDE()
# -----------------
# Check whether make has an 'include' directive that can support all
# the idioms we need for our automatic dependency tracking code.
AC_DEFUN([AM_MAKE_INCLUDE],
[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
cat > confinc.mk << 'END'
am__doit:
@echo this is the am__doit target >confinc.out
.PHONY: am__doit
END
am__include="#"
am__quote=
# BSD make does it like this.
echo '.include "confinc.mk" # ignored' > confmf.BSD
# Other make implementations (GNU, Solaris 10, AIX) do it like this.
echo 'include confinc.mk # ignored' > confmf.GNU
_am_result=no
for s in GNU BSD; do
AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
AS_CASE([$?:`cat confinc.out 2>/dev/null`],
['0:this is the am__doit target'],
[AS_CASE([$s],
[BSD], [am__include='.include' am__quote='"'],
[am__include='include' am__quote=''])])
if test "$am__include" != "#"; then
_am_result="yes ($s style)"
break
fi
done
rm -f confinc.* confmf.*
AC_MSG_RESULT([${_am_result}])
AC_SUBST([am__include])])
AC_SUBST([am__quote])])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it is modern enough.
# If it is, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
if test x"${MISSING+set}" != xset; then
MISSING="\${SHELL} '$am_aux_dir/missing'"
fi
# Use eval to expand $SHELL
if eval "$MISSING --is-lightweight"; then
am_missing_run="$MISSING "
else
am_missing_run=
AC_MSG_WARN(['missing' script is too old or missing])
fi
])
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
# --------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
# _AM_SET_OPTIONS(OPTIONS)
# ------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# _AM_PROG_CC_C_O
# ---------------
# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
# to automatically call this.
AC_DEFUN([_AM_PROG_CC_C_O],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([compile])dnl
AC_LANG_PUSH([C])dnl
AC_CACHE_CHECK(
[whether $CC understands -c and -o together],
[am_cv_prog_cc_c_o],
[AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
# Make sure it works both with $CC and with simple cc.
# Following AC_PROG_CC_C_O, we do the test twice because some
# compilers refuse to overwrite an existing .o file with -o,
# though they will create one.
am_cv_prog_cc_c_o=yes
for am_i in 1 2; do
if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
&& test -f conftest2.$ac_objext; then
: OK
else
am_cv_prog_cc_c_o=no
break
fi
done
rm -f core conftest*
unset am_i])
if test "$am_cv_prog_cc_c_o" != yes; then
# Losing compiler, so override with the script.
# FIXME: It is wrong to rewrite CC.
# But if we don't then we get into trouble of one sort or another.
# A longer-term fix would be to have automake use am__CC in this case,
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
CC="$am_aux_dir/compile $CC"
fi
AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_RUN_LOG(COMMAND)
# -------------------
# Run COMMAND, save the exit status in ac_status, and log it.
# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
AC_DEFUN([AM_RUN_LOG],
[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
(exit $ac_status); }])
# Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
'
case `pwd` in
*[[\\\"\#\$\&\'\`$am_lf]]*)
AC_MSG_ERROR([unsafe absolute working directory name]);;
esac
case $srcdir in
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
esac
# Do 'set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
am_has_slept=no
for am_try in 1 2; do
echo "timestamp, slept: $am_has_slept" > conftest.file
set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
if test "$[*]" = "X"; then
# -L didn't work.
set X `ls -t "$srcdir/configure" conftest.file`
fi
if test "$[*]" != "X $srcdir/configure conftest.file" \
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
if test "$[2]" = conftest.file || test $am_try -eq 2; then
break
fi
# Just in case.
sleep 1
am_has_slept=yes
done
test "$[2]" = conftest.file
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT([yes])
# If we didn't sleep, we still need to ensure time stamps of config.status and
# generated files are strictly newer.
am_sleep_pid=
if grep 'slept: no' conftest.file >/dev/null 2>&1; then
( sleep 1 ) &
am_sleep_pid=$!
fi
AC_CONFIG_COMMANDS_PRE(
[AC_MSG_CHECKING([that generated files are newer than configure])
if test -n "$am_sleep_pid"; then
# Hide warnings about reused PIDs.
wait $am_sleep_pid 2>/dev/null
fi
AC_MSG_RESULT([done])])
rm -f conftest.file
])
# Copyright (C) 2009-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_SILENT_RULES([DEFAULT])
# --------------------------
# Enable less verbose build rules; with the default set to DEFAULT
# ("yes" being less verbose, "no" or empty being verbose).
AC_DEFUN([AM_SILENT_RULES],
[AC_ARG_ENABLE([silent-rules], [dnl
AS_HELP_STRING(
[--enable-silent-rules],
[less verbose build output (undo: "make V=1")])
AS_HELP_STRING(
[--disable-silent-rules],
[verbose build output (undo: "make V=0")])dnl
])
case $enable_silent_rules in @%:@ (((
yes) AM_DEFAULT_VERBOSITY=0;;
no) AM_DEFAULT_VERBOSITY=1;;
*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
esac
dnl
dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
dnl do not support nested variable expansions.
dnl See automake bug#9928 and bug#10237.
am_make=${MAKE-make}
AC_CACHE_CHECK([whether $am_make supports nested variables],
[am_cv_make_support_nested_variables],
[if AS_ECHO([['TRUE=$(BAR$(V))
BAR0=false
BAR1=true
V=1
am__doit:
@$(TRUE)
.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
am_cv_make_support_nested_variables=yes
else
am_cv_make_support_nested_variables=no
fi])
if test $am_cv_make_support_nested_variables = yes; then
dnl Using '$V' instead of '$(V)' breaks IRIX make.
AM_V='$(V)'
AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
else
AM_V=$AM_DEFAULT_VERBOSITY
AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
fi
AC_SUBST([AM_V])dnl
AM_SUBST_NOTMAKE([AM_V])dnl
AC_SUBST([AM_DEFAULT_V])dnl
AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
AM_BACKSLASH='\'
AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_INSTALL_STRIP
# ---------------------
# One issue with vendor 'install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in "make install-strip", and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
# Installed binaries are usually stripped using 'strip' when the user
# run "make install-strip". However 'strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
# will honor the 'STRIP' environment variable to overrule this program.
dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
# This macro is traced by Automake.
AC_DEFUN([_AM_SUBST_NOTMAKE])
# AM_SUBST_NOTMAKE(VARIABLE)
# --------------------------
# Public sister of _AM_SUBST_NOTMAKE.
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# _AM_PROG_TAR(FORMAT)
# --------------------
# Check how to create a tarball in format FORMAT.
# FORMAT should be one of 'v7', 'ustar', or 'pax'.
#
# Substitute a variable $(am__tar) that is a command
# writing to stdout a FORMAT-tarball containing the directory
# $tardir.
# tardir=directory && $(am__tar) > result.tar
#
# Substitute a variable $(am__untar) that extract such
# a tarball read from stdin.
# $(am__untar) < result.tar
#
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AC_SUBST([AMTAR], ['$${TAR-tar}'])
# We'll loop over all known methods to create a tar archive until one works.
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
m4_if([$1], [v7],
[am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
[m4_case([$1],
[ustar],
[# The POSIX 1988 'ustar' format is defined with fixed-size fields.
# There is notably a 21 bits limit for the UID and the GID. In fact,
# the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
# and bug#13588).
am_max_uid=2097151 # 2^21 - 1
am_max_gid=$am_max_uid
# The $UID and $GID variables are not portable, so we need to resort
# to the POSIX-mandated id(1) utility. Errors in the 'id' calls
# below are definitely unexpected, so allow the users to see them
# (that is, avoid stderr redirection).
am_uid=`id -u || echo unknown`
am_gid=`id -g || echo unknown`
AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
if test $am_uid -le $am_max_uid; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
_am_tools=none
fi
AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
if test $am_gid -le $am_max_gid; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
_am_tools=none
fi],
[pax],
[],
[m4_fatal([Unknown tar format])])
AC_MSG_CHECKING([how to create a $1 tar archive])
# Go ahead even if we have the value already cached. We do so because we
# need to set the values for the 'am__tar' and 'am__untar' variables.
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
for _am_tool in $_am_tools; do
case $_am_tool in
gnutar)
for _am_tar in tar gnutar gtar; do
AM_RUN_LOG([$_am_tar --version]) && break
done
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
am__untar="$_am_tar -xf -"
;;
plaintar)
# Must skip GNU tar: if it does not support --format= it doesn't create
# ustar tarball either.
(tar --version) >/dev/null 2>&1 && continue
am__tar='tar chf - "$$tardir"'
am__tar_='tar chf - "$tardir"'
am__untar='tar xf -'
;;
pax)
am__tar='pax -L -x $1 -w "$$tardir"'
am__tar_='pax -L -x $1 -w "$tardir"'
am__untar='pax -r'
;;
cpio)
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
am__untar='cpio -i -H $1 -d'
;;
none)
am__tar=false
am__tar_=false
am__untar=false
;;
esac
# If the value was cached, stop now. We just wanted to have am__tar
# and am__untar set.
test -n "${am_cv_prog_tar_$1}" && break
# tar/untar a dummy directory, and stop if the command works.
rm -rf conftest.dir
mkdir conftest.dir
echo GrepMe > conftest.dir/file
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
rm -rf conftest.dir
if test -s conftest.tar; then
AM_RUN_LOG([$am__untar /dev/null 2>&1 && break
fi
done
rm -rf conftest.dir
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
m4_include([m4/libtool.m4])
m4_include([m4/ltoptions.m4])
m4_include([m4/ltsugar.m4])
m4_include([m4/ltversion.m4])
m4_include([m4/lt~obsolete.m4])
virt-p2v-1.42.3/PaxHeaders/cpuid.c 0000644 0000000 0000000 00000000130 14314553633 013625 x ustar 00 29 mtime=1664276379.71730762
29 atime=1665478120.02946287
30 ctime=1665495228.426332674
virt-p2v-1.42.3/cpuid.c 0000644 0001750 0001750 00000012317 14314553633 015437 0 ustar 00rjones rjones 0000000 0000000 /* virt-p2v
* Copyright (C) 2009-2019 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/**
* Find CPU vendor, topology and some CPU flags.
*
* lscpu (from util-linux) provides CPU vendor, topology and flags.
*
* ACPI can be read by seeing if F exists.
*
* CPU model is essentially impossible to get without using libvirt,
* but we cannot use libvirt for the reasons outlined in this message:
* https://www.redhat.com/archives/libvirt-users/2017-March/msg00071.html
*
* Note that #vCPUs and amount of RAM is handled by F.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "ignore-value.h"
#include "p2v.h"
static void
free_cpu_config (struct cpu_config *cpu)
{
if (cpu->vendor)
free (cpu->vendor);
if (cpu->model)
free (cpu->model);
memset (cpu, 0, sizeof *cpu);
}
/**
* Get the output of lscpu as a list of (key, value) pairs (as a
* flattened list of strings).
*/
static char **
get_lscpu (void)
{
const char *cmd;
CLEANUP_PCLOSE FILE *fp = NULL;
CLEANUP_FREE char *line = NULL;
ssize_t len;
size_t buflen = 0;
char **ret = NULL;
size_t ret_size = 0;
cmd = "lscpu";
fp = popen (cmd, "re");
if (fp == NULL) {
perror (cmd);
return NULL;
}
ret = malloc (sizeof (char *));
if (ret == NULL) error (EXIT_FAILURE, errno, "malloc");
ret[0] = NULL;
while (errno = 0, (len = getline (&line, &buflen, fp)) != -1) {
char *p;
char *key, *value;
if (len > 0 && line[len-1] == '\n')
line[len-1] = '\0';
/* Split the line at the first ':' character. */
p = strchr (line, ':');
if (p == NULL)
continue;
*p = '\0';
key = strdup (line);
/* Skip leading whitespace in the value. */
for (++p; *p && g_ascii_isspace (*p); ++p)
;
value = strdup (p);
/* Add key and value to the list, and trailing NULL pointer. */
ret_size += 2;
ret = realloc (ret, (ret_size + 1) * sizeof (char *));
if (ret == NULL) error (EXIT_FAILURE, errno, "realloc");
ret[ret_size-2] = key;
ret[ret_size-1] = value;
ret[ret_size] = NULL;
}
if (errno) {
perror (cmd);
guestfs_int_free_string_list (ret);
return NULL;
}
return ret;
}
/**
* Read a single field from lscpu output.
*
* If the field does not exist, returns C.
*/
static const char *
get_field (char **lscpu, const char *key)
{
size_t i;
for (i = 0; lscpu[i] != NULL; i += 2) {
if (STREQ (lscpu[i], key))
return lscpu[i+1];
}
return NULL;
}
/**
* Read the CPU vendor from lscpu output.
*/
static void
get_vendor (char **lscpu, struct cpu_config *cpu)
{
const char *vendor = get_field (lscpu, "Vendor ID");
if (vendor) {
/* Note this mapping comes from /usr/share/libvirt/cpu_map.xml */
if (STREQ (vendor, "GenuineIntel"))
cpu->vendor = strdup ("Intel");
else if (STREQ (vendor, "AuthenticAMD"))
cpu->vendor = strdup ("AMD");
/* Currently aarch64 lscpu has no Vendor ID XXX. */
}
}
/**
* Read the CPU topology from a separate lscpu invocation.
*/
void
get_cpu_topology (struct cpu_topo *topo)
{
CLEANUP_FREE_STRING_LIST char **lscpu = NULL;
lscpu = get_lscpu ();
if (lscpu != NULL) {
const char *sockets, *cores, *threads;
sockets = get_field (lscpu, "Socket(s)");
cores = get_field (lscpu, "Core(s) per socket");
threads = get_field (lscpu, "Thread(s) per core");
if (sockets && cores && threads) {
ignore_value (sscanf (sockets, "%u", &topo->sockets));
ignore_value (sscanf (cores, "%u", &topo->cores));
ignore_value (sscanf (threads, "%u", &topo->threads));
return;
}
}
topo->sockets = 1;
topo->cores = 1;
topo->threads = 1;
}
/**
* Read some important flags from lscpu output.
*/
static void
get_flags (char **lscpu, struct cpu_config *cpu)
{
const char *flags;
flags = get_field (lscpu, "Flags");
if (flags) {
cpu->apic = strstr (flags, " apic ") != NULL;
cpu->pae = strstr (flags, " pae ") != NULL;
/* aarch64 /proc/cpuinfo has a "Features" field, but lscpu does
* not expose it. However aarch64 Features does not contain any
* of the interesting flags above.
*/
}
}
/**
* Find out if the system uses ACPI.
*/
static void
get_acpi (struct cpu_config *cpu)
{
cpu->acpi = access ("/sys/firmware/acpi", F_OK) == 0;
}
void
get_cpu_config (struct cpu_config *cpu)
{
CLEANUP_FREE_STRING_LIST char **lscpu = NULL;
free_cpu_config (cpu);
lscpu = get_lscpu ();
if (lscpu != NULL) {
get_vendor (lscpu, cpu);
get_flags (lscpu, cpu);
}
get_acpi (cpu);
}
virt-p2v-1.42.3/PaxHeaders/gui.c 0000644 0000000 0000000 00000000132 14321226753 013305 x ustar 00 30 mtime=1665478123.019444281
30 atime=1665478123.022444263
30 ctime=1665495228.428332661
virt-p2v-1.42.3/gui.c 0000644 0001750 0001750 00000234714 14321226753 015124 0 ustar 00rjones rjones 0000000 0000000 /* virt-p2v
* Copyright (C) 2009-2019 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/**
* This file implements almost all of the virt-p2v graphical user
* interface (GUI).
*
* The GUI has three main dialogs:
*
* =over 4
*
* =item Connection dialog
*
* The connection dialog is the one shown initially. It asks the user
* to type in the login details for the remote conversion server and
* invites the user to test the ssh connection.
*
* =item Conversion dialog
*
* The conversion dialog asks for information about the target VM
* (eg. the number of vCPUs required), and about what to convert
* (eg. which network interfaces should be copied and which should be
* ignored).
*
* =item Running dialog
*
* The running dialog is displayed when the P2V process is underway.
* It mainly displays the virt-v2v debug messages.
*
* =back
*
* Note that the other major dialog (C<"Configure network ...">) is
* handled entirely by NetworkManager's L
* program and has nothing to do with this code.
*
* This file is written in a kind of "pseudo-Gtk" that currently targets Gtk
* 3.22 exclusively, but may later be extended to a broader Gtk version range.
* This is done using a few macros to implement old C functions or map
* them to newer functions.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* errors in */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
#if defined(__GNUC__) && __GNUC__ >= 6 /* gcc >= 6 */
#pragma GCC diagnostic ignored "-Wshift-overflow"
#endif
#include
#pragma GCC diagnostic pop
#include "ignore-value.h"
#include "p2v.h"
/* See note about "pseudo-Gtk" above. */
#include "gui-gtk3-compat.h"
/* Maximum vCPUs and guest memory that we will allow users to set.
* These limits come from
* https://access.redhat.com/articles/rhel-kvm-limits
*/
#define MAX_SUPPORTED_VCPUS 160
#define MAX_SUPPORTED_MEMORY_MB (UINT64_C (4000 * 1024))
static void create_connection_dialog (struct config *);
static void create_conversion_dialog (struct config *config,
const char * const *disks,
const char * const *removable);
static void create_running_dialog (void);
static void show_connection_dialog (void);
static void show_conversion_dialog (void);
static void show_running_dialog (void);
static void set_info_label (void);
/* The connection dialog. */
static GtkWidget *conn_dlg,
*server_entry, *port_entry,
*username_entry, *password_entry, *identity_entry, *sudo_button,
*spinner_hbox,
*spinner,
*spinner_message, *next_button;
/* The conversion dialog. */
static GtkWidget *conv_dlg,
*guestname_entry, *vcpu_topo, *vcpus_entry, *memory_entry,
*vcpus_warning, *memory_warning, *target_warning_label,
*o_combo, *oc_entry, *os_entry, *of_entry, *oa_combo,
*info_label,
*disks_list, *removable_list, *interfaces_list;
static int vcpus_entry_when_last_sensitive;
/* The running dialog which is displayed when virt-v2v is running. */
static GtkWidget *run_dlg,
*v2v_output_sw, *v2v_output, *log_label, *status_label,
*cancel_button, *shutdown_button;
/* Colour tags used in the v2v_output GtkTextBuffer. */
static GtkTextTag *v2v_output_tags[16];
/**
* The entry point from the main program.
*
* Note that C etc have already been called in C.
*/
void
gui_conversion (struct config *config,
const char * const *disks,
const char * const *removable)
{
/* Create the dialogs. */
create_connection_dialog (config);
create_conversion_dialog (config, disks, removable);
create_running_dialog ();
/* Start by displaying the connection dialog. */
show_connection_dialog ();
gtk_main ();
}
/*----------------------------------------------------------------------*/
/* Connection dialog. */
static void username_changed_callback (GtkWidget *w, gpointer data);
static void password_or_identity_changed_callback (GtkWidget *w, gpointer data);
static void test_connection_clicked (GtkWidget *w, gpointer data);
static void *test_connection_thread (void *data);
static gboolean start_spinner (gpointer user_data);
static gboolean stop_spinner (gpointer user_data);
static gboolean test_connection_error (gpointer user_data);
static gboolean test_connection_ok (gpointer user_data);
static void configure_network_button_clicked (GtkWidget *w, gpointer data);
static void xterm_button_clicked (GtkWidget *w, gpointer data);
static void about_button_clicked (GtkWidget *w, gpointer data);
static void connection_next_clicked (GtkWidget *w, gpointer data);
static void repopulate_output_combo (struct config *config);
/**
* Create the connection dialog.
*
* This creates the dialog, but it is not displayed. See
* C.
*/
static void
create_connection_dialog (struct config *config)
{
GtkWidget *intro, *table;
GtkWidget *server_label;
GtkWidget *server_hbox;
GtkWidget *port_colon_label;
GtkWidget *username_label;
GtkWidget *password_label;
GtkWidget *identity_label;
GtkWidget *test_hbox, *test;
GtkWidget *about;
GtkWidget *configure_network;
GtkWidget *xterm;
char port_str[64];
int row;
conn_dlg = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (conn_dlg), g_get_prgname ());
gtk_window_set_resizable (GTK_WINDOW (conn_dlg), FALSE);
/* The main dialog area. */
intro = gtk_label_new (_("Connect to a virt-v2v conversion server over SSH:"));
gtk_label_set_line_wrap (GTK_LABEL (intro), TRUE);
set_padding (intro, 10, 10);
table_new (table, 5, 2);
row = 0;
server_label = gtk_label_new_with_mnemonic (_("Conversion _server:"));
table_attach (table, server_label,
0, 1, row, GTK_FILL, GTK_FILL, 4, 4);
set_alignment (server_label, 1., 0.5);
hbox_new (server_hbox, FALSE, 4);
server_entry = gtk_entry_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (server_label), server_entry);
if (config->remote.server != NULL)
gtk_entry_set_text (GTK_ENTRY (server_entry), config->remote.server);
port_colon_label = gtk_label_new (":");
port_entry = gtk_entry_new ();
gtk_entry_set_width_chars (GTK_ENTRY (port_entry), 6);
snprintf (port_str, sizeof port_str, "%d", config->remote.port);
gtk_entry_set_text (GTK_ENTRY (port_entry), port_str);
gtk_box_pack_start (GTK_BOX (server_hbox), server_entry, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (server_hbox), port_colon_label, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (server_hbox), port_entry, FALSE, FALSE, 0);
table_attach (table, server_hbox,
1, 2, row, GTK_EXPAND|GTK_FILL, GTK_FILL, 4, 4);
row++;
username_label = gtk_label_new_with_mnemonic (_("_User name:"));
table_attach (table, username_label,
0, 1, row, GTK_FILL, GTK_FILL, 4, 4);
set_alignment (username_label, 1., 0.5);
username_entry = gtk_entry_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (username_label), username_entry);
if (config->auth.username != NULL)
gtk_entry_set_text (GTK_ENTRY (username_entry), config->auth.username);
else
gtk_entry_set_text (GTK_ENTRY (username_entry), "root");
table_attach (table, username_entry,
1, 2, row, GTK_EXPAND|GTK_FILL, GTK_FILL, 4, 4);
row++;
password_label = gtk_label_new_with_mnemonic (_("_Password:"));
table_attach (table, password_label,
0, 1, row, GTK_FILL, GTK_FILL, 4, 4);
set_alignment (password_label, 1., 0.5);
password_entry = gtk_entry_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (password_label), password_entry);
gtk_entry_set_visibility (GTK_ENTRY (password_entry), FALSE);
gtk_entry_set_input_purpose (GTK_ENTRY (password_entry),
GTK_INPUT_PURPOSE_PASSWORD);
if (config->auth.password != NULL)
gtk_entry_set_text (GTK_ENTRY (password_entry), config->auth.password);
table_attach (table, password_entry,
1, 2, row, GTK_EXPAND|GTK_FILL, GTK_FILL, 4, 4);
row++;
identity_label = gtk_label_new_with_mnemonic (_("SSH _Identity URL:"));
table_attach (table, identity_label,
0, 1, row, GTK_FILL, GTK_FILL, 4, 4);
set_alignment (identity_label, 1., 0.5);
identity_entry = gtk_entry_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (identity_label), identity_entry);
if (config->auth.identity.url != NULL)
gtk_entry_set_text (GTK_ENTRY (identity_entry), config->auth.identity.url);
table_attach (table, identity_entry,
1, 2, row, GTK_EXPAND|GTK_FILL, GTK_FILL, 4, 4);
row++;
sudo_button =
gtk_check_button_new_with_mnemonic (_("Use su_do when running virt-v2v"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sudo_button),
config->auth.sudo);
table_attach (table, sudo_button,
1, 2, row, GTK_FILL, GTK_FILL, 4, 4);
hbox_new (test_hbox, FALSE, 0);
test = gtk_button_new_with_mnemonic (_("_Test connection"));
gtk_box_pack_start (GTK_BOX (test_hbox), test, TRUE, FALSE, 0);
hbox_new (spinner_hbox, FALSE, 10);
spinner = gtk_spinner_new ();
gtk_box_pack_start (GTK_BOX (spinner_hbox), spinner, FALSE, FALSE, 0);
spinner_message = gtk_label_new (NULL);
gtk_label_set_line_wrap (GTK_LABEL (spinner_message), TRUE);
set_padding (spinner_message, 10, 10);
gtk_box_pack_start (GTK_BOX (spinner_hbox), spinner_message, TRUE, TRUE, 0);
gtk_box_pack_start
(GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (conn_dlg))),
intro, TRUE, TRUE, 0);
gtk_box_pack_start
(GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (conn_dlg))),
table, TRUE, TRUE, 0);
gtk_box_pack_start
(GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (conn_dlg))),
test_hbox, FALSE, FALSE, 0);
gtk_box_pack_start
(GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (conn_dlg))),
spinner_hbox, TRUE, TRUE, 0);
/* Buttons. */
gtk_dialog_add_buttons (GTK_DIALOG (conn_dlg),
_("_Configure network ..."), 1,
_("_XTerm ..."), 2,
_("_About virt-p2v " PACKAGE_VERSION " ..."), 3,
_("_Next"), 4,
NULL);
next_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (conn_dlg), 4);
gtk_widget_set_sensitive (next_button, FALSE);
configure_network =
gtk_dialog_get_widget_for_response (GTK_DIALOG (conn_dlg), 1);
xterm = gtk_dialog_get_widget_for_response (GTK_DIALOG (conn_dlg), 2);
about = gtk_dialog_get_widget_for_response (GTK_DIALOG (conn_dlg), 3);
/* Signals. */
g_signal_connect_swapped (G_OBJECT (conn_dlg), "destroy",
G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (G_OBJECT (test), "clicked",
G_CALLBACK (test_connection_clicked), config);
g_signal_connect (G_OBJECT (configure_network), "clicked",
G_CALLBACK (configure_network_button_clicked), NULL);
g_signal_connect (G_OBJECT (xterm), "clicked",
G_CALLBACK (xterm_button_clicked), NULL);
g_signal_connect (G_OBJECT (about), "clicked",
G_CALLBACK (about_button_clicked), NULL);
g_signal_connect (G_OBJECT (next_button), "clicked",
G_CALLBACK (connection_next_clicked), NULL);
g_signal_connect (G_OBJECT (username_entry), "changed",
G_CALLBACK (username_changed_callback), NULL);
g_signal_connect (G_OBJECT (password_entry), "changed",
G_CALLBACK (password_or_identity_changed_callback), NULL);
g_signal_connect (G_OBJECT (identity_entry), "changed",
G_CALLBACK (password_or_identity_changed_callback), NULL);
/* Call this signal to initialize the sensitivity of the sudo
* button correctly.
*/
username_changed_callback (NULL, NULL);
}
/**
* If the username is "root", disable the sudo button.
*/
static void
username_changed_callback (GtkWidget *w, gpointer data)
{
const char *str;
int username_is_root;
int sudo_is_set;
str = gtk_entry_get_text (GTK_ENTRY (username_entry));
username_is_root = str != NULL && STREQ (str, "root");
sudo_is_set = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sudo_button));
/* The sudo button is sensitive if:
* - The username is not "root", or
* - The button is not already checked (to allow the user to uncheck it)
*/
gtk_widget_set_sensitive (sudo_button, !username_is_root || sudo_is_set);
}
/**
* The password or SSH identity URL entries are mutually exclusive, so
* if one contains text then disable the other. This function is
* called when the "changed" signal is received on either.
*/
static void
password_or_identity_changed_callback (GtkWidget *w, gpointer data)
{
const char *str;
int password_set;
int identity_set;
str = gtk_entry_get_text (GTK_ENTRY (password_entry));
password_set = str != NULL && STRNEQ (str, "");
str = gtk_entry_get_text (GTK_ENTRY (identity_entry));
identity_set = str != NULL && STRNEQ (str, "");
if (!password_set && !identity_set) {
gtk_widget_set_sensitive (password_entry, TRUE);
gtk_widget_set_sensitive (identity_entry, TRUE);
}
else if (identity_set)
gtk_widget_set_sensitive (password_entry, FALSE);
else if (password_set)
gtk_widget_set_sensitive (identity_entry, FALSE);
}
/**
* Hide all other dialogs and show the connection dialog.
*/
static void
show_connection_dialog (void)
{
/* Hide the other dialogs. */
gtk_widget_hide (conv_dlg);
gtk_widget_hide (run_dlg);
/* Show everything except the spinner. */
gtk_widget_show_all (conn_dlg);
gtk_widget_hide (spinner_hbox);
}
/**
* Callback from the C button.
*
* This initiates a background thread which actually does the ssh to
* the conversion server and the rest of the testing (see
* C).
*/
static void
test_connection_clicked (GtkWidget *w, gpointer data)
{
struct config *config = data;
const gchar *port_str;
const gchar *identity_str;
size_t errors = 0;
struct config *copy;
int err;
pthread_t tid;
pthread_attr_t attr;
gtk_label_set_text (GTK_LABEL (spinner_message), "");
gtk_widget_show_all (spinner_hbox);
gtk_widget_hide (spinner);
/* Get the fields from the various widgets. */
free (config->remote.server);
config->remote.server = strdup (gtk_entry_get_text (GTK_ENTRY (server_entry)));
if (STREQ (config->remote.server, "")) {
gtk_label_set_text (GTK_LABEL (spinner_message),
_("error: No conversion server given."));
gtk_widget_grab_focus (server_entry);
errors++;
}
port_str = gtk_entry_get_text (GTK_ENTRY (port_entry));
if (sscanf (port_str, "%d", &config->remote.port) != 1 ||
config->remote.port <= 0 || config->remote.port >= 65536) {
gtk_label_set_text (GTK_LABEL (spinner_message),
_("error: Invalid port number. If in doubt, use \"22\"."));
gtk_widget_grab_focus (port_entry);
errors++;
}
free (config->auth.username);
config->auth.username = strdup (gtk_entry_get_text (GTK_ENTRY (username_entry)));
if (STREQ (config->auth.username, "")) {
gtk_label_set_text (GTK_LABEL (spinner_message),
_("error: No user name. If in doubt, use \"root\"."));
gtk_widget_grab_focus (username_entry);
errors++;
}
free (config->auth.password);
config->auth.password = strdup (gtk_entry_get_text (GTK_ENTRY (password_entry)));
free (config->auth.identity.url);
identity_str = gtk_entry_get_text (GTK_ENTRY (identity_entry));
if (identity_str && STRNEQ (identity_str, ""))
config->auth.identity.url = strdup (identity_str);
else
config->auth.identity.url = NULL;
config->auth.identity.file_needs_update = 1;
config->auth.sudo = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sudo_button));
if (errors)
return;
/* Give the testing thread its own copy of the config in case we
* update the config in the main thread.
*/
copy = copy_config (config);
/* No errors so far, so test the connection in a background thread. */
pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
err = pthread_create (&tid, &attr, test_connection_thread, copy);
if (err != 0)
error (EXIT_FAILURE, err, "pthread_create");
pthread_attr_destroy (&attr);
}
/**
* Run C (in a detached background thread). Once it
* finishes stop the spinner and set the spinner message
* appropriately. If the test is successful then we enable the
* C button. If unsuccessful, an error is shown in the
* connection dialog.
*/
static void *
test_connection_thread (void *data)
{
struct config *copy = data;
int r;
g_idle_add (start_spinner, NULL);
wait_network_online (copy);
r = test_connection (copy);
free_config (copy);
g_idle_add (stop_spinner, NULL);
if (r == -1)
g_idle_add (test_connection_error, NULL);
else
g_idle_add (test_connection_ok, NULL);
/* Thread is detached anyway, so no one is waiting for the status. */
return NULL;
}
/**
* Idle task called from C (but run on the
* main thread) to start the spinner in the connection dialog.
*/
static gboolean
start_spinner (gpointer user_data)
{
gtk_label_set_text (GTK_LABEL (spinner_message),
_("Testing the connection to the conversion server ..."));
gtk_widget_show (spinner);
gtk_spinner_start (GTK_SPINNER (spinner));
return FALSE;
}
/**
* Idle task called from C (but run on the
* main thread) to stop the spinner in the connection dialog.
*/
static gboolean
stop_spinner (gpointer user_data)
{
gtk_spinner_stop (GTK_SPINNER (spinner));
gtk_widget_hide (spinner);
return FALSE;
}
/**
* Idle task called from C (but run on the
* main thread) when there is an error. Display the error message and
* disable the C button so the user is forced to correct it.
*/
static gboolean
test_connection_error (gpointer user_data)
{
const char *err = get_ssh_error ();
gtk_label_set_text (GTK_LABEL (spinner_message), err);
/* Disable the Next button. */
gtk_widget_set_sensitive (next_button, FALSE);
return FALSE;
}
/**
* Idle task called from C (but run on the
* main thread) when the connection test was successful.
*/
static gboolean
test_connection_ok (gpointer user_data)
{
gtk_label_set_text
(GTK_LABEL (spinner_message),
_("Connected to the conversion server.\n"
"Press the \"Next\" button to configure the conversion process."));
/* Enable the Next button. */
gtk_widget_set_sensitive (next_button, TRUE);
gtk_widget_grab_focus (next_button);
/* Update the information in the conversion dialog. */
set_info_label ();
return FALSE;
}
/**
* Callback from the C button. This dialog is
* handled entirely by an external program which is part of
* NetworkManager.
*/
static void
configure_network_button_clicked (GtkWidget *w, gpointer data)
{
if (access ("/sbin/yast2", X_OK) >= 0)
ignore_value (system ("yast2 lan &"));
else
ignore_value (system ("nm-connection-editor &"));
}
/**
* Callback from the C button.
*/
static void
xterm_button_clicked (GtkWidget *w, gpointer data)
{
ignore_value (system ("xterm &"));
}
/**
* Callback from the C button.
*
* See also F and F.
*/
static void
about_button_clicked (GtkWidget *w, gpointer data)
{
GtkWidget *dialog;
GtkWidget *parent = conn_dlg;
dialog = gtk_about_dialog_new ();
g_object_set (G_OBJECT (dialog),
"program-name", g_get_prgname (),
"version", PACKAGE_VERSION_FULL " (" host_cpu ")",
"copyright", "\u00A9 2009-2019 Red Hat Inc.",
"comments",
_("Virtualize a physical machine to run on KVM"),
"license-type", GTK_LICENSE_GPL_2_0,
"website", "http://libguestfs.org/",
"authors", authors,
NULL);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
}
/**
* Callback when the connection dialog C button has been
* clicked.
*/
static void
connection_next_clicked (GtkWidget *w, gpointer data)
{
/* Switch to the conversion dialog. */
show_conversion_dialog ();
}
/*----------------------------------------------------------------------*/
/* Conversion dialog. */
static void populate_disks_store (GtkListStore *disks_store,
const char * const *disks);
static void populate_disks (GtkTreeView *disks_list_p,
const char * const *disks);
static void populate_removable_store (GtkListStore *removable_store,
const char * const *removable);
static void populate_removable (GtkTreeView *removable_list_p,
const char * const *removable);
static void populate_interfaces (GtkTreeView *interfaces_list_p);
static void toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer data);
static void network_edited_callback (GtkCellRendererToggle *cell, gchar *path_str, gchar *new_text, gpointer data);
static gboolean maybe_identify_click (GtkWidget *interfaces_list_p,
GdkEventButton *event,
gpointer data);
static void set_disks_from_ui (struct config *);
static void set_removable_from_ui (struct config *);
static void set_interfaces_from_ui (struct config *);
static void conversion_back_clicked (GtkWidget *w, gpointer data);
static void refresh_disks_clicked (GtkWidget *w, gpointer data);
static void start_conversion_clicked (GtkWidget *w, gpointer data);
static void vcpu_topo_toggled (GtkWidget *w, gpointer data);
static void vcpus_or_memory_check_callback (GtkWidget *w, gpointer data);
static void notify_ui_callback (int type, const char *data);
static bool get_phys_topo_from_conv_dlg (void);
static int get_vcpus_from_conv_dlg (void);
static uint64_t get_memory_from_conv_dlg (void);
enum {
DISKS_COL_CONVERT = 0,
DISKS_COL_HW_NAME,
DISKS_COL_DEVICE,
NUM_DISKS_COLS,
};
enum {
REMOVABLE_COL_CONVERT = 0,
REMOVABLE_COL_HW_NAME,
REMOVABLE_COL_DEVICE,
NUM_REMOVABLE_COLS,
};
enum {
INTERFACES_COL_CONVERT = 0,
INTERFACES_COL_DEVICE,
INTERFACES_COL_NETWORK,
NUM_INTERFACES_COLS,
};
/**
* Create the conversion dialog.
*
* This creates the dialog, but it is not displayed. See
* C.
*/
static void
create_conversion_dialog (struct config *config,
const char * const *disks,
const char * const *removable)
{
GtkWidget *back, *refresh_disks, *start_button;
GtkWidget *hbox, *left_vbox, *right_vbox;
GtkWidget *target_frame, *target_vbox, *target_tbl;
GtkWidget *guestname_label, *vcpus_label, *memory_label;
GtkWidget *output_frame, *output_vbox, *output_tbl;
GtkWidget *o_label, *oa_label, *oc_label, *of_label, *os_label;
GtkWidget *info_frame;
GtkWidget *disks_frame, *disks_sw;
GtkWidget *removable_frame, *removable_sw;
GtkWidget *interfaces_frame, *interfaces_sw;
char vcpus_str[64];
char memory_str[64];
int row;
conv_dlg = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (conv_dlg), g_get_prgname ());
gtk_window_set_resizable (GTK_WINDOW (conv_dlg), FALSE);
/* XXX It would be nice not to have to set this explicitly, but
* if we don't then Gtk chooses a very small window.
*/
gtk_widget_set_size_request (conv_dlg, 900, 600);
/* The main dialog area. */
hbox_new (hbox, TRUE, 1);
vbox_new (left_vbox, FALSE, 1);
vbox_new (right_vbox, TRUE, 1);
/* The left column: target properties and output options. */
target_frame = gtk_frame_new (_("Target properties"));
gtk_container_set_border_width (GTK_CONTAINER (target_frame), 4);
vbox_new (target_vbox, FALSE, 1);
table_new (target_tbl, 4, 3);
row = 0;
guestname_label = gtk_label_new_with_mnemonic (_("_Name:"));
table_attach (target_tbl, guestname_label,
0, 1, row, GTK_FILL, GTK_FILL, 1, 1);
set_alignment (guestname_label, 1., 0.5);
guestname_entry = gtk_entry_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (guestname_label), guestname_entry);
if (config->guestname != NULL)
gtk_entry_set_text (GTK_ENTRY (guestname_entry), config->guestname);
table_attach (target_tbl, guestname_entry,
1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
row++;
vcpu_topo = gtk_check_button_new_with_mnemonic (
_("Copy fully populated _pCPU topology"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (vcpu_topo),
config->vcpu.phys_topo);
table_attach (target_tbl, vcpu_topo, 0, 2, row, GTK_FILL, GTK_FILL, 1, 1);
row++;
vcpus_label = gtk_label_new_with_mnemonic (_("# _vCPUs:"));
table_attach (target_tbl, vcpus_label,
0, 1, row, GTK_FILL, GTK_FILL, 1, 1);
set_alignment (vcpus_label, 1., 0.5);
vcpus_entry = gtk_entry_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (vcpus_label), vcpus_entry);
snprintf (vcpus_str, sizeof vcpus_str, "%d", config->vcpu.cores);
gtk_entry_set_text (GTK_ENTRY (vcpus_entry), vcpus_str);
vcpus_entry_when_last_sensitive = config->vcpu.cores;
table_attach (target_tbl, vcpus_entry,
1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
vcpus_warning = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
GTK_ICON_SIZE_BUTTON);
table_attach (target_tbl, vcpus_warning,
2, 3, row, 0, 0, 1, 1);
row++;
memory_label = gtk_label_new_with_mnemonic (_("_Memory (MB):"));
table_attach (target_tbl, memory_label,
0, 1, row, GTK_FILL, GTK_FILL, 1, 1);
set_alignment (memory_label, 1., 0.5);
memory_entry = gtk_entry_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (memory_label), memory_entry);
snprintf (memory_str, sizeof memory_str, "%" PRIu64,
config->memory / 1024 / 1024);
gtk_entry_set_text (GTK_ENTRY (memory_entry), memory_str);
table_attach (target_tbl, memory_entry,
1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
memory_warning = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
GTK_ICON_SIZE_BUTTON);
table_attach (target_tbl, memory_warning,
2, 3, row, 0, 0, 1, 1);
gtk_box_pack_start (GTK_BOX (target_vbox), target_tbl, TRUE, TRUE, 0);
target_warning_label = gtk_label_new ("");
gtk_label_set_line_wrap (GTK_LABEL (target_warning_label), TRUE);
gtk_label_set_line_wrap_mode (GTK_LABEL (target_warning_label),
PANGO_WRAP_WORD);
gtk_label_set_max_width_chars (GTK_LABEL (target_warning_label), 50);
gtk_widget_set_size_request (target_warning_label, -1, 7 * 16);
gtk_box_pack_end (GTK_BOX (target_vbox), target_warning_label, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (target_frame), target_vbox);
output_frame = gtk_frame_new (_("Virt-v2v output options"));
gtk_container_set_border_width (GTK_CONTAINER (output_frame), 4);
vbox_new (output_vbox, FALSE, 1);
table_new (output_tbl, 5, 2);
row = 0;
o_label = gtk_label_new_with_mnemonic (_("Output _to (-o):"));
table_attach (output_tbl, o_label,
0, 1, row, GTK_FILL, GTK_FILL, 1, 1);
set_alignment (o_label, 1., 0.5);
o_combo = gtk_combo_box_text_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (o_label), o_combo);
gtk_widget_set_tooltip_markup (o_combo, _("libvirt means send the converted guest to libvirt-managed KVM on the conversion server. local means put it in a directory on the conversion server. rhv means write it to RHV-M/oVirt. glance means write it to OpenStack Glance. See the virt-v2v(1) manual page for more information about output options."));
repopulate_output_combo (config);
table_attach (output_tbl, o_combo,
1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
row++;
oc_label = gtk_label_new_with_mnemonic (_("_Output conn. (-oc):"));
table_attach (output_tbl, oc_label,
0, 1, row, GTK_FILL, GTK_FILL, 1, 1);
set_alignment (oc_label, 1., 0.5);
oc_entry = gtk_entry_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (oc_label), oc_entry);
gtk_widget_set_tooltip_markup (oc_entry, _("For libvirt only, the libvirt connection URI, or leave blank to add the guest to the default libvirt instance on the conversion server. For others, leave this field blank."));
if (config->output.connection != NULL)
gtk_entry_set_text (GTK_ENTRY (oc_entry), config->output.connection);
table_attach (output_tbl, oc_entry,
1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
row++;
os_label = gtk_label_new_with_mnemonic (_("Output _storage (-os):"));
table_attach (output_tbl, os_label,
0, 1, row, GTK_FILL, GTK_FILL, 1, 1);
set_alignment (os_label, 1., 0.5);
os_entry = gtk_entry_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (os_label), os_entry);
gtk_widget_set_tooltip_markup (os_entry, _("For local, put the directory name on the conversion server. For rhv, put the Export Storage Domain (server:/mountpoint). For others, leave this field blank."));
if (config->output.storage != NULL)
gtk_entry_set_text (GTK_ENTRY (os_entry), config->output.storage);
table_attach (output_tbl, os_entry,
1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
row++;
of_label = gtk_label_new_with_mnemonic (_("Output _format (-of):"));
table_attach (output_tbl, of_label,
0, 1, row, GTK_FILL, GTK_FILL, 1, 1);
set_alignment (of_label, 1., 0.5);
of_entry = gtk_entry_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (of_label), of_entry);
gtk_widget_set_tooltip_markup (of_entry, _("The output disk format, typically raw or qcow2. If blank, defaults to raw."));
if (config->output.format != NULL)
gtk_entry_set_text (GTK_ENTRY (of_entry), config->output.format);
table_attach (output_tbl, of_entry,
1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
row++;
oa_label = gtk_label_new_with_mnemonic (_("Output _allocation (-oa):"));
table_attach (output_tbl, oa_label,
0, 1, row, GTK_FILL, GTK_FILL, 1, 1);
set_alignment (oa_label, 1., 0.5);
oa_combo = gtk_combo_box_text_new ();
gtk_label_set_mnemonic_widget (GTK_LABEL (oa_label), oa_combo);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (oa_combo),
"sparse");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (oa_combo),
"preallocated");
switch (config->output.allocation) {
case OUTPUT_ALLOCATION_PREALLOCATED:
gtk_combo_box_set_active (GTK_COMBO_BOX (oa_combo), 1);
break;
default:
gtk_combo_box_set_active (GTK_COMBO_BOX (oa_combo), 0);
break;
}
table_attach (output_tbl, oa_combo,
1, 2, row, GTK_FILL, GTK_FILL, 1, 1);
gtk_box_pack_start (GTK_BOX (output_vbox), output_tbl, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (output_frame), output_vbox);
info_frame = gtk_frame_new (_("Information"));
gtk_container_set_border_width (GTK_CONTAINER (info_frame), 4);
info_label = gtk_label_new (NULL);
set_alignment (info_label, 0.1, 0.5);
set_info_label ();
gtk_container_add (GTK_CONTAINER (info_frame), info_label);
/* The right column: select devices to be converted. */
disks_frame = gtk_frame_new (_("Fixed hard disks"));
gtk_container_set_border_width (GTK_CONTAINER (disks_frame), 4);
disks_sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_set_border_width (GTK_CONTAINER (disks_sw), 8);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (disks_sw),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
disks_list = gtk_tree_view_new ();
populate_disks (GTK_TREE_VIEW (disks_list), disks);
scrolled_window_add_with_viewport (disks_sw, disks_list);
gtk_container_add (GTK_CONTAINER (disks_frame), disks_sw);
removable_frame = gtk_frame_new (_("Removable media"));
gtk_container_set_border_width (GTK_CONTAINER (removable_frame), 4);
removable_sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_set_border_width (GTK_CONTAINER (removable_sw), 8);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (removable_sw),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
removable_list = gtk_tree_view_new ();
populate_removable (GTK_TREE_VIEW (removable_list), removable);
scrolled_window_add_with_viewport (removable_sw, removable_list);
gtk_container_add (GTK_CONTAINER (removable_frame), removable_sw);
interfaces_frame = gtk_frame_new (_("Network interfaces"));
gtk_container_set_border_width (GTK_CONTAINER (interfaces_frame), 4);
interfaces_sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_set_border_width (GTK_CONTAINER (interfaces_sw), 8);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (interfaces_sw),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
interfaces_list = gtk_tree_view_new ();
/* See maybe_identify_click below for what we're doing. */
g_signal_connect (interfaces_list, "button-press-event",
G_CALLBACK (maybe_identify_click), NULL);
gtk_widget_set_tooltip_markup (interfaces_list, _("Left click on an interface name to flash the light on the physical interface."));
populate_interfaces (GTK_TREE_VIEW (interfaces_list));
scrolled_window_add_with_viewport (interfaces_sw, interfaces_list);
gtk_container_add (GTK_CONTAINER (interfaces_frame), interfaces_sw);
/* Pack the top level dialog. */
gtk_box_pack_start (GTK_BOX (left_vbox), target_frame, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (left_vbox), output_frame, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (left_vbox), info_frame, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (right_vbox), disks_frame, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (right_vbox), removable_frame, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (right_vbox), interfaces_frame, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (hbox), left_vbox, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (hbox), right_vbox, TRUE, TRUE, 0);
gtk_box_pack_start
(GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (conv_dlg))),
hbox, TRUE, TRUE, 0);
/* Buttons. */
gtk_dialog_add_buttons (GTK_DIALOG (conv_dlg),
_("_Back"), 1,
_("_Refresh disks (will reset selection)"), 2,
_("Start _conversion"), 3,
NULL);
back = gtk_dialog_get_widget_for_response (GTK_DIALOG (conv_dlg), 1);
refresh_disks = gtk_dialog_get_widget_for_response (GTK_DIALOG (conv_dlg), 2);
start_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (conv_dlg), 3);
/* Disable disk refreshing in case --test-disk was passed. */
if (disks != NULL &&
disks[0] != NULL &&
disks[0][0] == '/' &&
disks[1] == NULL)
gtk_widget_set_sensitive (refresh_disks, FALSE);
/* Signals. */
g_signal_connect_swapped (G_OBJECT (conv_dlg), "destroy",
G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (G_OBJECT (back), "clicked",
G_CALLBACK (conversion_back_clicked), NULL);
g_signal_connect (G_OBJECT (refresh_disks), "clicked",
G_CALLBACK (refresh_disks_clicked), NULL);
g_signal_connect (G_OBJECT (start_button), "clicked",
G_CALLBACK (start_conversion_clicked), config);
g_signal_connect (G_OBJECT (vcpu_topo), "toggled",
G_CALLBACK (vcpu_topo_toggled), NULL);
g_signal_connect (G_OBJECT (vcpus_entry), "changed",
G_CALLBACK (vcpus_or_memory_check_callback), NULL);
g_signal_connect (G_OBJECT (memory_entry), "changed",
G_CALLBACK (vcpus_or_memory_check_callback), NULL);
}
/**
* Hide all other dialogs and show the conversion dialog.
*/
static void
show_conversion_dialog (void)
{
/* Hide the other dialogs. */
gtk_widget_hide (conn_dlg);
gtk_widget_hide (run_dlg);
/* Show the conversion dialog. */
gtk_widget_show_all (conv_dlg);
vcpu_topo_toggled (NULL, NULL);
vcpus_or_memory_check_callback (NULL, NULL);
/* output_drivers may have been updated, so repopulate o_combo. */
repopulate_output_combo (NULL);
}
/**
* Update the C section in the conversion dialog.
*
* Note that C (the remote virt-v2v version) is read from
* the remote virt-v2v in the C function.
*/
static void
set_info_label (void)
{
CLEANUP_FREE char *text;
int r;
if (!v2v_version)
r = asprintf (&text, _("virt-p2v (client):\n%s"), PACKAGE_VERSION);
else
r = asprintf (&text,
_("virt-p2v (client):\n"
"%s\n"
"virt-v2v (conversion server):\n"
"%s"),
PACKAGE_VERSION_FULL, v2v_version);
if (r == -1) {
perror ("asprintf");
return;
}
gtk_label_set_text (GTK_LABEL (info_label), text);
}
/**
* Repopulate the list of output drivers in the C