inspection: Fix calls to case_sensitive_path (RHBZ#858126).

Don't assume that if guestfs_case_sensitive_path returns NULL, that it
means the file does not exist.

The (previously undefined) behaviour of case_sensitive_path was that a
NULL return meant "either the file doesn't exist or some other error".
However in commit 973581780d this was
changed so that if the last element of the path didn't exist, it was
assumed to be a new file and the (non-NULL) path of the new file is
returned.

This change breaks code (including in libguestfs) which tries to use
case_sensitive_path as a dual-purpose call to fix-up a path for
Windows and test if the file exists.  Such code should be rewritten so
that it explicitly tests for file existence after calling
case_sensitive_path.

I examined all the calls to case_sensitive_path in libguestfs and
modified them where necessary.
This commit is contained in:
Richard W.M. Jones
2012-09-28 10:15:13 +01:00
parent 55b7c4df78
commit 9ea6e97014
5 changed files with 35 additions and 34 deletions

View File

@@ -206,10 +206,8 @@ print_dhcp_address_windows (guestfs_h *g, char *root_fs)
/* Locate the SYSTEM hive case-sensitive path. */
system_path =
guestfs_case_sensitive_path (g, "/windows/system32/config/system");
if (!system_path) {
fprintf (stderr, "virt-dhcp-address: HKLM\\System not found in this guest.");
if (!system_path)
exit (EXIT_FAILURE);
}
/* Open the hive to parse it. Note that before libguestfs 1.19.35
* you had to download the file and parse it using hivex(3). Since

View File

@@ -356,6 +356,9 @@ sub resolve_windows_path
my $r;
eval { $r = $g->case_sensitive_path ($path); };
$r = undef if defined $r && ! $g->exists ($r);
return $r;
}

View File

@@ -418,12 +418,9 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs)
snprintf (software, len, "%s/system32/config/software",
fs->windows_systemroot);
char *software_path = guestfs___case_sensitive_path_silently (g, software);
if (!software_path) {
/* Missing software hive is a problem. */
error (g, "no HKLM\\SOFTWARE hive found in the guest");
char *software_path = guestfs_case_sensitive_path (g, software);
if (!software_path)
return NULL;
}
struct guestfs_application_list *ret = NULL;
const char *hivepath[] =

View File

@@ -157,11 +157,9 @@ guestfs___check_windows_root (guestfs_h *g, struct inspect_fs *fs)
return -1;
}
systemroot = guestfs___case_sensitive_path_silently (g, systemroots[i]);
if (!systemroot) {
error (g, _("cannot resolve Windows %%SYSTEMROOT%%"));
systemroot = guestfs_case_sensitive_path (g, systemroots[i]);
if (!systemroot)
return -1;
}
debug (g, "windows %%SYSTEMROOT%% = %s", systemroot);
@@ -189,9 +187,10 @@ check_windows_arch (guestfs_h *g, struct inspect_fs *fs)
char cmd_exe[len];
snprintf (cmd_exe, len, "%s/system32/cmd.exe", fs->windows_systemroot);
char *cmd_exe_path = guestfs___case_sensitive_path_silently (g, cmd_exe);
/* Should exist because of previous check above in has_windows_systemroot. */
char *cmd_exe_path = guestfs_case_sensitive_path (g, cmd_exe);
if (!cmd_exe_path)
return 0;
return -1;
char *arch = guestfs_file_architecture (g, cmd_exe_path);
free (cmd_exe_path);
@@ -210,17 +209,24 @@ static int
check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs)
{
int ret = -1;
int r;
size_t len = strlen (fs->windows_systemroot) + 64;
char software[len];
snprintf (software, len, "%s/system32/config/software",
fs->windows_systemroot);
char *software_path = guestfs___case_sensitive_path_silently (g, software);
char *software_path = guestfs_case_sensitive_path (g, software);
if (!software_path)
/* If the software hive doesn't exist, just accept that we cannot
* find product_name etc.
*/
return -1;
r = guestfs_is_file (g, software_path);
if (r == -1)
return -1;
/* If the software hive doesn't exist, just accept that we cannot
* find product_name etc.
*/
if (r == 0)
return 0;
int64_t node;
@@ -312,16 +318,23 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs)
static int
check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs)
{
int r;
size_t len = strlen (fs->windows_systemroot) + 64;
char system[len];
snprintf (system, len, "%s/system32/config/system",
fs->windows_systemroot);
char *system_path = guestfs___case_sensitive_path_silently (g, system);
char *system_path = guestfs_case_sensitive_path (g, system);
if (!system_path)
/* If the system hive doesn't exist, just accept that we cannot
* find hostname etc.
*/
return -1;
r = guestfs_is_file (g, system_path);
if (r == -1)
return -1;
/* If the system hive doesn't exist, just accept that we cannot
* find hostname etc.
*/
if (r == 0)
return 0;
int ret = -1;

View File

@@ -516,12 +516,7 @@ sub download_hive
my $hivefile = shift;
my $hiveshortname = shift;
my $winfile;
eval { $winfile = $g->case_sensitive_path ($hivefile); };
if ($@) {
die __x("virt-win-reg: {p}: file not found in guest: {err}\n",
p => $hivefile, err => $@);
}
my $winfile = $g->case_sensitive_path ($hivefile);
warn "downloading $winfile ..." if $debug;
eval { $g->download ($winfile, "$tmpdir/$hiveshortname"); };
@@ -538,12 +533,7 @@ sub upload_hive
my $hiveshortname = shift;
my $hivefile = shift;
my $winfile;
eval { $winfile = $g->case_sensitive_path ($hivefile); };
if ($@) {
die __x("virt-win-reg: {p}: file not found in guest: {err}\n",
p => $hivefile, err => $@);
}
my $winfile = $g->case_sensitive_path ($hivefile);
warn "uploading $winfile ..." if $debug;
eval { $g->upload ("$tmpdir/$hiveshortname", $winfile); };