From: Richard Jones Date: Thu, 9 Jul 2009 14:29:28 +0000 (+0100) Subject: Move 'resolve_windows_path' to Sys::Guestfs::Lib. X-Git-Tag: 1.0.57~14 X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=commitdiff_plain;h=64c565dc905cef89a681c0bd9dce0864f3b03797 Move 'resolve_windows_path' to Sys::Guestfs::Lib. --- diff --git a/inspector/virt-inspector.pl b/inspector/virt-inspector.pl index 5b225b2..67c81af 100755 --- a/inspector/virt-inspector.pl +++ b/inspector/virt-inspector.pl @@ -20,7 +20,7 @@ use warnings; use strict; use Sys::Guestfs; -use Sys::Guestfs::Lib qw(open_guest get_partitions); +use Sys::Guestfs::Lib qw(open_guest get_partitions resolve_windows_path); use Pod::Usage; use Getopt::Long; use Data::Dumper; @@ -422,7 +422,7 @@ sub check_windows_root local $_; my $r = shift; - my $boot_ini = resolve_windows_path ("/", "boot.ini"); + my $boot_ini = resolve_windows_path ($g, "/boot.ini"); $r->{boot_ini} = $boot_ini; if (defined $r->{boot_ini}) { @@ -443,7 +443,7 @@ sub check_windows_root } if (defined $systemroot) { - $r->{systemroot} = resolve_windows_path ("/", $systemroot); + $r->{systemroot} = resolve_windows_path ($g, "/$systemroot"); if (defined $r->{systemroot} && $windows_registry) { check_windows_registry ($r, $r->{systemroot}); } @@ -459,20 +459,18 @@ sub check_windows_registry # Download the system registry files. Only download the # interesting ones, and we don't bother with user profiles at all. - my $system32 = resolve_windows_path ($systemroot, "system32"); - if (defined $system32) { - my $config = resolve_windows_path ($system32, "config"); - if (defined $config) { - my $software = resolve_windows_path ($config, "software"); - if (defined $software) { - load_windows_registry ($r, $software, - "HKEY_LOCAL_MACHINE\\SOFTWARE"); - } - my $system = resolve_windows_path ($config, "system"); - if (defined $system) { - load_windows_registry ($r, $system, - "HKEY_LOCAL_MACHINE\\System"); - } + + my $configdir = resolve_windows_path ($g, "$systemroot/system32/config"); + if (defined $configdir) { + my $softwaredir = resolve_windows_path ($g, "$configdir/software"); + if (defined $softwaredir) { + load_windows_registry ($r, $softwaredir, + "HKEY_LOCAL_MACHINE\\SOFTWARE"); + } + my $systemdir = resolve_windows_path ($g, "$configdir/system"); + if (defined $systemdir) { + load_windows_registry ($r, $systemdir, + "HKEY_LOCAL_MACHINE\\System"); } } } @@ -527,28 +525,6 @@ sub load_windows_registry $r->{registry} = \@registry; } -# Because of case sensitivity, the actual path might have a different -# name, and ntfs-3g is always case sensitive. Find out what the real -# path is. Returns the correct full path, or undef. -sub resolve_windows_path -{ - local $_; - my $parent = shift; # Must exist, with correct case. - my $dir = shift; - - foreach ($g->ls ($parent)) { - if (lc ($_) eq lc ($dir)) { - if ($parent eq "/") { - return "/$_" - } else { - return "$parent/$_" - } - } - } - - undef; -} - sub check_grub { local $_; diff --git a/perl/lib/Sys/Guestfs/Lib.pm b/perl/lib/Sys/Guestfs/Lib.pm index 75b2056..e54b244 100644 --- a/perl/lib/Sys/Guestfs/Lib.pm +++ b/perl/lib/Sys/Guestfs/Lib.pm @@ -58,7 +58,7 @@ require Exporter; use vars qw(@EXPORT_OK @ISA); @ISA = qw(Exporter); -@EXPORT_OK = qw(open_guest get_partitions); +@EXPORT_OK = qw(open_guest get_partitions resolve_windows_path); =head2 open_guest @@ -219,6 +219,62 @@ sub is_pv { 0; } +=head2 resolve_windows_path + + $path = resolve_windows_path ($g, $path); + + $path = resolve_windows_path ($g, "/windows/system"); + ==> "/WINDOWS/System" + or undef if no path exists + +This function, which is specific to FAT/NTFS filesystems (ie. Windows +guests), lets you look up a case insensitive C<$path> in the +filesystem and returns the true, case sensitive path as required by +the underlying kernel or NTFS-3g driver. + +If C<$path> does not exist then this function returns C. + +The C<$path> parameter must begin with C character and be separated +by C characters. Do not use C<\>, drive names, etc. + +=cut + +sub resolve_windows_path +{ + local $_; + my $g = shift; + my $path = shift; + + if (substr ($path, 0, 1) ne "/") { + warn "resolve_windows_path: path must start with a / character"; + return undef; + } + + my @elems = split (/\//, $path); + shift @elems; + + # Start reconstructing the path at the top. + $path = "/"; + + foreach my $dir (@elems) { + my $found = 0; + foreach ($g->ls ($path)) { + if (lc ($_) eq lc ($dir)) { + if ($path eq "/") { + $path = "/$_"; + $found = 1; + } else { + $path = "$path/$_"; + $found = 1; + } + } + } + return undef unless $found; + } + + return $path; +} + 1; =head1 COPYRIGHT