Files
bpfire/config/updxlrator/updxlrator
ms 46c01c0912 Updatexlrator (not tested yet)
git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@421 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8
2007-02-15 21:26:14 +00:00

287 lines
6.3 KiB
Perl

#!/usr/bin/perl
#
# This code is distributed under the terms of the GPL
#
# (c) 2006 marco.s
#
# $Id: updxlrator,v 1.0 2006/10/03 00:00:00 marco.s Exp $
#
use strict;
use IO::Socket;
$|=1;
my $swroot="/var/ipfire";
my $updcachedir="/srv/web/ipfire/html/updatecache";
my %netsettings=();
my %xlratorsettings=();
my $http_port="81";
my $logfile="/var/log/updatexlrator/cache.log";
my $logging=0;
my $passive_mode=0;
my $maxusage=0;
my $nice='';
my @tmp=();
my $now='';
my $request='';
my $from_local_cache=0;
my $dsturl='';
my $hostaddr='';
my $username='';
my $method='';
my @metadata=();
my $sfNoSource = "0";
my $sfOk = "1";
my $sfOutdated = "2";
unless (-d "$updcachedir/metadata")
{
unless (-d "$updcachedir") { mkdir "$updcachedir"; }
mkdir "$updcachedir/metadata";
system("chown nobody.squid $updcachedir");
system("chmod 775 $updcachedir");
system("chown nobody.squid $updcachedir/metadata");
system("chmod 775 $updcachedir/metadata");
}
readhash("${swroot}/ethernet/settings", \%netsettings);
if (-e "$swroot/updatexlrator/settings")
{
&readhash("$swroot/updatexlrator/settings", \%xlratorsettings);
if ($xlratorsettings{'ENABLE_LOG'} eq 'on') { $logging=1; };
if ($xlratorsettings{'PASSIVE_MODE'} eq 'on') { $passive_mode=1; };
$maxusage=$xlratorsettings{'MAX_DISK_USAGE'};
if ($xlratorsettings{'LOW_DOWNLOAD_PRIORITY'} eq 'on') { $nice='/usr/bin/nice --adjustment=15 '; };
}
if (!$maxusage) { $maxusage=75; };
while (<>) {
$request=$_;
$from_local_cache=0;
@tmp=split(/ /,$request);
chomp(@tmp);
$dsturl =$tmp[0];
$hostaddr=$tmp[1]; while ($hostaddr =~ /.*\/$/) { chop $hostaddr; }
$username=$tmp[2]; if ($username eq '') { $username='-'; };
$method =$tmp[3];
if (($method eq 'GET') || ($method eq 'HEAD'))
{
# -----------------------------------------------------------
# Section: Windows Update / Windows Downloads
# -----------------------------------------------------------
if (
(($dsturl =~ m@^http://[^/]*\.microsoft\.com/.*\.(exe|psf|msi)$@i) ||
($dsturl =~ m@^http://[^/]*\.windowsupdate\.com/.*\.(exe|psf|cab)$@i))
&& ($dsturl !~ m@^http://[^/]*\.microsoft\.com/.*(/autoupd|selfupdate/).*\.cab@i)
&& ($dsturl !~ m@\&@)
)
{
$from_local_cache = &cache_access($dsturl,$hostaddr,$username,"Microsoft");
}
# -----------------------------------------------------------
# Section: Adobe Downloads
# -----------------------------------------------------------
if ($dsturl =~ m@^http://(ar)?download\.adobe\.com/.*\.(exe|bin|dmg|idx|gz)$@i)
{
$from_local_cache = &cache_access($dsturl,$hostaddr,$username,"Adobe");
}
# -----------------------------------------------------------
# Section: Symantec Downloads
# -----------------------------------------------------------
if ($dsturl =~ m@^[f|h]t?tp://[^/]*\.symantec(liveupdate)?\.com/.*\.(exe|zip|xdb)$@i)
{
$from_local_cache = &cache_access($dsturl,$hostaddr,$username,"Symantec");
}
# -----------------------------------------------------------
}
if ($from_local_cache) { $request="http://$netsettings{'GREEN_ADDRESS'}:$http_port/updatecache/".substr($dsturl,rindex($dsturl,"/")+1)." $hostaddr $username $method\n"; }
print $request;
}
# -------------------------------------------------------------------
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");
print LOGFILE time." $_[0] $_[1] $_[2] $_[3] $_[4]\n";
close(LOGFILE);
}
# -------------------------------------------------------------------
sub diskfree
{
open(DF,"/bin/df --block-size=1 $_[0]|");
while(<DF>)
{
unless ($_ =~ m/^Filesystem/ )
{
my ($device,$size,$used,$free,$percent,$mount) = split;
if ($free =~ m/^(\d+)$/)
{
close DF;
return $free;
}
}
}
close DF;
}
# -------------------------------------------------------------------
sub diskusage
{
open(DF,"/bin/df $_[0]|");
while(<DF>)
{
unless ($_ =~ m/^Filesystem/ )
{
my ($device,$size,$used,$free,$percent,$mount) = split;
if ($percent =~ m/^(\d+)%$/)
{
close DF;
$percent =~ s/%$//;
return $percent;
}
}
}
close DF;
}
# -------------------------------------------------------------------
sub getdownloadsize
{
my $remote=0;
my @response=();
my $contentlength=0;
my $url = $_[0];
$url =~ s@^(.*)://([^/]*)@@;
my $proto = $1;
my $fqhn = $2;
if ((-e "$swroot/red/active") && ($proto eq 'http'))
{
$remote = IO::Socket::INET->new(
PeerHost => $fqhn,
PeerPort => 'http(80)',
Timeout => 1
);
}
if ($remote)
{
print $remote "HEAD $url HTTP/1.0\n";
print $remote "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\n";
print $remote "Host: $fqhn\n";
print $remote "Accept: */*\n\n";
while (<$remote>) { push(@response,$_); }
close $remote;
if ($response[0] =~ /^HTTP\/\d+\.\d+\s\d+\sOK\s*$/)
{
foreach (@response)
{
if (/^Content-Length: /i)
{
s/^Content-Length: //i;
$contentlength=$_;
}
}
}
}
return $contentlength;
}
# -------------------------------------------------------------------
sub cache_access
{
my $updsource="UPDCACHE";
my $updfile='';
my $do_redirect=0;
$_[0] =~ s@\%2f@/@ig;
$updfile = substr($_[0],rindex($_[0],"/")+1);
if (!-e "$updcachedir/metadata/$updfile")
{
open(FILE,">$updcachedir/metadata/$updfile");
print FILE "$_[0]\n$_[3]\n$sfOutdated\n0\n";
close(FILE);
}
if (-e "$updcachedir/$updfile")
{
open(FILE,">>$updcachedir/metadata/$updfile");
print FILE time."\n";
close(FILE);
$do_redirect=1;
}
else
{
$updsource="DLSOURCE";
if ((!$passive_mode) && (&diskusage($updcachedir) <= $maxusage) && (&getdownloadsize <= &diskfree($updcachedir)) && (!-e "$updcachedir/download/$updfile"))
{
system("$nice/var/ipfire/updatexlrator/bin/download $_[0] &");
}
}
if ($logging) { &writelog($_[1],$_[2],$_[3],$updsource,$_[0]); }
return $do_redirect;
}
# -------------------------------------------------------------------