# -*- perl -*-
use 5.008;
use Fcntl qw':flock :seek :mode';
use IO::Handle;
use IPC::Open3;
use Encode;
use Digest::MD5 qw'md5_hex';
use File::Basename;
use Sys::Hostname;
use Symbol qw'gensym';
# set and untaint ENV if not in CLI (fexsrv provides clean ENV)
unless (-t) {
foreach my $v (keys %ENV) {
($ENV{$v}) = ($ENV{$v} =~ /(.*)/s);
}
$ENV{PATH} = '/usr/local/bin:/bin:/usr/bin';
$ENV{IFS} = " \t\n";
$ENV{BASH_ENV} = '';
}
unless ($FEXLIB = $ENV{FEXLIB} and -d $FEXLIB) {
die "$0: found no FEXLIB - fexsrv needs full path\n"
}
$FEXLIB =~ s:/+:/:g;
$FEXLIB =~ s:/$::;
# $FEXHOME is top-level directory of F*EX installation or vhost
# $ENV{HOME} is login-directory of user fex
# in default-installation both are equal, but they may differ
$FEXHOME = $ENV{FEXHOME} or $ENV{FEXHOME} = $FEXHOME = dirname($FEXLIB);
umask 077;
# defaults
$hostname = gethostname();
$tmpdir = $ENV{TMPDIR} || '/var/tmp';
$spooldir = $FEXHOME.'/spool';
$docdir = $FEXHOME.'/htdocs';
$logdir = $spooldir;
$autodelete = 'YES';
$overwrite = 'YES';
$limited_download = 'YES'; # multiple downloads only from same client
$keep = 5; # days
$recipient_quota = 0; # MB
$sender_quota = 0; # MB
$timeout = 30; # seconds
$bs = 2**16; # I/O blocksize
$use_cookies = 1;
$sendmail = '/usr/lib/sendmail';
$sendmail = '/usr/sbin/sendmail' unless -x $sendmail;
$mailmode = 'auto';
$bcc = 'fex';
$default_locale = '';
$fop_auth = 0;
$mail_authid = 'yes';
$force_https = 0;
$debug = 0;
$FHS = -f '/etc/fex/fex.ph' and -d '/usr/share/fex/lib';
# Debian FHS
if ($FHS) {
$ENV{FEXHOME} = $FEXHOME = '/usr/share/fex';
$spooldir = '/var/spool/fex';
$logdir = '/var/log/fex';
$docdir = '/var/lib/fex/htdocs';
$notify_newrelease = '';
}
# allowed download managers (HTTP User-Agent)
$adlm = '^(Axel|fex)';
# allowed multi download recipients
$amdl = '^(anonymous|_fexmail_)';
# local config
require "$FEXLIB/fex.ph" or die "$0: cannot load $FEXLIB/fex.ph - $!";
$fop_auth = 0 if $fop_auth =~ /no/i;
$mail_authid = 0 if $mail_authid =~ /no/i;
$force_https = 0 if $force_https =~ /no/i;
$debug = 0 if $debug =~ /no/i;
# check for name based virtual host
$vhost = vhost($ENV{'HTTP_HOST'});
push @doc_dirs,$docdir;
foreach my $ld (glob "$FEXHOME/locale/*/htdocs") {
push @doc_dirs,$ld;
}
$nomail = ($mailmode =~ /^MANUAL|nomail$/i);
if (not $nomail and not -x $sendmail) {
http_die("found no sendmail\n");
}
http_die("cannot determine the server hostname") unless $hostname;
$ENV{PROTO} = 'http' unless $ENV{PROTO};
$keep = $keep_default ||= $keep || 5;
$fra = $ENV{REMOTE_ADDR} || '';
$sid = $ENV{SID} || '';
mkdirp($dkeydir = "$spooldir/.dkeys"); # download keys
mkdirp($ukeydir = "$spooldir/.ukeys"); # upload keys
mkdirp($akeydir = "$spooldir/.akeys"); # authentification keys
mkdirp($skeydir = "$spooldir/.skeys"); # subuser authentification keys
mkdirp($gkeydir = "$spooldir/.gkeys"); # group authentification keys
mkdirp($xkeydir = "$spooldir/.xkeys"); # extra download keys
mkdirp($lockdir = "$spooldir/.locks"); # download lock files
if (my $ra = $ENV{REMOTE_ADDR} and $max_fail) {
mkdirp("$spooldir/.fail");
$faillog = "$spooldir/.fail/$ra";
}
unless ($admin) {
$admin = $ENV{SERVER_ADMIN} ? $ENV{SERVER_ADMIN} : 'fex@'.$hostname;
}
# $ENV{SERVER_ADMIN} may be set empty in fex.ph!
$ENV{SERVER_ADMIN} = $admin unless defined $ENV{SERVER_ADMIN};
$mdomain ||= '';
if ($use_cookies) {
if (my $cookie = $ENV{HTTP_COOKIE}) {
if ($cookie =~ /\bakey=(\w+)/) { $akey = $1 }
# elsif ($cookie =~ /\bskey=(\w+)/) { $skey = $1 }
}
}
if (@locales) {
if ($default_locale and not grep /^$default_locale$/,@locales) {
push @locales,$default_locale;
}
if (@locales == 1) {
$default_locale = $locales[0];
}
}
$default_locale ||= 'english';
unless ($durl) {
my $host = '';
my $port = 0;
($host,$port) = split(':',$ENV{HTTP_HOST}||'');
$host = $hostname;
unless ($port) {
$port = 80;
if (open my $xinetd,'<',"/etc/xinetd.d/fex") {
while (<$xinetd>) {
if (/^\s*port\s*=\s*(\d+)/) {
$port = $1;
last;
}
}
close $xinetd;
}
}
# use same protocal as uploader for download
if ($ENV{PROTO} eq 'https' and $port == 443 or $port == 80) {
$durl = "$ENV{PROTO}://$host/fop";
} else {
$durl = "$ENV{PROTO}://$host:$port/fop";
}
}
@durl = ($durl) unless @durl;
sub reexec {
exec($FEXHOME.'/bin/fexsrv') if $ENV{KEEP_ALIVE};
exit;
}
sub jsredirect {
$url = shift;
$cont = shift || 'request accepted: continue';
http_header('200 ok');
print html_header($head||$ENV{SERVER_NAME});
pq(qq(
''
''
'