$EDITOR = $ENV{EDITOR} || $ENV{VISUAL} ||
(-x '/usr/bin/editor' ? '/usr/bin/editor' : 'vi');
-$opt_c = $opt_v = $opt_l = $opt_L = $opt_h = $opt_w = $opt_u = $opt_R = 0;
+$opt_c = $opt_v = $opt_l = $opt_L = $opt_h = $opt_w = $opt_u = 0;
$opt_M = $opt_E = 0;
$opt_r = $opt_d = $opt_q = $opt_a = $opt_n = $opt_k = $opt_m = '';
-$opt_y = $opt_S = $opt_C = $opt_D = $opt_A = $opt_V = $opt_P = '';
+$opt_y = $opt_S = $opt_C = $opt_D = $opt_A = $opt_V = $opt_P = $opt_R = '';
${'opt_/'} = '';
@__ = @ARGV;
warn "WARNING: \$spooldir differs from $FEXHOME/spool !\n";
}
-getopts('hcvlLwuMRE/q:r:d:a:n:k:m:y:S:C:A:V:D:P:') or usage(2);
+getopts('hcvlLwuME/q:r:d:a:n:k:m:y:S:C:A:V:D:P:R:') or usage(2);
usage(0) if $opt_h;
examples() if $opt_E;
# set user restriction file
if ($opt_R) {
- $user = shift or die "usage: $0 -R user\n";
- $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
- die "$0: no user $user\n" unless -d "$spooldir/$user";
- unless (@local_rdomains) {
- die "$0: no \@local_rdomains in server config\n";
- }
- my $rf = "$spooldir/$user/\@ALLOWED_RECIPIENTS";
- open $rf,'>',$rf or die "$0: cannot open $rf - $!";
- print {$rf} "\@LOCAL_RDOMAINS\n";
- close $rf;
- print "$user restricted\n";
+ if ($opt_R eq 'i') {
+ $user = shift or die "usage: $0 -Ri user\n";
+ $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
+ die "$0: no user $user\n" unless -d "$spooldir/$user";
+ unless (@local_rdomains) {
+ die "$0: no \@local_rdomains in server config\n";
+ }
+ my $rf = "$spooldir/$user/\@ALLOWED_RECIPIENTS";
+ open $rf,'>',$rf or die "$0: cannot open $rf - $!";
+ print {$rf} "\@LOCAL_RDOMAINS\n";
+ close $rf;
+ print "$user restricted to internal recipients\n";
+ exit;
+ } elsif ($opt_R eq 'l') {
+ $user = shift or die "usage: $0 -Rl user\n";
+ $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
+ die "$0: no user $user\n" unless -d "$spooldir/$user";
+ my $rf = "$spooldir/$user/\@ALLOWED_RECIPIENTS";
+ open $rf,'>',$rf or die "$0: cannot open $rf - $!";
+ print {$rf} "\@LOCAL_USERS\n";
+ close $rf;
+ print "$user restricted to local recipients\n";
+ exit;
+ } else {
+ usage(2);
+ }
exit;
}
$0 -/ admin auth-ID # set new admin and auth-ID
$0 -q user s:quota # set new disk quota (MB) for sender user
$0 -q user r:quota # set new disk quota (MB) for recipient user
-$0 -R user # restrict user: only internal recipients allowed
+$0 -Ri user # restrict user: only internal domain recipients allowed
+$0 -Rl user # restrict user: only local users as recipients allowed
$0 -rr user # edit user recipients restriction
$0 -ru user # edit user upload restriction
$0 -rd user # edit user download restriction
our ($SH,$windoof,$sigpipe,$useragent);
our ($FEXSERVER);
-our $version = 20150826;
+our $version = 20160104;
# server defaults
my $server = 'fex.rus.uni-stuttgart.de';
# clean up regular spool
opendir $spooldir,'.' or die "$0: $spooldir - $!\n";
while ($to = readdir $spooldir) {
+ next if $to =~ /^\./;
next if $to !~ /@/ or $_ = readlink($to) and not /\//;
+ next unless -d $to;
if (@demo and -f "$to/.demo" and time > lmtime("$to/.demo")+$demo[1]*DS) {
logdel($to,"demo user $to deleted");
next;
}
- if (-d $to and $to !~ /^\./) {
- unless (opendir TO,$to) {
- warn "$0: $spooldir/$to - $!\n";
- next;
- }
- while ($from = readdir TO) {
- next if $from !~ /@/;
- if ($from eq '@GROUP') {
- foreach $group (glob "$to/$from/*") {
- if (readlink $group and not -f $group) {
- logdel($group,"$group deleted (master has gone)");
- }
+ unless (opendir TO,$to) {
+ warn "$0: $spooldir/$to - $!\n";
+ next;
+ }
+ while ($from = readdir TO) {
+ next if $from !~ /@/;
+ if ($from eq '@GROUP') {
+ foreach $group (glob "$to/$from/*") {
+ if (readlink $group and not -f $group) {
+ logdel($group,"$group deleted (master has gone)");
}
- } else {
- if (-d "$to/$from" and $from !~ /^\./) {
- unless (opendir FROM,"$to/$from") {
- warn "$0: $spooldir/$to/$from - $!\n";
- next;
- }
- while ($file = readdir FROM) {
- next if $file eq '.' or $file eq '..';
- if (-d "$to/$from/$file" and $file !~ /^\./) {
- cleanup($to,$from,$file);
- rmdir "$to/$from/$file" unless $opt_d;
- }
+ }
+ } else {
+ if (-d "$to/$from" and $from !~ /^\./) {
+ unless (opendir FROM,"$to/$from") {
+ warn "$0: $spooldir/$to/$from - $!\n";
+ next;
+ }
+ while ($file = readdir FROM) {
+ next if $file eq '.' or $file eq '..';
+ if (-d "$to/$from/$file" and $file !~ /^\./) {
+ cleanup($to,$from,$file);
+ rmdir "$to/$from/$file" unless $opt_d;
}
- closedir FROM;
- rmdir "$to/$from" unless $opt_d;
}
+ closedir FROM;
+ rmdir "$to/$from" unless $opt_d;
}
}
- closedir TO;
- unless (-f "$to/\@PERSISTENT" or $to eq $admin) {
- @glob = glob "$to/*/* $to/\@MAINUSER/* $to/\@GROUP/*";
- unless (@glob or -f "$to/\@") {
- logdel($to,"$to deleted");
- }
- $user = $to;
- if ($login_check and -l "$user/.login") {
- my $lc = &$login_check(readlink("$user/.login"));
- if ($lc) {
- if (-f "$user/\@~" and not "$user/@") {
- rename "$user/\@~","$user/@" unless $opt_d;
- logv("$user reanimated (login_check)");
- }
- } else {
- rename "$user/@","$user/\@~" unless $opt_d;
- logv("$user deactivated (login_check)");
+ }
+ closedir TO;
+ unless (-f "$to/\@PERSISTENT" or $to eq $admin) {
+ @glob = glob "$to/*/* $to/\@MAINUSER/* $to/\@GROUP/*";
+ unless (@glob or -f "$to/\@") {
+ logdel($to,"$to deleted");
+ }
+ $user = $to;
+ if ($login_check and -l "$user/.login") {
+ my $lc = &$login_check(readlink("$user/.login"));
+ if ($lc) {
+ if (-f "$user/\@~" and not "$user/@") {
+ rename "$user/\@~","$user/@" unless $opt_d;
+ logv("$user reanimated (login_check)");
}
+ } else {
+ rename "$user/@","$user/\@~" unless $opt_d;
+ logv("$user deactivated (login_check)");
}
}
}
if (time > lmtime($user)+$expire*DS) {
# print "$spooldir/$user\n";
- my $locale = readlink "$user/\@LOCALE";
+ local $locale = readlink "$user/\@LOCALE";
$locale = 'english' unless $locale and $reactivation{$locale};
&{$reactivation{$locale}}($expire,$user);
sleep 1;
our ($fexhome,$idf,$tmpdir,$windoof,$useragent);
our ($xv,%autoview);
our $bs = 2**16; # blocksize for tcp-reading and writing file
-our $version = 20150826;
+our $version = 20160104;
our $CTYPE = 'ISO-8859-1';
our $fexsend = $ENV{FEXSEND} || 'fexsend';
+our $DEBUG = $ENV{DEBUG};
my %SSL = (SSL_version => 'TLSv1');
my $sigpipe;
$SSL{SSL_verify_mode} = 0;
chdir $ENV{USERPROFILE}.'\Desktop';
# open XX,'>XXXXXX';close XX;
+} elsif ($Config{osname} =~ /^darwin/i or $ENV{MACOS}) {
+ $0 =~ s:(.*)/:: and $ENV{PATH} .= ":$1";
+ $fexhome = $ENV{FEXHOME} || $ENV{HOME}.'/.fex';
+ $tmpdir = $ENV{FEXTMP} || $ENV{TMPDIR} || "$fexhome/tmp";
+ $idf = "$fexhome/id";
+ $_ = `sw_vers -productVersion 2>/dev/null`||'';
+ chomp;
+ $useragent = "fexget-$version (MacOS $_)";
} else {
$0 =~ s:(.*)/:: and $ENV{PATH} .= ":$1";
$fexhome = $ENV{FEXHOME} || $ENV{HOME}.'/.fex';
}
}
-my ($file,%files,$download,$server,$port,$fop);
+my ($file,%files,$download,$server,$port,$fop,$https);
if ($opt_f) {
unless ($ENV{FEXID} or -f $ENV{HOME}.'/.fex/id') {
}
if ($url =~ m{^http(s?)://([\w\.\-]+)(:(\d+))?(/.*fop/\S+)}) {
+ $https = $1;
$server = $2;
$port = $4 || ($1?443:80);
$fop = $5;
if ($ENV{DISPLAY} and $download =~ /\.(gif|jpg|png|tiff?)$/i) {
# see also mimeopen and xdg-mime
+ # http://unix.stackexchange.com/questions/144047/how-does-xdg-open-do-its-work
if (my $xv = $xv || pathsearch('xv') || pathsearch('xdg-open')) {
printf "run \"%s %s\" [Yn] ? ",basename($xv),basename($download);
$_ = <STDIN>||'';
}
if ($download =~ /$atype/) {
- if ($download =~ /\.(tgz|tar.gz)$/) { extract('tar tvzf','tar xvzf') }
- elsif ($download =~ /\.tar$/) { extract('tar tvf','tar xvf') }
- elsif ($download =~ /\.zip$/i) { extract('unzip -l','unzip') }
- elsif ($download =~ /\.7z$/i) { extract('7z l','7z x') }
+ if ($download =~ /\.(tgz|tar.gz)$/) { extract('tar tvzf','tar xvzf') }
+ elsif ($download =~ /\.tar$/) { extract('tar tvf','tar xvf') }
+ elsif ($download =~ /\.zip$/i) { extract('unzip -l','unzip') }
+ elsif ($download =~ /\.7z$/i) { extract('7z l','7z x') }
else { die "$0: unknown archive \"$download\"\n" }
if ($? == 0) {
unlink $download;
my $l = shift;
my $x = shift;
my $d = $download;
- my $xd = '.';
+ my $xd = '';
local $_;
if (-t and not $windoof) {
system(split(' ',$l),$download);
$d =~ s:.*/:./:;
$d =~ s/\.[^.]+$//;
+ $d =~ s:/*$:/:;
for (;;) {
$xd = inquire("extract to directory (Ctrl-C to keep archive): ",$d);
- last if $xd =~ s:^(\./*)*!?$:./:;
+ last if $xd =~ s:^(\./*)*!?$::;
if ($xd eq '-') {
print "keeping $download\n";
exit;
last;
}
}
- print "extracting to $xd :\n";
+ print "extracting to $xd :\n" if $xd;
system(split(' ',$x),$download);
+ print "extracted to $xd\n" if $xd;
}
sub del {
sub forward {
my $url = shift;
my ($server,$port);
- my ($uri,$dkey,$list,$cmd,$n);
+ my ($uri,$dkey,$list,$cmd,$n,$copy);
my @r;
if ($url =~ m{^http(s?)://([\w\.\-]+)(:(\d+))?(/fop/.+)}) {
die "$0: no reply from fex server $server\n" unless $_;
warn "<-- $_" if $opt_v;
- unless (/^HTTP.*200/) {
+ if (/^HTTP.*already exists/) {
+ if ($uri =~ m:/fop/(\w+)/:) {
+ $dkey = $1;
+ }
+ } elsif (/^HTTP.*200/) {
+ # ok!
+ } else {
s/^HTTP.... \d+ //;
die "$0: $_";
}
warn "<-- $_" if $opt_v;
}
- $cmd = 'fexsend -l >/dev/null 2>&1';
- print "$cmd\n" if $opt_v;
+ print "fexsend -l\n" if $opt_v;
system 'fexsend -l >/dev/null 2>&1';
$list = $ENV{HOME}.'/.fex/tmp/fexlist';
open $list,$list or die "$0: cannot open $list - $!\n";
$pipe = $download = $opt_s;
} elsif (-p $opt_s or -c $opt_s) {
$download = $opt_s;
+ $nocheck = 'pipe or character device';
} else {
$download = $file.'.tmp';
$seek = -s $download || 0;
}
} else {
# ask server for real file name
- serverconnect($server, $port);
- sendheader("$server:$port","HEAD $proxy_prefix$fop HTTP/1.1","User-Agent: $useragent");
+ sendheader(
+ "$server:$port",
+ "HEAD $proxy_prefix$fop HTTP/1.1",
+ "User-Agent: $useragent"
+ );
my $reply = $_ = <$SH>;
unless (defined $_ and /\w/) {
die "$0: no response from server\n";
}
}
if ($checkstorage and not $nocheck) {
- $t0 = time;
+ my $t0 = my $t1 = my $t2 = time;
my $n = 0;
+ my $buf = '.' x M;
+ my $storagetest = $file.'.test';
+ my $error = "$0: cannot write \"$storagetest\"";
+ open $storagetest,'>',$storagetest or die "$error - $!\n";
print STDERR "checking storage...\r";
- $buf = '.' x M;
- while (-s $download < $checkstorage) {
- syswrite X,$buf or do {
- unlink $download;
- die "\n$0: cannot write $download - $!\n";
+ while (-s $storagetest < $checkstorage) {
+ syswrite $storagetest,$buf or do {
+ unlink $storagetest;
+ die "\n$error - $!\n";
};
$n++;
- print STDERR "checking storage... ".$n." MB\r";
+ $t2 = int(time);
+ if ($t2 > $t1) {
+ print STDERR "checking storage... ".$n." MB\r";
+ $t1 = $t2;
+ }
}
- close X or do {
- unlink $download;
- die "\n$0: cannot write $download - $!\n";
+ close $storagetest or do {
+ unlink $storagetest;
+ die "\n$error - $!\n";
};
print STDERR "checking storage... ".$n." MB ok!\n";
- unlink $download;
- if (time-$t0 < 25) {
- open X,'>',$download or die "$0: cannot write to \"$download\" - $!\n";
- } else {
+ unlink $storagetest;
+ if (time-$t0 > 25) {
# retry after timeout
+ serverconnect($server,$port);
return(download($server,$port,$fop,'nocheck'))
}
}
}
-sub quote {
- local $_ = shift;
- s/([^\w¡-ÿ_%\/=~:.,-])/\\$1/g;
- return $_;
-}
-
-
{
my $tty;
if (defined(&TIOCSTI) and $tty and open($tty,'>',$tty)) {
print $prompt;
+ # push default answer into keyboard buffer
foreach my $a (split("",$default)) { ioctl($tty,&TIOCSTI,$a) }
chomp($_ = <STDIN>||'');
} else {
- $prompt =~ s/([\?:=]\s*)/ [$default]$1/ or $prompt .= " [$default]";
+ $prompt =~ s/([\?:=]\s*)/ [$default]$1/ or $prompt .= " [$default] ";
print $prompt;
chomp($_ = <STDIN>||'');
$_ = $default unless length;
my $connect = "CONNECT $server:$port HTTP/1.1";
local $_;
- if ($opt_v and $port == 443 and %SSL) {
- foreach my $v (keys %SSL) {
- printf "%s => %s\n",$v,$SSL{$v};
- }
- }
-
if ($proxy) {
tcpconnect(split(':',$proxy));
- if ($port == 443) {
+ if ($https) {
printf "--> %s\n",$connect if $opt_v;
nvtsend($connect,"");
$_ = <$SH>;
unless (/^HTTP.1.. 200/) {
die "$0: proxy error : $_";
}
- eval "use IO::Socket::SSL";
- die "$0: cannot load IO::Socket::SSL\n" if $@;
+ &enable_ssl;
$SH = IO::Socket::SSL->start_SSL($SH,%SSL);
}
} else {
tcpconnect($server,$port);
}
-# if ($port == 443 and $opt_v) {
+# if ($https and $opt_v) {
# printf "%s\n",$SH->get_cipher();
# }
}
undef $SH;
}
- if ($port == 443) {
+ if ($https) {
# eval "use IO::Socket::SSL qw(debug3)";
- eval "use IO::Socket::SSL";
- die "$0: cannot load IO::Socket::SSL\n" if $@;
+ &enable_ssl;
$SH = IO::Socket::SSL->new(
PeerAddr => $server,
PeerPort => $port,
if ($SH) {
autoflush $SH 1;
+ binmode $SH;
} else {
die "$0: cannot connect $server:$port - $@\n";
}
}
+sub enable_ssl {
+ eval "use IO::Socket::SSL";
+ die "$0: cannot load IO::Socket::SSL\n" if $@;
+ eval '$SSL{SSL_verify_mode} = 0 if Net::SSLeay::SSLeay() <= 9470143';
+ if ($opt_v) {
+ foreach my $v (keys %SSL) {
+ printf "%s => %s\n",$v,$SSL{$v};
+ }
+ }
+}
+
+
sub sendheader {
my $sp = shift;
my @head = @_;
}
+sub quote {
+ local $_ = shift;
+ s/([^\w\@\/%^,.=+_:+-])/\\$1/g;
+ return $_;
+}
+
+
+sub debug {
+ print "## DEBUG: @_\n" if $DEBUG;
+}
+
+
# from MIME::Base64::Perl
sub encode_b64 {
my $res = "";
$| = 1;
-our ($SH,$fexhome,$idf,$tmpdir,$windoof,$useragent,$editor,$nomail);
+our ($SH,$fexhome,$idf,$tmpdir,$windoof,$macos,$useragent,$editor,$nomail);
our ($anonymous,$public);
our ($tpid,$frecipient);
our ($FEXID,$FEXXX,$HOME);
our (%alias);
our $chunksize = 0;
-our $version = 20150826;
+our $version = 20160104;
our $_0 = $0;
-our $DEBUG;
+our $DEBUG = $ENV{DEBUG};
my %SSL = (SSL_version => 'TLSv1');
my $sigpipe;
$useragent = sprintf("fexsend-$version (%s %s)",
$Config{osname},$Config{archname});
$SSL{SSL_verify_mode} = 0;
+} elsif ($Config{osname} =~ /^darwin/i or $ENV{MACOS}) {
+ $macos = $Config{osname};
+ # http://stackoverflow.com/questions/989349/running-a-command-in-a-new-mac-os-x-terminal-window
+ $HOME = (getpwuid($<))[7]||$ENV{HOME};
+ $fexhome = $HOME.'/.fex';
+ $tmpdir = $ENV{FEXTMP} || $ENV{TMPDIR} || "$fexhome/tmp";
+ $tmpdir =~ s:/$::;
+ $idf = "$fexhome/id";
+ chmod 0600,$idf;
+ $editor = $ENV{EDITOR} || 'open -W -n -e';
+ $_ = `sw_vers -productVersion 2>/dev/null`||'';
+ chomp;
+ $useragent = "fexsend-$version (MacOS $_)";
} else {
$0 =~ s:.*/::;
$HOME = (getpwuid($<))[7]||$ENV{HOME};
$fexhome = $HOME.'/.fex';
$tmpdir = $ENV{FEXTMP} || "$fexhome/tmp";
$idf = "$fexhome/id";
+ chmod 0600,$idf;
$editor = $ENV{EDITOR} || 'vi';
$_ = `(lsb_release -d||uname -a)2>/dev/null`||'';
chomp;
s/^Description:\s+//;
$useragent = "fexsend-$version ($_)";
- chmod 0600,$idf;
}
if (-f ($_ = '/etc/fex/config.pl')) {
my $timeout = 30; # server timeout
my $fexlist = "$tmpdir/fexlist";
my ($usage,$hints);
-my $xx = $0 =~ /^xx/;
+my $xx = $0 =~ /\bxx$/;
if ($xx) {
$usage = "usage: send file(s): xx [:slot] file...\n".
$usage = <<EOD;
usage: $0 [options] file(s) [@] recipient(s)
or: $0 [special options]
+ or: $0 -l [recipient-regexp]
or: $0 -f \# recipient(s)
or: $0 -x \# [-C -k -D -K -S]
options: -v verbose mode
-c compress file with gzip
-g encrypt file with gpg
-m limit limit throughput (kB/s)
- -i tag use ID data [tag] from ID file
+ -i account use ID data [account] from ID file
-C comment add comment to notification e-mail
-k max keep file max days on fex server
-D delay auto-delete after download
-o overwrite mode, do not resume
-a archive put files in archive (.zip .7z .tar .tgz)
-s stream read data from pipe and upload it with stream name
-special options: -I initialize ID file or show ID
- -I tag add alternate ID data (secondary logins) to ID file
- -l list sent files numbered (# needed for -f -x -d -N)
- -f \# forward already uploaded file to another recipient
- -x \# modify options -C -k -D -K for already uploaded file
- -d \# delete file on fex server
- -N \# resend notification e-mail
- -Q check quotas
- -A edit server address book (aliases)
- -S show server/user settings and auth-ID
- -H show hints, examples and more options
- -V show version
- (\# is a file number, see output from $0 -l)
+special options: -I initialize ID file or show ID
+ -I account add alternate ID data (secondary logins) to ID file
+ -l list sent files numbers (# needed for -f -x -d -N)
+ -f \# forward already uploaded file to another recipient
+ -x \# use -C -k -D -K for already uploaded file
+ -d \# delete file on fex server
+ -N \# resend notification e-mail
+ -Q check quotas
+ -A edit server address book (aliases)
+ -S show server/user settings and auth-ID
+ -H show hints, examples and more options
+ -V show version
+ (# is a file number, see output from $0 -l)
examples: $0 visualization.mpg framstag\@rus.uni-stuttgart.de
$0 -a images.zip *.jpg webmaster\@flupp.org,metoo
lshw | $0 -s hardware.list admin\@flupp.org
With option -s you can send any data coming from a pipe (STDIN) as a file
without wasting local disc space.
-With option -X you can specify any parameter, e.g.: -X autodelete=yes
+With option -X you can specify any URL parameter, e.g.:
+fexsend -X autodelete=yes ...
+fexsend -X 'autodelete=no&locale=german' ...
For HTTPS you can set the environment variables:
SSLVERIFY=1 # activate server identity verification
$_ = "$fexhome/config.pl"; require if -f;
getopts('hvIm:') or die $usage;
} else {
+ if ($macos and not @ARGV) {
+ &ask_file;
+ }
$opt_h = $opt_v = $opt_m = $opt_c = $opt_k = $opt_d = $opt_l = $opt_I = 0;
$opt_H = $opt_K = $opt_D = $opt_R = $opt_M = $opt_L = $opt_Q = $opt_A = 0;
$opt_x = $opt_o = $opt_g = $opt_V = $opt_U = $opt_F = $opt_n = $opt_q = 0;
elsif ($opt_A) { edit_address_book($from) }
elsif (${'opt_@'}) { &show_address_book }
elsif ($opt_d and $anonymous) { &purge }
-elsif ($opt_d and $ARGV[-1] =~ /^\d+$/) { &delete }
+elsif ($opt_d and $ARGV[-1] =~ /^\d+$/) { &delete_file_number }
else { &send_fex }
exit;
my ($fexcgi,$from,$id);
if (open $idf,$idf) {
$fexcgi = <$idf>;
+ # $fexcgi = <$idf> if $fexcgi =~ /^\[.+\]/;
$from = <$idf>;
$id = <$idf>;
while (<$idf>) {
sendheader("$fs:$port","GET $proxy_prefix/fur?user=$mail&verify=no HTTP/1.1");
http_response();
+ # header
while (<$SH>) {
s/\r//;
printf "<-- $_"if $opt_v;
}
+# menu for MacOS users
+sub menu {
+ my $key;
+ my $new;
+ local $_;
+
+ system 'clear';
+ print "\n";
+ print "fexsend-$version\n";
+
+ for (;;) {
+ if (open $idf,$idf) {
+ $fexcgi = getline($idf) and
+ $from = getline($idf) and
+ $id = getline($idf);
+ close $idf;
+ last if $id;
+ }
+ &set_ID;
+ }
+
+ print "\n";
+ print "$from on $fexcgi\n";
+ print "\n";
+
+ for (;;) {
+ print "\n";
+ print "[s] send a file or directory\n";
+ print "[u] update fexsend\n";
+ print "[l] change login data (user, server, auth-ID)\n";
+ print "[h] help\n";
+ print "[q] quit\n";
+ print "\n";
+ print "your choice: ";
+ $key = ReadKey(0);
+ if ($key eq 'q') {
+ print "$key\n";
+ print "\n";
+ print "Type [Cmd]W to close this window.\n";
+ exit;
+ }
+ if ($key eq 'h') {
+ print "$key\n";
+ print
+ "\n".
+ "With fexsend you can send files of any size to any e-mail address.\n".
+ "\n".
+ "At the recipient or file prompt [RETURN] brings you to this option menu.\n".
+ "\n".
+ "To send more than one file:\n".
+ "When you enter * at the file prompt, you will be first asked for an archive name\n".
+ "and then you can drag+drop multiple files.\n".
+ "\n".
+ "Do not forget to terminate each input line with [RETURN].\n".
+ "\n".
+ "See http://fex.rus.uni-stuttgart.de/ for more informations.\n";
+ next;
+ }
+ if ($key eq 'u') {
+ print "$key\n";
+ if ($0 =~ m:(^/client/|/sw/):) {
+ print "\n";
+ print "use swupdate to update fexsend!\n";
+ next;
+ }
+ $new = $0.'.new';
+ system "curl http://fex.belwue.de/download/fexsend>".quote($new);
+ chmod 0755,$new;
+ system qw'perl -c',$new;
+ if ($? == 0) {
+ rename $new,$0;
+ exec $0;
+ } else {
+ print "\n";
+ print "cannot install new fexsend\n";
+ }
+ next;
+ }
+ if ($key eq 'l') {
+ print "$key\n";
+ system 'clear';
+ &set_ID;
+ next;
+ }
+ if ($key eq 's' or $key eq "\n") {
+ print "s\n";
+ &ask_file;
+ next;
+ }
+ }
+ exit;
+}
+
+
+# for MacOS
+sub ask_file {
+ my ($file,$comment,$recipient,$archive,$size,$cmd,$key);
+ my @files;
+ my $qfiles;
+ local $_;
+
+ system 'clear';
+
+ &set_ID unless -s $idf;
+
+ print "\n";
+ print "Enter [RETURN] after each input line.\n";
+ print "\n";
+
+ for (;;) {
+ print "Recipient(s): ";
+ $recipient = <STDIN>;
+ chomp $recipient;
+ $recipient =~ s/^\s+//;
+ $recipient =~ s/\s+$//;
+ $recipient =~ s/[\s;,]+/,/g;
+ &menu unless $recipient;
+ last if $recipient =~ /\w/ or $recipient eq '.';
+ }
+
+ for (;;) {
+ print "\n";
+ print "Drag a file into this window or hit [RETURN] ";
+ print $archive ? "to continue.\n" : "for menu options.\n";
+ print "File to send: ";
+ $file = <STDIN>||'';
+ chomp $file;
+ $file =~ s/^\s+//;
+ $file =~ s/ $// if $file !~ /\\ $/;
+ &menu unless $file or $archive;
+ if ($file eq '*') {
+ print "Archive name: ";
+ $archive = <STDIN>||'';
+ chomp $archive;
+ next unless $archive;
+ $archive =~ s/^\s+//g;
+ $archive =~ s/\s+$//g;
+ $archive =~ s/[^\w=.+-]/_/g;
+ next;
+ }
+ if ($file) {
+ unless (-e $file) {
+ $file =~ s/\\\\/\000/g;
+ $file =~ s/\\//g;
+ $file =~ s/\000/\\/g;
+ }
+ unless (-r $file) {
+ print "\"$file\" is not readable\n";
+ next;
+ }
+ my $qf = quote($file);
+ if (`du -ms $qf` =~ /^(\d+)/) {
+ $size += $1;
+ printf "%d MB\n",$1;
+ }
+ if ($archive) {
+ push @files,$file;
+ next;
+ }
+ }
+ if ($archive) {
+ next unless @files;
+ $qfiles = join(' ',map(quote($_),@files));
+ if ($size < 2048) {
+ $archive .= '.zip';
+ } else {
+ $archive .= '.tar';
+ }
+ }
+ print "\n";
+ print "Comment: ";
+ $comment = <STDIN>||'';
+ chomp $comment;
+ print "\n";
+ if ($comment =~ s/^:\s*-/-/) {
+ $cmd = quote($0)." $comment ";
+ if ($archive) {
+ $cmd .= '-a '.quote($archive).' '.$qfiles;
+ } else {
+ $cmd .= quote($file);
+ }
+ $cmd .= ' '.quote($recipient);
+ print $cmd,"\n";
+ system $cmd;
+ } else {
+ print quote($0)." -C '$comment' ";
+ if ($archive) {
+ printf "-a %s %s %s\n",quote($archive),$qfiles,$recipient;
+ system $0,'-C',$comment,'-a',$archive,@files,$recipient;
+ } else {
+ printf "%s %s\n",quote($file),$recipient;
+ system $0,'-C',$comment,$file,$recipient;
+ }
+ }
+ print "\n";
+ print "[s] send another file to $recipient\n";
+ print "[n] send another file to another recipient\n";
+ print "[q] quit\n";
+ print "\n";
+ print "your choice: ";
+ for (;;) {
+ $key = ReadKey(0);
+ &ask_file if $key eq 'n';
+ if ($key eq 's' or $key eq "\n") {
+ print "s\n";
+ last;
+ }
+ if ($key eq 'q') {
+ print "$key\n";
+ exit;
+ }
+ }
+ $file = $comment = $archive = '';
+ @files = ();
+ }
+}
+
+
+sub set_ID {
+ my ($server,$port,$user,$logo);
+ local $_;
+
+ print "\n";
+ for (;;) {
+ print "F*EX server URL: ";
+ $server = <STDIN>;
+ $server =~ s/[\s\n]//g;
+ if ($server =~ s:/fup/(\w+)$::) {
+ $_ = decode_b64($1);
+ if (/(from|user)=(.+)&id=(.+)/) {
+ $user = $2;
+ $id = $3;
+ }
+ }
+ $server =~ s:/fup.*::;
+ $server =~ s:/+$::;
+ next if $server !~ /\w/;
+ if ($server =~ s/^https:..// or $server =~ /:443/) {
+ $server =~ s/:.*//;
+ $port = 443;
+ eval "use IO::Socket::SSL";
+ if ($@) {
+ print "\nno perl SSL modules installed - cannot use https\n\n";
+ next;
+ }
+ $SH = IO::Socket::SSL->new(
+ PeerAddr => $server,
+ PeerPort => $port,
+ Proto => 'tcp',
+ %SSL
+ );
+ } else {
+ $server =~ s:^http.//::;
+ if ($server =~ s/:(\d+)//) {
+ $port = $1;
+ } else {
+ $port = 80;
+ }
+ $SH = IO::Socket::INET->new(
+ PeerAddr => $server,
+ PeerPort => $port,
+ Proto => 'tcp',
+ );
+ }
+ unless ($SH) {
+ print "\ncannot connect to $server:$port - $!\n\n";
+ next;
+ }
+ sendheader(
+ "$server:$port",
+ "GET /logo.jpg HTTP/1.0",
+ "User-Agent: $useragent",
+ "Connection: close",
+ );
+ $_ = <$SH>||'';
+ unless (/HTTP.1.1 200/) {
+ print "\nbad server reply: $_\n";
+ next;
+ }
+ while (<$SH>) { last if /^\s*$/ }
+ local $/;
+ $logo = <$SH>||'';
+ close $SH;
+ if (length $logo < 9999) {
+ print "\n$server is not a F*EX server!\n\n";
+ next;
+ }
+ open $logo,">$tmpdir/fex.jpg";
+ print {$logo} $logo;
+ close $logo;
+ last;
+ }
+
+ for (;;) {
+ last if $user;
+ print "Your login (e-mail address): ";
+ $user = <STDIN>;
+ $user =~ s/[\s\n]//g;
+ if ($user !~ /.@[\w.-]+$/) {
+ print "\"$user\" is not a valid e-mail address!\n";
+ next;
+ }
+ }
+
+ for (;;) {
+ last if $id;
+ print "Your auth-ID for this account: ";
+ $id = <STDIN>;
+ $id =~ s/[\s\n]//g;
+ }
+
+ open $idf,'>',$idf or die "$0: cannot write to $idf - $!\n";
+ print {$idf} "$server\n",
+ "$user\n",
+ "$id\n";
+ close $idf;
+ print "\n";
+ print "Login data written to $idf\n\n";
+ print "fexing test file to $user:\n\n";
+ system "$0 -o -M -C test $tmpdir/fex.jpg $user";
+ print "\n";
+ if ($? != 0) {
+ print "fexsend failed, login data is invalid, try again\n";
+ &set_ID;
+ } else {
+ print "fexsend test succeeded!\n";
+ sleep 3;
+ }
+}
+
+
+# read one key from terminal in raw mode
+sub ReadKey {
+ my $key;
+ local $SIG{INT} = sub { stty('reset'); exit };
+
+ stty('raw');
+ # loop necessary for ESXi support
+ while (not defined $key) {
+ $key = getc(STDIN);
+ }
+ stty('reset');
+ return $key;
+}
+
+
+sub stty {
+ if (shift eq 'raw') {
+ system qw'stty -echo -icanon eol',"\001";
+ } else {
+ system qw'stty echo icanon eol',"\000";
+ }
+}
+
+
sub send_xx {
my $transferfile = shift;
my $file = '';
- my (@r,@tar);
+ my (@r,@tar,$dir);
$SIG{PIPE} = $SIG{INT} = sub {
unlink $transferfile;
print "making tar transfer file $transferfile :\n";
# single file? then add this directly
if (scalar @ARGV == 1) {
- my ($dir,$file);
# strip path if not ending with /
if ($ARGV[0] =~ m:(.+)/(.+): and $2 !~ m:/$:) {
($dir,$file) = ($1,$2);
# list spool
sub list {
my (@r,$r);
- my ($data,$dkey,$n);
+ my ($data,$dkey);
+ my $n = 0;
+ my $s = 1;
+ my $a = shift @ARGV || '.';
local $_;
female_mode("list spooled files?") if $opt_F;
- if ($opt_l and $n = shift @ARGV and $n =~ /^\d+$/) {
- open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
- while (<$fexlist>) {
- if (/^\s*(\d+)\) (\w+) (.+)/ and $1 eq $n) {
- serverconnect($server,$port) unless $SH;
- sendheader(
- "$server:$port",
- "GET $proxy_prefix/fop/$2/$2?LIST HTTP/1.1",
- "User-Agent: $useragent",
- );
- $_ = <$SH>||'';
- s/\r//;
- print "<-- $_" if $opt_v;
- if (/^HTTP.* 200/) {
+ if ($opt_l) {
+ if ($a =~ /^\d+$/) {
+ open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
+ while (<$fexlist>) {
+ if (/^\s*(\d+)\) (\w+) (.+)/ and $1 eq $a) {
+ serverconnect($server,$port) unless $SH;
+ sendheader(
+ "$server:$port",
+ "GET $proxy_prefix/fop/$2/$2?LIST HTTP/1.1",
+ "User-Agent: $useragent",
+ );
+ $_ = <$SH>||'';
+ s/\r//;
print "<-- $_" if $opt_v;
- while (<$SH>) {
- s/\r//;
- if (/^\n/) {
- print;
- print while <$SH>;
+ if (/^HTTP.* 200/) {
+ print "<-- $_" if $opt_v;
+ while (<$SH>) {
+ s/\r//;
+ if (/^\n/) {
+ print;
+ print while <$SH>;
+ }
}
+ } elsif (s:HTTP/[\d\. ]+::) {
+ die "$0: server response: $_";
+ } else {
+ die "$0: no response from fex server $server\n";
}
- } elsif (s:HTTP/[\d\. ]+::) {
- die "$0: server response: $_";
- } else {
- die "$0: no response from fex server $server\n";
+ exit;
}
- exit;
}
+ die "$0: file \#$a not found in fexlist\n";
}
- die "$0: file \#$n not found in fexlist\n";
- } else {
- @r = formdatapost(
- from => $from,
- to => $opt_l ? '*' : $from,
- command => $opt_C,
- );
}
+
+ @r = formdatapost(
+ from => $from,
+ to => $opt_l ? '*' : $from,
+ command => $opt_C,
+ );
die "$0: no response from fex server $server\n" unless @r;
$_ = shift @r;
unless (/^HTTP.* 200/) {
s/&/&/g;
s/"/\"/g;
s/</</g;
- if (/^(to .* :)/) {
- print "\n$1\n";
- print {$fexlist} "\n$1\n";
+ if (/^(to (.+) :)/) {
+ $s = $2 =~ /$a/;
+ print "\n$_\n" if $s;
+ print {$fexlist} "\n$_\n";
} elsif (m/(\d+) MB (.+)/) {
$n++;
- printf "%4s) %8d MB %s\n","#$n",$1,$2;
+ printf "%4s) %8d MB %s\n","#$n",$1,$2 if $s;
printf {$fexlist} "%3d) %s %s\n",$n,$dkey,$2;
}
}
}
-sub delete {
+sub delete_file_number {
my ($to,$file);
while (@ARGV) {
$opt_d = shift @ARGV;
- die "$usage: $0 -d #\n" if $opt_d !~ /^\d+$/;
+ die "usage: $0 -d #\n" if $opt_d !~ /^\d+$/;
open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
while (<$fexlist>) {
}
+sub delete_file {
+ my ($from,$to,$file) = @_;
+ local $_;
+
+ unless ($SH) {
+ serverconnect($server,$port);
+ query_sid($server,$port) unless $anonymous;
+ }
+
+ $file = urlencode($file);
+ sendheader(
+ "$server:$port",
+ "GET $proxy_prefix/fop/$to/$from/$file?id=$sid&DELETE HTTP/1.1",
+ "User-Agent: $useragent",
+ );
+
+ while (<$SH>) {
+ s/\r//;
+ printf "<-- $_"if $opt_v;
+ last if /^\s*$/;
+ }
+}
+
+
+sub urlencode {
+ local $_ = shift;
+ s/([^_=:,;<>()+.\w\-])/'%'.uc(unpack("H2",$1))/ge;
+ return $_;
+}
+
+
sub send_fex {
my @to;
my $file = '';
if ($anonymous) {
my $aok;
- sendheader("$server:$port","OPTIONS FEX HTTP/1.1");
+ sendheader("$server:$port","OPTIONS /FEX HTTP/1.1");
$_ = <$SH>||'';
s/\r//;
die "$0: no response from fex server $server\n" unless $_;
}
if (@ARGV > 1 and not ($opt_a or $opt_s or $opt_d)) {
- print "Archive name (name.tar, name.tgz or name.zip) or [ENTER] to send file for file:\n";
+ print "Archive name (name.tar, name.tgz or name.zip) or [RETURN] to send file for file:\n";
$opt_a = <STDIN>;
$opt_a =~ s/^\s+//;
$opt_a =~ s/\s+$//;
+ $opt_a =~ s/\//_/g;
+ }
+
+ if ($macos and not $opt_a and -d "@ARGV") {
+ my $dir = "@ARGV";
+ my $qdir = quote($dir);
+ if (`du -s $qdir` =~ /^(\d+)/ and $1 < 2**21) {
+ $opt_a = "$dir.zip";
+ } else {
+ $opt_a = "$dir.tar";
+ }
}
if ($opt_s) {
$opt_a =~ s:.*/::g;
}
foreach my $file (@ARGV) {
- die "$0: cannot read $file\n" unless -l $file or -r $file;
+ die "$0: cannot read \"$file\"\n" unless -l $file or -r $file;
}
$opt_a .= ".$atype" if $opt_a !~ /\.$atype$/;
$transferfile = "$tmpdir/$opt_a";
# else { system(qw'7z a -tzip -mm=copy',$transferfile,@ARGV) }
system(qw'7z a -tzip',$transferfile,@ARGV);
@files = ($transferfile);
+ } elsif ($macos and scalar(@ARGV) == 1) {
+ ## ditto-zip is now handled by formdatapost()
+ system 'true';
+ @files = ($opt_a);
} else {
# zip archives must be < 2 GB, so split as necessary
@files = zipsplit($transferfile,@ARGV);
} else {
## tar is now handled by formdatapost()
# system(qw'tar cvf',$transferfile,@ARGV);
+ system 'true';
@files = ($opt_a);
}
} elsif ($atype eq 'tgz') {
unless ($opt_d) {
unless (-f $file) {
if (-e $file) {
- die "$0: $file is not a regular file, try option -a\n"
+ die "$0: \"$file\" is not a regular file, try option -a\n"
} else {
- die "$0: $file does not exist\n";
+ die "$0: \"$file\" does not exist\n";
}
}
- die "$0: cannot read $file\n" unless -r $file;
+ die "$0: cannot read \"$file\"\n" unless -r $file;
}
push @files,$file;
}
foreach my $file (@files) {
my @s = stat($file);
unless (@s and ($s[2] & S_IROTH) and -r $file) {
- die "$0: $file is not world readable\n";
+ die "$0: \"$file\" is not world readable\n";
}
}
}
foreach my $file (@files) {
sleep 1; # do not overrun server!
unless (-s $file or $opt_d or $opt_a or $opt_s) {
- die "$0: cannot send empty file $file\n";
+ die "$0: cannot send empty file \"$file\"\n";
}
female_mode("send file $file?") if $opt_F;
@r = formdatapost(
if (not @r or not grep /\w/,@r) {
die "$0: no response from server\n";
}
+ next if "@r" eq '0'; # already transfered
if (($r) = grep /^ERROR:/,@r) {
if ($anonymous and $r =~ /purge it/) {
die "$0: file is already on server for $to - use another anonymous recipent\n";
+ } elsif ($r =~ /timeout/i) {
+ close $SH;
+ retry("timed out");
} else {
$r =~ s/.*?:\s*//;
$r =~ s/<.+?>//g;
die "$0: server error: $r\n";
}
}
+ unless ($opt_d) {
+ if (scalar(@r) == 1) {
+ die "$0: server error: @r\n";
+ } else {
+ if ($r[0] !~ /HTTP.1.. 2/) {
+ if ($r[0] =~ /HTTP.[\s\d.]+(.+)/) {
+ die "$0: server error: $1\n";
+ } else {
+ die "$0: server error:\n".join("\n",@r)."\n";
+ }
+ }
+ }
+ }
if (($r) = grep /<h3>\Q$file/,@r) {
$r =~ s/<.+?>//g;
print "$r\n";
if ($opt_a !~ /^afex_\d+\.tar$/ and $file !~ /afex_\d+\.tar$/) {
# print grep({s/^(X-Recipient:.*\((.+)\))/Parameters: $2\n/i} @r);
my $nonot = 0;
- my ($recipient,$location);
+ my $recipient = '';
+ my $location = '';
foreach (@r) {
if (/^(X-)?(Recipient.*)/i) {
$recipient = $2;
}
if (/^(X-)?(Location.*)/i) {
$location = $2;
- if ($from eq $to or $from =~ /^\Q$to\E@/i
- or $nomail or $anonymous or $nonot) {
- print "$recipient\n";
- print "$location\n";
- }
}
}
- unless ($opt_d or $location) {
- if (scalar(@r) == 1) {
- die "$0: server error: @r\n";
- } else {
- if ($r[0] !~ /HTTP.1.. 2/ and $r[0] =~ /HTTP.[\s\d.]+(.+)/) {
- die "$0: server error: $1\n";
- } else {
- die "$0: server error:\n".join("\n",@r)."\n";
- }
- }
+ if ($from eq $to or $from =~ /^\Q$to\E@/i
+ or $nomail or $anonymous or $nonot)
+ {
+ print "$recipient\n" if $recipient;
+ print "$location\n" if $location;
}
}
}
open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
while (<$fexlist>) {
- if (/^\s*(\d+)\) (\w+) \[\d+ d\] (.+)/ and $1 eq $opt_f) {
+ if (/^\s*(\d+)\) (\w+) .\s*\d+ d. ([+-] )?(.+)/ and $1 eq $opt_f) {
$n = $1;
$dkey = $2;
- $file = $3;
+ $file = $4;
if ($file =~ s/ "(.*)"$//) {
$opt_C ||= $1 if $1 ne 'NOMAIL';
}
open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
while (<$fexlist>) {
- if (/^\s*(\d+)\) (\w+) \[\d+ d\] (.+)/ and $1 eq $opt_N) {
+ if (/^\s*(\d+)\) (\w+) .\s*\d+ d. (.+)/ and $1 eq $opt_N) {
$n = $1;
$dkey = $2;
last;
open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
while (<$fexlist>) {
- if (/^\s*(\d+)\) (\w+) \[\d+ d\] (.+)/ and $1 eq $opt_x) {
+ if (/^\s*(\d+)\) (\w+) .\s*\d+ d. (.+)/ and $1 eq $opt_x) {
$n = $1;
$dkey = $2;
$file = $3;
sub formdatapost {
my %P = @_;
- my ($boundary,$filename,$filesize,$length,$buf,$file,$fpsize,$resume,$seek);
+ my ($boundary,$filename,$length,$buf,$file,$fpsize,$resume,$seek);
my ($flink);
my (@hh,@hb,@r,@pv,$to);
my ($bytes,$t,$bt);
my $bs = 2**16; # blocksize for reading and sending file
my $fileid = int(time);
my $chunk = 0;
+ my $filesize = 0;
my $connection = '';
my $pct = '';
- my ($tar,$aname,$atype,$tarlist,$tarerror,$location,$transferfile);
+ my $dittodir = '.';
+ my ($tar,$ditto,$aname,$atype,$list,$error,$location,$transferfile);
local $_;
if (defined($file = $P{file})) {
$of =~ s/([^_\w\.\-])/\\$1/g;
shelldo("gzip <$if>$of");
$filesize = -s $transferfile;
- die "$0: cannot gzip $file\n" unless $filesize;
+ die "$0: cannot gzip \"$file\"\n" unless $filesize;
$file = $transferfile;
}
if (not $windoof and $opt_a and $file =~ /(.+)\.(tar|tgz)$/) {
$aname = $1;
$atype = $2;
- $tarlist = "$tmpdir/$aname.list";
- $tarerror = "$tmpdir/$aname.error";
+ $list = "$tmpdir/$aname.list";
+ $error = "$tmpdir/$aname.error";
$tar = 'tar -cv';
$tar .= 'z' if $atype eq 'tgz';
if (`tar --help 2>/dev/null` =~ /--index-file/) {
- $tar .= " --index-file=$tarlist -f-";
+ $tar .= " --index-file=$list -f-";
} else {
$tar .= " -f-";
}
}
}
foreach (@ARGV) {
- $file = $_;
- $file =~ s/([^\w\-\@\#%,.=+~_:])/\\$1/g;
- $tar .= ' '.$file;
+ $tar .= ' '.quote($_);
}
# print "calculating archive size... ";
- open $tar,"$tar 2>$tarerror|" or die "$0: cannot run tar - $!\n";
+ open $tar,"$tar 2>$error|" or die "$0: cannot run tar - $!\n";
$t0 = int(time) if -t STDOUT;
while ($b = read $tar,$_,$bs) {
$filesize += $b;
printf "Archive size: %d MB\n",int($filesize/M) if -t STDOUT;
unless (close $tar) {
$_ = '';
- if (open $tarerror,$tarerror) {
+ if (open $error,$error) {
local $/;
- $_ = <$tarerror>;
- close $tarerror;
+ $_ = <$error>;
+ close $error;
}
- unlink $tarlist,$tarerror;
+ unlink $list,$error;
die "$0: tar error:\n$_";
}
$file = "$aname.$atype";
undef $SH; # force reconnect (timeout!)
}
+ # special file: ditto-zip-on-the-fly
+ # ditto: Can't archive multiple sources
+ elsif ($macos and $opt_a and $file =~ /(.+)\.(zip)$/ and scalar(@ARGV) == 1) {
+ $aname = $1;
+ $atype = $2;
+ $list = "$tmpdir/$aname.list";
+ $error = "$tmpdir/$aname.error";
+ $ditto = 'ditto -c -k --sequesterRsrc --keepParent';
+ if (-d "@ARGV" and "@ARGV" =~ m:^(.+)/(.+):) {
+ $dittodir = $1;
+ $file = $2;
+ $file =~ s/([^\w\-\@\#%,.=+_:])/\\$1/g;
+ $ditto .= ' '.$file;
+ } else {
+ foreach (@ARGV) {
+ $file = $_;
+ $file =~ s/([^\w\-\@\#%,.=+_:])/\\$1/g;
+ $ditto .= ' '.$file;
+ }
+ }
+ # print "calculating archive size... ";
+ debug("cd $dittodir;$ditto -");
+ open $ditto,"cd $dittodir;$ditto - 2>$error|"
+ or die "$0: cannot run ditto - $!\n";
+ $t0 = int(time) if -t STDOUT;
+ while ($b = read $ditto,$_,$bs) {
+ $filesize += $b;
+ if ($t0) {
+ $t1 = int(time);
+ if ($t1>$t0) {
+ printf "Archive size: %d MB\r",int($filesize/M);
+ $t0 = $t1;
+ }
+ }
+ }
+ printf "Archive size: %d MB\n",int($filesize/M) if -t STDOUT;
+ unless (close $ditto) {
+ $_ = '';
+ if (-s $error and open $error,$error) {
+ local $/;
+ $_ = <$error>;
+ close $error;
+ }
+ unlink $list,$error;
+ die "$0: ditto-zip error:\n$_";
+ }
+ unlink $list,$error;
+ $file = "$aname.$atype";
+ $filename = encode_utf8($file);
+ undef $SH; # force reconnect (timeout!)
+ }
+
# single file
else {
$filename = encode_utf8(${'opt_='} || $file);
if ($opt_d) {
$filesize = 0;
} elsif (not $opt_g and not $opt_s) {
- $filesize = -s $file or die "$0: $file is empty or not readable\n";
+ $filesize = -s $file or die "$0: \"$file\" is empty or not readable\n";
}
}
$P{id} = $sid; # ugly hack!
+ $filename =~ s/\\/_/g; # \ is a illegal character for fexsrv
+
# ask server if this file has been already sent
- if ($file and not $xx and not
- ($opt_s or $opt_g or $opt_o or $opt_d or $opt_l or $opt_L or ${'opt_/'}))
- {
- ($seek,$location) = query_file($server,$port,$frecipient||$P{to},$P{from},
- $P{id},$filename,$fileid);
- if ($filesize == $seek) {
- print "Location: $location\n" if $location and $nomail;
- warn "$0: $file has been already transferred\n";
- return $file;
- } elsif ($seek and $seek < $filesize) {
- $resume = " (resuming at byte $seek)";
- } elsif ($filesize <= $seek) {
- $seek = 0;
+ if ($file and not $xx) {
+ if (not $opt_d and $opt_o) {
+ # delete before overwrite
+ delete_file($from,$to,$filename);
+ serverconnect($server,$port);
+ query_sid($server,$port) unless $anonymous;
+ $P{id} = $sid; # ugly hack!
+ } elsif (not($opt_s or $opt_g or $opt_d or $opt_l or $opt_L or ${'opt_/'})) {
+ ($seek,$location) = query_file($server,$port,
+ $frecipient||$P{to},$P{from},$P{id},$filename,$fileid);
+ if ($filesize == $seek) {
+ print "Location: $location\n" if $location and $nomail;
+ warn "$0: $file has been already transferred\n";
+ return 0;
+ } elsif ($seek and $seek < $filesize) {
+ $resume = " (resuming at byte $seek)";
+ } elsif ($filesize <= $seek) {
+ $seek = 0;
+ }
}
if ($proxy) {
sleep 1; # do not overrun proxy
push @hb,"--$boundary";
push @hb,"Content-Disposition: form-data; name=\"$name\"";
push @hb,"";
- push @hb,encode_utf8($P{$v});
+ # push @hb,encode_utf8($P{$v});
+ push @hb,$P{$v};
}
}
$tpid = fork();
if (defined $tpid and $tpid == 0) {
sleep 1;
- if (open $tarlist,$tarlist) {
- # print "\n$tar|\n"; system "ls -l $tarlist";
- while ($tarlist) {
- while (<$tarlist>) {
+ if (open $list,$list) {
+ # print "\n$tar|\n"; system "ls -l $list";
+ while ($list) {
+ while (<$list>) {
print ' 'x(length($file)+40),"\r",$_;
}
sleep 1;
print "Fast forward to byte $seek (resuming)\n";
readahead($file,$seek);
}
+ } elsif ($ditto) {
+ $ditto =~ s/ditto/ditto -V/;
+ open $file,"cd $dittodir;$ditto -|" or die "$0: cannot run ditto - $!\n";
+ if ($seek) {
+ print "Fast forward to byte $seek (resuming)\n";
+ readahead($file,$seek);
+ }
} else {
if ($opt_g) {
- my $fileq = $file;
- $fileq =~ s/([^\w\-\@\#%,.=+~_:])/\\$1/g;
+ my $fileq = quote($file);
open $file,"gpg -e -r $to <$fileq|" or die "$0: cannot run gpg - $!\n";
} else {
- open $file,$file or die "$0: cannot read $file - $!\n";
+ open $file,$file or die "$0: cannot read \"$file\" - $!\n";
seek $file,$seek,0;
}
binmode $file;
alarm(0);
$bytes += $b;
if ($filesize > 0 and $bytes+$seek > $filesize) {
- die "$0: $file filesize has grown while uploading\n";
+ if ($tpid) {
+ kill 9,$tpid;
+ unlink $list;
+ }
+ die "$0: \"$file\" filesize has grown while uploading\n";
}
$bt += $b;
$t2 = time;
if ($tpid) {
sleep 2;
kill 9,$tpid;
- unlink $tarlist;
+ unlink $list;
}
-
+
+ if ($fileid =~ /[a-z]/ and not ($opt_s or $opt_g)) {
+ if ($opt_a) {
+ if ($fileid ne md5_hex(fmd(@ARGV))) {
+ print "\n" unless $opt_q;
+ die "$0: files have been modified while uploading\n";
+ }
+ } else {
+ if ($fileid ne fileid($file)) {
+ print "\n" unless $opt_q;
+ die "$0: file has been modified while uploading\n";
+ }
+ }
+ }
+
unless ($opt_q) {
if (not $chunksize and $bytes+$seek < $filesize) {
- die "$0: $file filesize has shrunk while uploading\n";
+ die "$0: \"$file\" filesize has shrunk while uploading\n";
}
if ($seek or $chunksize and $chunksize < $filesize) {
$size = -s $file;
if ($size > 2147480000) {
unlink @zipfiles;
- die "$0: $file too big for zip\n";
+ die "$0: \"$file\" too big for zip\n";
}
if ($zsize + $size > 2147000000) {
push @zipfiles,zip($zipbase.'_'.$n.'.zip',@files);
my $seek = 0;
my $qfileid = '';
my ($head,$location);
- my ($response,$fexsrv);
+ my ($response,$fexsrv,$cc);
local $_;
$to =~ s/,.*//;
if (/^X-File-ID:\s+(.+)/) { $qfileid = $1 }
if (/^X-Features:\s+(.+)/) { $features = $1 }
if (/^X-Location:\s+(.+)/) { $location = $1 }
+ if (/^Connection: close/) { $cc = $_ }
}
# return true seek only if file is identified
$seek = 0 if $qfileid and $qfileid ne $fileid;
+ if ($cc) {
+ serverconnect($server,$port);
+ $sid = $id;
+ }
+
return ($seek,$location);
}
print {$ab} $AB{ADDRESS_BOOK};
close $ab;
- system $editor,$ab;
+ system "$editor $ab";
exit unless -s $ab;
$opt_o = $opt_A;
$sid = $id;
- if ($port eq 443) {
+ if ($port eq 443 or $proxy) {
return if $features; # early return if we know enough
- $req = "OPTIONS FEX HTTP/1.1";
- } elsif ($proxy) {
- return if $features; # early return if we know enough
- $req = "GET $proxy_prefix/SID HTTP/1.1";
+ $req = "OPTIONS /FEX HTTP/1.1";
+ $req = "HEAD / HTTP/1.1";
} else {
- $req = "GET SID HTTP/1.1";
+ $req = "GET /SID HTTP/1.1";
}
sendheader("$server:$port",$req,"User-Agent: $useragent");
s/\r//;
print "<-- $_" if $opt_v;
- if (/^HTTP.* [25]0[01] /) {
+ if ($req =~ /OPTIONS/ and /^HTTP.* 502 /) {
+ # (reverse) proxy error
+ close $SH;
+ serverconnect($server,$port);
+ $req = "GET /SID HTTP/1.0";
+ sendheader("$server:$port",$req,"User-Agent: $useragent");
+ $_ = <$SH>;
+ unless (defined $_ and /\w/) {
+ print "\n" if $opt_v;
+ die "$0: no response from server\n";
+ }
+ s/\r//;
+ print "<-- $_" if $opt_v;
+ while (<$SH>) {
+ s/\r//;
+ print "<-- $_" if $opt_v;
+ $features = $1 if /^X-Features: (.+)/;
+ $timeout = $1 if /^X-Timeout: (\d+)/;
+ last if /^\n/;
+ }
+ close $SH;
+ serverconnect($server,$port);
+ } elsif (/^HTTP.* [25]0[01] /) {
if (not $proxy and $port ne 443 and /^HTTP.* 201 (.+)/) {
$sid = 'MD5H:'.md5_hex($id.$1);
}
+ my $cc;
while (<$SH>) {
s/\r//;
print "<-- $_" if $opt_v;
$features = $1 if /^X-Features: (.+)/;
$timeout = $1 if /^X-Timeout: (\d+)/;
- last if /^\n/;
+ $cc = $_ if /^Connection: close/;
+ last if /^\n/;
+ }
+ if ($cc) {
+ serverconnect($server,$port);
+ $sid = $id;
}
} elsif (/^HTTP.* 301 /) {
while (<$SH>) { last if /Location/ }
die "$0: no Content-Length in server-reply\n" unless $cl;
- open F,">$save" or die "$0: cannot write to $save - $!\n";
- binmode F;
+ open $save,">$save" or die "$0: cannot write to $save - $!\n";
+ binmode $save;
$t0 = $t1 = int(time);
$tso = '';
while ($b = read($SH,$_,$bs)) {
$B += $b;
- print F;
+ print {$save} $_;
if (int(time) > $t1) {
$t1 = int(time);
$ts = ts($B,$cl);
}
print STDERR ts($B,$cl),"\n";
- close F;
+ close $save;
}
}
-# fileid is inode and mtime
sub fileid {
- my @s = stat(shift);
- return @s ? $s[1].$s[9] : int(time);
+ my $file = shift;
+ my @s = stat($file);
+
+ if (@s) {
+ return md5_hex($file.$s[0].$s[1].$s[7].$s[9]);
+ } else {
+ warn "$0: $file - $!\n";
+ return int(time);
+ }
}
s/.*\s+//;
s/[<>]//g;
if (/,/) {
- warn "$0: ignoring mutt multi-alias $to = $alias\n";
+ warn "$0: ignoring mutt multi-alias $to = $_\n";
last;
}
if (/@/) {
}
-# collect file meta data (filename, inode, mtime)
+# collect (hashed) file meta data
sub fmd {
my @files = @_;
my ($file,$dir);
while (defined ($file = readdir($dir))) {
next if $file eq '..';
if ($file eq '.') {
- $fmd .= $file.fileid($dir);
+ $fmd .= fileid($dir);
} else {
$fmd .= fmd("$dir/$file");
}
closedir $dir;
}
} else {
- $fmd .= $file.fileid($file);
+ $fmd .= fileid($file);
}
}
unless (defined $_ and /\w/) {
die "$0: no response from server\n";
}
- print "<-- $_\n" if $opt_v;
s/\r?\n//;
+ print "<-- $_\n" if $opt_v;
# CGI fatalsToBrowser
if (/^HTTP.* 500/) {
@r = <$SH> unless @r;
die "$0: server error: $error\n";
}
- print "<-- $_\n" if $opt_v;
return $_;
}
local $/;
open $0,$0 or die "cannot read $0 - $!\n";
- $_ = <$0>;
+ $cfc = <$0>;
close $0;
- s/.*\n$cfb\n//s;
- $cfc = $_;
+ $cfc =~ s/.*\n$cfb\n//s;
- foreach my $p (qw(fexget sexsend)) {
+ foreach my $p (qw'fexget sexsend') {
open $p,$p or die "cannot read $p - $!\n";
$_ = <$p>;
close $p;
close $p;
}
- exec "l $0 fexget sexsend";
+ exec "l fexsend fexget sexsend";
exit;
}
if ($SH) {
autoflush $SH 1;
+ binmode $SH;
} else {
die "$0: cannot connect $server:$port - $@\n";
}
}
+sub quote {
+ local $_ = shift;
+ s/([^\w\@\/%^,.=+_:+-])/\\$1/g;
+ return $_;
+}
+
+
+sub debug {
+ print "## DEBUG: @_\n" if $DEBUG;
+}
+
+
# from MIME::Base64::Perl
sub encode_b64 {
my $res = "";
# import from fex.pp
our ($hostname,$debug,$timeout,$max_error,$max_error_handler);
-our ($spooldir,@logdir,$docdir,$xkeydir,$lockdir);
+our ($spooldir,@logdir,$docdir,$xkeydir,$akeydir,$lockdir);
our ($force_https,$default_locale,$bs,$MB,$adlm);
our (@locales);
http_error(413);
}
- if (/^(GET \/|X-Forwarded-For|User-Agent)/i) {
+ if (/^(GET \/|\S*Forwarded|\S*Client-IP|\S*Coming-From|User-Agent)/i) {
$hid .= $_."\n";
}
# reverse-proxy?
+ # (only IPv4 support!)
if ($reverse_proxy_ip and $reverse_proxy_ip eq $ra and
- /^X-Forwarded-For: ([\d.]+)/
+ /^\S*(Forwarded|Client-IP|Coming-From)\S*: ([\d.]+)/i
) {
- $ENV{REMOTE_ADDR} = $ra = $1;
+ $ENV{REMOTE_ADDR} = $ra = $2;
$ENV{REMOTE_HOST} = $rh = gethostbyaddr(inet_aton($ra),AF_INET) || '';
$ENV{HTTP_HOST} = $hostname;
if ($ENV{PROTO} eq 'https') { $port = 443 }
}
}
- if ($request =~ /^OPTIONS FEX HTTP\/[\d\.]+$/i) {
+ if ($request =~ /^OPTIONS \/?FEX HTTP\/[\d\.]+$/i) {
fexlog($connect,@log);
nvt_print(
"HTTP/1.1 201 OK",
$ENV{LOCALE} = $locale = $default_locale;
}
+ # for dynamic HTML documents
+ if ($ENV{HTTP_COOKIE} =~ /akey=(\w+)/) {
+ my $akey = $1;
+ my ($user,$id);
+ if ($user = readlink "$akeydir/$akey") {
+ $user =~ s:.*/::;
+ $user = untaint($user);
+ if ($id = slurp("$spooldir/$user/@")) {
+ chomp $id;
+ $ENV{AKEY} = $akey;
+ $ENV{USER} = $user;
+ $ENV{ID} = $id;
+ }
+ }
+ }
+
# check for name based virtual host
$vhost = vhost($ENV{'HTTP_HOST'});
--- /dev/null
+#!/usr/bin/perl -w
+#
+# Programname: fpg - Frams' Perl grep
+# Author: framstag@rus.uni-stuttgart.de
+# Copyright: GPL
+#
+# History:
+# 2003-02-27 Framstag initial version
+# 2003-02-28 Framstag added exit status
+# 2007-03-09 Framstag added option -Q
+# 2007-06-01 Framstag added options -s and -c
+# and changed default output mode
+# 2007-06-03 Framstag added ReadLine-support
+# 2007-08-31 Framstag added option -x
+# 2008-02-06 Framstag added implicit gunzip
+# -F ==> -R, new -F option
+# 2008-10-07 Framstag added option -p
+# -n ==> -S, new -n option
+# 2008-10-14 Framstag added option -M
+# 2008-11-23 Framstag added option -~
+
+use Getopt::Std;
+use Term::ReadLine;
+use locale;
+
+sub usage {
+ die <<EOD
+usage: $0 [options] 'EXP' [file...]
+ or: $0 [options] -Q file...
+options: -r recursively scan through directories
+ -i ignore case
+ -v print only lines that do NOT match
+ -s verbose scanning/searching
+ -n prefix with line number
+ -l list filenames only
+ -L list filenames only that do NOT match
+ -p show paragraphs, not lines (multiline record separator)
+ -o show only matched strings, not whole lines
+ -M mail-mode: search and show complete mails from mbox files
+ -c print (count) only number of matches (NOT LINES!)
+ -F EXP is a string, not a Perl regular expression
+ -e EXP is any perl code which returns TRUE/FALSE
+ -S \# minimum string length \# for binary files, default: 4
+ -C \# \# lines of context
+ -R 'RS' record separator, default: newline (\\n) if not set -p
+ -x 'exp' extra regexp for highlighting (not used for searching)
+ -X 'exp' exclude files (filename matching this regexp) when searching
+ -~ search in backup files *~ #*#, too
+ -Q query-loop-prompt for search expression (with readline)
+arguments: EXP is a Perl regular expression
+ file... can be one or more files, even binary or compressed ones
+EOD
+#examples: $0 -r 'from.*STDIN' *
+# $0 -e 'length>30 and not /\\w/' script
+#See "perldoc perlre" for help on regular expressions.
+}
+
+$0 =~ s:.*/::;
+$| = 1;
+
+$maxlen = 0;
+
+$opt_i = $opt_r = $opt_v = $opt_l = $opt_h = $opt_e = $opt_n = $opt_o = 0;
+$opt_s = $opt_c = $opt_Q = $opt_F = $opt_p = $opt_M = $opt_C = $opt_S = 0;
+${'opt_~'} = 0;
+$opt_S = 4;
+$opt_x = $opt_X = '';
+$opt_R = "\n";
+
+usage() if !getopts('hirvlLFMopscQen~S:R:C:x:X:') or $opt_h and not @ARGV;
+
+unless ($opt_Q) {
+ $exp = shift or usage();
+}
+
+if ($opt_C and ($opt_l or $opt_L or $opt_s or $opt_v or $opt_p or $opt_M)) {
+ die "$0: cannot mix option -C with any of -l -L -s -v -p -M\n";
+}
+
+if ($opt_M and ($opt_l or $opt_L or $opt_s or $opt_v or $opt_p or $opt_C)) {
+ die "$0: cannot mix option -M with any of -l -L -s -v -p -C\n";
+}
+
+if ($opt_o and ($opt_v or $opt_l or $opt_L or $opt_c or $opt_F or $opt_C)) {
+ die "$0: cannot mix option -E with any of -l -L -v -c -C -F\n";
+}
+
+$opt_XX = 0;
+if (not ${'opt_~'}) {
+ @bfiles = grep(/~$|^#.*#$/,@ARGV);
+ if (@bfiles and
+ (grep(/[^~]$/,@ARGV) or grep(/(^|\/)#[^\/]*#$/,@ARGV))) {
+ $opt_XX = 1;
+ warn "$0: ignoring @bfiles\n"; # unless $opt_r;
+ }
+}
+
+if (-t STDOUT) {
+ $B = "\033[1m";
+ $N = "\033[m";
+} else {
+ $B = $N = '';
+}
+
+if ($opt_p) { $/ = '' }
+else { $/ = $opt_R }
+#else { eval '$/ = "'.$opt_R.'"' }
+
+$opt_h = 1 if not $opt_r and @ARGV < 2;
+
+if ($opt_Q) {
+ $q = new Term::ReadLine $0;
+ $q->ornaments(0) unless $ENV{PERL_RL};
+ for (;;) {
+ $exp = $q->readline("$B\nsearch-expression:$N ");
+ last unless $exp;
+ &scan;
+ }
+} else {
+ &scan;
+}
+
+exit ($found?0:1);
+
+sub scan {
+ $egrep = '';
+ if ($opt_e) {
+ eval "\$egrep = sub { $exp }";
+ } else {
+ $exp =~ s/([\@\$\%\^\&\*\(\)\+\[\]\{\}\\\|\.\?])/\\$1/g if $opt_F;
+ $exp = '(?i)'.$exp if $opt_i;
+ $exp = '(?s)'.$exp if $opt_p or $opt_R;
+ #? $exp =~ s/\.\*\*/[.\n]*/g;
+ }
+
+ $found = 0;
+
+ if (@ARGV) {
+ foreach $file (@ARGV) {
+ next if $opt_X and $file =~ /$opt_X/;
+ next if $opt_XX and ($file =~ /~$/ or $file =~ m{(^|/)#[^/]*#$});
+ my $error = ''; open $file,$file or $error = $!; close $file;
+ if ($error) {
+ warn "$0: cannot read file $file - $error\n";
+ next;
+ }
+ unless (-f $file or -d $file or -c $file or -S $file or -p $file) {
+ warn "$0: ignoring special file $file\n";
+ next;
+ }
+ $maxlen = length $file if $maxlen < length $file;
+ # printf "%s\r",substr("scanning $file".(" " x 255),0,$maxlen+9) if -t STDOUT;
+ # print $B."scanning $file\n".$N if -t STDOUT and not $opt_l||$opt_L;
+ if ($opt_r and -d $file) {
+ $found += grepd($file);
+ next;
+ }
+ # next if -z $file; # Achtung: special files unter /proc sind "empty" !
+ # $type = `file -L $file`;
+ # if ($type =~ /text/i and open F,$file or open F,"strings $file|") {
+ $fileq = quotemeta $file;
+ if (-T $file) {
+ open $file,$file;
+ # warn "$file\n";
+ } else {
+ if ($file =~ /\.bz2$/) {
+ open $file,"bunzip2 <$fileq|";
+ # warn "gunzip <$file|\n";
+ } elsif ($file =~ /\.gz$/) {
+ open $file,"gunzip <$fileq|";
+ # warn "gunzip <$file|\n";
+ } else {
+ open $file,"strings -a -n $opt_S $fileq|";
+ # warn "strings -n $opt_S $file|\n";
+ }
+ }
+ if (fileno $file) {
+ $found += grepf($file,$file);
+ close $file;
+ } else {
+ warn "$0: cannot open $file - $!\n";
+ next;
+ }
+ }
+ # print " " x ($maxlen+9),"\r" if -t STDOUT;
+ } else {
+ $found = grepf(STDIN);
+ }
+}
+
+sub grepd {
+ my $dir = shift;
+ my $file;
+ my $found = 0;
+
+ opendir $dir,$dir or return;
+ while (defined($file = readdir $dir)) {
+ next if $file eq '.' or $file eq '..';
+ if (not ${'opt_~'} and $file =~ /~$|^#[^\/]*#$/) {
+ # warn "$0: ignoring $dir/$file\n";
+ next;
+ }
+ $file = "$dir/$file";
+ next unless -r $file;
+ if (-d $file and not -l $file) {
+ $found += grepd($file);
+ next;
+ }
+ next unless -f $file or -c $file or -S $file or -p $file or -z $file;
+ $fileq = quotemeta $file;
+ if (-T $file and open $file,$file or
+ open $file,"strings -a -n $opt_S $fileq|") {
+ $found += grepf($file,$file);
+ close $file;
+ }
+ }
+ closedir $dir;
+ return $found;
+}
+
+
+sub grepf {
+ my $F = shift;
+ my $file = shift;
+ my $found = 0;
+ my ($n,$l,$c);
+
+ warn $B."scanning $file".$N."\n" if -t STDOUT and $opt_s;
+
+ while (<$F>) {
+ $_ .= "\n" unless /\n$/;
+ if ($opt_M) {
+ if ($mail and (/^From / or eof $F)) {
+ my $__ = $_;
+ $_ = $mail;
+ $mail = $__;
+ } else {
+ $mail .= $_;
+ next;
+ }
+ }
+ $l++;
+ $n = 0;
+ if ($opt_C) {
+ for (my $i=$opt_C;$i;$i--) {
+ $C{$i} = $C{$i-1} if defined $C{$i-1};
+ }
+ $C{0} = [$l,$_];
+ }
+ if ($opt_e) {
+ if ($opt_v) {
+ next if &$egrep;
+ } else {
+ unless (&$egrep) {
+ if ($opt_C and $c) {
+ print "$l:" if $opt_n;
+ print;
+ $L{$l} = $l;
+ $c--;
+ }
+ next;
+ }
+ }
+ $n++;
+ } else {
+ if ($opt_v) {
+ # print ">>>$_" if $opt_i and /$exp/oi or /$exp/o;
+ if ($opt_Q) {
+ next if /$exp/m;
+ } else {
+ next if /$exp/om;
+ }
+ $n++;
+ } else {
+ if ($opt_c) {
+ if ($opt_Q) { $n++ while /$exp/mg }
+ else { $n++ while /$exp/omg }
+ } else {
+ if ($opt_o) {
+ my $m = '';
+ while (s/($exp)//) {
+ $n++;
+ $m .= "$1\n";
+ }
+ $_ = $m;
+ } elsif ($opt_Q) {
+ $n += s/($exp)/$B$1$N/mg;
+ } else {
+ $n += s/($exp)/$B$1$N/omg;
+ }
+ }
+ }
+ }
+ unless ($n) {
+ if ($opt_C and $c) {
+ print "$l:" if $opt_n;
+ print;
+ $L{$l} = $l;
+ $c--;
+ }
+ next;
+ }
+ $found += $n;
+ # print " " x ($maxlen+9),"\r" if -t STDOUT and $found==1;
+ next if $opt_c;
+ last if $opt_l or $opt_L;
+ if ($file and not $opt_s) {
+ print "\n$B$file$N:\n";
+ $file = '';
+ }
+ if ($opt_x and $n) {
+ if ($opt_i) { s/($opt_x)/$B$1$N/ogi }
+ else { s/($opt_x)/$B$1$N/og }
+ }
+ for (my $i=$opt_C;$i;$i--) {
+ if (defined $C{$i}) {
+ my ($ln,$ls) = @{$C{$i}};
+ unless (defined $L{$ln}) {
+ $L{$ln} = $ln;
+ print "$ln:" if $opt_n;
+ print $ls;
+ }
+ }
+ }
+ print "$l:" if $opt_n;
+ print;
+ $L{$l} = $l;
+ $c = $opt_C;
+ }
+
+ if ($opt_c) {
+ print "$file:" if @ARGV>1;
+ print "$found\n";
+ } else {
+ print "$file\n" if $opt_l and $found or $opt_L and not $found;
+ }
+ return $found;
+}
#!/usr/bin/perl -w
#
-# l / ll / lf / llf - substitute of the classic ls command
+# l / ll / lf / llf - better replacement of the classic ls command
#
# Author: Ulli Horlacher <framstag@rus.uni-stuttgart.de>
#
-# Copyright: GNU General Public License
+# Copyright: Perl Artistic License
use Cwd qw'abs_path';
use File::Basename;
# parse CLI arguments
$opt_l = $opt_i = $opt_t = $opt_s = $opt_a = $opt_r = $opt_d = $opt_n = 0;
$opt_L = $opt_N = $opt_c = $opt_u = $opt_S = $opt_R = $opt_z = $opt_h = 0;
-$opt_U = $opt_x = 0;
-${'opt_*'} = ${'opt_?'} = 0;
+$opt_U = $opt_x = $opt_E = 0;
+${'opt_*'} = 0;
$opt_m = $opt_f = $opt_F = $opt_D = '';
-&usage if !getopts('hdnlLNitcuarsxUSRz*?m:f:D:F:') || $opt_h;
+getopts('hdnlLNitcuarsxUSREz*m:f:D:F:') or usage(1);
+usage(0) if $opt_h;
$opt_z = 1 unless $opt_R;
$opt_l = 1 if $0 eq 'll';
$opt_l = $opt_i = $opt_a = $opt_S = 1 if $0 eq 'lll';
+&examples if $opt_E;
if ($0 eq 'lf' or $0 eq 'llf') {
- unless ($opt_F) {
- $opt_F = shift;
- unless (length $opt_F) {
- print "find regexp: ";
- chomp($opt_F = <STDIN>||'');
- }
- }
- $opt_l = $0 if $0 eq 'llf';
- $opt_F = '.' unless length $opt_F;
- $opt_R = $opt_F;
+ $opt_F ||= shift or usage(1);
+ $opt_R ||= scalar(@ARGV) || ($opt_F eq '.');
+ $opt_l ||= $0 eq 'llf';
}
$postsort = $opt_t||$opt_s;
$postproc = $postsort||$opt_z;
-&examples if ${'opt_?'};
-
# mark for squeeze operation
$z = $opt_z ? "\0" : '';
sub usage {
+ my $status = shift;
my $opts = '[-lastcuidnrzLRxNS*] [-f format] [-D X:Y]';
+ local *OUT = $status ? *STDERR : *STDOUT;
+
if ($0 ne 'lf') {
- print "usage: $0 $opts [-F regexp] [file...]\n";
+ print OUT "usage: $0 $opts [-F regexp] [file...]\n";
}
$opts =~ s/R//;
- print "usage: lf $opts regexp [directory...]\n";
- print <<EOD;
-options: -l long list
+ print OUT "usage: lf $opts regexp [directory...]\n";
+ print OUT <<EOD;
+options: -l long list (implicit if called 'll')
-a list also .* files
-s sort by size
-t sort by time
-F find files matching case insensitive regexp
-N show only normal (regular) files
-S print statistics summary at end
- -* list plain file names (without masking \\)
+ -* list plain file names (without \\ masking)
-f user defined format output, format characters are:
m=mode, u=user, g=group, s=size, l=hard links count, i=inode
n=name only, d=date, a=access+modification+inodechange dates
-D list only files newer than X and older than Y
XY format: NUMBER[smhd] (s=seconds, m=minutes, h=hours, d=days)
XY format: YYYY-MM-DD (Y=year, M=month, D=day)
- -? show examples
+ -E show examples
EOD
- exit 2;
+ exit $status;
}
sub examples {
l -D 10d: # list files newer than 10 days
ll # list files long format (equal to: l -l)
lll # list files extra long format (equal to: l -liS)
-lf 'status.*mp3' # list files recursive matching regexp (equal to: l -RF)
-lf sda3 /dev # list devices matching sda3 (equal to: l -RF sd3 /dev)
+lf 'status.*mp3' # list files matching regexp (equal to: l -F 'status.*mp3')
+lf sda1 /dev # list devices matching sda1 (equal to: l -RF sda1 /dev)
EOD
exit;
}
GET./browserconfig\.xml
User-Agent:.*(Webnote|FeedFetcher|\w+bot|bot/|Website.Watcher|crawler|spider|searchme|Yandex|Slurp|ScoutJet|findlinks|urlmon|nagios)
User-Agent:.fnb.*quak
+ User-Agent:.Google.favicon
From:.*(msnbot|yandex|googlebot|webcrawler)
Referer:.*sex.*stream
Referer:.*stream.*sex
DNT:
Via:
profile:
+ Upgrade-Insecure-Requests:
if-modified-since
Surrogate-Capability
Proxy-Authorization
http\.
+ Device-Stock
NOKIA_
GPRS
X-Proxy-ID
X-Moz
X.Wap
X-FH
+ X-FB
+ X-WS
X-Nokia
X-UCBrowser
X-NSN
X-Country
X-ClickOnceSupport
X-Newrelic
+ X-IMForwards
+ X-Clearswift
+ X-MDS
.*:\s*$
);
sleep 1;
@log = `ls -rt $logdir[0]/.debug/*_${pid}.$cgi 2>/dev/null`;
if ($log = $log[-1] and open $log,$log) {
- # binmode($log,":encoding(UTF-8)");
+ binmode($log,":encoding(UTF-8)");
while (<$log>) {
s/\r//;
if (/^Content-Disposition:.*name="FILE".*filename="(.+)"/i) {
eval 'use Net::INET6Glue::INET_is_INET6';
-our $version = 20150826;
+our $version = 20160104;
+our $DEBUG = $ENV{DEBUG};
my %SSL = (SSL_version => 'TLSv1');
my $sigpipe;
}
} elsif ($0 eq 'sexget' or $0 eq 'fuckme') {
+
+ $opt_g = 0;
getopts('hgvVdu:') or die $usage;
die $usage if $opt_h;
} else { # sexsend
- $opt_g = 1;
+ $opt_g = 0;
getopts('hguvqVTt:') or die $usage;
die $usage if $opt_h;
my $connect = "CONNECT $server:$port HTTP/1.1";
local $_;
- if ($opt_v and $port == 443 and %SSL) {
- foreach my $v (keys %SSL) {
- printf "%s => %s\n",$v,$SSL{$v};
- }
- }
-
if ($proxy) {
tcpconnect(split(':',$proxy));
- if ($port == 443) {
+ if ($https) {
printf "--> %s\n",$connect if $opt_v;
nvtsend($connect,"");
$_ = <$SH>;
unless (/^HTTP.1.. 200/) {
die "$0: proxy error : $_";
}
- eval "use IO::Socket::SSL";
- die "$0: cannot load IO::Socket::SSL\n" if $@;
+ &enable_ssl;
$SH = IO::Socket::SSL->start_SSL($SH,%SSL);
}
} else {
tcpconnect($server,$port);
}
-# if ($port == 443 and $opt_v) {
+# if ($https and $opt_v) {
# printf "%s\n",$SH->get_cipher();
# }
}
undef $SH;
}
- if ($port == 443) {
+ if ($https) {
# eval "use IO::Socket::SSL qw(debug3)";
- eval "use IO::Socket::SSL";
- die "$0: cannot load IO::Socket::SSL\n" if $@;
+ &enable_ssl;
$SH = IO::Socket::SSL->new(
PeerAddr => $server,
PeerPort => $port,
if ($SH) {
autoflush $SH 1;
+ binmode $SH;
} else {
die "$0: cannot connect $server:$port - $@\n";
}
}
+sub enable_ssl {
+ eval "use IO::Socket::SSL";
+ die "$0: cannot load IO::Socket::SSL\n" if $@;
+ eval '$SSL{SSL_verify_mode} = 0 if Net::SSLeay::SSLeay() <= 9470143';
+ if ($opt_v) {
+ foreach my $v (keys %SSL) {
+ printf "%s => %s\n",$v,$SSL{$v};
+ }
+ }
+}
+
+
sub sendheader {
my $sp = shift;
my @head = @_;
}
+sub quote {
+ local $_ = shift;
+ s/([^\w\@\/%^,.=+_:+-])/\\$1/g;
+ return $_;
+}
+
+
+sub debug {
+ print "## DEBUG: @_\n" if $DEBUG;
+}
+
+
# from MIME::Base64::Perl
sub encode_b64 {
my $res = "";
BEGIN { ($ENV{PERLINIT}||'') =~ /(.+)/s and eval $1 }
+use utf8;
use Fcntl qw(:flock);
use Digest::MD5 qw(md5_hex);
# authorized login URL
my $url = "$ENV{PROTO}://$ENV{HTTP_HOST}/fup/".b64("from=$user&id=$id");
pq(qq(
- '<h2>for user <a href="$url">$user</a></h2>'
+ '<script>'
+ ' function show_user() { return(alert('
+ ' "server:\\t$ENV{HTTP_HOST}\\n"+'
+ ' "user:\\t$user\\n"+'
+ ' "auth-ID:\\t$id\\n"+'
+ ' "URL:\\t\\t$url"'
+ ' ));}'
+ '</script>'
+ '<h2>for user <a href="#" onclick="show_user();" title="click to see account data">$user</a></h2>'
'<table>'
));
($quota,$du) = check_sender_quota($user);
' <input type="hidden" name="user" value="$user">'
' <input type="hidden" name="id" value="$id">'
' <script>function show_id() {return(alert("auth-ID: $id"));}</script>'
- ' Change your <a href="" onclick="show_id();" title="$id">auth-ID</a> to'
+ ' Change your <a href="#" onclick="show_id();" title="$id">auth-ID</a> to'
' <input type="text" name="nid" size="16">'
' <input type="submit" value="remember it!">'
));
BEGIN { ($ENV{PERLINIT}||'') =~ /(.+)/s and eval $1 }
+use utf8;
use Fcntl qw':flock :seek';
use Cwd qw'abs_path';
use File::Basename;
and not($dkey and ($ENV{HTTP_COOKIE}||'') =~ /dkey=$dkey/)
and open $file,'<',"$file/download")
{
- $_ = <$file> || '';
+ my $d1 = <$file> || ''; # first download
+ chomp $d1;
close $file;
- chomp;
if ($ra) {
# allow downloads from same ip
- $_ = '' if /\Q$ra/;
+ $d1 = '' if $d1 =~ /\Q$ra/;
# allow downloads from sender ip
- $_ = '' if (readlink("$file/ip")||'') eq $ra;
+ $d1 = '' if (readlink("$file/ip")||'') eq $ra;
}
- if ($_) {
- s/(.+) ([\w.:]+)$/by $2 at $1/;
+ if ($d1 and $d1 =~ s/(.+) ([\w.:]+)$/$2 at $1/) {
$file = filename($file);
- http_die("$file has already been downloaded $_");
+ http_die("$file has already been downloaded by $d1");
}
}
$sb = sendfile($file,$seek,$stop);
BEGIN { ($ENV{PERLINIT}||'') =~ /(.+)/s and eval $1 }
+use utf8;
use Fcntl qw(:flock);
use Digest::MD5 qw(md5_hex);
$v =~ /^group$/i ? $group = checkchars('group',$vv):
$v =~ /^ab$/i ? $ab = $vv:
$v =~ /^gm$/i ? $gm = $vv:
- $v =~ /^show$/i ? $tools = checkchars('parameter',$vv):
+ $v =~ /^show$/i ? $show = checkchars('parameter',$vv):
$ESAC;
}
$nomail = $comment if $comment =~ /NOMAIL|!#!/;
+if ($show and $show eq 'tools') {
+ nvt_print(
+ "HTTP/1.1 302 Found",
+ "Location: /tools.html",
+ 'Expires: 0',
+ 'Content-Length: 0',
+ ''
+ );
+ &reexec;
+
+ if (open $tools,"$docdir/tools.html") {
+ while (<$tools>) {
+ while (/\$([\w_]+)\$/) {
+ my $var = $1;
+ my $env = $ENV{$var} || '';
+ s/\$$var\$/$env/g;
+ };
+ print;
+ }
+ }
+ exit;
+}
+
+
if ($akey) {
# sid is not set with web browser
# empty POST? ==> back to foc
if ($ENV{REQUEST_METHOD} eq 'POST' and not
- ($subuser or $notify or $nid or $ssid or $group or $ab or $gm or $tools
+ ($subuser or $notify or $nid or $ssid or $group or $ab or $gm
or $disclaimer or $encryption or $pubkey))
{
nvt_print(
exit;
}
-if ($tools) {
- pq(qq(
- 'To use one of the following F*EX clients you must configure them after'
- 'download:'
- '<p>'
- '<table border=1>'
- ' <tr><th align=left>F*EX server:<td><code>$ENV{PROTO}://$ENV{HTTP_HOST}</code></tr>'
- ' <tr><th align=left>Proxy:<td>(your web proxy address, may be empty)</tr>'
- ' <tr><th align=left>User:<td><code>$user</code></tr>'
- ' <tr><th align=left>Auth-ID:<td><code>$id</code></tr>'
- '</table>'
- ));
- if (open $tools,"$docdir/tools.html") {
- while (<$tools>) {
- while (/\$([\w_]+)\$/) {
- my $var = $1;
- my $env = $ENV{$var} || '';
- s/\$$var\$/$env/g;
- };
- print;
- }
- }
- exit;
-}
-
if ($group) {
&handle_group;
}
''
'to upload files to F*EX group "$group"'
''
- 'See http://$ENV{HTTP_HOST}/ for more information about F*EX.'
+ 'See http://$ENV{HTTP_HOST}/index.html for more information about F*EX.'
''
'Questions? ==> F*EX admin: $admin'
));
BEGIN { ($ENV{PERLINIT}||'') =~ /(.+)/s and eval $1 }
+use utf8;
use Encode;
use Fcntl qw':flock :seek :mode';
use IO::Handle;
$id = $rid = $anonymous = 'anonymous';
if ($to =~ /^anonymous/) {
@to = ($to);
- $autodelete{$to} = $autodelete = 'NO';
+ $autodelete{$to} = $autodelete = $specific{'autodelete'}||'NO';
}
$nomail = $anonymous;
}
# set akey link for HTTP sessions
# (need original id for consistant non-moving akey)
if (-d $akeydir and open $idf,'<',"$from/@" and my $id = getline($idf)) {
- $akey = untaint(md5_hex("$from:$id"));
- mksymlink("$akeydir/$akey","../$from");
- # show URL from fexsend
- if ($from eq $to and $comment eq '*') {
+ # akey for webbrowser or fexsend special
+ if (not $sid or ($from eq $to and ($comment eq '*')) or $command) {
+ $akey = untaint(md5_hex("$from:$id"));
mksymlink("$akeydir/$akey","../$from");
}
}
- int((time-mtime("$file/filename"))/$DS);
if ($comment =~ /NOMAIL/ or
(readlink "$to/\@NOTIFICATION"||'') =~ /^no/i) {
- printf "%8s MB [%s d] %s/%s/%s\n",
+ printf "%8s MB (%2s d) %s/%s/%s\n",
$size,
$rkeep,
$durl,
$dkey,
urlencode(basename($file));
} else {
- printf "%8s MB [%s d] <a href=\"%s\">%s</a>%s %s\n",
+ printf "%8s MB (%2s d) <a href=\"%s\">%s</a>%s %s\n",
$size,
$rkeep,
untaint("/fup?akey=$akey&dkey=$dkey&command=RENOTIFY"),
}
my $rkeep = untaint(readlink "$file/keep"||$keep_default)
- int((time-mtime("$file/filename"))/$DS);
- printf "%8s MB [%s d] <a href=\"%s\">%s</a>%s\n",
+ printf "%8s MB (%2s d) %s <a href=\"%s\">%s</a>%s\n",
$size,
$rkeep,
+ stat("$file/download")?'+':'-',
untaint("/fup?akey=$akey&dkey=$dkey&command=FORWARD"),
$filename,
$comment?qq( "$comment"):'';
$akey,$dkey;
printf "[<a href=\"/fup?akey=%s&dkey=%s&command=COPY\">forward</a>] ",
$akey,$dkey;
- printf "%8s MB (%s d) <a href=\"%s\">%s</a>%s\n",
+ printf "%8s MB (%2s d) <a href=\"%s\">%s</a>%s\n",
$size,$rkeep,$url,$filename,$comment;
}
}
my @cookies;
if ($logout and my $cookie = $ENV{HTTP_COOKIE}) {
while ($cookie =~ s/(\w+key)=\w+//) {
- push @cookies,"Set-Cookie: $1=; Max-Age=0; Discard";
+ push @cookies,"Set-Cookie: $1=x; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
}
}
' <input type="hidden" name="from" value="$from">'
' <input type="hidden" name="id" value="$id">'
' <table border="1">'
- ' <tr><td>sender: <td><a href="/fup/$ab64">$from</a></tr>'
+ ' <tr><td>sender: <td><a href="/foc">$from</a></tr>'
' <tr title="e-mail address or alias"><td>recipient(s):'
' <td><input type="text" name="to" size="96" value="$to"><br>'
));
foreach my $rd (@local_rdomains) {
print "*\@$rd\n";
}
+ } elsif (/^\@LOCAL_USERS/) {
+ foreach (glob "*/@") {
+ s:/.::;
+ print "$_\n";
+ }
} else {
print "$_\n";
}
pq(qq(
'<p><hr><p>'
'<b>'
- 'Warning: the recipient must not be a mailing list, because after'
- 'download the file will be no more available!'
+ 'Warning: the recipient must not be a mailing list,'
+ 'because after download the file will be no more available!'
'</b><br>'
- 'Contact <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a>'
- 'if you want to fex to a mailing list,'
+ 'Contact <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a> if you want to fex to a mailing list,'
'he can allow multiple downloads for specific addresses.'
+ '<p>'
+ 'Use a <a href="/tools.html">F*EX client</a> if you want to send more than one file or resume an interrupted upload.'
'</body></html>'
- ));
+ '<p>
+ ));
exit;
}
pq(qq(
' <input type="hidden" name="akey" value="$akey">'
' <table border="1">'
- ' <tr><td>sender:<td>$from</tr>'
+ ' <tr><td>sender:<td><a href="/foc">$from</a></tr>'
));
if ($anonymous) {
pq(qq(
pq(qq(
'<form action="/fup"'
' method="post"'
- ' accept-charset="ISO-8859-1"'
+ ' accept-charset="UTF-8"'
' enctype="multipart/form-data">'
' <table>'
' <tr><td>sender:'
# parse HTTP QUERY_STRING (parameter=value pairs)
if ($qs) {
foreach (split '&',$qs) {
- if (s/^(\w+)=//) {
- my $x = $1;
+ if (s/^(\w+)=(.*)//) {
+ my $p = uc($1);
+ my $v = $2;
# decode URL-encoding
- s/%([a-f0-9]{2})/chr(hex($1))/gie;
- setparam($x,$_);
+ $v =~ s/%([a-f0-9]{2})/chr(hex($1))/gie;
+ setparam($p,$v);
+ if ($p eq 'AUTODELETE') {
+ $specific{'autodelete'} = $autodelete = $v;
+ }
+ if ($p eq 'KEEP' and /^\d+$/) {
+ $specific{'keep'} = $keep = $v;
+ }
}
}
}
foreach my $address (split(",",$address)) {
$address .= '@'.$mdomain if $mdomain and $address !~ /@/;
push @{$ab{$alias}},$address;
- $autodelete{$alias} = $autodelete;
- $keep{$alias} = $keep;
- $locale{$alias} = $locale;
+ $autodelete{$alias} = $autodelete if $autodelete;
+ $keep{$alias} = $keep if $keep;
+ $locale{$alias} = $locale if $locale;
}
}
}
} elsif ($locale{$to}) {
$locale{$address} = $locale{$to};
} else {
- $locale{$address} = $locale ;
+ $locale{$address} = $::locale ;
}
unless ($locale{$address}) {
$locale{$address} = $default_locale || 'english';
if ($from eq "@to") {
# special "fex yourself"
- mksymlink("$filed/autodelete",'NO');
+ mksymlink("$filed/autodelete",$specific{'autodelete'}||'NO');
} else {
$autodelete{$to} = $autodelete unless $autodelete{$to};
if ($autodelete{$to} =~ /^(DELAY|NO|\d+)$/i) {
$ar .= '|[^\@]+\@' . $rd;
}
$ar .= ')';
+ } elsif (/^\@LOCAL_USERS/ and -s "$to/@") {
+ $allowed = 1;
+ last;
} else {
# allow wildcard *, but not regexps
$ar = quotemeta $_;
sub forward {
my $file = shift;
my ($nfile,$to,$AB);
- my ($filename);
+ my ($filename,$keep);
my (%to);
http_die("no file data for <code>$file</code>") unless -f "$file/data";
+ $keep = $::keep||$keep_default;
+ if (my $mt = mtime("$file/data")) { $keep += int((time-$mt)/$DS) }
+
if (@to) {
# check recipients restriction
}
}
+ @to = keys %to;
+
http_header('200 OK');
print html_header($head);
- @to = keys %to;
-
foreach my $to (my @loop = @to) {
$to =~ s/:\w+=.*//; # remove options from address
$nfile = $file;
close $comment;
}
if ($autodelete =~ /^(DELAY|NO|\d+)$/i) {
- symlink($autodelete,"$nfile/autodelete");
- }
- symlink($keep||$keep_default, "$nfile/keep");
- copy("$file/id", "$nfile/id");
- copy("$file/ip", "$nfile/ip");
- copy("$file/speed", "$nfile/speed");
- copy("$file/replyto", "$nfile/replyto");
- $filename = copy("$file/filename", "$nfile/filename");
- link "$file/data", "$nfile/data"
+ symlink $autodelete,"$nfile/autodelete";
+ }
+ symlink $keep, "$nfile/keep";
+ copy("$file/id", "$nfile/id");
+ copy("$file/ip", "$nfile/ip");
+ copy("$file/speed", "$nfile/speed");
+ copy("$file/replyto", "$nfile/replyto");
+ $filename = copy("$file/filename", "$nfile/filename");
+ link "$file/data", "$nfile/data"
or die http_die("cannot create $nfile/data - $!");
unless ($dkey = readlink("$nfile/dkey") and -l "$dkeydir/$dkey") {
$dkey = randstring(8);
} elsif ($v eq 'FEXYOURSELF') {
$submit = $vv;
@to = ($from);
+ $specific{'autodelete'} = $autodelete = 'no';
} elsif ($v eq 'TO') {
# extract AUTODELETE and KEEP options
if ($vv =~ s/[\s,]+AUTODELETE=(\w+)//i) {
if ($from) {
if ($to eq '.') {
$to = $from;
+ unless ($specific{'autodelete'}) {
+ $specific{'autodelete'} = $autodelete = 'no';
+ }
}
if ($to eq '//') {
$to = $from;
+ unless ($specific{'autodelete'}) {
+ $specific{'autodelete'} = $autodelete = 'no';
+ }
$comment = '//';
}
}
BEGIN { ($ENV{PERLINIT}||'') =~ /(.+)/s and eval $1 }
+use utf8;
use Fcntl qw(:flock :seek :mode);
# import from fex.ph
BEGIN { ($ENV{PERLINIT}||'') =~ /(.+)/s and eval $1 }
+use utf8;
+
# add fex lib
(our $FEXLIB) = $ENV{FEXLIB} =~ /(.+)/;
die "$0: no $FEXLIB\n" unless -d $FEXLIB;
BEGIN { ($ENV{PERLINIT}||'') =~ /(.+)/s and eval $1 }
+use utf8;
use Fcntl qw(:flock :seek :mode);
use Digest::MD5 qw(md5_hex);
+2015-12-29 fexsend: added search pattern argument to option -l
+2015-12-25 fup: added +/- download flag in LIST command output
+2015-12-18 fup: allow AUTODELETE and KEEP parameter for anonymous user and
+ sender=recipient
+2015-12-01 hint for fexget and fexit in notification email
+2015-12-01 fixed bug notification email ignores (sometimes) locale
+2015-11-27 fixed bug first line in encrypted notification emails gets lost
+2015-11-21 fixed bad UTF8 encoding for french spanish czech galician
+2015-11-10 fexget: fixed bug timeout for big files on slow storage
+2015-10-14 install: fixed bug missing fex group
+2015-10-09 fexsend: better support for reverse proxy (closing connection)
+2015-10-06 fexsend: abort if file has been modified while uploading
+2015-10-04 fup: when forwarding a file, keep time is calculated for today,
+ not for upload day
+2015-09-29 fexget: fixed bug no https download
+2015-09-26 fex_cleanup: fixed bug send no locale reactivation.txt
+2015-09-21 fexget: fixed bug resume download on aborted storage test file
+ leads to corrupted file
+2015-09-17 changed LIST output formating (more consistent)
+2015-09-17 fexget: fixed bug cannot forward a file that was received from myself
+2015-09-16 fexsend: more robust fileID (md5sum of metadata)
+2015-09-14 fup: show autodelete=no if sender == recipient
+2015-09-11 moved comment to top in notification email
+2015-09-08 fup,fuc: fixed bug link to F*EX clients tools.html broken (loop)
+2015-09-06 fexsend: added ditto-zip for MacOSX
+2015-09-02 fexsend: added MacOSX support
+2015-09-01 fac: added option -Rl for local users
+2015-09-01 fup: added local users restriction option
2015-08-26 fur: fixed bug no registration possible
2015-08-25 fup: fixed bug uninitialized value when called by sup.html
- fac: option -q quota=0 means use default quota
+2015-08-25 fac: option -q quota=0 means use default quota
2015-08-24 better detection of UTF8 in comment
2015-08-14 fixed bug "Wide character in print at (...)/fex.pp" in function pq()
2015-07-29 install: fixed various bugs
2015-07-15 dop: symbolic links generate a HTTP 302 (temporarily redirection)
instead of a HTTP 301 (permanently redirection) response
2015-06-16 fexsend: fixed bug hangs with https
- new fex.ph config variable @mailing_lists
+2015-06-16 new fex.ph config variable @mailing_lists
2015-06-15 fup: always display fur link, if @local_domains is defined
2015-06-10 fexsrv: fixed warning with https and SIGCHLD
2015-05-16 fexsrv/dop: added active and passive redirect support
2015-03-08 fup: fixed bug uninitialized value $address if alias address is
used twice
2015-03-07 disallow email addresses starting with "-"
- fex_cleanup: do not terminate on sendmail error
+2015-03-07 fex_cleanup: do not terminate on sendmail error
2015-03-01 no file name in email subject if notification is encrypted
2015-02-28 fexsrv: restrict HTTP header to 64 kB ($bs) and POST (not fup) to
128 MB
2015-02-18 fuc: fixed bug no gpg usage help
2015-02-17 fexsend: check SSLeay version and adjust SSL_verify_mode
2015-02-16 fup: save upload URL in spool
- in notification+reminder emails use same protocol for download URL
+2015-02-16 in notification+reminder emails use same protocol for download URL
like in upload
2015-02-08 rup: fixed various bugs (not working at all)
2015-02-05 fup: fixed bug cannot send to groups
2015-01-27 fup: set autodelete=no if sender == recipient
(use case: provide download link for mailing lists)
- new fex.ph config variable $fex_yourself (default yes)
+2015-01-27 new fex.ph config variable $fex_yourself (default yes)
2015-01-25 fexsend: fixed bug cannot forward a file name with "&"
2015-01-21 main user is always first member of a new group
- substituted CGI::Carp with web error handler via PERLINIT environment
+2015-01-21 substituted CGI::Carp with web error handler via PERLINIT environment
2015-01-17 new fex.ph config variable $mail_authid (default yes)
2015-01-16 fixed bug no notfication for still existing file (overwrite)
2015-01-15 fixed bug no locale reminder notfication
- fixed bug wrong result for recipients with NOTIFICATION=no
+2015-01-15 fixed bug wrong result for recipients with NOTIFICATION=no
2015-01-13 fexsend: added option -N resend notification email
- resending notification email deletes download ip restriction
- fup: fixed bug sending to groups broken
+2015-01-13 resending notification email deletes download ip restriction
+2015-01-13 fup: fixed bug sending to groups broken
2015-01-10 fexsend: added option -S show server/user settings
- fup: added command LISTSETTINGS
+2015-01-10 fup: added command LISTSETTINGS
2015-01-09 foc: added save-or-display (MIME) option for download
2015-01-04 fexsend: fixed bug dies too early on multiple files and one
file has been already transfered
DEFAULT:!3DES:!MD5
2014-12-24 fexget,fexsend,sexsend: evaluate environment variables SSLVERIFY
SSLVERSION SSLCAPATH SSLCAFILE SSLCIPHERLIST
- fexget,fexsend,sexsend: use TLS, not SSL
+2014-12-24 fexget,fexsend,sexsend: use TLS, not SSL
2014-12-23 fexsend: $HOME/.fex/config with $opt_* and %alias variables
- fexget: $HOME/.fex/config with $opt_* and %autoview variables
+2014-12-23 fexget: $HOME/.fex/config with $opt_* and %autoview variables
2014-12-19 fur: fixed bug race condition with fex_cleanup (external->internal)
2014-12-17 install/update: fixed bug some spool files are owned by user root
2014-12-16 fexsrv: fixed bug handling of User-Agent FDM
2014-12-09 added l ll lf to distribution
- fexwall: also mail to sub and group users
+2014-12-09 fexwall: also mail to sub and group users
2014-12-03 fup: remove file after upload if restricted user has set NOMAIL
- fup: fixed bug wrong message "user notified" if NOMAIL
+2014-12-03 fup: fixed bug wrong message "user notified" if NOMAIL
2014-12-02 fup: also check recipient restrictions on command CHECKRECIPIENT
2014-11-24 fexget: autoview gif jpg png tif after download
2014-11-20 count unfinished upload size into quota, too
- fixed bug wrong quota calculation on SysV UNIX like Solaris
+2014-11-20 fixed bug wrong quota calculation on SysV UNIX like Solaris
2014-11-18 fexsend: added environment variables SSLVERIFY SSLCAPATH SSLCAFILE
2014-11-18 dop: added HTTP basic authentication for htdoc directory with
.htauth file
2014-11-14 ignore @forbidden_recipients if $SPOOL/$USER exists
(admin has created user)
2014-11-11 fup: fixed bug groups from other users in address book selection
- fup: added useragent to $SPOOL/$TO/$FROM/$FILE/
+2014-11-11 fup: added useragent to $SPOOL/$TO/$FROM/$FILE/
2014-11-10 fup: present locales in recipient query form, too
2014-11-07 FAQ: added text anchor URLs
2014-11-03 added missing fexget fexsend sexget sexsend for tools.html
2014-09-01 fup: upload status bar waits longer, until $timeout
2014-08-27 fex_cleanup: use wget for new release dedection
2014-08-18 fexsend: workaround for stunnel bug (options -s and -g)
- fex_cleanup,fexsend: always restrict permissions on fexsend id-file
+2014-08-18 fex_cleanup,fexsend: always restrict permissions on fexsend id-file
2014-08-16 fac: added options -P and -E (more examples)
2014-08-15 install: fixed bug wrong owner in spool
- fex_cleanup: do not terminate on error, but print warning
+2014-08-15 fex_cleanup: do not terminate on error, but print warning
2014-08-13 fexsrv,fexsend,fexget: reenabled IPv6 support
2014-08-10 fac: added option -/ to set new admin
2014-08-08 moved $admin_pw from fex.ph to auth-ID for user $admin
- fex_cleanup: fixed bug in notify_newrelease
- fac(CGI): switched from HTTP basic authorization to auth-ID/akey
- fexsend: always use CHECKRECIPIENT, not only for aliases
+2014-08-08 fex_cleanup: fixed bug in notify_newrelease
+2014-08-08 fac(CGI): switched from HTTP basic authorization to auth-ID/akey
+2014-08-08 fexsend: always use CHECKRECIPIENT, not only for aliases
2014-08-07 dop: generate on-the-fly gzipped documents if requested
2014-08-06 fixed bug install script dysfunctional (permission, hostname)
2014-07-25 reenabled vhost support
2013-09-23 fexsend: fixed bug option -c sends uncompressed file
2013-09-19 sub and group users have the same quota amount like their main user
2013-09-18 fixed bug permission denied for locale htdocs
- anonymous user now with hostname domain instead of mail domain
+2013-09-18 anonymous user now with hostname domain instead of mail domain
2013-09-17 dop: set locale cookie, too
2013-09-15 foc: added "Change the disclaimer" option
2013-09-12 fup: expand domainless address with server hostname if such a user
exists (needed for fbm/nettest)
2013-09-09 new FAQ design (questions first, then Q+A)
2013-09-04 fac: modify $hostname when vhost fex.ph is created
- fuc: recognize comment=NOMAIL
+2013-09-04 fuc: recognize comment=NOMAIL
2013-08-26 fexsend: always show download URL if recipient is "."
2013-08-20 fup,fop: fixed bug no DELETE and RESUME for fexmail and anonymous
users (because of storage swap)
2013-08-18 sexsend: fixed bug data corruption when using https
- fop,fup: fixed bug bad file locking when using multiple recipients
- fexsend: fixed bug hangs on server error when sending archive
+2013-08-18 fop,fup: fixed bug bad file locking when using multiple recipients
+2013-08-18 fexsend: fixed bug hangs on server error when sending archive
2013-08-17 fixed bug $sender_from ignored
- fup,foc: added notification email resending on user request
+2013-08-17 fup,foc: added notification email resending on user request
2013-08-16 fac: fixed bug wrong output order for option -l
2013-08-14 fop: fixed bug no multiple downloads for fexmail
- fac: added option -M for resending notification emails
+2013-08-14 fac: added option -M for resending notification emails
2013-08-09 afex: fixed bug ID for input
2013-08-06 fexsrv: always includes "Server: fexsrv" in HTTP reply
fexsend: terminates if no fexsrv HTTP reply
2013-07-18 fup,fexsend: use header Content-Location instead of Content-Type for
file linking
2013-07-15 fup: modifying keep references actual time, not upload date
- fexsend: fixed bug no feedback on option -x -k (modify keep)
+2013-07-15 fexsend: fixed bug no feedback on option -x -k (modify keep)
2013-07-13 fup: fixed bug user specific keep and autodelete defaults are ignored
2013-07-12 fup,fop: added file link support
- fexsend: added option -/ for file linking
+2013-07-12 fexsend: added option -/ for file linking
2013-07-09 fexget: added option -P proxy:port
2013-06-28 new all-in-one FAQ
2013-06-27 fup: to/from storage swap for fexmail and anonymous users
- fup: anonymous recipient with random number
+2013-06-27 fup: anonymous recipient with random number
2013-06-26 fop: allow multiple downloads from same ip
- fup,fac: extended "fex yourself" support
- added sup.html
+2013-06-26 fup,fac: extended "fex yourself" support
+2013-06-26 added sup.html
2013-06-22 fop,fexsend: Location output for fexmail for already transfered files
2013-06-19 fexget: fixed bug cannot download MIME file
2013-06-15 fex.ph: new config variable $notify_newrelease checks
(with hooks in fop,fop.fuc,foc,fur)
2013-06-03 fuc: fixed bug user can modify his auth-ID to an illegal value
2013-05-30 install: force creation of $admin_pw
- fex_cleanup: fixed bug wrong fexadmin fexid for reactivation emails
+2013-05-30 fex_cleanup: fixed bug wrong fexadmin fexid for reactivation emails
2013-05-25 added afex and asex to distribution
2013-05-23 dop: fixed bug no output on file.stream
2013-05-22 install script installs as user fex (and not as root)
2013-05-19 security patch: config variable @local_rhosts restricts download of
files from new external users to specific ip ranges
- use <from> and <to> syntax in notification email header
- added support for $max_fail_handler()
+2013-05-19 use <from> and <to> syntax in notification email header
+2013-05-19 added support for $max_fail_handler()
2013-05-18 fac: fixed bug option -rd does not work
- fac: added option -R
+2013-05-18 fac: added option -R
2013-05-16 fop: fexmail support (multiple downloads allowed)
2013-05-09 fup: fixed bug anonymous only works if $mdomain is defined
- fop: fixed bug anonymous only works if recipient host is in
+2013-05-09 fop: fixed bug anonymous only works if recipient host is in
@anonymous_upload list
2013-05-07 fup: fixed bug multiple Location HTTP headers generate an error with
some web browsers
2013-04-05 fexsend: fixed bug server timeout when sending huge ZIPs
2013-02-20 fac: added -m maintenance mode
2013-02-17 fup: fixed bug stored comment in spool not in UTF8
- fop: fixed bug file deletion also deletes fop.log
+2013-02-17 fop: fixed bug file deletion also deletes fop.log
2013-02-16 fur,fex.ph: allow "*" for local domains self registration
- fex.ph: new config variable @registration_hosts
- fex.ph: new config variable @admin_hosts
+2013-02-16 fex.ph: new config variable @registration_hosts
+ new config variable @admin_hosts
2013-02-11 fur: fixed bug insecure dependency with exuser
2013-01-31 receiving of reminder emails is user configurable
2013-01-24 fup: decode UTF8 comment
2012-11-08 fop: fixed bug cannot use "?" in file name with fexsend
2012-11-07 fixed security bug restricted user can redirect files
2012-11-06 fup: show download-URL after upload if sender = recipient
- fup,fop,fac: added user up/download IP restriction by admin
+2012-11-06 fup,fop,fac: added user up/download IP restriction by admin
2012-11-05 added HTTP Strict Transport Security (HSTS) if $force_https is set
- fixed bug afex accessible via xkey from everywhere
+2012-11-05 fixed bug afex accessible via xkey from everywhere
2012-11-02 fup: fixed bug one time upload URL gives "no recipient specified"
error
2012-11-01 fup: fixed bug public upload always gives error
2012-10-16 fop,fup: added afex support
- fup: accept recipients . and //
+2012-10-16 fup: accept recipients . and //
2012-10-15 sex,sexsend: added anonymous mode (no auth-ID necessary)
2012-10-14 fop,fup: added support for fexsend anonymous mode
2012-10-11 fex.ph: added optional config variable $overwrite
2012-10-10 fup: anonymous upload with non-anonymous recipient
2012-09-30 fup: fixed bug groups not working any more (NOMAIL)
2012-09-19 fup: logout functions respects login CGI (or symlink)
- foc: detailed/brief notification mail configuration
+2012-09-19 foc: detailed/brief notification mail configuration
2012-09-18 fexsend: added options -. and -n
- fup: added shortmail option in comment
+2012-09-18 fup: added shortmail option in comment
2012-09-17 added mailmode configuration option in fex.ph
- fup: shows download-URL if NOMAIL
+2012-09-17 fup: shows download-URL if NOMAIL
2012-09-15 sex: public URL parameter may be in base64 format, too
2012-09-10 dop: added more security checks
2012-09-01 dop: added streaming document output
2012-08-30 sex: fixed bug second receiving client corrupts the stream
2012-08-26 Changed licence from AGPL to Perl Artistic
2012-08-21 schwuppdiwupp: error handling on network failures for Windows
- schwuppdiwupp: removed Tk::FileSelect for Windows
+ removed Tk::FileSelect for Windows
2012-07-11 fop: fixed bug no multiple downloads for anonymous uploads
2012-07-10 fixed French, Spanish and Czech localization (code syntax) bugs
2012-07-09 fup: anonymous upload with modifyable keep option and multiple
2012-07-05 fexsrv: added camel easteregg
2012-07-02 fup: added optional anonymous upload with fex.ph variable
@anonymous_upload
- fup: fixed bug throttle 0 configuration is ignored
+2012-07-02 fup: fixed bug throttle 0 configuration is ignored
2012-07-01 fexsend: optional argument '@' as files/recipients separator
- fexsend: fixed bug notification email for recipient '.'
+ fixed bug notification email for recipient '.'
2012-06-21 dop: inside HTML documents: #include "file"
2012-06-06 fexget: new option -+
2012-06-05 fexsend: new option -+
2012-06-01 fup: show transfered size instead of total size in status window
2012-05-04 fexsrv: added bunny easteregg
2012-05-02 fexsrv: allow HTTP 1.0 with Range header (wget!)
- fexsrv: disallow negative value in Range (client signed int bug)
+ disallow negative value in Range (client signed int bug)
2012-04-26 Changed licence from GPL to AGPL
2012-04-07 foc: check new address book for syntax errors
2012-04-06 foc: added comment field for new subuser information
2012-04-04 removed F*IX because of too many bugs and no maintainer any more
2012-03-05 fup: fixed bug shell wildcards in recipient address are expanded to
known users from spool
- fex.ph: added optional config variable @locales
+2012-03-05 fex.ph: added optional config variable @locales
2012-03-01 dop: delivers MIME type text/plain if "?!" is appended to URL
2012-02-20 foc: show auth-ID after click on link
2012-02-07 fop: MIME-type text/html is no longer possible for security reasons
2012-02-04 added optional french localization
2012-02-03 fixed bug 0.0.0.0 not recognized as ip address
- fex.ph: added optional config variable $keep_max
+2012-02-03 fex.ph: added optional config variable $keep_max
2012-02-02 HTTP parameter filtering to prevent cross-site scripting attacks
2012-02-01 config variable @throttle may also contains ip addresses
2012-01-25 pup: locale selection in native language, default autodelete=no
- fup: "send another file" with same keep and autodelete parameters
+2012-01-25 fup: "send another file" with same keep and autodelete parameters
2012-01-17 fixed bug reactivation.txt in czech instead english
2012-01-06 fup: fixed bug show wrong remaining keep days
2012-01-02 fup.pl: fixed bug bad FAQ link
2011-09-07 fac(CGI): fixed bug infinitve loop in watch logfile
2011-09-06 fup,fac,fur: new additional login URL type:
http://FEXSERVER/fup/B64ID
- fup: show "or select from address book" only if there are entries
+2011-09-06 fup: show "or select from address book" only if there are entries
2011-09-05 fexsrv: fixed bug locale cookie not fetched on http://cgi?parameter
2011-09-01 rup: fixed bug cannot find files (no more SID in akeys directory)
2011-08-30 fex.ph: new config variable @forbidden_recipients
2011-08-29 fexsend: accept file number for delete option -d, too
- dop: fixed bug no text document output if external file command is
+2011-08-29 dop: fixed bug no text document output if external file command is
non-GNU
2011-08-26 added one time upload OKEY
2011-08-13 fex_cleanup: fixed bug comment missing in reminder email
2011-08-11 dop: #if ... #else ... #elseif ... #endif inside HTML documents
- dop: show HTML sourcecode if "!" is appended to URL
+ show HTML sourcecode if "!" is appended to URL
2011-08-10 fex_cleanup: delete obsolete users, too, via fex.ph $account_expire
new FAQ design (with Javascript/CSS)
2011-08-09 fup: show error on invalid SKEY or GKEY
- fuc: fixed bug subuser and groupuser not lowercase forced
- address book may also contain option locale=<languange>
+2011-08-09 fuc: fixed bug subuser and groupuser not lowercase forced
+2011-08-09 address book may also contain option locale=<languange>
2011-08-08 fex_cleanup: auto-expire user accounts with fex.ph variable
$account_expire
- fexsend,fup: allow forward with locale
- dop: extra security check: files from lib and spool are not allowed
+2011-08-08 fexsend,fup: allow forward with locale
+2011-08-08 dop: extra security check: files from lib and spool are not allowed
2011-08-07 fup: subusers and groupusers can also select a locale
- fup: if user selects a locale login, save it as default locale
+2011-08-07 fup: if user selects a locale login, save it as default locale
(does not affect fexsend and schwuppdiwupp)
- notification emails come in default locale
+2011-08-07 notification emails come in default locale
2011-08-03 fexsend: fixed bug uninitialized value when using chunked mode
- fexsend: added undocumented option -F female mode
+ added undocumented option -F female mode
2011-07-31 fexsend: added option -s streaming data
- fup: accept streaming data
+2011-07-31 fup: accept streaming data
2011-07-30 fexsend: -a tar archives no longer use a intermediate transferfile,
but send via pipe (streaming)
- fexsend: fixed bug no resume on -a archives
- fexsend: always ask server if file already has been uploaded
- fup: more information on F*EX clients download and configuration
+2011-07-30 fexsend: fixed bug no resume on -a archives
+2011-07-30 fexsend: always ask server if file already has been uploaded
+2011-07-30 fup: more information on F*EX clients download and configuration
2011-07-27 fup: if comment contains "!bcc!" then sender will get a bcc
of notification email
2011-07-26 fexget: added option -X do not extract archive file
- fexget: added option -a get all files
- fexsrv: fixed bug uninitialized value when using a reverse proxy
- fex_cleanup: fixed bug notify reminder email not localized
+2011-07-26 fexget: added option -a get all files
+2011-07-26 fexsrv: fixed bug uninitialized value when using a reverse proxy
+2011-07-26 fex_cleanup: fixed bug notify reminder email not localized
2011-07-22 fac(CGI): fixed bug displaying < and & in logfiles
- fac(CGI): added getting error.log
- fop: allow multiple downloads from any client if sender = recipient
+2011-07-22 fac(CGI): added getting error.log
+2011-07-22 fop: allow multiple downloads from any client if sender = recipient
2011-07-16 added doc/reverse_proxy
2011-07-14 added optional czech localization
2011-07-01 FAQ.html reformated
2011-06-17 fixed bug $bcc is ignored
2011-06-16 fexsend,fexget: better reverse proxy support
(always send Host header)
- added optional galician localization
+2011-06-16 added optional galician localization
2011-06-15 fup: fixed bug always keep_default days in notification email
2011-06-14 fexsend: transparent proxy detection (and support)
- fixed bug $docdir ignored
+2011-06-14 fixed bug $docdir ignored
2011-06-10 fex.ph: new config variable $bcc for notification emails
2011-06-09 set Reply-To in all notification emails
- fup: fixed security bug everyone can upload files with empty auth-ID
+2011-06-09 fup: fixed security bug everyone can upload files with empty auth-ID
2011-06-05 fup: fixed bug insecure dependency in printf on "forward file"
2011-06-03 fup,fop: added throttle bandwith limit option (fex.ph)
2011-06-02 fup: added bandwith limit option
2011-06-01 added PID and request-number to the logs
- fex_cleanup: fixed bug no expire with AUTODELETE=NO
+2011-06-01 fex_cleanup: fixed bug no expire with AUTODELETE=NO
2011-05-31 support for FEXLIB /usr/local/share/fex/lib /usr/share/fex/lib
2011-05-30 fup,fexsend: added option -x to modify file parameters
2011-05-29 fup,fexsend: forward files with new comment and keep time
- rup: add mdomain to addresses without domain
+2011-05-29 rup: add mdomain to addresses without domain
2011-05-18 fup: fixed bug restricted users can forward files to anybody
2011-05-17 fixed bug access problems with AKEYs: now use SID instead of SIP
2011-05-11 added helper script mksgkeys (regenerates missing SKEYs and GKEYs)
2011-05-10 fex_cleanup: cleanup ADDRESS_BOOK file upload
- fex.ph,fex_cleanup: AUTODELETE=NUMBER ==>
+2011-05-10 fex.ph,fex_cleanup: AUTODELETE=NUMBER ==>
delete file on next NUMBER day after download
2011-05-09 fac,fup: added user specific autodelete default
- fac,fex_cleanup: added user specific keep default
+2011-05-09 fac,fex_cleanup: added user specific keep default
2011-04-27 fexsend: fixed bug archiv.zip not working on Windows
- dop: added index function for htdoc directory with .htindex file
+2011-04-27 dop: added index function for htdoc directory with .htindex file
2011-04-25 fexsend: better proxy support (non-persistent connections)
2011-04-24 xx: better ESXi support (heuristic guessing of tar format)
2011-04-22 sexsend: base64 support for $FEXID and $FEXXX
2011-02-24 dop: evaluate <<perl-code>> inside html documents
2011-02-21 fexsend,fup: added option fexsend -U show authorized (login) URL
2011-02-18 do not modify download URL protocol if $dkey is set in fex.ph
- fac(CGI): fixed bug uninitialized value $server
- URLs in notification emails are derived from config variable $durl
+2011-02-18 fac(CGI): fixed bug uninitialized value $server
+2011-02-18 URLs in notification emails are derived from config variable $durl
2011-02-17 fup: fixed bug access denied with SKEY
2011-02-08 fup,fop,fuc: fixed bug access problems with sip in AKEYs
- fup: fixed bug no notification email for multiple recipients
+2011-02-08 fup: fixed bug no notification email for multiple recipients
2011-02-07 fexsend,fop: do not send same file (filename and mtime) twice
2011-02-06 fup: fixed bug no notification email after first failed upload
2011-01-31 schwuppdiwupp: added ISO-8859-1 support
2011-01-30 schwuppdiwupp: added running camel
2011-01-28 schwuppdiwupp: added chunksize to proxy options
- schwuppdiwupp: fixed bug timeout when using address book
- fexsend: fixed bug chunksize 0
+2011-01-28 schwuppdiwupp: fixed bug timeout when using address book
+2011-01-28 fexsend: fixed bug chunksize 0
2011-01-27 schwuppdiwupp: added advanced preferences Proxy and TMPDIR
2011-01-26 fex_cleanup: fixed bug uninitialized value in debuglog
- fex_cleanup: added option -v
- fexsend,fexget,sexsend: added option -V show version
- schwuppdiwupp: added drag&drop support for windows
- schwuppdiwupp: added 7zG support
+2011-01-26 fex_cleanup: added option -v
+2011-01-26 fexsend,fexget,sexsend: added option -V show version
+2011-01-26 schwuppdiwupp: added drag&drop support for windows
+2011-01-26 schwuppdiwupp: added 7zG support
2011-01-25 fuc: fixed bug cannot delete all subusers
- schwuppdiwupp: fixed bug 7-zip not found
- schwuppdiwupp: added drive letters in directory selection
+2011-01-25 schwuppdiwupp: fixed bug 7-zip not found
+2011-01-25 schwuppdiwupp: added drive letters in directory selection
2011-01-24 fop: IE bug workaround to store *.exe files
2011-01-18 schwuppdiwupp: added tar, zip and 7z container
2011-01-17 fexsend: fixed bug option -l not working with https URL
2011-01-16 fup: added 7zip hint in notification emails
2011-01-13 schwuppdiwupp: fixed bug no transfer at all when comment is set
2011-01-12 rup: added logging
- rup: wrong recipient cannot download file, but will get an error
- fac(CGI): fixed bug $server not declared
+2011-01-12 rup: wrong recipient cannot download file, but will get an error
+2011-01-12 fac(CGI): fixed bug $server not declared
2011-01-07 fexget: keep file permission in overwrite mode
2011-01-04 fex_cleanup: fixed bug autodelete after partial download
2010-12-26 fex_cleanup: fixed bug too early expire for forwarded files
2010-12-10 new config variable @public_recipients for new CGI pup
- (public upload) - upload without auth-ID
+2010-12-10 (public upload) - upload without auth-ID
2010-12-09 fex.ph,fur: new config variable @local_rdomain for self-
registration of restricted external-to-internal users
2010-12-08 fup,foc: no access to foc for restricted users
2010-12-02 fup: if there is a cgi-bin/login it will be called on "logout"
2010-11-24 fex.ph: new config variable $default_locale
- dop: auto-expires every document (to prevent browser caching)
+2010-11-24 dop: auto-expires every document (to prevent browser caching)
2010-11-16 fexsrv: better error handling if CGI is not executable
2010-11-09 new SKEYs and GKEYs, because old ones could be not unique
access for subuser only with SKEY
access for groupuser only with GKEY
2010-11-07 fup,fuc: added GKEY
- fexsend: SKEY or GKEY URLs can be recipients, too
+2010-11-07 fexsend: SKEY or GKEY URLs can be recipients, too
2010-11-04 fexget: added (hidden) option -K
2010-11-03 fexsend: fixed bug proxy usage failed
2010-11-02 fop: fixed bug corrupted download with Internet Explorer
2010-10-25 fop,fup: better locking: no uploading is possible while a
download is in progress for the same file
2010-10-24 fix,fop: fixed bug subuser not working (SKEY problem)
- xx: added locking
+2010-10-24 xx: added locking
2010-10-23 xx,fop: added xx :slot option (multiple storage slots)
2010-10-20 fup,fop,fexsend: fexsend for subuser with SKEY
2010-10-19 fup: expires *KEY cookies on logout
2010-09-27 fup: fixed bug missing Content-Type in upload status report
2010-09-20 fexsrv: IPv6 http support
2010-09-15 fac(CGI): fixed bug cannot delete and (re)create user
- fac(CGI): fixed bug cannot create user who was a recipient
+2010-09-15 fac(CGI): fixed bug cannot create user who was a recipient
2010-09-12 fexsend,fop: fixed bug resuming upload does not work with alias
- fup: fixed bug resuming upload handles autodelete and keep
+2010-09-12 fup: fixed bug resuming upload handles autodelete and keep
parameters incorrectly
2010-09-07 fac(CGI): fixed bug not working if there is no user at all
2010-09-05 fop: extra parameter keep=days
2010-08-31 install: fixed bug wrong ownership for spool files
2010-08-25 perl 5.8 required
- fexget: -s can write to named pipe or character special file
+2010-08-25 fexget: -s can write to named pipe or character special file
2010-08-21 fop: $limited_download checks dkey cookie instead of client IP
2009-08-20 removed mma
2010-08-18 fex_cleanup: fixed bug not expiring
2010-08-17 fac: fixed bug accept users without domain
- install: fixed bug empty $admin_pw
+2010-08-17 install: fixed bug empty $admin_pw
2010-08-15 fex.ph: optional fix address $sender_from (instead of F*EX user) in
notification email From
2010-08-14 added optional spanish localization
2010-08-12 fup: speedup 90%
- fop: speedup 20%
- fop: better fexget compatibility
+2010-08-12 fop: speedup 20%
+2010-08-12 fop: better fexget compatibility
(close connection after file delivery)
2010-08-11 fop: fixed IE download bug (missing header separating line)
- fop: fixed 1 min delay bug on AUTODELETE=YES
+2010-08-11 fop: fixed 1 min delay bug on AUTODELETE=YES
2010-08-08 sex: support for compressed streams
- sex,sexsend: removed unneccesary text mode (option -t)
- sex,sexsend: speedup factor 5
- added sexxx
+2010-08-08 sex,sexsend: removed unneccesary text mode (option -t)
+2010-08-08 sex,sexsend: speedup factor 5
+2010-08-08 added sexxx
2010-08-06 sex: fixed various bugs in client and server
- fac(CGI): fixed bug AKEY not working
+2010-08-06 fac(CGI): fixed bug AKEY not working
2010-08-03 xx: no user inquiry for postprocessing if output is a pipe
2010-08-02 added optional german localization
2010-07-31 separated subusers in extra file $SPOOL/$USER/@SUBUSER
2010-07-25 fop: log also aborted downloads
2010-07-23 added fac CGI
2010-07-18 fexsrv,fup,fexsend: extra XKEY download with short // URL
- fexsend: fixed bug CHECKRECIPIENT not working
+2010-07-18 fexsend: fixed bug CHECKRECIPIENT not working
2010-07-16 added cookie support (for AKEY and SKEY)
- fup: fixed bug showstatus window too small for close button
+2010-07-16 fup: fixed bug showstatus window too small for close button
2010-07-13 schwuppdiwupp: added CHECKRECIPIENT
2010-07-12 fop,xx: allow several concurrent downloads of STDFEX
2010-07-10 fop: workaround for stupid IE download bug
2010-07-01 fexsrv,fex.ph: new config variable $force_https
2010-06-29 fop: new config variable $limited_download with default NO
=> allow multiple downloads through proxy farm (varying IPs)
- fop: note every successful download in spool file "download"
+2010-06-29 fop: note every successful download in spool file "download"
2010-06-25 fexget: fixed bug download status info update too often
2010-06-23 fur: better sendmail clone compatibility:
use space instead of comma as address separator
2010-06-19 fexget: new option -o overwrite mode
- fexget: use ./$file.tmp for downloading instead of $HOME/.fex/tmp/
+2010-06-19 fexget: use ./$file.tmp for downloading instead of $HOME/.fex/tmp/
2010-06-16 schwuppdiwupp: edit and select address book entries
2010-06-15 rup: fixed bug case sensitive recipient address
2010-06-12 fop: send X-File-ID on HEAD request, too
- fexget: added support of X-File-ID
+2010-06-12 fexget: added support of X-File-ID
2010-06-11 schwuppdiwupp: (chunked) multi-POST for proxy with 4 GB limit
- schwuppdiwupp: X-File-ID support
+2010-06-11 schwuppdiwupp: X-File-ID support
2010-06-08 fup,fexsend: (chunked) multi-POST for proxy with 4 GB limit
2010-06-06 fup,fop,fexsend: protocol extension X-File-ID (contains mtime
of file) is the successor of X-Size for more
2010-05-27 fexsend: added option -b bounce (copy-forward)
2010-05-26 fup,foc: added copy-forward feature
2010-05-20 fexsend: fixed bug uninitialized value with option -@
- fur: fixed bug $main::admin not declared
+2010-05-20 fur: fixed bug $main::admin not declared
2010-05-17 fexsend: added option -H for hints
- fexsend: added option -A for edit server address book
+2010-05-17 fexsend: added option -A for edit server address book
2010-05-16 fexsend: added HTTPS proxy support
- fup: fixed bug uninitialized value (line 1059)
+2010-05-16 fup: fixed bug uninitialized value (line 1059)
2010-05-13 fup: fixed bug ignored KEEP and AUTODELETE options for groups
2010-05-12 fup: fixed bug ignored autodelete option from ADDRESSBOOK
2010-04-30 fup: fixed bug uninitialized value with CHECKRECIPIENT
- fexsend: no SID for https
+2010-04-30 fexsend: no SID for https
2010-04-28 fup: fixed bug case sensitiv group addresses
2010-04-27 fexsend: fixed bug ignored server address book options
- fexsend: displays recipients and options before starting post
- fup: fixed bug ignored server address book autodelete option
+2010-04-27 fexsend: displays recipients and options before starting post
+2010-04-27 fup: fixed bug ignored server address book autodelete option
2010-04-26 fexsrv: log all HTTP headers (no more ignore list)
2010-04-25 fexsrv: accept HTTP header with continuation lines
2010-04-22 fex.pp: added htdocs/header.html support
- fex.ph: added variable @H1_extra organization link and logo
+2010-04-22 fex.ph: added variable @H1_extra organization link and logo
2010-04-20 fexsrv,fexsend: HTTP header X-Timeout (info server->client)
- fexsrv: logging with locking
+2010-04-20 fexsrv: logging with locking
2010-04-19 fexsend: removed broken option -A and replaced it with more
flexible feature "." for recipient address
- fexsend: fixed bug dies if sender is subuser (ADDRESS_BOOK error)
- fup: fixed bug no COMMENT in notification email
- dop: fixed bug error output with non GNU file command
+2010-04-19 fexsend: fixed bug dies if sender is subuser (ADDRESS_BOOK error)
+2010-04-19 fup: fixed bug no COMMENT in notification email
+2010-04-19 dop: fixed bug error output with non GNU file command
2010-04-17 fexsend,fexget: added option -i for alternative accounts or servers
2010-04-12 fexsend: new verbose output format --> <--
2010-04-11 fexsend: added option -Q quota query
2010-04-09 fup,fac: added quota support
2010-03-25 fup: fixed bug "Insecure dependency" when using AKEY parameter
(eg: sending a second file)
- fup_template.html: fixed bug upload status window always shows
+2010-03-25 fup_template.html: fixed bug upload status window always shows
"ERROR: no file data received"
2010-03-24 fexsend: fixed bug dies if there is no server address book
2010-03-22 FIX.jar: fixed bug interpret HTTP response "200 OK" as error.
2010-03-20 fup,fop: set mtime on user directory for last successfull access
2010-03-19 fexsend: fixed bug abort on short address if there is no server
address book
- fex_cleanup: better cleanup for dkeys directory
+2010-03-19 fex_cleanup: better cleanup for dkeys directory
2010-03-18 fup: fixed bug cannot DELETE with group recipient
2010-03-17 fup: fixed bug wrong success message on aborted uploads
- fop: fixed bug cannot handle @group names
+2010-03-17 fop: fixed bug cannot handle @group names
2010-03-16 fup,fuc: fixed bug mixed case in F*EX group names and addresses
2010-03-14 fex.pp: do not send notification emails on empty files
- fup,fuc: added F*EX groups
+2010-03-14 fup,fuc: added F*EX groups
2010-03-12 fup,fop: fixed bug case sensitiv FROM and TO addresses
2010-03-05 fup: fixed bug aliases are not accepted with fop_auth
2010-03-04 fexsrv: use CGI login if it exists as start-page
2010-02-26 fexsend: first check server address book, then mutt aliases
- fop: do not terminate session after ADDRESSBOOK request
+2010-02-26 fop: do not terminate session after ADDRESSBOOK request
2010-02-18 fexget: fixed bug always append existing file, ask for overwriting
2010-02-08 fexsrv: fixed bug uninitialized value in substitution (line 229)
- fex.pp: better qmail compatibility (space separated addresses)
+2010-02-08 fex.pp: better qmail compatibility (space separated addresses)
2010-02-07 fac: fixed bug uninitialized $EDITOR environment variable
2009-12-28 fup,fop,fexsend: protocol extension X-Size for more reliable
resume function (checks size of file)
2009-08-12 fup: fixed bug "send another file" for subusers
2009-08-10 fexsend: fixed bug timeout on big archives
2009-07-27 to and from addresses in spool are now always localpart@domain,
- install contains automatic spool converter
- fup: fixed bug short aliases address list mismatch
+2009-07-27 install contains automatic spool converter
+2009-07-27 fup: fixed bug short aliases address list mismatch
2009-07-24 fup,fex_cleanup: fixed bug delete all files for multiple
recipients after any download
- fexget: fixed bug delete local file before download
+2009-07-24 fexget: fixed bug delete local file before download
2009-07-20 fup: added autodelete and keep hack for HTML form
2009-07-18 fup: fixed bug leading . in file directory name
- fup: added CHECKRECIPIENT support
- fup: code cleanup, new 3-stage user interface
- fexsend: added CHECKRECIPIENT feature
+2009-07-18 fup: added CHECKRECIPIENT support
+2009-07-18 fup: code cleanup, new 3-stage user interface
+2009-07-18 fexsend: added CHECKRECIPIENT feature
2009-07-17 fexget: fixed bug wrong UTF8 handling
2009-07-16 fop: fixed bug sending wrong file size if TO or FROM has
uppercase chars ==> resuming upload did not work
2009-07-11 fup: can select more than one address from address book
2009-07-08 fup,fex.pp: fixed bug wrong download URLs
2009-07-07 new spool directory layout $TO/$FROM/urlencode($FILENAME)
- fup: be more restrictive in accepting (illegal) parameters values
- fup,fuc: subuser access key name is now SKEY (KEY is depreciated)
- rup: new HTML layout, fixed bug in file select box
+2009-07-07 fup: be more restrictive in accepting (illegal) parameters values
+2009-07-07 fup,fuc: subuser access key name is now SKEY (KEY is depreciated)
+2009-07-07 rup: new HTML layout, fixed bug in file select box
2009-07-06 fup: substitute all control characters in file name and comment
with "_"
2009-07-02 better install script, guesses IP
$TO/$FROM/$FILE --> $TO/$FROM/md5h($FILENAME)
to avoid filename collisions
2009-06-28 added mailman authorization mma
- better address-book integration in fup
+2009-06-28 fup: better address-book integration
2009-06-26 FIX.jar: fixed several bugs, now working with Windows Vista, too
2009-06-25 added fup_template.html as an example for customizing upload page
2009-06-22 fup,fexsend,fexget: LIST also shows COMMENT
2009-05-17 fup: check if there is enough free space in spool
2009-04-07 new perl based install; requires server IP for xinetd binding
2009-03-25 fexget: fixed bug saving failed if on other partition then FEXHOME
- fexget: fixed bug calculated wrong transfer rate
- fexget: changed default answers to more secure values
+2009-03-25 fexget: fixed bug calculated wrong transfer rate
+2009-03-25 fexget: changed default answers to more secure values
2009-03-24 fexsend: new option -l for listing sent files
- fup: support for listing sent files
- fex.pp: default charset is now UTF-8 in HTTP reply
+2009-03-24 fup: support for listing sent files
+2009-03-24 fex.pp: default charset is now UTF-8 in HTTP reply
2009-03-16 fur: fixed bug no lower case transformation for user and domain
2009-03-05 fop: fixed bug no parallel download possible on multiple recipients
2009-03-03 dop: send Last-Modified HTTP header (java needs it)
2009-02-22 fop: fixed bug download failed without FROM parameter
2009-02-20 test for /usr/lib/sendmail and /usr/sbin/sendmail
2009-02-18 fop: fixed bug file size query for alias recipient
- fexget: added option -a to get address-book from server
+2009-02-18 fexget: added option -a to get address-book from server
2009-02-17 fup,fuc: better linking
2009-02-14 fup: first send notification emails, then send HTTP 200 OK to client
- fup: accept ADDRESS_BOOK as upload
+2009-02-14 fup: accept ADDRESS_BOOK as upload
2009-02-13 fup,foc,fuc: added ADDRESS_BOOK support
- added fix and FIX.jar (Java applet client)
+2009-02-13 added fix and FIX.jar (Java applet client)
2009-02-11 fop: fixed bug file size request with multiple $to gives always 0
(no upload resume possible with multiple recipients)
- fop: check for valid recipient address (in file path)
+2009-02-11 fop: check for valid recipient address (in file path)
==> early abort possible when client uses illegal address for
upload (resume-HEAD-request)
2009-02-10 fur: catch errors from sendmail(clone) and save them to $log
2009-01-31 fexsrv: fixed bug handling of missing trailing / in doc requests
2009-01-30 rup: fixed bug wrong download URL in notification email
2009-01-26 fexsend: archive format 7z and zip with default compression
- fup,fuc,foc,rup: link to F*EX start page in top header
+2009-01-26 fup,fuc,foc,rup: link to F*EX start page in top header
2009-01-21 fuc: URL for subusers with KEY parameter
- fup.fuc,foc: fixed bug wrong AKEY lookup
+2009-01-21 fup.fuc,foc: fixed bug wrong AKEY lookup
2009-01-20 fexsrv: better handling of URLs with trailing / (==> index.html)
- fop: fixed bug endless loop with fop_auth mode
+2009-01-20 fop: fixed bug endless loop with fop_auth mode
2009-01-13 fup,fop: support for MIME-file types
- fexsend: added option -M for MIME-file to be displayed in webbrowser
+2009-01-13 fexsend: added option -M for MIME-file to be displayed in webbrowser
on download
2009-01-04 fup: increase minimum timeout to 10 s
2008-12-26 fup: do not allow re-upload (overwrite) if file is in download
2008-12-21 fup: fixed bug removing old autodelete and error files failed
2008-12-20 added logwatch
2008-12-18 fexget: fixed bug responsiveness on slow links
- fexget: fixed bug save file name for archives
+2008-12-18 fexget: fixed bug save file name for archives
2008-12-12 fexget: better responsiveness on slow links (modem, ISDN)
- fup: added warning for incompatible clients (konqueror, etc)
+2008-12-12 fup: added warning for incompatible clients (konqueror, etc)
2008-12-11 fexsend: allow comments in ID file
2008-12-03 fup,fex.pp: fixed bug UTF-8 subject in notfication email
2008-12-02 fexsend: better responsiveness on slow links (modem, ISDN)
- fop: send UTF-8 filename in HTTP header Content-Disposition
- fexget: save original filename (parse HTTP header)
+2008-12-02 fop: send UTF-8 filename in HTTP header Content-Disposition
+2008-12-02 fexget: save original filename (parse HTTP header)
2008-11-28 fexserv: added special FlashGet (download sucker) brake
- html error messages now with HTTP_HOST und server-time info
+2008-11-28 html error messages now with HTTP_HOST und server-time info
2008-11-27 added htdocs/version and htdocs/tools.html
- added fexsend, fexget, sexsend, sexget to htdocs/download
- dop: fixed bug symlink of symlink leads to hangup
- fop: teergrub download managers and other suckers
+2008-11-27 added fexsend, fexget, sexsend, sexget to htdocs/download
+2008-11-27 dop: fixed bug symlink of symlink leads to hangup
+2008-11-27 fop: teergrub download managers and other suckers
2008-11-26 fop: with URL parameter ?KEEP file can be downloaded more than once
- fexget: added option -k for keep on server
+2008-11-26 fexget: added option -k for keep on server
2008-11-24 fex_cleanup: fixed bug $autodelete not defined
- fexget: added HTTPS/SSL support
+2008-11-24 fexget: added HTTPS/SSL support
2008-11-22 fexsrv: reject requests with IP hostnames in HTTP Host header
2008-11-21 fex.ph,fop: $autodelete="DELAY" allows file download many times
(but only from same IP and until next fex_cleanup run)
- fup,fop: fixed bug options keep and delete autodelay do not
+2008-11-21 fup,fop: fixed bug options keep and delete autodelay do not
work with spool on NFS
2008-11-20 fexsend: added HTTPS/SSL support
- fex.ph: added config variable $autodelete
- fup: fixed bug subuser cannot send files
+2008-11-20 fex.ph: added config variable $autodelete
+2008-11-20 fup: fixed bug subuser cannot send files
2008-11-19 use md5-hash of $from:$id instead of URL parameters FROM=$from&ID=$id
- fac: set correct exit status
+2008-11-19 fac: set correct exit status
2008-11-16 fup: fixed bug DELETE not working
- install: do not overwrite lib/fup.pl (perhaps contains site config)
+2008-11-16 install: do not overwrite lib/fup.pl (perhaps contains site config)
2008-11-15 fex_cleanup: clean up $SPOOL/.ukeys/, too
2008-11-14 fup: show "user config" link only after authorization
2008-11-13 foc,fuc,fup: quick sub-user creation with auto-notification.
2008-10-29 fup: do not require HTTP authorization if request already
contains ID (methode used by xx)
2008-10-28 fex.pp: fixed bug $warning not defined
- fup: fixed bug do not allow subuser in fop_auth mode
+2008-10-28 fup: fixed bug do not allow subuser in fop_auth mode
2008-10-27 install: do not overwrite existing htdoc/index.html
- fup: fixed bug resend (SEEK) leads to HTTP error 666
+2008-10-27 fup: fixed bug resend (SEEK) leads to HTTP error 666
2008-10-26 fexsrv: accept HTTP request with absolute URLs (http://...), too
2008-10-23 fexsrv: fixed bug continue connect logfile entry
2008-10-17 fexsrv: fixed bug keep_alive with HTTP/1.0
- fexsrv: fixed bug wrong warning in debug mode with empty line
+2008-10-17 fexsrv: fixed bug wrong warning in debug mode with empty line
2008-10-07 fexsrv: moved TIMEOUT message to debug.log
2008-10-06 dop: fixed bug opening file (did not deliver any file!)
- dop: implemented HTTP keep-alive (delivering more than one
+2008-10-06 dop: implemented HTTP keep-alive (delivering more than one
document per session)
2008-10-04 if config variable $fop_auth is set, download requires
- authentication and upload is restricted to registered users
+2008-10-04 authentication and upload is restricted to registered users
2008-10-02 dop: declare exectuable scripts as application/octet-stream
- fup: added link to Windows client schwuppdiwupp.exe
+2008-10-02 fup: added link to Windows client schwuppdiwupp.exe
2008-09-29 write upload speed to upload directory
2008-09-17 fac: fixed bug locating FEXLIB
2008-09-12 fup: added config lib/fup.pl
2008-08-31 added fur (F*EX User (auto-) Registration)
2008-08-25 will die when no hostname is available
2008-08-21 added fexsend to htdocs/download
- fup: added ID mail sendback option
+2008-08-21 fup: added ID mail sendback option
2008-08-20 fac: added -l option
2008-08-19 fexsrv: fixed bug SSL handling
2008-08-15 fup,fuc,fexsrv: dynamic protocol detection (HTTP/HTTPS)
2008-08-14 fup: fixed bug login possible with wrong login data (but no upload)
2008-08-13 fup: showstatus terminates immediately when empty file was uploaded
- fup: showstatus shows error message on illegal recipient address
+2008-08-13 fup: showstatus shows error message on illegal recipient address
or when no file was uploaded
(nececessary for stupid Internet Explorer!)
2008-08-11 splitted debugfiles with time stamp in filename
- fex_cleanup: clean up aborted uploads, .ukeys/ and .debug/, too
- fexsend,fexget: allow more than one file (with all options)
+2008-08-11 fex_cleanup: clean up aborted uploads, .ukeys/ and .debug/, too
+2008-08-11 fexsend,fexget: allow more than one file (with all options)
2008-08-08 fup: eliminate superfluous newlines in logfile on error handling
- changed bareword filehandles to indirect filehandles
+2008-08-08 changed bareword filehandles to indirect filehandles
2008-08-06 fup: decode %NUMBERs in file names from POST
2008-08-02 fexsend: bug fix -A option and argument handling
2008-08-01 fup: regular users can change the recipient in the upload form,
sub users can not
2008-07-31 fup: fixed bug internet explorer not showing upload status window
- fup: fixed bug with id / special id / real id mixup
- fuc: nearly complete rewrite, better user interface
+2008-07-31 fup: fixed bug with id / special id / real id mixup
+2008-07-31 fuc: nearly complete rewrite, better user interface
2008-07-30 fup: fixed bug when account is a symlink
- fup: fixed bug in authentication of subusers
+2008-07-30 fup: fixed bug in authentication of subusers
2008-07-03 fop: workaround for Internet Explorer download bug
2008-07-02 fup,fop: switched default charset from ISO-8859-1 to UTF-8
- fup: uid for showstatus synchronization
+2008-07-02 fup: uid for showstatus synchronization
2008-06-21 fexget: downloading without wget, file number as argument
2008-06-20 fexget,fop: added DELETE option
- fexsend: send more files in one run
+2008-06-20 fexsend: send more files in one run
2008-05-30 added missing sex to distribution
- fexsend: added -A archiv to yourself option
+2008-05-30 fexsend: added -A archiv to yourself option
2008-05-28 fup: fixed bug in LIST and DELETE commands
2008-05-27 fexsrv: correct HTTP redirect on missing trailing / in URL
2008-05-26 sex,sexsend: better public mode
2008-05-24 sex,sexsend: added text mode option
2008-05-23 added missing foc and rup to distribution
2008-05-20 fexsend: fixed bug in list parsing (-l option)
- dop: fixed bug in file type determining on symbolic links
+2008-05-20 dop: fixed bug in file type determining on symbolic links
2008-05-15 fexsrv,dop: fixed bug in HTTP keep_alive multi-requests
2008-05-02 fexsrv,dop: support for HTTP keep_alive multi-requests
- fexsrv: more robust header parsing (ignore superfluous spaces)
+2008-05-02 fexsrv: more robust header parsing (ignore superfluous spaces)
2008-04-28 added support for HTTP keep_alive
- fexsrv: added SID (session ID) support
- fexsend: encrypt ID with MD5 and SID
+2008-04-28 fexsrv: added SID (session ID) support
+2008-04-28 fexsend: encrypt ID with MD5 and SID
2008-04-20 added foc and rup
- fop: return apropriate error message when file has been (auto)deleted
+2008-04-20 fop: return apropriate error message when file has been (auto)deleted
or is expired; error message is kept 3*keep_default days
2008-04-19 install: do not overwrite old fex.ph, but create fex.ph_new instead
2008-04-18 fup: fixed bug filename with path in notification email
2008-04-16 fexsrv,fop,dop: implemented HTTP HEAD
2008-04-14 renamed cgilaunch to fexsrv
- fup: do not send notify-mail if file already exists (overwrite mode)
- fup: do not accept file if authentication fails
- fup,fop,fexsend: new secure download URL scheme with random dkey
+2008-04-14 fup: do not send notify-mail if file already exists (overwrite mode)
+2008-04-14 fup: do not accept file if authentication fails
+2008-04-14 fup,fop,fexsend: new secure download URL scheme with random dkey
2008-04-11 fup: fixed bug in upload bar with 8-bit file names
- fex_cleanup: fixed bug not removing aborted uploads
+2008-04-11 fex_cleanup: fixed bug not removing aborted uploads
2008-04-10 added F*EX camel logo
2008-04-09 added dop (generic document output)
- install: better infos
+2008-04-09 install: better infos
2008-04-08 renamed confusing ID to auth-ID (request by chris@citecs.de)
- fuc: fixed bug with more than 1 sub-user
+2008-04-08 fuc: fixed bug with more than 1 sub-user
2008-04-07 fup: readded keep parameter (code got lost sometime?)
- fup: added sender restriction (ALLOWED_RECIPIENTS)
- fac: added restriction option -r and delete user option -d
+2008-04-07 fup: added sender restriction (ALLOWED_RECIPIENTS)
+2008-04-07 fac: added restriction option -r and delete user option -d
2008-04-06 fup: use Net::DNS instead of external host command
- fup: more debuglog, fixed wrong error messages
- added doc/concept doc/FAQ
+2008-04-06 fup: more debuglog, fixed wrong error messages
+2008-04-06 added doc/concept doc/FAQ
2008-04-02 install: better error handling (patch by chris@citecs.de)
- more docs and improved logging
+2008-04-02 more docs and improved logging
2008-04-01 cgilaunch: fixed bug in determing REMOTE_HOST when using stunnel
- fexget: added -s streaming option
- sex,sexsend: added public mode
+2008-04-01 fexget: added -s streaming option
+2008-04-01 sex,sexsend: added public mode
2008-03-31 changed project name to F*EX because of name collision with
http://freshmeat.net/projects/fex/
- added sex, sexsend and sexget to distribution
+2008-03-31 added sex, sexsend and sexget to distribution
2008-03-28 xx: changed syntax, now compatible to zz
- added zz to distribution
+2008-03-28 added zz to distribution
2008-03-27 fup: fixed bug in mail address verification
2008-03-24 fup,fexsend: show transfer rate in kB if filesize < 2 MB
- fup: code-cleanup, more comments
- fex.pp: umask 077
+2008-03-24 fup: code-cleanup, more comments
+2008-03-24 fex.pp: umask 077
2008-03-23 fup: fixed bug in using multiple recipients
2008-03-22 first public release
2007-01-27 first file fexed via fex.rus.uni-stuttgart.de
+2007-01-15 first file fexed via wwwtest6.belwue.de
2006-11-?? first code
# execute this as root!
# Redhat : stunnel-4 does not work! you need to install stunnel-5
+# Debian : stunnel-5.06 does not work! you need to install stunnel-5.18
mkdir /home/fex/etc
cd /home/fex/etc/
type = unlisted
protocol = tcp
port = 443
- cps = 5 10
+ cps = 10 2
user = fex
groups = yes
server = $stunnel
Important changes:
-- moved to new distribution site fex.belwue.de
-
-- autodelete=no if sender == recipient
-
-- no file name in email subject if notification is encrypted
-
-- added active and passive redirect support for standard HTTP documents
+- added fexit (Windows client) and macfexsend (MacOS client) support
- fixed various bugs
New features for users
----------------------
+2016-01-04:
+
+- new Windows client fexit
+
+- new MacOS client macfexsend
+
+
+
2015-01-12:
- user configuration: save-or-display (MIME) for download
-fex-20150826
+fex-20160104
+++ /dev/null
-<html>
-<head><title>F*EX FAQ</title></head>
-<body>
-
-## <pre>
-## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
-## </pre>
-
-<< require "./faq.pl" or print $! >>
-
-</body>
-</html>
--- /dev/null
+FAQ/index.html
\ No newline at end of file
Q: I cannot install a web server like fexsrv, because I have no root permissions. Is there a pure-CGI-version of F*EX which runs with an apache web server?
A: F*EX is hard bound to fexsrv for several reasons (performance, file size limit, session concept, etc) and cannot be run as CGI under apache. But you might have a look at
- * http://gpl.univ-avignon.fr/filez/
+ * https://github.com/FileZ/FileZ
* http://freshmeat.net/projects/eventh/
* http://www.schaarwaechter.de/sp/projekte/dateiaustausch.html (German only!)
* It is unknown how long they will exist - DropLoad and ALLPeers already have terminated their business.
Q: Why name "F*EX" and not shortly "FEX"?
-A: At publication time there was already an (older) program named "FEX" listed on freshmeat.net.
+A: At publication time there was already a program named "FEX" listed on freshmeat.net.
Q: Who is the author?
A: The main author is Ulli Horlacher <framstag@rus.uni-stuttgart.de><br>
- But there are also a lot of contributors.
+ But there are also a lot of contributors all around the world.
Q: Why a camel as the logo?
A: The logo was inspired by the Perl camel, but it is based on a Steiff plush camel, which rides with us on our racing tandem.
The logo was drawn by my stoker Beate.
- http://fex.belwue.de/Vortrag/tosa.html
+ http://fex.rus.uni-stuttgart.de/Vortrag/tosa.html
-Q: What do I need to install F*EX?
+Q: What do I need to install a F*EX server?
A: A UNIX or Windows server with a DNS entry, smtp for outgoing email and one open and free incoming tcp port.
You must have administrative rights (UNIX: root) on this server and a basic understanding of UNIX and networking.
Q: What means DNS and smtp? What is a tcp port?
A: Do not install F*EX. It is beyond your horizon.
-Q: Does F*EX support IPv6?
+Q: Does F*EX support IPv6 and SSL/TLS?
A: Yes.
Q: Can I run F*EX on Windows?
A: Contact <fex@nepustil.net> http://www.nepustil.net/ for F*EX hosting.
Q: The F*EX server is all in Perl?! Isn't Perl too slow for this job?
-A: fex.belwue.de runs on a PC and F*EX is able to handle uploads with more than 300 MB/s.
+A: F*EX is able to handle uploads with more than 300 MB/s on an office PC.
Try this with an ordinary webserver like Apache!
Q: Which licence does F*EX have? And why?
A: Perl Artistic free software with a special anti-military clause:
http://fex.belwue.de/doc/Licence
"I want peace on earth and goodwill towards men"
- http://www.youtube.com/watch?v=JHU0HinVhYc
+ https://www.youtube.com/watch?v=JHU0HinVhYc https://en.wikipedia.org/wiki/Sneakers_%281992_film%29
Q: Is there a F*EX mailing list?
A: https://listserv.uni-stuttgart.de/mailman/listinfo/fex
Q: Where can I get commercial support for F*EX?
A: Contact <fex@nepustil.net> http://www.nepustil.net/
+Q: How big is F*EX?
+A: Server: 400 kB, 11000 lines of code
+ Clients: 180 kB, 5500 lines of code
+ Documentation: 130 kB
+ Localizations: 250 kB
+
Q: Who else is using F*EX?
A: For example:
* German Aerospace Center http://fex.dlr.de
* Swiss National Supercomputing Centre http://fex.cscs.ch
* Centre National de la Recherche Scientifique (French National Center for Scientific Research) http://bigfiles.cnrs-gif.fr
* Institut Pasteur http://dl.pasteur.fr
+ * Justus Liebig University http://fex.hrz.uni-giessen.de
+ * Fiat Chrysler https://fex.fiatitem.com/
* Palo Alto Research Center (Xerox PARC) http://parcftp.parc.com
* Baden-Württembergs extended LAN http://fex.belwue.de
* Deutsche Kinemathek Museum für Film und Fernsehen http://upload.deutsche-kinemathek.de
Requested features are:
<ul>
<li>testers for MacOS, AIX and other UNIXes
- <li>a new maintainer for the Java client F*IX
<li>an Android or iOS client
+ <li>HTML5/websocket support
<li>a F*EX plugin for thunderbird or outlook
see thunderbird's filelink
https://support.mozillamessaging.com/en-US/kb/filelink-large-attachments
A: Register them as your subusers, create a F*EX group or a one-time upload key with "user config & operation control"
See also http://fex.belwue.de/usecases/foreign.html
+Q: I am not a user of your site. How can I send a file to a registered user?
+A: See question above: you must ask a regular user to register you as his subuser.
+ You will then get a specific upload URL from him.
+
Q: Sometimes I can download a file more than once, especially when I repeat it quickly. Is the autodelete feature buggy?
A: The F*EX server has a grace time of 1 minute after first sucessfully download in which the file is still available. This is necessary because of some stupid "download managers" which request the file several times at once. Otherwise they would report an error to the user.
A: An expired file is definitively deleted. Even the admin cannot restore it.
You must re-request it from the sender.
+Q: When I try to download a file again, I get the error message: "file has been autodeleted after download". Can you restore it?
+A: No. You must re-request it from the sender.
+
Q: I have sent a second file with the same name, but the recpient has not received a second notification email. Why?
A: A file with the same name to the same recpient overwrites the first one if it is still there (no download so far).
A second notification email of the same file(name) is not suggestive.
A: Use "!#!" as comment, then no notification email will be sent.
Of course you then have to inform the recipient manually.
+Q: Can I delete a file without downloading?
+A: Add "?DELETE" to your download URL.
+
Q: Can I get a copy of the notification email?
A: Add "!bcc!" to the comment field on upload.
our ($fexhome,$idf,$tmpdir,$windoof,$useragent);
our ($xv,%autoview);
our $bs = 2**16; # blocksize for tcp-reading and writing file
-our $version = 20150826;
+our $version = 20160104;
our $CTYPE = 'ISO-8859-1';
our $fexsend = $ENV{FEXSEND} || 'fexsend';
+our $DEBUG = $ENV{DEBUG};
my %SSL = (SSL_version => 'TLSv1');
my $sigpipe;
$SSL{SSL_verify_mode} = 0;
chdir $ENV{USERPROFILE}.'\Desktop';
# open XX,'>XXXXXX';close XX;
+} elsif ($Config{osname} =~ /^darwin/i or $ENV{MACOS}) {
+ $0 =~ s:(.*)/:: and $ENV{PATH} .= ":$1";
+ $fexhome = $ENV{FEXHOME} || $ENV{HOME}.'/.fex';
+ $tmpdir = $ENV{FEXTMP} || $ENV{TMPDIR} || "$fexhome/tmp";
+ $idf = "$fexhome/id";
+ $_ = `sw_vers -productVersion 2>/dev/null`||'';
+ chomp;
+ $useragent = "fexget-$version (MacOS $_)";
} else {
$0 =~ s:(.*)/:: and $ENV{PATH} .= ":$1";
$fexhome = $ENV{FEXHOME} || $ENV{HOME}.'/.fex';
}
}
-my ($file,%files,$download,$server,$port,$fop);
+my ($file,%files,$download,$server,$port,$fop,$https);
if ($opt_f) {
unless ($ENV{FEXID} or -f $ENV{HOME}.'/.fex/id') {
}
if ($url =~ m{^http(s?)://([\w\.\-]+)(:(\d+))?(/.*fop/\S+)}) {
+ $https = $1;
$server = $2;
$port = $4 || ($1?443:80);
$fop = $5;
if ($ENV{DISPLAY} and $download =~ /\.(gif|jpg|png|tiff?)$/i) {
# see also mimeopen and xdg-mime
+ # http://unix.stackexchange.com/questions/144047/how-does-xdg-open-do-its-work
if (my $xv = $xv || pathsearch('xv') || pathsearch('xdg-open')) {
printf "run \"%s %s\" [Yn] ? ",basename($xv),basename($download);
$_ = <STDIN>||'';
}
if ($download =~ /$atype/) {
- if ($download =~ /\.(tgz|tar.gz)$/) { extract('tar tvzf','tar xvzf') }
- elsif ($download =~ /\.tar$/) { extract('tar tvf','tar xvf') }
- elsif ($download =~ /\.zip$/i) { extract('unzip -l','unzip') }
- elsif ($download =~ /\.7z$/i) { extract('7z l','7z x') }
+ if ($download =~ /\.(tgz|tar.gz)$/) { extract('tar tvzf','tar xvzf') }
+ elsif ($download =~ /\.tar$/) { extract('tar tvf','tar xvf') }
+ elsif ($download =~ /\.zip$/i) { extract('unzip -l','unzip') }
+ elsif ($download =~ /\.7z$/i) { extract('7z l','7z x') }
else { die "$0: unknown archive \"$download\"\n" }
if ($? == 0) {
unlink $download;
my $l = shift;
my $x = shift;
my $d = $download;
- my $xd = '.';
+ my $xd = '';
local $_;
if (-t and not $windoof) {
system(split(' ',$l),$download);
$d =~ s:.*/:./:;
$d =~ s/\.[^.]+$//;
+ $d =~ s:/*$:/:;
for (;;) {
$xd = inquire("extract to directory (Ctrl-C to keep archive): ",$d);
- last if $xd =~ s:^(\./*)*!?$:./:;
+ last if $xd =~ s:^(\./*)*!?$::;
if ($xd eq '-') {
print "keeping $download\n";
exit;
last;
}
}
- print "extracting to $xd :\n";
+ print "extracting to $xd :\n" if $xd;
system(split(' ',$x),$download);
+ print "extracted to $xd\n" if $xd;
}
sub del {
sub forward {
my $url = shift;
my ($server,$port);
- my ($uri,$dkey,$list,$cmd,$n);
+ my ($uri,$dkey,$list,$cmd,$n,$copy);
my @r;
if ($url =~ m{^http(s?)://([\w\.\-]+)(:(\d+))?(/fop/.+)}) {
die "$0: no reply from fex server $server\n" unless $_;
warn "<-- $_" if $opt_v;
- unless (/^HTTP.*200/) {
+ if (/^HTTP.*already exists/) {
+ if ($uri =~ m:/fop/(\w+)/:) {
+ $dkey = $1;
+ }
+ } elsif (/^HTTP.*200/) {
+ # ok!
+ } else {
s/^HTTP.... \d+ //;
die "$0: $_";
}
warn "<-- $_" if $opt_v;
}
- $cmd = 'fexsend -l >/dev/null 2>&1';
- print "$cmd\n" if $opt_v;
+ print "fexsend -l\n" if $opt_v;
system 'fexsend -l >/dev/null 2>&1';
$list = $ENV{HOME}.'/.fex/tmp/fexlist';
open $list,$list or die "$0: cannot open $list - $!\n";
$pipe = $download = $opt_s;
} elsif (-p $opt_s or -c $opt_s) {
$download = $opt_s;
+ $nocheck = 'pipe or character device';
} else {
$download = $file.'.tmp';
$seek = -s $download || 0;
}
} else {
# ask server for real file name
- serverconnect($server, $port);
- sendheader("$server:$port","HEAD $proxy_prefix$fop HTTP/1.1","User-Agent: $useragent");
+ sendheader(
+ "$server:$port",
+ "HEAD $proxy_prefix$fop HTTP/1.1",
+ "User-Agent: $useragent"
+ );
my $reply = $_ = <$SH>;
unless (defined $_ and /\w/) {
die "$0: no response from server\n";
}
}
if ($checkstorage and not $nocheck) {
- $t0 = time;
+ my $t0 = my $t1 = my $t2 = time;
my $n = 0;
+ my $buf = '.' x M;
+ my $storagetest = $file.'.test';
+ my $error = "$0: cannot write \"$storagetest\"";
+ open $storagetest,'>',$storagetest or die "$error - $!\n";
print STDERR "checking storage...\r";
- $buf = '.' x M;
- while (-s $download < $checkstorage) {
- syswrite X,$buf or do {
- unlink $download;
- die "\n$0: cannot write $download - $!\n";
+ while (-s $storagetest < $checkstorage) {
+ syswrite $storagetest,$buf or do {
+ unlink $storagetest;
+ die "\n$error - $!\n";
};
$n++;
- print STDERR "checking storage... ".$n." MB\r";
+ $t2 = int(time);
+ if ($t2 > $t1) {
+ print STDERR "checking storage... ".$n." MB\r";
+ $t1 = $t2;
+ }
}
- close X or do {
- unlink $download;
- die "\n$0: cannot write $download - $!\n";
+ close $storagetest or do {
+ unlink $storagetest;
+ die "\n$error - $!\n";
};
print STDERR "checking storage... ".$n." MB ok!\n";
- unlink $download;
- if (time-$t0 < 25) {
- open X,'>',$download or die "$0: cannot write to \"$download\" - $!\n";
- } else {
+ unlink $storagetest;
+ if (time-$t0 > 25) {
# retry after timeout
+ serverconnect($server,$port);
return(download($server,$port,$fop,'nocheck'))
}
}
}
-sub quote {
- local $_ = shift;
- s/([^\w¡-ÿ_%\/=~:.,-])/\\$1/g;
- return $_;
-}
-
-
{
my $tty;
if (defined(&TIOCSTI) and $tty and open($tty,'>',$tty)) {
print $prompt;
+ # push default answer into keyboard buffer
foreach my $a (split("",$default)) { ioctl($tty,&TIOCSTI,$a) }
chomp($_ = <STDIN>||'');
} else {
- $prompt =~ s/([\?:=]\s*)/ [$default]$1/ or $prompt .= " [$default]";
+ $prompt =~ s/([\?:=]\s*)/ [$default]$1/ or $prompt .= " [$default] ";
print $prompt;
chomp($_ = <STDIN>||'');
$_ = $default unless length;
my $connect = "CONNECT $server:$port HTTP/1.1";
local $_;
- if ($opt_v and $port == 443 and %SSL) {
- foreach my $v (keys %SSL) {
- printf "%s => %s\n",$v,$SSL{$v};
- }
- }
-
if ($proxy) {
tcpconnect(split(':',$proxy));
- if ($port == 443) {
+ if ($https) {
printf "--> %s\n",$connect if $opt_v;
nvtsend($connect,"");
$_ = <$SH>;
unless (/^HTTP.1.. 200/) {
die "$0: proxy error : $_";
}
- eval "use IO::Socket::SSL";
- die "$0: cannot load IO::Socket::SSL\n" if $@;
+ &enable_ssl;
$SH = IO::Socket::SSL->start_SSL($SH,%SSL);
}
} else {
tcpconnect($server,$port);
}
-# if ($port == 443 and $opt_v) {
+# if ($https and $opt_v) {
# printf "%s\n",$SH->get_cipher();
# }
}
undef $SH;
}
- if ($port == 443) {
+ if ($https) {
# eval "use IO::Socket::SSL qw(debug3)";
- eval "use IO::Socket::SSL";
- die "$0: cannot load IO::Socket::SSL\n" if $@;
+ &enable_ssl;
$SH = IO::Socket::SSL->new(
PeerAddr => $server,
PeerPort => $port,
if ($SH) {
autoflush $SH 1;
+ binmode $SH;
} else {
die "$0: cannot connect $server:$port - $@\n";
}
}
+sub enable_ssl {
+ eval "use IO::Socket::SSL";
+ die "$0: cannot load IO::Socket::SSL\n" if $@;
+ eval '$SSL{SSL_verify_mode} = 0 if Net::SSLeay::SSLeay() <= 9470143';
+ if ($opt_v) {
+ foreach my $v (keys %SSL) {
+ printf "%s => %s\n",$v,$SSL{$v};
+ }
+ }
+}
+
+
sub sendheader {
my $sp = shift;
my @head = @_;
}
+sub quote {
+ local $_ = shift;
+ s/([^\w\@\/%^,.=+_:+-])/\\$1/g;
+ return $_;
+}
+
+
+sub debug {
+ print "## DEBUG: @_\n" if $DEBUG;
+}
+
+
# from MIME::Base64::Perl
sub encode_b64 {
my $res = "";
$| = 1;
-our ($SH,$fexhome,$idf,$tmpdir,$windoof,$useragent,$editor,$nomail);
+our ($SH,$fexhome,$idf,$tmpdir,$windoof,$macos,$useragent,$editor,$nomail);
our ($anonymous,$public);
our ($tpid,$frecipient);
our ($FEXID,$FEXXX,$HOME);
our (%alias);
our $chunksize = 0;
-our $version = 20150826;
+our $version = 20160104;
our $_0 = $0;
-our $DEBUG;
+our $DEBUG = $ENV{DEBUG};
my %SSL = (SSL_version => 'TLSv1');
my $sigpipe;
$useragent = sprintf("fexsend-$version (%s %s)",
$Config{osname},$Config{archname});
$SSL{SSL_verify_mode} = 0;
+} elsif ($Config{osname} =~ /^darwin/i or $ENV{MACOS}) {
+ $macos = $Config{osname};
+ # http://stackoverflow.com/questions/989349/running-a-command-in-a-new-mac-os-x-terminal-window
+ $HOME = (getpwuid($<))[7]||$ENV{HOME};
+ $fexhome = $HOME.'/.fex';
+ $tmpdir = $ENV{FEXTMP} || $ENV{TMPDIR} || "$fexhome/tmp";
+ $tmpdir =~ s:/$::;
+ $idf = "$fexhome/id";
+ chmod 0600,$idf;
+ $editor = $ENV{EDITOR} || 'open -W -n -e';
+ $_ = `sw_vers -productVersion 2>/dev/null`||'';
+ chomp;
+ $useragent = "fexsend-$version (MacOS $_)";
} else {
$0 =~ s:.*/::;
$HOME = (getpwuid($<))[7]||$ENV{HOME};
$fexhome = $HOME.'/.fex';
$tmpdir = $ENV{FEXTMP} || "$fexhome/tmp";
$idf = "$fexhome/id";
+ chmod 0600,$idf;
$editor = $ENV{EDITOR} || 'vi';
$_ = `(lsb_release -d||uname -a)2>/dev/null`||'';
chomp;
s/^Description:\s+//;
$useragent = "fexsend-$version ($_)";
- chmod 0600,$idf;
}
if (-f ($_ = '/etc/fex/config.pl')) {
my $timeout = 30; # server timeout
my $fexlist = "$tmpdir/fexlist";
my ($usage,$hints);
-my $xx = $0 =~ /^xx/;
+my $xx = $0 =~ /\bxx$/;
if ($xx) {
$usage = "usage: send file(s): xx [:slot] file...\n".
$usage = <<EOD;
usage: $0 [options] file(s) [@] recipient(s)
or: $0 [special options]
+ or: $0 -l [recipient-regexp]
or: $0 -f \# recipient(s)
or: $0 -x \# [-C -k -D -K -S]
options: -v verbose mode
-c compress file with gzip
-g encrypt file with gpg
-m limit limit throughput (kB/s)
- -i tag use ID data [tag] from ID file
+ -i account use ID data [account] from ID file
-C comment add comment to notification e-mail
-k max keep file max days on fex server
-D delay auto-delete after download
-o overwrite mode, do not resume
-a archive put files in archive (.zip .7z .tar .tgz)
-s stream read data from pipe and upload it with stream name
-special options: -I initialize ID file or show ID
- -I tag add alternate ID data (secondary logins) to ID file
- -l list sent files numbered (# needed for -f -x -d -N)
- -f \# forward already uploaded file to another recipient
- -x \# modify options -C -k -D -K for already uploaded file
- -d \# delete file on fex server
- -N \# resend notification e-mail
- -Q check quotas
- -A edit server address book (aliases)
- -S show server/user settings and auth-ID
- -H show hints, examples and more options
- -V show version
- (\# is a file number, see output from $0 -l)
+special options: -I initialize ID file or show ID
+ -I account add alternate ID data (secondary logins) to ID file
+ -l list sent files numbers (# needed for -f -x -d -N)
+ -f \# forward already uploaded file to another recipient
+ -x \# use -C -k -D -K for already uploaded file
+ -d \# delete file on fex server
+ -N \# resend notification e-mail
+ -Q check quotas
+ -A edit server address book (aliases)
+ -S show server/user settings and auth-ID
+ -H show hints, examples and more options
+ -V show version
+ (# is a file number, see output from $0 -l)
examples: $0 visualization.mpg framstag\@rus.uni-stuttgart.de
$0 -a images.zip *.jpg webmaster\@flupp.org,metoo
lshw | $0 -s hardware.list admin\@flupp.org
With option -s you can send any data coming from a pipe (STDIN) as a file
without wasting local disc space.
-With option -X you can specify any parameter, e.g.: -X autodelete=yes
+With option -X you can specify any URL parameter, e.g.:
+fexsend -X autodelete=yes ...
+fexsend -X 'autodelete=no&locale=german' ...
For HTTPS you can set the environment variables:
SSLVERIFY=1 # activate server identity verification
$_ = "$fexhome/config.pl"; require if -f;
getopts('hvIm:') or die $usage;
} else {
+ if ($macos and not @ARGV) {
+ &ask_file;
+ }
$opt_h = $opt_v = $opt_m = $opt_c = $opt_k = $opt_d = $opt_l = $opt_I = 0;
$opt_H = $opt_K = $opt_D = $opt_R = $opt_M = $opt_L = $opt_Q = $opt_A = 0;
$opt_x = $opt_o = $opt_g = $opt_V = $opt_U = $opt_F = $opt_n = $opt_q = 0;
elsif ($opt_A) { edit_address_book($from) }
elsif (${'opt_@'}) { &show_address_book }
elsif ($opt_d and $anonymous) { &purge }
-elsif ($opt_d and $ARGV[-1] =~ /^\d+$/) { &delete }
+elsif ($opt_d and $ARGV[-1] =~ /^\d+$/) { &delete_file_number }
else { &send_fex }
exit;
my ($fexcgi,$from,$id);
if (open $idf,$idf) {
$fexcgi = <$idf>;
+ # $fexcgi = <$idf> if $fexcgi =~ /^\[.+\]/;
$from = <$idf>;
$id = <$idf>;
while (<$idf>) {
sendheader("$fs:$port","GET $proxy_prefix/fur?user=$mail&verify=no HTTP/1.1");
http_response();
+ # header
while (<$SH>) {
s/\r//;
printf "<-- $_"if $opt_v;
}
+# menu for MacOS users
+sub menu {
+ my $key;
+ my $new;
+ local $_;
+
+ system 'clear';
+ print "\n";
+ print "fexsend-$version\n";
+
+ for (;;) {
+ if (open $idf,$idf) {
+ $fexcgi = getline($idf) and
+ $from = getline($idf) and
+ $id = getline($idf);
+ close $idf;
+ last if $id;
+ }
+ &set_ID;
+ }
+
+ print "\n";
+ print "$from on $fexcgi\n";
+ print "\n";
+
+ for (;;) {
+ print "\n";
+ print "[s] send a file or directory\n";
+ print "[u] update fexsend\n";
+ print "[l] change login data (user, server, auth-ID)\n";
+ print "[h] help\n";
+ print "[q] quit\n";
+ print "\n";
+ print "your choice: ";
+ $key = ReadKey(0);
+ if ($key eq 'q') {
+ print "$key\n";
+ print "\n";
+ print "Type [Cmd]W to close this window.\n";
+ exit;
+ }
+ if ($key eq 'h') {
+ print "$key\n";
+ print
+ "\n".
+ "With fexsend you can send files of any size to any e-mail address.\n".
+ "\n".
+ "At the recipient or file prompt [RETURN] brings you to this option menu.\n".
+ "\n".
+ "To send more than one file:\n".
+ "When you enter * at the file prompt, you will be first asked for an archive name\n".
+ "and then you can drag+drop multiple files.\n".
+ "\n".
+ "Do not forget to terminate each input line with [RETURN].\n".
+ "\n".
+ "See http://fex.rus.uni-stuttgart.de/ for more informations.\n";
+ next;
+ }
+ if ($key eq 'u') {
+ print "$key\n";
+ if ($0 =~ m:(^/client/|/sw/):) {
+ print "\n";
+ print "use swupdate to update fexsend!\n";
+ next;
+ }
+ $new = $0.'.new';
+ system "curl http://fex.belwue.de/download/fexsend>".quote($new);
+ chmod 0755,$new;
+ system qw'perl -c',$new;
+ if ($? == 0) {
+ rename $new,$0;
+ exec $0;
+ } else {
+ print "\n";
+ print "cannot install new fexsend\n";
+ }
+ next;
+ }
+ if ($key eq 'l') {
+ print "$key\n";
+ system 'clear';
+ &set_ID;
+ next;
+ }
+ if ($key eq 's' or $key eq "\n") {
+ print "s\n";
+ &ask_file;
+ next;
+ }
+ }
+ exit;
+}
+
+
+# for MacOS
+sub ask_file {
+ my ($file,$comment,$recipient,$archive,$size,$cmd,$key);
+ my @files;
+ my $qfiles;
+ local $_;
+
+ system 'clear';
+
+ &set_ID unless -s $idf;
+
+ print "\n";
+ print "Enter [RETURN] after each input line.\n";
+ print "\n";
+
+ for (;;) {
+ print "Recipient(s): ";
+ $recipient = <STDIN>;
+ chomp $recipient;
+ $recipient =~ s/^\s+//;
+ $recipient =~ s/\s+$//;
+ $recipient =~ s/[\s;,]+/,/g;
+ &menu unless $recipient;
+ last if $recipient =~ /\w/ or $recipient eq '.';
+ }
+
+ for (;;) {
+ print "\n";
+ print "Drag a file into this window or hit [RETURN] ";
+ print $archive ? "to continue.\n" : "for menu options.\n";
+ print "File to send: ";
+ $file = <STDIN>||'';
+ chomp $file;
+ $file =~ s/^\s+//;
+ $file =~ s/ $// if $file !~ /\\ $/;
+ &menu unless $file or $archive;
+ if ($file eq '*') {
+ print "Archive name: ";
+ $archive = <STDIN>||'';
+ chomp $archive;
+ next unless $archive;
+ $archive =~ s/^\s+//g;
+ $archive =~ s/\s+$//g;
+ $archive =~ s/[^\w=.+-]/_/g;
+ next;
+ }
+ if ($file) {
+ unless (-e $file) {
+ $file =~ s/\\\\/\000/g;
+ $file =~ s/\\//g;
+ $file =~ s/\000/\\/g;
+ }
+ unless (-r $file) {
+ print "\"$file\" is not readable\n";
+ next;
+ }
+ my $qf = quote($file);
+ if (`du -ms $qf` =~ /^(\d+)/) {
+ $size += $1;
+ printf "%d MB\n",$1;
+ }
+ if ($archive) {
+ push @files,$file;
+ next;
+ }
+ }
+ if ($archive) {
+ next unless @files;
+ $qfiles = join(' ',map(quote($_),@files));
+ if ($size < 2048) {
+ $archive .= '.zip';
+ } else {
+ $archive .= '.tar';
+ }
+ }
+ print "\n";
+ print "Comment: ";
+ $comment = <STDIN>||'';
+ chomp $comment;
+ print "\n";
+ if ($comment =~ s/^:\s*-/-/) {
+ $cmd = quote($0)." $comment ";
+ if ($archive) {
+ $cmd .= '-a '.quote($archive).' '.$qfiles;
+ } else {
+ $cmd .= quote($file);
+ }
+ $cmd .= ' '.quote($recipient);
+ print $cmd,"\n";
+ system $cmd;
+ } else {
+ print quote($0)." -C '$comment' ";
+ if ($archive) {
+ printf "-a %s %s %s\n",quote($archive),$qfiles,$recipient;
+ system $0,'-C',$comment,'-a',$archive,@files,$recipient;
+ } else {
+ printf "%s %s\n",quote($file),$recipient;
+ system $0,'-C',$comment,$file,$recipient;
+ }
+ }
+ print "\n";
+ print "[s] send another file to $recipient\n";
+ print "[n] send another file to another recipient\n";
+ print "[q] quit\n";
+ print "\n";
+ print "your choice: ";
+ for (;;) {
+ $key = ReadKey(0);
+ &ask_file if $key eq 'n';
+ if ($key eq 's' or $key eq "\n") {
+ print "s\n";
+ last;
+ }
+ if ($key eq 'q') {
+ print "$key\n";
+ exit;
+ }
+ }
+ $file = $comment = $archive = '';
+ @files = ();
+ }
+}
+
+
+sub set_ID {
+ my ($server,$port,$user,$logo);
+ local $_;
+
+ print "\n";
+ for (;;) {
+ print "F*EX server URL: ";
+ $server = <STDIN>;
+ $server =~ s/[\s\n]//g;
+ if ($server =~ s:/fup/(\w+)$::) {
+ $_ = decode_b64($1);
+ if (/(from|user)=(.+)&id=(.+)/) {
+ $user = $2;
+ $id = $3;
+ }
+ }
+ $server =~ s:/fup.*::;
+ $server =~ s:/+$::;
+ next if $server !~ /\w/;
+ if ($server =~ s/^https:..// or $server =~ /:443/) {
+ $server =~ s/:.*//;
+ $port = 443;
+ eval "use IO::Socket::SSL";
+ if ($@) {
+ print "\nno perl SSL modules installed - cannot use https\n\n";
+ next;
+ }
+ $SH = IO::Socket::SSL->new(
+ PeerAddr => $server,
+ PeerPort => $port,
+ Proto => 'tcp',
+ %SSL
+ );
+ } else {
+ $server =~ s:^http.//::;
+ if ($server =~ s/:(\d+)//) {
+ $port = $1;
+ } else {
+ $port = 80;
+ }
+ $SH = IO::Socket::INET->new(
+ PeerAddr => $server,
+ PeerPort => $port,
+ Proto => 'tcp',
+ );
+ }
+ unless ($SH) {
+ print "\ncannot connect to $server:$port - $!\n\n";
+ next;
+ }
+ sendheader(
+ "$server:$port",
+ "GET /logo.jpg HTTP/1.0",
+ "User-Agent: $useragent",
+ "Connection: close",
+ );
+ $_ = <$SH>||'';
+ unless (/HTTP.1.1 200/) {
+ print "\nbad server reply: $_\n";
+ next;
+ }
+ while (<$SH>) { last if /^\s*$/ }
+ local $/;
+ $logo = <$SH>||'';
+ close $SH;
+ if (length $logo < 9999) {
+ print "\n$server is not a F*EX server!\n\n";
+ next;
+ }
+ open $logo,">$tmpdir/fex.jpg";
+ print {$logo} $logo;
+ close $logo;
+ last;
+ }
+
+ for (;;) {
+ last if $user;
+ print "Your login (e-mail address): ";
+ $user = <STDIN>;
+ $user =~ s/[\s\n]//g;
+ if ($user !~ /.@[\w.-]+$/) {
+ print "\"$user\" is not a valid e-mail address!\n";
+ next;
+ }
+ }
+
+ for (;;) {
+ last if $id;
+ print "Your auth-ID for this account: ";
+ $id = <STDIN>;
+ $id =~ s/[\s\n]//g;
+ }
+
+ open $idf,'>',$idf or die "$0: cannot write to $idf - $!\n";
+ print {$idf} "$server\n",
+ "$user\n",
+ "$id\n";
+ close $idf;
+ print "\n";
+ print "Login data written to $idf\n\n";
+ print "fexing test file to $user:\n\n";
+ system "$0 -o -M -C test $tmpdir/fex.jpg $user";
+ print "\n";
+ if ($? != 0) {
+ print "fexsend failed, login data is invalid, try again\n";
+ &set_ID;
+ } else {
+ print "fexsend test succeeded!\n";
+ sleep 3;
+ }
+}
+
+
+# read one key from terminal in raw mode
+sub ReadKey {
+ my $key;
+ local $SIG{INT} = sub { stty('reset'); exit };
+
+ stty('raw');
+ # loop necessary for ESXi support
+ while (not defined $key) {
+ $key = getc(STDIN);
+ }
+ stty('reset');
+ return $key;
+}
+
+
+sub stty {
+ if (shift eq 'raw') {
+ system qw'stty -echo -icanon eol',"\001";
+ } else {
+ system qw'stty echo icanon eol',"\000";
+ }
+}
+
+
sub send_xx {
my $transferfile = shift;
my $file = '';
- my (@r,@tar);
+ my (@r,@tar,$dir);
$SIG{PIPE} = $SIG{INT} = sub {
unlink $transferfile;
print "making tar transfer file $transferfile :\n";
# single file? then add this directly
if (scalar @ARGV == 1) {
- my ($dir,$file);
# strip path if not ending with /
if ($ARGV[0] =~ m:(.+)/(.+): and $2 !~ m:/$:) {
($dir,$file) = ($1,$2);
# list spool
sub list {
my (@r,$r);
- my ($data,$dkey,$n);
+ my ($data,$dkey);
+ my $n = 0;
+ my $s = 1;
+ my $a = shift @ARGV || '.';
local $_;
female_mode("list spooled files?") if $opt_F;
- if ($opt_l and $n = shift @ARGV and $n =~ /^\d+$/) {
- open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
- while (<$fexlist>) {
- if (/^\s*(\d+)\) (\w+) (.+)/ and $1 eq $n) {
- serverconnect($server,$port) unless $SH;
- sendheader(
- "$server:$port",
- "GET $proxy_prefix/fop/$2/$2?LIST HTTP/1.1",
- "User-Agent: $useragent",
- );
- $_ = <$SH>||'';
- s/\r//;
- print "<-- $_" if $opt_v;
- if (/^HTTP.* 200/) {
+ if ($opt_l) {
+ if ($a =~ /^\d+$/) {
+ open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
+ while (<$fexlist>) {
+ if (/^\s*(\d+)\) (\w+) (.+)/ and $1 eq $a) {
+ serverconnect($server,$port) unless $SH;
+ sendheader(
+ "$server:$port",
+ "GET $proxy_prefix/fop/$2/$2?LIST HTTP/1.1",
+ "User-Agent: $useragent",
+ );
+ $_ = <$SH>||'';
+ s/\r//;
print "<-- $_" if $opt_v;
- while (<$SH>) {
- s/\r//;
- if (/^\n/) {
- print;
- print while <$SH>;
+ if (/^HTTP.* 200/) {
+ print "<-- $_" if $opt_v;
+ while (<$SH>) {
+ s/\r//;
+ if (/^\n/) {
+ print;
+ print while <$SH>;
+ }
}
+ } elsif (s:HTTP/[\d\. ]+::) {
+ die "$0: server response: $_";
+ } else {
+ die "$0: no response from fex server $server\n";
}
- } elsif (s:HTTP/[\d\. ]+::) {
- die "$0: server response: $_";
- } else {
- die "$0: no response from fex server $server\n";
+ exit;
}
- exit;
}
+ die "$0: file \#$a not found in fexlist\n";
}
- die "$0: file \#$n not found in fexlist\n";
- } else {
- @r = formdatapost(
- from => $from,
- to => $opt_l ? '*' : $from,
- command => $opt_C,
- );
}
+
+ @r = formdatapost(
+ from => $from,
+ to => $opt_l ? '*' : $from,
+ command => $opt_C,
+ );
die "$0: no response from fex server $server\n" unless @r;
$_ = shift @r;
unless (/^HTTP.* 200/) {
s/&/&/g;
s/"/\"/g;
s/</</g;
- if (/^(to .* :)/) {
- print "\n$1\n";
- print {$fexlist} "\n$1\n";
+ if (/^(to (.+) :)/) {
+ $s = $2 =~ /$a/;
+ print "\n$_\n" if $s;
+ print {$fexlist} "\n$_\n";
} elsif (m/(\d+) MB (.+)/) {
$n++;
- printf "%4s) %8d MB %s\n","#$n",$1,$2;
+ printf "%4s) %8d MB %s\n","#$n",$1,$2 if $s;
printf {$fexlist} "%3d) %s %s\n",$n,$dkey,$2;
}
}
}
-sub delete {
+sub delete_file_number {
my ($to,$file);
while (@ARGV) {
$opt_d = shift @ARGV;
- die "$usage: $0 -d #\n" if $opt_d !~ /^\d+$/;
+ die "usage: $0 -d #\n" if $opt_d !~ /^\d+$/;
open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
while (<$fexlist>) {
}
+sub delete_file {
+ my ($from,$to,$file) = @_;
+ local $_;
+
+ unless ($SH) {
+ serverconnect($server,$port);
+ query_sid($server,$port) unless $anonymous;
+ }
+
+ $file = urlencode($file);
+ sendheader(
+ "$server:$port",
+ "GET $proxy_prefix/fop/$to/$from/$file?id=$sid&DELETE HTTP/1.1",
+ "User-Agent: $useragent",
+ );
+
+ while (<$SH>) {
+ s/\r//;
+ printf "<-- $_"if $opt_v;
+ last if /^\s*$/;
+ }
+}
+
+
+sub urlencode {
+ local $_ = shift;
+ s/([^_=:,;<>()+.\w\-])/'%'.uc(unpack("H2",$1))/ge;
+ return $_;
+}
+
+
sub send_fex {
my @to;
my $file = '';
if ($anonymous) {
my $aok;
- sendheader("$server:$port","OPTIONS FEX HTTP/1.1");
+ sendheader("$server:$port","OPTIONS /FEX HTTP/1.1");
$_ = <$SH>||'';
s/\r//;
die "$0: no response from fex server $server\n" unless $_;
}
if (@ARGV > 1 and not ($opt_a or $opt_s or $opt_d)) {
- print "Archive name (name.tar, name.tgz or name.zip) or [ENTER] to send file for file:\n";
+ print "Archive name (name.tar, name.tgz or name.zip) or [RETURN] to send file for file:\n";
$opt_a = <STDIN>;
$opt_a =~ s/^\s+//;
$opt_a =~ s/\s+$//;
+ $opt_a =~ s/\//_/g;
+ }
+
+ if ($macos and not $opt_a and -d "@ARGV") {
+ my $dir = "@ARGV";
+ my $qdir = quote($dir);
+ if (`du -s $qdir` =~ /^(\d+)/ and $1 < 2**21) {
+ $opt_a = "$dir.zip";
+ } else {
+ $opt_a = "$dir.tar";
+ }
}
if ($opt_s) {
$opt_a =~ s:.*/::g;
}
foreach my $file (@ARGV) {
- die "$0: cannot read $file\n" unless -l $file or -r $file;
+ die "$0: cannot read \"$file\"\n" unless -l $file or -r $file;
}
$opt_a .= ".$atype" if $opt_a !~ /\.$atype$/;
$transferfile = "$tmpdir/$opt_a";
# else { system(qw'7z a -tzip -mm=copy',$transferfile,@ARGV) }
system(qw'7z a -tzip',$transferfile,@ARGV);
@files = ($transferfile);
+ } elsif ($macos and scalar(@ARGV) == 1) {
+ ## ditto-zip is now handled by formdatapost()
+ system 'true';
+ @files = ($opt_a);
} else {
# zip archives must be < 2 GB, so split as necessary
@files = zipsplit($transferfile,@ARGV);
} else {
## tar is now handled by formdatapost()
# system(qw'tar cvf',$transferfile,@ARGV);
+ system 'true';
@files = ($opt_a);
}
} elsif ($atype eq 'tgz') {
unless ($opt_d) {
unless (-f $file) {
if (-e $file) {
- die "$0: $file is not a regular file, try option -a\n"
+ die "$0: \"$file\" is not a regular file, try option -a\n"
} else {
- die "$0: $file does not exist\n";
+ die "$0: \"$file\" does not exist\n";
}
}
- die "$0: cannot read $file\n" unless -r $file;
+ die "$0: cannot read \"$file\"\n" unless -r $file;
}
push @files,$file;
}
foreach my $file (@files) {
my @s = stat($file);
unless (@s and ($s[2] & S_IROTH) and -r $file) {
- die "$0: $file is not world readable\n";
+ die "$0: \"$file\" is not world readable\n";
}
}
}
foreach my $file (@files) {
sleep 1; # do not overrun server!
unless (-s $file or $opt_d or $opt_a or $opt_s) {
- die "$0: cannot send empty file $file\n";
+ die "$0: cannot send empty file \"$file\"\n";
}
female_mode("send file $file?") if $opt_F;
@r = formdatapost(
if (not @r or not grep /\w/,@r) {
die "$0: no response from server\n";
}
+ next if "@r" eq '0'; # already transfered
if (($r) = grep /^ERROR:/,@r) {
if ($anonymous and $r =~ /purge it/) {
die "$0: file is already on server for $to - use another anonymous recipent\n";
+ } elsif ($r =~ /timeout/i) {
+ close $SH;
+ retry("timed out");
} else {
$r =~ s/.*?:\s*//;
$r =~ s/<.+?>//g;
die "$0: server error: $r\n";
}
}
+ unless ($opt_d) {
+ if (scalar(@r) == 1) {
+ die "$0: server error: @r\n";
+ } else {
+ if ($r[0] !~ /HTTP.1.. 2/) {
+ if ($r[0] =~ /HTTP.[\s\d.]+(.+)/) {
+ die "$0: server error: $1\n";
+ } else {
+ die "$0: server error:\n".join("\n",@r)."\n";
+ }
+ }
+ }
+ }
if (($r) = grep /<h3>\Q$file/,@r) {
$r =~ s/<.+?>//g;
print "$r\n";
if ($opt_a !~ /^afex_\d+\.tar$/ and $file !~ /afex_\d+\.tar$/) {
# print grep({s/^(X-Recipient:.*\((.+)\))/Parameters: $2\n/i} @r);
my $nonot = 0;
- my ($recipient,$location);
+ my $recipient = '';
+ my $location = '';
foreach (@r) {
if (/^(X-)?(Recipient.*)/i) {
$recipient = $2;
}
if (/^(X-)?(Location.*)/i) {
$location = $2;
- if ($from eq $to or $from =~ /^\Q$to\E@/i
- or $nomail or $anonymous or $nonot) {
- print "$recipient\n";
- print "$location\n";
- }
}
}
- unless ($opt_d or $location) {
- if (scalar(@r) == 1) {
- die "$0: server error: @r\n";
- } else {
- if ($r[0] !~ /HTTP.1.. 2/ and $r[0] =~ /HTTP.[\s\d.]+(.+)/) {
- die "$0: server error: $1\n";
- } else {
- die "$0: server error:\n".join("\n",@r)."\n";
- }
- }
+ if ($from eq $to or $from =~ /^\Q$to\E@/i
+ or $nomail or $anonymous or $nonot)
+ {
+ print "$recipient\n" if $recipient;
+ print "$location\n" if $location;
}
}
}
open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
while (<$fexlist>) {
- if (/^\s*(\d+)\) (\w+) \[\d+ d\] (.+)/ and $1 eq $opt_f) {
+ if (/^\s*(\d+)\) (\w+) .\s*\d+ d. ([+-] )?(.+)/ and $1 eq $opt_f) {
$n = $1;
$dkey = $2;
- $file = $3;
+ $file = $4;
if ($file =~ s/ "(.*)"$//) {
$opt_C ||= $1 if $1 ne 'NOMAIL';
}
open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
while (<$fexlist>) {
- if (/^\s*(\d+)\) (\w+) \[\d+ d\] (.+)/ and $1 eq $opt_N) {
+ if (/^\s*(\d+)\) (\w+) .\s*\d+ d. (.+)/ and $1 eq $opt_N) {
$n = $1;
$dkey = $2;
last;
open $fexlist,$fexlist or die "$0: $fexlist - $!\n";
while (<$fexlist>) {
- if (/^\s*(\d+)\) (\w+) \[\d+ d\] (.+)/ and $1 eq $opt_x) {
+ if (/^\s*(\d+)\) (\w+) .\s*\d+ d. (.+)/ and $1 eq $opt_x) {
$n = $1;
$dkey = $2;
$file = $3;
sub formdatapost {
my %P = @_;
- my ($boundary,$filename,$filesize,$length,$buf,$file,$fpsize,$resume,$seek);
+ my ($boundary,$filename,$length,$buf,$file,$fpsize,$resume,$seek);
my ($flink);
my (@hh,@hb,@r,@pv,$to);
my ($bytes,$t,$bt);
my $bs = 2**16; # blocksize for reading and sending file
my $fileid = int(time);
my $chunk = 0;
+ my $filesize = 0;
my $connection = '';
my $pct = '';
- my ($tar,$aname,$atype,$tarlist,$tarerror,$location,$transferfile);
+ my $dittodir = '.';
+ my ($tar,$ditto,$aname,$atype,$list,$error,$location,$transferfile);
local $_;
if (defined($file = $P{file})) {
$of =~ s/([^_\w\.\-])/\\$1/g;
shelldo("gzip <$if>$of");
$filesize = -s $transferfile;
- die "$0: cannot gzip $file\n" unless $filesize;
+ die "$0: cannot gzip \"$file\"\n" unless $filesize;
$file = $transferfile;
}
if (not $windoof and $opt_a and $file =~ /(.+)\.(tar|tgz)$/) {
$aname = $1;
$atype = $2;
- $tarlist = "$tmpdir/$aname.list";
- $tarerror = "$tmpdir/$aname.error";
+ $list = "$tmpdir/$aname.list";
+ $error = "$tmpdir/$aname.error";
$tar = 'tar -cv';
$tar .= 'z' if $atype eq 'tgz';
if (`tar --help 2>/dev/null` =~ /--index-file/) {
- $tar .= " --index-file=$tarlist -f-";
+ $tar .= " --index-file=$list -f-";
} else {
$tar .= " -f-";
}
}
}
foreach (@ARGV) {
- $file = $_;
- $file =~ s/([^\w\-\@\#%,.=+~_:])/\\$1/g;
- $tar .= ' '.$file;
+ $tar .= ' '.quote($_);
}
# print "calculating archive size... ";
- open $tar,"$tar 2>$tarerror|" or die "$0: cannot run tar - $!\n";
+ open $tar,"$tar 2>$error|" or die "$0: cannot run tar - $!\n";
$t0 = int(time) if -t STDOUT;
while ($b = read $tar,$_,$bs) {
$filesize += $b;
printf "Archive size: %d MB\n",int($filesize/M) if -t STDOUT;
unless (close $tar) {
$_ = '';
- if (open $tarerror,$tarerror) {
+ if (open $error,$error) {
local $/;
- $_ = <$tarerror>;
- close $tarerror;
+ $_ = <$error>;
+ close $error;
}
- unlink $tarlist,$tarerror;
+ unlink $list,$error;
die "$0: tar error:\n$_";
}
$file = "$aname.$atype";
undef $SH; # force reconnect (timeout!)
}
+ # special file: ditto-zip-on-the-fly
+ # ditto: Can't archive multiple sources
+ elsif ($macos and $opt_a and $file =~ /(.+)\.(zip)$/ and scalar(@ARGV) == 1) {
+ $aname = $1;
+ $atype = $2;
+ $list = "$tmpdir/$aname.list";
+ $error = "$tmpdir/$aname.error";
+ $ditto = 'ditto -c -k --sequesterRsrc --keepParent';
+ if (-d "@ARGV" and "@ARGV" =~ m:^(.+)/(.+):) {
+ $dittodir = $1;
+ $file = $2;
+ $file =~ s/([^\w\-\@\#%,.=+_:])/\\$1/g;
+ $ditto .= ' '.$file;
+ } else {
+ foreach (@ARGV) {
+ $file = $_;
+ $file =~ s/([^\w\-\@\#%,.=+_:])/\\$1/g;
+ $ditto .= ' '.$file;
+ }
+ }
+ # print "calculating archive size... ";
+ debug("cd $dittodir;$ditto -");
+ open $ditto,"cd $dittodir;$ditto - 2>$error|"
+ or die "$0: cannot run ditto - $!\n";
+ $t0 = int(time) if -t STDOUT;
+ while ($b = read $ditto,$_,$bs) {
+ $filesize += $b;
+ if ($t0) {
+ $t1 = int(time);
+ if ($t1>$t0) {
+ printf "Archive size: %d MB\r",int($filesize/M);
+ $t0 = $t1;
+ }
+ }
+ }
+ printf "Archive size: %d MB\n",int($filesize/M) if -t STDOUT;
+ unless (close $ditto) {
+ $_ = '';
+ if (-s $error and open $error,$error) {
+ local $/;
+ $_ = <$error>;
+ close $error;
+ }
+ unlink $list,$error;
+ die "$0: ditto-zip error:\n$_";
+ }
+ unlink $list,$error;
+ $file = "$aname.$atype";
+ $filename = encode_utf8($file);
+ undef $SH; # force reconnect (timeout!)
+ }
+
# single file
else {
$filename = encode_utf8(${'opt_='} || $file);
if ($opt_d) {
$filesize = 0;
} elsif (not $opt_g and not $opt_s) {
- $filesize = -s $file or die "$0: $file is empty or not readable\n";
+ $filesize = -s $file or die "$0: \"$file\" is empty or not readable\n";
}
}
$P{id} = $sid; # ugly hack!
+ $filename =~ s/\\/_/g; # \ is a illegal character for fexsrv
+
# ask server if this file has been already sent
- if ($file and not $xx and not
- ($opt_s or $opt_g or $opt_o or $opt_d or $opt_l or $opt_L or ${'opt_/'}))
- {
- ($seek,$location) = query_file($server,$port,$frecipient||$P{to},$P{from},
- $P{id},$filename,$fileid);
- if ($filesize == $seek) {
- print "Location: $location\n" if $location and $nomail;
- warn "$0: $file has been already transferred\n";
- return $file;
- } elsif ($seek and $seek < $filesize) {
- $resume = " (resuming at byte $seek)";
- } elsif ($filesize <= $seek) {
- $seek = 0;
+ if ($file and not $xx) {
+ if (not $opt_d and $opt_o) {
+ # delete before overwrite
+ delete_file($from,$to,$filename);
+ serverconnect($server,$port);
+ query_sid($server,$port) unless $anonymous;
+ $P{id} = $sid; # ugly hack!
+ } elsif (not($opt_s or $opt_g or $opt_d or $opt_l or $opt_L or ${'opt_/'})) {
+ ($seek,$location) = query_file($server,$port,
+ $frecipient||$P{to},$P{from},$P{id},$filename,$fileid);
+ if ($filesize == $seek) {
+ print "Location: $location\n" if $location and $nomail;
+ warn "$0: $file has been already transferred\n";
+ return 0;
+ } elsif ($seek and $seek < $filesize) {
+ $resume = " (resuming at byte $seek)";
+ } elsif ($filesize <= $seek) {
+ $seek = 0;
+ }
}
if ($proxy) {
sleep 1; # do not overrun proxy
push @hb,"--$boundary";
push @hb,"Content-Disposition: form-data; name=\"$name\"";
push @hb,"";
- push @hb,encode_utf8($P{$v});
+ # push @hb,encode_utf8($P{$v});
+ push @hb,$P{$v};
}
}
$tpid = fork();
if (defined $tpid and $tpid == 0) {
sleep 1;
- if (open $tarlist,$tarlist) {
- # print "\n$tar|\n"; system "ls -l $tarlist";
- while ($tarlist) {
- while (<$tarlist>) {
+ if (open $list,$list) {
+ # print "\n$tar|\n"; system "ls -l $list";
+ while ($list) {
+ while (<$list>) {
print ' 'x(length($file)+40),"\r",$_;
}
sleep 1;
print "Fast forward to byte $seek (resuming)\n";
readahead($file,$seek);
}
+ } elsif ($ditto) {
+ $ditto =~ s/ditto/ditto -V/;
+ open $file,"cd $dittodir;$ditto -|" or die "$0: cannot run ditto - $!\n";
+ if ($seek) {
+ print "Fast forward to byte $seek (resuming)\n";
+ readahead($file,$seek);
+ }
} else {
if ($opt_g) {
- my $fileq = $file;
- $fileq =~ s/([^\w\-\@\#%,.=+~_:])/\\$1/g;
+ my $fileq = quote($file);
open $file,"gpg -e -r $to <$fileq|" or die "$0: cannot run gpg - $!\n";
} else {
- open $file,$file or die "$0: cannot read $file - $!\n";
+ open $file,$file or die "$0: cannot read \"$file\" - $!\n";
seek $file,$seek,0;
}
binmode $file;
alarm(0);
$bytes += $b;
if ($filesize > 0 and $bytes+$seek > $filesize) {
- die "$0: $file filesize has grown while uploading\n";
+ if ($tpid) {
+ kill 9,$tpid;
+ unlink $list;
+ }
+ die "$0: \"$file\" filesize has grown while uploading\n";
}
$bt += $b;
$t2 = time;
if ($tpid) {
sleep 2;
kill 9,$tpid;
- unlink $tarlist;
+ unlink $list;
}
-
+
+ if ($fileid =~ /[a-z]/ and not ($opt_s or $opt_g)) {
+ if ($opt_a) {
+ if ($fileid ne md5_hex(fmd(@ARGV))) {
+ print "\n" unless $opt_q;
+ die "$0: files have been modified while uploading\n";
+ }
+ } else {
+ if ($fileid ne fileid($file)) {
+ print "\n" unless $opt_q;
+ die "$0: file has been modified while uploading\n";
+ }
+ }
+ }
+
unless ($opt_q) {
if (not $chunksize and $bytes+$seek < $filesize) {
- die "$0: $file filesize has shrunk while uploading\n";
+ die "$0: \"$file\" filesize has shrunk while uploading\n";
}
if ($seek or $chunksize and $chunksize < $filesize) {
$size = -s $file;
if ($size > 2147480000) {
unlink @zipfiles;
- die "$0: $file too big for zip\n";
+ die "$0: \"$file\" too big for zip\n";
}
if ($zsize + $size > 2147000000) {
push @zipfiles,zip($zipbase.'_'.$n.'.zip',@files);
my $seek = 0;
my $qfileid = '';
my ($head,$location);
- my ($response,$fexsrv);
+ my ($response,$fexsrv,$cc);
local $_;
$to =~ s/,.*//;
if (/^X-File-ID:\s+(.+)/) { $qfileid = $1 }
if (/^X-Features:\s+(.+)/) { $features = $1 }
if (/^X-Location:\s+(.+)/) { $location = $1 }
+ if (/^Connection: close/) { $cc = $_ }
}
# return true seek only if file is identified
$seek = 0 if $qfileid and $qfileid ne $fileid;
+ if ($cc) {
+ serverconnect($server,$port);
+ $sid = $id;
+ }
+
return ($seek,$location);
}
print {$ab} $AB{ADDRESS_BOOK};
close $ab;
- system $editor,$ab;
+ system "$editor $ab";
exit unless -s $ab;
$opt_o = $opt_A;
$sid = $id;
- if ($port eq 443) {
+ if ($port eq 443 or $proxy) {
return if $features; # early return if we know enough
- $req = "OPTIONS FEX HTTP/1.1";
- } elsif ($proxy) {
- return if $features; # early return if we know enough
- $req = "GET $proxy_prefix/SID HTTP/1.1";
+ $req = "OPTIONS /FEX HTTP/1.1";
+ $req = "HEAD / HTTP/1.1";
} else {
- $req = "GET SID HTTP/1.1";
+ $req = "GET /SID HTTP/1.1";
}
sendheader("$server:$port",$req,"User-Agent: $useragent");
s/\r//;
print "<-- $_" if $opt_v;
- if (/^HTTP.* [25]0[01] /) {
+ if ($req =~ /OPTIONS/ and /^HTTP.* 502 /) {
+ # (reverse) proxy error
+ close $SH;
+ serverconnect($server,$port);
+ $req = "GET /SID HTTP/1.0";
+ sendheader("$server:$port",$req,"User-Agent: $useragent");
+ $_ = <$SH>;
+ unless (defined $_ and /\w/) {
+ print "\n" if $opt_v;
+ die "$0: no response from server\n";
+ }
+ s/\r//;
+ print "<-- $_" if $opt_v;
+ while (<$SH>) {
+ s/\r//;
+ print "<-- $_" if $opt_v;
+ $features = $1 if /^X-Features: (.+)/;
+ $timeout = $1 if /^X-Timeout: (\d+)/;
+ last if /^\n/;
+ }
+ close $SH;
+ serverconnect($server,$port);
+ } elsif (/^HTTP.* [25]0[01] /) {
if (not $proxy and $port ne 443 and /^HTTP.* 201 (.+)/) {
$sid = 'MD5H:'.md5_hex($id.$1);
}
+ my $cc;
while (<$SH>) {
s/\r//;
print "<-- $_" if $opt_v;
$features = $1 if /^X-Features: (.+)/;
$timeout = $1 if /^X-Timeout: (\d+)/;
- last if /^\n/;
+ $cc = $_ if /^Connection: close/;
+ last if /^\n/;
+ }
+ if ($cc) {
+ serverconnect($server,$port);
+ $sid = $id;
}
} elsif (/^HTTP.* 301 /) {
while (<$SH>) { last if /Location/ }
die "$0: no Content-Length in server-reply\n" unless $cl;
- open F,">$save" or die "$0: cannot write to $save - $!\n";
- binmode F;
+ open $save,">$save" or die "$0: cannot write to $save - $!\n";
+ binmode $save;
$t0 = $t1 = int(time);
$tso = '';
while ($b = read($SH,$_,$bs)) {
$B += $b;
- print F;
+ print {$save} $_;
if (int(time) > $t1) {
$t1 = int(time);
$ts = ts($B,$cl);
}
print STDERR ts($B,$cl),"\n";
- close F;
+ close $save;
}
}
-# fileid is inode and mtime
sub fileid {
- my @s = stat(shift);
- return @s ? $s[1].$s[9] : int(time);
+ my $file = shift;
+ my @s = stat($file);
+
+ if (@s) {
+ return md5_hex($file.$s[0].$s[1].$s[7].$s[9]);
+ } else {
+ warn "$0: $file - $!\n";
+ return int(time);
+ }
}
s/.*\s+//;
s/[<>]//g;
if (/,/) {
- warn "$0: ignoring mutt multi-alias $to = $alias\n";
+ warn "$0: ignoring mutt multi-alias $to = $_\n";
last;
}
if (/@/) {
}
-# collect file meta data (filename, inode, mtime)
+# collect (hashed) file meta data
sub fmd {
my @files = @_;
my ($file,$dir);
while (defined ($file = readdir($dir))) {
next if $file eq '..';
if ($file eq '.') {
- $fmd .= $file.fileid($dir);
+ $fmd .= fileid($dir);
} else {
$fmd .= fmd("$dir/$file");
}
closedir $dir;
}
} else {
- $fmd .= $file.fileid($file);
+ $fmd .= fileid($file);
}
}
unless (defined $_ and /\w/) {
die "$0: no response from server\n";
}
- print "<-- $_\n" if $opt_v;
s/\r?\n//;
+ print "<-- $_\n" if $opt_v;
# CGI fatalsToBrowser
if (/^HTTP.* 500/) {
@r = <$SH> unless @r;
die "$0: server error: $error\n";
}
- print "<-- $_\n" if $opt_v;
return $_;
}
local $/;
open $0,$0 or die "cannot read $0 - $!\n";
- $_ = <$0>;
+ $cfc = <$0>;
close $0;
- s/.*\n$cfb\n//s;
- $cfc = $_;
+ $cfc =~ s/.*\n$cfb\n//s;
- foreach my $p (qw(fexget sexsend)) {
+ foreach my $p (qw'fexget sexsend') {
open $p,$p or die "cannot read $p - $!\n";
$_ = <$p>;
close $p;
close $p;
}
- exec "l $0 fexget sexsend";
+ exec "l fexsend fexget sexsend";
exit;
}
if ($SH) {
autoflush $SH 1;
+ binmode $SH;
} else {
die "$0: cannot connect $server:$port - $@\n";
}
}
+sub quote {
+ local $_ = shift;
+ s/([^\w\@\/%^,.=+_:+-])/\\$1/g;
+ return $_;
+}
+
+
+sub debug {
+ print "## DEBUG: @_\n" if $DEBUG;
+}
+
+
# from MIME::Base64::Perl
sub encode_b64 {
my $res = "";
eval 'use Net::INET6Glue::INET_is_INET6';
-our $version = 20150826;
+our $version = 20160104;
+our $DEBUG = $ENV{DEBUG};
my %SSL = (SSL_version => 'TLSv1');
my $sigpipe;
}
} elsif ($0 eq 'sexget' or $0 eq 'fuckme') {
+
+ $opt_g = 0;
getopts('hgvVdu:') or die $usage;
die $usage if $opt_h;
} else { # sexsend
- $opt_g = 1;
+ $opt_g = 0;
getopts('hguvqVTt:') or die $usage;
die $usage if $opt_h;
my $connect = "CONNECT $server:$port HTTP/1.1";
local $_;
- if ($opt_v and $port == 443 and %SSL) {
- foreach my $v (keys %SSL) {
- printf "%s => %s\n",$v,$SSL{$v};
- }
- }
-
if ($proxy) {
tcpconnect(split(':',$proxy));
- if ($port == 443) {
+ if ($https) {
printf "--> %s\n",$connect if $opt_v;
nvtsend($connect,"");
$_ = <$SH>;
unless (/^HTTP.1.. 200/) {
die "$0: proxy error : $_";
}
- eval "use IO::Socket::SSL";
- die "$0: cannot load IO::Socket::SSL\n" if $@;
+ &enable_ssl;
$SH = IO::Socket::SSL->start_SSL($SH,%SSL);
}
} else {
tcpconnect($server,$port);
}
-# if ($port == 443 and $opt_v) {
+# if ($https and $opt_v) {
# printf "%s\n",$SH->get_cipher();
# }
}
undef $SH;
}
- if ($port == 443) {
+ if ($https) {
# eval "use IO::Socket::SSL qw(debug3)";
- eval "use IO::Socket::SSL";
- die "$0: cannot load IO::Socket::SSL\n" if $@;
+ &enable_ssl;
$SH = IO::Socket::SSL->new(
PeerAddr => $server,
PeerPort => $port,
if ($SH) {
autoflush $SH 1;
+ binmode $SH;
} else {
die "$0: cannot connect $server:$port - $@\n";
}
}
+sub enable_ssl {
+ eval "use IO::Socket::SSL";
+ die "$0: cannot load IO::Socket::SSL\n" if $@;
+ eval '$SSL{SSL_verify_mode} = 0 if Net::SSLeay::SSLeay() <= 9470143';
+ if ($opt_v) {
+ foreach my $v (keys %SSL) {
+ printf "%s => %s\n",$v,$SSL{$v};
+ }
+ }
+}
+
+
sub sendheader {
my $sp = shift;
my @head = @_;
}
+sub quote {
+ local $_ = shift;
+ s/([^\w\@\/%^,.=+_:+-])/\\$1/g;
+ return $_;
+}
+
+
+sub debug {
+ print "## DEBUG: @_\n" if $DEBUG;
+}
+
+
# from MIME::Base64::Perl
sub encode_b64 {
my $res = "";
--- /dev/null
+<html>
+<head>
+ <title>fexit</title>
+ <style>
+ pre {
+ padding: 8px;
+ background: #eef;
+ border: thin dashed #0076A3;
+ font-family: courier;
+ }
+ </style>
+</head>
+<body>
+
+<<$ENV{FEXIT} = 'http://fex.belwue.de/download/fexit.exe';'';>>
+
+<h1><a href="$FEXIT$">fexit</a> for Windows</h1>
+
+<a href="$FEXIT$">fexit</a> is a <a href="/index.html">F*EX</a>
+client for sending files of any size to any e-mail address.<br>
+<a href="$FEXIT$">fexit</a> can also send directories or
+download files and resume the upload or download after link failures,
+which your webbrowser cannot do.
+<p>
+You can start <a href="$FEXIT$">fexit</a> via Windows explorer or
+via command console (cmd).<br>
+You can also drag files or directories to the fexit icon with the Windows
+explorer.
+<p>
+#if $ENV{ID}
+When you run <a href="$FEXIT$">fexit</a> for the first time you are
+asked for the "F*EX server URL". You can enter your personal URL:
+<p>
+<code>
+<<"$ENV{PROTO}://$ENV{HTTP_HOST}/fup/".b64("from=$ENV{USER}&id=$ENV{ID}")>>
+</code>
+<p>
+(use your mouse for copy+paste)
+<p>
+<<require "./fexitinstaller";''>>
+#endif
+##<pre><<foreach $v (keys %ENV) { printf "%s=%s\n",$v,$ENV{$v} }>>
+</body>
+</html>
--- /dev/null
+#!/usr/bin/perl -w
+
+$user = $ENV{USER};
+$id = $ENV{ID};
+$url = "$ENV{PROTO}://$ENV{HTTP_HOST}";
+$fi = 'fexitinstaller.cmd';
+$fe = 'http://fex.belwue.de/download/fexit.exe';
+$ps = '%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe';
+$cmd = <<EOD;
+mkdir "%USERPROFILE%\\fex"
+cd "%USERPROFILE%\\fex"
+if not exist id (
+ echo $url>id
+ echo $user>>id
+ echo $id>>id
+)
+cd "%USERPROFILE%\\Desktop"
+$ps -command "& { (New-Object Net.WebClient).DownloadFile('$fe','fexit.exe') }"
+\@explorer "%USERPROFILE%\\Desktop"
+\@set /p x="press [ENTER]"
+EOD
+$cmd =~ s/\n/\r\n/g;
+
+if (chdir "$spooldir/$user" and open $fi,'>',$fi) {
+ print {$fi} $cmd;
+ close $fi;
+ system "$FEXHOME/bin/fexsend ".
+ "-oKq -C 'fexit for your Windows desktop' $fi $user >/dev/null";
+ if ($? == 0) {
+ print "<p>\n";
+ print "<h3>A fexit installer has been sent to you. Check your email.</h3>\n";
+ }
+ unlink $fi;
+}
--- /dev/null
+<html>
+<head>
+ <title>fexsend for Mac</title>
+ <style>
+ pre {
+ padding: 8px;
+ background: #eef;
+ border: thin dashed #0076A3;
+ font-family: courier;
+ }
+ </style>
+</head>
+<body>
+
+<h1>fexsend for Apple Macintosh OS X</h1>
+
+fexsend is a <a href="/index.html">F*EX</a> client for sending files of
+any size to any e-mail address.<br>
+fexsend can also send directories and resume the upload
+after a link failure, which your webbrowser cannot do.
+
+<h3>To install fexsend:</h3>
+<ol>
+<li> start a "Terminal":<br>
+ go to <mark>Finder</mark>, press ⇧⌘U to open the Utility
+ Application folder and double-click <mark>Terminal.app</mark> with left
+ mouse button
+<p>
+<li> copy this code into the Terminal window:
+ <pre>curl http://fex.belwue.de/download/fexsend.command|bash</pre>
+ Do not forget to enter [RETURN]
+ <p>
+ You can use your mouse for copying:
+ <p>
+ <ol>
+ <li>move your mouse cursor with hold left mouse button over the
+ code obove (the code will be marked)
+ <li>press ⌘C
+ <li>move your mouse cursor into the Terminal window
+ <li>click left mouse button
+ <li>press ⌘V
+ </ol>
+</ol>
+
+<h3>To run fexsend:</h3>
+<ol>
+ <li> in <mark>Finder</mark> click <mark>Desktop</mark> with left mouse button
+ <li> double-click <mark>fexsend.command</mark> with left mouse button
+</ol>
+<p>
+<<
+ if ($ENV{ID}) {
+ my $url = "$ENV{PROTO}://$ENV{HTTP_HOST}/fup/"
+ . b64("from=$ENV{USER}&id=$ENV{ID}");
+ qq(
+ When asked for "F*EX server URL" enter:
+ <p>
+ <code>$url</code>
+ <p>
+ (again, use your mouse for copy+paste)
+ );
+ }
+>>
+</body>
+</html>
<center></center>
<h1> <a href="/">F*EX</a> tools</h1>
-<<$ENV{TA}='http://fex.belwue.de';''>>
+<<$ENV{TA} = 'http://fex.belwue.de';'';>>
+#if $ENV{AKEY}
+To use one of the following F*EX clients you must configure them.
+See <a href="/foc">user config</a> for your account data.
+<p>
+#endif
+
+<h3>UNIX:</h3>
<table border=1>
<tr><td><a href="/download/fexsend">fexsend</a>
- <td>UNIX CLI client for sending files (with many
+ <td>client for sending files (with many
<a href="$TA$/fstools/fexsend.html">
additional features</a>)</tr>
<tr><td><a href="/download/fexget">fexget</a>
- <td>UNIX CLI client for receiving files (with many
+ <td>client for receiving files (with many
<a href="$TA$/fstools/fexget.html">
additional features</a>)</tr>
-<tr><td><a href="$TA$/download/fexget.exe">fexget</a>
- <td>Windows CLI client for receiving files
<tr><td><a href="/download/sex.tar">sexsend, sexget</a>
- <td>UNIX CLI clients for sending and receiving streams</tr>
+ <td>clients for sending and receiving streams</tr>
+</table>
+<p>
+<h3>Windows:</h3>
+<table border=1>
+<!--
<tr><td><a href="$TA$/download/schwuppdiwupp.exe">schwuppdiwupp</a>
- <td>Windows GUI client for sending files</tr>
-<tr><td><a href="$TA$/download/macschwupp.tar">schwuppdiwupp</a>
- <td>Macintosh GUI client for sending files</tr>
+ <td>GUI client for sending files</tr>
+<tr><td><a href="$TA$/download/fexget.exe">fexget</a>
+ <td>client for receiving files
+-->
+<tr><td><a href="/fexit.html">fexit</a>
+ <td>client for sending and receiving files
+</table>
+<p>
+<h3>Macintosh:</h3>
+<table border=1>
+<tr><td><a href="/macfexsend.html">fexsend.command</a>
+ <td>client for sending files and directories</tr>
</table>
<p>
-In opposite to most web browsers all these clients can handle files
-greater than 2 GB and are able to resume interrupted up/downloads.
+In opposite to many web browsers all these clients can handle files
+or directories greater than 2 GB and are able to resume interrupted
+up/downloads.
<p>
Hint for UNIX users:
<pre> wget -qO- http://$HTTP_HOST$/xx.tar | tar xvf -</pre>
print "http://fex.rus.uni-stuttgart.de" unless -s "$docdir$a";
print "$a\">anonymous usage</a>";
>>
+## <hr>
+## <pre>
+## <<
+## #while (($v,$vv) = each %ENV) { printf "%s = %s\n",$v,$vv if $vv !~ /\n/ }
+## #foreach $v (qw'AKEY USER ID') { printf "$v = %s\n",$ENV{$v} }
+## '';
+## >>
+## </pre>
</BODY>
</HTML>
-fex-20150826
+fex-20160104
unless (getpwnam('fex')) {
print "creating user fex\n";
- system 'useradd -s /bin/bash -c "File EXchange" -m fex';
+ system 'groupadd -g 80 fex 2>/dev/null || groupadd fex';
+ my @g = getgrnam('fex') or die "$0: cannot groupadd fex\n";
+ my $gid = $g[2];
+ if (getpwuid($gid)) {
+ system "useradd -s /bin/bash -c 'File EXchange' -g $gid -m fex"
+ } else {
+ system "useradd -s /bin/bash -c 'File EXchange' -u $gid -g $gid -m fex"
+ }
exit $? if $?;
}
mkdir "$FEXHOME/spool",0700 or die "cannot mkdir $FEXHOME/spool - $!\n";
mkdir "$FEXHOME/spool/.error",0700;
}
+foreach my $dir (qw'.dkeys .ukeys .akeys .skeys .gkeys .xkeys .locks') {
+ mkdir "$FEXHOME/spool/$dir",0700;
+}
+
chownr('fex',"$FEXHOME/spool/.");
# fex-VM?
chownr('fex',"$FEXHOME/locale/$locale");
$hl = "$FEXHOME/htdocs/locale/$locale";
symlink "$FEXHOME/locale/$locale/htdocs",$hl unless -l $hl;
+ chownr('fex',"$FEXHOME/htdocs/locale/$locale");
} else {
push @nlocales,"./install $1\n";
}
use Fcntl qw(:flock :seek :mode);
use POSIX qw(strftime locale_h);
use Cwd qw(getcwd abs_path);
+use utf8;
# import from fex.pp
our ($bs,$tmpdir,@doc_dirs);
@files = ("$1.tar");
open $file,'-|',qw'gzip -c',@files or http_error(503);
} elsif ($file =~ /(.+)\.(tar|tgz|zip)$/ and
- @s = lstat($streamfile = "$1.stream") and $s[4] == $<)
+ @s = lstat($streamfile = "$1.stream") and
+ ($s[4] == $< or $s[4] == 0))
{
- # streaming file (only if it is owned by user fex)
+ # streaming file
chdir dirname($file);
security_check($file);
if (-l $streamfile and readlink($streamfile) =~ /^:(.+):$/) {
## optional: your mail domain
## if set it will be used as domain for every user without domain
## local_user ==> local_user@$mdomain
-## if not set, addresses without domains produce an error
+## if not set, addresses without domain produce an error
# $mdomain = 'MY.MAIL.DOMAIN';
# $admin = 'fexmaster@'.$mdomain;
# -*- perl -*-
use 5.008;
+use utf8;
use Fcntl qw':flock :seek :mode';
use IO::Handle;
use IPC::Open3;
$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
+$dkeydir = "$spooldir/.dkeys"; # download keys
+$ukeydir = "$spooldir/.ukeys"; # upload keys
+$akeydir = "$spooldir/.akeys"; # authentification keys
+$skeydir = "$spooldir/.skeys"; # subuser authentification keys
+$gkeydir = "$spooldir/.gkeys"; # group authentification keys
+$xkeydir = "$spooldir/.xkeys"; # extra download keys
+$lockdir = "$spooldir/.locks"; # download lock files
if (my $ra = $ENV{REMOTE_ADDR} and $max_fail) {
mkdirp("$spooldir/.fail");
nvt_print("Strict-Transport-Security: max-age=2851200; preload");
}
if ($use_cookies) {
+ $akey = md5_hex("$from:$id") if $id and $from;
if ($akey) {
- nvt_print("Set-Cookie: akey=$akey; Max-Age=9999; Discard");
+ nvt_print("Set-Cookie: akey=$akey; path=/; Max-Age=9999; Discard");
}
# if ($skey) {
# nvt_print("Set-Cookie: skey=$skey; Max-Age=9999; Discard");
$debuglog = sprintf("%s/%s_%s_%s.%s",
$ddir,time,$$,$ENV{REQUESTCOUNT}||0,$prg);
$debuglog =~ s/\s/_/g;
+ # http://perldoc.perl.org/perlunifaq.html#What-is-a-%22wide-character%22%3f
# open $debuglog,'>>:encoding(UTF-8)',$debuglog or return;
open $debuglog,'>>',$debuglog or return;
+ # binmode($debuglog,":utf8");
autoflush $debuglog 1;
# printf {$debuglog} "\n### %s ###\n",isodate(time);
}
while ($_ = shift @_) {
+ $_ = encode_utf8($_) if utf8::is_utf8($_);
s/\n*$/\n/;
s/<.+?>//g; # remove HTML
print {$debuglog} $_;
my $q = "[\'\"]"; # quote delimiter chars " and '
# remove first newline and look for default indention
- s/^(\«(\d+)?)?\n//;
+ s/^((\d+)?)?\n//;
$i = ' ' x ($2||0);
# remove trailing spaces at end
- s/[ \t]*\»?$//;
+ s/[ \t]*?$//;
@s = split "\n";
" -a -e -r $bcc -r $to"
) or return;
- print {$po} $plain;
+ print {$po} "\n",$plain,"\n";
close $po;
$enc .= $_ while <$pi>;
$data = "$dkeydir/$P{dkey}/data";
$size = $bytes = -s $data;
return unless $size;
- if ($nowarning) {
- $warning = '';
- } else {
- $warning =
- "Please avoid download with Internet Explorer, ".
- "because it has too many bugs.\n".
- "We recommend Firefox or wget.";
- }
+ $warning =
+ "We recommend fexget or fexit for download,\n".
+ "because these clients can resume the download after an interruption.\n".
+ "See $proto://$hostname/tools.html";
+ # if ($nowarning) {
+ # $warning = '';
+ # } else {
+ # $warning =
+ # "Please avoid download with Internet Explorer, ".
+ # "because it has too many bugs.\n\n";
+ # }
if ($filename =~ /\.(tar|zip|7z|arj|rar)$/) {
$warning .= "\n\n".
"$filename is a container file.\n".
or http_die("cannot start sendmail - $!");
}
}
+ $comment .= "\n" if $comment;
if ($comment =~ s/^!(shortmail|\.)!\s*//i
- or (readlink "$to/\@NOTIFICATION"||'') =~ /short/i
+ or (readlink("$to/\@NOTIFICATION")||'') =~ /short/i
) {
$body = qqq(qq(
'$comment'
- ''
'$download'
'$size'
));
} else {
- $comment = "Comment: $comment\n" if $comment;
$disclaimer = slurp("$from/\@DISCLAIMER") || qqq(qq(
'$warning'
''
));
$disclaimer .= "\n" . $::disclaimer if $::disclaimer;
$body = qqq(qq(
+ '$comment'
'$from has uploaded the file'
' "$filename"'
'($size) for $receiver. Use'
'$download'
'to download this file within $days.'
''
- '$comment'
'$autodelete'
''
'$disclaimer'
sub reactivation {
my ($expire,$user) = @_;
my $fexsend = "$FEXHOME/bin/fexsend";
+ my $reactivation = "$FEXLIB/reactivation.txt";
return if $nomail;
if (-x $fexsend) {
+ if ($locale) {
+ my $lr = "$FEXHOME/locale/$locale/lib/reactivation.txt";
+ $reactivation = $lr if -f $lr and -s $lr;
+ }
$fexsend .= " -M -D -k 30 -C"
." 'Your F*EX account has been inactive for $expire days,"
." you must download this file to reactivate it."
." Otherwise your account will be deleted.'"
- ." $FEXLIB/reactivation.txt $user";
+ ." $reactivation $user";
# on error show STDOUT and STDERR
- system "$fexsend >/dev/null 2>&1";
- if ($?) {
- warn "$fexsend\n";
- system $fexsend;
- }
+ my $fo = `$fexsend 2>&1`;
+ warn $fexsend.'\n'.$fo if $?;
} else {
warn "$0: cannot execute $fexsend for reactivation()\n";
}
(if you have javascript enabled and popups allowed).
<p>
<em>NOTE: Many web browsers cannot upload files > 2 GB!</em><br>
-If your file is larger you have to use a special <a href="/fuc?show=tools">F*EX client</a>
+If your file is larger you have to use a special <a href="/tools.html">F*EX client</a>
or Firefox or Google Chrome which have no size limit.<br>
-You also need a <a href="/fuc?show=tools">F*EX client</a> for resuming interrupted uploads. Your web browser cannot do this.
+You also need a <a href="/tools.html">F*EX client</a> for resuming interrupted uploads. Your web browser cannot do this.
<p>
If you want to send more than one file, then put them in a zip or tar archive,
e.g. with <a href="http://www.7-zip.org/download.html">7-Zip</a>.
# config for F*EX CGI fup
+use utf8;
+
$info_1 = $info_login = <<EOD;
<p><hr><p>
<a href="/">F*EX (File EXchange)</a>
<html>
-<head><title>F*EX FAQ</title></head>
+<head>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+ <title>F*EX FAQ</title>
+</head>
<body>
## <pre>
## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
## </pre>
+Ce document est périmé. Merci de consulter
+la <a href="/FAQ/meta.html?locale=french">FAQ anglaise</a>
+<p>
+
<< require "./faq.pl" or print $! >>
</body>
<html>
-<head><title>F*EX FAQ</title></head>
+<head>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+ <title>F*EX FAQ</title>
+</head>
<body>
## <pre>
## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
## </pre>
+Ce document est périmé. Merci de consulter
+la <a href="/FAQ/meta.html?locale=french">FAQ anglaise</a>
+<p>
+
<< require "./faq.pl" or print $! >>
</body>
+use utf8;
package FAQ;
my ($faq,$var,$env,$q,$a,$c,$s,$t,$n);
print "<style type=text/css><!-- h2,h3 {font-weight:normal} --></style>\n";
-print '<h1><a name="top" href="/index.html">F*EX</a> ',
- " Frequently Asked Questions</h1>\n";
+print '<h1><a name="top" href="/index.html">F*EX</a> ';
+printf "Frequently Asked Questions: %s</h1>\n",ucfirst($faq);
if ($faq ne 'local') {
- print "<h3>\n";
+ print "<h3>Sections: ";
foreach $s (@sections,'All') {
if ($s =~ /$faq/i) {
print "<b>$s</b>\n";
print "</h3>\n";
}
+print "<p><hr><p>\n";
print "<table>\n";
foreach my $faq (@faq) {
};
($q,$a) = split /A:\s*/;
$q =~ s/[\s\n]+$//;
+ $q =~ s/^\s+//;
$q =~ s! (/\w[\S]+/[\S]+)! <code>$1</code>!g;
$a =~ s/[\s\n]+$/\n/;
+ $a =~ s/^\s+//;
while ($a =~ s/^(\s*)\*/$1<ul>\n$1<li>/m) {
while ($a =~ s/(<li>.*\n\s*)\*/$1<li>/g) {}
$a =~ s:(.*\n)(\s*)(<li>[^\n]+\n):$1$2$3$2</ul>\n:s
# $a =~ s/^\s*<br>\s*//mg;
$a =~ s/<([^\s<>\@]+\@[\w.-]+)>/<a href="mailto:$1"><$1><\/a>/g;
$a =~ s! (/\w[\S]+/[\S]+)! <code>$1</code>!g;
- $a =~ s!(https?://[\w-]+\.[^\s<>]+)!<a href="$1">[$1]</a>!g or
- $a =~ s!(https?://[^\s<>]+)!<code>$1</code></a>!g;
+ $a =~ s!(https?://[\w-]+\.[^\s<>()]+)!<a href="$1">[$1]</a>!g or
+ $a =~ s!(https?://[^\s<>()]+)!<code>$1</code></a>!g;
push @{$Q{$faq}},$q;
push @{$A{$faq}},$a;
}
$t = $s if $faq eq 'all';
for ($n = 0; $n < scalar(@{$Q{$c}}); $n++) {
- printf "<tr><th align=left>%s Q%d:<td> <a href=\"#%s%d\">%s</tr>\n",
- $s,$n+1,$t,$n+1,${Q{$c}[$n]};
+ $q = ${Q{$c}[$n]};
+ $qa = anchor($q);
+ printf '<tr valign=top><th align=left>'.
+ '<a href="#%s%d" style="text-decoration: none">'.
+ '<font color="black">%s Q%d</a>:'.
+ '<td><a href="#%s">%s</a></tr>'."\n",
+ $t,$n+1,$s,$n+1,$qa,$q;
}
}
print "</table>\n";
+print "<p><hr><p>\n";
foreach $s (sections($faq)) {
$t = $s if $faq eq 'all';
for ($n = 0; $n < scalar(@{$Q{$c}}); $n++) {
- print "<p><hr><p>\n";
+ $q = ${Q{$c}[$n]};
+ $qa = anchor($q);
+ print "<p>\n";
print "<table>\n";
- printf "<tr><th><a name=\"%s%d\">%s Q%d:</a><td>%s</tr>\n",
- $t,$n+1,$s,$n+1,${Q{$c}[$n]};
+ printf "<tr valign=top><th>".
+ "<a name=\"%s%d\">%s Q%d:</a>".
+ "<a name=\"%s\"></a>".
+ "<td><b>%s</b></tr>\n",
+ $t,$n+1,$s,$n+1,$qa,$q;
printf "<tr valign=top><th>%s A%d:<td>\n%s</tr>\n",
$s,$n+1,${A{$c}[$n]};
- print "<tr><th>[<a href=\"#top\">Top</a>]<td></tr>\n";
print "</table>\n";
+ print "[<a href=\"#top\">↑ Questions</a>]\n";
}
}
s/\s+$//;
return "<pre>$_</pre>\n";
}
+
+sub anchor {
+ local $_ = shift;
+ s/<.+?>//g;
+ s/\(.+?\)//g;
+ s/\W/_/g;
+ s/_+$//;
+ return $_;
+}
<html>
-<head><title>F*EX FAQ</title></head>
+<head>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+ <title>F*EX FAQ</title>
+</head>
<body>
## <pre>
## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
## </pre>
+Ce document est périmé. Merci de consulter
+la <a href="/FAQ/meta.html?locale=french">FAQ anglaise</a>
+<p>
+
<< require "./faq.pl" or print $! >>
</body>
A: fex.rus.uni-stuttgart.de tourne sur un ordinateur de bureau et est capable de gérer des uploads
à plus de 300 MB/s. Essayer donc ça avec un serveur web généraliste comme Apache !
-Q: De quoi ais-je besoin de pour installer F*EX ?
+Q: De quoi ais-je besoin pour installer F*EX ?
A: D'une machine UNIX avec une entrée DNS et un service smtp fonctionnel. Vous devez être root sur la machine.
Q: Qu'est-ce que DNS et smtp ?
Q: Qui est l'auteur ?
A: Ulli Horlacher framstag@rus.uni-stuttgart.de
-Q: Quel est la licence de F*EX ?
+Q: Quelle est la licence de F*EX ?
A: Perl Artistic free software
Q: Est-ce qu'il y a une mailing list F*EX ?
<html>
-<head><title>F*EX FAQ</title></head>
+<head>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+ <title>F*EX FAQ</title>
+</head>
<body>
## <pre>
## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
## </pre>
+Ce document est périmé. Merci de consulter
+la <a href="/FAQ/meta.html?locale=french">FAQ anglaise</a>
+<p>
+
<< require "./faq.pl" or print $! >>
</body>
<html>
-<head><title>F*EX FAQ</title></head>
+<head>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+ <title>F*EX FAQ</title>
+</head>
<body>
## <pre>
## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
## </pre>
+Ce document est périmé. Merci de consulter
+la <a href="/FAQ/meta.html?locale=french">FAQ anglaise</a>
+<p>
+
<< require "./faq.pl" or print $! >>
</body>
<html>
-<head><title>F*EX FAQ</title></head>
+<head>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+ <title>F*EX FAQ</title>
+</head>
<body>
## <pre>
## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
## </pre>
+Ce document est périmé. Merci de consulter
+la <a href="/FAQ/meta.html?locale=french">FAQ anglaise</a>
+<p>
+
<< require "./faq.pl" or print $! >>
</body>
# config for F*EX CGI fup
+use utf8;
+
$info_1 = $info_login = <<EOD;
<p><hr><p>
<a href="/">F*EX (File EXchange)</a>
# config for F*EX CGI fup
+use utf8;
+
$info_1 = $info_login = <<EOD;
<p><hr><p>
<a href="/">F*EX (File EXchange)</a>
# configurazione per F*EX CGI fup
+use utf8;
+
$info_1 = $info_login = <<EOD;
<p><hr><p>
<a href="/">F*EX (File EXchange)</a>
# czech: Michal Simunek <michal.simunek@gmail.com>
# french: Jean-Baptiste Denis <jbd@jbdenis.net>
+'english'
+'german'
+'swabian'
+'spanish'
+'galician'
+'italian'
+'czech'
+'french'
+
F*EX operation control ERROR
F*EX Bedienungssteuerungs-Fehler
F*EX Fehler bei dr Bedienongsschdeuerong
Změnit odesílání zřeknutí se odpovědnosti</a> u správy s upozorněním
Changer la clause de non-responsabilité</a> à envoyer avec le message de notification
-Change your <a href="" onclick="show_id();" title="$id">auth-ID</a> to
-Ändern Sie Ihre <a href="" onclick="show_id();" title="$id">auth-ID</a> in
-Ändr die <a href="" onclick="show_id();" title="$id">auth-ID</a> noch
-Cambie su <a href="" onclick="show_id();" title="$id">auth-ID</a> en
-Cambie o seu <a href="" onclick="show_id();" title="$id">auth-ID</a> en
-Cambia il tuo <a href="" onclick="show_id();" title="$id">auth-ID</a> in
-Změnit si ověřovací ID <a href="" onclick="show_id();" title="$id">auth-ID</a> na
-Changer votre <a href="" onclick="show_id();" title="$id">auth-ID</a> pour
+Change your <a href="#" onclick="show_id();" title="$id">auth-ID</a> to
+Ändern Sie Ihre <a href="#" onclick="show_id();" title="$id">auth-ID</a> in
+Ändr die <a href="#" onclick="show_id();" title="$id">auth-ID</a> noch
+Cambie su <a href="#" onclick="show_id();" title="$id">auth-ID</a> en
+Cambie o seu <a href="#" onclick="show_id();" title="$id">auth-ID</a> en
+Cambia il tuo <a href="#" onclick="show_id();" title="$id">auth-ID</a> in
+Změnit si ověřovací ID <a href="#" onclick="show_id();" title="$id">auth-ID</a> na
+Changer votre <a href="#" onclick="show_id();" title="$id">auth-ID</a> pour
remember it
merken
Downloads will now be saved
Downloads werden nun gespeichert
-Downloads werdet ab jetzt gschpeichert
+Ronderlads werdet ab jetzt gschpeichert
Descargas están guardadas
Downloads will now be saved
I downloads saranno ora salvati
Downloads will now be displayed (if possible)
Downloads werden nun angezeigt (wenn möglich)
-Downloads werdet ab jetzt ozeigt (wenns ghot)
+Ronderlads werdet ab jetzt ozeigt (wenns ghot)
Descargas están indicadas ahora (si posible)
Downloads will now be displayed (if possible)
I downloads saranno mostrati (se possibile)
value="pokračovat"
value="continuer"
->User:
->Benutzer:
->Benutzr:
->Usuario:
->Usuario:
->Utente:
->Uživatel:
->Utilisateur:
+#>User:
+#>Benutzer:
+#>Benutzr:
+#>Usuario:
+#>Usuario:
+#>Utente:
+#>Uživatel:
+#>Utilisateur:
user config ERROR
ERROR Benutzer-Einstellungen
Více informací o svém účtu získáte na http://$ENV{HTTP_HOST}/index.html
Voir http://$ENV{HTTP_HOST}/index.html pour plus d'informations sur
+See $proto:
+Siehe $proto:
+Guck uff $proto:
+Vea $proto:
+Véxase $proto:
+Vedi $proto:
+Více $proto:
+Voir $proto:
+
Questions? ==> F*EX admin: $admin
Fragen? ==> Kontaktieren Sie den F*EX Administrator: $admin
Froga? ==> Belaeschtig ruhig dr F*EX Adminischdrator: $admin
'Používání
'Utilisez
-See http://$ENV{HTTP_HOST}/ for more information about
-Siehe http://$ENV{HTTP_HOST}/ fuer mehr Informationen ueber
+See http://$ENV{HTTP_HOST}/index.html for more information about
+Siehe http://$ENV{HTTP_HOST}/index.html fuer mehr Informationen ueber
Guck halt uff http://$ENV{HTTP_HOST}/index.html wenn De meh wisse willsch ieber
-Vea http://$ENV{HTTP_HOST}/ para obtener más información sobre
-Véxase http://$ENV{HTTP_HOST}/ para obter más información sobre
-Vedi http://$ENV{HTTP_HOST}/ per ulteriori informazioni
-Informace, jak používat F*EX, naleznete na http://$ENV{HTTP_HOST}/
-Voir http://$ENV{HTTP_HOST}/ pour plus d'informations sur
+Vea http://$ENV{HTTP_HOST}/index.html para obtener más información sobre
+Véxase http://$ENV{HTTP_HOST}/index.html para obter más información sobre
+Vedi http://$ENV{HTTP_HOST}/index.html per ulteriori informazioni
+Informace, jak používat F*EX, naleznete na http://$ENV{HTTP_HOST}/index.html
+Voir http://$ENV{HTTP_HOST}/index.html pour plus d'informations sur
$notify not found in $gf
$notify nicht gefunden in $gf
Upravit F*EX skupinu
Éditez le groupe F*EX
-A F*EX group is similar to a mailing list, but for files:
-Eine F*EX-Gruppe ist einem E-Mail-Verteiler ähnlich, hier geht es jedoch um Daten-Verteilung:
-A F*EX-Grupp isch so was wie en E-Mail-Verdoiler, allerdengs werde do Date verdoilt:
-Un grupo F*EX es similar a una lista de correo, pero para ficheros:
-Un grupo F*EX é semellante a unha lista de correo, pero para ficheiros:
-Un gruppo F*EX e' simile ad una lista di distribuzione, ma per i file:
-F*EX skupina je podobná poštovní konferenci s tím rozdílem, že se odesílají soubory:
-Un groupe F*EX est similaire à une liste de diffusion (mailing-list), mais pour des fichiers
-
When a member fexes a file to this list,
Wenn ein Mitglied eine Datei für die Gruppe bereitstellt,
Wenn oi Mitglied a Datei fier die reschdlich Grupp nuffläd
delete file $autodelete days after download
Lösche Datei $autodelete Tage nach dem Download
-Lösch Datei $autodelete Dag nochm ronderlada
+Lösch Datei $autodelete Dag nochm Ronderlada
borrar archivo $autodelete dias despues del descargar
delete file $autodelete days after download
cancella file $autodelete giorni dopo il download
Su auth-ID de F*EX solicitada para $fup?from=$from es:
O seu auth-ID de F*EX solicitado para $fup?from=$from é:
Il tuo auth-ID di F*EX che hai richiesto per $fup?from=$from e':
-Požadované ověřovací ID pro $fup?from=$from je:
+Vaše požadované F*EX ověřovací ID pro $fup?from=$from je:
Votre auth-ID F*EX pour $fup?from=$from est:
Or use:
O use:
Or use:
Oppure usa
-Nebo pou¾ijte:
+Nebo použijte:
Ou utilisez:
Your reqested F*EX login is:
>reenviar<
>forward<
>prosegui<
->pøedat<
+>přeposlat<
>faire suivre<
Files for other e-mail addresses you own will not be listed here!
Zřejmě používáte prohlížeč "$1", který není kompatibilní s F*EX a pravděpodobně nebude správně fungovat
Votre client semble être "$1" qui est incompatible avec F*EX et ne va sans doute pas fonctionner
-We recommend firefox
-Wir empfehlen \"Firefox\"
-Mir empfehled \"Firefox\"
-Recomendamos firefox
-Recomendamos firefox
-Raccomandiamo firefox
-Doporučujeme používat Firefox
-Nous recommandons firefox
-
sender:
Absender:
Absendr:
Alternativer Java Client</a> (fier Dateia wo größer send als 2 GB oder zum Sende von meh als oiner Datei)
Cliente java alternativo</a> (par ficheros > 2 GB o envío de más de un fichero)
Cliente java alternativo</a> (para ficheiros > 2 GB ou envío de más dun fichero)
-Client java alternativo</a> (per file > 2 GB o per spedizioni di piu' di un file)
+Client java alternativo</a> (per file > 2 GB o per spedizioni di più di un file)
Alternativní Java klient</a> (pro soubory větší než 2 GB či pro odesílání více než jednoho souboru)
Client Java alternatif</a> (pour les fichiers > 2 GB ou envoyer plusieurs fichiers d'un coup)
-Warning: the recipient must not be a mailing list, because after
-Warnung: die Empfängeradresse darf keine Mailingliste sein, weil nach dem
-Obacht: die Empfängeradress darf koi Mailinglischt sei, weil nochm
-Warning: the recipient must not be a mailing list, because after
-Warning: the recipient must not be a mailing list, because after
-Warning: the recipient must not be a mailing list, because after
-Warning: the recipient must not be a mailing list, because after
-Warning: the recipient must not be a mailing list, because after
-
-download the file will be no more available
-Download wird die Datei nicht mehr verfügbar sein
-Ronderlada isch die Datei nemme verfügbar
-download the file will be no more available
-download the file will be no more available
-download the file will be no more available
-download the file will be no more available
-download the file will be no more available
-
-Contact <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a>
-Kontaktieren Sie den <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a>
-Frog dr <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a>
-Contact <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a>
-Contact <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a>
-Contact <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a>
-Contact <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a>
-Contact <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a>
-
-if you want to fex to a mailing list
-wenn Sie an eine Mailingliste fexen wollen
-wenn Du an a Mailinglischt fexa wilsch
-if you want to fex to a mailing list
-if you want to fex to a mailing list
-if you want to fex to a mailing list
-if you want to fex to a mailing list
-if you want to fex to a mailing list
+Warning: the recipient must not be a mailing list
+Warnung: die Empfängeradresse darf keine Mailingliste sein
+Obacht: die Empfängeradress darf koi Mailinglischt sei
+Aviso: el destinatario no debe ser una lista de correo
+Warning: the recipient must not be a mailing list
+Attenzione: il destinatario non deve essere una lista di distribuzione
+Upozornění: příjemce nemůže být poštovní konference
+Attention: le destinataire ne peut pas être une liste de diffusion
+
+because after download the file will be no more available
+weil nach dem Download wird die Datei nicht mehr verfügbar sein
+weil nochm Ronderlada isch die Datei nemme verfügbar
+porque tras la descarga del fichero ya no estará disponible
+because after download the file will be no more available
+siccome dopo il download il file non sarà più disponibile
+protože soubor již nebude po stažení dostupný
+parce qu'après le téléchargement, le fichier ne sera plus disponible
+
+Contact <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a> if you want to fex to a mailing list
+Kontaktieren Sie den <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a> wenn Sie an eine Mailingliste fexen wollen
+Frog dr <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a> wenn Du an a Mailinglischt fexa wilsch
+Contacte con <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a> si desea hacer un envío a una lista de correo
+Contact <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a> if you want to fex to a mailing list
+Contatta <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster se vuoi fexare ad una lista di distribuzione
+Chcete-li poslat soubor do poštovní konference, kontaktujte <a href="mailto:$ENV{SERVER_ADMIN}">fexmastera</a>
+Contacter <a href="mailto:$ENV{SERVER_ADMIN}">fexmaster</a> si vous voulez fexer à une liste de diffusion
he can allow multiple downloads for specific addresses
er kann für bestimmte Adressen einen mehrfachen Download freischalten
der ko fir beschtemmte Adressa a mehrfaches Ronderlada erlauba
+el puede permitir múltipes descargas para una direcció,nespecífica
he can allow multiple downloads for specific addresses
-he can allow multiple downloads for specific addresses
-he can allow multiple downloads for specific addresses
-he can allow multiple downloads for specific addresses
-he can allow multiple downloads for specific addresses
-
+egli puo' permettere download multipli per indirizzi specifici
+ten může umožnit vícenásobná stahování pro určité adresy
+il peut autoriser plusieurs téléchargements pour des adresses spécifiques
+
+Use a <a href="/tools.html">F*EX client</a> if you want to send more than one file or resume an interrupted upload
+Verwenden Sie einen <a href="/tools.html">F*EX client</a> wenn Sie mehr als eine Datei versenden wollen oder einen abgebrochenen Upload wiederaufnehmen wollen
+Nemm an <a href="/tools.html">F*EX client</a> wenn du meh als oi Datei verschicka willsch oder an abbrochona Nufflad wiederaufnehma willsch
+Use un <a href="/tools.html">cliente F*EX</a> si desea enviar más de un fichero o continuar una subida interrumpida
+Use a <a href="/tools.html">F*EX client</a> if you want to send more than one file or resume an interrupted upload
+Usa <a href="/tools.html">F*EX client</a> se vuoi spedire più di un file o riesumare un upload interrotto
+Pokud chcete odeslat více než jeden soubor, nebo pokračovat v přerušeném nahrávání, použijte <a href="/tools.html">klienta pro F*EX</a>
+Utilisez un <a href="/tools.html">client F*EX</a> si vous voulez envoyer plus d'un fichier ou poursuivre un upload interrompue
+
You have to fill out this form completely to continue
Sie müssen dieses Formular komplett ausfüllen um fortzufahren
Du musch des Formular ganz ausffülla sonsch kosch ned weitrmacha
Wenn De meh als oi Datei verschigge willsch, no mach a zip oddr a tar Archiv
Si desea enviar más de un fichero póngalos en un archivo zip
De querer enviar más dun fichero póñaos nun arquivo zip
-Se vuoi spedire piu' di un file, mettili in un archivio zip o tar
+Se vuoi spedire più di un file, mettili in un archivio zip o tar
Chcete-li odeslat více jak jeden soubor, zkomprimujte jej do zip nebo tar archivu
Si vous voulez envoyer plus d'un fichier, mettez les dans un zip ou une archive tar
protože má příliš mnoho chyb
parce qu'il a beaucoup trop de problèmes
-We recommend Firefox or wget
-Wir empfehlen Ihnen Firefox oder wget
-Nemm lieber Firefox oder wget
-Recomendamos Firefox o wget
-Recomendámoslle Firefox ou wget
-Raccomandiamo di usare Firefox o wget
-Doporučujeme použít Firefox či wget
-Nous reconmmandons Firefox ou wget
+We recommend
+Wir empfehlen
+Mir empfehled
+Recomendamos
+Recomendamos
+Raccomandiamo
+Doporučujeme používat
+Nous recommandons
+
+#We recommend Firefox or wget
+#Wir empfehlen Ihnen Firefox oder wget
+#Nemm lieber Firefox oder wget
+#Recomendamos Firefox o wget
+#Recomendámoslle Firefox ou wget
+#Raccomandiamo di usare Firefox o wget
+#Doporučujeme použít Firefox či wget
+#Nous reconmmandons Firefox ou wget
+
+We recommend fexget or fexit for download
+Wir empfehlen fexget oder fexit fuer den Download
+Mir empfehlad fexget odr fexit firs Ronderlada
+Recomendamos fexget o fexit para la descarga
+We recommend fexget or fexit for download
+Raccomandiamo fexget o fexit per il download
+Pro stahování doporučujeme fexget nebo fexit,
+Nous recommandons fexget ou fexit pour un téléchargement
+
+because these clients can resume the download after an interruption
+weil diese Programme einen unterbrochenen Download wiederaufnehmen koennen
+weil Du mit dene Denger an abbrochana Ronderlad wiederaufnehma kosch
+porque estos clientes pueden continuar una descarga que ha sido interrumpida
+because these clients can resume the download after an interruption
+dato che questi clients possono riesumare il download dopo una interruzione
+protože tito klienti umožňují pokračovat ve stahování po přerušení
+parce que ces clients peuvent poursuivre un téléchargement après une interruption
After download (or view with a web browser!),
Nach Download (oder Ansicht mit dem Web Browser!)
-Nachm Ronderlada (oddr wenn Du se mit Deim Webbrowser oguckt hosch!)
+Nochm Ronderlada (odr wenn Du's mitm Webbrowser oguckt hosch!)
Tras la descarga,
Tras a descarga,
Dopo il download (o dopo essere stato visto con un browser WEB!)
$receiver = 'vy
$receiver = 'vous
-Comment:
-Kommentar:
-Kommendar:
-Comentario:
-Comentario:
-Commento:
-Komentář:
-Commentaire:
-
-" day"
-" Tag"
-" Dag"
-" día"
-" día"
-" giorno"
-" den"
-" jour"
-
-" days"
-" Tagen"
-" Dag"
-" días"
-" días"
-" giorni"
-" dnů"
-" jours"
-
-> days<
-> Tagen<
-> Dag<
-> días<
-> días<
-> giorni<
-> dnů<
-> jours<
+ day"
+ Tag"
+ Dag"
+ día"
+ día"
+ giorno"
+ den"
+ jour"
+
+ days"
+ Tagen"
+ Dag"
+ días"
+ días"
+ giorni"
+ dnů"
+ jours"
+
+ days<
+ Tagen<
+ Dag<
+ días<
+ días<
+ giorni<
+ dnů<
+ jours<
has uploaded the file
hat die Datei
to download this file within $days
um die Datei innerhalb von $days herunterzuladen
-damit Du dui Datei ennerhalb von $days ronderlade kosch
+damit Du dui Datei ennerhalb von $days ronderlada kosch
para descargar este fichero antes de $days
para descargar este fichero antes de $days
per scaricare questo file entro $days
zde klikněte pravým tlačítkem myši a vyberte "Uložit jako"
cliquez ici avec le bouton droit de la souris et sélectionner "save as"
-Meta questions
-Meta Fragen
-Meta Froga
-Meta Preguntas
-Meta Preguntas
-Meta Domande
-Všeobecné Máte otázky
-Questions générales
-
-User questions
-Benutzer Fragen
-Benutzr Froga
-Usario Preguntas
-Usuario Preguntas
-Utente Domande
-Uživatel Máte otázky
-Questions utilisateurs
-
-Admin questions
-Administratoren Fragen
-Adminischdrator Froga
-Admin Preguntas
-Admin Preguntas
-Amministratore Domande
-Správce Máte otázky
-Questions administrateur
-
-Misc questions
-Sonstige Fragen
-Vermischte Froga
-Misc Preguntas
-Misc Preguntas
-Misc Domande
-Misc Máte otázky
-Questions diverses
+#Meta questions
+#Meta Fragen
+#Meta Froga
+#Meta Preguntas
+#Meta Preguntas
+#Meta Domande
+#Všeobecné Máte otázky
+#Questions générales
+
+#User questions
+#Benutzer Fragen
+#Benutzr Froga
+#Usario Preguntas
+#Usuario Preguntas
+#Utente Domande
+#Uživatel Máte otázky
+#Questions utilisateurs
+
+#Admin questions
+#Administratoren Fragen
+#Adminischdrator Froga
+#Admin Preguntas
+#Admin Preguntas
+#Amministratore Domande
+#Správce Máte otázky
+#Questions administrateur
+
+#Misc questions
+#Sonstige Fragen
+#Vermischte Froga
+#Misc Preguntas
+#Misc Preguntas
+#Misc Domande
+#Misc Máte otázky
+#Questions diverses
Your F*EX account has been inactive for $expire days
Ihr F*EX Account ist seit $expire Tagen inaktiv