--- orig/coreutils-5.0/src/df.c 2003-03-04 16:07:53.000000000 -0500 +++ coreutils-5.0/src/df.c 2003-07-13 13:52:01.000000000 -0400 @@ -115,6 +115,14 @@ /* If nonzero, print filesystem type as well. */ static int print_type; +/* If nonzero, print a total line at the end. */ +static int grand_total; + +/* Totals for the grand_total option. */ +static uintmax_t total_blocks; +static uintmax_t total_used; +static uintmax_t total_avail; + /* For long options that have no equivalent short option, use a non-character as a pseudo short option, starting with CHAR_MAX + 1. */ enum @@ -139,6 +147,7 @@ {"no-sync", no_argument, NULL, NO_SYNC_OPTION}, {"type", required_argument, NULL, 't'}, {"exclude-type", required_argument, NULL, 'x'}, + {"total", no_argument, NULL, 'o'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} @@ -373,6 +382,14 @@ } } + if (grand_total) + { + total_blocks += total * input_units; + total_used += (negate_used ? -used : used) * input_units; + total_avail += + (negate_available ? -available : available) * input_units; + } + printf (" %*s %*s %*s ", width, df_readable (0, total, buf[0], input_units, output_units), @@ -774,8 +791,13 @@ print_type = 0; posix_format = 0; exit_status = 0; + grand_total = 0; + total_blocks = 0; + total_used = 0; + total_avail = 0; - while ((c = getopt_long (argc, argv, "aB:iF:hHklmPTt:vx:", long_options, NULL)) + while ((c = getopt_long (argc, argv, "aB:iF:hHklmoPTt:vx:", long_options, + NULL)) != -1) { switch (c) @@ -810,6 +832,9 @@ human_output_opts = 0; output_block_size = 1024 * 1024; break; + case 'o': + grand_total = 1; + break; case 'T': print_type = 1; break; @@ -929,5 +954,70 @@ show_entry (argv[i], &stats[i - optind]); } + if (grand_total) + { + int width; + int use_width; + uintmax_t output_units; + double pct = -1; + char buf[3][LONGEST_HUMAN_READABLE + 2]; + + if (inode_format) + { + width = 7; + use_width = 5; + output_units = 1; + } + else + { + width = (human_output_opts & human_autoscale + ? 5 + ! (human_output_opts & human_base_1024) + : 9); + use_width = ((posix_format + && ! (human_output_opts & human_autoscale)) + ? 8 : 4); + output_units = output_block_size; + } + + printf ("%-20s", "total"); + printf (" %*s %*s %*s ", + width, df_readable (0, total_blocks, buf[0], 1, output_units), + width, df_readable (0, total_used, buf[1], 1, output_units), + width, df_readable (0, total_avail, buf[2], 1, output_units)); + + if (total_used <= TYPE_MAXIMUM (uintmax_t) / 100 + && total_used + total_avail != 0 + && total_avail >= 0) + { + uintmax_t u100 = total_used * 100; + uintmax_t nonroot_total = total_used + total_avail; + pct = u100 / nonroot_total + (u100 % nonroot_total != 0); + } + else + { + double u = total_used; + double a = total_avail; + double nonroot_total = u + a; + if (nonroot_total) + { + double ipct; + pct = u * 100 / nonroot_total; + ipct = (long) pct; + + /* Like `pct = ceil (dpct);', but avoid ceil so that + the math library needn't be linked. */ + if (ipct - 1 < pct && pct <= ipct + 1) + pct = ipct + (ipct < pct); + } + } + + if (0 <= pct) + printf ("%*.0f%%", use_width - 1, pct); + else + printf ("%*s", use_width, "- "); + + printf ("\n"); + } + exit (exit_status); }