#!/usr/local/bin/perl
# gophertree
# Prints pretty indented listings of a Gopher menu tree
# Copyright (C) 1992, Trustees of Michigan State University
# 
# Modifications:
# Original author unknown
# 07/07/92 Boone      Major conversion from gopherls
# End Modifications

sub dokill
{
    kill 9,$child if $child;
}

sub Opengopher
{
    $sockaddr++;
    local($them,$port) = @_;	
    $them = 'localhost' unless $them;

    $AF_INET = 2;
    $SOCK_STREAM = 1;

    $SIG{'INT'} = 'dokill';

    $sockaddr = 'S n a4 x8';

    chop($hostname = `hostname`);

    ($name,$aliases,$proto) = getprotobyname('tcp');
    ($name,$aliases,$port) = getservbyname($port,'tcp')
	unless $port =~ /^\d+$/;;
    ($name,$aliases,$type,$len,$thisaddr) = gethostbyname($hostname);
    ($name,$aliases,$type,$len,$thataddr) = gethostbyname($them);

    $this = pack($sockaddr, $AF_INET, $sockaddr, $thisaddr);
    $that = pack($sockaddr, $AF_INET, $port, $thataddr);

    # Make the socket filehandle.
    socket(S, $AF_INET, $SOCK_STREAM, $proto) || die $!;

    # Give the socket an address.
    bind(S, $this) || die $!;

    # Call up the server.
    connect(S,$that) || die $!;

    # Set socket to be command buffered.
    select(S); $| = 1; select(STDOUT);

}

sub GetList 
{
	local($CurrentHost, $Port, $Path, $indent) = @_;
	local(@dirx, $Name, $Obj, $fname, $ftype, $fhost, $i);
	&Opengopher($CurrentHost, $Port);
	print S "$Path\n";
	@dirx = <S>;
	close(S);
	$i = 0;
	foreach (@dirx) 
	{
		last if /^\./;
		chop; chop;
		($ObjName, $Path, $CurrentHost, $Port) = split('\t', $_);
		$Name = substr($ObjName, 1);
		$Obj = substr($ObjName, 0, 1);
		$fname = $indent . $Name;
		$ftype = "";
		$ftype = "File" if ($Obj eq "0");
		$ftype = "Dir" if ($Obj eq "1");
		$ftype = "Phone" if ($Obj eq "2");
		$ftype = "Error" if ($Obj eq "3");
		$ftype = "MacHqx" if ($Obj eq "4");
		$ftype = "PcHqx" if ($Obj eq "5");
		$ftype = "Uue" if ($Obj eq "6");
		$ftype = "Index" if ($Obj eq "7");
		$ftype = "Telnet" if ($Obj eq "8");
		$ftype = "Binary" if ($Obj eq "9");
		$ftype = "File" if ($Obj eq "R");
		$ftype = "TN3270" if ($Obj eq "T");
		$ftype = "File" if ($Obj eq "e");
		$ftype = "Ftp" if ($Obj eq "f");
		$ftype = "HTML" if ($Obj eq "h");
		$ftype = "Info" if ($Obj eq "i");
		$ftype = "Mail" if ($Obj eq "m");
		$ftype = "Sound" if ($Obj eq "s");
		$ftype = "Index" if ($Obj eq "w");
		$fhost = $CurrentHost;

		write if (($i < $breaklong) && ($Obj ne "i"));

		if (($Obj eq "1") && ($CurrentHost eq $firsthost) && 
			(($Port != $firstport) || ($Path != ""))) 
		{
			&GetList($CurrentHost, $Port, $Path, $indent . $iadd);
		}

		$i++ if ($Obj eq "0");
		if ($i == 15) 
		{
			print("$indent. . .\n");
			--$-;
		}
	}
}

# **************************************************************************
# * Main
# **************************************************************************

# Parse command line

	if ($#ARGV < 1) 
	{
		print "Usage:  gophertree  host  port  path\n";
		exit(1);
	}

	$firsthost = $CurrentHost = $ARGV[0];
	$firstport = $Port = $ARGV[1];
	$Path = "";
	if ($#ARGV == 2) 
	{
		$Path = $ARGV[2];
	}

# Initialize some variables

	($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
	$today = $mon+1 . "/" . $mday . "/" . $year;

	$^ = 'TOP';         # Report header format
	$~ = 'STDOUT';      # Report body format
	$indent = "";       # Goes in front of description to indicate treeness

# CHANGE--User-configurable defaults

	$breaklong = 15;    # CHANGE--Where to break long lists, place ". . ."
	$= = 55;            # CHANGE--Lines per page
	$iadd = "  ";       # CHANGE--Amount to indent each new level

# Real work

	&GetList($CurrentHost, $Port, $Path, $indent);
	exit(0);

#
# Formats
#

format TOP =

MSU Gopher Road Map                      Host: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$firsthost
Last Update: @<<<<<<<                                               Page: @>>
$today $%

Name					Type	Destination
--------------------------------------	-------	------------------------------
.

format STDOUT =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  @<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$fname $ftype $fhost
.
