fish: Change 'int argc' to 'size_t argc' throughout.
[libguestfs.git] / tools / virt-df
index 5a064cc..9c92521 100755 (executable)
@@ -20,13 +20,14 @@ use warnings;
 use strict;
 
 use Sys::Guestfs;
-use Sys::Guestfs::Lib qw(open_guest get_partitions resolve_windows_path
-  inspect_all_partitions inspect_partition
-  inspect_operating_systems mount_operating_system inspect_in_detail);
+use Sys::Guestfs::Lib qw(open_guest get_partitions);
+
 use Pod::Usage;
 use Getopt::Long;
 use Data::Dumper;
 use XML::Writer;
+use POSIX qw(ceil);
+
 use Locale::TextDomain 'libguestfs';
 
 =encoding utf8
@@ -106,8 +107,8 @@ my $csv;
 
 =item B<--csv>
 
-Write out the results in CSV format (comma-separated values).  This
-format can be imported easily into databases and spreadsheets, but
+Write out the results in CSV format (comma-separated values).  This format
+can be imported easily into databases and spreadsheets, but
 read L</NOTE ABOUT CSV FORMAT> below.
 
 =cut
@@ -118,6 +119,8 @@ my $human;
 
 Print sizes in human-readable format.
 
+You are not allowed to use I<-h> and I<--csv> at the same time.
+
 =cut
 
 my $inodes;
@@ -145,6 +148,9 @@ if ($version) {
     exit
 }
 
+# RHBZ#600977
+die __"virt-df: cannot use -h and --csv options together\n" if $human && $csv;
+
 # Open the guest handle.
 
 if (@ARGV == 0) {
@@ -162,7 +168,7 @@ if (@ARGV == 0) {
     # https://bugzilla.redhat.com/show_bug.cgi?id=538041
     @doms = grep { $_->get_id () != 0 } @doms;
 
-    my @domnames = map { $_->get_name () } @doms;
+    my @domnames = sort (map { $_->get_name () } @doms);
 
     if (@domnames) {
         print_title ();
@@ -230,9 +236,7 @@ sub print_stat
         push @cols, ($blocks-$bfree)*$factor; # total 1K blocks used
         push @cols, $bavail*$factor;   # total 1K blocks available
 
-        # XXX %used column comes out different from the native 'df'
-        # program.  Need to check how 'df' calculates this.
-        push @cols, 100.0 - 100.0 * $bavail / $blocks;
+        push @cols, 100.0 - 100.0 * $bfree / $blocks;
 
         if ($human) {
             $cols[2] = human_size ($cols[2]);
@@ -248,9 +252,7 @@ sub print_stat
         push @cols, $files-$ffree;
         push @cols, $ffree;
 
-        # XXX %used column comes out different from the native 'df'
-        # program.  Need to check how 'df' calculates this.
-        push @cols, 100.0 - 100.0 * $favail / $files;
+        push @cols, 100.0 - 100.0 * $ffree / $files;
     }
 
     print_cols (@cols);
@@ -280,6 +282,7 @@ sub print_title
         printf "%-36s%10s %10s %10s %5s\n",
           $cols[1], $cols[2], $cols[3], $cols[4], $cols[5];
     } else {
+        # Columns don't need special CSV quoting.
         print (join (",", @cols), "\n");
     }
 }
@@ -292,10 +295,17 @@ sub print_cols
         printf ("%-36s", $label);
         print "\n"," "x36 if length ($label) > 36;
 
-        my $percent = sprintf "%3.1f%%", $_[5];
+        # Use 'ceil' on the percentage in order to emulate
+        # what df itself does.
+        my $percent = sprintf "%3d%%", ceil($_[5]);
+
         printf ("%10s %10s %10s %5s\n", $_[2], $_[3], $_[4], $percent);
     } else {
-        printf ("\"%s\",\"%s\",%d,%d,%d,%.1f%%\n", @_);
+        # Need to quote libvirt domain and filesystem.
+        my $dom = shift;
+        my $fs = shift;
+        print csv_quote($dom), ",", csv_quote($fs), ",";
+        printf ("%d,%d,%d,%.1f%%\n", @_);
     }
 }
 
@@ -313,6 +323,31 @@ sub human_size
     }
 }
 
+# Quote field for CSV without using an external module.
+sub csv_quote
+{
+    local $_ = shift;
+
+    my $needs_quoting = /[ ",\n\0]/;
+    return $_ unless $needs_quoting;
+
+    my $i;
+    my $out = '"';
+    for ($i = 0; $i < length; ++$i) {
+        my $c = substr $_, $i, 1;
+        if ($c eq '"') {
+            $out .= '""';
+        } elsif ($c eq '\0') {
+            $out .= '"0';
+        } else {
+            $out .= $c;
+        }
+    }
+    $out .= '"';
+
+    return $out;
+}
+
 =head1 NOTE ABOUT CSV FORMAT
 
 Comma-separated values (CSV) is a deceptive format.  It I<seems> like
@@ -348,11 +383,11 @@ L<http://libguestfs.org/>.
 
 =head1 AUTHOR
 
-Richard W.M. Jones L<http://et.redhat.com/~rjones/>
+Richard W.M. Jones L<http://people.redhat.com/~rjones/>
 
 =head1 COPYRIGHT
 
-Copyright (C) 2009 Red Hat Inc.
+Copyright (C) 2009-2010 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