#!/usr/bin/perl -w

use 5.006;
use Getopt::Std;
use Socket;
use IO::Socket::INET;

$ENV{PATH} .= ':/sbin:/usr/sbin';

$usage = "usage: $0 [-p port] [IP-address]\n";
$xinetd = '/etc/xinetd.d/fex';

if ($<) {
  die "you must be root to install F*EX\n";
}


$opt_p = 80;

if (open F,$xinetd) {
  while (<F>) {
    if (/^\s*port\s*=\s*(\d+)/) {
      $opt_p = $fexport = $1;
    }
    if (/^\s*bind\s*=\s*([\d.]+)/) {
      $fexip = $1;
    }
  }
  close F;
}

getopts('p:') or die $usage;

$ip = shift || $fexip || 0;

if (not $ip and open P,"ifconfig|") {
  $guessed_ip = 0;
  while (<P>) {
    if (/inet addr:([\d.]+)/) { 
      $guessed_ip = $1;
      last;
    }
  }
  close P;
  print "Your IP [$guessed_ip] : ";
  chomp($ip = <STDIN>);
  $ip = $guessed_ip unless $ip;
}

$ip =~ /^\d+\.\d+\.\d+\.\d+$/ or die $usage;

($hostname) = gethostbyaddr(gethostbyname($ip),AF_INET);
die "cannot find hostname for IP $ip\n" unless $hostname;

print "checking prerequisites\n";

if (`which xinetd` =~ m{^/}) {
  print "found xinetd\n";
} else {
  print "xinetd executable NOT found\n";
  $premiss++;
}

if ( -x '/usr/lib/sendmail') {
  print "found /usr/lib/sendmail\n";
} elsif ( -x '/usr/sbin/sendmail') {
  print "found /usr/sbin/sendmail\n";
} else {
  print "sendmail NOT found\n";
  $premiss++;  
}

if ($premiss) {
  print "installation aborted, nothing das been touched yet\n";
  print "what now? ==> see doc/installation\n";
  exit 1;
}

unless ($fexport) {
  
  $SH = IO::Socket::INET->new(
    PeerAddr => $ip,
    PeerPort => $opt_p,
    Proto    => 'tcp',
  );
  
  if ($SH) {
    print "There is already a tcp-service running on $ip:$opt_p !\n";
    print "Select another port for F*EX by running $0 -p OTHERPORT $ip\n";
    print "or an alternative IP-address by running $0 OTHERADDRESS\n";
    exit 5;
  }
}

print "prerequisites checked, ok\n";

unless (getpwnam('fex')) {
  print "creating user fex\n";
  system 'useradd -c "File EXchange" -m fex';
}

@FEX = getpwnam('fex') or die "cannot create user fex\n";
$FEXHOME  = $FEX[7];

die "no HOME directory for user fex\n" unless -d $FEXHOME;

print "Installing:\n";

@save = (
  "$FEXHOME/lib/fex.ph",
  "$FEXHOME/lib/fup.pl",
  "$FEXHOME/htdocs/index.html",
);

foreach $f (@save) {
  system "mv -v $f ${f}_save" if -f $f;
}

system "cp -av bin cgi-bin lib etc htdocs doc $FEXHOME";

if  (-d "$FEXHOME/spool") {
  &convert_spool;
} else {
  chmod 0700,$FEXHOME;
  mkdir "$FEXHOME/spool",0700 or die "cannot mkdir $FEXHOME/spool - $!\n";
  mkdir "$FEXHOME/spool/.error",0700;
}

foreach $f (@save) {
  if (-f "${f}_save") {
    system "mv -v $f ${f}_new ; mv -v ${f}_save $f";
  }
}

system "chown -R fex:root $FEXHOME";

if (-d '/etc/xinetd.d') {
  unless (-f $xinetd) {
    open $xinetd,">$xinetd" or die "cannot write $xinetd - $!\n";
    open F,'etc/xinetd_fex' or die "cannot read etc/xinetd_fex - $!\n";
    while (<F>) {
      s/FEXHOME/$FEXHOME/;
      s/PORT/$opt_p/;
      s/ADDRESS/$ip/;
      print {$xinetd} $_;
    }
    close F;
    close $xinetd;
    system qw(/etc/init.d/xinetd restart);
  }
} else {
  print "WARNING: No /etc/xinetd.d found.\n";
  print "WARNING: You have to install etc/xinetd_fex manually.\n";
}

$crontab = `crontab -u fex -l 2>/dev/null`;
if ($crontab !~ /fex_cleanup/) {
  open $crontab,">fex.cron" or die "cannot create fex.cron - $!\n";
  print {$crontab} $crontab,"\n";
  print {$crontab} " 3 3 * * * exec $FEXHOME/bin/fex_cleanup\n";
  close $crontab;
  system qw(crontab -u fex fex.cron);
}

exit if -f "$FEXHOME/lib/fex.ph_new";

system qw(perl -p -i -e),"s/HOSTNAME/$hostname/","$FEXHOME/lib/fex.ph";

print <<EOD;

See also: 
	bin/fexsend
	bin/fexget
	bin/sexsend
	bin/sexget
they are (optional) UNIX shell-clients. Install them, wherever you want.

Your local F*EX config is in $FEXHOME/lib/fex.ph
Please edit it *NOW* and change it to your needs!
EOD


# convert spool: user --> user@maildomain
sub convert_spool {
  my ($f,$d,$to,$from,$link);

  $FEXLIB = "$FEXHOME/lib";
  require "$FEXLIB/fex.pp" or die "$0: cannot load $FEXLIB/fex.pp - $!\n";
  
  foreach $f (glob 'spool/.dkeys/*') {
    if ($link = readlink $f) {
      (undef,$to,$from,$file) = split('/',$link);
      if ($file) {
        $to   .= '@'.$mdomain if $to   !~ /@/;
        $from .= '@'.$mdomain if $from !~ /@/;
        if ($link ne "../$to/$from/$file") {
          unlink $f;
          symlink "../$to/$from/$file",$f;
        }
      }
    }
  }
  
  foreach $d (glob "spool/*/*") {
    if (not -l $d and -d $d and $d =~ m:/[^@]+$: and $d !~ /[A-Z]/) {
      rename $d,"$d\@$mdomain";
    }
  }
  
  foreach $d (glob "spool/*") {
    if (not -l $d and -d $d and $d !~ /@/ and $d !~ /[A-Z]/) {
      rename $d,"$d\@$mdomain";
    }
  }

}
