Fixes to dugraph

Dave Martindale dave at onfcanim.UUCP
Wed Jan 20 10:28:53 AEST 1988


Dale Worley's "dugraph" is a useful little program.  However, it has one
serious glitch: it fails badly on a directory where the space reported
by "du" for the directory itself is less than the sum of all of its
subdirectories.

At least on a recent 4BSD system, du reports disk usage in Kb, regardless
of the size of the blocks and fragments in the underlying filesystem.
If the filesystem uses 512-byte fragments, the total disk space used
by a file or a directory may not be an integral multiple of 1Kb, and
is then rounded to the nearest 1K for printing.  However, the true size
(not the rounded size) propagates up the tree.  When dugraph sums the
sizes of all subdirectories, the rounding errors accumulate and the
total may not match the size reported for the directory itself.

The patches below fix this problem.  They also make two other changes:

1) A leading slash on a pathname is taken as belonging to the first
   component, rather than creating an extra null node.  Thus a du of /usr
   will display the top-level directory as "/usr", not as nullstring with
   a subdirectory of "usr".  This also changes the handling of multiple
   adjacent slashes in a pathname - it's not clear what is "correct"
   anyway, but this gets rid of the useless null directories.

2) The "last" field in the tree node is useless, since essentially the
   same information can be found by looking at the right brother pointer.
   The field, plus the routine for setting it, have been deleted.

	Dave Martindale
	watmath!onfcanim!dave

------ feed to "patch" -------------------------------------------------------
*** dugraph.old	Tue Jan 19 10:19:52 1988
--- dugraph.c	Tue Jan 19 18:55:09 1988
***************
*** 18,24 ****
  			int			print_limit;
  								/* location we can't print on or
  								 * after */
- 			int			last;	/* are we last son of our father? */
  			char			name[1];	/* name */
  		  };
  
--- 18,23 ----
***************
*** 42,48 ****
  void			sort();
  void			calc_loc();
  void			blank();
- void			mark_last();
  void			calc_pc();
  void			output();
  void			position();
--- 41,46 ----
***************
*** 69,78 ****
  	/* print out the tree */
  	for (t = root->lson; t != NULL; t = t->rbrother)
  		{
- 		/* mark the last son of each directory */
  		/* figure out the print columns */
  		t->print_col = 0;
! 		dfs1(calc_pc, mark_last, t);
  		dfs1(output, NULL, t);
  		}
  	/* put blank space at end */
--- 67,75 ----
  	/* print out the tree */
  	for (t = root->lson; t != NULL; t = t->rbrother)
  		{
  		/* figure out the print columns */
  		t->print_col = 0;
! 		dfs1(calc_pc, NULL, t);
  		dfs1(output, NULL, t);
  		}
  	/* put blank space at end */
***************
*** 111,118 ****
  	 * down the tree, constructing nodes as needed */
  	for (t = root, np = name; np != NULL; np = np1)
  		{
  		/* extract the next directory-part */
! 		if ((np1 = strchr(np, '/')) != NULL)
  			{
  			/* we found a slash, replace it with a null, and position
  			 * np1 to point to the remainder of the name */
--- 108,118 ----
  	 * down the tree, constructing nodes as needed */
  	for (t = root, np = name; np != NULL; np = np1)
  		{
+ 		/* group any leading slashes with the name itself */
+ 		for (np1 = np; *np1 == '/'; np1++)
+ 			;
  		/* extract the next directory-part */
! 		if ((np1 = strchr(np1, '/')) != NULL)
  			{
  			/* we found a slash, replace it with a null, and position
  			 * np1 to point to the remainder of the name */
***************
*** 248,254 ****
  			cs += t1->size;
  			}
  		/* cs is the size accounted for by subdirectories */
! 		cs = t->size - cs;
  		}
  	/* cs is the size of the files in the directory itself */
  	/* convert cs to lines */
--- 248,257 ----
  			cs += t1->size;
  			}
  		/* cs is the size accounted for by subdirectories */
! 		if (cs >= t->size)
! 			cs = 0;
! 		else
! 			cs = t->size - cs;
  		}
  	/* cs is the size of the files in the directory itself */
  	/* convert cs to lines */
***************
*** 298,315 ****
  			}
  	}
  
- /* mark the last son of each directory */
- void mark_last(t)
- 	struct node	*t;
- 	{
- 	struct node	*t1, *t2;	/* scratch pointers */
- 	t->last = 0;
- 	for (t1 = t->lson, t2 = NULL; t1 != NULL; t2 = t1, t1 = t1->rbrother)
- 		;
- 	if (t2 != NULL)
- 		t2->last = 1;
- 	}
- 
  /* calculate the print columns */
  void calc_pc(t)
  	struct node	*t;
--- 301,306 ----
***************
*** 329,335 ****
  	position(t->loc);
  	printf("--%s%s", t->name, (t->lson != NULL ? "--+" : ""));
  	/* remove the bar for our father if we are the last son */
! 	if (t->last)
  		bar_count--;
  	/* add the location of the bar to the bar list if we have a son */
  	if (t->lson != NULL)
--- 320,326 ----
  	position(t->loc);
  	printf("--%s%s", t->name, (t->lson != NULL ? "--+" : ""));
  	/* remove the bar for our father if we are the last son */
! 	if (t->rbrother == NULL && bar_count > 0)
  		bar_count--;
  	/* add the location of the bar to the bar list if we have a son */
  	if (t->lson != NULL)



More information about the Comp.sources.bugs mailing list