Tab to space (whitespace fixes only).
[libguestfs.git] / tools / virt-ls
1 #!/usr/bin/perl -w
2 # virt-ls
3 # Copyright (C) 2009 Red Hat Inc.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 use warnings;
20 use strict;
21
22 use Sys::Guestfs;
23 use Sys::Guestfs::Lib qw(open_guest get_partitions resolve_windows_path
24   inspect_all_partitions inspect_partition
25   inspect_operating_systems mount_operating_system);
26 use Pod::Usage;
27 use Getopt::Long;
28 use Locale::TextDomain 'libguestfs';
29 use File::Temp qw/tempdir/;
30
31 =encoding utf8
32
33 =head1 NAME
34
35 virt-ls - List files in a virtual machine
36
37 =head1 SYNOPSIS
38
39  virt-ls [--options] domname directory
40
41  virt-ls [--options] disk.img [disk.img ...] directory
42
43 =head1 DESCRIPTION
44
45 C<virt-ls> is a command line tool to list the names of files in a
46 directory inside a virtual machine or disk image.
47
48 C<virt-ls> is just a simple wrapper around L<libguestfs(3)>
49 functionality.  For more complex cases you should look at the
50 L<guestfish(1)> tool.
51
52 C<virt-ls> can be used in one of three modes: simple, long and
53 recursive.  A simple listing is like the ordinary L<ls(1)> command:
54
55  $ virt-ls myguest /
56  bin
57  boot
58  [etc.]
59
60 With the C<-l> (C<--long>) option, C<virt-ls> shows more detail:
61
62  $ virt-ls -l myguest /
63  total 204
64  dr-xr-xr-x.   2 root root   4096 2009-08-25 19:06 bin
65  dr-xr-xr-x.   5 root root   3072 2009-08-25 19:06 boot
66  [etc.]
67
68 With the C<-R> (C<--recursive>) option, C<virt-ls> lists the
69 names of files and directories recursively:
70
71  $ virt-ls -R myguest /tmp
72  foo
73  foo/bar
74  [etc.]
75
76 You I<cannot> combine these options.  To do more complicated things,
77 use L<guestfish(1)>.
78
79 =head1 OPTIONS
80
81 =over 4
82
83 =cut
84
85 my $help;
86
87 =item B<--help>
88
89 Display brief help.
90
91 =cut
92
93 my $version;
94
95 =item B<--version>
96
97 Display version number and exit.
98
99 =cut
100
101 my $uri;
102
103 =item B<--connect URI> | B<-c URI>
104
105 If using libvirt, connect to the given I<URI>.  If omitted, then we
106 connect to the default libvirt hypervisor.
107
108 If you specify guest block devices directly, then libvirt is not used
109 at all.
110
111 =cut
112
113 my $mode;
114
115 =item B<-l> | B<--long>
116
117 =item B<-R> | B<--recursive>
118
119 Select the mode.  With neither of these options, C<virt-ls>
120 produces a simple, flat list of the files in the named directory.
121
122 C<virt-ls -l> produces a "long listing", which shows more detail (just
123 like the plain C<ls -l> command).
124
125 C<virt-ls -R> produces a recursive list of files starting at the named
126 directory.  See the documentation for the C<guestfs_find> command
127 L<guestfs(3)> for precise details.
128
129 You cannot combine these options.
130
131 =back
132
133 =cut
134
135 sub set_mode_l
136 {
137     die __"virt-ls: cannot combine -l and -R options\n" if $mode;
138     $mode = "l";
139 }
140
141 sub set_mode_R
142 {
143     die __"virt-ls: cannot combine -l and -R options\n" if $mode;
144     $mode = "R";
145 }
146
147 GetOptions ("help|?" => \$help,
148             "version" => \$version,
149             "connect|c=s" => \$uri,
150             "long|l" => \&set_mode_l,
151             "recursive|R" => \&set_mode_R,
152     ) or pod2usage (2);
153 pod2usage (1) if $help;
154 if ($version) {
155     my $g = Sys::Guestfs->new ();
156     my %h = $g->version ();
157     print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
158     exit
159 }
160
161 pod2usage (__"virt-ls: no image, VM names or directory to list given")
162     if @ARGV <= 1;
163
164 my $directory = pop @ARGV;
165
166 my $g;
167 if ($uri) {
168     $g = open_guest (\@ARGV, address => $uri);
169 } else {
170     $g = open_guest (\@ARGV);
171 }
172
173 $g->launch ();
174
175 # List of possible filesystems.
176 my @partitions = get_partitions ($g);
177
178 # Now query each one to build up a picture of what's in it.
179 my %fses =
180     inspect_all_partitions ($g, \@partitions,
181       use_windows_registry => 0);
182
183 my $oses = inspect_operating_systems ($g, \%fses);
184
185 my @roots = keys %$oses;
186 die __"no root device found in this operating system image\n" if @roots == 0;
187 die __"multiboot operating systems are not supported by virt-ls\n" if @roots > 1;
188 my $root_dev = $roots[0];
189
190 my $os = $oses->{$root_dev};
191 mount_operating_system ($g, $os);
192
193 unless ($mode) {
194     my @r = $g->ls ($directory);
195     print "$_\n" foreach @r;
196 } elsif ($mode eq "l") {
197     print ($g->ll ($directory));
198 } else { # $mode eq "R"
199     my $dir = tempdir (CLEANUP => 1);
200     $g->find0 ($directory, "$dir/find0");
201     open F, "$dir/find0" or die "$dir/find0: $!\n";
202     my $r;
203     my $line;
204     while (($r = read (F, $line, 1024)) > 0) {
205         $line =~ tr{\0}{\n};
206         print $line;
207     }
208     close F;
209 }
210
211 =head1 SEE ALSO
212
213 L<guestfs(3)>,
214 L<guestfish(1)>,
215 L<virt-cat(1)>,
216 L<virt-tar(1)>,
217 L<Sys::Guestfs(3)>,
218 L<Sys::Guestfs::Lib(3)>,
219 L<Sys::Virt(3)>,
220 L<http://libguestfs.org/>.
221
222 =head1 AUTHOR
223
224 Richard W.M. Jones L<http://et.redhat.com/~rjones/>
225
226 =head1 COPYRIGHT
227
228 Copyright (C) 2009 Red Hat Inc.
229
230 This program is free software; you can redistribute it and/or modify
231 it under the terms of the GNU General Public License as published by
232 the Free Software Foundation; either version 2 of the License, or
233 (at your option) any later version.
234
235 This program is distributed in the hope that it will be useful,
236 but WITHOUT ANY WARRANTY; without even the implied warranty of
237 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
238 GNU General Public License for more details.
239
240 You should have received a copy of the GNU General Public License
241 along with this program; if not, write to the Free Software
242 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.