#! /usr/bin/perl
#
#  Purpose:
#  FlowTracker_Grapher runs periodically (configurable) to update FlowTracker 
#  graphs with the latest data collected by FlowTracker_Collector.
#
#  Description:
#  The user initiates the script from a command line appending an "&" to put
#  it in the background. The script re-creates four graphs for each existing 
#  RRDtool file (i.e., last 24 hours, last 7 days, last month, last year.)
#  A set of rrdtool parameters, in the FlowViewer_Configuration.pm file,
#  permits the user to configure parameters like size and color, etc.. When
#  finished with all of the existing Trackings, the script will go to sleep for
#  the remainder of the specified graphing period.
#
#  Controlling Parameters (specified in FlowViewer_Configuration.pm):
#  Name                 Description
#  -----------------------------------------------------------------------
#  rrd_area             Color of the area underneath the graph
#  rrd_line             Color of the line at the top of the graphed area
#  rrd_width            Width of the graph
#  rrd_height           Height of the graph
#  rrd_font             Color of the font used in the graphs
#  rrd_back             Image background color
#  rrd_canvas           Color of the background of the actual graph
#  rrd_grid             Color of the minor grid lines
#  rrd_mgrid            Color of the major grid lines
#  rrd_frame            Color of the graph frame
#  rrd_shadea           Color for the top and left border
#  rrd_shadeb           Color for the right and bottom border
#  rrd_thick            Thickness of the line at the top of the graph
#  rrd_lower_limit      Bottom of the y-axis
#  rrd_slope_mode       "--slope-mode" will round off tops of graph  
#  rrd_vrule_color      Color of the line that indicates when the filter was changed
#
#  Modification history:
#  Author       Date            Vers.   Description
#  -----------------------------------------------------------------------
#  J. Loiacono  07/04/2006      3.0     Original version.
#  J. Loiacono  12/25/2006      3.1     Archives, lazy-mode, permissions
#  J. Loiacono  02/22/2007      3.2     Changes to incorporate Groups
#  J. Loiacono  12/07/2007      3.3     Alerts, flexible logging,
#                                       3 years, time-zones
#
#$Author$
#$Date$
#$Header$
#
###########################################################################
#
#               BEGIN EXECUTABLE STATEMENTS
#
 
use FlowViewer_Configuration;
use FlowViewer_Utilities;
use lib $cgi_bin_directory;

# Load the colors 
     
$colors_file = "$cgi_bin_directory/FlowGrapher_Colors"; 
     
open (COLORS,"<$colors_file") || die "Can't open colors file; $colors_file\n"; 
while (<COLORS>) { 
        chop;    
        ($red,$green,$blue,$color_1,$color_2) = split(/\s+/); 
        $color_name = $color_1; 
        if ($color_2 ne "") { $color_name = $color_1 . " " . $color_2; } 
        $R = &dec2hex($red);   if (length($R) < 2) { $R = "0" . $R; }  
        $G = &dec2hex($green); if (length($G) < 2) { $G = "0" . $G; }  
        $B = &dec2hex($blue);  if (length($B) < 2) { $B = "0" . $B; }  
        $hex_colors{$color_name} =  $R . $G . $B; 
}    
$hex_colors{"standard"} = $rrd_area; 
sub dec2hex($) { return sprintf("%lx", $_[0]) } 

if ($time_zone eq "") { 
        open(DATE,"date 2>&1|");   
        while (<DATE>) {  
                ($d_tz,$m_tz,$dt_tz,$t_tz,$time_zone,$y_tz) = split(/\s+/,$_);  
        }        
}  

$a = 0; while ($a == 0) {

	if (($log_grapher_short eq "Y") || ($log_grapher_long eq "Y")) { open (LOG,">>$log_directory/FlowTracker_Grapher.log"); }
	if ($debug_tracker eq "Y") { open(DEBUG,">$work_directory/DEBUG_TRACKER"); }

	$end_rrd        = time;
	$num_trackings  = 0;
	$groups_exist   = 0;
	$archives_exist = 0;
	%trackings      = ();

	if (($log_grapher_short eq "Y") || ($log_grapher_long eq "Y") || (debug_grapher eq "Y")) { 
                $current_time = time;
                $current_time_out = epoch_to_date($current_time,"LOCAL"); 
                $current_time_rrd = $current_time_out . " $time_zone"; 
                $current_time_rrd =~ s/:/\\:/g; 

		if (($log_grapher_short eq "Y") || ($log_grapher_long eq "Y")) { print LOG   "Starting a graphing loop at: $current_time_out\n"; }
		if ($debug_tracker eq "Y") { print DEBUG "Starting a graphing loop at: $current_time_out\n"; }
	}

	# Work through each tracking
	
	while ($filter_file = <$filter_directory/*>) {
	
		($directory,$tracking) = $filter_file =~ m/(.*\/)(.*)$/;
		($tracking,$extension) = split(/\./,$tracking);
	
		$num_trackings++;

                # Load information from filter file for graph and HTML page re-creation
      
		%FORM = ();
		$tracking_type = "";
		@component_links = ();
		$vrule_1 = "";
		$vrule_2 = "";
		$vrule_3 = "";
		$hrule = "";
		$alert_threshold = 0;
		$call_string = "";
		$sampling_multiplier = "";

                open (FILTER,"<$filter_file"); 
                while (<FILTER>) { 
                        chop;    
                        $key = substr($_,0,8); 
                        if ($key eq " input: ") { 
                                ($input,$field,$field_value) = split(/: /); 

				if ($field eq "tracking_type")   { $tracking_type = $field_value; }

				if ($field eq "tracking_label") { 
					$FORM{tracking_label} = $field_value;
					$trackings{$tracking} = $field_value;
					$tracking_label = $field_value; }
				if ($field eq "general_comment") { 
					$FORM{general_comment} = $field_value;
					$general_comment = $field_value; }
				if ($field eq "alert_threshold") { 
					$FORM{alert_threshold} = $field_value;
					$alert_threshold = $field_value; }
				if ($field eq "alert_frequency") { 
					$FORM{alert_frequency} = $field_value;
					$alert_frequency = $field_value; }
				if ($field eq "alert_destination") { 
					$FORM{alert_destination} = $field_value;
					$alert_destination = $field_value; }
				if ($field eq "sampling_multiplier") { 
					$FORM{sampling_multiplier} = $field_value;
					$sampling_multiplier = $field_value;
					$call_string .= "sampling_multiplier=$field_value&"; }

 				if ($field eq "device_name") { 
					$FORM{device_name} = $field_value;
					$call_string  = "device_name=$field_value&"; }
				if ($field eq "source_addresses") { 
					$FORM{source_address} = $field_value;
					$call_string .= "source_addresses=$field_value&"; }
				if ($field eq "source_ports") { 
					$FORM{source_port} = $field_value;
					$call_string .= "source_ports=$field_value&"; } 
				if ($field eq "source_ifs") { 
					$FORM{source_if} = $field_value;
					$call_string .= "source_ifs=$field_value&"; }
				if ($field eq "source_ases") { 
					$FORM{source_as} = $field_value;
					$call_string .= "source_ases=$field_value&"; }
				if ($field eq "dest_addresses") { 
					$FORM{dest_address} = $field_value;
					$call_string .= "dest_addresses=$field_value&"; }
				if ($field eq "dest_ports") { 
					$FORM{dest_port} = $field_value;
					$call_string .= "dest_ports=$field_value&"; }
				if ($field eq "dest_ifs") { 
					$FORM{dest_if} = $field_value; 
					$call_string .= "dest_ifs=$field_value&"; }
				if ($field eq "dest_ases") { 
					$FORM{dest_as} = $field_value;
					$call_string .= "dest_ases=$field_value&"; }
				if ($field eq "protocols") { 
					$FORM{protocols} = $field_value;
					$call_string .= "protocols=$field_value&"; } 
				if ($field eq "tos_fields") { 
					$FORM{tos_fields} = $field_value;
					$call_string .= "tcp_flags=$field_value&"; }
				if ($field eq "tcp_flags") { 
					$FORM{tcp_flags} = $field_value;
					$call_string .= "tos_fields=$field_value&"; }
				if ($field eq "exporter") { 
					$FORM{exporter} = $field_value;
					$call_string .= "exporter=$field_value&"; }
				if ($field eq "nexthop_ips") { 
					$FORM{nexthop_ip} = $field_value;
					$call_string .= "nexthop_ips=$field_value&"; }

                                if ($field eq "revision") { 

                                        ($notate_graphs,$revision_date,$revision_comment) = split(/\|/,$field_value);  
                                        $revision_date_out = epoch_to_date($revision_date,"LOCAL"); 
                                        $revision_date_out =~ s/:/\\:/g;

                                        if ($notate_graphs eq "Y") {   
						if (($vrule_1 ne "") && ($vrule_2 ne "") && ($vrule_3 ne "")) {
							$vrule_1 = $vrule_2;
							$vrule_2 = $vrule_3;
                                                        $vrule_3 = "VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; 
						}
                                                if ($vrule_1 eq "") { 
                                                        $vrule_1 = "VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; 
                                                        next; }  
                                                elsif ($vrule_2 eq "") { 
                                                        $vrule_2 = "VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; 
                                                        next; }  
                                                elsif ($vrule_3 eq "") { 
                                                        $vrule_3 = "VRULE:$revision_date#$rrd_vrule_color:\"$revision_date_out\\: $revision_comment\\n\""; 
                                                        next; }  
                                        } 
                                }       

				if ($alert_threshold > 0) {
					$hrule = "    HRULE:$alert_threshold#$rrd_hrule_color";
				}
			}
                }                
                close (FILTER);

		$call_string =~ s/\s+//g; 
		$trackings{$tracking} .= "^" . $general_comment;
		
		if ($tracking_type eq "Group") {
                	open (FILTER,"<$filter_file"); 
                	while (<FILTER>) { 
                        	chop;    
                        	$key = substr($_,0,8); 
                        	if ($key eq " input: ") { 
					next;
				} else {
				        ($component_position,$component_label,$component_color) = split(/\^/);
					$component_file = $component_label; 
					$component_file =~ s/^\s+//; 
					$component_file =~ s/\s+$//; 
					$component_file =~ s/\&/-/g; 
					$component_file =~ s/\//-/g; 
					$component_file =~ s/\(/-/g; 
					$component_file =~ s/\)/-/g; 
					$component_file =~ s/\./-/g; 
					$component_file =~ s/\s+/_/g; 
					$component_file =~ tr/[A-Z]/[a-z]/;
					$component_html  = $tracker_short ."/". $component_file ."/index.html";
					push (@component_links,$component_html);
				}
			}
		}

		$html_directory = $tracker_directory ."/". $tracking;
		$html_file      = $html_directory ."/index.html";
		$tracking_file  = $tracking;

		&create_FlowTracker_html;

		# Look to skip Archives

		if ($extension eq "archive") { 
			$trackings{$tracking} .= "^Archive";
			$archives_exist = 1;
			next;
		} elsif ($tracking_type eq "Group") {
			$trackings{$tracking} .= "^Group";
			$groups_exist = 1;
		}

		if ($log_grapher_long eq "Y") { print LOG "creating graphs for: $tracking\n"; }
	
		# Create each of the four graphs for this tracking
		
                $rrdtool_file = "$rrdtool_directory/$tracking" . ".rrd";  

		foreach $graph_type ("Daily", "Weekly", "Monthly", "Yearly", "Three Years") {
		
			$x_grid  = "";

			if ($graph_type eq "Daily") {
				$start_rrd = $end_rrd - 86400;
                                $line_peak = "",
				$sample = "     Data collected over 5 minute periods          Graph Last Updated\\: $current_time_rrd";
				$rrd_title = "\"Last 24 Hours\"";
				if ($labels_in_titles) { $rrd_title = "\"$tracking_label\: Last 24 Hours\""; }
				$graph_file = "$tracker_directory/$tracking/daily.png"; }
			elsif ($graph_type eq "Weekly") {
				$start_rrd = $end_rrd - (7*86400);
                                $line_peak = "LINE$rrd_thick:flowpeak#$rrd_peak:\"Peak 5 Minute Period\"",
				$sample = "     Data averaged over 30 minute periods          Graph Last Updated\\: $current_time_rrd";
				$rrd_title = "\"Last 7 Days\"";
				if ($labels_in_titles) { $rrd_title = "\"$tracking_label\: Last 7 Days\""; }
				$graph_file = "$tracker_directory/$tracking/weekly.png"; }
			elsif ($graph_type eq "Monthly") {
				$start_rrd = $end_rrd - (28*86400);
                                $line_peak = "LINE$rrd_thick:flowpeak#$rrd_peak:\"Peak 5 Minute Period\"",
				$sample = "     Data averaged over 2 hour periods             Graph Last Updated\\: $current_time_rrd";
				$rrd_title = "\"Last 4 Weeks\"";
				if ($labels_in_titles) { $rrd_title = "\"$tracking_label\: Last 4 Weeks\""; }
				$graph_file = "$tracker_directory/$tracking/monthly.png"; }
			elsif ($graph_type eq "Yearly") {
				$start_rrd = $end_rrd - (365*86400);
                                $line_peak = "LINE$rrd_thick:flowpeak#$rrd_peak:\"Peak 5 Minute Period\"",
				$sample = "     Data averaged over 24 hour periods            Graph Last Updated\\: $current_time_rrd";
				$rrd_title = "\"Last 12 Months\"";
				if ($labels_in_titles) { $rrd_title = "\"$tracking_label\: Last 12 Months\""; }
				$graph_file = "$tracker_directory/$tracking/yearly.png";
			}
			elsif ($graph_type eq "Three Years") {
				$start_rrd = $end_rrd - (3*365*86400);
                                $line_peak = "LINE$rrd_thick:flowpeak#$rrd_peak:\"Peak 5 Minute Period\"",
				$sample = "     Data averaged over 24 hour periods            Graph Last Updated\\: $current_time_rrd";
				$rrd_title = "\"Last Three Years\"";
				if ($labels_in_titles) { $rrd_title = "\"$tracking_label\: Last Three Years\""; }
				$x_grid = "--x-grid MONTH:1:YEAR:1:MONTH:2:2800000:%b";
				$graph_file = "$tracker_directory/$tracking/threeyears.png";
			}

			if ($extension eq "grp") {

				$DEF_parameters  = "";
				$AREA_parameters = "";
				@components = ();

        			open (GROUP,"<$filter_file"); 
        			@group_lines = <GROUP>; 
        			close (GROUP); 
     
        			foreach $group_line (@group_lines) { 
                			if ($group_line =~ / input:/) { next; }
                			else { push (@components,$group_line); } 
        			}

				$num_components = 0;
				$first_below = 1;
        			foreach $component (@components) { 

				        $num_components++;
				        chop $component;
				        ($component_position,$component_label,$component_color) = split(/\^/,$component);
				 
					$component_file = $component_label; 
					$component_file =~ s/^\s+//; 
					$component_file =~ s/\s+$//; 
					$component_file =~ s/\&/-/g; 
					$component_file =~ s/\//-/g; 
					$component_file =~ s/\(/-/g; 
					$component_file =~ s/\)/-/g; 
					$component_file =~ s/\./-/g; 
					$component_file =~ s/\s+/_/g; 
					$component_file =~ tr/[A-Z]/[a-z]/;
					$component_rrd  = $rrdtool_directory ."/". $component_file .".rrd";

					$component_archive  = $rrdtool_directory ."/". $component_file .".archive";
					if (-e $component_archive) { $component_rrd = $component_archive; }
				 
				        $DEF_parameters  .= "DEF:flowbits$num_components=$component_rrd:flowbits:AVERAGE ";
				        $AREA_parameters .= "COMMENT:\"     \" ";
				 
				        if ($component_position < 200) {
				                $AREA_parameters .= "AREA:flowbits$num_components#$hex_colors{$component_color}:\"$component_label\\n\":STACK ";
				        } elsif (($component_position >= 200) && ($first_below)) {
				                $DEF_parameters .= "CDEF:flowbits_below$num_components=flowbits$num_components,-1,* ";
				                $AREA_parameters .= "AREA:flowbits_below$num_components#$hex_colors{$component_color}:\"$component_label\\n\" ";
				                $first_below = 0;
				        } else {
				                $DEF_parameters .= "CDEF:flowbits_below$num_components=flowbits$num_components,-1,* ";
				                $AREA_parameters .= "AREA:flowbits_below$num_components#$hex_colors{$component_color}:\"$component_label\\n\":STACK ";
				        }
				}
			
				@graph_parameters =  
			        ('--title',"$rrd_title",  
			        '--start',$start_rrd,  
			        '--end',$end_rrd,  
			        '--width',$rrd_width,  
			        '--height',$rrd_height,  
			        '--interlace',  
                                '--lazy',
			        '--vertical-label',"\"Bits per Second\"",  
			        $x_grid,
			        $rrd_slope_mode,  
			        "--color=FONT#$rrd_font",  
			        "--color=BACK#$rrd_back",  
			        "--color=CANVAS#$rrd_canvas",  
			        "--color=GRID#$rrd_grid",  
			        "--color=MGRID#$rrd_mgrid",  
			        "--color=FRAME#$rrd_frame",  
			        "--color=SHADEA#$rrd_frame",  
			        "--color=SHADEB#$rrd_frame",  
			        '--lower-limit',$rrd_lower_limit,  
			        '--alt-autoscale', 
			        $DEF_parameters, 
                                "COMMENT:\"$sample   \"",
                                "COMMENT:\"\\n\"",
			        $AREA_parameters,
                                "COMMENT:\"\\n\"",
                                $vrule_1,
                                $vrule_2,
                                $vrule_3);

			} else {

                        	@graph_parameters =
                                ('--title',"$rrd_title",
                                '--start',$start_rrd,
                                '--end',$end_rrd,
                                '--width',$rrd_width,
                                '--height',$rrd_height,
                                '--interlace',
                                '--lazy',
                                '--vertical-label',"\"Bits per Second\"",
			        $x_grid,
                                $rrd_slope_mode,
                                "--color=FONT#$rrd_font",
                                "--color=BACK#$rrd_back",
                                "--color=CANVAS#$rrd_canvas",
                                "--color=GRID#$rrd_grid",
                                "--color=MGRID#$rrd_mgrid",
                                "--color=FRAME#$rrd_frame",
                                "--color=SHADEA#$rrd_frame",
                                "--color=SHADEB#$rrd_frame",
                                '--lower-limit',$rrd_lower_limit,
                                "DEF:flowbits=$rrdtool_file:flowbits:AVERAGE",
                                "DEF:flowpeak=$rrdtool_file:flowbits:MAX",
                                'VDEF:flowbitsmax=flowbits,MAXIMUM',
                                'VDEF:flowbitsavg=flowbits,AVERAGE',
                                'VDEF:flowbitsmin=flowbits,MINIMUM',
                                'VDEF:flowbitspct=flowbits,95,PERCENT',
                                "AREA:flowbits#$rrd_area",
                                "LINE$rrd_thick:flowbits#$rrd_line:",
                                "COMMENT:\"$sample   \"",
                                "COMMENT:\"\\n\"",
                                "COMMENT:\"     95th percentile    \"",
                                "GPRINT:flowbitspct:\"%6.2lf %Sbps\"",
                                "COMMENT:\"             \"",
				$line_peak,
                                "COMMENT:\"\\n\"",
                                "COMMENT:\"             Maximum    \"",
                                "GPRINT:flowbitsmax:\"%6.2lf %Sbps \"",
                                "COMMENT:\"\\n\"",
                                "COMMENT:\"             Average    \"",
                                "GPRINT:flowbitsavg:\"%6.2lf %Sbps \"",
                                "COMMENT:\"\\n\"",
                                "COMMENT:\"             Minimum    \"",
                                "GPRINT:flowbitsmin:\"%6.2lf %Sbps \"",
                                "COMMENT:\"                        [List Values]\\n\"",
                                "COMMENT:\"\\n\"",
                                $vrule_1,
                                $vrule_2,
                                $vrule_3,
				$hrule);
			}
 
                        $rrdgraph_command = "$rrdtool_bin_directory/rrdtool graph " . "$graph_file " . "@graph_parameters " . ">/dev/null";
			if ($debug_tracker eq "Y") { print DEBUG "\n\n$rrdgraph_command\n\n"; }

                        system($rrdgraph_command);

			chmod $graph_file_perms, $graph_file;

                        if ($debug_tracker eq "Y") { print DEBUG "finished $graph_type for $graph_file\n"; }
		}

	}

	# Update the Active Trackings HTML file

	$active_trackings_webpage = "$tracker_directory/$actives_webpage";
	open(TRACKINGS,">$active_trackings_webpage");

	print TRACKINGS "<html>\n"; 
	print TRACKINGS "<head>\n"; 
	print TRACKINGS "<title>\n"; 
	print TRACKINGS "FlowTracker Active Trackings\n"; 
	print TRACKINGS "</title>\n"; 
	print TRACKINGS "</head>\n"; 
	print TRACKINGS "<body bgcolor=$bg_color text=$text_color link=$link_color vlink=$vlink_color>\n"; 
	print TRACKINGS "<style type=text/css><!-- A { text-decoration:none } --></style>"; 
	print TRACKINGS "<center>\n"; 
	print TRACKINGS "<font face=arial>";
        print TRACKINGS "<table>\n";  
        print TRACKINGS "<tr valign=middle>\n";  
        print TRACKINGS "<td>\n";  
	print TRACKINGS "<a href=$cgi_bin_short/FlowTracker.cgi><img src=$tracker_short/FlowTracker.png border=0 usemap=#FlowTracker_Map></a>\n"; 
	if ($user_logo ne "") {
	        print TRACKINGS "<a href=$user_hyperlink>";
	        print TRACKINGS "<img src=$reports_short/$user_logo border=0>";
	        print TRACKINGS "</a>";
	}
        print TRACKINGS "</td><td width=30></td>\n";  
        print TRACKINGS "<td valign=bottom>\n";  
        print TRACKINGS "<center><h3>$trackings_title\n";  
        print TRACKINGS "<br>Netflow Trackings</h3>\n";  
        print TRACKINGS "</center></td>\n";  
        print TRACKINGS "</tr>\n";  
        print TRACKINGS "</table>\n";
        print TRACKINGS "<br><br>\n";  
	print TRACKINGS "<font face=arial size=-1>";
        print TRACKINGS "<table frame=border rules=all cellpadding=15>\n";

	@sorted_trackings = sort (keys (%trackings));

	# Output the Individual Trackings

	print TRACKINGS "<th>Individual Trackings</th>\n";
	print TRACKINGS "<th>General Comment</th>\n";

	foreach $tracking (@sorted_trackings) {
		($tracking_label,$general_comment,$class) = split(/\^/,$trackings{$tracking});
		if ($class ne "") { next; }
		if ($debug_tracker eq "Y") { print DEBUG "active tracking: $tracking\n"; }
		$tracking_link = "<a href=$tracker_short/$tracking>$tracking_label</a>";
		print TRACKINGS "<tr valign=top>\n";
		print TRACKINGS "<td>\n";
		print TRACKINGS "<font face=arial size=-1>";
		print TRACKINGS "$tracking_link";
		print TRACKINGS "</td>\n";
		print TRACKINGS "<td>\n";
		print TRACKINGS "<font face=arial size=-1>";
		print TRACKINGS "$general_comment<br>";
		print TRACKINGS "</td>\n";
		print TRACKINGS "</tr>\n";
	}

	# Output the Group Trackings

	if ($groups_exist) {

		print TRACKINGS "<th>Group Trackings</th>\n";
		print TRACKINGS "<th>General Comment</th>\n";
	
		foreach $tracking (@sorted_trackings) {
			($tracking_label,$general_comment,$class) = split(/\^/,$trackings{$tracking});
			if ($class ne "Group") { next; }
			if ($debug_tracker eq "Y") { print DEBUG "group tracking: $tracking\n"; }
			$tracking_link = "<a href=$tracker_short/$tracking>$tracking_label</a>";
			print TRACKINGS "<tr valign=top>\n";
			print TRACKINGS "<td>\n";
			print TRACKINGS "<font face=arial size=-1>";
			print TRACKINGS "$tracking_link";
			print TRACKINGS "</td>\n";
			print TRACKINGS "<td>\n";
			print TRACKINGS "<font face=arial size=-1>";
			print TRACKINGS "$general_comment<br>";
			print TRACKINGS "</td>\n";
			print TRACKINGS "</tr>\n";
		}
	}

	# Output the Archived Trackings

	if ($archives_exist) {

		print TRACKINGS "<th>Archived Trackings</th>\n";
		print TRACKINGS "<th>General Comment</th>\n";
	
		foreach $tracking (@sorted_trackings) {
			($tracking_label,$general_comment,$class) = split(/\^/,$trackings{$tracking});
			if ($class ne "Archive") { next; }
			if ($debug_tracker eq "Y") { print DEBUG "archived tracking: $tracking\n"; }
			$tracking_link = "<a href=$tracker_short/$tracking>$tracking_label</a>";
			print TRACKINGS "<tr valign=top>\n";
			print TRACKINGS "<td>\n";
			print TRACKINGS "<font face=arial size=-1>";
			print TRACKINGS "$tracking_link";
			print TRACKINGS "</td>\n";
			print TRACKINGS "<td>\n";
			print TRACKINGS "<font face=arial size=-1>";
			print TRACKINGS "$general_comment<br>";
			print TRACKINGS "</td>\n";
			print TRACKINGS "</tr>\n";
		}
	}

        print TRACKINGS "</table>\n";
	print TRACKINGS "</body>\n"; 
	print TRACKINGS "</html>\n"; 

	close(TRACKINGS);

	chmod $actives_file_perms, $active_trackings_webpage;

	# Update log and go to sleep for what remains of 5-minute period

       	$end_graphing_time = time;
       	$loop_time = $end_graphing_time - $end_rrd;
       	$sleep_period = $graphing_period - $loop_time;

       	if (($log_grapher_short eq "Y") || ($log_grapher_long eq "Y")) { print LOG "Finished with this loop. $num_trackings graph sets created. Loop took: $loop_time seconds  sleep_period: $sleep_period\n\n"; }

	close (LOG);
	close (DEBUG);

       	sleep ($sleep_period);
}
