#!/usr/local/bin/perl
#################################################################
#
# + FtpLocate - FTP search engine
#
# by Distributed System Lab E.E. NCKU Taiwan 2003
# http://turtle.ee.ncku.edu.tw/ftplocate/
#
#################################################################
use IO::Socket;
############################# subs ##############################
sub touch {
foreach (@_) {
open(T, ">>$_"); close(T);
}
chmod(0644, @_);
}
sub readfile {
my $fname=$_[0];
my @f;
open(F, "$fname") || die "Open $fname for read error\n";
@f=<F>;
close(F);
return(@f);
}
sub writefile {
my ($fname,@f)=@_;
open(F, ">$fname") || die "Open file $fname for write error\n";
foreach (@f) { print F $_; }
close(F);
chmod(0644, $fname);
return($fname);
}
sub do_config {
my @f=@_;
foreach (@f) {
if ( /%/ ) {
s!%FTPLOCATEHTMLDIR%!/$fldir!g;
s!%FTPLOCATECGIDIR%!/cgi-bin/$fldir!g;
s!%FTPLOCATEDIR%!$cgidir/$fldir!g;
s!%LANG%!$lang!g;
s!%TMPDIR%!$tmpdir!g;
s!%HOSTNAME%!$fqdn!;
}
}
return(@f);
}
sub uidgid {
my $user=$_[0];
my ($name, $pass, $uid, $gid);
open(P, "/etc/passwd");
while (<P>) {
($name, $pass, $uid, $gid)=split(/:/);
if ( $user eq $name ) { return($uid, $gid); }
}
close(P);
return(-1, -1);
}
sub mbfree {
my $dir=$_[0];
my ($fs, $total, $used, $free, $freepercent, $mp);
open(DF, "df -k /tmp|");
$_=<DF>; $_=<DF>; chop;
close(DF);
($fs, $total, $used, $free, $freepercent, $mp)=split(/\s+/);
return ($free/1024);
}
sub ask {
my ($prompt, $default)=@_;
my $ans;
if ( $always_yes==1 ) { return $default; }
print $prompt;
$ans=<STDIN>; chop($ans);
if ($ans eq "" ) {
return $default;
} else {
return $ans;
}
}
sub dirname {
my $i;
$i=rindex($_[0],'/');
if ( $i > 0 ) {
return substr($_[0], 0, $i);
} else {
return ".";
}
}
use Sys::Hostname;
sub default_domain {
my ($hostname, $fqdn);
open (R, "/etc/resolv.conf"); # from resolv.conf
while (<R>) {
if ( /domain\s+\.?(.*)\s?/i ) { close(R); return($1); }
}
close(R);
$hostname=hostname(); # from hostname
if ($hostname =~ /\./ ) {
return( substr($hostname,index($hostname,'.')+1) );
}
open (R, "/etc/hosts"); # from hosts
while (<R>) {
if ( /$hostname\./i ) {
foreach ( split(/\s+/) ) {
if ( /$hostname\./i && (length($_)>length($fqdn)) ) { $fqdn=$_; }
}
close(R);
return( substr($fqdn,index($fqdn,'.')+1) );
}
}
close(R);
return("");
}
sub my_fqdn {
my ($hostname, $domain);
$hostname=hostname();
if ( $hostname =~ /\./ ) {
return $hostname;
} else {
return $hostname.'.'.default_domain();
}
}
######################## global variable ########################
$DOCDIR=dirname($0)."/doc";
$BINDIR=dirname($0)."/bin";
$TEMPLATEDIR=dirname($0)."/template";
############################# main ##############################
foreach (@ARGV) {
if ( /-y/i ) { # define variable used by ask routine
$always_yes=1;
} elsif ( /-c/i ) { # no exit in dependence error
$always_install=1;
} elsif ( /-bsdport/i ) { #
$bsdport=1;
}
}
print "
=================================================
FtpLocate Install Program
by Distributed System Lab E.E. NCKU Taiwan 2003
http://turtle.ee.ncku.edu.tw/ftplocate/
=================================================\n\n";
#################################################################
#
# check basic requirement for ftplocate
#
#################################################################
print "check uid...";
if ( $> == 0 ) {
print "ok\n";
} else {
print "\nYou need to be root to install this program\n\n";
if ( !$always_install ) {
exit 1;
}
}
print "check perl...";
eval { require "sys/syscall.ph"; };
if (!$@) {
print "ok\n";
} else {
print qq|\n\nperl *.ph file not found, pease do\n\n|.
qq|cd /usr/include\n|.
qq|h2ph -r -l .\n|.
qq|\nto create ph files (Don't miss the dot at the line)\n\n|;
if ( !$always_install ) {
exit 1;
}
}
print "check glimpse...";
if ( (-x "/usr/local/bin/agrep" || -x "/usr/bin/agrep")
&& (-x "/usr/local/bin/glimpse" || -x "/usr/bin/glimpse") ) {
print "ok\n";
} else {
print "\nPlease install Glimpse(http://glimpse.cs.arizona.edu) first\n\n";
if ( !$always_install ) {
exit 1;
}
}
print "check web server...";
$remote_sock=new IO::Socket::INET( Proto=>'tcp',
PeerAddr=>'localhost',
PeerPort=>80,);
if ( $remote_sock ) {
print "ok\n";
} else {
print "\nPlease install a web server first\n\n";
if ( !$always_install ) {
exit 1;
}
}
#################################################################
#
# guess default
#
#################################################################
$deffqdn=my_fqdn();
$defwwwuser='nobody';
$defwwwuser='apache' if ( (uidgid('apache'))[0]>0 );
$defwwwuser='www' if ( (uidgid('www'))[0]>0 );
$defhtmldir="/usr/local/www/data";
$defcgidir="/usr/local/www/cgi-bin";
if ( $bsdport ) { #if bsd port, pre-mkdir to bypass the below dir check
$defwwwuser='www';
if ( ! -d "/usr/local/www/data" ) {
mkdir("/usr/local/www/data", 0755);
}
if ( ! -d "/usr/local/www/cgi-bin" ) {
mkdir("/usr/local/www/cgi-bin", 0755);
}
}
foreach (
"/usr/local/www/data",
"/usr/local/apache/data",
"/opt/apache/share/data",
"/opt/apache/data",
"/var/www/html",
"/usr/local/www/data") {
if ( -d $_ ) { $defhtmldir=$_; last }
}
foreach (
"/usr/local/www/cgi-bin",
"/usr/local/apache/cgi-bin",
"/opt/apache/share/cgi-bin",
"/opt/apache/cgi-bin",
"/var/www/cgi-bin",
"/usr/local/www/cgi-bin") {
if ( -d $_ ) { $defcgidir=$_; last }
}
#####################################################################
#
# confirm setting
#
#################################################################
$fqdn=ask(
"\nWhat is the domainname of your machine?
(default: $deffqdn)\n", $deffqdn);
print "The machine's domainname is [$fqdn]\n";
for ($i=0; $i<3; $i++) {
$wwwuser=ask(
"\nWhich user does your web server run as?
(default: $defwwwuser)\n", $defwwwuser);
($uid, $gid)=uidgid($wwwuser);
if ($uid>0) {
print "Web server effective user is [$wwwuser]\n"; last;
} else {
print "User $wwwuser doesn't exist\n";
}
}
die "Too many retry, abort...\n" unless $i<3;
for ($i=0; $i<3; $i++) {
$htmldir=ask(
"\nWhat is your system HTML path?
(default: $defhtmldir)\n", $defhtmldir);
if ( -d "$htmldir" ) {
print "Your system HTML path is [$htmldir]\n"; last;
} else {
print "Dir $htmldir doesn't exist\n";
}
}
die "Too many retry, abort...\n" unless $i<3;
for ($i=0; $i<3; $i++) {
$cgidir=ask(
"\nWhat is your system CGI path?
(default: $defcgidir)\n", $defcgidir);
if ( -d "$cgidir" ) {
print "Your system CGI path is [$cgidir]\n"; last;
} else {
print "Dir $cgidir doesn't exist\n";
}
}
die "Too many retry, abort...\n" unless $i<3;
for ($i=0; $i<3; $i++) {
$fldir=ask(
"\nWhat subdir will be used for FtpLocate under HTML and CGI?
(default: ftplocate)\n", "ftplocate");
if ( -d "$htmldir/$fldir" || -d "$cgidir/$fldir" ) {
if ( -d "$htmldir/$fldir" ) { print "$htmldir/$fldir exists,\n"; }
if ( -d "$cgidir/$fldir" ) { print "$cgidir/$fldir exists,\n"; }
if ( ask("rename to $fldir.old?(Y/n)", "y") !~ /^n/i ) {
rename("$htmldir/$fldir", "$htmldir/$fldir.old");
rename("$cgidir/$fldir", "$cgidir/$fldir.old");
print "rename $fldir to $fldir.old\n";
last;
}
} else {
last;
}
}
die "Too many retry, abort...\n" unless $i<3;
print "The FtpLocate html dir is [$htmldir/$fldir]\n";
print "The FtpLocate cgi dir is [$cgidir/$fldir]\n";
if ( mbfree("/tmp") >= 100 ) {
$deftmpdir="/tmp";
} else {
$deftmpdir="$cgidir/$fldir/tmp";
}
$tmpdir=ask(
"\nWhat is the tmp directory for FtpLocate?
(default: $deftmpdir, at least 100mb free space is required)\n", $deftmpdir);
print "The tmp directory for FtpLocate is [$tmpdir]\n";
$lang=ask(
"\nWhat language do you prefer?
(e for english, z for tradition chinese, default is english)\n", "english");
if ( $lang =~ /^z/i ) {
$lang="zhtw";
} else {
$lang="english";
}
print "The language for FtpLocate is [$lang]\n";
if ( ask("\n
=================================================
The setting for Ftplocate is
=================================================
domainname: $fqdn
www user: $wwwuser
help/doc dir: $htmldir/$fldir
program dir: $cgidir/$fldir
filelist dir: $cgidir/$fldir/filelist
desc dir: $cgidir/$fldir/desc
cache dir: $cgidir/$fldir/cache
tmp dir: $tmpdir
language: $lang
Are you sure to start installation?(Y/n)", "Y") =~ /^n/i ) {
die "Canceled by user!\n";
}
#################################################################
#
# mkdir, copy files, config templates
#
#################################################################
# mkdir...
mkdir("$htmldir/$fldir", 0755);
mkdir("$cgidir/$fldir", 0755);
mkdir("$cgidir/$fldir/filelist", 0755);
mkdir("$cgidir/$fldir/desc", 0755);
mkdir("$cgidir/$fldir/cache", 0755);
if ( ! -d $tmpdir ) { mkdir("$tmpdir", 0755); }
# copy files...
print "cp doc to $htmldir/$fldir\n";
`cp $DOCDIR/* $htmldir/$fldir`;
print "cp bin to $cgidir/$fldir\n";
`cp $BINDIR/* $cgidir/$fldir`;
print "config templates\n";
# copy files by template
writefile("$htmldir/$fldir/index.html",
do_config(readfile("$TEMPLATEDIR/index.html")) );
writefile("$htmldir/$fldir/help.english.html",
do_config(readfile("$TEMPLATEDIR/help.english.html")) );
writefile("$htmldir/$fldir/help.zhtw.html",
do_config(readfile("$TEMPLATEDIR/help.zhtw.html")) );
writefile("$cgidir/$fldir/config",
do_config(readfile("$TEMPLATEDIR/config")) );
writefile("$cgidir/$fldir/config.site",
do_config(readfile("$TEMPLATEDIR/config.site")) );
writefile("$cgidir/$fldir/indexer.sh",
do_config(readfile("$TEMPLATEDIR/indexer.sh")) );
writefile("/usr/local/bin/ftplocate",
do_config(readfile("$TEMPLATEDIR/ftplocate")) );
print "set owner and mode\n";
chdir("$cgidir/$fldir");
touch("log.map", "log.system", "log.user");
($uid, $gid)=uidgid($wwwuser);
chown($uid, $gid, "cache", "log.map", "log.user", "log.system");
chown($uid, $gid, $tmpdir) if ($tmpdir ne "/tmp") ;
chmod(0755, "indexer.sh", "/usr/local/bin/ftplocate");
print "\nInstallation completes...\n";
print "
To enable your FtpLocate search engine, you have to:\n\n";
if ($^X ne "/usr/local/bin/perl") {
print "0. Please change the '#!/usr/local/bin/perl' to '#!$^X' in $cgidir/$fldir/*pl\n";
}
print "1. find the effective user of your http process and ensure
$cgidir/$fldir/cache
$cgidir/$fldir/log.user
$tmpdir
are writable by that user ($wwwuser)
2. edit config.site: $cgidir/$fldir/config.site
3. run indexer.sh: $cgidir/$fldir/indexer.sh
4. test text client: /usr/local/bin/ftplocate
5. test FtpLocate CGI: http://$fqdn/cgi-bin/$fldir/flsummary.pl
";
$free=int(mbfree("$cgidir/$fldir"));
if ( $free < 100 ) {
print "
The free space available for $cgidir/$fldir is only $free MB!
Since FtpLocate will use large disk space in data collecting and indexing,
we strongly suggest you move dir filelist and desc to another partition.
";
}
print "\nThanks for using FtpLocate :)\n\nChung-Kie Tung 08/28/2003\n\n";
syntax highlighted by Code2HTML, v. 0.9.1