#!/usr/bin/perl
###
##	Original package IRCCS version 1, Copyright (c) 1995
##	Daniel J. Wightman.  Rewritten from Nov to Dec 2000.
##	Packaged Dec 19 and published as IRCCS (fruitbrick) version 2.
##
##	FruitBrick (IRCCS) - Internet Relay Chat Control System version 2
##	Copyright (C) 1995, 2000  Daniel J. Wightman <dent@abonica.net>
##
##	See the copyright or COPYRIGHT in the main program directory for
##	details.  See the LICENSE in the main program directory as well.
###
# ------------------------------------------------------------------
# COMLIST - command database generator
# ------------------------------------------------------------------
# This will read the list of files in the command directories and
# create a hash database containing the names/paths of same.
# Then we'll recurse over the hash list and generate code for
# each file that, either opens the corrisponding file, or the
# actual code for the perl file itself, which is eval'd later.

# FOR TESTING
#@servdirs = ('chanserv');
#$comdir = "../commands";
#$chancoms = "chanserv";
#$thisnick = "chanserv";
#$flags{commands} = "fixed";
# END TESTING

{
# This is the routine that's inserted into the hash element
# when the dump flag is on.
$subroutine = "&loadcom";

$thisnick = &dcase($channick);
&traverse("$comdir/$chancoms");

$thisnick = &dcase($nicknick);
&traverse("$comdir/$nickcoms");

$thisnick = &dcase($memonick);
&traverse("$comdir/$memocoms");

$thisnick = &dcase($gamenick);
&traverse("$comdir/$gamecoms");

$thisnick = &dcase($opernick);
&traverse("$comdir/$opercoms");

# uncomment these later if you find a need for killserv
# $thisnick = $killnick;
# &dcase($thisnick);
# &traverse("$comdir/$killcoms");

# The entire hash base we just created was stored in
# our generic hash.  Now just copy it over to the hash
# we'll really use.  Why do this?  Because we need to use
# the same traverse routine to load other command bases

%commands = %temphash;
undef(%temphash);

# ok, we have a problem.  We can't reuse the routine unless we
# pass a name to it.  So what, we'll use 'commands'.  we can change
# this later if we want.  Just make sure it matches in the &engine
# routine.

# This is the routine that's inserted into the hash element
# when the dump flag is on. use this one for ctcp
$subroutine = "&loadctcp";

$thisnick = "commands"; # "commands" has no meaning here, it's just a filler
&traverse("ctcp");

undef $subroutine;

%ctcp = %temphash; # same as before
undef(%temphash);

# testing
#foreach $i (keys %{$commands{chanserv}})
#	{
#	print "$i\n";
#	}
#print "DONE!\n";
# test

}
# -------------------------------------------------------------------------
# CONFIGERR
# -------------------------------------------------------------------------
# If one of our root directories don't exist then one or more items in
# the configuration file is missing or incorrect.

sub configerr
{
print STDERR "==== Configuration Error ====\n";
print STDERR "Directory $_[0] doesn't exist!\n";
print STDERR "Check the confiuration file for\n";
print STDERR "the appropriate service directory\n";
print STDERR "and try again.\n";
exit; # just get out entirely now.
}
# -------------------------------------------------------------------------
# TRAVERSE
# -------------------------------------------------------------------------
# Found at: http://www.perl.com/CPAN-local/scripts/findstuff
# I've modified it, added to it, to pull in the contents of each
# command file, or to point to a sub routine that will do it at
# run time. The traverse routine originaly just traversed a dir structure.
##
# Recurse over subdirectories.

sub traverse
{
local($dir) = shift;
local($path);
unless (opendir(DIR, $dir))
	{
	closedir(DIR);
	&configerr($dir);
	return; # doesn't return, exits instead, but hay, it's clearer this way
	}
foreach (readdir(DIR))
	{
	# we don't want to load . .. or ~ files.
	next if $_ eq '.' || $_ eq '..' || $_ =~ /\~/;
	$path = "$dir/$_";

	if (-d $path)
		{
		# a directory
		# we need to load the file of the same name FROM
		# that directory or generate generic code for it.
		&makedefault($path);
		&traverse($path); # recurse over yourself
		}
	elsif (-f _)
		{
# TEST
# print ":$path:\n";
#!TEST
		# a plain file
		# Now, if we have the proper flag set, we load
		# the command code directly into this hash element.
		&makesource($path);
		}
	}
closedir(DIR);
}
# -------------------------------------------------------------------------
# MAKESOURCE
# -------------------------------------------------------------------------
# just load the command file into the hash or point to the sub routine
# that runs it from disk, depending on the flag setting.
sub makesource
{
if($flags{commands} =~ /fixed/i)
	{
	open COMS, "<$_[0]" or die "strange error running command loader under admin directory: $!\n";
	undef $/;
	$temphash{$thisnick}{$_[0]} = <COMS>;
	close(COMS);
	$/ = "\n";
	}
else
	{
	# apparently we'll load at run time.  Just
	# point to the routine that loads the command.
	# we pass it a parameter, the command path, later.
	$temphash{$thisnick}{$_[0]} = $subroutine;
	}

}
# -------------------------------------------------------------------------
# MAKEDEFAULT
# -------------------------------------------------------------------------
# For each directory name under the sub command root we have to have a
# command.  If we don't then when someone uses a directory name as a
# command the source will fail.  Here's an example
# /msg ChanServ SET
# Theres a directory ./commands/chanserv/SET
# but there's no source file for that.  Here's what we do.  We search
# for a specific filename "DIR.DIR" under each directory.  We give that
# filename a '.' in it so that it's not loaded into the command base.
# It's the same filename for each sub directory.  If this file doesn't
# exist we load the file from $comdir/DIR.DIR and if THAT doesn't
# exist we exit with failure from this routine cos I put it there.

sub makedefault
{
# if it's a FILE and NOT a directory
if (-f "$_[0]/DIR.DIR")
	{
	if($flags{commands} =~ /fixed/i)
		{
		open COMS, "< $_[0]/DIR.DIR" or die "strange error running makedefault under admin directory: $!\n";
		undef $/;
		$temphash{$thisnick}{$_[0]} = <COMS>;
		close(COMS);
		$/ = "\n";
		}
	else
		{
		# special case here, not like the makesource we'll point
		# to a different subroutine.
		$temphash{$thisnick}{$_[0]} = "&loaddefault";
		}

	}
elsif(-f "$comdir/DIR.DIR")
	{
	# 
	if($flags{commands} =~ /fixed/i)
		{
		open COMS, "< $comdir/DIR.DIR" or die "strange error running makedefault under admin directory, section 2: $!\n";
		undef $/;
		$temphash{$thisnick}{$_[0]} = <COMS>;
		close(COMS);
		$/ = "\n";
		}
	else
		{
		# special case here, not like the makesource we'll point
		# to a different subroutine.
		$temphash{$thisnick}{$_[0]} = "&loaddefault";
		}
	}
else
	{
	print STDERR "DUDE! Comon!  Read some of the instructions huh?\n";
	print STDERR "I died while trying to run sub makedefault in file\n";
	print STDERR "./admin/COMLIST cos you deleted the DIR.DIR file in\n";
	print STDERR "the $comdir directory.  OR did you redefine it?\n";
	exit;
	}
}
# -------------------------------------------------------------------------
# MAKEHELP - *DISABLED* This doesn't function yet, it's here for future work
# -------------------------------------------------------------------------
# For each directory there's a help file that contains the help for
# the commands in that particular directory.  This file is called
# DIR.HELP and is loaded into the hash $helpcom/$path the same
# way DIR.DIR is except THIS one prepends $helpcom to it.

sub makehelp
{
# if it's a FILE and NOT a directory
if (-f "$_[0]/DIR.HELP")
	{
	if($flags{commands} =~ /fixed/i)
		{
		open COMS, "< $_[0]/DIR.HELP" or die "strange error running makehelp under admin directory: $!\n";
		undef $/;
		$temphash{$thisnick}{$_[0]} = <COMS>;
		close(COMS);
		$/ = "\n";
		}
	else
		{
		# special case here, not like the makesource we'll point
		# to a different subroutine.
		$temphash{$thisnick}{$_[0]} = "&loadhelp";
		}

	}
elsif(-f "$comdir/DIR.HELP")
	{
	# 
	if($flags{commands} =~ /fixed/i)
		{
		open COMS, "< $comdir/DIR.HELP" or die "strange error running makedefault under admin directory, section 2: $!\n";
		undef $/;
		$temphash{$thisnick}{$_[0]} = <COMS>;
		close(COMS);
		$/ = "\n";
		}
	else
		{
		# special case here, not like the makesource we'll point
		# to a different subroutine.
		$temphash{$thisnick}{$_[0]} = "&loadhelp";
		}
	}
else
	{
	print STDERR "DUDE! Comon!  Read some of the instructions huh?\n";
	print STDERR "I died while trying to run sub makehelp in file\n";
	print STDERR "./admin/COMLIST cos you deleted the DIR.HELP file in\n";
	print STDERR "the $comdir directory.  OR did you redefine it?\n";
	exit;
	}
}
# -------------------------------------------------------------------------
# We create another administrative file to load the databases for
# nicks chans memos and games.  It's no longer contained in this file.
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------













