From: fextracker Date: Tue, 29 Mar 2016 02:00:03 +0000 (+0200) Subject: Original release 20160328 X-Git-Tag: 20160328 X-Git-Url: https://git.treefish.org/fex.git/commitdiff_plain/20160328?ds=sidebyside Original release 20160328 2016-03-11: fuc: added MIME headers to notification e-mail 2016-03-08: fexsend: added support for recipient:options 2016-03-07: fexsend,fexget: added update function to option -V 2016-03-04: install: fixed bug wrong permissions for /home/fex/locale/*/htdocs 2016-03-02: dop: run embedded <<<code>>> without return value output 2016-03-02: dop: 10 s timeout for (all) embedded <<code>> 2016-02-26: dop: run <<code>> within perl namespace (package) DOP 2016-02-25: fexsend: added option -T internet speed test 2016-02-22: fexit: added internet speed test 2016-02-11: fexit: added option -s file streaming 2016-02-08: added @extra_header config with default security settings for 2016-02-08: Content-Security-Policy, X-Frame-Options, X-XSS-Protection, 2016-02-08: X-Content-Type-Options 2016-02-03: fup: every address or alias can have attached :options 2016-02-03: (keep,autodelete,locale) 2016-01-29: fexit: added xx clipboard support 2016-01-21: fexsend: fixed bug not working cgi-bin/login 2016-01-15: fup: fixed bug UTF8 error in italian source 2016-01-14: fup: fixed bug after login $info_login instead of $info_1 is 2016-01-14: displayed --- diff --git a/bin/afex b/bin/afex index f9b1a0c..f78c205 100755 --- a/bin/afex +++ b/bin/afex @@ -130,7 +130,7 @@ sub guessserver { my $fexserver = ''; my $rc = '/etc/resolv.conf'; local $_; - + open $rc,$rc or die "$0: cannot open $rc - $!\n"; while (<$rc>) { if (/^\s*domain\s+([\w.-]+)/) { diff --git a/bin/ezz b/bin/ezz index c15ece3..523dc8c 100755 --- a/bin/ezz +++ b/bin/ezz @@ -23,7 +23,7 @@ Examples: ezz head -3 ezz - head -3 -Limitation: zz does not work across different accounts! +Limitation: zz does not work across different accounts! EOD } diff --git a/bin/fbm b/bin/fbm index 96d2a22..1d9c10d 100755 --- a/bin/fbm +++ b/bin/fbm @@ -20,7 +20,7 @@ use constant M => 2**20; our ($SH,$windoof,$sigpipe,$useragent); our ($FEXSERVER); -our $version = 20160104; +our $version = 20160328; # server defaults my $server = 'fex.rus.uni-stuttgart.de'; @@ -46,7 +46,7 @@ options: -n do not store on server -P use proxy server:port examples: $0 1000 EOD - + if ($Config{osname} =~ /^mswin/i) { $windoof = $Config{osname}; $useragent = sprintf("fbm-$version (%s %s)", @@ -78,7 +78,7 @@ if ($opt_h) { exit; } -if ($opt_P) { +if ($opt_P) { if ($opt_P =~ /^[\w.-]+:\d+/) { $proxy = $opt_P; } else { @@ -111,9 +111,9 @@ print "Testing $server:\n"; id => $id, comment => $opt_n ? 'NOSTORE' : 'NOMAIL', keep => 1, - autodelete => 'YES', + autodelete => 'YES', ); - + if (not @r or not grep /\w/,@r) { die "$0: no response from server\n"; } @@ -130,12 +130,12 @@ if (($r) = grep /^Location: http/,@r) { } else { download("/ddd/$mb"); } - + exit; sub formdatapost { - my %P = @_; + my %P = @_; my ($boundary,$filename,$filesize,$length); my (@hh,@hb,@r,@pv); my ($t,$bt,$t0,$t1,$t2,$tt); @@ -148,10 +148,10 @@ sub formdatapost { @r = (); serverconnect($server,$port); - + $boundary = randstring(48); $P{command} = 'CHECKRECIPIENT'; - + # HTTP POST variables @pv = qw'from to id command'; foreach my $v (@pv) { @@ -213,7 +213,7 @@ sub formdatapost { push @hb,$P{$v}; } } - + # at last, the file push @hb,"--$boundary"; push @hb,"Content-Disposition: form-data; name=\"FILE\"; filename=\"$filename\""; @@ -242,12 +242,12 @@ sub formdatapost { pop @hb; pop @hb; nvtsend(@hh,@hb) or die "$0: server has closed the connection\n"; - + $t0 = $t2 = int(time); $t1 = 0; - + autoflush $SH 0; - + for (;;) { print {$SH} $buf or die "$0: server has closed the connection\n"; $b += $bs; @@ -275,7 +275,7 @@ sub formdatapost { } last if $bt >= $mb*M; } - + autoflush $SH 1; print {$SH} "\r\n--$boundary--\r\n"; @@ -285,14 +285,14 @@ sub formdatapost { last if @r and $r[0] =~ / 204 / and /^$/ or /<\/html>/i; push @r,$_; } - + $tt = (time-$t0)||1; printf STDERR "upload: %d MB in %d s, %d kB/s \n", int($bt/M),$tt,int($bt/k/$tt); - + close $SH; undef $SH; - + return @r; } @@ -312,7 +312,7 @@ sub serverconnect { my ($server,$port) = @_; my $connect = "CONNECT $server:$port HTTP/1.1"; local $_; - + if ($proxy) { tcpconnect(split(':',$proxy)); if ($port == 443) { @@ -337,12 +337,12 @@ sub serverconnect { # set up tcp/ip connection sub tcpconnect { my ($server,$port) = @_; - + if ($SH) { close $SH; undef $SH; } - + if ($port == 443) { eval "use IO::Socket::SSL"; die "$0: cannot load IO::Socket::SSL\n" if $@; @@ -358,25 +358,25 @@ sub tcpconnect { Proto => 'tcp', ); } - + if ($SH) { autoflush $SH 1; } else { die "$0: cannot connect $server:$port - $@\n"; } - + print "TCPCONNECT to $server:$port\n" if $opt_v; } sub nvtsend { local $SIG{PIPE} = sub { $sigpipe = "@_" }; - + $sigpipe = ''; - + die "$0: internal error: no active network handle\n" unless $SH; die "$0: remote host has closed the link\n" unless $SH->connected; - + foreach my $line (@_) { print {$SH} $line,"\r\n"; if ($sigpipe) { @@ -384,7 +384,7 @@ sub nvtsend { return 0; } } - + return 1; } @@ -403,7 +403,7 @@ sub download { local $_; serverconnect($server,$port); - + sendheader( "GET $proxy_prefix$fop HTTP/1.1", "User-Agent: $useragent", @@ -459,7 +459,7 @@ sub download { sub sendheader { my @head = @_; my $head; - + foreach $head (@head) { print "--> $head\n" if $opt_v; print {$SH} $head,"\r\n"; diff --git a/bin/fex_cleanup b/bin/fex_cleanup index 2dabc00..1d87dcf 100755 --- a/bin/fex_cleanup +++ b/bin/fex_cleanup @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl -w # cleanup for F*EX service # @@ -14,7 +14,7 @@ use Cwd 'abs_path'; use Digest::MD5 'md5_hex'; use constant DS => 60*60*24; - + # do not run as CGI! exit if $ENV{SCRIPT_NAME}; @@ -48,7 +48,7 @@ require "$FEXLIB/fex.pp" or die "$0: cannot load $FEXLIB/fex.pp - $!\n"; my $logdir = $logdir[0]; -# localized functions +# localized functions # (needed for reminder and account reactivation e-mails) foreach my $lf (glob "$FEXHOME/locale/*/lib/lf.pl") { require $lf } @@ -134,7 +134,7 @@ closedir $spooldir; # clean up download key lookup directory if (chdir $dkeydir and opendir D,'.') { while ($file = readdir D) { - if ($link = readlink $file and + if ($link = readlink $file and (not -l "$link/dkey" or readlink "$link/dkey" ne $file)) { logdel($file,".dkeys/$file deleted"); } @@ -312,7 +312,7 @@ if (chdir "$spooldir/.reg" and opendir D,'.') { closedir D; } -# send account expiration warning +# send account expiration warning if ($account_expire and $account_expire =~ /^(\d+)/) { my $expire = $1; if (chdir $spooldir) { @@ -374,7 +374,7 @@ if (%vhost) { } } -if ($notify_newrelease and $notify_newrelease !~ /^no$/i +if ($notify_newrelease and $notify_newrelease !~ /^no$/i or not defined $notify_newrelease) { $notify_newrelease ||= $admin; $newnew = $new = ''; @@ -383,6 +383,7 @@ if ($notify_newrelease and $notify_newrelease !~ /^no$/i $_ = slurp("$FEXHOME/doc/version")||''; if (/(\d+)/) { $qn = "new?$hostname:$1" } else { $qn = "new?$hostname:0" } + print "checking for new F*EX release\n" if $opt_v; for (1..3) { sleep rand(10); $newnew = `wget -qO- http://fex.belwue.de/$qn 2>/dev/null`; @@ -422,7 +423,7 @@ sub cleanup { my $kf = "$to/$from/$file/keep"; my $ef = "$to/$from/$file/error"; local $_; - + $keep = readlink $kf || readlink "$to/\@KEEP" || $keep_default; $file = "$to/$from/$file"; @@ -451,7 +452,7 @@ sub cleanup { $delay = 1 if $delay !~ /^\d+$/; $delay--; $mtime = lmtime($download); - if ($mtime and $today > $delay*DS+$mtime + if ($mtime and $today > $delay*DS+$mtime and logdel($data,"$data deleted")) { if (open $ef,'>',$ef) { printf {$ef} "%s has been autodeleted after download at %s\n", @@ -491,7 +492,7 @@ sub cleanup { # also _fexmail_* logdel($file,"$file deleted") and verbose("rmrf $file (today=$today mtime_upload=$mtime)"); - } elsif (logdel($data,"$data deleted")) { + } elsif (logdel($data,"$data deleted")) { verbose("unlink $data (today=$today mtime=$mtime keep=$keep)"); if (open $ef,'>',$ef) { $filename = $file; @@ -501,13 +502,13 @@ sub cleanup { } } } - } + } elsif ($file !~ /STDFEX$/ and - $mtime+$warn*DS < $today and + $mtime+$warn*DS < $today and $dkey = readlink("$file/dkey") and - not -s $download and - not -f $notify and - (readlink("$to/\@REMINDER")||'yes') ne 'no') + not -s $download and + not -f $notify and + (readlink("$to/\@REMINDER")||'yes') ne 'no') { my $locale = readlink "$to/\@LOCALE" || readlink "$file/\@LOCALE"; $locale = 'english' unless $locale and $notify{$locale}; @@ -545,7 +546,7 @@ sub autodelete { chomp($autodelete = <$adf>||''); close $adf; } - + return $autodelete||$::autodelete; } @@ -563,7 +564,7 @@ sub logdel { warn "$file DEL FAILED : $!\n" if -t or $opt_v; } } - + return $status; } diff --git a/bin/fexget b/bin/fexget index c375cea..b0616a1 100755 --- a/bin/fexget +++ b/bin/fexget @@ -30,10 +30,11 @@ our $SH; our ($fexhome,$idf,$tmpdir,$windoof,$useragent); our ($xv,%autoview); our $bs = 2**16; # blocksize for tcp-reading and writing file -our $version = 20160104; +our $version = 20160328; our $CTYPE = 'ISO-8859-1'; our $fexsend = $ENV{FEXSEND} || 'fexsend'; our $DEBUG = $ENV{DEBUG}; +our $_0 = $0; my %SSL = (SSL_version => 'TLSv1'); my $sigpipe; @@ -150,7 +151,7 @@ $opt_V = $opt_X = $opt_f = $opt_L = $opt_H = 0; ${'opt_+'} = 0; $opt_s = $opt_k = $opt_i = $opt_P = ''; $_ = "$fexhome/config.pl"; require if -f; -getopts('hvVHlLdkzoaXf+m:s:i:K:P:') or die $usage; +getopts('hvVHlLdkzoaXVf+m:s:i:K:P:') or die $usage; $opt_k = '?KEEP' if $opt_k; if ($opt_m =~ /(\d+)/) { @@ -159,7 +160,27 @@ if ($opt_m =~ /(\d+)/) { $opt_m = 0 } -print "Version: $version\n" if $opt_V; +if ($opt_V) { + print "Version: $version\n"; + unless (@ARGV) { + print "Upgrade fexget? "; + $_ = ||''; + if (/^y/i) { + my $new = `wget -nv -O- http://fex.belwue.de/download/fexget`; + if ($new !~ /upgrade fexget/) { + die "$0: bad update\n"; + } + system qw'cp -a',$_0,$_0.'_old'; + exit $? if $?; + open $_0,'>',$_0 or die "$0: cannot write $_0. - $!\n"; + print {$_0} $new; + close $_0; + exec $_0,qw'-V .'; + } + } + exit if "@ARGV" eq '.'; +} + die $usage if $opt_h; if ($opt_H) { print $hints; @@ -172,15 +193,14 @@ my $ffl = "$tmpdir/fexget"; # F*EX files list (cache) my @rcamel = ( ' -(_*) _ _ - \\\\/ \\/ \\ + (_*p _ _ + \\\\/ \/ \\ \ __ )=* //\\\\//\\\\ ', -' \\\\/\\\\/ -', -' //\\\\//\\\\ -'); +" \\\\/\\\\/ \n", +" //\\\\//\\\\\n" +); # get fexlog if ($opt_z) { @@ -566,7 +586,7 @@ sub keep { sub download { my ($server,$port,$fop,$nocheck) = @_; - my ($file,$download,$ssl,$pipe,$filesize,$checkstorage); + my ($file,$download,$ssl,$pipe,$filesize,$checkstorage,$dkey); my (@hh,@r); my ($t0,$t1,$t2,$tt,$tm,$ts,$kBs,$b,$bt,$tb,$B,$buf); my $length = 0; @@ -619,8 +639,11 @@ sub download { $seek = -s $download || 0; } + $fop =~ m:/fop/(\w+)/: and $dkey=$1 or $dkey=''; + push @hh,"GET $proxy_prefix$fop$opt_k HTTP/1.1", "User-Agent: $useragent", + "Cookie: dkey=$dkey", "Connection: close"; push @hh,"Range: bytes=$seek-" if $seek; diff --git a/bin/fexsend b/bin/fexsend index 7e498dc..f47bed4 100755 --- a/bin/fexsend +++ b/bin/fexsend @@ -37,7 +37,7 @@ our ($tpid,$frecipient); our ($FEXID,$FEXXX,$HOME); our (%alias); our $chunksize = 0; -our $version = 20160104; +our $version = 20160328; our $_0 = $0; our $DEBUG = $ENV{DEBUG}; @@ -45,6 +45,7 @@ my %SSL = (SSL_version => 'TLSv1'); my $sigpipe; if ($Config{osname} =~ /^mswin/i) { + # http://slu.livejournal.com/17395.html $windoof = $Config{osname}; $HOME = $ENV{USERPROFILE}; $fexhome = $ENV{FEXHOME} || $HOME.'\fex'; @@ -55,8 +56,8 @@ if ($Config{osname} =~ /^mswin/i) { $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 + $macos = $Config{osname}; $HOME = (getpwuid($<))[7]||$ENV{HOME}; $fexhome = $HOME.'/.fex'; $tmpdir = $ENV{FEXTMP} || $ENV{TMPDIR} || "$fexhome/tmp"; @@ -142,10 +143,11 @@ special options: -I initialize ID file or show ID -d \# delete file on fex server -N \# resend notification e-mail -Q check quotas + -T up:down test internet speed with up and down MBs -A edit server address book (aliases) -S show server/user settings and auth-ID -H show hints, examples and more options - -V show version + -V show version and ask for upgrade (# 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 @@ -231,7 +233,7 @@ whereas archive types zip and 7z need a temporary archive file on local disk. 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 URL parameter, e.g.: +With option -X you can specify any URL parameter, e.g.: fexsend -X autodelete=yes ... fexsend -X 'autodelete=no&locale=german' ... @@ -286,11 +288,22 @@ my @rcamel = ( *=( __ / \\\\/\\\\/ ', -' \\\\/\\\\/ +" \\\\/\\\\/ \n", +" //\\\\//\\\\\n" +); + +my @rrcamel = ( +' + (_*p _ _ + \\\\/ \/ \\ + \ __ )=* + //\\\\//\\\\ ', -' //\\\\//\\\\ -'); +" \\\\/\\\\/ \n", +" //\\\\//\\\\\n" +); +autoflush STDOUT; autoflush STDERR; if ($windoof and not @ARGV and not $ENV{PROMPT}) { @@ -312,7 +325,7 @@ my @_ARGV = @ARGV; # save arguments our ($opt_q,$opt_h,$opt_H,$opt_v,$opt_m,$opt_c,$opt_k,$opt_d,$opt_l,$opt_I, $opt_K,$opt_D,$opt_u,$opt_f,$opt_a,$opt_C,$opt_R,$opt_M,$opt_L,$opt_Q, $opt_A,$opt_i,$opt_z,$opt_Z,$opt_b,$opt_P,$opt_x,$opt_X,$opt_V,$opt_U, - $opt_s,$opt_o,$opt_g,$opt_F,$opt_n,$opt_r,$opt_S,$opt_N); + $opt_s,$opt_o,$opt_g,$opt_F,$opt_n,$opt_r,$opt_S,$opt_N,$opt_T); if ($xx) { $opt_q = 1 if @ARGV and $ARGV[-1] eq '--' and pop @ARGV or not -t STDOUT; @@ -331,9 +344,9 @@ if ($xx) { ${'opt_@'} = ${'opt_!'} = ${'opt_+'} = ${'opt_.'} = ${'opt_/'} = 0; ${'opt_='} = ${'opt_#'} = ''; $opt_u = $opt_f = $opt_a = $opt_C = $opt_i = $opt_b = $opt_P = $opt_X = ''; - $opt_s = $opt_r = ''; + $opt_s = $opt_r = $opt_T = ''; $_ = "$fexhome/config.pl"; require if -f; - getopts('hHvcdognVDKlILUARWMFzZqQS@!+./r:m:k:u:f:a:s:C:i:b:P:x:X:N:=:#:') + getopts('hHvcdognVDKlILUARWMFzZqQS@!+./r:m:k:u:f:a:s:C:i:b:P:x:X:N:T:=:#:') or die $usage; if ($opt_H) { @@ -343,6 +356,23 @@ if ($xx) { if ($opt_V) { print "Version: $version\n"; + unless (@ARGV) { + print "Upgrade fexsend? "; + $_ = ||''; + if (/^y/i) { + my $new = `wget -nv -O- http://fex.belwue.de/download/fexsend`; + if ($new !~ /upgrade fexsend/) { + die "$0: bad update\n"; + } + system qw'cp -aL',$_0,$_0.'_old'; + exit $? if $?; + open $_0,'>',$_0 or die "$0: cannot write $_0. - $!\n"; + print {$_0} $new; + close $_0; + exec $_0,qw'-V .'; + } + } + exit if "@ARGV" eq '.'; } if ($opt_K and $opt_D) { @@ -477,6 +507,29 @@ if ($opt_I) { exit; } +if ($opt_T) { + my ($up,$down); + + $usage = "usage: $0 -T MB_up[:MB_down] [fexserver]\n"; + if ($opt_T =~ /^(\d+)$/) { + $up = $down = $1; + } elsif ($opt_T =~ /^(\d+):(\d+)$/) { + $up = $1; + $down = $2; + } else { + die $usage; + } + + if (@ARGV) { + nettest($ARGV[0],$up,$down); + } elsif ($fexcgi) { + nettest($fexcgi,$up,$down); + } else { + nettest('fex.belwue.de',$up,$down); + } + exit; +} + if (@ARGV > 1 and $ARGV[-1] =~ /(^|\/)anonymous/) { $fexcgi = $1 if $ARGV[-1] =~ s:(.+)/::; die "usage: $0 [options] file FEXSERVER/anonymous\n" unless $fexcgi; @@ -805,7 +858,7 @@ sub menu { my $key; my $new; local $_; - + system 'clear'; print "\n"; print "fexsend-$version\n"; @@ -824,7 +877,7 @@ sub menu { print "\n"; print "$from on $fexcgi\n"; print "\n"; - + for (;;) { print "\n"; print "[s] send a file or directory\n"; @@ -835,15 +888,15 @@ sub menu { print "\n"; print "your choice: "; $key = ReadKey(0); - if ($key eq 'q') { + if ($key eq 'q') { print "$key\n"; print "\n"; print "Type [Cmd]W to close this window.\n"; exit; } - if ($key eq 'h') { + if ($key eq 'h') { print "$key\n"; - print + print "\n". "With fexsend you can send files of any size to any e-mail address.\n". "\n". @@ -855,10 +908,10 @@ sub menu { "\n". "Do not forget to terminate each input line with [RETURN].\n". "\n". - "See http://fex.rus.uni-stuttgart.de/ for more informations.\n"; + "See http://fex.rus.uni-stuttgart.de/ for more information.\n"; next; } - if ($key eq 'u') { + if ($key eq 'u') { print "$key\n"; if ($0 =~ m:(^/client/|/sw/):) { print "\n"; @@ -878,13 +931,13 @@ sub menu { } next; } - if ($key eq 'l') { + if ($key eq 'l') { print "$key\n"; system 'clear'; &set_ID; next; } - if ($key eq 's' or $key eq "\n") { + if ($key eq 's' or $key eq "\n") { print "s\n"; &ask_file; next; @@ -900,9 +953,9 @@ sub ask_file { my @files; my $qfiles; local $_; - + system 'clear'; - + &set_ID unless -s $idf; print "\n"; @@ -1021,7 +1074,7 @@ sub ask_file { sub set_ID { my ($server,$port,$user,$logo); local $_; - + print "\n"; for (;;) { print "F*EX server URL: "; @@ -1071,7 +1124,6 @@ sub set_ID { sendheader( "$server:$port", "GET /logo.jpg HTTP/1.0", - "User-Agent: $useragent", "Connection: close", ); $_ = <$SH>||''; @@ -1092,7 +1144,7 @@ sub set_ID { close $logo; last; } - + for (;;) { last if $user; print "Your login (e-mail address): "; @@ -1103,14 +1155,14 @@ sub set_ID { next; } } - + for (;;) { last if $id; print "Your auth-ID for this account: "; $id = ; $id =~ s/[\s\n]//g; } - + open $idf,'>',$idf or die "$0: cannot write to $idf - $!\n"; print {$idf} "$server\n", "$user\n", @@ -1131,11 +1183,111 @@ sub set_ID { } + +sub nettest { + my $url = shift; + my $up = shift; + my $down = shift; + my $bs = 2**16; + my ($length,$t0,$t1,$t2,$tt,$tb,$tc,$B,$kBs,$bt); + + my $nettest = $sid = 'nettest'; + + $port ||= 80; + if ($url =~ s:^https.//::) { + $https = $port = 443; + } else { + $url =~ s:^http.//::; + $port = $1 if $url =~ s/:(\d+)//; + } + $url =~ s/[\/:].*//; + $server = $url; + + if ($up) { + serverconnect($server,$port); + checkrecipient($nettest,$nettest); + warn "$0: send to $server:$port\n"; + formdatapost( + from => $nettest, + to => $nettest, + id => $nettest, + file => $nettest, + size => $up*M, + comment => 'NOSTORE', + ); + } + + if ($down) { + serverconnect($server,$port); + warn "$0: receive from $server:$port\n"; + sendheader("$server:$port","GET $proxy_prefix/ddd/$down HTTP/1.0"); + $_ = <$SH>; + die "$0: no response from fex server $server\n" unless $_; + s/\r//; + + if (/^HTTP\/[\d.]+ 2/) { + warn "<-- $_" if $opt_v; + while (<$SH>) { + s/\r//; + print "<-- $_" if $opt_v; + last if /^$/; + $length = $1 if /^Content-Length:\s*(\d+)/i; + } + } else { + s/HTTP\/[\d.]+ \d+ //; + die "$0: bad server reply: $_"; + } + + unless ($length) { + die "$0: no Content-Length header in server reply\n"; + } + + + if (${'opt_+'}) { + print $rrcamel[0]; + $tc = 0; + } + + $t0 = $t1 = $t2 = int(time); + $B = 0; + while ($B < $length) { + $b = read $SH,$_,$bs or die "$0: cannot read after $B bytes - $!\n"; + # defined($_ = <$SH>) or die "$0: cannot read after $B bytes - $!\n"; + # $b = length; + $B += $b; + $bt += $b; + $t2 = time; + if (${'opt_+'} and int($t2*10)>$tc) { + print $rrcamel[$tc%2+1]; + $tc = int($t2*10); + } + if (int($t2) > $t1) { + $kBs = int($bt/k/($t2-$t1)); + $t1 = $t2; + $bt = 0; + printf STDERR "nettest: %d MB (%d%%) %d kB/s \r", + int($B/M),int(100*$B/$length),$kBs; + } + } + close $SH; + + $tt = $t2-$t0; + $kBs = int($B/k/($tt||1)); + if (${'opt_+'}) { + print $rrcamel[1]; + print $rrcamel[2]; + } + printf STDERR "nettest: %d MB in %d s = %d kB/s \n", + int($B/M),$tt,$kBs; + } +} + + # 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) { @@ -1339,7 +1491,6 @@ sub list { sendheader( "$server:$port", "GET $proxy_prefix/fop/$2/$2?LIST HTTP/1.1", - "User-Agent: $useragent", ); $_ = <$SH>||''; s/\r//; @@ -1364,7 +1515,7 @@ sub list { die "$0: file \#$a not found in fexlist\n"; } } - + @r = formdatapost( from => $from, to => $opt_l ? '*' : $from, @@ -1391,7 +1542,7 @@ sub list { s/&/&/g; s/"/\"/g; s/</||''; s/\r//; @@ -1528,14 +1678,13 @@ sub delete_file { 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; @@ -1917,7 +2066,7 @@ sub send_fex { } } if ($from eq $to or $from =~ /^\Q$to\E@/i - or $nomail or $anonymous or $nonot) + or $nomail or $anonymous or $nonot) { print "$recipient\n" if $recipient; print "$location\n" if $location; @@ -2174,10 +2323,10 @@ sub get_xx { sub formdatapost { my %P = @_; - my ($boundary,$filename,$length,$buf,$file,$fpsize,$resume,$seek); + my ($boundary,$filename,$length,$buf,$file,$fpsize,$resume,$seek,$nettest); my ($flink); my (@hh,@hb,@r,@pv,$to); - my ($bytes,$t,$bt); + my ($bytes,$b,$t,$bt); my ($t0,$t1,$t2,$tt,$tc); my $bs = 2**16; # blocksize for reading and sending file my $fileid = int(time); @@ -2285,7 +2434,7 @@ sub formdatapost { } # print "calculating archive size... "; debug("cd $dittodir;$ditto -"); - open $ditto,"cd $dittodir;$ditto - 2>$error|" + 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) { @@ -2315,6 +2464,12 @@ sub formdatapost { undef $SH; # force reconnect (timeout!) } + elsif ($P{to} eq 'nettest') { + $filename = $nettest = 'nettest'; + $filesize = $P{size}; + $fileid = 0; + } + # single file else { $filename = encode_utf8(${'opt_='} || $file); @@ -2334,7 +2489,7 @@ sub formdatapost { $filename .= '.gpg' if $opt_g; - unless ($opt_d) { + unless ($opt_d or $nettest) { if ($opt_g) { $filesize = -1; $fileid = int(time); @@ -2363,7 +2518,7 @@ sub formdatapost { unless ($SH) { serverconnect($server,$port); - query_sid($server,$port) unless $anonymous; + query_sid($server,$port) unless $anonymous or $nettest; } $P{id} = $sid; # ugly hack! @@ -2371,7 +2526,7 @@ sub formdatapost { $filename =~ s/\\/_/g; # \ is a illegal character for fexsrv # ask server if this file has been already sent - if ($file and not $xx) { + if ($file and not $xx and not $nettest) { if (not $opt_d and $opt_o) { # delete before overwrite delete_file($from,$to,$filename); @@ -2548,6 +2703,8 @@ sub formdatapost { print "Fast forward to byte $seek (resuming)\n"; readahead($file,$seek); } + } elsif ($nettest) { + # } else { if ($opt_g) { my $fileq = quote($file); @@ -2564,8 +2721,17 @@ sub formdatapost { print $rcamel[0] if ${'opt_+'}; + $buf = '#' x $bs if $nettest; + $SIG{ALRM} = sub { retry("timed out") }; - while (my $b = read $file,$buf,$bs) { + + while ($bytes < $fpsize) { + if ($nettest) { + $b = $bs; + } else { + $b = read $file,$buf,$bs; + last if $b == 0; + } alarm($timeout*2); if ($https) { print {$SH} $buf or &sigpipehandler; @@ -2574,7 +2740,7 @@ sub formdatapost { } alarm(0); $bytes += $b; - if ($filesize > 0 and $bytes+$seek > $filesize) { + if (not $nettest and $filesize > 0 and $bytes+$seek > $filesize) { if ($tpid) { kill 9,$tpid; unlink $list; @@ -2619,7 +2785,9 @@ sub formdatapost { last if $filesize > 0 and $bytes >= $fpsize; sleep 1 while ($opt_m and $bytes/k/(time-$t0||1) > $opt_m); } - close $file; # or die "$0: error while reading $file - $!\n"; + + close $file unless $nettest; + $tt = ($t2-$t0)||1; print $rcamel[2] if ${'opt_+'}; @@ -2630,7 +2798,7 @@ sub formdatapost { kill 9,$tpid; unlink $list; } - + if ($fileid =~ /[a-z]/ and not ($opt_s or $opt_g)) { if ($opt_a) { if ($fileid ne md5_hex(fmd(@ARGV))) { @@ -2644,7 +2812,7 @@ sub formdatapost { } } } - + unless ($opt_q) { if (not $chunksize and $bytes+$seek < $filesize) { die "$0: \"$file\" filesize has shrunk while uploading\n"; @@ -2652,7 +2820,7 @@ sub formdatapost { if ($seek or $chunksize and $chunksize < $filesize) { if ($fpsize>2*M) { - printf STDERR "%s: %d MB in %d s (%d kB/s)", + printf STDERR "%s: %d MB in %d s = %d kB/s", $opt_s||$opt_a||$file, int($bytes/M), $tt, @@ -2664,7 +2832,7 @@ sub formdatapost { $chunk,int(($bytes+$seek)/M); } } else { - printf STDERR "%s: %d kB in %d s (%d kB/s)", + printf STDERR "%s: %d kB in %d s = %d kB/s", $opt_s||$opt_a||$file, int($bytes/k), $tt, @@ -2678,13 +2846,13 @@ sub formdatapost { } } else { if ($bytes>2*M) { - printf STDERR "%s: %d MB in %d s (%d kB/s) \n", + printf STDERR "%s: %d MB in %d s = %d kB/s \n", $opt_s||$opt_a||$file, int($bytes/M), $tt, int($bytes/k/$tt); } else { - printf STDERR "%s: %d kB in %d s (%d kB/s) \n", + printf STDERR "%s: %d kB in %d s = %d kB/s \n", $opt_s||$opt_a||$file, int($bytes/k), $tt, @@ -2692,7 +2860,7 @@ sub formdatapost { } } - if (-t STDOUT and not ($opt_s or $opt_g)) { + if (-t STDOUT and not ($opt_s or $opt_g or $nettest)) { print STDERR "waiting for server ok..." } } @@ -2700,6 +2868,7 @@ sub formdatapost { autoflush $SH 1; print {$SH} "\r\n--$boundary--\r\n"; + # return if $nettest; # special handling of streaming file because of stunnel tcp shutdown bug if ($opt_s or $opt_g) { @@ -2860,8 +3029,7 @@ sub query_file { my ($response,$fexsrv,$cc); local $_; - $to =~ s/,.*//; - $to =~ s/:\w+=.*//; + $to =~ s/[,:].*//; $to = $AB{$to} if $AB{$to}; $filename =~ s/([^_=:,;<>()+.\w\-])/'%'.uc(unpack("H2",$1))/ge; # urlencode if ($skey) { @@ -3040,12 +3208,12 @@ sub query_sid { if ($port eq 443 or $proxy) { return if $features; # early return if we know enough $req = "OPTIONS /FEX HTTP/1.1"; - $req = "HEAD / HTTP/1.1"; + $req = "HEAD /index.html HTTP/1.1"; } else { $req = "GET /SID HTTP/1.1"; } - sendheader("$server:$port",$req,"User-Agent: $useragent"); + sendheader("$server:$port",$req); $_ = <$SH>; unless (defined $_ and /\w/) { print "\n" if $opt_v; @@ -3059,7 +3227,7 @@ sub query_sid { close $SH; serverconnect($server,$port); $req = "GET /SID HTTP/1.0"; - sendheader("$server:$port",$req,"User-Agent: $useragent"); + sendheader("$server:$port",$req); $_ = <$SH>; unless (defined $_ and /\w/) { print "\n" if $opt_v; @@ -3129,7 +3297,7 @@ sub xxget { $xx =~ s:.*/::; $url = "$proxy_prefix/fop/$from/$from/$xx?ID=$id"; - sendheader("$server:$port","GET $url HTTP/1.0","User-Agent: $useragent"); + sendheader("$server:$port","GET $url HTTP/1.0"); http_response(); while (<$SH>) { s/\r//; @@ -3218,6 +3386,7 @@ sub checkrecipient { $_ = shift @r or die "$0: no reply from server\n"; if (/ 2\d\d /) { + return if $to eq 'nettest'; foreach (@r) { last if /^$/; if (s/X-(Recipient: .+)/$1\n/) { @@ -3301,7 +3470,7 @@ sub readahead { sub fileid { my $file = shift; my @s = stat($file); - + if (@s) { return md5_hex($file.$s[0].$s[1].$s[7].$s[9]); } else { @@ -3314,9 +3483,10 @@ sub fileid { sub get_mutt_alias { my $to = shift; my $ma = $HOME.'/.mutt/aliases'; - my $alias; + my ($alias,$options); local $_; + $to =~ s/(:.+)// and $options = $1; open $ma,$ma or return $to; while (<$ma>) { if (/^alias \Q$to\E\s/i) { @@ -3333,11 +3503,13 @@ sub get_mutt_alias { if (/@/) { $alias = $_; warn "$0: found mutt alias $to = $alias\n"; + $alias .= $options if $options; last; } } } close $ma; + $to = "$to:$options" if $options; return ($alias||$to); } @@ -3623,8 +3795,10 @@ sub sendheader { my $head; push @head,"Host: $sp"; + push @head,"User-Agent: $useragent"; foreach $head (@head) { + chomp $head; print "--> $head\n" if $opt_v; print {$SH} $head,"\r\n"; } diff --git a/bin/fexsrv b/bin/fexsrv index e89b6f9..8bef7fc 100755 --- a/bin/fexsrv +++ b/bin/fexsrv @@ -254,7 +254,7 @@ REQUEST: while (*STDIN) { # reverse-proxy? # (only IPv4 support!) if ($reverse_proxy_ip and $reverse_proxy_ip eq $ra and - /^\S*(Forwarded|Client-IP|Coming-From)\S*: ([\d.]+)/i + /^\S*(Forwarded|Client-IP|Coming-From)\S*: ([\da-f:.]+)/i ) { $ENV{REMOTE_ADDR} = $ra = $2; $ENV{REMOTE_HOST} = $rh = gethostbyaddr(inet_aton($ra),AF_INET) || ''; @@ -881,6 +881,7 @@ sub redirect { '' )); } + fexlog($connect,@log,"REDIRECT $newurl"); if ($rr =~ /^http/) { exit; } else { diff --git a/bin/fexwall b/bin/fexwall index c632e15..09dec2e 100755 --- a/bin/fexwall +++ b/bin/fexwall @@ -42,7 +42,7 @@ our ($FEXHOME,$hostname,$sendmail,$spooldir,$admin,$bcc); # load common code, local config : $HOME/lib/fex.ph require "$FEXLIB/fex.pp" or die "$0: cannot load $FEXLIB/fex.pp - $!\n"; -die "$0: \$admin not configured in $FEXLIB/fex.ph\n" +die "$0: \$admin not configured in $FEXLIB/fex.ph\n" if not $admin or $admin =~ /example.org/; $opt_h = 0; @@ -83,7 +83,7 @@ foreach $group (glob "*/\@GROUP/*") { close $group; } } - + foreach $subuser (glob "*/\@SUBUSER") { if (open $subuser,$subuser) { while (<$subuser>) { @@ -94,7 +94,7 @@ foreach $subuser (glob "*/\@SUBUSER") { close $subuser; } } - + # @users = qw'framstag@fex'; die "$0: no users found\n" unless @users or grep /@/,@users; push @users,$bcc; diff --git a/bin/fpg b/bin/fpg index be610fe..5f2f751 100755 --- a/bin/fpg +++ b/bin/fpg @@ -8,7 +8,7 @@ # 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 +# 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 @@ -27,7 +27,7 @@ sub usage { die <) { $_ .= "\n" unless /\n$/; if ($opt_M) { @@ -248,9 +248,9 @@ sub grepf { $C{0} = [$l,$_]; } if ($opt_e) { - if ($opt_v) { + if ($opt_v) { next if &$egrep; - } else { + } else { unless (&$egrep) { if ($opt_C and $c) { print "$l:" if $opt_n; @@ -276,16 +276,16 @@ sub grepf { if ($opt_Q) { $n++ while /$exp/mg } else { $n++ while /$exp/omg } } else { - if ($opt_o) { + if ($opt_o) { my $m = ''; while (s/($exp)//) { $n++; $m .= "$1\n"; } $_ = $m; - } elsif ($opt_Q) { + } elsif ($opt_Q) { $n += s/($exp)/$B$1$N/mg; - } else { + } else { $n += s/($exp)/$B$1$N/omg; } } @@ -309,7 +309,7 @@ sub grepf { $file = ''; } if ($opt_x and $n) { - if ($opt_i) { s/($opt_x)/$B$1$N/ogi } + 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--) { @@ -327,7 +327,7 @@ sub grepf { $L{$l} = $l; $c = $opt_C; } - + if ($opt_c) { print "$file:" if @ARGV>1; print "$found\n"; diff --git a/bin/l b/bin/l index c7d7667..affd4a2 100755 --- a/bin/l +++ b/bin/l @@ -4,7 +4,7 @@ # # Author: Ulli Horlacher # -# Copyright: Perl Artistic License +# Perl Artistic License use Cwd qw'abs_path'; use File::Basename; @@ -76,7 +76,7 @@ if ($opt_D) { $newer = $1; } } - + # preselect date field number if ($opt_c) { $sdf = 'c' } elsif ($opt_u) { $sdf = 'a' } @@ -102,13 +102,13 @@ if (@LIST && $postproc) { $opt_z = '%'.$opt_z.'s '; @LIST = grep { s/\0 *([,\d\.\-]+) /sprintf($opt_z,$1)/e } @LIST; } - + @LIST = reverse @LIST if $opt_r; if (not ($opt_t or $opt_U) and grep /^d[rR-][wW-][xX-]/,@LIST) { foreach (@LIST) { print if /^d/ } foreach (@LIST) { print unless /^d/ } - } else { + } else { print @LIST; } } @@ -118,7 +118,7 @@ if ($opt_S && $SS) { print "$SS file(s):"; printf " r=%d (%s Bytes)",$SS{'-'},&d3($Ss) if $SS{'-'}; delete $SS{'-'}; - foreach my $type (qw(l d c b p s ?)) { + foreach my $type (qw(l d c b p s ?)) { printf " %s=%d",$type,$SS{$type} if $SS{$type}; delete $SS{$type}; } @@ -130,7 +130,7 @@ exit ($found ? 0 : 1); # collect files and build file lists -# +# # INPUT: filenames # # GLOBAL: @LIST @@ -140,10 +140,10 @@ sub collect { # loop over all argument files/directories foreach $f (@files) { - + # skip jed and emacs backup files # next if $f =~ /~$/ and not $opt_a and not $opt_l; - + # recursive? if ($opt_R) { @@ -158,7 +158,7 @@ sub collect { list($f); # traverse real subdirs - if (-d $f and not -l $f) { + if (-d $f and not -l $f) { $f =~ s:/*$:/:; # skip other file systems on -x if ($opt_x) { @@ -168,12 +168,12 @@ sub collect { } collect(getfiles($f)); } - + } else { - + # suppress trailing / on -d option $f =~ s:/$:: if $opt_d; - + # on trailing / list subdirs, too if ($f =~ m:/$:) { &list(&getfiles($f)) } elsif ($f eq '') { &list('/') } @@ -187,7 +187,7 @@ sub collect { } list($f); } - + } } } @@ -225,7 +225,7 @@ sub list { $day = $date; $day =~ s/\s.*//; - + if ($older) { next if $older =~ /-/ and $day gt $older; next if $older !~ /-/ and $dates{m} > time-$older; @@ -234,7 +234,7 @@ sub list { next if $newer =~ /-/ and $day lt $newer; next if $newer !~ /-/ and $dates{m} < time-$newer; } - + if (defined $linkname) { # prepend sorting string @@ -259,7 +259,7 @@ sub list { elsif ($i eq 'l') { $line .= sprintf '%3s ', $links } elsif ($i eq 'i') { $line .= sprintf '%14s ', $inode } elsif ($i eq 'd') { $line .= sprintf '%10s ', $date } - elsif ($i eq 'a') { $line .= sprintf '%10s %10s %10s ', + elsif ($i eq 'a') { $line .= sprintf '%10s %10s %10s ', $dates{'a'},$dates{'m'},$dates{'c'} } } else { if ($i eq 'm') { $line .= $mode.' ' } @@ -278,10 +278,10 @@ sub list { &isodate($dates{'c'}).' ' } } } - + # predefined formats } else { - + if ($opt_n) { if ($opt_l) { $line .= sprintf "%06o %6d %6d $z%15s %10d ", $mode,$uid,$gid,$size,$date } @@ -293,25 +293,25 @@ sub list { else { $line .= sprintf "%s $z%19s %s ", $mode,$size,substr($date,0,-3) } } - + if ($opt_i) { $line .= sprintf '%3s %10s ',$links,$inode } } $line .= $linkname."\n"; - - if ($postproc) { + + if ($postproc) { push @LIST,$line; - } else { + } else { $line =~ s/\0//; print $line; } $found++; - + } else { lstat $file; warn "$0: cannot get dir-info for ".quote($file)." - $!\n"; } - + } } @@ -319,7 +319,7 @@ sub list { # # INPUT: file name # -# OUTPUT: filename with linkname, inode, hard link count, size, mode string, +# OUTPUT: filename with linkname, inode, hard link count, size, mode string, # UID, GID, isodate sub info { my $file = shift; @@ -331,14 +331,14 @@ sub info { if ($opt_L) { @stat = stat $file } else { @stat = lstat $file } - + if (@stat) { - + $inode = $stat[1]; $bmode = $stat[2]; $links = $stat[3]; - %dates = ('m' => $stat[9], - 'a' => $stat[8], + %dates = ('m' => $stat[9], + 'a' => $stat[8], 'c' => $stat[10]); if ($opt_n) { @@ -350,7 +350,7 @@ sub info { $gid = getgrgid($stat[5]) || $stat[5]; $date = &isodate($dates{$sdf}); } - + if (-f _) { $type = '-'; $size = $stat[7]; } elsif (!$opt_L && -l _) { $type = 'l'; } elsif (-d _) { $type = 'd'; } @@ -376,7 +376,7 @@ sub info { $mode = $type.$mode; } else { # with short list display only effektive file access modes - $mode = $type + $mode = $type . (-r _ ? 'R' : '-') . (-w _ ? 'W' : '-') . (-x _ ? 'X' : '-'); @@ -406,7 +406,7 @@ sub info { } $size = &d3($size); - + # determine longest size field if ($opt_z) { my $x = length $size; @@ -421,7 +421,7 @@ sub info { } $mode =~ s/\+$//; #$mode .= ' ' unless $mode =~ /\+$/; - + return ($linkname,$inode,$links,$size,$mode,$uid,$gid,$date,%dates); } @@ -453,22 +453,22 @@ sub getfiles { if (opendir D,$dir) { $dir = '' if $dir eq '.'; - while (defined($f = readdir D)) { - + while (defined($f = readdir D)) { + # skip . and .. pseudo-subdirs next if $f =~ m:(^|/)\.\.?/*$:; # skip ONTAP snapshot dir next if $f =~ m:(^|/)\.snapshot/*$:; - + # skip jed and emacs backup files # next if $f =~ /~$/ and not $opt_a and not $opt_l; - + if ($f =~ /$opt_m/) { my $x = $dir.$f; - if (not -l $x and -d $x and not ($opt_R or $postsort or $opt_U)) { + if (not -l $x and -d $x and not ($opt_R or $postsort or $opt_U)) { push @dirs,$x; - } else { + } else { push @files,$x; } } @@ -481,7 +481,7 @@ sub getfiles { } else { warn "$0: cannot read $dir : $!\n"; } - + return (@dirs,@files); } @@ -517,7 +517,7 @@ sub isodate { sub quote { local $_ = shift; my $mc = '\'\[\]\\\\ `"$?&<>$*()|{};'; - + unless (defined $_) { die "@_"; @x = caller; @@ -547,8 +547,8 @@ sub usage { my $status = shift; my $opts = '[-lastcuidnrzLRxNS*] [-f format] [-D X:Y]'; local *OUT = $status ? *STDERR : *STDOUT; - - if ($0 ne 'lf') { + + if ($0 ne 'lf') { print OUT "usage: $0 $opts [-F regexp] [file...]\n"; } $opts =~ s/R//; @@ -576,7 +576,7 @@ options: -l long list (implicit if called 'll') -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 + -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) -E show examples @@ -588,7 +588,7 @@ sub examples { print </dev/null`; if ($log = $log[-1] and open $log,$log) { - binmode($log,":encoding(UTF-8)"); + binmode($log,":utf8"); while (<$log>) { s/\r//; if (/^Content-Disposition:.*name="FILE".*filename="(.+)"/i) { @@ -184,9 +187,14 @@ sub read_debug_log { $_ = <$log>; my $v = <$log>||''; $v =~ s/[\r\n]+//; - printf " %s=\"%s\"\n",$p,utf8decode($v)||$v if $v; - read_akey($v) if $p eq 'AKEY'; - read_skey($v) if $p eq 'SKEY'; + if ($v) { + my $vv = utf8decode($v)||$v; + $vv =~ s/[\x00-\x1F]/_/g; + $vv =~ s/[\x80-\x9F]/_/g; + printf " %s=\"%s\"\n",$p,$vv; + read_akey($v) if $p eq 'AKEY'; + read_skey($v) if $p eq 'SKEY'; + } } elsif (/^(Param|Exp): (\w+=".+")/) { print " $2\n"; } diff --git a/bin/sexsend b/bin/sexsend index d9fe821..9a7d48b 100755 --- a/bin/sexsend +++ b/bin/sexsend @@ -19,7 +19,7 @@ use constant M => 2**20; eval 'use Net::INET6Glue::INET_is_INET6'; -our $version = 20160104; +our $version = 20160328; our $DEBUG = $ENV{DEBUG}; my %SSL = (SSL_version => 'TLSv1'); @@ -331,7 +331,7 @@ if ($mode eq 'anonymous') { } request("POST /sex?BS=$bs&user=$user$mode$type$timeout$stream HTTP/1.0"); -print STDERR "==> (streaming ...)\n" if $opt_v; +print STDERR "--> (streaming ...)\n" if $opt_v; transfer(STDIN,$SH); @@ -395,20 +395,22 @@ sub transfer { sub request { my $req = shift; - print STDERR "==> $req\n" if $opt_v; - syswrite $SH,"$req\r\n\r\n"; + print STDERR "--> $req\n" if $opt_v; + syswrite $SH,"$req\r\n"; + syswrite $SH,"User-Agent: sexsend\r\n"; + syswrite $SH,"\r\n"; for (;;) { unless (defined($_ = &getline)) { die "$0: server has closed the connection\n"; } if (/^HTTP\/[\d\.]+ 200/) { - print STDERR "<== $_" if $opt_v; + print STDERR "<-- $_" if $opt_v; last; } elsif (/^HTTP\/[\d\.]+ 199/) { - print STDERR "<== $_" if $opt_v; + print STDERR "<-- $_" if $opt_v; } else { if ($opt_v) { - print STDERR "<== $_"; + print STDERR "<-- $_"; exit 3; } else { s:^HTTP/[ \d\.]+::; @@ -420,7 +422,7 @@ sub request { while (defined($_ = &getline)) { last if /^\s*$/; $H{uc($1)} = $2 if /(.+):\s*(.+)/; - print STDERR "<== $_" if $opt_v; + print STDERR "<-- $_" if $opt_v; } } @@ -461,7 +463,7 @@ sub query_sid { local $_; $req = "GET SID HTTP/1.1"; - print STDERR "==> $req\n" if $opt_v; + print STDERR "--> $req\n" if $opt_v; syswrite $SH,"$req\r\n\r\n"; $_ = &getline; unless (defined $_ and /\w/) { @@ -470,12 +472,12 @@ sub query_sid { } s/\r//; if (/^HTTP.* 201 (.+)/) { - print STDERR "<== $_" if $opt_v; + print STDERR "<-- $_" if $opt_v; $id = 'MD5H:'.md5_hex($id.$1); while (defined($_ = &getline)) { s/\r//; last if /^\n/; - print STDERR "<== $_" if $opt_v; + print STDERR "<-- $_" if $opt_v; } } else { die "$0: $server does not support session ID\n"; diff --git a/bin/zz b/bin/zz index 8195b87..0317412 100755 --- a/bin/zz +++ b/bin/zz @@ -2,7 +2,7 @@ # to use zz with vim, write to your .vimrc: # -# noremap zz> :w !zz +# noremap zz> :w !zz # noremap zz< :r !zz ZZ=${ZZ:-$HOME/.zz} @@ -30,26 +30,26 @@ Examples: (within tin:) |azz (within vi:) :w !zz (within vi:) :r !zz - + Limitation: zz does not work across different accounts or hosts! Use xx instead. EOD fi -if [ "$1" = + ]; then +if [ "$1" = + ]; then shift exec cat -- "$@" >>$ZZ fi if [ -t 0 ]; then - if [ -z "$1" ]; then + if [ -z "$1" ]; then exec cat -- $ZZ - elif [ "$1" = .. ]; then + elif [ "$1" = .. ]; then exec cat -- $ZZ~ - else + else test -f $ZZ && mv $ZZ $ZZ~ exec cat -- "$@" >$ZZ fi else test -f $ZZ && mv $ZZ $ZZ~ exec cat >$ZZ -fi +fi diff --git a/cgi-bin/fac b/cgi-bin/fac index 6a41ab7..262975d 100755 --- a/cgi-bin/fac +++ b/cgi-bin/fac @@ -410,7 +410,7 @@ sub createUser { $idf = "$user/@"; if (-f $idf) { - html_error($error,"There is already an user $user!"); + html_error($error,"There is already an user $user!"); } open $idf,'>',$idf or http_die("cannot write $idf - $!"); diff --git a/cgi-bin/fop b/cgi-bin/fop index dec3abc..c5098fc 100755 --- a/cgi-bin/fop +++ b/cgi-bin/fop @@ -100,6 +100,7 @@ if ($file =~ m:^([^/]+)/[^/]+$:) { if ($mdomain and $file =~ s:(.+)/(.+)/(.+):$3:) { $to = lc $1; $from = lc $2; + $to =~ s/[:,].*//; $to .= '@'.$hostname if $to eq 'anonymous'; $from .= '@'.$hostname if $from eq 'anonymous'; $to .= '@'.$mdomain if -d "$to\@$mdomain"; @@ -733,6 +734,7 @@ sub sendfile { } else { $range = sprintf("bytes %s-%s/%s",$seek,$total_size-1,$total_size); } + # RFC 7233 "Responses to a Range Request" nvt_print( 'HTTP/1.1 206 Partial Content', "Content-Length: $size", @@ -764,6 +766,7 @@ sub sendfile { "Connection: close", ); # nvt_print('','HTTP/1.1 200 OK',"Content-Length: $size","Content-Type: $type"); exit; + nvt_print($_) foreach(@extra_header); } else { http_header('200 OK'); print html_header($head); @@ -795,6 +798,7 @@ sub sendfile { if ($type eq 'application/octet-stream') { nvt_print(qq'Content-Disposition: attachment; filename="$filename"'); } + nvt_print($_) foreach(@extra_header); } nvt_print("X-Size: $total_size"); diff --git a/cgi-bin/fuc b/cgi-bin/fuc index 4d7ee3c..897fd69 100755 --- a/cgi-bin/fuc +++ b/cgi-bin/fuc @@ -97,7 +97,7 @@ if ($show and $show eq 'tools') { '' ); &reexec; - + if (open $tools,"$docdir/tools.html") { while (<$tools>) { while (/\$([\w_]+)\$/) { @@ -135,7 +135,7 @@ if ($akey) { if ($user and $akey and $qs and $qs =~ /info=(.+?)&skey=(.+)/) { $subuser = $1; $skey = $2; - notify_subuser($user,$subuser,"$fup?skey=$skey",$comment); + notify_subuser($user,$subuser,"$fup?skey=$skey#$user",$comment); http_header("200 OK"); print html_header($head); pq(qq( @@ -845,6 +845,8 @@ sub notify_otuser { 'To: $otuser' 'Subject: Your upload URL' 'X-Mailer: F*EX' + 'Content-Type: text/plain; charset=utf-8' + 'Content-Transfer-Encoding: 8bit' '' 'This is an automatically generated e-mail.' '' @@ -880,6 +882,8 @@ sub notify_subuser { 'Cc: $user' 'Subject: Your F*EX account on $server' 'X-Mailer: F*EX' + 'Content-Type: text/plain; charset=utf-8' + 'Content-Transfer-Encoding: 8bit' '' 'This is an automatically generated e-mail.' '' diff --git a/cgi-bin/fup b/cgi-bin/fup index 7d222f9..2a799ac 100755 --- a/cgi-bin/fup +++ b/cgi-bin/fup @@ -58,6 +58,7 @@ my @header; # HTTP entity header my $fileid; # file ID my $captive; my $muser; # main user fur sub or group user +my %specific; # upload specific KEEP and AUTODELETE parameters # load common code, local config: $FEXLIB/fex.ph require "$FEXLIB/fex.pp"; @@ -109,7 +110,8 @@ if ($addto) { my %to; foreach $to (@to) { $to{$to} = 1 } push @to,$addto unless $to{$addto}; - if ($submit and @to == 1) { $addto = '' } + # user has submitted with [select from your address book] ? + # if ($submit and @to == 1) { $addto = '' } } $to = join(',',@to); @@ -631,11 +633,12 @@ if (($from and $id and $rid eq $id or $gkey or $skey) and $command) { foreach my $to (@group?@group:@to) { # my $options = sprintf "(autodelete=%s,keep=%s,locale=%s)", # readlink "$to/\@LOCALE"||$locale||$locale{$to}||$default_locale; - my $options = sprintf "(autodelete=%s,keep=%s,locale=%s,notification=%s)", + # my $options = sprintf "(autodelete=%s,keep=%s,locale=%s,notification=%s)", + my $options = sprintf "(autodelete=%s,keep=%s,locale=%s)", $autodelete{$to}||$autodelete, $keep{$to}||$keep_default, - readlink("$to/\@LOCALE")||$default_locale, - readlink("$to/\@NOTIFICATION")||'full'; + readlink("$to/\@LOCALE")||$locale{$to}||$default_locale; + # readlink("$to/\@NOTIFICATION")||'full'; nvt_print("X-Recipient: $to $options"); } nvt_print(''); @@ -840,6 +843,8 @@ unless ($file) { { present_locales('/fup'); + # print "[$addto] [$submit] [@to]

\n"; + @ab = (""); # select menu from server address book @@ -849,6 +854,7 @@ unless ($file) { if (/(\S+)[=\s]+(\S+@[\w.-]+\S*)/) { $_ = "$1 <$2>"; s/,.*/,.../g; + s/:.*/>/; push @ab,""; } } @@ -948,9 +954,6 @@ unless ($file) { print "Alternate Java client (for files > 2 GB or sending of more than one file)\n"; } print &logout; - if (-x "$FEXHOME/cgi-bin/login") { - print $info_login||$info_1; - } pq(qq( '


' '' @@ -962,8 +965,9 @@ unless ($file) { '

' 'Use a F*EX client if you want to send more than one file or resume an interrupted upload.' '' - '

+ '

' )); + print $info_1; exit; } @@ -1240,7 +1244,7 @@ unless ($file) { # } print "\n"; - print $info_1; + print $info_login||$info_1; if ($debug and $debug>1) { print "


\n
\n";
@@ -1417,11 +1421,12 @@ if ($nostore) {
     my $to = $_;
     $to =~ s/:\w+=.*//; # remove options from address
     my $file = "$to/$from/$fkey";
-    my $options = sprintf "(autodelete=%s,keep=%s,locale=%s,notification=%s)",
+    # my $options = sprintf "(autodelete=%s,keep=%s,locale=%s,notification=%s)",
+    my $options = sprintf "(autodelete=%s,keep=%s,locale=%s)",
       readlink("$file/autodelete")||$autodelete,
       readlink("$file/keep")||readlink("$to/\@KEEP")||$keep_default,
-      readlink("$to/\@LOCALE")||readlink("$file/locale")||$default_locale,
-      readlink("$to/\@NOTIFICATION")||'full';
+      readlink("$to/\@LOCALE")||readlink("$file/locale")||$default_locale;
+      # readlink("$to/\@NOTIFICATION")||'full';
     nvt_print("X-Recipient: $to $options");
     nvt_print("X-Location: $durl/$dkey{$to}/$fkey") unless $restricted;
   }
@@ -1510,7 +1515,13 @@ if ($okey) {
   print "&bwlimit=$bwlimit&autodelete=$autodelete&keep=$keep\">";
   print "send another file\n";
   if ($http_client !~ /fexsend/ and $http_client =~ /Linux/i) {
-    print qq'

Hi Linux-user, try fexsend! ☺

\n'; + print '

Hi Linux-user, try ', + '', + "fexsend! ☺

\n"; + } + if ($http_client !~ /fexit/ and $http_client =~ /Windows/i) { + print '

Hi Windows-user, try fexit! ', + "☺

\n"; } print &logout; } @@ -1558,6 +1569,9 @@ sub parse_request { if ($p eq 'KEEP' and /^\d+$/) { $specific{'keep'} = $keep = $v; } + # if ($p eq 'LOCALE') { + # $specific{'locale'} = $locale = $v; + # } } } } @@ -1677,23 +1691,39 @@ sub parse_request { # collect multiple addresses and check for aliases (not group) if (@to and "@to" !~ /^@[\w-]+$/ - and not ($gkey or $addto or $command =~ /^LIST(RECEIVED)?$/)) - { - + and not ($gkey or $addto or $command =~ /^LIST(RECEIVED)?$/)) { # read address book if ($from and open my $AB,'<',"$from/\@ADDRESS_BOOK") { - my ($alias,$address,$autodelete,$locale,$keep); + my ($alias,$addresses,$autodelete,$locale,$keep); while (<$AB>) { s/#.*//; $_ = lc $_; if (s/^\s*(\S+)[=\s]+(\S+)//) { - ($alias,$address) = ($1,$2); + ($alias,$addresses) = ($1,$2); + # alias specific options? $autodelete = $locale = $keep = ''; $autodelete = $1 if /autodelete=(\w+)/; $locale = $1 if /locale=(\w+)/; $keep = $1 if /keep=(\d+)/; - foreach my $address (split(",",$address)) { - $address .= '@'.$mdomain if $mdomain and $address !~ /@/; + foreach my $address (split(",",$addresses)) { + # alias address specific :options? + if ($address =~ s/(.+?):(.+)/$1/) { + my @options = split(':',$2); + $address = expand($address); + foreach (@options) { + if (/^keep=(\d+)$/i) { + $alias_keep{$alias}{$address} = $1 + } + if (/^autodelete=(yes|no|delay)$/i) { + $alias_autodelete{$alias}{$address} = $1 + } + if (/^locale=(\w+)$/i) { + $alias_locale{$alias}{$address} = $1 + } + } + } else { + $address = expand($address); + } push @{$ab{$alias}},$address; $autodelete{$alias} = $autodelete if $autodelete; $keep{$alias} = $keep if $keep; @@ -1707,46 +1737,86 @@ sub parse_request { # look for recipient's options and eliminate dupes %to = (); foreach my $to (my @loop = @to) { - # address book alias? - if ($to !~ /@/ and $ab{$to}) { - foreach my $address (my @loop = @{$ab{$to}}) { - $address .= '@'.$mdomain if $mdomain and $address !~ /@/; + # address book alias? + if ($to !~ /@/ and ($ab{$to} or $to =~ /(.+?):(.+)/ and $ab{$1})) { + my $alias = $to; + my @options = (); + $alias =~ s/:(.*)// and @options = split(':',$1); + if (@options) { + # alias with :options + $alias =~ s/:.*//; + foreach my $address (my @loop = @{$ab{$alias}}) { + $to{$address} = $address; # ignore dupes + foreach (@options) { + $keep{$address} = $1 if /^keep=(\d+)$/i; + $autodelete{$address} = $1 if /^autodelete=(yes|no|delay)$/i; + $locale{$address} = $1 if /^locale=(\w+)$/i; + } + } + } + foreach my $address (my @loop = @{$ab{$alias}}) { $to{$address} = $address; # ignore dupes - if ($specific{'autodelete'}) { - $autodelete{$address} = $specific{'autodelete'}; - } elsif ($autodelete{$to}) { - $autodelete{$address} = $autodelete{$to}; - } else { - $autodelete{$address} = readlink "$address/\@AUTODELETE" - || $autodelete; + unless ($keep{$address}) { + $keep{$address} = $keep{$alias} if $keep{$alias}; + if ($specific{'keep'}) { + $keep{$address} = $specific{'keep'} + } elsif (my $keep = $alias_keep{$alias}{$address}) { + $keep{$address} = $keep; + } elsif ($keep{$alias}) { + $keep{$address} = $keep{$alias} + } } - if (my $locale = readlink "$address/\@LOCALE") { - $locale{$address} = $locale; - } elsif ($locale{$to}) { - $locale{$address} = $locale{$to}; - } else { - $locale{$address} = $::locale ; + unless ($autodelete{$address}) { + if ($specific{'autodelete'}) { + $autodelete{$address} = $specific{'autodelete'}; + } elsif (my $autodelete = $alias_autodelete{$alias}{$address}) { + $autodelete{$address} = $keep; + } elsif ($autodelete{$alias}) { + $autodelete{$address} = $autodelete{$alias}; + } else { + $autodelete{$address} = readlink "$address/\@AUTODELETE" + || $autodelete; + } } unless ($locale{$address}) { - $locale{$address} = $default_locale || 'english'; + if (my $locale = readlink "$address/\@LOCALE") { + $locale{$address} = $locale; + } elsif ($locale{$alias}) { + $locale{$address} = $locale{$alias}; + } elsif ($locale = $alias_locale{$alias}{$address}) { + $locale{$address} = $locale; + } else { + $locale{$address} = $::locale ; + } + $locale{$address} ||= $default_locale || 'english'; } - if ($specific{'keep'}) { $keep{$address} = $specific{'keep'} } - elsif ($keep{$to}) { $keep{$address} = $keep{$to} } } } else { + # regular address, not an alias + if ($to =~ s/(.+?):(.+)/$1/) { + my @options = split(':',$2); + $to = expand($to); + foreach (@options) { + $keep{$to} = $1 if /^keep=(\d+)$/i; + $autodelete{$to} = $1 if /^autodelete=(yes|no|delay)$/i; + $locale{$to} = $1 if /^locale=(\w+)$/i; + } + } $to = expand($to); $to{$to} = $to; # ignore dupes unless ($autodelete{$to}) { - $autodelete{$to} = readlink "$to/\@AUTODELETE" || $autodelete; + $autodelete{$to} = untaint(readlink("$to/\@AUTODELETE") + ||$autodelete); + if ($specific{'autodelete'}) { + $autodelete{$to} = $specific{'autodelete'}; + } + } + unless ($keep{$to}) { + $keep{$to} = $keep_default; + $keep{$to} = $keep if $keep; + $keep{$to} = untaint(readlink "$to/\@KEEP") if -l "$to/\@KEEP"; + $keep{$to} = $specific{'keep'} if $specific{'keep'}; } - $autodelete{$to} = $specific{'autodelete'} if $specific{'autodelete'}; - $keep{$to} = $keep_default; - $keep{$to} = $keep if $keep; - $keep{$to} = untaint(readlink "$to/\@KEEP") if -l "$to/\@KEEP"; - $keep{$to} = $specific{'keep'} if $specific{'keep'}; - # recipient specific parameters - $keep{$to} = $1 if $to =~ /:keep=(\d+)/i; - $autodelete{$to} = $1 if $to =~ /:autodelete=(\w+)/i; } $autodelete{$to} = 'NO' if $to =~ /$amdl/; # mailing lists, etc if (-e "$to/\@CAPTIVE") { @@ -2435,7 +2505,7 @@ sub forward { } @to = keys %to; - + http_header('200 OK'); print html_header($head); @@ -2614,15 +2684,15 @@ sub setparam { $locale = $1; } elsif ($v eq 'REDIRECT' and $vv =~ /^([\w?=]+)$/) { $redirect = $1; - } elsif (($v eq 'KEY' or $v eq 'SKEY') and $vv =~ /^([\w:]+)$/) { + } elsif ($v eq 'SKEY' and $vv =~ /^([\w:]+)/) { $skey = $1; $restricted = $v; - } elsif ($v eq 'GKEY' and $vv =~ /^([\w:]+)$/) { + } elsif ($v eq 'GKEY' and $vv =~ /^([\w:]+)/) { $gkey = $1 unless $nomail; $restricted = $v; - } elsif ($v eq 'DKEY' and $vv =~ /^(\w+)$/) { + } elsif ($v eq 'DKEY' and $vv =~ /^(\w+)/) { $dkey = $1; - } elsif ($v eq 'AKEY' and $vv =~ /^(\w+)$/) { + } elsif ($v eq 'AKEY' and $vv =~ /^(\w+)/) { $akey = $1; } elsif ($v eq 'FROM' or $v eq 'USER') { $from = normalize_email($vv); @@ -2721,7 +2791,7 @@ sub setparam { $keep = $keep_max if $keep_max and $keep > $keep_max; $specific{'keep'} = $keep; } elsif ($v eq 'TIMEOUT' and $vv =~ /^(\d+)$/) { - $specific{'timeout'} = $timeout = $1; + $specific{'timeout'} = $timeout = $1; } } @@ -2827,6 +2897,11 @@ sub mail_forgotten { # lookup akey, skey and gkey (full and sub user and group) sub check_keys { + if (@to and "@to" ne '_') { + http_die("you cannot mix TO and SKEY URL parameters") if $skey; + http_die("you cannot mix TO and GKEY URL parameters") if $gkey; + } + # only one key can be valid $akey = $gkey = '' if $skey; $akey = $skey = '' if $gkey; diff --git a/cgi-bin/fur b/cgi-bin/fur index 5db49c4..bca85af 100755 --- a/cgi-bin/fur +++ b/cgi-bin/fur @@ -196,7 +196,7 @@ unless ($user or $exuser or $demouser) { pq(qq( '

' '


' - 'User types overview' + 'User types overview' '' )); } else { diff --git a/cgi-bin/sex b/cgi-bin/sex index ab7abc8..c8f28ce 100755 --- a/cgi-bin/sex +++ b/cgi-bin/sex @@ -139,6 +139,7 @@ elsif ($mode eq 'POP') { while (sysread($fifo,$_,$bs)) { syswrite STDOUT,$_ or die $!; } + unlink $fifo; exit; } diff --git a/doc/Changes b/doc/Changes index e95c668..cdc834f 100644 --- a/doc/Changes +++ b/doc/Changes @@ -1,3 +1,23 @@ +2016-03-11 fuc: added MIME headers to notification e-mail +2016-03-08 fexsend: added support for recipient:options +2016-03-07 fexsend,fexget: added update function to option -V +2016-03-04 install: fixed bug wrong permissions for /home/fex/locale/*/htdocs +2016-03-02 dop: run embedded <<>> without return value output + dop: 10 s timeout for (all) embedded <> +2016-02-26 dop: run <> within perl namespace (package) DOP +2016-02-25 fexsend: added option -T internet speed test +2016-02-22 fexit: added internet speed test +2016-02-11 fexit: added option -s file streaming +2016-02-08 added @extra_header config with default security settings for + Content-Security-Policy, X-Frame-Options, X-XSS-Protection, + X-Content-Type-Options +2016-02-03 fup: every address or alias can have attached :options + (keep,autodelete,locale) +2016-01-29 fexit: added xx clipboard support +2016-01-21 fexsend: fixed bug not working cgi-bin/login +2016-01-15 fup: fixed bug UTF8 error in italian source +2016-01-14 fup: fixed bug after login $info_login instead of $info_1 is + displayed 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 @@ -32,7 +52,7 @@ 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) +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 2015-06-16 new fex.ph config variable @mailing_lists @@ -49,12 +69,12 @@ 2015-04-01 group name may only contain (some) ASCII characters 2015-03-29 fop: fixed bug no more download from same (recipient) ip 2015-03-18 added local URL redirect service -2015-03-08 fup: fixed bug uninitialized value $address if alias address is +2015-03-08 fup: fixed bug uninitialized value $address if alias address is used twice 2015-03-07 disallow email addresses starting with "-" 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 +2015-02-28 fexsrv: restrict HTTP header to 64 kB ($bs) and POST (not fup) to 128 MB 2015-02-27 no more usage of CGI.pm at all 2015-02-25 fup: added $auth_hook @@ -65,7 +85,7 @@ 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-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) 2015-01-27 new fex.ph config variable $fex_yourself (default yes) @@ -103,7 +123,7 @@ 2014-11-20 count unfinished upload size into quota, too 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 +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) @@ -147,7 +167,7 @@ 2014-06-03 fuc: fixed bug cannot edit and save groups 2014-05-26 fuc: ignore akey cookie to prevent cross-site request forgery 2014-05-26 fup,foc,fuc,rup,pup: better parameter filtering to prevent - cross-site scripting attacks + cross-site scripting attacks 2014-05-25 fup: fixed bug insecure dependency when forwarding a file to a user which has set a default keep value 2014-05-23 fexget: fixed bug download fails on big file and slow disk @@ -175,13 +195,13 @@ 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 +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 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 +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 2013-08-18 fop,fup: fixed bug bad file locking when using multiple recipients @@ -193,9 +213,9 @@ 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 + fexsend: terminates if no fexsrv HTTP reply 2013-07-28 dop: added .htaccessfrom support -2013-07-27 fex.ph,dop: security enhancement: +2013-07-27 fex.ph,dop: security enhancement: static documents must be in @doc_dirs dop: documents with leading . are not allowed 2013-07-25 fexsend: added option -= to upload a file with another name @@ -221,13 +241,13 @@ 2013-06-12 fac(CGI): fixed bug wrong spooldir for virtual server 2013-06-11 fex.ph: new config variable $usage_conditions for registrations mails fop: fixed bug fexmail download possible only once -2013-06-10 fac: added option -D to disable a user +2013-06-10 fac: added option -D to disable a user (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 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-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 @@ -238,9 +258,9 @@ 2013-05-16 fop: fexmail support (multiple downloads allowed) 2013-05-09 fup: fixed bug anonymous only works if $mdomain is defined 2013-05-09 fop: fixed bug anonymous only works if recipient host is in - @anonymous_upload list + @anonymous_upload list 2013-05-07 fup: fixed bug multiple Location HTTP headers generate an error with - some web browsers + some web browsers 2013-05-03 added support for axel download accelerator (multiple HTTP Range) 2013-05-02 add X-FEX-File-ID header to notification emails 2013-04-23 dop: fixed bug HTTP 301 redirection timeout on symlinks @@ -274,7 +294,7 @@ 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 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" +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 @@ -303,11 +323,11 @@ downloads 2012-07-05 fexsrv: added camel easteregg 2012-07-02 fup: added optional anonymous upload with fex.ph variable - @anonymous_upload + @anonymous_upload 2012-07-02 fup: fixed bug throttle 0 configuration is ignored 2012-07-01 fexsend: optional argument '@' as files/recipients separator fixed bug notification email for recipient '.' -2012-06-21 dop: inside HTML documents: #include "file" +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 @@ -341,7 +361,7 @@ 2011-11-15 fup: fixed bug with $autodelete = $NUMBER; 2011-11-08 fac: added option -S statistics 2011-11-02 fup: show remaining keep time in files listing -2011-10-28 fup: fixed bug uninitialized value when using copy-forward +2011-10-28 fup: fixed bug uninitialized value when using copy-forward 2011-10-13 fup: FILESIZE hack for firefox 7 to support uploads > 4 GB 2011-10-05 fup: fixed bug wrong sender quota calculation 2011-10-03 fex.ph: added configuration variables @upload_hosts @download_hosts @@ -350,14 +370,14 @@ 2011-09-20 fex.ph: added optional config variable $boring for unhumorous mode 2011-09-19 fur: $USER/.auto contains additional info about account creation 2011-09-07 fac(CGI): fixed bug infinitve loop in watch logfile -2011-09-06 fup,fac,fur: new additional login URL type: +2011-09-06 fup,fac,fur: new additional login URL type: http://FEXSERVER/fup/B64ID 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 -2011-08-29 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 @@ -368,7 +388,7 @@ 2011-08-09 fup: show error on invalid SKEY or GKEY 2011-08-09 fuc: fixed bug subuser and groupuser not lowercase forced 2011-08-09 address book may also contain option locale= -2011-08-08 fex_cleanup: auto-expire user accounts with fex.ph variable +2011-08-08 fex_cleanup: auto-expire user accounts with fex.ph variable $account_expire 2011-08-08 fexsend,fup: allow forward with locale 2011-08-08 dop: extra security check: files from lib and spool are not allowed @@ -385,7 +405,7 @@ 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 +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 2011-07-26 fexget: added option -a get all files @@ -394,7 +414,7 @@ 2011-07-22 fac(CGI): fixed bug displaying < and & in logfiles 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-16 added doc/reverse_proxy 2011-07-14 added optional czech localization 2011-07-01 FAQ.html reformated 2011-06-30 translate install job 20 times faster @@ -402,7 +422,7 @@ 2011-06-22 fup: disable HTML code in file listing (filename & comment) 2011-06-21 added optional italian localization 2011-06-17 fixed bug $bcc is ignored -2011-06-16 fexsend,fexget: better reverse proxy support +2011-06-16 fexsend,fexget: better reverse proxy support (always send Host header) 2011-06-16 added optional galician localization 2011-06-15 fup: fixed bug always keep_default days in notification email @@ -424,7 +444,7 @@ 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 -2011-05-10 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 2011-05-09 fac,fex_cleanup: added user specific keep default @@ -434,7 +454,7 @@ 2011-04-24 xx: better ESXi support (heuristic guessing of tar format) 2011-04-22 sexsend: base64 support for $FEXID and $FEXXX 2011-04-01 fexsend: continue without SID if SID is not available -2011-03-26 fexsrv: deactivate header_hook (inquisition) if request is a +2011-03-26 fexsrv: deactivate header_hook (inquisition) if request is a regular fop request 2011-03-18 fexsend: base64 support for $FEXID and $FEXXX 2011-03-09 fexget,fexsend: fixed bug no file listing for https @@ -475,7 +495,7 @@ 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 +2010-12-10 new config variable @public_recipients for new CGI pup 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 @@ -491,7 +511,7 @@ 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-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) @@ -519,11 +539,11 @@ 2010-08-17 fac: fixed bug accept users without domain 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 + notification email From 2010-08-14 added optional spanish localization 2010-08-12 fup: speedup 90% 2010-08-12 fop: speedup 20% -2010-08-12 fop: better fexget compatibility +2010-08-12 fop: better fexget compatibility (close connection after file delivery) 2010-08-11 fop: fixed IE download bug (missing header separating line) 2010-08-11 fop: fixed 1 min delay bug on AUTODELETE=YES @@ -547,11 +567,11 @@ 2010-07-10 fop: workaround for stupid IE download bug 2010-07-03 fex.ph,fex.pp: new config variable @remote_domains 2010-07-01 fexsrv,fex.ph: new config variable $force_https -2010-06-29 fop: new config variable $limited_download with default NO +2010-06-29 fop: new config variable $limited_download with default NO => allow multiple downloads through proxy farm (varying IPs) 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: +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 2010-06-19 fexget: use ./$file.tmp for downloading instead of $HOME/.fex/tmp/ @@ -563,12 +583,12 @@ 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 - reliable resume function + of file) is the successor of X-Size for more + reliable resume function 2010-06-02 schwuppdiwupp: added proxy support 2010-05-31 fexsend: fixed bug windows path elements in filename -2010-05-30 better server proxy support: - AKEY and SKEY no longer rely on client ip +2010-05-30 better server proxy support: + AKEY and SKEY no longer rely on client ip 2010-05-29 fexsend: added proxy support 2010-05-28 fur: allow registration confirmation more than once 2010-05-27 fexsend: added option -b bounce (copy-forward) @@ -669,10 +689,10 @@ 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 +2009-07-06 fup: substitute all control characters in file name and comment with "_" 2009-07-02 better install script, guesses IP -2009-06-29 changed spool directory layout +2009-06-29 changed spool directory layout $TO/$FROM/$FILE --> $TO/$FROM/md5h($FILENAME) to avoid filename collisions 2009-06-28 added mailman authorization mma @@ -689,7 +709,7 @@ 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 2009-03-25 fexget: fixed bug calculated wrong transfer rate -2009-03-25 fexget: changed default answers to more secure values +2009-03-25 fexget: changed default answers to more secure values 2009-03-24 fexsend: new option -l for listing sent files 2009-03-24 fup: support for listing sent files 2009-03-24 fex.pp: default charset is now UTF-8 in HTTP reply @@ -709,7 +729,7 @@ 2009-02-11 fop: fixed bug file size request with multiple $to gives always 0 (no upload resume possible with multiple recipients) 2009-02-11 fop: check for valid recipient address (in file path) - ==> early abort possible when client uses illegal address for + ==> 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-02-09 fexsrv: fixed bug wrong log sequence in debug files @@ -732,7 +752,7 @@ 2008-12-23 sexsend,sexget: added HTTPS/SSL support 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 +2008-12-18 fexget: fixed bug responsiveness on slow links 2008-12-18 fexget: fixed bug save file name for archives 2008-12-12 fexget: better responsiveness on slow links (modem, ISDN) 2008-12-12 fup: added warning for incompatible clients (konqueror, etc) @@ -761,7 +781,7 @@ 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 2008-11-19 fac: set correct exit status -2008-11-16 fup: fixed bug DELETE not working +2008-11-16 fup: fixed bug DELETE not working 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 @@ -800,9 +820,9 @@ 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 2008-08-13 fup: showstatus shows error message on illegal recipient address - or when no file was uploaded + or when no file was uploaded (nececessary for stupid Internet Explorer!) -2008-08-11 splitted debugfiles with time stamp in filename +2008-08-11 splitted debugfiles with time stamp in filename 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 @@ -859,7 +879,7 @@ 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 2008-04-06 fup: more debuglog, fixed wrong error messages -2008-04-06 added doc/concept doc/FAQ +2008-04-06 added doc/concept doc/FAQ 2008-04-02 install: better error handling (patch by chris@citecs.de) 2008-04-02 more docs and improved logging 2008-04-01 cgilaunch: fixed bug in determing REMOTE_HOST when using stunnel diff --git a/doc/Contribs b/doc/Contribs index 9dc8d78..4be058c 100644 --- a/doc/Contribs +++ b/doc/Contribs @@ -1,5 +1,5 @@ Beate Herrmann : - - artwork + - artwork Sebastian Zaiser : - upload status window @@ -9,7 +9,7 @@ Bernd Strehhuber : Kurt Jaeger : - ipv6 support - + Andre Hafner : - web admin interface fac - VM @@ -39,22 +39,22 @@ Nicola Fioravanti (http://revshell.com): Waldemar Bronsch : - German localization - + Tobias Gunkel : - German localization Hans-Georg Bickel : - Swabian localization - + Francisco Ruiz : - Spanish localization Anton Meixome : - Galician localization - + Vanni Piagno : - Italian localization - + Michal Simunek : - Czech localization diff --git a/doc/IPv6 b/doc/IPv6 index 3861b17..f810490 100644 --- a/doc/IPv6 +++ b/doc/IPv6 @@ -1,7 +1,7 @@ To enable IPv6 on the server you need: - The Perl module Socket6 - You can install it on Debian or Ubuntu with: + You can install it on Debian or Ubuntu with: apt-get install libsocket6-perl - Add to /etc/xinetd.d/fex the line: @@ -13,5 +13,5 @@ To enable IPv6 on the server you need: To enable IPv6 for fexsend, fexget and sexsend you need: - The Perl module Net::INET6Glue::INET_is_INET6 - You can install it on Debian or Ubuntu with: + You can install it on Debian or Ubuntu with: apt-get install libnet-inet6glue-perl diff --git a/doc/SEX b/doc/SEX index b7a4a7d..8d8ced3 100644 --- a/doc/SEX +++ b/doc/SEX @@ -44,7 +44,7 @@ Since today my solution was F*EX: 3) on destination host get container.tar from F*EX-server and extract it: - fexget FEXURL + fexget FEXURL tar xvf container.tar rm container.tar @@ -55,7 +55,7 @@ Backdraws: - creation of container.tar needs (a lot of) time - container.tar needs (too much) disk space on source and destination host and on the F*EX-Server - + Small solution: @@ -116,4 +116,3 @@ admin workstation behin a firewall. Or the other direction. (*) The example above has only a few kB, but one can use sexxx for many GB or even TB! On my VMs I get a throughput of 90 MB/s. - diff --git a/doc/SSL b/doc/SSL index 14f5abd..6eb73bf 100644 --- a/doc/SSL +++ b/doc/SSL @@ -15,6 +15,8 @@ openssl x509 -text -in stunnel.pem chmod 600 stunnel.pem cat <stunnel.conf +debug = warning +output = /home/fex/spool/stunnel.log cert = /home/fex/etc/stunnel.pem sslVersion = all TIMEOUTclose = 1 @@ -22,7 +24,7 @@ exec = perl execargs = perl -T /home/fex/bin/fexsrv stunnel EOD -case $(lsb_release -a 2>/dev/null) in +case $(lsb_release -a 2>/dev/null) in *CentOS*) echo 'fips = no' >>stunnel.conf;; esac diff --git a/doc/concept b/doc/concept index 26ad9da..fde9902 100644 --- a/doc/concept +++ b/doc/concept @@ -17,7 +17,7 @@ Main features of F*EX * full-users can create subusers, who can send only to this full-user * full-users can create groups, an analogy to mailing lists, but for files * self registration possible for internal and external users - * maintenance-free: no admin interaction necessary + * maintenance-free: no admin interaction necessary * sending to multiple recipients needs storage on the server only once * quotas for sending and receiving * F*EX is a HTTP web-service and needs no firewall-tunnels @@ -40,7 +40,7 @@ Main features of F*EX The end user normally uses F*EX with his web browser and the URLs http://YOURFEXSERVER/fup (file upload) and http://YOURFEXSERVER/fop (file -download). +download). F*EX is not an anonymous service (exception: "public upload" and @@ -52,7 +52,7 @@ program "fac" (F*EX admin control) or http://YOURFEXSERVER/fac Alternativly the users can register theirselves with http://YOURFEXSERVER/fur (F*EX user registration), if the admin allows them to do so. This is done by setting the variables @local_domains and @local_hosts in FEXHOME/lib/fex.ph -Example: +Example: @local_hosts = qw(127.0.0.1 10.10.100.0-10.10.255.255); @local_domains = qw(rus.uni-stuttgart.de flupp.org); @@ -75,12 +75,12 @@ the local recipient domains. For example: F*EX full users can create one time upload URLs with -http://YOURFEXSERVER/fuc +http://YOURFEXSERVER/fuc With such a URL a foreign user can send this F*EX full user a single file. F*EX full users can theirselves register "subusers" with -http://YOURFEXSERVER/fuc +http://YOURFEXSERVER/fuc Subusers can only fex to their full-user, not to any others, and they cannot create other subusers. @@ -95,7 +95,7 @@ he cannot change anymore his default settings (KEEP, AUTODELETE, etc) The F*EX user is the same as the "sender" in the fup CGI and the "from" -parameter in the F*EX URL. +parameter in the F*EX URL. The (confusing) naming scheme is historically based :-) @@ -106,7 +106,7 @@ email. You do not need to build F*EX URLs manually, they are generated by the -F*EX programs. +F*EX programs. A F*EX session is based on unique URL parameters or POST variables (FROM, @@ -121,18 +121,18 @@ A SKEY is made of md5_hex("$mainuser:$subuser:$subuserid") A GKEY is made of md5_hex("$mainuser:$groupname:$groupuser:$groupuserid") Note: the AKEY, SKEY and GKEY always can be stolen by a network sniffer! -If you need true security, then you have to use https instead of http! +If you need true security, then you have to use https instead of http! After download the file will be deleted after a grace time of 1 minute. This grace time allows a recipient to get the file again if he had -problems in saving it. +problems in saving it. With the fexsend client the sender can change this behavior: option -D means "delay autodelete": do not delete the the file directly after download, but with the nightly fex_cleanup cronjob. More downloads are possible only from the same client (identified by cookie or ip -address). +address). option -K means "keep file": do not delete the file after download, but only after expiration date (normally 5 days). More downloads are possible @@ -164,7 +164,7 @@ requires (HTTP) authorization. The credentials are the F*EX user email and auth-ID. See extra documentation SSL for using https. -If you want to have encrypted emails, then you need a GPG public key for +If you want to have encrypted emails, then you need a GPG public key for the user fex. Create it with "gpg --gen-key" (use fex@YOURFEXSERVER as the user or the $bcc address from fex.ph if you have set it, see below). Next, the user has to upload his public key via webinterface "user config & @@ -206,14 +206,14 @@ below! FEXHOME contains: - spool/ spool directory and user data + spool/ spool directory and user data htdocs/ directory for generic download files bin/ directory for programs cgi-bin/ directory for CGI programs lib/ directory for library and config files doc/ additional documentation locale/ alternative language installation - + Files in spool: @@ -240,7 +240,7 @@ Files in spool: $user/@KEEP keep default $user/@LOCALE locale default $user/@CAPTIVE user must not change his settings - $user/@FEXYOURSELF user can only fex to himself via + $user/@FEXYOURSELF user can only fex to himself via web interface $to/$from/$file/upload file data in upload progress $to/$from/$file/filename original file name @@ -294,7 +294,7 @@ This is done via UKEY, a unique upload identifier. The download key (DKEY) is a unique identifier for - guess what - downloading. It also prevents an attacker to get the file, because only the recipient knows the DKEY as part of the download URL from the -notification email. +notification email. XKEY is an optional extra download key to have a short download URL in shape http://YOURFEXSERVER//XKEY @@ -302,7 +302,7 @@ The XKEY always starts with // and is provided as a COMMENT by the client. Example: fexsend schwuppdiwupp.jpg // The user has to realize that such URLs have very low security. -If you need to trace a F*EX request, then set +If you need to trace a F*EX request, then set $debug = 1; in fex.ph and look in ~/spool/.debug/ for the correspondening files. @@ -323,7 +323,7 @@ In this case "From: $admin" will be used in the notification emails. F*EX comes with its own web server: fexsrv Standard web servers like apache have been proven problematic, either in -speed or because of a 2-GB-limit. +speed or because of a 2-GB-limit. It is not possible to use the F*EX CGIs with an alternative web server, because the F*EX CGIs need special fexsrv features. @@ -331,7 +331,7 @@ because the F*EX CGIs need special fexsrv features. xinetd starts fexsrv for every new connection, which then executes the CGIs fup (file upload), fop (file output), fuc (fex user control), foc (fex operation control), fac (fex admin control), fur (fex user -registration) and sex (stream exchange). +registration) and sex (stream exchange). SEX has the opposite authorization model of FEX: The sender does not @@ -342,7 +342,7 @@ otherwise. The client programs for sexing are sexsend and sexget. You can call them also fuckyou and fuckme :-) -With the F*EX client fexsend you can have a streaming file transfer with +With the F*EX client fexsend you can have a streaming file transfer with spooling: on client side there is no temporary buffer file (archive), but the data is sent directly to the F*EX server. This saves time and disk space on the client. @@ -383,14 +383,16 @@ directory. You can name single IPs, also as IP ranges (example: 129.69.0.0-129.69.255.255) dop is not a regular CGI program (like fup or fop), but a sub-program of -fexsrv. +fexsrv. *.html files may contain $VARIABLES$ which will be substituted with the value of the corresponding environment variable. See example $SERVER_ADMIN$ in FEXHOME/htdocs/index.html *.html files may contain <> (even multiline) which will be -evaluated. See example FEXHOME/htdocs/dynamic.html +evaluated and its output will be placed in. Same goes for <<>> +but without output catching. +See example FEXHOME/htdocs/dynamic.html This perl-code must not contain '>>' strings itself! Pay attention: do not place security relevant data inside << >> because it will be delivered to the client if the URL ends with '!'! See example: @@ -462,7 +464,7 @@ Or to delete inactive users you can put in fex.ph: $account_expire = "365:delete"; This deletes user accounts automatically which have been inactive for 365 -days. +days. Of course you can use any number of days. @@ -489,7 +491,7 @@ because most proxies do not support persistant tcp sessions. See fex-client_2.pdf for the F*EX protocol specification. To understand and trace the F*EX protocol you can use fexsend with the -v -option. +option. Example (--> means send to server, <-- means receive from server): @@ -504,47 +506,47 @@ TCPCONNECT to fex.rus.uni-stuttgart.de <-- X-SID: 8p2Y2qa2 <-- X-Timeout: 30 <-- Content-Length: 0 -<-- +<-- --> HEAD /fop/framstag@flupp.org/framstag@fex.rus.uni-stuttgart.de/X.png??ID=MD5H:226e896d0adab86892957aa8158b37ba HTTP/1.1 --> <-- HTTP/1.1 200 OK <-- Content-Length: 0 <-- X-Size: 0 <-- X-Features: SID,CHECKRECIPIENT,GROUPS,QUOTA,FILEID,MULTIPOST,XKEY -<-- +<-- --> POST /fup HTTP/1.1 --> Host: fex.rus.uni-stuttgart.de --> User-Agent: fexsend (Ubuntu 8.04.4 LTS) --> Content-Length: 149935162 --> Content-Type: multipart/form-data; boundary=JhUOtQ3sgV5ZcHJzrTny523nBFqgUNvSAOUHoRMTdZfGpAjs ---> +--> --> --JhUOtQ3sgV5ZcHJzrTny523nBFqgUNvSAOUHoRMTdZfGpAjs --> Content-Disposition: form-data; name="FROM" ---> +--> --> framstag@fex.rus.uni-stuttgart.de --> --JhUOtQ3sgV5ZcHJzrTny523nBFqgUNvSAOUHoRMTdZfGpAjs --> Content-Disposition: form-data; name="TO" ---> +--> --> framstag@flupp.org --> --JhUOtQ3sgV5ZcHJzrTny523nBFqgUNvSAOUHoRMTdZfGpAjs --> Content-Disposition: form-data; name="ID" ---> +--> --> MD5H:226e896d0adab86892957aa8158b37ba --> --JhUOtQ3sgV5ZcHJzrTny523nBFqgUNvSAOUHoRMTdZfGpAjs --> Content-Disposition: form-data; name="FILESIZE" ---> +--> --> 149934400 --> --JhUOtQ3sgV5ZcHJzrTny523nBFqgUNvSAOUHoRMTdZfGpAjs --> Content-Disposition: form-data; name="FILE"; filename="X.png" --> Content-Type: application/octet-stream --> Content-Length: 149934400 --> X-File-ID: 1283077463 ---> +--> --> (file content) --> --JhUOtQ3sgV5ZcHJzrTny523nBFqgUNvSAOUHoRMTdZfGpAjs-- <-- Location: http://fex.rus.uni-stuttgart.de/fop/CoVhikzk/X.png <-- X-Recipient: framstag@flupp.org (autodelete=YES,keep=5) -<-- +<-- Comment on the HEAD request above: The client fexsend sends it to request whether the file has been sent @@ -560,7 +562,7 @@ CHECKRECIPIENT is a HTTP POST request to check whether the recpient's email address is valid to the server. GET ADDRESS_BOOK is a HTTP GET request to check if the recipient with a short address (= address without @) is an alias in the senders server -address book. +address book. Please use "fexsend -v" by yourself to see the whole protocol dialoge. Many HTTP proxies have a POST limit, which is often at 2 GB, but sometimes diff --git a/doc/debugging b/doc/debugging index d81dfe2..dec7369 100644 --- a/doc/debugging +++ b/doc/debugging @@ -13,4 +13,3 @@ with detailed debugging output. If this does not help at all, contact me :-) framstag@rus.uni-stuttgart.de - diff --git a/doc/fex-client_1.pdf b/doc/fex-client_1.pdf index a574738..adbd5fb 100644 Binary files a/doc/fex-client_1.pdf and b/doc/fex-client_1.pdf differ diff --git a/doc/fex-client_2.pdf b/doc/fex-client_2.pdf index 1bbd79c..6065df3 100644 Binary files a/doc/fex-client_2.pdf and b/doc/fex-client_2.pdf differ diff --git a/doc/installation b/doc/installation index 0e63e12..1b24c25 100644 --- a/doc/installation +++ b/doc/installation @@ -2,7 +2,7 @@ Prerequisites: ============== To install the F*EX server, you need a UNIX system with perl, xinetd and -/usr/lib/sendmail (either original or a clone like postfix or exim). +/usr/lib/sendmail (either original or a clone like postfix or exim). Your perl must have the following standard core modules: CGI @@ -34,9 +34,9 @@ To install F*EX, simply run "./install", then edit lib/fex.ph and set your local config. If you want to upgrade from a previous F*EX version, you also can run "./install", no old config files will be overwritten. Also index.html is kept. - + Alternativly use "./install -p 8888" to install F*EX on port 8888 instead -on default port 80. +on default port 80. Run "./install" again for installing optional localizations (languages). diff --git a/doc/new b/doc/new index c0ae6f2..badf322 100644 --- a/doc/new +++ b/doc/new @@ -2,6 +2,11 @@ New release on http://fex.belwue.de/fex.html Important changes: -- added fexit (Windows client) and macfexsend (MacOS client) support +- recipient address can have attached :options (keep,autodelete,locale) + +- added config variable @extra_header with default HTTP security headers, + see: https://securityheaders.io/?q=http%3A%2F%2Ffex.belwue.de + +- dynamic HTML runs in own Perl namespace (DOP) - fixed various bugs diff --git a/doc/newfeatures b/doc/newfeatures index 57e383f..5f3636e 100644 --- a/doc/newfeatures +++ b/doc/newfeatures @@ -1,6 +1,11 @@ New features for users ---------------------- +2016-03-15: + +- recipient address can have attached :options (keep,autodelete,locale) + + 2016-01-04: - new Windows client fexit @@ -17,7 +22,7 @@ New features for users - fexsend has new option -N resend notification email - + 2014-12-24: - the CLI clients respect the environment variables SSLVERIFY SSLVERSION @@ -52,4 +57,3 @@ New features for users - allow multiple downloads from same ip - fexget proxy support - diff --git a/doc/version b/doc/version index 366b2e9..7b735e5 100644 --- a/doc/version +++ b/doc/version @@ -1 +1 @@ -fex-20160104 +fex-20160328 diff --git a/doc/xx b/doc/xx index 3a99684..af6b6a0 100644 --- a/doc/xx +++ b/doc/xx @@ -1,6 +1,6 @@ With xx you have a network wide shell based clip board for files and STDIN/STDOUT: easy data exchange between different accounts on different -hosts. +hosts. usage: send file(s): xx file... or: send STDIN: xx - @@ -13,8 +13,8 @@ Pipe example: framstag@tandem:~: uname -a | xx /home/framstag/.fex/tmp/STDFEX : 0 kB in 1 s (0 kB/s) - - + + framstag@fex:~: xx transfered: 0 MB (100%) Linux tandem 2.6.24-28-server #1 SMP Wed Aug 18 22:01:20 UTC 2010 i686 GNU/Linux @@ -30,19 +30,19 @@ File transfer example: (...) /boot/System.map-2.6.24-27-generic /home/framstag/.fex/tmp/STDFEX : 34 MB in 2 s (17605 kB/s) - - + + framstag@fex:/tmp: xx transfered: 34 MB (100%) Files in transfer-container: - + drwxr-xr-x root/root 0 2010-10-20 07:37 boot/ -rw-r--r-- root/root 7905085 2010-05-25 15:38 boot/initrd.img-2.6.24-27-generic -rw-r--r-- root/root 1927544 2010-10-16 20:38 boot/vmlinuz-2.6.24-28-generic (...) -rw-r--r-- root/root 906803 2010-03-24 14:33 boot/System.map-2.6.24-27-generic - - Extract these files? + + Extract these files? One problem are shared system accounts like root where different persons @@ -51,7 +51,7 @@ personal data. But you can put the ID authorization in the environment variable FEXID. -fexsend on your local account gives you a string for "cut and paste", example: +fexsend on your local account gives you a string for "cut and paste", example: framstag@moep:~: fexsend -I export FEXID='fex.rus.uni-stuttgart.de:8080 framstag jmBhf9ht' @@ -68,7 +68,7 @@ Now you can use xx (or fexsend and fexget) as normal. Example: root@tandem:~# grep sshd /var/log/daemon | xx transfered: 265 kB in 1 s (265 kB/s) - + framstag@moep:~: xx | wc -l 434279 @@ -85,15 +85,15 @@ be transfered uncompressed. Tip: If you want to transfer files uncompress, then use: tar cvf - your files... | xx With default usage only one "storage slot" is available: STDFEX -But you can use as many "storage slots" as you want by using "xx :TAG" +But you can use as many "storage slots" as you want by using "xx :TAG" Examples: uname -a | xx - + grep sshd /var/log/daemon | xx :log - - xx :log | grep obertux - + + xx :log | grep obertux + xx :config /boot /etc /root - + xx :config -- diff --git a/htdocs/FAQ/admin.faq b/htdocs/FAQ/admin.faq index 4c442ca..61691fc 100644 --- a/htdocs/FAQ/admin.faq +++ b/htdocs/FAQ/admin.faq @@ -3,7 +3,7 @@ A: F*EX is hard bound to fexsrv for several reasons (performance, file size limi * https://github.com/FileZ/FileZ * http://freshmeat.net/projects/eventh/ - * http://www.schaarwaechter.de/sp/projekte/dateiaustausch.html (German only!) + * http://www.schaarwaechter.de/sp/projekte/dateiaustausch.html (German only!) which implement a file exchange as pure CGIs, but with a 2 GB file size limit, which F*EX does not have. @@ -19,7 +19,7 @@ A: Become user fex and create some users with fac, exa /home/fex/bin/fac -u memyselfandi@my.do.main secret-auth-id Then log in using the web interface: http://YOURFEXSERVER/ - + ... and join the F*EX mailing list! ☺ https://listserv.uni-stuttgart.de/mailman/listinfo/fex @@ -27,8 +27,8 @@ Q: What is /home/fex/bin/fac and /home/fex/cgi-bin/fac ? A: fac stands for F*EX Admin Control /home/fex/bin/fac is the (full) CLI version - - /home/fex/cgi-bin/fac is the (restricted) web version. You have to call it with your webbrowser: + + /home/fex/cgi-bin/fac is the (restricted) web version. You have to call it with your webbrowser: http://YOURFEXSERVER/fac Q: F*EX is not working at all! I cannot connect to it with my web browser! @@ -52,7 +52,7 @@ A: F*EX users are defined by a directory in the spool. Therefore execute: cd /home/fex/spool ln -s user@do.main alias@other.address - + Now the user is known as user@do.main and alias@other.address Q: I want that all my local users can use F*EX. How? @@ -77,11 +77,11 @@ A: Let them register themselves with http://YOURFEXSERVER/fur

      # your local receiving domains
      @local_rdomains = qw(flupp.org *.flupp.org);
-     	     
+
      # your local receiving hosts
      @local_rhosts = qw(127.0.0.1 129.69.0.0-129.69.255.255 176.9.84.26);
    
- + Or you can manually create a restricted external user with (example):
      /home/fex/bin/fac -u framstag@rus.uni-stuttgart.de hoppla
@@ -116,7 +116,7 @@ A: Add the mailing list address to @mailing_list in /home/fex/lib/fex.ph
    This allows multiple downloads.
 
 Q: I need more security! How can I enable (https) encryption?
-A: Read doc/SSL and also look for "fop_auth" in doc/concept 
+A: Read doc/SSL and also look for "fop_auth" in doc/concept
    (doc is a local directory in your installation or online http://fex.belwue.de/doc/)
    For email encryption see http://fex.belwue.de/gpg.html
 
@@ -126,7 +126,7 @@ A: * See variable @H1_extra in /home/fex/lib/fex.ph and you can add HTML code to
    * Contact  http://www.nepustil.net/ if you need more customization.
 
 Q: F*EX is too complicated for my tie users. I need a simplified upload form.
-A: See /home/fex/htdocs/fup_template.html and /home/fex/htdocs/sup.html 
+A: See /home/fex/htdocs/fup_template.html and /home/fex/htdocs/sup.html
    or use public upload, see http://fex.belwue.de/usecases/foreign.html
 
 Q: F*EX is still too complicated! I need something more simplified.
@@ -138,8 +138,8 @@ A: See http://fex.belwue.de/usecases/BIGMAIL.html
 Q: Can I get a localized version in my native languange?
 A: With your help, yes. Please contact 
 
-Q: I need ACLs for group access, a file browser and integration in my
-   native file system.
+Q: I need ACLs for group access, versioning, a file browser and integration in
+   my local file system.
 A: This is beyond the scope of F*EX, which is designed for efficient file transfer only.
 
 Q: Feature/design XY is missing.
diff --git a/htdocs/FAQ/faq.pl b/htdocs/FAQ/faq.pl
index 6cadd49..3a2fcff 100644
--- a/htdocs/FAQ/faq.pl
+++ b/htdocs/FAQ/faq.pl
@@ -45,7 +45,7 @@ foreach my $faq (@faq) {
     $q =~ s! (/\w[\S]+/[\S]+)! $1!g;
     $a =~ s/[\s\n]+$/\n/;
     $a =~ s/^\s+//;
-    while ($a =~ s/^(\s*)\*/$1
    \n$1
  • /m) { + while ($a =~ s/^(\s*)\*/$1
      \n$1
    • /m) { while ($a =~ s/(
    • .*\n\s*)\*/$1
    • /g) {} $a =~ s:(.*\n)(\s*)(
    • [^\n]+\n):$1$2$3$2
    \n:s } diff --git a/htdocs/FAQ/meta.faq b/htdocs/FAQ/meta.faq index 8a5f3a2..f910621 100644 --- a/htdocs/FAQ/meta.faq +++ b/htdocs/FAQ/meta.faq @@ -1,6 +1,6 @@ Q: What is so special about F*EX? -A: See feature list http://fex.belwue.de/features.html - and use cases http://fex.belwue.de/usecases/ +A: See feature list http://fex.rus.uni-stuttgart.de/features.html + and use cases http://fex.rus.uni-stuttgart.de/usecases/ Q: Why not use one of the commercial services like DropLoad, ALLPeers, YouSendIt, etc? A: * They have a file size limit of 2 GB or even less. @@ -9,7 +9,7 @@ A: * They have a file size limit of 2 GB or even less. * There are no UNIX (CLI) clients for them. * They need java, active-X, flash or other evil plugins. * 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 a program named "FEX" listed on freshmeat.net. @@ -47,7 +47,7 @@ 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: +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" https://www.youtube.com/watch?v=JHU0HinVhYc https://en.wikipedia.org/wiki/Sneakers_%281992_film%29 @@ -63,7 +63,7 @@ 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 @@ -83,7 +83,7 @@ A: F*EX is written in Perl which does not have common security problems with buf F*EX does not use an extra web server or a (SQL) database, so no typical web attacks are possible. F*EX was analysed by security company revshell.com and labeled as "secure". F*EX comes with source code, so everybody can verify it. - + Q: Feature/design XY is missing. A: Contact the author diff --git a/htdocs/FAQ/misc.faq b/htdocs/FAQ/misc.faq index 050902d..107cef5 100644 --- a/htdocs/FAQ/misc.faq +++ b/htdocs/FAQ/misc.faq @@ -10,7 +10,7 @@ A: Contact the author see thunderbird's filelink https://support.mozillamessaging.com/en-US/kb/filelink-large-attachments https://developer.mozilla.org/en/Thunderbird/Filelink_Providers -
  • more (other) languange support (japanese, bavarian, klingon ...) +
  • more (other) languange support (japanese, bavarian, klingon ...)
Q: Can I donate something for F*EX? diff --git a/htdocs/FAQ/user.faq b/htdocs/FAQ/user.faq index 641886a..86128c3 100644 --- a/htdocs/FAQ/user.faq +++ b/htdocs/FAQ/user.faq @@ -70,12 +70,18 @@ A: Either you or someone else have already downloaded this file. Now it is gone. Q: Can I fex to a mailing list? A: Generally: no, because the first download makes the file no more available for others. - Contact $SERVER_ADMIN$, he can allow multiple downloads for specific addresses. - + Contact $SERVER_ADMIN$, he can allow multiple downloads for specific addresses. + Q: Sending as a F*EX user is easy, but how to receive files from others, outside? 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: What is a F*EX group? +A: F*EX group is similar to a mailing list, but for files: + When a member fexes a file to this list, then all other members will receive it. + Any full user can create a F*EX group and add or delete members. + See "user config & operation control" → "Manage your subusers and groups" + 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. @@ -84,7 +90,7 @@ Q: Sometimes I can download a file more than once, especially when I repeat it q 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. Your fexmaster has set AUTODELETE=DELAY as default, which means that the autodelete cleanup process is called once a day. - + Power users (use the source, Luke!) can set a "do not delete after download" flag. Q: I have uploaded a file to a list of recipients. Will the file be deleted after the first recipient has dowloaded it? @@ -128,6 +134,10 @@ A: No. Q: Can I have encrypted emails? A: See http://fex.belwue.de/gpg.html +Q: I need ACLs for group access, versioning, a file browser and integration in + my local file system. +A: This is beyond the scope of F*EX, which is designed for efficient file transfer only. + Q: I cannot download files with Internet Explorer, it tells me "Cannot open Internet site". What shall I do? A: Use Firefox or any other Internet-compatible web browser, that Internet Explorer is not. This is one of the many bugs of Internet Explorer. @@ -145,7 +155,7 @@ A: For example with "Stuffit Expander": Q: How can I prevent the fexsend error SSL3_GET_SERVER_CERTIFICATE:certificate verify failed? A: Set the environment variable SSLVERIFY=0 - Rationale: - Your openssl library cannot resolve the SSL certification path. + Rationale: + Your openssl library cannot resolve the SSL certification path. With SSLVERIFY=0 you tell openssl to ignore certification verification. Yes, this is a crude workaround :-} diff --git a/htdocs/SEX.html b/htdocs/SEX.html index 81b83ad..2014702 100644 --- a/htdocs/SEX.html +++ b/htdocs/SEX.html @@ -1,4 +1,4 @@ - + Stream EXchange
diff --git a/htdocs/download/fexget b/htdocs/download/fexget index c375cea..b0616a1 100755 --- a/htdocs/download/fexget +++ b/htdocs/download/fexget @@ -30,10 +30,11 @@ our $SH; our ($fexhome,$idf,$tmpdir,$windoof,$useragent); our ($xv,%autoview); our $bs = 2**16; # blocksize for tcp-reading and writing file -our $version = 20160104; +our $version = 20160328; our $CTYPE = 'ISO-8859-1'; our $fexsend = $ENV{FEXSEND} || 'fexsend'; our $DEBUG = $ENV{DEBUG}; +our $_0 = $0; my %SSL = (SSL_version => 'TLSv1'); my $sigpipe; @@ -150,7 +151,7 @@ $opt_V = $opt_X = $opt_f = $opt_L = $opt_H = 0; ${'opt_+'} = 0; $opt_s = $opt_k = $opt_i = $opt_P = ''; $_ = "$fexhome/config.pl"; require if -f; -getopts('hvVHlLdkzoaXf+m:s:i:K:P:') or die $usage; +getopts('hvVHlLdkzoaXVf+m:s:i:K:P:') or die $usage; $opt_k = '?KEEP' if $opt_k; if ($opt_m =~ /(\d+)/) { @@ -159,7 +160,27 @@ if ($opt_m =~ /(\d+)/) { $opt_m = 0 } -print "Version: $version\n" if $opt_V; +if ($opt_V) { + print "Version: $version\n"; + unless (@ARGV) { + print "Upgrade fexget? "; + $_ = ||''; + if (/^y/i) { + my $new = `wget -nv -O- http://fex.belwue.de/download/fexget`; + if ($new !~ /upgrade fexget/) { + die "$0: bad update\n"; + } + system qw'cp -a',$_0,$_0.'_old'; + exit $? if $?; + open $_0,'>',$_0 or die "$0: cannot write $_0. - $!\n"; + print {$_0} $new; + close $_0; + exec $_0,qw'-V .'; + } + } + exit if "@ARGV" eq '.'; +} + die $usage if $opt_h; if ($opt_H) { print $hints; @@ -172,15 +193,14 @@ my $ffl = "$tmpdir/fexget"; # F*EX files list (cache) my @rcamel = ( ' -(_*) _ _ - \\\\/ \\/ \\ + (_*p _ _ + \\\\/ \/ \\ \ __ )=* //\\\\//\\\\ ', -' \\\\/\\\\/ -', -' //\\\\//\\\\ -'); +" \\\\/\\\\/ \n", +" //\\\\//\\\\\n" +); # get fexlog if ($opt_z) { @@ -566,7 +586,7 @@ sub keep { sub download { my ($server,$port,$fop,$nocheck) = @_; - my ($file,$download,$ssl,$pipe,$filesize,$checkstorage); + my ($file,$download,$ssl,$pipe,$filesize,$checkstorage,$dkey); my (@hh,@r); my ($t0,$t1,$t2,$tt,$tm,$ts,$kBs,$b,$bt,$tb,$B,$buf); my $length = 0; @@ -619,8 +639,11 @@ sub download { $seek = -s $download || 0; } + $fop =~ m:/fop/(\w+)/: and $dkey=$1 or $dkey=''; + push @hh,"GET $proxy_prefix$fop$opt_k HTTP/1.1", "User-Agent: $useragent", + "Cookie: dkey=$dkey", "Connection: close"; push @hh,"Range: bytes=$seek-" if $seek; diff --git a/htdocs/download/fexsend b/htdocs/download/fexsend index 7e498dc..f47bed4 100755 --- a/htdocs/download/fexsend +++ b/htdocs/download/fexsend @@ -37,7 +37,7 @@ our ($tpid,$frecipient); our ($FEXID,$FEXXX,$HOME); our (%alias); our $chunksize = 0; -our $version = 20160104; +our $version = 20160328; our $_0 = $0; our $DEBUG = $ENV{DEBUG}; @@ -45,6 +45,7 @@ my %SSL = (SSL_version => 'TLSv1'); my $sigpipe; if ($Config{osname} =~ /^mswin/i) { + # http://slu.livejournal.com/17395.html $windoof = $Config{osname}; $HOME = $ENV{USERPROFILE}; $fexhome = $ENV{FEXHOME} || $HOME.'\fex'; @@ -55,8 +56,8 @@ if ($Config{osname} =~ /^mswin/i) { $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 + $macos = $Config{osname}; $HOME = (getpwuid($<))[7]||$ENV{HOME}; $fexhome = $HOME.'/.fex'; $tmpdir = $ENV{FEXTMP} || $ENV{TMPDIR} || "$fexhome/tmp"; @@ -142,10 +143,11 @@ special options: -I initialize ID file or show ID -d \# delete file on fex server -N \# resend notification e-mail -Q check quotas + -T up:down test internet speed with up and down MBs -A edit server address book (aliases) -S show server/user settings and auth-ID -H show hints, examples and more options - -V show version + -V show version and ask for upgrade (# 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 @@ -231,7 +233,7 @@ whereas archive types zip and 7z need a temporary archive file on local disk. 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 URL parameter, e.g.: +With option -X you can specify any URL parameter, e.g.: fexsend -X autodelete=yes ... fexsend -X 'autodelete=no&locale=german' ... @@ -286,11 +288,22 @@ my @rcamel = ( *=( __ / \\\\/\\\\/ ', -' \\\\/\\\\/ +" \\\\/\\\\/ \n", +" //\\\\//\\\\\n" +); + +my @rrcamel = ( +' + (_*p _ _ + \\\\/ \/ \\ + \ __ )=* + //\\\\//\\\\ ', -' //\\\\//\\\\ -'); +" \\\\/\\\\/ \n", +" //\\\\//\\\\\n" +); +autoflush STDOUT; autoflush STDERR; if ($windoof and not @ARGV and not $ENV{PROMPT}) { @@ -312,7 +325,7 @@ my @_ARGV = @ARGV; # save arguments our ($opt_q,$opt_h,$opt_H,$opt_v,$opt_m,$opt_c,$opt_k,$opt_d,$opt_l,$opt_I, $opt_K,$opt_D,$opt_u,$opt_f,$opt_a,$opt_C,$opt_R,$opt_M,$opt_L,$opt_Q, $opt_A,$opt_i,$opt_z,$opt_Z,$opt_b,$opt_P,$opt_x,$opt_X,$opt_V,$opt_U, - $opt_s,$opt_o,$opt_g,$opt_F,$opt_n,$opt_r,$opt_S,$opt_N); + $opt_s,$opt_o,$opt_g,$opt_F,$opt_n,$opt_r,$opt_S,$opt_N,$opt_T); if ($xx) { $opt_q = 1 if @ARGV and $ARGV[-1] eq '--' and pop @ARGV or not -t STDOUT; @@ -331,9 +344,9 @@ if ($xx) { ${'opt_@'} = ${'opt_!'} = ${'opt_+'} = ${'opt_.'} = ${'opt_/'} = 0; ${'opt_='} = ${'opt_#'} = ''; $opt_u = $opt_f = $opt_a = $opt_C = $opt_i = $opt_b = $opt_P = $opt_X = ''; - $opt_s = $opt_r = ''; + $opt_s = $opt_r = $opt_T = ''; $_ = "$fexhome/config.pl"; require if -f; - getopts('hHvcdognVDKlILUARWMFzZqQS@!+./r:m:k:u:f:a:s:C:i:b:P:x:X:N:=:#:') + getopts('hHvcdognVDKlILUARWMFzZqQS@!+./r:m:k:u:f:a:s:C:i:b:P:x:X:N:T:=:#:') or die $usage; if ($opt_H) { @@ -343,6 +356,23 @@ if ($xx) { if ($opt_V) { print "Version: $version\n"; + unless (@ARGV) { + print "Upgrade fexsend? "; + $_ = ||''; + if (/^y/i) { + my $new = `wget -nv -O- http://fex.belwue.de/download/fexsend`; + if ($new !~ /upgrade fexsend/) { + die "$0: bad update\n"; + } + system qw'cp -aL',$_0,$_0.'_old'; + exit $? if $?; + open $_0,'>',$_0 or die "$0: cannot write $_0. - $!\n"; + print {$_0} $new; + close $_0; + exec $_0,qw'-V .'; + } + } + exit if "@ARGV" eq '.'; } if ($opt_K and $opt_D) { @@ -477,6 +507,29 @@ if ($opt_I) { exit; } +if ($opt_T) { + my ($up,$down); + + $usage = "usage: $0 -T MB_up[:MB_down] [fexserver]\n"; + if ($opt_T =~ /^(\d+)$/) { + $up = $down = $1; + } elsif ($opt_T =~ /^(\d+):(\d+)$/) { + $up = $1; + $down = $2; + } else { + die $usage; + } + + if (@ARGV) { + nettest($ARGV[0],$up,$down); + } elsif ($fexcgi) { + nettest($fexcgi,$up,$down); + } else { + nettest('fex.belwue.de',$up,$down); + } + exit; +} + if (@ARGV > 1 and $ARGV[-1] =~ /(^|\/)anonymous/) { $fexcgi = $1 if $ARGV[-1] =~ s:(.+)/::; die "usage: $0 [options] file FEXSERVER/anonymous\n" unless $fexcgi; @@ -805,7 +858,7 @@ sub menu { my $key; my $new; local $_; - + system 'clear'; print "\n"; print "fexsend-$version\n"; @@ -824,7 +877,7 @@ sub menu { print "\n"; print "$from on $fexcgi\n"; print "\n"; - + for (;;) { print "\n"; print "[s] send a file or directory\n"; @@ -835,15 +888,15 @@ sub menu { print "\n"; print "your choice: "; $key = ReadKey(0); - if ($key eq 'q') { + if ($key eq 'q') { print "$key\n"; print "\n"; print "Type [Cmd]W to close this window.\n"; exit; } - if ($key eq 'h') { + if ($key eq 'h') { print "$key\n"; - print + print "\n". "With fexsend you can send files of any size to any e-mail address.\n". "\n". @@ -855,10 +908,10 @@ sub menu { "\n". "Do not forget to terminate each input line with [RETURN].\n". "\n". - "See http://fex.rus.uni-stuttgart.de/ for more informations.\n"; + "See http://fex.rus.uni-stuttgart.de/ for more information.\n"; next; } - if ($key eq 'u') { + if ($key eq 'u') { print "$key\n"; if ($0 =~ m:(^/client/|/sw/):) { print "\n"; @@ -878,13 +931,13 @@ sub menu { } next; } - if ($key eq 'l') { + if ($key eq 'l') { print "$key\n"; system 'clear'; &set_ID; next; } - if ($key eq 's' or $key eq "\n") { + if ($key eq 's' or $key eq "\n") { print "s\n"; &ask_file; next; @@ -900,9 +953,9 @@ sub ask_file { my @files; my $qfiles; local $_; - + system 'clear'; - + &set_ID unless -s $idf; print "\n"; @@ -1021,7 +1074,7 @@ sub ask_file { sub set_ID { my ($server,$port,$user,$logo); local $_; - + print "\n"; for (;;) { print "F*EX server URL: "; @@ -1071,7 +1124,6 @@ sub set_ID { sendheader( "$server:$port", "GET /logo.jpg HTTP/1.0", - "User-Agent: $useragent", "Connection: close", ); $_ = <$SH>||''; @@ -1092,7 +1144,7 @@ sub set_ID { close $logo; last; } - + for (;;) { last if $user; print "Your login (e-mail address): "; @@ -1103,14 +1155,14 @@ sub set_ID { next; } } - + for (;;) { last if $id; print "Your auth-ID for this account: "; $id = ; $id =~ s/[\s\n]//g; } - + open $idf,'>',$idf or die "$0: cannot write to $idf - $!\n"; print {$idf} "$server\n", "$user\n", @@ -1131,11 +1183,111 @@ sub set_ID { } + +sub nettest { + my $url = shift; + my $up = shift; + my $down = shift; + my $bs = 2**16; + my ($length,$t0,$t1,$t2,$tt,$tb,$tc,$B,$kBs,$bt); + + my $nettest = $sid = 'nettest'; + + $port ||= 80; + if ($url =~ s:^https.//::) { + $https = $port = 443; + } else { + $url =~ s:^http.//::; + $port = $1 if $url =~ s/:(\d+)//; + } + $url =~ s/[\/:].*//; + $server = $url; + + if ($up) { + serverconnect($server,$port); + checkrecipient($nettest,$nettest); + warn "$0: send to $server:$port\n"; + formdatapost( + from => $nettest, + to => $nettest, + id => $nettest, + file => $nettest, + size => $up*M, + comment => 'NOSTORE', + ); + } + + if ($down) { + serverconnect($server,$port); + warn "$0: receive from $server:$port\n"; + sendheader("$server:$port","GET $proxy_prefix/ddd/$down HTTP/1.0"); + $_ = <$SH>; + die "$0: no response from fex server $server\n" unless $_; + s/\r//; + + if (/^HTTP\/[\d.]+ 2/) { + warn "<-- $_" if $opt_v; + while (<$SH>) { + s/\r//; + print "<-- $_" if $opt_v; + last if /^$/; + $length = $1 if /^Content-Length:\s*(\d+)/i; + } + } else { + s/HTTP\/[\d.]+ \d+ //; + die "$0: bad server reply: $_"; + } + + unless ($length) { + die "$0: no Content-Length header in server reply\n"; + } + + + if (${'opt_+'}) { + print $rrcamel[0]; + $tc = 0; + } + + $t0 = $t1 = $t2 = int(time); + $B = 0; + while ($B < $length) { + $b = read $SH,$_,$bs or die "$0: cannot read after $B bytes - $!\n"; + # defined($_ = <$SH>) or die "$0: cannot read after $B bytes - $!\n"; + # $b = length; + $B += $b; + $bt += $b; + $t2 = time; + if (${'opt_+'} and int($t2*10)>$tc) { + print $rrcamel[$tc%2+1]; + $tc = int($t2*10); + } + if (int($t2) > $t1) { + $kBs = int($bt/k/($t2-$t1)); + $t1 = $t2; + $bt = 0; + printf STDERR "nettest: %d MB (%d%%) %d kB/s \r", + int($B/M),int(100*$B/$length),$kBs; + } + } + close $SH; + + $tt = $t2-$t0; + $kBs = int($B/k/($tt||1)); + if (${'opt_+'}) { + print $rrcamel[1]; + print $rrcamel[2]; + } + printf STDERR "nettest: %d MB in %d s = %d kB/s \n", + int($B/M),$tt,$kBs; + } +} + + # 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) { @@ -1339,7 +1491,6 @@ sub list { sendheader( "$server:$port", "GET $proxy_prefix/fop/$2/$2?LIST HTTP/1.1", - "User-Agent: $useragent", ); $_ = <$SH>||''; s/\r//; @@ -1364,7 +1515,7 @@ sub list { die "$0: file \#$a not found in fexlist\n"; } } - + @r = formdatapost( from => $from, to => $opt_l ? '*' : $from, @@ -1391,7 +1542,7 @@ sub list { s/&/&/g; s/"/\"/g; s/</||''; s/\r//; @@ -1528,14 +1678,13 @@ sub delete_file { 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; @@ -1917,7 +2066,7 @@ sub send_fex { } } if ($from eq $to or $from =~ /^\Q$to\E@/i - or $nomail or $anonymous or $nonot) + or $nomail or $anonymous or $nonot) { print "$recipient\n" if $recipient; print "$location\n" if $location; @@ -2174,10 +2323,10 @@ sub get_xx { sub formdatapost { my %P = @_; - my ($boundary,$filename,$length,$buf,$file,$fpsize,$resume,$seek); + my ($boundary,$filename,$length,$buf,$file,$fpsize,$resume,$seek,$nettest); my ($flink); my (@hh,@hb,@r,@pv,$to); - my ($bytes,$t,$bt); + my ($bytes,$b,$t,$bt); my ($t0,$t1,$t2,$tt,$tc); my $bs = 2**16; # blocksize for reading and sending file my $fileid = int(time); @@ -2285,7 +2434,7 @@ sub formdatapost { } # print "calculating archive size... "; debug("cd $dittodir;$ditto -"); - open $ditto,"cd $dittodir;$ditto - 2>$error|" + 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) { @@ -2315,6 +2464,12 @@ sub formdatapost { undef $SH; # force reconnect (timeout!) } + elsif ($P{to} eq 'nettest') { + $filename = $nettest = 'nettest'; + $filesize = $P{size}; + $fileid = 0; + } + # single file else { $filename = encode_utf8(${'opt_='} || $file); @@ -2334,7 +2489,7 @@ sub formdatapost { $filename .= '.gpg' if $opt_g; - unless ($opt_d) { + unless ($opt_d or $nettest) { if ($opt_g) { $filesize = -1; $fileid = int(time); @@ -2363,7 +2518,7 @@ sub formdatapost { unless ($SH) { serverconnect($server,$port); - query_sid($server,$port) unless $anonymous; + query_sid($server,$port) unless $anonymous or $nettest; } $P{id} = $sid; # ugly hack! @@ -2371,7 +2526,7 @@ sub formdatapost { $filename =~ s/\\/_/g; # \ is a illegal character for fexsrv # ask server if this file has been already sent - if ($file and not $xx) { + if ($file and not $xx and not $nettest) { if (not $opt_d and $opt_o) { # delete before overwrite delete_file($from,$to,$filename); @@ -2548,6 +2703,8 @@ sub formdatapost { print "Fast forward to byte $seek (resuming)\n"; readahead($file,$seek); } + } elsif ($nettest) { + # } else { if ($opt_g) { my $fileq = quote($file); @@ -2564,8 +2721,17 @@ sub formdatapost { print $rcamel[0] if ${'opt_+'}; + $buf = '#' x $bs if $nettest; + $SIG{ALRM} = sub { retry("timed out") }; - while (my $b = read $file,$buf,$bs) { + + while ($bytes < $fpsize) { + if ($nettest) { + $b = $bs; + } else { + $b = read $file,$buf,$bs; + last if $b == 0; + } alarm($timeout*2); if ($https) { print {$SH} $buf or &sigpipehandler; @@ -2574,7 +2740,7 @@ sub formdatapost { } alarm(0); $bytes += $b; - if ($filesize > 0 and $bytes+$seek > $filesize) { + if (not $nettest and $filesize > 0 and $bytes+$seek > $filesize) { if ($tpid) { kill 9,$tpid; unlink $list; @@ -2619,7 +2785,9 @@ sub formdatapost { last if $filesize > 0 and $bytes >= $fpsize; sleep 1 while ($opt_m and $bytes/k/(time-$t0||1) > $opt_m); } - close $file; # or die "$0: error while reading $file - $!\n"; + + close $file unless $nettest; + $tt = ($t2-$t0)||1; print $rcamel[2] if ${'opt_+'}; @@ -2630,7 +2798,7 @@ sub formdatapost { kill 9,$tpid; unlink $list; } - + if ($fileid =~ /[a-z]/ and not ($opt_s or $opt_g)) { if ($opt_a) { if ($fileid ne md5_hex(fmd(@ARGV))) { @@ -2644,7 +2812,7 @@ sub formdatapost { } } } - + unless ($opt_q) { if (not $chunksize and $bytes+$seek < $filesize) { die "$0: \"$file\" filesize has shrunk while uploading\n"; @@ -2652,7 +2820,7 @@ sub formdatapost { if ($seek or $chunksize and $chunksize < $filesize) { if ($fpsize>2*M) { - printf STDERR "%s: %d MB in %d s (%d kB/s)", + printf STDERR "%s: %d MB in %d s = %d kB/s", $opt_s||$opt_a||$file, int($bytes/M), $tt, @@ -2664,7 +2832,7 @@ sub formdatapost { $chunk,int(($bytes+$seek)/M); } } else { - printf STDERR "%s: %d kB in %d s (%d kB/s)", + printf STDERR "%s: %d kB in %d s = %d kB/s", $opt_s||$opt_a||$file, int($bytes/k), $tt, @@ -2678,13 +2846,13 @@ sub formdatapost { } } else { if ($bytes>2*M) { - printf STDERR "%s: %d MB in %d s (%d kB/s) \n", + printf STDERR "%s: %d MB in %d s = %d kB/s \n", $opt_s||$opt_a||$file, int($bytes/M), $tt, int($bytes/k/$tt); } else { - printf STDERR "%s: %d kB in %d s (%d kB/s) \n", + printf STDERR "%s: %d kB in %d s = %d kB/s \n", $opt_s||$opt_a||$file, int($bytes/k), $tt, @@ -2692,7 +2860,7 @@ sub formdatapost { } } - if (-t STDOUT and not ($opt_s or $opt_g)) { + if (-t STDOUT and not ($opt_s or $opt_g or $nettest)) { print STDERR "waiting for server ok..." } } @@ -2700,6 +2868,7 @@ sub formdatapost { autoflush $SH 1; print {$SH} "\r\n--$boundary--\r\n"; + # return if $nettest; # special handling of streaming file because of stunnel tcp shutdown bug if ($opt_s or $opt_g) { @@ -2860,8 +3029,7 @@ sub query_file { my ($response,$fexsrv,$cc); local $_; - $to =~ s/,.*//; - $to =~ s/:\w+=.*//; + $to =~ s/[,:].*//; $to = $AB{$to} if $AB{$to}; $filename =~ s/([^_=:,;<>()+.\w\-])/'%'.uc(unpack("H2",$1))/ge; # urlencode if ($skey) { @@ -3040,12 +3208,12 @@ sub query_sid { if ($port eq 443 or $proxy) { return if $features; # early return if we know enough $req = "OPTIONS /FEX HTTP/1.1"; - $req = "HEAD / HTTP/1.1"; + $req = "HEAD /index.html HTTP/1.1"; } else { $req = "GET /SID HTTP/1.1"; } - sendheader("$server:$port",$req,"User-Agent: $useragent"); + sendheader("$server:$port",$req); $_ = <$SH>; unless (defined $_ and /\w/) { print "\n" if $opt_v; @@ -3059,7 +3227,7 @@ sub query_sid { close $SH; serverconnect($server,$port); $req = "GET /SID HTTP/1.0"; - sendheader("$server:$port",$req,"User-Agent: $useragent"); + sendheader("$server:$port",$req); $_ = <$SH>; unless (defined $_ and /\w/) { print "\n" if $opt_v; @@ -3129,7 +3297,7 @@ sub xxget { $xx =~ s:.*/::; $url = "$proxy_prefix/fop/$from/$from/$xx?ID=$id"; - sendheader("$server:$port","GET $url HTTP/1.0","User-Agent: $useragent"); + sendheader("$server:$port","GET $url HTTP/1.0"); http_response(); while (<$SH>) { s/\r//; @@ -3218,6 +3386,7 @@ sub checkrecipient { $_ = shift @r or die "$0: no reply from server\n"; if (/ 2\d\d /) { + return if $to eq 'nettest'; foreach (@r) { last if /^$/; if (s/X-(Recipient: .+)/$1\n/) { @@ -3301,7 +3470,7 @@ sub readahead { sub fileid { my $file = shift; my @s = stat($file); - + if (@s) { return md5_hex($file.$s[0].$s[1].$s[7].$s[9]); } else { @@ -3314,9 +3483,10 @@ sub fileid { sub get_mutt_alias { my $to = shift; my $ma = $HOME.'/.mutt/aliases'; - my $alias; + my ($alias,$options); local $_; + $to =~ s/(:.+)// and $options = $1; open $ma,$ma or return $to; while (<$ma>) { if (/^alias \Q$to\E\s/i) { @@ -3333,11 +3503,13 @@ sub get_mutt_alias { if (/@/) { $alias = $_; warn "$0: found mutt alias $to = $alias\n"; + $alias .= $options if $options; last; } } } close $ma; + $to = "$to:$options" if $options; return ($alias||$to); } @@ -3623,8 +3795,10 @@ sub sendheader { my $head; push @head,"Host: $sp"; + push @head,"User-Agent: $useragent"; foreach $head (@head) { + chomp $head; print "--> $head\n" if $opt_v; print {$SH} $head,"\r\n"; } diff --git a/htdocs/download/sexsend b/htdocs/download/sexsend index d9fe821..9a7d48b 100755 --- a/htdocs/download/sexsend +++ b/htdocs/download/sexsend @@ -19,7 +19,7 @@ use constant M => 2**20; eval 'use Net::INET6Glue::INET_is_INET6'; -our $version = 20160104; +our $version = 20160328; our $DEBUG = $ENV{DEBUG}; my %SSL = (SSL_version => 'TLSv1'); @@ -331,7 +331,7 @@ if ($mode eq 'anonymous') { } request("POST /sex?BS=$bs&user=$user$mode$type$timeout$stream HTTP/1.0"); -print STDERR "==> (streaming ...)\n" if $opt_v; +print STDERR "--> (streaming ...)\n" if $opt_v; transfer(STDIN,$SH); @@ -395,20 +395,22 @@ sub transfer { sub request { my $req = shift; - print STDERR "==> $req\n" if $opt_v; - syswrite $SH,"$req\r\n\r\n"; + print STDERR "--> $req\n" if $opt_v; + syswrite $SH,"$req\r\n"; + syswrite $SH,"User-Agent: sexsend\r\n"; + syswrite $SH,"\r\n"; for (;;) { unless (defined($_ = &getline)) { die "$0: server has closed the connection\n"; } if (/^HTTP\/[\d\.]+ 200/) { - print STDERR "<== $_" if $opt_v; + print STDERR "<-- $_" if $opt_v; last; } elsif (/^HTTP\/[\d\.]+ 199/) { - print STDERR "<== $_" if $opt_v; + print STDERR "<-- $_" if $opt_v; } else { if ($opt_v) { - print STDERR "<== $_"; + print STDERR "<-- $_"; exit 3; } else { s:^HTTP/[ \d\.]+::; @@ -420,7 +422,7 @@ sub request { while (defined($_ = &getline)) { last if /^\s*$/; $H{uc($1)} = $2 if /(.+):\s*(.+)/; - print STDERR "<== $_" if $opt_v; + print STDERR "<-- $_" if $opt_v; } } @@ -461,7 +463,7 @@ sub query_sid { local $_; $req = "GET SID HTTP/1.1"; - print STDERR "==> $req\n" if $opt_v; + print STDERR "--> $req\n" if $opt_v; syswrite $SH,"$req\r\n\r\n"; $_ = &getline; unless (defined $_ and /\w/) { @@ -470,12 +472,12 @@ sub query_sid { } s/\r//; if (/^HTTP.* 201 (.+)/) { - print STDERR "<== $_" if $opt_v; + print STDERR "<-- $_" if $opt_v; $id = 'MD5H:'.md5_hex($id.$1); while (defined($_ = &getline)) { s/\r//; last if /^\n/; - print STDERR "<== $_" if $opt_v; + print STDERR "<-- $_" if $opt_v; } } else { die "$0: $server does not support session ID\n"; diff --git a/htdocs/fexit.html b/htdocs/fexit.html index 3bbfeb0..ce281d3 100644 --- a/htdocs/fexit.html +++ b/htdocs/fexit.html @@ -12,33 +12,71 @@ -<<$ENV{FEXIT} = 'http://fex.belwue.de/download/fexit.exe';'';>> +<<<$ENV{FEXIT} = 'http://fex.belwue.de/download/fexit.exe'>>> -

fexit for Windows

+

fexit for Windows

+##<<>> + +#if $ENV{ID} +<> +#endif +

fexit is a F*EX -client for sending files of any size to any e-mail address.
+client for sending files of any size to any e-mail address.
fexit can also send directories or -download files and resume the upload or download after link failures, -which your webbrowser cannot do. +download files and resume the upload or download after link failures.
+Your webbrowser cannot do this.

-You can start fexit via Windows explorer or -via command console (cmd).
+You can start fexit via Windows explorer +(double-click fexit icon) or via command console (cmd.exe). +
You can also drag files or directories to the fexit icon with the Windows explorer.

+With fexit you also have access to the +F*EX internet clipboard to exchange files +between your Windows or UNIX accounts. +

+ +

+ #if $ENV{ID} -When you run fexit for the first time you are -asked for the "F*EX server URL". You can enter your personal URL: +


+When you run fexit for the first time and you are +asked for the "F*EX server URL" you can enter your personal URL:

-<<"$ENV{PROTO}://$ENV{HTTP_HOST}/fup/".b64("from=$ENV{USER}&id=$ENV{ID}")>> +<<"$ENV{PROTO}://$ENV{HTTP_HOST}/fup/".::b64("from=$ENV{USER}&id=$ENV{ID}")>>

(use your mouse for copy+paste) -

-<> #endif -##

<>
+
+##
<>
+ +


+

command line usage

+
+upload usage: fexit [-c "comment"] [-a archive] file(s) recipient[,...]
+example: fexit flupp.avi framstag@rus.uni-stuttgart.de
+example: fexit -c "lab research" -a data *.png x1@flupp.org,x2@flupp.org
+
+download usage: fexit FEX-download-URL
+example: fexit http://fex.rus.uni-stuttgart.de/fop/jHn34yp7/flupp.avi
+
+additional options:
+  -v                               # HTTP verbose output
+  -u fexserver/user@domain:auth-ID # use this server & user
+  -o                               # overwrite file
+  -d                               # delete file
+  -x [files]                       # F*EX clipboard read/write
+  -s [files]                       # SEX read/write yourself
+  -m kBs                           # max kBs throuput
+  -T up-MBs[:down-MBs]             # test internet speed
+  -X "parameter"                   # additional URI parameter
+  -X?                              # show recipients parameter
+
+ diff --git a/htdocs/fexitinstaller b/htdocs/fexitinstaller index 3054e57..df1c887 100644 --- a/htdocs/fexitinstaller +++ b/htdocs/fexitinstaller @@ -1,34 +1,39 @@ #!/usr/bin/perl -w $user = $ENV{USER}; -$id = $ENV{ID}; +$authid = $ENV{ID}; $url = "$ENV{PROTO}://$ENV{HTTP_HOST}"; $fi = 'fexitinstaller.cmd'; +$id = '%USERPROFILE%\\fex\\id'; $fe = 'http://fex.belwue.de/download/fexit.exe'; +$fx = '%USERPROFILE%\\Desktop\\fexit.exe'; $ps = '%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe'; $cmd = <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]" + mkdir "%USERPROFILE%\\fex" + if not exist "$id" ( + echo $url>"$id" + echo $user>>"$id" + echo $authid>>"$id" + ) + $ps -command "& { (New-Object Net.WebClient).DownloadFile('$fe','$fx') }" + setx PATH "%PATH%;%USERPROFILE%\\Desktop" + \@echo. + \@set /p x="See fexit on Desktop." EOD +# \@explorer "%USERPROFILE%\\Desktop" +$cmd =~ s/^ //gm; $cmd =~ s/\n/\r\n/g; -if (chdir "$spooldir/$user" and open $fi,'>',$fi) { +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"; + system "$::FEXHOME/bin/fexsend ". + "-oKq -C 'fexit for your Windows desktop' $fi $user >/dev/null 2>&1"; if ($? == 0) { print "

\n"; print "

A fexit installer has been sent to you. Check your email.

\n"; } unlink $fi; } + +return ''; diff --git a/htdocs/fup_template.html b/htdocs/fup_template.html index 7d9fd30..1fdc7d2 100644 --- a/htdocs/fup_template.html +++ b/htdocs/fup_template.html @@ -23,9 +23,9 @@
@@ -34,13 +34,13 @@ -
recipient(s):(e-mail address)
comment: (optional)
file name:
+


-After "submit" you will see an upload progress bar +After "submit" you will see an upload progress bar (if you have javascript enabled and popups allowed).

NOTE: Most web browsers cannot upload files > 2 GB!
diff --git a/htdocs/index.html b/htdocs/index.html index 5fda09d..867f0c8 100644 --- a/htdocs/index.html +++ b/htdocs/index.html @@ -1,4 +1,4 @@ - + F*EX - File EXchange

@@ -9,9 +9,9 @@ F*EX (Frams' Fast File EXchange) is a service to send big (large, huge, giant, ...) files from a user A to a user B.

-The sender uploads the file to the F*EX server using a +The sender uploads the file to the F*EX server using a WWW upload form and the recipient -automatically gets a notification e-mail with a download-URL. +automatically gets a notification e-mail with a download-URL.

You say: @@ -25,14 +25,14 @@ I say: You still need F*EX :-)

- + For example, you want to send your friend your last holiday video (1 GB). You have the following possibilities (and problems):

  • sending a DVD by postal service

    - Out of the question - we live in the year - <> + Out of the question - we live in the year + <> after invention of the internet! Sending media (hardware) is for grandpas.

    @@ -60,7 +60,7 @@ You have the following possibilities (and problems):

  • Who else can download your file?
  • Who else can delete your file?
  • You have to send your friend the download-URL, he has to - inform you about the successful download, you have to delete + inform you about the successful download, you have to delete it afterwards.
    All in all: a pain in the ass.
@@ -130,7 +130,7 @@ the shell-tools sexsend and sexget. Authentication is the same as with F*EX.

Still questions?

-See the full feature list, +See the full feature list, the FAQ and the use cases. @@ -138,4 +138,4 @@ and the use cases.
contact: fexmaster
- + diff --git a/htdocs/macfexsend.html b/htdocs/macfexsend.html index 2c17c78..633b2f0 100644 --- a/htdocs/macfexsend.html +++ b/htdocs/macfexsend.html @@ -22,8 +22,8 @@ after a link failure, which your webbrowser cannot do.

To install fexsend:

  1. start a "Terminal":
    - go to Finder, press ⇧⌘U to open the Utility - Application folder and double-click Terminal.app with left + go to Finder, press ⇧⌘U to open the Utility + Application folder and double-click Terminal.app with left mouse button

  2. copy this code into the Terminal window: @@ -51,7 +51,7 @@ after a link failure, which your webbrowser cannot do. << if ($ENV{ID}) { my $url = "$ENV{PROTO}://$ENV{HTTP_HOST}/fup/" - . b64("from=$ENV{USER}&id=$ENV{ID}"); + . ::b64("from=$ENV{USER}&id=$ENV{ID}"); qq( When asked for "F*EX server URL" enter:

    diff --git a/htdocs/sup.html b/htdocs/sup.html index a8dc9b2..7d4ad85 100644 --- a/htdocs/sup.html +++ b/htdocs/sup.html @@ -20,9 +20,9 @@


    @@ -36,17 +36,17 @@ your file: - +


    -After "submit" you will see an upload progress bar +After "submit" you will see an upload progress bar (if you have javascript enabled and popups allowed).
    After the end a download URL will be shown.

    -You can also use the regular upload form +You can also use the regular upload form (with more features).

    NOTE: Only Firefox or Google Chrome can upload files > 2 GB!
    diff --git a/htdocs/tools.html b/htdocs/tools.html index 84e377c..af26d0d 100644 --- a/htdocs/tools.html +++ b/htdocs/tools.html @@ -1,4 +1,4 @@ - + F*EX tools

    @@ -15,11 +15,11 @@ See user config for your account data.

    UNIX:

    fexsend - client for sending files (with many + client for sending files (with many additional features)
    fexget - client for receiving files (with many + client for receiving files (with many additional features)
    sexsend, sexget @@ -48,7 +48,7 @@ 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.

    -Hint for UNIX users: +Hint for UNIX users:

      wget -qO- http://$HTTP_HOST$/xx.tar | tar xvf -
    installs fexsend, fexget and xx. @@ -56,7 +56,7 @@ installs fexsend, fexget and also installs the client programs for Stream EXchange and << - my $a = "/usecases/anonymous.html"; + my $a = "/usecases/anonymous.html"; print "anonymous usage"; diff --git a/htdocs/users.html b/htdocs/users.html new file mode 100644 index 0000000..a4a0b7e --- /dev/null +++ b/htdocs/users.html @@ -0,0 +1,74 @@ + +F*EX users types + +

    F*EX users types

    +This is a short overview over the different F*EX user types. + +
      +
    • regular (full) user

      +
        +
      • created by the fexmaster or self registration +
      • can send to anybody +
      • can change his settings (user configuration) +
      • can edit address book +
      • can use all F*EX clients +
      • can create sub users +
      • can create groups and group users +
      • can create one-time upload keys +
      +
    • sub user

      +
        +
      • created by a regular user (= main user) +
      • can send only to his main user +
      • cannot change his settings (user configuration) +
      • cannot create other users +
      +
    • group user

      +
        +
      • created by a regular user (= main user) +
      • can send only to his group +
      • cannot change his settings (user configuration) +
      • cannot create other users +
      +
    • restricted user

      +
        +
      • created by the fexmaster +
      • can send only to recipients defined by the fexmaster +
      • can change some of his settings (user configuration) +
      • can have upload or download restrictions +
      • cannot create other users +
      +
    • external user

      +
        +
      • is a restricted user created by self registration +
      +
    • anonymous user

      +
        +
      • created by the fexmaster +
      • authentificated by his IP +
      • cannot change his settings (user configuration) +
      • can send only to himself, but forward the download URL to anybody +
      • cannot create other users +
      +
    • public user

      +
        +
      • created by the fexmaster +
      • is only a recipient, anybody can send to him wihout registration +
      • cannot change his settings (user configuration) +
      • can be an extension of a regular user +
      +
    • captive user

      +
        +
      • created by the fexmaster +
      • is a super-restricted user +
      • cannot change his settings (user configuration) +
      • cannot create other users +
      +
    • demo user

      +
        +
      • sub type of the full user with limited quota and account life time +
      • suitable only for testing +
      +
    + + diff --git a/htdocs/version b/htdocs/version index 366b2e9..7b735e5 100644 --- a/htdocs/version +++ b/htdocs/version @@ -1 +1 @@ -fex-20160104 +fex-20160328 diff --git a/install b/install index 87dc2fe..7019bee 100755 --- a/install +++ b/install @@ -25,6 +25,9 @@ if (system("host $fex >/dev/null") != 0) { die "host $fex is not resolvable - check /etc/resolv.conf\n"; } +# $fexupdate = '/root/bin/fexupdate'; +# die "found $fexupdate\n" if -x $fexupdate; + $opt_p = 80; if (open $xinetd,$xinetd) { @@ -123,7 +126,7 @@ print "prerequisites checked, ok\n"; unless (getpwnam('fex')) { print "creating user fex\n"; - system 'groupadd -g 80 fex 2>/dev/null || groupadd fex'; + system 'groupadd --system fex 2>/dev/null || groupadd fex'; my @g = getgrnam('fex') or die "$0: cannot groupadd fex\n"; my $gid = $g[2]; if (getpwuid($gid)) { @@ -385,7 +388,7 @@ unless (-f $xinetd) { system qw'crontab -u fex fex.cron'; } - chownr('fex:root',$FEXHOME,"$FEXHOME/spool/."); + chownr('fex:root',$FEXHOME,"$FEXHOME/spool/.","$FEXHOME/htdocs/."); chmodr('go-r',"$FEXHOME/lib","$FEXHOME/cgi-bin","$FEXHOME/spool/."); print "\n"; @@ -403,6 +406,9 @@ unless (-f $xinetd) { "< $FEXHOME/doc/newfeatures\n"; } +chmod 0755,"$FEXHOME/htdocs/locale"; +chmod 0755,glob("$FEXHOME/locale/*/htdocs"); + if (@local_rdomains and not @local_rhosts) { print "\nWARNING:\n"; print "In $fph you have \@local_rdomains but not \@local_rhosts!\n"; diff --git a/lib/dop b/lib/dop index b41dbc1..dc92d70 100755 --- a/lib/dop +++ b/lib/dop @@ -223,15 +223,31 @@ sub http_output { } $dynamic = $htmldoc =~ s/$mark/$include/; } - # evaluate <> - while ($htmldoc =~ /<<(.+?)>>/s) { - local $pc = $1; - local $__ = ''; - tie *STDOUT => "Buffer",\$__; - $__ .= eval $pc; - untie *STDOUT; - $dynamic = $htmldoc =~ s/<<(.+?)>>/$__/s; - }; + # evaluate <> or <<>> + { + local $timeout = ''; + local $SIG{ALRM} = sub { $timeout = '

    TIMEOUT!

    ' }; + alarm(10); + while ($htmldoc =~ /<<(.+?>?)>>/s) { + local $pc = $1; + if ($pc =~ s/^<(.+)>$/$1/) { + # eval code without output substitution + eval('package DOP;' . $pc); + last if $timeout; + $dynamic = $htmldoc =~ s/<<<(.+?)>>>//s; + } else { + # eval code with output substitution + local $__ = ''; + tie *STDOUT => "Buffer",\$__; + $__ .= eval('package DOP;' . $pc); + untie *STDOUT; + last if $timeout; + $dynamic = $htmldoc =~ s/<<(.+?)>>/$__/s; + } + } + alarm(0); + $dynamic = $htmldoc =~ s/<<(.+?>?)>>/$timeout/sg if $timeout; + } # substitute $variable$ with value from environment (if present) while ($htmldoc =~ /\$([\w_]+)\$/g) { $var = $1; @@ -269,7 +285,6 @@ sub http_output { "Content-Length: $size", "Content-Range: $range", "Content-Type: $type", - '', ); } else { # streaming? @@ -279,7 +294,6 @@ sub http_output { 'Server: fexsrv', "Expires: 0", "Content-Type: $type", - '', ); } else { # Java (clients) needs Last-Modified header! @@ -298,10 +312,11 @@ sub http_output { "Content-Length: $size", "Content-Type: $type", ); - nvt_print("Set-Cookie: locale=$locale") if $use_cookies and $locale; - nvt_print(''); + # nvt_print("Set-Cookie: locale=$locale") if $use_cookies and $locale; } } + nvt_print($_) foreach(@extra_header); + nvt_print(''); if ($ENV{REQUEST_METHOD} eq 'GET') { if ($type eq 'text/html') { diff --git a/lib/fex.ph b/lib/fex.ph index 8c3ee12..c69943d 100644 --- a/lib/fex.ph +++ b/lib/fex.ph @@ -7,7 +7,7 @@ $hostname = 'MYHOSTNAME.MYDOMAIN'; ## to change it, you MUST call: fac -/ admin-email-address auth-id $admin = 'fex@'.$hostname; -## server admin email address shown on web page +## server admin email address shown on web page $ENV{SERVER_ADMIN} = $admin; ## restrict web administration to ip range(s) @@ -21,8 +21,8 @@ $notify_newrelease = $admin; ## optional: download-URLs sent in notification emails # @durl = qw( -# http://MYFEXSERVER/fop -# https://MYFEXSERVER/fop +# http://MYFEXSERVER/fop +# https://MYFEXSERVER/fop # http://MYPROXY/fex/fop # ); @@ -67,20 +67,20 @@ $mailmode = 'AUTO'; # $logdir = $spooldir; ## default quota in MB for recipient; 0 means "no quota" -$recipient_quota = 0; +$recipient_quota = 0; ## default quota in MB for sender; 0 means "no quota" -$sender_quota = 0; +$sender_quota = 0; ## expiration: keep files that number of days (default) -$keep = 5; +$keep = 5; ## expiration: keep files that number of days (maximum) $keep_max = 99; ## autodelete: delete files after download (automatically) ## YES ==> immediatelly (1 minute grace time) -## DELAY ==> after download at next fex_cleanup cronjob run +## DELAY ==> after download at next fex_cleanup cronjob run ## 2 ==> 2 days after download (can be any number!) ## NO ==> keep until expiration date (see $keep) $autodelete = 'YES'; @@ -91,7 +91,7 @@ $autodelete = 'YES'; $limited_download = 'YES'; ## allow RECIPIENT = SENDER -## in this case subsequentials downloads from any ip are possible until +## in this case subsequentials downloads from any ip are possible until ## regular file expiration (KEEP); exception for $limited_download $fex_yourself = 'YES'; @@ -100,8 +100,8 @@ $overwrite = 'YES'; ## allow user requests for forgotten auth-IDs (then send by email) $mail_authid = 'YES'; - -## optional: from which hosts and for which mail domains users may + +## optional: from which hosts and for which mail domains users may ## register themselves as full users (must set both!) # @local_hosts = qw(127.0.0.1 ::1 10.10.100.0-10.10.200.255 129.69.1.129); # @local_domains = qw(uni-stuttgart.de flupp.org); @@ -116,8 +116,8 @@ $mail_authid = 'YES'; ## optional: allow restricted user registration only by certain hosts # @registration_hosts = qw(129.69.0.0-129.69.255.255 176.9.84.26); -## optional: for certain remote domains do not use sender address in -## notfication email From, because their MTA will probably +## optional: for certain remote domains do not use sender address in +## notfication email From, because their MTA will probably ## reject it if From and To contain their domain name. ## Instead use $admin for From. See also $sender_from # @remote_domains = qw(flupp.org); @@ -147,7 +147,7 @@ $mail_authid = 'YES'; ## 0 means : full speed ## first match wins # @throttle = qw( -# framstag@*:0 microsoft.com:100 +# framstag@*:0 microsoft.com:100 # 127.0.0.1:0 202.0.0.0-211.255.255.255:1024 # [::1]:0 [fe00::0-fe00::ffff]:0 # ); diff --git a/lib/fex.pp b/lib/fex.pp index be911d2..8bfddbf 100644 --- a/lib/fex.pp +++ b/lib/fex.pp @@ -63,6 +63,17 @@ $mail_authid = 'yes'; $force_https = 0; $debug = 0; +# https://securityheaders.io/ +# https://scotthelme.co.uk/hardening-your-http-response-headers/ +# http://content-security-policy.com/ +@extra_header = ( + # "Content-Security-Policy: sandbox allow-forms allow-scripts", + "Content-Security-Policy: script-src 'self' 'unsafe-inline'", + "X-Frame-Options: SAMEORIGIN", + "X-XSS-Protection: 1; mode=block", + "X-Content-Type-Options: nosniff", +); + $FHS = -f '/etc/fex/fex.ph' and -d '/usr/share/fex/lib'; # Debian FHS if ($FHS) { @@ -277,12 +288,12 @@ sub http_header { nvt_print("Server: fexsrv"); nvt_print("Expires: 0"); nvt_print("Cache-Control: no-cache"); - # http://en.wikipedia.org/wiki/Clickjacking - nvt_print("X-Frame-Options: SAMEORIGIN"); if ($force_https) { # https://www.owasp.org/index.php/HTTP_Strict_Transport_Security + # https://scotthelme.co.uk/hsts-the-missing-link-in-tls/ nvt_print("Strict-Transport-Security: max-age=2851200; preload"); } + nvt_print($_) foreach(@extra_header); if ($use_cookies) { $akey = md5_hex("$from:$id") if $id and $from; if ($akey) { @@ -1551,8 +1562,8 @@ sub notify { or http_die("cannot start sendmail - $!"); } } - $comment .= "\n" if $comment; - if ($comment =~ s/^!(shortmail|\.)!\s*//i + $comment = "\n$comment\n" if $comment; + if ($comment =~ s/\n!(shortmail|\.)!\s*//i or (readlink("$to/\@NOTIFICATION")||'') =~ /short/i ) { $body = qqq(qq( @@ -1569,7 +1580,7 @@ sub notify { '' 'Questions? ==> F*EX admin: $admin' )); - $disclaimer .= "\n" . $::disclaimer if $::disclaimer; + $disclaimer .= "\n$::disclaimer\n" if $::disclaimer; $body = qqq(qq( '$comment' '$from has uploaded the file' diff --git a/lib/fup.pl b/lib/fup.pl index 24eccf7..e9e4c3b 100644 --- a/lib/fup.pl +++ b/lib/fup.pl @@ -20,7 +20,7 @@ EOD $info_2 = <

    -After submission you will see an upload progress bar +After submission you will see an upload progress bar (if you have javascript enabled and popups allowed).

    NOTE: Many web browsers cannot upload files > 2 GB!
    @@ -28,7 +28,7 @@ If your file is larger you have to use a special F*EX clie or Firefox or Google Chrome which have no size limit.
    You also need a
    F*EX client for resuming interrupted uploads. Your web browser cannot do this.

    -If you want to send more than one file, then put them in a zip or tar archive, +If you want to send more than one file, then put them in a zip or tar archive, e.g. with 7-Zip.

    See also the FAQ and diff --git a/locale/czech/htdocs/FAQ/FAQ.html b/locale/czech/htdocs/FAQ/FAQ.html new file mode 100644 index 0000000..a096645 --- /dev/null +++ b/locale/czech/htdocs/FAQ/FAQ.html @@ -0,0 +1,12 @@ + +F*EX FAQ + + +##

    +## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
    +## 
    + +<< require "./faq.pl" or print $! >> + + + diff --git a/locale/french/htdocs/FAQ/admin.html b/locale/french/htdocs/FAQ/admin.html index a3b32d4..167fa35 100644 --- a/locale/french/htdocs/FAQ/admin.html +++ b/locale/french/htdocs/FAQ/admin.html @@ -10,7 +10,7 @@ ## Ce document est périmé. Merci de consulter -la FAQ anglaise +la FAQ anglaise

    << require "./faq.pl" or print $! >> diff --git a/locale/french/htdocs/FAQ/all.html b/locale/french/htdocs/FAQ/all.html index a3b32d4..167fa35 100644 --- a/locale/french/htdocs/FAQ/all.html +++ b/locale/french/htdocs/FAQ/all.html @@ -10,7 +10,7 @@ ## Ce document est périmé. Merci de consulter -la FAQ anglaise +la FAQ anglaise

    << require "./faq.pl" or print $! >> diff --git a/locale/french/htdocs/FAQ/local.html b/locale/french/htdocs/FAQ/local.html index a3b32d4..167fa35 100644 --- a/locale/french/htdocs/FAQ/local.html +++ b/locale/french/htdocs/FAQ/local.html @@ -10,7 +10,7 @@ ## Ce document est périmé. Merci de consulter -la FAQ anglaise +la FAQ anglaise

    << require "./faq.pl" or print $! >> diff --git a/locale/french/htdocs/FAQ/meta.faq b/locale/french/htdocs/FAQ/meta.faq index 0a19172..c99ef60 100644 --- a/locale/french/htdocs/FAQ/meta.faq +++ b/locale/french/htdocs/FAQ/meta.faq @@ -26,7 +26,7 @@ Q: Perl n'est-il pas trop lent pour faire tout ça ? 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 pour installer F*EX ? +Q: De quoi ai-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 ? diff --git a/locale/french/htdocs/FAQ/meta.html b/locale/french/htdocs/FAQ/meta.html index a3b32d4..167fa35 100644 --- a/locale/french/htdocs/FAQ/meta.html +++ b/locale/french/htdocs/FAQ/meta.html @@ -10,7 +10,7 @@ ## Ce document est périmé. Merci de consulter -la FAQ anglaise +la FAQ anglaise

    << require "./faq.pl" or print $! >> diff --git a/locale/french/htdocs/FAQ/misc.html b/locale/french/htdocs/FAQ/misc.html index a3b32d4..167fa35 100644 --- a/locale/french/htdocs/FAQ/misc.html +++ b/locale/french/htdocs/FAQ/misc.html @@ -10,7 +10,7 @@ ## Ce document est périmé. Merci de consulter -la FAQ anglaise +la FAQ anglaise

    << require "./faq.pl" or print $! >> diff --git a/locale/french/htdocs/FAQ/user.html b/locale/french/htdocs/FAQ/user.html index a3b32d4..167fa35 100644 --- a/locale/french/htdocs/FAQ/user.html +++ b/locale/french/htdocs/FAQ/user.html @@ -10,7 +10,7 @@ ## Ce document est périmé. Merci de consulter -la FAQ anglaise +la FAQ anglaise

    << require "./faq.pl" or print $! >> diff --git a/locale/galician/htdocs/FAQ/FAQ.html b/locale/galician/htdocs/FAQ/FAQ.html new file mode 100644 index 0000000..a096645 --- /dev/null +++ b/locale/galician/htdocs/FAQ/FAQ.html @@ -0,0 +1,12 @@ + +F*EX FAQ + + +##

    +## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
    +## 
    + +<< require "./faq.pl" or print $! >> + + + diff --git a/locale/german/htdocs/FAQ/FAQ.html b/locale/german/htdocs/FAQ/FAQ.html new file mode 100644 index 0000000..a096645 --- /dev/null +++ b/locale/german/htdocs/FAQ/FAQ.html @@ -0,0 +1,12 @@ + +F*EX FAQ + + +##
    +## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
    +## 
    + +<< require "./faq.pl" or print $! >> + + + diff --git a/locale/italian/htdocs/FAQ/FAQ.html b/locale/italian/htdocs/FAQ/FAQ.html new file mode 100644 index 0000000..a096645 --- /dev/null +++ b/locale/italian/htdocs/FAQ/FAQ.html @@ -0,0 +1,12 @@ + +F*EX FAQ + + +##
    +## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
    +## 
    + +<< require "./faq.pl" or print $! >> + + + diff --git a/locale/spanish/htdocs/FAQ/FAQ.html b/locale/spanish/htdocs/FAQ/FAQ.html new file mode 100644 index 0000000..a096645 --- /dev/null +++ b/locale/spanish/htdocs/FAQ/FAQ.html @@ -0,0 +1,12 @@ + +F*EX FAQ + + +##
    +## << while (($v,$vv) = each %ENV) { print "$v = $vv\n" } >>
    +## 
    + +<< require "./faq.pl" or print $! >> + + + diff --git a/locale/translate b/locale/translate index 2fdd709..8d581ec 100755 --- a/locale/translate +++ b/locale/translate @@ -34,6 +34,8 @@ use File::Copy; $> = $FEX[2]; $) = $FEX[3]; +umask 022; + $FEXHOME = $ENV{FEXHOME} || $FEX[7]; # require "$FEXHOME/lib/fex.pp" @@ -101,43 +103,47 @@ foreach $file (@trfiles) { print "$ft written\n"; } -foreach $file (@cpfiles) { - my $fs = "locale/$lang/$file"; - if (-e $fs) { - my $fd = "$FEXHOME/$fs"; - mkdirp(dirname($fd)); - if (-f $fs) { - $fd .= '_new' if -e $fd; - if (copy($fs,$fd)) { - chmod((stat $fs)[2],$fd); - print "$fd written\n"; - } - } else { - if (-f $fd) { - my $fds = $fd.'_save'; - my $fdn = $fd.'_new'; - system "rm -rf $fds $fdn"; - rename $fd,$fds; - system "tar cf - $fs | (cd $FEXHOME; tar xf -)"; - rename $fd,$fdn; - rename $fds,$fd; - print "$fdn written\n"; +if ($FEXHOME !~ /fexdev/) { + + foreach $file (@cpfiles) { + my $fs = "locale/$lang/$file"; + if (-e $fs) { + my $fd = "$FEXHOME/$fs"; + mkdirp(dirname($fd)); + if (-f $fs) { + $fd .= '_new' if -e $fd; + if (copy($fs,$fd)) { + chmod((stat $fs)[2],$fd); + print "$fd written\n"; + } } else { - system "tar cf - $fs | (cd $FEXHOME; tar xf -)"; - print "$fd written\n"; + if (-f $fd) { + my $fds = $fd.'_save'; + my $fdn = $fd.'_new'; + system "rm -rf $fds $fdn"; + rename $fd,$fds; + system "tar cf - $fs | (cd $FEXHOME; tar xf -)"; + rename $fd,$fdn; + rename $fds,$fd; + print "$fdn written\n"; + } else { + system "tar cf - $fs | (cd $FEXHOME; tar xf -)"; + print "$fd written\n"; + } } } } -} -foreach $fs (qw(fex.ph dop)) { - $fd = "$FEXHOME/locale/$lang/lib/$fs"; - symlink "../../../lib/$fs",$fd and print "$fd linked\n"; -} + foreach $fs (qw(fex.ph dop)) { + $fd = "$FEXHOME/locale/$lang/lib/$fs"; + symlink "../../../lib/$fs",$fd and print "$fd linked\n"; + } + + unless (-f "$FEXHOME/locale/$lang/htdocs/FAQ/meta.faq") { + unlink "$FEXHOME/locale/$lang/htdocs/FAQ/FAQ.html"; + rmdir "$FEXHOME/locale/$lang/htdocs/FAQ"; + } -unless (-f "$FEXHOME/locale/$lang/htdocs/FAQ/meta.faq") { - unlink "$FEXHOME/locale/$lang/htdocs/FAQ/FAQ.html"; - rmdir "$FEXHOME/locale/$lang/htdocs/FAQ"; } make_lf($lang); diff --git a/locale/translations b/locale/translations index 0aed2d0..25f1044 100644 --- a/locale/translations +++ b/locale/translations @@ -507,7 +507,7 @@ und eine Informations-E-Mail wurde an diese Adresse verschickt ond a Was-macha-musch-E-Mail isch do no verschickt worda y un email de información ha sido enviado a esta dirección e un correo informativo acaba de se enviar a este enderezo -e una e-mail di informazioni è stata spedita a questo indirizzo +e una e-mail di informazioni è stata spedita a questo indirizzo a informační e-mail byl odeslán na tuto adresu et un message d'information a été envoyé à cette adresse @@ -1413,7 +1413,7 @@ ajouter à la liste des destinataires check recipient(s) and continue Empfänger überprüfen und fortsetzen -Empfänger ieberpriafe ond weitermache +Empfängr ieberpriafa ond weitermacha compruebe el/los destinatario(s) y continúe comprobe o/os destinatario(s) e continúe controlla i/il destinatari(o) e continua @@ -2010,7 +2010,7 @@ Ihre Domain $exd ist nicht zugelassen für Registrierung Dei Domain $exd ghod ned for d'Regischtrierong Su dominio $exd no está permitido a registrar Your domain $exd is not allowed for registration -Il tuo dominio $exd non è permesso per la registrazione +Il tuo dominio $exd non è permesso per la registrazione Registrace z domény $exd není povolena Votre domaine $exd n'est pas autorisé à l'enregistrement @@ -2730,7 +2730,7 @@ Ihr F*EX Account ist seit $expire Tagen inaktiv Du hosch dei F*EX Konto seit $expire Tag nemme bnutzt Su cuenta de F*EX ha estado inactivo $expire dias A súa conta F*EX estivo inactiva durante $expire día -Il tuo account F*EX è stato inattivo per $expire giorni +Il tuo account F*EX è stato inattivo per $expire giorni Váš F*EX účet byl neaktivní $expire dnů Votre compte F*EX a été inactif pendant $expire days