#!/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=; 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 (

) { ($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|"); $_=; $_=; 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=; 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 () { 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 () { 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";