Additions to du
Kim Ahlström <[email protected]>
| Newsgroups | gmane.comp.gnu.fileutils.bugs |
|---|---|
| Message-ID | <[email protected]> |
Hi! I have have made two additions to the du utility that I thought you might want to take a look at. First. The addition of a -p flag. When this is used the file's size in percent relative to the total number of shown files will be printed. A downside to this is that du has to go through all files first before it can start producing output, thus making it silent for a moment. Example: % src/du -p /Users/kim/temp/fileutils-4.1.11/tests/ 3.94% /Users/kim/temp/fileutils-4.1.11/tests/chgrp 4.33% /Users/kim/temp/fileutils-4.1.11/tests/chmod 3.15% /Users/kim/temp/fileutils-4.1.11/tests/chown 11.81% /Users/kim/temp/fileutils-4.1.11/tests/cp ... Second. The three kinds of output flags -kmbB, -hH and -p can now be given simultaneously and will all output their respective data followed by a tab. -kmb will print first, then -hH and last -p. Like this: % src/du -p /Users/kim/temp/fileutils-4.1.11/tests/ 40 40K 3.94% /Users/kim/temp/fileutils-4.1.11/tests/chgrp 44 44K 4.33% /Users/kim/temp/fileutils-4.1.11/tests/chmod 32 32K 3.15% /Users/kim/temp/fileutils-4.1.11/tests/chown 120 120K 11.81% /Users/kim/temp/fileutils-4.1.11/tests/cp ... or: % src/du -bh /Users/kim/temp/fileutils-4.1.11/tests/ 40960 40K /Users/kim/temp/fileutils-4.1.11/tests/chgrp 45056 44K /Users/kim/temp/fileutils-4.1.11/tests/chmod 32768 32K /Users/kim/temp/fileutils-4.1.11/tests/chown 122880 120K /Users/kim/temp/fileutils-4.1.11/tests/cp ... or: % src/du -p -B 5K /Users/kim/temp/fileutils-4.1.11/tests/ 8 3.94% /Users/kim/temp/fileutils-4.1.11/tests/chgrp 9 4.33% /Users/kim/temp/fileutils-4.1.11/tests/chmod 7 3.15% /Users/kim/temp/fileutils-4.1.11/tests/chown 24 11.81% /Users/kim/temp/fileutils-4.1.11/tests/cp ... Included is a diff file that was made with du.c of version 4.1.11 of the GNU Fileutils. If you want one that was made with the latest stable (4.1) instead I will more than gladly send one over. I have tried to adhere to the GNU coding standards as thoroughly as possible and commented the code where I thought needed. I also wrote a ChangeLog entry to clarify code changes. ChangeLog: 2002-09-18 Kim Ahlstrom <[email protected]> Added -p flag that prints percentage of file's size relative to all printed files' size. New output handling. * src/du.c: Added global variables to handle the new -p flag and output options. (print_size): Rewrite to allow output from both the -kmb flags, the -hH flags and the new -p flag at the same time. Added code to accumulate data for percentage calculation (-p flag). (du_files): Print files and data accumulated by percentage calculation (-p flag). (main): Added -p flag switch-case. Modified h,H,k,m,b,B switch-cases to allow the -h and -H flags being active while either -kmbB flags are active. (usage): Explain -p flag. If you have any questions I will be more than happy to answer! Best Regards Kim Ahlstrom [email protected] http://kim.animanga.nu/ (Swedish only)
du.c.diff
(application/octet-stream, 6.5 KB)
--- ../../du.4111.orig.c Wed Jul 10 10:09:05 2002
+++ du.c Thu Sep 19 22:21:36 2002
@@ -99,6 +99,31 @@
int stat ();
int lstat ();
+/* Linked list structure to hold filepaths and n_blocks,
+ to be used with the -p flag for percentage. */
+
+struct list_def
+{
+ char * path; /* Filepath (dynamically allocated) */
+ uintmax_t size; /* Number of n_blocks ( print_size()'s first argument ) */
+ struct list_def *next; /* Next node */
+};
+
+/* Nodes in the linked list of filepaths and n_blocks. */
+struct list_def *first_node, *last_node, *now_node = NULL;
+
+/* If nonzero, suppress printing. */
+static int suppress = 0;
+
+/* If nonzero, calculate percentages (-p). */
+static int display_percentage = 0;
+
+/* If nonzero, one of the -kmbB flags has been provided. */
+static int display_byte_kilo_mega = 0;
+
+/* Holds the output_block_size for human numbers (-h or -H). */
+static int h_block_size = 0;
+
/* Name under which this program was invoked. */
char *program_name;
@@ -168,6 +193,7 @@
{"kilobytes", no_argument, NULL, 'k'}, /* long form is obsolescent */
{"max-depth", required_argument, NULL, MAX_DEPTH_OPTION},
{"megabytes", no_argument, NULL, 'm'}, /* obsolescent */
+ {"percent", no_argument, NULL, "p"},
{"one-file-system", no_argument, NULL, 'x'},
{"separate-dirs", no_argument, NULL, 'S'},
{"summarize", no_argument, NULL, 's'},
@@ -208,6 +234,7 @@
"), stdout);
fputs (_("\
-L, --dereference dereference all symbolic links\n\
+ -p, --percent print sizes in percent relative to all files' total size\n\
-S, --separate-dirs do not include size of subdirectories\n\
-s, --summarize display only a total for each argument\n\
"), stdout);
@@ -353,20 +380,94 @@
}
}
-/* Print N_BLOCKS followed by STRING on a line. NBLOCKS is the number of
- ST_NBLOCKSIZE-byte blocks; convert it to OUTPUT_BLOCK_SIZE units before
- printing. If OUTPUT_BLOCK_SIZE is negative, use a human readable
- notation instead. */
+/* If -p flag was provided we start by accumulating file data and not printing.
+ Printing will be requested by the du_files function after accumulation.
+ Print N_BLOCKS[\thuman_readable\tpercentage]\tSTRING on a line.
+ N_BLOCKS is the number of ST_NBLOCKSIZE-byte blocks; convert it to
+ OUTPUT_BLOCK_SIZE units before printing. If OUTPUT_BLOCK_SIZE is negative,
+ use a human readable notation instead. */
static void
print_size (uintmax_t n_blocks, const char *string)
{
char buf[LONGEST_HUMAN_READABLE + 1];
- printf ("%s\t%s\n",
- human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
- output_block_size, human_ceiling),
- string);
- fflush (stdout);
+ double prcnt; /* Temporary variable to hold the percent. */
+
+ if (suppress != 0)
+ {
+ /* The p flag is on and we are accumulating file data.
+ Thus we don't want to print. */
+
+ now_node = malloc (sizeof (struct list_def));
+ if (now_node == NULL)
+ {
+ fprintf (stderr, "%s: %s", program_name, strerror (errno));
+ exit (1);
+ }
+
+ if (first_node == NULL)
+ {
+ first_node = now_node;
+ now_node->next = NULL;
+ }
+ else
+ {
+ last_node->next = now_node;
+ now_node->next = NULL;
+ }
+
+ last_node = now_node;
+
+ now_node->path = malloc (strlen (string));
+ if (now_node->path == NULL)
+ {
+ fprintf (stderr, "%s: %s", program_name, strerror (errno));
+ exit (1);
+ }
+
+ strncpy (now_node->path, string, strlen (string) + 1);
+ now_node->size = n_blocks;
+ }
+ else
+ {
+ /* Print. */
+ if (display_byte_kilo_mega != 0)
+ {
+ /* Bytes, Kilobytes, Megabytes (-kmbB). */
+ printf ("%s\t",
+ human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
+ output_block_size, human_ceiling));
+ }
+ if (h_block_size != 0)
+ {
+ /* Human form (-hH). */
+ printf ("%s\t",
+ human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
+ h_block_size, human_ceiling));
+ }
+ if (display_percentage != 0)
+ {
+ /* Percentage (-p). */
+ prcnt = ( (double)n_blocks / (double)tot_size) * 100;
+ printf ("%.2f%%\t", prcnt);
+ }
+
+ if (display_byte_kilo_mega == 0 && h_block_size == 0 && display_percentage == 0)
+ {
+ /* No output flags were provided. */
+ printf ("%s\t%s\n",
+ human_readable_inexact (n_blocks, buf, ST_NBLOCKSIZE,
+ output_block_size, human_ceiling),
+ string);
+ }
+ else
+ {
+ /* Filepath. */
+ printf ("%s\n", string);
+ }
+
+ fflush (stdout);
+ }
}
/* Restore the previous working directory or exit.
@@ -553,6 +654,17 @@
count_entry (arg, 1, 0, 0);
}
+ /* If the -p flag was provided,
+ stop suppressing printing and print the accumulated data. */
+ if (display_percentage != 0)
+ {
+ suppress = 0;
+ for (now_node = first_node; now_node != NULL; now_node = now_node->next)
+ {
+ print_size (now_node->size, now_node->path);
+ }
+ }
+
if (print_totals)
print_size (tot_size, _("total"));
}
@@ -582,7 +694,7 @@
human_block_size (getenv ("DU_BLOCK_SIZE"), 0, &output_block_size);
- while ((c = getopt_long (argc, argv, "abchHklmsxB:DLSX:", long_options, NULL))
+ while ((c = getopt_long (argc, argv, "abchHklmpsxB:DLSX:", long_options, NULL))
!= -1)
{
long int tmp_long;
@@ -597,22 +709,33 @@
case 'b':
output_block_size = 1;
+ display_byte_kilo_mega = 1;
break;
case 'c':
print_totals = 1;
break;
+ case 'p':
+ suppress = 1;
+ display_percentage = 1;
+ break;
+
case 'h':
- output_block_size = -1024;
+ h_block_size = -1024;
+ if(!display_byte_kilo_mega)
+ output_block_size = -1024;
break;
case 'H':
- output_block_size = -1000;
+ h_block_size = -1000;
+ if(!display_byte_kilo_mega)
+ output_block_size = -1000;
break;
case 'k':
output_block_size = 1024;
+ display_byte_kilo_mega = 1;
break;
case MAX_DEPTH_OPTION: /* --max-depth=N */
@@ -626,6 +749,7 @@
case 'm': /* obsolescent */
output_block_size = 1024 * 1024;
+ display_byte_kilo_mega = 1;
break;
case 'l':
@@ -642,6 +766,7 @@
case 'B':
human_block_size (optarg, 1, &output_block_size);
+ display_byte_kilo_mega = 1;
break;
case 'D':