#
# This code is distributed under the terms of the GPL
#
-# (c) 2006 marco.s
+# (c) 2006-2008 marco.s - http://update-accelerator.advproxy.net
#
-# $Id: download,v 1.0 2006/08/30 00:00:00 marco.s Exp $
+# $Id: download,v 2.0 2008/04/06 00:00:00 marco.s Exp $
#
use strict;
+use HTTP::Date;
+my $swroot='/var/ipfire';
+my $apphome="$swroot/updatexlrator";
my $logfile="/var/log/updatexlrator/download.log";
-my $debug = 1;
-my $updcachedir="/var/updatecache";
-my $updfile='';
-my @metadata=();
+my $logging=0;
+my $repository='/var/updatecache';
+my $login='';
+my $dlrate='';
+my $uuid='';
+my $wget="$apphome/bin/wget";
+my $useragent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
+my %xlratorsettings=();
+my %proxysettings=();
+my @http_header=();
+my $remote_mtime=0;
+my $updatefile='';
+my $unique=0;
+my $mirror=1;
my $sfOk="1";
-my $dsturl=@ARGV[0]; if ($dsturl eq '') { exit; }
+my $vendorid = @ARGV[0]; if ($vendorid eq '') { exit; }
+my $sourceurl = @ARGV[1]; if ($sourceurl eq '') { exit; }
+my $cfmirror = @ARGV[2]; if ($cfmirror eq '') { exit; }
-$dsturl =~ s@\%2f@/@ig;
-$updfile = substr($dsturl,rindex($dsturl,"/")+1);
+umask(0002);
-# ---------------------------------------------------------------
-# Retrieve file
-# ---------------------------------------------------------------
+$sourceurl =~ s@\%2f@/@ig;
+$sourceurl =~ s@\%7e@~@ig;
+$updatefile = substr($sourceurl,rindex($sourceurl,"/")+1);
+$updatefile =~ s@\%20@ @ig;
+$vendorid =~ tr/A-Z/a-z/;
-if ($debug)
+unless (-d "$repository/download/$vendorid")
{
- &writelog("Retrieving file for local cache: $updfile");
- `/usr/bin/wget -nc -nd -nv -P $updcachedir/download $dsturl >>$logfile 2>&1`;
-} else
+ system("mkdir $repository/download/$vendorid");
+ system("$apphome/bin/setperms download/$vendorid");
+}
+
+exit if (-e "$repository/download/$vendorid/$updatefile");
+
+system("touch $repository/download/$vendorid/$updatefile");
+
+if ($cfmirror)
+{
+ $uuid = `echo $updatefile | md5sum`;
+} else {
+ $uuid = `echo $sourceurl | md5sum`;
+}
+
+$uuid =~ s/[^0-9a-f]//g;
+$uuid =~ s/([a-f\d]{8})([a-f\d]{4})([a-f\d]{4})([a-f\d]{4})([a-f\d]{12})/$1-$2-$3-$4-$5/;
+
+if (-e "$swroot/updatexlrator/settings")
+{
+ &readhash("$swroot/updatexlrator/settings", \%xlratorsettings);
+ if ($xlratorsettings{'ENABLE_LOG'} eq 'on') { $logging=1; };
+ if ($xlratorsettings{'MAX_DOWNLOAD_RATE'} ne '') { $dlrate = "--limit-rate=" . int($xlratorsettings{'MAX_DOWNLOAD_RATE'} / 8) . "k" };
+}
+
+if (-e "$swroot/proxy/settings") { &readhash("$swroot/proxy/settings", \%proxysettings); }
+
+if (-e "$swroot/proxy/advanced/settings")
+{
+ %proxysettings=();
+ &readhash("$swroot/proxy/advanced/settings", \%proxysettings);
+}
+
+if (($proxysettings{'UPSTREAM_PROXY'}) && ($proxysettings{'UPSTREAM_USER'}))
{
- `/usr/bin/wget -nc -nd -nv -P $updcachedir/download $dsturl 2>&1`;
+ $login = "--proxy-user=\"$proxysettings{'UPSTREAM_USER'}\"";
+ if ($proxysettings{'UPSTREAM_PASSWORD'})
+ {
+ $login .= " --proxy-password=\"$proxysettings{'UPSTREAM_PASSWORD'}\"";
+ }
}
-if ($debug) { &writelog("Moving file into the cache directory -> \"$updcachedir/$updfile\""); }
-system("mv $updcachedir/download/$updfile $updcachedir");
+if ($xlratorsettings{'MAX_DOWNLOAD_RATE'} eq '')
+{
+ &writelog("Retrieving file for local cache: $updatefile");
+} else {
+ &writelog("Retrieving file for local cache at max. " . $xlratorsettings{'MAX_DOWNLOAD_RATE'} . " kBit/s: $updatefile");
+}
-# ---------------------------------------------------------------
-# Write metadata
-# ---------------------------------------------------------------
+$ENV{'http_proxy'} = $proxysettings{'UPSTREAM_PROXY'};
+@http_header = `$wget $login --user-agent="$useragent" --spider -S $sourceurl 2>&1`;
+$ENV{'http_proxy'} = '';
-if ($debug) { &writelog("Writing metadata \"$updcachedir/metadata/$updfile\""); }
+foreach (@http_header)
+{
+ chomp;
+ if (/^\s*Content-Length:\s/) { s/[^0-9]//g; &writelog("Remote file size: $_ bytes"); }
+ if (/^\s*Last-Modified:\s/) { s/^\s*Last-Modified:\s//; $remote_mtime = HTTP::Date::str2time($_); &writelog("Remote file date: $_"); }
+}
-open(FILE,"$updcachedir/metadata/$updfile");
-@metadata = <FILE>;
-close(FILE);
-chomp @metadata;
-$metadata[2]="$sfOk";
-$metadata[3]=time;
-open(FILE,">$updcachedir/metadata/$updfile");
-foreach (@metadata) { print FILE "$_\n"; }
-print FILE time."\n";
-close(FILE);
+$ENV{'http_proxy'} = $proxysettings{'UPSTREAM_PROXY'};
+unlink "$repository/download/$vendorid/$updatefile";
+$_ = system("$wget $login $dlrate --user-agent=\"$useragent\" -q -nc -P $repository/download/$vendorid $sourceurl");
+$ENV{'http_proxy'} = '';
-# ===============================================================
+if ($_ == 0)
+{
+ &writelog("Download finished with result code: OK");
+
+ unless (-d "$repository/$vendorid")
+ {
+ system("mkdir $repository/$vendorid");
+ system("$apphome/bin/setperms $vendorid");
+ }
+
+ unless (-d "$repository/$vendorid/$uuid")
+ {
+ system("mkdir $repository/$vendorid/$uuid");
+ system("$apphome/bin/setperms $vendorid/$uuid");
+ }
+
+ &writelog("Moving file to the cache directory: $vendorid/$uuid");
+ $updatefile =~ s@ @\\ @ig;
+ system("mv $repository/download/$vendorid/$updatefile $repository/$vendorid/$uuid");
+ # Workaround for IPCop's mv bug:
+ utime time,$remote_mtime,"$repository/$vendorid/$uuid/$updatefile";
+ $updatefile =~ s@\\ @ @ig;
+
+ &setcachestatus("$repository/$vendorid/$uuid/source.url",$sourceurl);
+ &setcachestatus("$repository/$vendorid/$uuid/status",$sfOk);
+ &setcachestatus("$repository/$vendorid/$uuid/checkup.log",time);
+ &setcachestatus("$repository/$vendorid/$uuid/access.log",time);
+
+ system("$apphome/bin/setperms $vendorid/$uuid/*");
+
+} else {
+ &writelog("Download finished with result code: ERROR");
+ if (-e "$repository/download/$vendorid/$updatefile") { unlink ("$repository/download/$vendorid/$updatefile"); }
+}
+
+
+# -------------------------------------------------------------------
+
+sub readhash
+{
+ my $filename = $_[0];
+ my $hash = $_[1];
+ my ($var, $val);
+
+ if (-e $filename)
+ {
+ open(FILE, $filename) or die "Unable to read file $filename";
+ while (<FILE>)
+ {
+ chop;
+ ($var, $val) = split /=/, $_, 2;
+ if ($var)
+ {
+ $val =~ s/^\'//g;
+ $val =~ s/\'$//g;
+
+ # Untaint variables read from hash
+ $var =~ /([A-Za-z0-9_-]*)/; $var = $1;
+ $val =~ /([\w\W]*)/; $val = $1;
+ $hash->{$var} = $val;
+ }
+ }
+ close FILE;
+ }
+}
+
+# -------------------------------------------------------------------
sub writelog
{
- open (LOGFILE,">>$logfile");
- my @now = localtime(time);
- printf LOGFILE "%02d:%02d:%02d %s\n",$now[2],$now[1],$now[0],$_[0];
- close LOGFILE;
+ if ($logging)
+ {
+ open (LOGFILE,">>$logfile");
+ my @now = localtime(time);
+ printf LOGFILE "%04d-%02d-%02d %02d:%02d:%02d [%d] %s\n",$now[5]+1900,$now[4]+1,$now[3],$now[2],$now[1],$now[0],$$,$_[0];
+ close LOGFILE;
+ }
+}
+
+# -------------------------------------------------------------------
+
+sub setcachestatus
+{
+ open (FILE,">$_[0]");
+ print FILE "$_[1]\n";
+ close FILE;
}
-# ===============================================================
+# -------------------------------------------------------------------