diff --git a/components/disk.graph/index.php b/components/disk.graph/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..598e360f173601909fa8f93c45e8ff0be3e3905b
--- /dev/null
+++ b/components/disk.graph/index.php
@@ -0,0 +1,26 @@
+<?
+	exec("/usr/local/bin/shame.py -a", $Shame);
+	for ( $i=1 ; $i < (count($Shame) - 1); $i++)
+	{
+		list($space, $place, $user, $size) = preg_split("/ +/", $Shame[$i]);
+		if ($i <= 12)
+		{
+			$item[]=$user;
+			$slice[]=preg_replace('/M/', '', ${size});
+		}
+		else {
+			$otherSize += preg_replace('/M/', '', ${size});
+		}
+	}
+//	$itemName[]="Other";
+//	$sliceSize[]=$otherSize;
+	$slice = array_merge(array($otherSize),$slice);
+	$item = array_merge(array("Other"), $item);
+
+/*	echo "<pre>";
+	print_r($slice);
+	print_r($item);*/
+
+	include("pieChart.php");
+	piechart("Top 12 Users of disk space", $slice, $item)
+?>
diff --git a/components/disk.graph/pieChart.php b/components/disk.graph/pieChart.php
new file mode 100644
index 0000000000000000000000000000000000000000..7edcc68ac4aaa25ea98e9e0f2385c824beb1d2a1
--- /dev/null
+++ b/components/disk.graph/pieChart.php
@@ -0,0 +1,156 @@
+<?
+
+function piechart($title, $slice, $itemName) {
+
+	function matchset($xx)
+	{
+	    $arrx = array_values($xx);
+	    $i = 0;
+	    while (list ($key, $val) = each ($arrx))
+		{
+			$xy[$i] = $val;
+			$i++;
+	    }
+	    $cnt = $i;
+		return $xy;
+	}
+	$sliced = matchset($slice);
+	$countqw = count($sliced);
+	
+	$ItemNames = matchset($itemName);
+	
+	// initialize some variables
+	$sum = 0;
+	$degrees = Array();
+	$diameter = 250;
+	$radius = $diameter/2;
+	
+	// calculate sum of slices
+	for ($x=0; $x<$countqw ; $x++)
+	{
+		$sum += $sliced[$x];
+	}
+	
+	// convert each slice into corresponding percentage of 360-degree circle
+	$degCount = 0;
+	for ($y=0; $y<$countqw; $y++)
+	{
+		if((($sliced[$y]/$sum) * 360) > '0')
+		{
+			$degrees[$degCount] = ($sliced[$y]/$sum) * 360;
+			$degCount++;
+		}	
+	}
+	
+	
+	// set up image and colours
+	Header("Content-Type: image/png");
+	$im = ImageCreate(550, 300);
+	
+	$black = ImageColorAllocateAlpha($im, 0, 0, 0, 0);
+	$white = ImageColorAllocateAlpha($im, 255, 255, 255, 127);
+	$hexCode = array("255,153,0","0,204,153","204,255,102","255,102,102","102,204,255","204,153,255","255,0,0","51,0,255","255,51,153","204,0,255","255,255,51","51,255,51","255,102,0");
+	// fill image with white
+	ImageFill($im, 0, 0, $white);
+	
+	// draw baseline
+	ImageLine($im, 150,150, 225, 150, $black);
+	
+	for ($z=0; $z<$countqw; $z++)
+	{
+		// calculate and draw arc corresponding to each slice
+		ImageArc($im, 150, 150, $diameter, $diameter, $last_angle,
+		($last_angle+$degrees[$z]), $black);
+		$last_angle = $last_angle+$degrees[$z];
+	
+		// calculate coordinate of end-point of each arc by obtaining
+		// length of segment and adding radius
+		// remember that cos() and sin() return value in radians
+		// and have to be converted back to degrees!
+		$end_x = round(150 + ($radius * cos($last_angle*pi()/180)));
+		$end_y = round(150 + ($radius * sin($last_angle*pi()/180)));
+	
+		// demarcate slice with another line
+		ImageLine($im, 150, 150, $end_x, $end_y, $black);
+	}
+	
+	// this section is meant to calculate the mid-point of each slice
+	// so that it can be filled with colour
+	
+	// initialize some variables
+	$prev_angle = 0;
+	$pointer = 0;
+	
+	for ($z=0; $z<$countqw; $z++)
+	{
+		// to calculate mid-point of a slice, the procedure is to use an angle
+		//bisector
+		// and then obtain the mid-point of that bisector
+		$pointer = $prev_angle + $degrees[$z];
+		$this_angle = ($prev_angle + $pointer) / 2;
+		$prev_angle = $pointer;
+	
+		// get end-point of angle bisector
+		$end_x = round(150 + ($radius * cos($this_angle*pi()/180)));
+		$end_y = round(150 + ($radius * sin($this_angle*pi()/180)));
+	
+		// given start point (150,150) and end-point above, mid-point can be
+		// calculated with standard mid-point formula
+		$mid_x = round((150+($end_x))/2);
+		$mid_y = round((150+($end_y))/2);
+			
+		// depending on which slice, fill with appropriate colour
+		$hexCodeSplit = explode(',',$hexCode[$z]);
+		$WedgeColor = ImageColorAllocate($im, $hexCodeSplit[0],$hexCodeSplit[1],$hexCodeSplit[2]);
+		
+		ImageFillToBorder($im, $mid_x, $mid_y, $black, $WedgeColor);		
+	}
+	
+	// write string
+	ImageString($im,5, 250, 10, "$title", $black);
+	
+	$red = ImageColorAllocate($im, 255, 153, 153);
+	$blue = ImageColorAllocate($im, 0, 0, 255);
+	
+	// Create Color key and slice description
+	$adjPosition = 40;
+	
+	for ($z=0; $z<$degCount; $z++)
+	{
+		$percent = ($degrees[$z]/360)*100;
+		$percent = round($percent,2);
+		$adjPosition = $adjPosition + 15;
+		$hexCodeSplit = explode(',',$hexCode[$z]);
+		$percentLen = strlen($percent);
+		if($percentLen == '4'){$percent = " "."$percent";}
+		if($percentLen == '3'){$percent = "  "."$percent";}
+		if($percentLen == '2'){$percent = "   "."$percent";}
+		if($percentLen == '1'){$percent = "    "."$percent";}
+		ImageString($im,2, 300, ($adjPosition+1), "$percent%", $black);
+	
+		$WedgeColor = ImageColorAllocate($im, $hexCodeSplit[0],$hexCodeSplit[1],$hexCodeSplit[2]);
+	
+		ImageFilledRectangle($im, 340, $adjPosition, 350, ($adjPosition+10), $black);
+		ImageFilledRectangle($im, 341, ($adjPosition+1), 349, ($adjPosition+9), $WedgeColor);
+		if($sliced[$z] >= "1000" && $sliced[$z] < "1000000")
+		{
+			$sliced[$z] = $sliced[$z]/1000;
+			$sliced[$z] = sprintf("%01.2f", "$sliced[$z]")."G";
+		}
+		else
+		$sliced[$z] = "$sliced[$z]"."M";
+		$sliceLen = strlen($sliced[$z]);
+		if($sliceLen == '5'){$sliced[$z] = " "."$sliced[$z]";}
+		if($sliceLen == '4'){$sliced[$z] = "  "."$sliced[$z]";}
+		if($sliceLen == '3'){$sliced[$z] = "   "."$sliced[$z]";}
+		if($sliceLen == '2'){$sliced[$z] = "    "."$sliced[$z]";}
+		if($sliceLen == '1'){$sliced[$z] = "     "."$sliced[$z]";}
+	
+		ImageString($im,2, 360, ($adjPosition+1), "$sliced[$z]", $black);
+		ImageString($im,2, 410, ($adjPosition+1), "$ItemNames[$z]", $black);
+	}
+	
+	// output to browser
+	ImagePNG($im);
+}
+?>
diff --git a/components/shame.php b/components/shame.php
new file mode 100644
index 0000000000000000000000000000000000000000..8625acee67f991a3ef40fc2ba59e4574b5081def
--- /dev/null
+++ b/components/shame.php
@@ -0,0 +1,19 @@
+<?	exec("/usr/local/bin/shame.py -a", $Shame);
+	$smarty->assign('title',"The SUCS Hall of Shame");
+	$o="<div style='text-align: center;'><img src=\"/images/shame.php\" alt=\"pie chart of top 12 disk users\"/></div>";
+
+	$o.="<table align=\"center\">\n";
+	$o.="\t<tr><th align=\"center\">User</th><th align=\"center\">Home Directory Size</th></tr>\n";
+	for ( $i=1 ; $i < (count($Shame) - 1); $i++)
+	{
+		list($space, $place, $user, $size) = preg_split("/ +/", $Shame[$i]);
+		if ($size > 0)
+			$o.="\t<tr><td align=\"center\">$user</td><td align=\"center\">${size}B</td></tr>\n";
+	}
+	$o.="</table>\n";
+
+	$o.=$Shame[count($Shame) - 1];
+	$o.="<br />\n";
+	//readfile("tail.html");
+	$smarty->assign('body', $o);
+?>
diff --git a/htdocs/images/shame.php b/htdocs/images/shame.php
new file mode 120000
index 0000000000000000000000000000000000000000..2f7e3141f979873624beb8381900c5e5579ea151
--- /dev/null
+++ b/htdocs/images/shame.php
@@ -0,0 +1 @@
+../../components/disk.graph/index.php
\ No newline at end of file