#!/usr/bin/perl # # This code is distributed under the terms of the GPL # # (c) 2006 marco.s # # $Id: checkup,v 1.0 2006/08/30 00:00:00 marco.s Exp $ # use strict; use IO::Socket; use HTTP::Date; my $swroot='/var/ipfire'; my $scriptpath=substr($0,0,rindex($0,"/")); my $apphome="/var/ipfire/updatexlrator"; my $logfile="/var/log/updatexlrator/checkup.log"; my $debug=(-e "$apphome/debug"); my $repository='/srv/web/ipfire/html/updatecache'; my %xlratorsettings=(); my $download=0; my $updatefile=''; my $sourceurl=''; my $remote_size=0; my $local_size=0; my $remote_mtime=0; my $local_mtime=0; my @updatelist=(); my @metadata=(); @updatelist = <$repository/*>; my $sfUnknown = "0"; my $sfOk = "1"; my $sfOutdated = "2"; if (-e "$swroot/updatexlrator/settings") { &readhash("$swroot/updatexlrator/settings", \%xlratorsettings); if ($xlratorsettings{'FULL_AUTOSYNC'} eq 'on') { $download=1; }; } foreach (@updatelist) { if (!-d $_) { $updatefile = substr($_,rindex($_,"/")+1); if (-e "$repository/metadata/$updatefile") { open (FILE,"$repository/metadata/$updatefile"); @metadata = ; close FILE; chomp(@metadata); $sourceurl = $metadata[0]; $remote_size = &getdownloadsize($sourceurl); $local_size = (-s "$repository/$updatefile"); $remote_mtime = &getlastmod($sourceurl); $local_mtime = &getmtime("$repository/$updatefile"); if ($remote_mtime eq 0) { $metadata[2] = $sfUnknown; if ($debug) { &writelog("$updatefile - WARNING: Source not found"); } print "$updatefile - WARNING: Source not found\n"; } elsif (($local_mtime eq $remote_mtime) && ($local_size == $remote_size)) { $metadata[2] = $sfOk; $metadata[3] = time; if ($debug) { &writelog("$updatefile"); } print "$updatefile\n"; } else { $metadata[2] = $sfOutdated; $metadata[3] = time; if ($debug) { &writelog("$updatefile - WARNING: Out of date"); } print "$updatefile - WARNING: Out of date\n"; if ($download) { if ($debug) { 1 while $remote_size =~ s/^(-?\d+)(\d{3})/$1.$2/; print "Please wait, retrieving file ($remote_size Byte) from source ..."; `$scriptpath/../bin/wget -nd -nv -O $repository/$updatefile $sourceurl >>$logfile 2>&1`; print "\n"; } else { `$scriptpath/../bin/wget -nd -nv -O $repository/$updatefile $sourceurl 2>&1`; } $local_mtime = &getmtime("$repository/$updatefile"); if ($local_mtime eq $remote_mtime) { $metadata[2] = $sfOk; } } } open (FILE,">$repository/metadata/$updatefile"); foreach (@metadata) { print FILE "$_\n"; } close FILE; } } } # ------------------------------------------------------------------- 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 () { 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 getmtime { my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($_[0]); return $mtime; } # ------------------------------------------------------------------- sub getlastmod { my $remote=0; my @response=(); my $lastmoddate=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 (/^Last-Modified: /i) { s/^Last-Modified: //i; $lastmoddate=HTTP::Date::str2time($_); } } } } return $lastmoddate; } # ------------------------------------------------------------------- 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=int($_); } } } } return $contentlength; } # ------------------------------------------------------------------- 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; } # -------------------------------------------------------------------