#!/usr/bin/perl -w
#-----------------------------------------------------------------------------
#
#  Copyright (C) 2000 Ryan C. Gordon (icculus@linuxgames.com)
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
#
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Revision history:
#  1.0.0 : First release
#  1.0.2 : Minor bugfixes.
#  1.1.0 : Prints version in <title>, more customizable, optionally allows
#           fingering to arbitrary sites for use as a web interface to finger,
#           supports VirtualHost sites, better error output.
#  1.1.1 : Highlights URLs and email addresses.
#-----------------------------------------------------------------------------

use strict;


# Version of IcculusFinger. Change this if you are forking the code.
my $version = "v1.1.1";


# Location where the server can find the finger client it will be using
#  to get information. This string is executed and what it writes to stdout
#  is read in by this script.
my $fingerprog = "/usr/local/bin/finger";


# Uncomment this to always do finger requests to the same host.
# Define which host the finger request goes to. If you don't define $host,
#  then users may finger any system on the internet by specifying a hostname:
#  user=dimwit@doofus.com, for example. Not setting $host at all like that
#  could leave a mild exploit available.
#my $host = undef;   # Makes this script work as a web interface to finger.
#my $host = "icculus.org";  # limit queries to users@icculus.org
my $host = $ENV{SERVER_NAME}; #  This is good for VirtualHost setups.


# This is the URL to where the script can be obtained. Feel free to change
#  it if you like. Leave it undef'd to not supply a link at all in the
#  final HTML output.
#my $scripturl = undef;
#my $scripturl = "/misc/finger.pl";
my $scripturl = "http://icculus.org/IcculusFinger/";


# This is printed after the credits at the bottom change it to whatever you
#  like. Obviously, HTML in the string is acceptable, as is an empty string
#  (""), but undef doesn't fly here.
my $wittyremark = "<br><i>Stick it in the camel and go.</i>";




#-----------------------------------------------------------------------------#
#     The rest is probably okay without you laying yer dirty mits on it.      #
#-----------------------------------------------------------------------------#

my $script_link = (defined $scripturl) ?
                     "<a href=\"$scripturl\">This script</a>" :
                     "This script" ;


sub output_start {

print <<__EOF__;
Content-type: text/html


<html>
  <head>
    <title> IcculusFinger $version </title>
  </head>

  <body>

__EOF__

}


sub output_ending {

print <<__EOF__;

    <hr>
    <center>
      <font size="-3">
        $script_link was written by
        <a href="mailto:icculus\@icculus.org">Ryan C. Gordon</a>.
        $wittyremark
      </font>
    </center>

  </body>
</html>

__EOF__

}




# Mainline.


my $user;

$host =~ tr/A-Z/a-z/ if defined $host;

if ((defined $ENV{GATEWAY_INTERFACE}) and ($ENV{GATEWAY_INTERFACE} ne "")) {
    my $QueryString = $ENV{QUERY_STRING};
    if ($QueryString =~ /user=(.*)/) {
        $user = $1;
        $user =~ s/&.*//;
        $user =~ tr/A-Z/a-z/;
    }
} else {
    print("\n\nRun this as a cgi-bin: $0?user=login[\@hostname]\n\n\n");
    exit 1;
}

my $requested_host = undef;
if ((defined $user) && ($user =~ s/\@(.*)//)) {
    $requested_host = $1;
    $requested_host =~ tr/A-Z/a-z/;
}

output_start();

my $errormsg = undef;
if (not defined $user) {
    $errormsg = "No user specified.";
} elsif ((not defined $host) and (not defined $requested_host)) {
    $errormsg = "No host specified.";
} elsif ((defined $host) and (defined $requested_host)) {
    if ($host ne $requested_host) {
        $errormsg = "You aren't permitted to specify a hostname, just a user.";
    }
} elsif (length($user) > 20) {
    # The 20 char limit is just for safety against potential buffer overflows
    #  in finger servers, but it's more or less arbitrary.
    # !!! TODO FIXME: Check for bogus characters in username/host.
    $errormsg = "Bogus user specified.";
}

if (defined $errormsg) {
   print("    <center><h1>$errormsg</h1></center>\n");
} else {
    if (not defined $host) {
        $host = $requested_host;
    }

    if (not open(FINGER, "$fingerprog $user\@$host |")) {
        print("    <center><h1>Couldn't run finger program: $!.</h1></center>\n\n");
    } else {

        print("    <center><h1>Finger info for $user\@$host...</h1></center>\n");
        print("    <hr>\n\n<pre>\n\n");

        while (<FINGER>) {
	    # try to make URLs into hyperlinks in the HTML output.
	    1 while (s/(?<!href=")(?<!">)\b([a-zA-z]+?:\/\/[\S]+)/<a href="$1">$1<\/a>/);
	    # try to make email addresses into hyperlinks in the HTML output.
	    1 while (s/\b(?<!href="mailto:)(?<!">)\b([\w\.]+?\@[\w\.]+)/<a href=\"mailto:$1\">$1<\/a>/);

	    print("$_");
        }

        close(FINGER);
        print("\n</pre>\n");
    }
}

output_ending();

exit 0;

# end of finger.pl ...


