Hi maintainers, I always use the "du" utility when I'm cleaning-up my harddrive. Although this utility has always helped my a lot, it lacked the ability to show the directory usage as a percentage of the total disk usage. For my own convenience I've modified the CVS du and added these two options:
-p, --percentages print percentages --min-perc=PERC only print sizes over PERC percentage When the "-p --min-perc=5" options are used, it produces an output like: Processing files: ................................................................................................ 24,3% [#### ] ./linux-headers-2.6.12-8/include 28,2% [##### ] ./linux-headers-2.6.12-8 6,5% [# ] ./linux-headers-2.6.12-8-686/include/config 6,6% [# ] ./linux-headers-2.6.12-8-686/include 8,1% [# ] ./linux-headers-2.6.12-8-686 24,3% [#### ] ./linux-headers-2.6.12-9/include 28,3% [##### ] ./linux-headers-2.6.12-9 6,5% [# ] ./linux-headers-2.6.12-9-686/include/config 6,6% [# ] ./linux-headers-2.6.12-9-686/include 8,1% [# ] ./linux-headers-2.6.12-9-686 100,0% [####################] . Maybe you find this a nice addition to the du capabilities. Please let me know what you think of this functionality and if you will evaluate this code? Kind regards, Marcel Ibes e-mail: [EMAIL PROTECTED] PATCH CODE (diff -u): --- coreutils/src/du.c 2005-10-15 12:14:13.000000000 +0200 +++ ./coreutils-mi/src/du.c 2005-10-30 22:11:36.159653832 +0100 @@ -52,7 +52,7 @@ #define PROGRAM_NAME "du" #define AUTHORS \ - "Torbjorn Granlund", "David MacKenzie, Paul Eggert", "Jim Meyering" + "Torbjorn Granlund", "David MacKenzie, Paul Eggert", "Jim Meyering", "Marcel Ibes" #if DU_DEBUG # define FTS_CROSS_CHECK(Fts) fts_cross_check (Fts) @@ -74,6 +74,27 @@ dev_t st_dev; }; +/* MI: Initialy the perc_entries will hold up to 1024 entries */ +#define INIT_PERC_SIZE 1024 + +/* MI: The total amount of entries in the perc_entries array */ +static int total_perc_entries = 0; +static int max_perc_entries = INIT_PERC_SIZE; + +/* MI: If nonzero, print percentages. */ +static int print_perc = 0; +static int min_perc = 0; + +/* MI: structure to hold the file and its size */ +struct perc_entry +{ + char *file_name; + uintmax_t size; +}; + +/* MI: Dynamic array that can hold all the files */ +struct perc_entry *perc_entries; + /* A set of dev/ino pairs. */ static Hash_table *htab; @@ -206,7 +227,8 @@ MEGABYTES_LONG_OPTION, TIME_OPTION, - TIME_STYLE_OPTION + TIME_STYLE_OPTION, + MIN_PERC_OPTION }; static struct option const long_options[] = @@ -228,6 +250,8 @@ {"null", no_argument, NULL, '0'}, {"megabytes", no_argument, NULL, MEGABYTES_LONG_OPTION}, {"no-dereference", no_argument, NULL, 'P'}, + {"percentages", no_argument, NULL, 'p'}, + {"min-perc", required_argument, 0, MIN_PERC_OPTION}, {"one-file-system", no_argument, NULL, 'x'}, {"separate-dirs", no_argument, NULL, 'S'}, {"summarize", no_argument, NULL, 's'}, @@ -313,6 +337,8 @@ fputs (_("\ -L, --dereference dereference all symbolic links\n\ -P, --no-dereference don't follow any symbolic links (this is the default)\n\ + -p, --percentages print percentages\n\ + --min-perc=PERC only print sizes over PERC percentage\n\ -0, --null end each output line with 0 byte rather than newline\n\ -S, --separate-dirs do not include size of subdirectories\n\ -s, --summarize display only a total for each argument\n\ @@ -346,6 +372,109 @@ exit (status); } +/* MI: Add an entry to the perc_entries array */ +static void add_perc_entry(FTSENT *ent, uintmax_t filesize) +{ + if (total_perc_entries == max_perc_entries) + { + // Need to allocate more memory + max_perc_entries *= 2; + + // fputc ('R', stdout); + // fflush (stdout); + + perc_entries = xrealloc(perc_entries, + max_perc_entries * sizeof(struct perc_entry)); + + if (perc_entries == NULL) + { + // Oops, not enough memory + error (0, 0, _("error: not enough available memory.")); + exit(EXIT_FAILURE); + } + } + + struct perc_entry *p; + + p = perc_entries; + p += total_perc_entries; + + p->file_name = xcalloc(1, ent->fts_pathlen + 1); + memcpy(p->file_name, ent->fts_path, ent->fts_pathlen); + + p->size = filesize; + total_perc_entries++; +} + +/* MI: Create the percentage progress bar */ +char* perc_bar(double perc) +{ + static char ret_val[23]; + int hashes; + + sprintf(ret_val, "[ ]\0"); + + if (perc > 0) + { + hashes = (int) (perc / 5); + } + else + { + hashes = 0; + } + + hashes += 1; + + int i; + + for (i = 1; i < hashes; i++) + { + ret_val[i] = '#'; + } + + return (char*) &ret_val; +} + +/* MI: Process and write the procentages to the screen */ +static void process_perc(uintmax_t total_size) +{ + int i; + double perc; + + struct perc_entry *p; + + printf("\n\n"); + + // printf("\n\nFound a total of %d files\n", total_perc_entries); + // printf("With a total size of %d\n\n", total_size); + + p = perc_entries; + + for (i = 0; i < total_perc_entries; i++) + { + if (total_size > 0) + { + // We don't want a divide by zero! + perc = (( (double) p->size / (double) total_size) * 100); + } + else + { + perc = 0; + } + + if (perc >= min_perc) + { + printf("%0.1f%\t%s\t%s\n", perc, perc_bar(perc), p->file_name); + } + + free(p->file_name); + + p++; + } + + free(perc_entries); +} + static size_t entry_hash (void const *x, size_t table_size) { @@ -618,8 +747,20 @@ if ((IS_DIR_TYPE (ent->fts_info) && level <= max_depth) || ((opt_all && level <= max_depth) || level == 0)) - print_size (&dui_to_print, file); - + { + if (print_perc) + { + /* MI: Add file to perc_entries */ + fputc ('.', stdout); + fflush (stdout); + add_perc_entry(ent, dui_to_print.size); + } + else + { + print_size (&dui_to_print, file); + } + } + return ok; } @@ -636,6 +777,9 @@ if (*files) { FTS *fts = xfts_open (files, bit_flags, NULL); + + if (print_perc) + printf("%s", _("Processing files: ")); while (1) { @@ -663,6 +807,10 @@ fts_close (fts); } + /* MI: Show percentages */ + if (print_perc) + process_perc(tot_dui.size); + if (print_grand_total) print_size (&tot_dui, _("total")); @@ -695,6 +843,17 @@ bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); + /* MI: Allocate some space to hold the perc_entries */ + perc_entries = (struct perc_entry*) xmalloc(max_perc_entries * sizeof(struct perc_entry)); + + if (perc_entries == NULL) + { + // Oops, no memory to allocate array + error (0, 0, + _("error: not enough available memory.")); + exit(EXIT_FAILURE); + } + atexit (close_stdout); exclude = new_exclude (); @@ -702,7 +861,7 @@ human_output_opts = human_options (getenv ("DU_BLOCK_SIZE"), false, &output_block_size); - while ((c = getopt_long (argc, argv, DEBUG_OPT "0abchHklmsxB:DLPSX:", + while ((c = getopt_long (argc, argv, DEBUG_OPT "0abchHklmsxB:DLPpSX:", long_options, NULL)) != -1) { switch (c) @@ -814,6 +973,14 @@ bit_flags = FTS_PHYSICAL; break; + case 'p': /* --percentage */ + print_perc = 1; + break; + + case MIN_PERC_OPTION: + min_perc = atoi(optarg); + break; + case 'S': opt_separate_dirs = true; break; _______________________________________________ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils