#!/usr/local/bin/perl
#################################################################
#
# + FtpLocate - FTP search engine
#
# by Distributed System Lab E.E. NCKU Taiwan 2000
# http://ftp.ee.ncku.edu.tw/ftplocate/
#
#################################################################

use CGI; CGI::ReadParse(*input);
use Socket;
unshift(@INC, substr($0, 0, rindex($0,'/')) ); # add prog path to INC
require ("config");

########################### get_*, for raw web ####################

sub zget_desc {
  my $client=$_[0];
  
  if ( ! -f "$DESCDIR/desc.txt" ) {
    print qq"Content-type: text/plain\n\nFiledesc not available\n";
    return 0;
  }

  open (LOG, ">>$SYSTEMLOG");
  print LOG timestr()." flserv - zget_desc($client)\n";
  close(LOG);

  print "Content-Type: application/x-unknown\n";
  print "Content-Disposition: attachment; filename=desc.txt.gz\n\n"; 
  open (T, "$CMD_GZIP < $DESCDIR/desc.txt |");
  while ( <T> ) {
    print $_;
  }
  close(T);
  return 1;
}

sub zget_filelist {
  my ($client,$site)=@_;
  my $zero;

  $zero=sprintf($SETFPATTERN, 0);
  
  if ( ! -f "$FILELISTDIR/$site/$zero" ) {
    print qq"Content-type: text/plain\n\n$site filelist not available\n";
    return 0;
  }

  open (LOG, ">>$SYSTEMLOG");
  print LOG timestr()." flserv - zget_filelist($client, $site)\n";
  close(LOG);

  print "Content-Type: application/x-unknown\n";
  print "Content-Disposition: attachment; filename=$site.gz\n\n"; 
  open (T, "$FTPLOCATEDIR/flcatsite.pl $site|$CMD_GZIP|");
  while ( <T> ) {
    print $_;
  }
  close(T);
  return 1;
}
  
sub get_maplist {
  my (@locallist, @remotelist);

  if ( $_[0] !~ /!!/ ) {
    print "Content-type: text/plain\n\nFormat error in your map\n";
    return 0;
  }

  @remotelist=split(/[\r\n]+/, $_[0]);
  @locallist=localmaplist();

  print "Content-type: text/plain\n\n";		# send out local map
  foreach (@locallist) {
    print "$_\n";
  }
  maplistupdate(maplistmerge( @locallist, @remotelist ));
  return 1;
}

sub get_toplist {
  my $n=$_[0];
  my ($totalcount, $topcount, @top);

  if ( $n < 1 ) {
    print "Content-type: text/plain\n\nparam must > 0\n";
    return 0;
  }
  ($totalcount, $topcount, @top)=toplist($n);
  print "Content-type: text/plain\n\n";
  print "$topcount/$totalcount\n";
  foreach (@top) {
    print "$_\n";
  }
  return 1;
}
  
sub get_summary {
  my ($client, $fsite)=@_;
  my @summary;

  @summary=summarylist($client);
  print "Content-type: text/plain\n\n";

  foreach (@summary) {
    if ( $fsite eq "" ) {
      print "$_\n";
    } else {
      if ( $_ =~ /$fsite/ ) { print "$_\n"; }
    }
  }
  return 1;
}

sub exec_flsearch {
  my ($client, $query, $fsite)=@_;
  my ($resultfname, $cachestr);
  my ($starttime, $starttimestr, $searchtime, $i);

  $starttime=gettimeofday(); $starttimestr=timestr();

  if ( $fsite eq "" ) {
    $resultfname=CGI::escape($query);
  } else {
    $resultfname=CGI::escape($query)."-$fsite";
  }

  print "Content-type: text/plain\n\n";
  if ( $query!~m![/\w\d\.\+\-\\_~]{2}! ) {	# keyword to short
    print "error! keyword too short\n";
    exit 0;
  } elsif ( -f "$CACHEDIR/$resultfname" ) {	# cache hit
    $cachestr="cache";
    print "cache hit\n";
  } elsif ( -f "$FTPLOCATEDIR/flindex.pl.RUNNING" ) { # service not available
    print "error! indexing, service not available\n";
    exit 0;
  } else {					# cache miss
    $cachestr="";
    print "cache miss\n";
    do_flsearch($client, $query, $fsite, $resultfname);
  }
  open (M, "$CACHEDIR/$resultfname.more");
  while(<M>) { print $_; } 		
  close(M);
  open (L, "$CACHEDIR/$resultfname");
  $i=0;
  while(<L>) { print $_; $i++; }
  close(L);

  $searchtime=int((gettimeofday()-$starttime)*100+0.5)/100;
  loguser($starttimestr, $searchtime, $client, $fsite, $i, $query, $cachestr);
  return 1;
}
    
sub exec_dsearch {
  my ($client, $query)=@_;
  my ($resultfname, $cachestr);
  my ($starttime, $starttimestr, $searchtime);

  $starttime=gettimeofday(); $starttimestr=timestr();

  $resultfname=CGI::escape($query)."desc";

  print "Content-type: text/plain\n\n";
  if ( $query!~m![/\w\d\.\+\-\\_~]{2}! ) {	# keyword to short
    print "error! keyword too short\n";
    exit 0;
  } elsif ( -f "$CACHEDIR/$resultfname" ) {	# cache hit
    print "cache hit\n";
  } elsif ( -f "$FTPLOCATEDIR/dindex.pl.RUNNING" ) { # service not available
    print "error! indexing, service not available\n";
    exit 0;
  } else {					# cache miss
    print "cache miss\n";
    do_dsearch($query, $resultfname);
  }
  open (L, "$CACHEDIR/$resultfname");
  $i=0;
  while(<L>) { print $_; $i++; }
  close(L);

  $searchtime=int((gettimeofday()-$starttime)*100+0.5)/100;
  loguser($starttimestr, $searchtime, $client, "", $i, $query, $cachestr);
  return 1;
}

sub help {
  print "Content-type: text/plain\n\n";
  print "Available Command:
zget_desc
zget_filelist(fsite)
get_maplist(maplist)
get_toplist(n)
get_summary(fsite)
exec_flsearch(query,fsite)
exec_dsearch(query)
";
  return 1;
}

############################# main ##############################

$cmd=clean_str($input{'cmd'}); 
$query=clean_str($input{'query'});
$fsite=clean_str($input{'fsite'});
$n=clean_str($input{'n'});
$client=ip2fqdn(client_ip());
$remotelist=$input{'maplist'};

if ( $cmd eq "zget_desc" ) {
  zget_desc($client);

} elsif ( $cmd eq "zget_filelist" ) {
  zget_filelist($client,$fsite);

} elsif ( $cmd eq "get_maplist" ) {
  get_maplist($remotelist);

} elsif ( $cmd eq "get_toplist" ) {
  get_toplist($n);

} elsif ( $cmd eq "get_summary" ) {
  get_summary($client, $fsite);

} elsif ( $cmd eq "exec_flsearch" ) {
  exec_flsearch($client, $query, $fsite);

} elsif ( $cmd eq "exec_dsearch" ) {
  exec_dsearch($client, $query);

} else {
  help();
}

