summaryrefslogtreecommitdiff
path: root/other/tor/bin/rrd-graph
diff options
context:
space:
mode:
Diffstat (limited to 'other/tor/bin/rrd-graph')
-rwxr-xr-xother/tor/bin/rrd-graph413
1 files changed, 413 insertions, 0 deletions
diff --git a/other/tor/bin/rrd-graph b/other/tor/bin/rrd-graph
new file mode 100755
index 0000000..63c5c43
--- /dev/null
+++ b/other/tor/bin/rrd-graph
@@ -0,0 +1,413 @@
+#!/usr/bin/perl -w
+
+use strict;
+use RRDs;
+use BER;
+
+my $HOSTNAME = `hostname`;
+
+#my $IMG_URL = 'http://images.noreply.org/tor-running-routers/';
+#my $IMG_URL = 'http://new.noreply.org/tor-running-routers/';
+my $IMG_URL = '';
+my $NOW = time;
+my $GMTIME = gmtime($NOW);
+my $START_AT = $NOW-4*30*24*3600;
+my $END_AT = $NOW-4*3600;
+my $OLD_AT = $NOW-7*24*3600;
+my $RRD = '/home/weasel/www/www.noreply.org/Build/other/tor/rrd/running_Routers.rrd';
+my $RRD_DIR = '/home/weasel/www/www.noreply.org/Build/other/tor/rrd/nodes';
+my $INDEX_DIR = '/home/weasel/www/www.noreply.org/Build/other/tor/index';
+my $RESULT_DIR = 'result.new';
+
+# Get list of RRD files
+opendir(D,$RRD_DIR) or die ("Cannot opendir $RRD_DIR: $!\n");
+my @SOURCES = grep { /\.rrd$/ } readdir(D);
+@SOURCES = grep {
+ my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+ $atime,$mtime,$ctime,$blksize,$blocks) = stat($RRD_DIR.'/'.$_);
+ $mtime >= $START_AT;
+ } @SOURCES;
+closedir(D);
+
+# Read hash <-> name mapping
+my %hashes_router;
+opendir(D,$INDEX_DIR) or die ("Cannot opendir $INDEX_DIR: $!\n");
+my @NAME = grep { /\.name$/ } readdir(D);
+closedir(D);
+for my $hash (@NAME) {
+ my $f = $INDEX_DIR.'/'.$hash;
+ open (F, $f) or warn("Cannot open $f: $!\n"), next;
+ my $name = <F>;
+ my $platform = <F>;
+ my $published = <F>;
+ chomp $name;
+ chomp $platform;
+ chomp $published;
+ close F;
+ $hash =~ s/\.name$//;
+ $hashes_router{$hash} = {name => $name, platform => $platform, published => $published };
+};
+
+@SOURCES = grep { !/^TRAF-/ } @SOURCES;
+@SOURCES = sort {
+ my $aa = $a;
+ my $bb = $b;
+ $aa =~ s/\.rrd//;
+ $bb =~ s/\.rrd//;
+ lc($hashes_router{$aa}->{'name'}) cmp lc($hashes_router{$bb}->{'name'}) ||
+ $a cmp $b
+ } @SOURCES;
+
+my @params = 'MAGIX1';
+push @params, sprintf('MAGIX2');
+push @params, sprintf('-e %s', $END_AT);
+#push @params, sprintf('-e %s', $NOW- 2*24*3600);
+push @params, sprintf('-t %s', "Running routers");
+push @params, sprintf('-aPNG');
+push @params, sprintf('-v %s', "# Routers");
+#push @params, sprintf('-w %d', 600);
+#push @params, sprintf('-h %d', 400);
+push @params, sprintf('-w %d', 497);
+push @params, sprintf('-h %d', 301);
+#push @params, sprintf('-h %d', 271);
+
+push @params, sprintf('DEF:%s=%s:%s:%s', 'd_runningVerified' , $RRD, 'runningVerified', 'AVERAGE');
+push @params, sprintf('CDEF:%s=%s' , 'c_runningVerified' , 'd_runningVerified');
+push @params, sprintf('DEF:%s=%s:%s:%s', 'd_runningUnverified' , $RRD, 'runningUnverified', 'AVERAGE');
+push @params, sprintf('CDEF:%s=%s' , 'c_runningUnverified' , 'd_runningUnverified');
+push @params, sprintf('DEF:%s=%s:%s:%s', 'd_exit80Verified' , $RRD, 'exit80Verified', 'AVERAGE');
+push @params, sprintf('CDEF:%s=%s' , 'c_exit80Verified' , 'd_exit80Verified');
+
+push @params, sprintf('DEF:%s=%s:%s:%s', 'd_f_runningVerified' , $RRD, 'fastRunningVerified', 'AVERAGE');
+push @params, sprintf('CDEF:%s=%s' , 'c_f_runningVerified' , 'd_f_runningVerified');
+push @params, sprintf('DEF:%s=%s:%s:%s', 'd_f_runningUnverified' , $RRD, 'fastRunningUnverifi', 'AVERAGE');
+push @params, sprintf('CDEF:%s=%s' , 'c_f_runningUnverified' , 'd_f_runningUnverified');
+push @params, sprintf('DEF:%s=%s:%s:%s', 'd_f_exit80Verified' , $RRD, 'fastExit80Verified', 'AVERAGE');
+push @params, sprintf('CDEF:%s=%s' , 'c_f_exit80Verified' , 'd_f_exit80Verified');
+
+#push @params, sprintf('%s:%s#%s:%s' , 'AREA' , 'c_runningVerified' , '7777FF', 'verified Nodes' );
+#push @params, sprintf('%s:%s#%s:%s' , 'STACK' , 'c_runningUnverified' , 'FF7700', 'unverified Nodes' );
+#push @params, sprintf('%s:%s#%s:%s' , 'LINE3' , 'c_exit80Verified' , '00FF00', 'verified Nodes exiting to port 80' );
+push @params, sprintf('%s:%s#%s:%s' , 'AREA' , 'c_runningVerified' , 'AAAAFF', 'verified Nodes' );
+push @params, sprintf('%s:%s#%s:%s' , 'STACK' , 'c_runningUnverified' , 'FF7700', '+unverified Nodes' );
+push @params, sprintf('%s:%s#%s:%s' , 'LINE2' , 'c_exit80Verified' , 'BBFFBB', 'verified Nodes exiting to port 80' );
+
+push @params, sprintf('%s:%s#%s:%s' , 'LINE3' , 'c_f_runningVerified' , '0000FF', 'fast verified Nodes' );
+push @params, sprintf('%s:%s#%s:%s' , 'STACK' , 'c_f_runningUnverified' , 'FF0000', '+fast unverified Nodes' );
+push @params, sprintf('%s:%s#%s:%s' , 'LINE3' , 'c_f_exit80Verified' , '00FF00', 'fast verified Nodes exiting to port 80' );
+
+push @params, sprintf('CDEF:%s=d_runningVerified,0,*,%s,+' , 'zeroline' , '0');
+push @params, sprintf('%s:%s' , 'LINE1' , 'zeroline' );
+
+
+
+my @totalTraffic = 'MAGIX1';
+push @totalTraffic, sprintf('MAGIX2');
+#push @totalTraffic, sprintf('-s %s', $START_AT);
+push @totalTraffic, sprintf('-e %s', $END_AT);
+#push @totalTraffic, sprintf('-e %s', $NOW- 2*24*3600);
+push @totalTraffic, sprintf('-t %s', "Total Traffic");
+push @totalTraffic, sprintf('-aPNG');
+push @totalTraffic, sprintf('-v %s', "Bandwidth Used");
+#push @totalTraffic, sprintf('-w %d', 600);
+#push @totalTraffic, sprintf('-h %d', 400);
+push @totalTraffic, sprintf('-w %d', 497);
+push @totalTraffic, sprintf('-h %d', 201);
+#push @totalTraffic, sprintf('-h %d', 301);
+#push @totalTraffic, sprintf('-h %d', 271);
+
+
+my %body;
+my %index;
+my $traf_item_counter = 0;
+
+for my $source (@SOURCES) {
+ my $hash = $source;
+ $hash =~ s/\.rrd$//;
+ my $name = $hashes_router{$hash}->{'name'};
+ my $platform = $hashes_router{$hash}->{'platform'};
+ my $published = $hashes_router{$hash}->{'published'};
+ my $def = $name;
+ my $cdef = 'c_'.$def;
+ my $label = $def;
+
+ my $source_traffic = $RRD_DIR .'/TRAF-'. $source;
+ $source = $RRD_DIR .'/'. $source;
+
+ my (undef,undef,undef,undef,undef,undef,undef,undef, undef,$mtime,undef,undef,undef) = stat($source);
+ my $section = $mtime < $OLD_AT ? 'old' : 'current';
+
+
+ my @this;
+ push @this, sprintf($RESULT_DIR.'/node-%s.png', $hash);
+ push @this, sprintf('-s %s', $START_AT);
+ push @this, sprintf('-e %s', $END_AT);
+ push @this, sprintf('-t %s', "$name");
+ push @this, sprintf('-aPNG');
+ push @this, sprintf('-v %s', "running");
+ push @this, sprintf('-w %d', 150);
+ push @this, sprintf('-h %d', 50);
+
+ push @this, sprintf('DEF:%s=%s:%s:%s', 'd_runningVerified' , $source, 'runningVerified', 'AVERAGE');
+ push @this, sprintf('CDEF:%s=%s' , 'c_runningVerified' , 'd_runningVerified');
+
+ push @this, sprintf('DEF:%s=%s:%s:%s', 'd_runningUnverified' , $source, 'runningUnverified', 'AVERAGE');
+ push @this, sprintf('CDEF:%s=%s' , 'c_runningUnverified' , 'd_runningUnverified');
+
+ push @this, sprintf('DEF:%s=%s:%s:%s', 'd_exit80Verified' , $source, 'exit80Verified', 'AVERAGE');
+ push @this, sprintf('CDEF:c_exit80Verified=d_exit80Verified,0.5,*,c_runningVerified,*');
+
+ push @this, sprintf('%s:%s#%s' , 'AREA' , 'c_runningVerified' , '7777FF' );
+ push @this, sprintf('%s:%s#%s' , 'STACK' , 'c_runningUnverified' , 'FF7700' );
+ push @this, sprintf('%s:%s#%s' , 'AREA' , 'c_exit80Verified' , '00FF00' );
+
+ push @this, sprintf('CDEF:%s=d_runningVerified,0,*,%s,+' , 'zeroline' , '0');
+ push @this, sprintf('%s:%s' , 'LINE1' , 'zeroline' );
+
+ my ($averages,$xsize,$ysize) = RRDs::graph @this;
+ warn RRDs::error if RRDs::error;
+
+ $body{$section} .= "<h2><a name=\"$hash\">$name</a></h2>".
+ "<p>".
+ "Last descriptor data:".
+ "<blockquote>".
+ "platform $platform<br>".
+ "published $published".
+ "</blockquote>".
+ "<p><img width=\"$xsize\" height=\"$ysize\" alt=\"$name running\" src=\"$IMG_URL"."node-$hash.png\">\n";
+ $index{$section} .= "<li><a href=\"$section.html#$hash\">$name</a></li>\n";
+
+ if (-e $source_traffic) {
+ $traf_item_counter++;
+ push @totalTraffic, sprintf('DEF:read%d=%s:read:AVERAGE', $traf_item_counter, $source_traffic);
+ push @totalTraffic, sprintf('DEF:write%d=%s:write:AVERAGE', $traf_item_counter, $source_traffic);
+ push @totalTraffic, sprintf('DEF:max_read%d=%s:read:MAX', $traf_item_counter, $source_traffic);
+ push @totalTraffic, sprintf('DEF:max_write%d=%s:write:MAX', $traf_item_counter, $source_traffic);
+ #push @totalTraffic, sprintf('DEF:min_read%d=%s:read:MIN', $traf_item_counter, $source_traffic);
+ #push @totalTraffic, sprintf('DEF:min_write%d=%s:write:MIN', $traf_item_counter, $source_traffic);
+ push @totalTraffic, sprintf('DEF:max_capacity%d=%s:capacity:MAX', $traf_item_counter, $source);
+
+ push @totalTraffic, sprintf('CDEF:cleanread%d=read%d,UN,0,read%d,IF', $traf_item_counter, $traf_item_counter, $traf_item_counter);
+ push @totalTraffic, sprintf('CDEF:cleanwrite%d=write%d,UN,0,write%d,IF', $traf_item_counter, $traf_item_counter, $traf_item_counter);
+ push @totalTraffic, sprintf('CDEF:max_cleanread%d=max_read%d,UN,0,max_read%d,IF', $traf_item_counter, $traf_item_counter, $traf_item_counter);
+ push @totalTraffic, sprintf('CDEF:max_cleanwrite%d=max_write%d,UN,0,max_write%d,IF', $traf_item_counter, $traf_item_counter, $traf_item_counter);
+ #push @totalTraffic, sprintf('CDEF:min_cleanread%d=min_read%d,UN,0,min_read%d,IF', $traf_item_counter, $traf_item_counter, $traf_item_counter);
+ #push @totalTraffic, sprintf('CDEF:min_cleanwrite%d=min_write%d,UN,0,min_write%d,IF', $traf_item_counter, $traf_item_counter, $traf_item_counter);
+ push @totalTraffic, sprintf('CDEF:max_cleancapacity%d=max_capacity%d,UN,0,max_capacity%d,IF', $traf_item_counter, $traf_item_counter, $traf_item_counter);
+
+ if ($traf_item_counter == 1) {
+ push @totalTraffic, sprintf('CDEF:aggread%d=cleanread%d', $traf_item_counter, $traf_item_counter);
+ push @totalTraffic, sprintf('CDEF:aggwrite%d=cleanwrite%d', $traf_item_counter, $traf_item_counter);
+ push @totalTraffic, sprintf('CDEF:max_aggread%d=max_cleanread%d', $traf_item_counter, $traf_item_counter);
+ push @totalTraffic, sprintf('CDEF:max_aggwrite%d=max_cleanwrite%d', $traf_item_counter, $traf_item_counter);
+ #push @totalTraffic, sprintf('CDEF:min_aggread%d=min_cleanread%d', $traf_item_counter, $traf_item_counter);
+ #push @totalTraffic, sprintf('CDEF:min_aggwrite%d=min_cleanwrite%d', $traf_item_counter, $traf_item_counter);
+ push @totalTraffic, sprintf('CDEF:max_aggcapacity%d=max_cleancapacity%d', $traf_item_counter, $traf_item_counter);
+ } else {
+ push @totalTraffic, sprintf('CDEF:aggread%d=cleanread%d,aggread%d,+', $traf_item_counter, $traf_item_counter, $traf_item_counter-1);
+ push @totalTraffic, sprintf('CDEF:aggwrite%d=cleanwrite%d,aggwrite%d,+', $traf_item_counter, $traf_item_counter, $traf_item_counter-1);
+ push @totalTraffic, sprintf('CDEF:max_aggread%d=max_cleanread%d,max_aggread%d,+', $traf_item_counter, $traf_item_counter, $traf_item_counter-1);
+ push @totalTraffic, sprintf('CDEF:max_aggwrite%d=max_cleanwrite%d,max_aggwrite%d,+', $traf_item_counter, $traf_item_counter, $traf_item_counter-1);
+ #push @totalTraffic, sprintf('CDEF:min_aggread%d=min_cleanread%d,min_aggread%d,+', $traf_item_counter, $traf_item_counter, $traf_item_counter-1);
+ #push @totalTraffic, sprintf('CDEF:min_aggwrite%d=min_cleanwrite%d,min_aggwrite%d,+', $traf_item_counter, $traf_item_counter, $traf_item_counter-1);
+ push @totalTraffic, sprintf('CDEF:max_aggcapacity%d=max_cleancapacity%d,max_aggcapacity%d,+', $traf_item_counter, $traf_item_counter, $traf_item_counter-1);
+ };
+
+ for my $thumb (0, 1) {
+ @this = ();
+ push @this, sprintf($RESULT_DIR.'/node-'.($thumb ? 'small-' : '').'traf-%s.png', $hash);
+ #push @this, sprintf('-s %s', '-604800');
+ push @this, sprintf('-s %s', $START_AT);
+ push @this, sprintf('-e %s', $END_AT);
+ push @this, sprintf('-t %s', "$name traffic");
+ push @this, sprintf('-v %s', "bytes/sec");
+ if ($thumb) {
+ push @this, sprintf('-w %d', 150);
+ push @this, sprintf('-h %d', 50);
+ };
+ push @this, sprintf('-aPNG');
+ push @this, sprintf('DEF:read=%s:read:AVERAGE', $source_traffic);
+ push @this, sprintf('DEF:maxread=%s:read:MAX', $source_traffic);
+ #push @this, sprintf('DEF:minread=%s:read:MIN', $source_traffic);
+ push @this, sprintf('DEF:write=%s:write:AVERAGE', $source_traffic);
+ push @this, sprintf('DEF:maxwrite=%s:write:MAX', $source_traffic);
+ #push @this, sprintf('DEF:minwrite=%s:write:MIN', $source_traffic);
+ push @this, sprintf('DEF:maxcapacity=%s:capacity:MAX', $source);
+ push @this, sprintf('AREA:read#00FF00:Read');
+ push @this, sprintf('LINE2:write#0000FF:Write');
+ unless ($thumb) {
+ push @this, sprintf('LINE1:maxread#009A2C:Read [max 15min]');
+ push @this, sprintf('LINE1:maxwrite#5555FF:Write [max 15min]');
+ #push @this, sprintf('LINE1:minread#FF76D4:Read [min]');
+ #push @this, sprintf('LINE1:minwrite#222255:Write [min]');
+ push @this, sprintf('LINE1:maxcapacity#FF5555:Capacity');
+ }
+ #push @this, sprintf('COMMENT:\\n');
+ #push @this, sprintf('COMMENT:%s\\r', $GMTIME);
+ #push @this, sprintf('COMMENT:\\n');
+ #push @this, sprintf('COMMENT: Min Max Average Last\\n');
+ #push @this, sprintf('COMMENT:Read: ');
+ #push @this, sprintf('GPRINT:minread:MIN:%6.2lf %sb/s ');
+ #push @this, sprintf('GPRINT:maxread:MAX:%6.2lf %sb/s ');
+ #push @this, sprintf('GPRINT:read:AVERAGE:%6.2lf %sb/s ');
+ #push @this, sprintf('GPRINT:read:LAST:%6.2lf %sb/s\\n');
+ #push @this, sprintf('COMMENT:Write: ');
+ #push @this, sprintf('GPRINT:minwrite:MIN:%6.2lf %sb/s ');
+ #push @this, sprintf('GPRINT:maxwrite:MAX:%6.2lf %sb/s ');
+ #push @this, sprintf('GPRINT:write:AVERAGE:%6.2lf %sb/s ');
+ #push @this, sprintf('GPRINT:write:LAST:%6.2lf %sb/s\\n');
+
+ #push @this, sprintf('CDEF:%s=read,0,*,%s,+' , 'zeroline' , '0');
+ #push @this, sprintf('%s:%s' , 'LINE1' , 'zeroline' );
+
+ ($averages,$xsize,$ysize) = RRDs::graph @this;
+ warn RRDs::error if RRDs::error;
+
+ };
+ $body{$section} .= " <a href=\"$IMG_URL"."node-traf-$hash.png\">";
+ $body{$section} .= "<img width=\"$xsize\" height=\"$ysize\" alt=\"$name traffic\" src=\"$IMG_URL"."node-small-traf-$hash.png\">";
+ $body{$section} .= "</a>";
+ };
+ #$body{$section} .= "<br><a href=\"#_top\">top</a>";
+ $body{$section} .= "<br><a href=\"./\">back</a>";
+ $body{$section} .= '</p>';
+};
+push @totalTraffic, sprintf('AREA:aggread%d#00FF00:Read bytes/s', $traf_item_counter);
+push @totalTraffic, sprintf('LINE2:aggwrite%d#0000FF:Write bytes/s', $traf_item_counter);
+push @totalTraffic, sprintf('LINE1:max_aggread%d#009A2C:Read [max 15min]', $traf_item_counter);
+push @totalTraffic, sprintf('LINE1:max_aggwrite%d#5555FF:Write [max 15min]', $traf_item_counter);
+#push @totalTraffic, sprintf('LINE1:min_aggread%d#FF76D4:Read [min]', $traf_item_counter);
+#push @totalTraffic, sprintf('LINE1:min_aggwrite%d#222255:Write [min]', $traf_item_counter);
+push @totalTraffic, sprintf('LINE1:max_aggcapacity%d#FF5555:Capacity', $traf_item_counter);
+
+push @totalTraffic, sprintf('CDEF:zeroline=aggread%d,0,*', $traf_item_counter);
+push @totalTraffic, sprintf('%s:%s' , 'LINE1' , 'zeroline' );
+
+
+my $html = "<html><head><title>Number of Running Tor routers</title></head><body>";
+$html .= "<h1><a name=\"_top\">Number of Running Tor routers</a></h1>";
+$html .= "<a href=\"../\">..</a><br>\n";
+
+
+if ($params[0] ne 'MAGIX1' || $params[1] ne 'MAGIX2') {
+ warn "params[0,1] aren't MAGIX1,2. not nice";
+} else {
+ $params[0] = $RESULT_DIR.'/totalWeekly.png';
+ $params[1] = sprintf('-s %s', $NOW-7*24*3600);
+ my ($averages,$xsize,$ysize) = RRDs::graph @params;
+ warn RRDs::error if RRDs::error;
+
+ $params[0] = $RESULT_DIR.'/totalBiWeekly.png';
+ $params[1] = sprintf('-s %s', $NOW-14*24*3600);
+ ($averages,$xsize,$ysize) = RRDs::graph @params;
+ warn RRDs::error if RRDs::error;
+
+ $params[0] = $RESULT_DIR.'/totalMonthly.png';
+ $params[1] = sprintf('-s %s', $NOW-35*24*3600);
+ ($averages,$xsize,$ysize) = RRDs::graph @params;
+ warn RRDs::error if RRDs::error;
+
+ $params[0] = $RESULT_DIR.'/total.png';
+ $params[1] = sprintf('-s %s', $START_AT);
+ ($averages,$xsize,$ysize) = RRDs::graph @params;
+ warn RRDs::error if RRDs::error;
+
+ $params[0] = $RESULT_DIR.'/total9Months.png';
+ $params[1] = sprintf('-s %s', $NOW-9*30*24*3600);
+ ($averages,$xsize,$ysize) = RRDs::graph @params;
+ warn RRDs::error if RRDs::error;
+
+ $html .= "<p><img width=\"$xsize\" height=\"$ysize\" src=\"$IMG_URL"."total.png\"></p>";
+ $html .= "<p>\"Fast\" means a capacity of over 20,000 bytes/second</p>\n";
+ $html .= "<p>Number of routers over the <a href=\"$IMG_URL"."total9Months.png\">last 9 months</a> | ";
+ $html .= " <a href=\"$IMG_URL"."totalMonthly.png\">last month</a> |";
+ $html .= " <a href=\"$IMG_URL"."totalBiWeekly.png\">last 2 weeks</a></p>";
+};
+
+
+if ($totalTraffic[0] ne 'MAGIX1' || $totalTraffic[1] ne 'MAGIX2') {
+ warn "totalTraffic[0,1] aren't MAGIX1,2. not nice";
+} else {
+ $totalTraffic[0] = $RESULT_DIR.'/totalTrafficWeekly.png';
+ $totalTraffic[1] = sprintf('-s %s', $NOW-7*24*3600);
+ my ($averages,$xsize,$ysize) = RRDs::graph @totalTraffic;
+ warn RRDs::error if RRDs::error;
+
+ $totalTraffic[0] = $RESULT_DIR.'/totalTrafficBiWeekly.png';
+ $totalTraffic[1] = sprintf('-s %s', $NOW-14*24*3600);
+ ($averages,$xsize,$ysize) = RRDs::graph @totalTraffic;
+ warn RRDs::error if RRDs::error;
+
+ $totalTraffic[0] = $RESULT_DIR.'/totalTrafficMonthly.png';
+ $totalTraffic[1] = sprintf('-s %s', $NOW-35*24*3600);
+ ($averages,$xsize,$ysize) = RRDs::graph @totalTraffic;
+ warn RRDs::error if RRDs::error;
+
+ $totalTraffic[0] = $RESULT_DIR.'/totalTraffic.png';
+ $totalTraffic[1] = sprintf('-s %s', $START_AT);
+ ($averages,$xsize,$ysize) = RRDs::graph @totalTraffic;
+ warn RRDs::error if RRDs::error;
+
+ $totalTraffic[0] = $RESULT_DIR.'/totalTraffic9Months.png';
+ $totalTraffic[1] = sprintf('-s %s', $NOW-9*30*24*3600);
+ ($averages,$xsize,$ysize) = RRDs::graph @totalTraffic;
+ warn RRDs::error if RRDs::error;
+
+ $html .= "<p><img width=\"$xsize\" height=\"$ysize\" src=\"$IMG_URL"."totalTraffic.png\"></p>";
+ $html .= "<p>Bandwidth usage for <a href=\"$IMG_URL"."totalTraffic9Months.png\">last 9 months</a> | ";
+ $html .= " <a href=\"$IMG_URL"."totalTrafficMonthly.png\">last month</a> |";
+ $html .= " <a href=\"$IMG_URL"."totalTrafficBiWeekly.png\">last 2 weeks</a></p>";
+}
+
+
+
+$html .= "<p>The directory is downloaded from ";
+ $html .= "<a href=\"http://tor.noreply.org:9030/\">http://tor.noreply.org:9030/</a>";
+
+$html .= " at regular intervals.<br>\n";
+$html .= "Other directory sources are ";
+ $html .= "<a href=\"http://moria.mit.edu:9031/\">http://moria.mit.edu:9031/</a>";
+
+$html .= " and\n";
+ $html .= "<a href=\"http://moria.mit.edu:9032/\">http://moria.mit.edu:9032/</a>";
+
+$html .= ".";
+$html .= "<h1>Recent Nodes</h1>";
+$html .= "<ul>".$index{'current'}."</ul>";
+#$html .= $body{'current'};
+$html .= "<h1>Older Nodes</h1>";
+$html .= "<ul>".$index{'old'}."</ul>";
+#$html .= $body{'current'};
+$html .= "<br><br><br>\n";
+$html .= 'Images created with Tobi Oetiker\'s <a href="http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/">rrdtool</a>'."\n";
+$html .= "<hr>\nBuilt at $GMTIME on $HOSTNAME<br>\n";
+$html .= "<a href=\"mailto:web\@palfrader.org\">Peter Palfrader &lt;web\@palfrader.org&gt;</a>\n";
+$html .= "</body></html>\n";
+
+open (F, ">$RESULT_DIR/index.html") or die ("Cannot open index.html: $!\n");
+print F $html;
+close F;
+
+open (F, ">$RESULT_DIR/current.html") or die ("Cannot open current.html: $!\n");
+print F "<html><head><title>Current Tor Routers</title></head><body>",
+ "<h1><a name=\"_top\">Current Tor routers</a></h1>",
+ "<a href=\"./\">./</a><br>\n",
+ $body{'current'},
+ "<br><br><br>\n",
+ 'Images created with Tobi Oetiker\'s <a href="http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/">rrdtool</a>'."\n",
+ "<hr>\nBuilt at $GMTIME on $HOSTNAME<br>\n",
+ "<a href=\"mailto:web\@palfrader.org\">Peter Palfrader &lt;web\@palfrader.org&gt;</a>\n",
+ "</body></html>\n";
+close F;
+
+open (F, ">$RESULT_DIR/old.html") or die ("Cannot open old.html: $!\n");
+print F "<html><head><title>Older Tor Routers</title></head><body>",
+ "<h1><a name=\"_top\">Older Tor routers</a></h1>",
+ "<a href=\"./\">./</a><br>\n",
+ $body{'old'},
+ "<br><br><br>\n",
+ 'Images created with Tobi Oetiker\'s <a href="http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/">rrdtool</a>'."\n",
+ "<hr>\nBuilt at $GMTIME on $HOSTNAME<br>\n",
+ "<a href=\"mailto:web\@palfrader.org\">Peter Palfrader &lt;web\@palfrader.org&gt;</a>\n",
+ "</body></html>\n";
+close F;