#! /bin/perl
########################################################################
#  By accessing this software, CRAWL.PL, you are duly informed of
#  and agree to be bound by the conditions described below in
#  this notice:
#
#  This software product, CRAWL.PL, is developed by Bradley Huffaker, and
#  copyrighted(C) 1998 by the University of California, San Diego (UCSD),
#  with all rights reserved.  UCSD administers the NSF grant to CAIDA,
#  number NCR-9711092, under which this code was developed. 

#  NCR-9796082 and NCR-9616602, under which most of this code was
#  developed.
#
#  CRAWL.PL is a free software. You can redistribute it and/or modify it
#  under the terms of the CAIDA General Public License v.1 as
#  published by UCSD and is incorporated by reference herein.  CRAWL.PL is
#  distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF MERCHANTABILITY
#  OR FITNESS FOR A PARTICULAR PURPOSE or that the use of it will not
#  infringe on any third party's intellectual property rights.
#
#  You should have received a copy of the CAIDA General Public
#  License v.1 along with the CRAWL.PL program.  If for any reason you
#  have not received a copy, please write to
#
#                       University of California, San Diego
#                       SDSC/CAIDA
#                       9500 Gilman Dr., MS-0505
#                       La Jolla, CA 92093 - 0505  USA
#
#  Or contact INFO@CAIDA.ORG
#######################################################################
# File:crawl.pl
# Goal: To allow for a general tool for crawl nodes.
#
# Written: Bradley Huffaker (4/22/98)
#
# crawl -r roots_file -d depth -o outputfile
# crawl -d depth (root1 root3 ....)
# crawl

require 'user_file.pl';

my ($filename,$depth,$roots_file,@roots) = &GetParams();
($filename,$depth,@roots) = &SetDefaults($filename,$depth,$roots_file,@roots);

&Debug($filename,$depth,@roots);
&Main($filename,$depth,@roots);

($junk,$junk,$junk,$day,$mon,$year) = localtime();
$year += 1900;
#$mon = "0".$mon if ($mon < 10);
#$day = "0".$day if ($day < 10);
$date = (1900+$year)." ".$mon." ".$day;


sub Main 
{
	my ($filename,$depth,@roots) = @_;
	if ($filename)
	{
		open (STDOUT, ">$filename")
			|| die("Unable to open file \"$filename\":$!");
	}
	print STDOUT "d $date\n";
	undef %reached;
	while ($#roots > -1 && $depth >= 0)
	{
		@next_depth =();
		foreach $root (@roots)
		{
		   #print STDERR "depth:$depth ",$ip2name{$root},"($root)\n";
			$reached{$root} = 1;
			@neighbors = ProcessNode($root);
			foreach $node (@neighbors)
			{
				if (!$reached{$node} )
				{
					$reach{$node} = 1;
					push @next_depth,$node
				}
			}
		}
		$depth--;
		@roots = @next_depth;
		print STDERR "   depth:$depth  roots:$#roots\n";
	}
	close STDOUT 
		if ($filename);
}


sub GetParams
{
	my $error;
	foreach $each (@ARGV)
	{
		if ($each eq "-d")
		{
			$type = "d";
		}
		elsif ($each eq "-f")
		{
			$type = "f";
		}
		elsif ($each eq "-r")
		{
			$type = "r";
		}
		else
		{
			if ($type eq "f")
			{
				$error = 1
					if ($filename);
				$filename = $each;
			}
			elsif ($type eq "r")
			{
				$error = 1
					if ($roots_file);
				$roots_file = $each;
			}	
			elsif ($type eq "d")
			{
				$error = 1
					if ($depth || !($each=~/^\d+$/));
				$depth = $each;
			}
			else
			{
				push (@roots,$each);
			}
			undef $type;
		}
	}
	if ($error)
	{
	   print("crawl.pl [-d depth] [-r roots_file] [-o out_file] [root1 root2 ..]\n");
	   exit;
	}
	return ($filename,$depth,$roots_file,@roots);
}

sub Debug
{
	my ($filename,$depth,@roots) = @_;
	print "filename:$filename\n";
	print "Debug Message\n";
	print "depth: $depth\n";
	my $count = 0;
	my $output;
	foreach $each (@roots)
	{
		$next = $each.", ";
		if (!$output)
		{
			$output = "  ".$next;
		}
		elsif (length($output) +length($next) > 80)
		{
			print $output,"\n";
			$output = "  ".$next;
		}
		else
		{
			$output .= $next;
		}
	}
	print $output,"\n";
}

sub SetDefaults
{
	my ($filename,$depth,$roots_file,@roots) = @_;
	$filename = "out"
		if (!$filename);
	$depth = 1
		if (!$depth);
	if (!@roots)
	{
		$roots_file = "roots.txt"
			if (!$roots_file);
		@roots = &GetRoots($roots_file);
		foreach $root (@roots)
		{
			print "$root\n";
		}
	}
	@roots = ("pinot.nlanr.net")
		if (!@roots);
	return ($filename,$depth,@roots);
}

sub GetRoots
{
	my ($filename) = @_;
	open (ROOTS, "<$filename") || die("Root file $filename:$!");
	my @roots;
	while (<ROOTS>)
	{
		s/\s+//g;
		push @roots,$_;
	}
	close ROOTS;
	return @roots;
}
	

sub nslookup
{
	my ($address) = @_;
	$output = `nslookup $address`;
	my ($node,$ip)=($output=~/Name:\s+([^\s]+)\s+Address:\s+([^\s]+)/);
	return ($node,$ip);
}
