#!/usr/bin/perl # The LearningOnline Network # # $Id: checkforupdates.pl,v 1.3 2013/10/02 23:47:17 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # ################################################# =pod =head1 NAME checkforupdates.pl =head1 SYNOPSIS checkforupdates.pl gathers version numbers and computes checksums for LON-CAPA modules, scripts, and a couple of configuration files, and compares them with those expected for the version of LON-CAPA installed on the server. =head1 DESCRIPTION If there are discrepancies in checksums between the installed modules and those expected, or if there are problems performing the update check, or if a newer stable release of LON-CAPA is available, an e-mail will be sent to the e-mail address configured to receive these types of alert. Run as www. =cut ################################################# use strict; use lib '/home/httpd/lib/perl/'; use Apache::lonnet(); use Apache::lonlocal(); use LONCAPA::Configuration; use LONCAPA::Checksumming; use Apache::loncommon(); my $perlvar= LONCAPA::Configuration::read_conf('loncapa.conf'); my ($londaemons,$lonlib,$lonincludes,$lontabdir,$lonhost,$defdom,$origmail, $docroot); if (ref($perlvar) eq 'HASH') { $londaemons = $perlvar->{'lonDaemons'}; $lonlib = $perlvar->{'lonLib'}; $lonincludes = $perlvar->{'lonIncludes'}; $lontabdir = $perlvar->{'lonTabDir'}; $lonhost = $perlvar->{'lonHostID'}; $defdom = $perlvar->{'lonDefDomain'}; $origmail = $perlvar->{'lonAdmEMail'}; $docroot = $perlvar->{'lonDocRoot'}; } undef($perlvar); &Apache::lonlocal::get_language_handle(); my ($distro,$send,$message); my $loncaparev = &Apache::lonnet::get_server_loncaparev($defdom); my ($version,$timestamp) = split(/\-/,$loncaparev); if ($loncaparev =~ /CVS_HEAD/) { $message = &Apache::lonlocal::mt('Code checking unavailable for LON-CAPA CVS HEAD')."\n"; } else { # Get Linux distro if (open(PIPE, "$londaemons/distprobe |")) { $distro = ; close(PIPE); } if ($distro) { my ($serversums,$serverversions) = &LONCAPA::Checksumming::get_checksums($distro,$londaemons,$lonlib, $lonincludes,$lontabdir); if ((ref($serversums) eq 'HASH') && (ref($serverversions) eq 'HASH')) { if (keys(%{$serversums}) > 0) { my ($result,$numchg) = &LONCAPA::Checksumming::compare_checksums('mail',$lonhost, $version, $serversums, $serverversions); if ($numchg) { $send = 1; } $message = $result; } else { $message = &Apache::lonlocal::mt('No comparison attempted - failed to retrieve checksums for installed files.'); } } else { $message = &Apache::lonlocal::mt('No comparison attempted - failed to retrieve checksums for installed files.'); } } else { $message = &Apache::lonlocal::mt('No comparison attempted - unable to determine Linux distribution.'); } my ($update_toprod,$update_totest); my ($smajor,$sminor,$sdecimal,$smodifier) = ($version =~ /^(\d+)\.(\d+)\.(\d+)\.?(\w*)$/); my ($production,$proddate,$testing,$testdate) = &latest_release(); my ($pmajor,$pminor,$pdecimal,$pmodifier) = ($production =~ /^(\d+)\.(\d+)\.(\d+)\.?(\w*)$/); if ($smodifier =~ /^RC(\d+)$/) { my $scand = $1; my ($tmajor,$tminor,$tdecimal,$tmodifier) = ($testing =~ /^(\d+)\.(\d+)\.(\d+)\.?(\w*)$/); my $tcand; if ($tmodifier =~ /^RC(\d+)$/) { $tcand = $1; } if (($smajor < $tmajor ) || (($smajor == $tmajor) && ($sminor < $tminor)) || (($smajor == $tmajor) && ($sminor == $tminor) && ($sdecimal < $tdecimal)) || ((($smajor == $tmajor) && ($sminor == $tminor) && ($sdecimal == $tdecimal) && (($scand && $tcand) && ($scand < $tcand))))) { $update_totest = $testing; } } if (($smajor < $pmajor ) || (($smajor == $pmajor) && ($sminor < $pminor)) || (($smajor == $pmajor) && ($sminor == $pminor) && ($sdecimal < $pdecimal))) { $update_toprod = $production; } if ($update_totest) { $message .= "\n\n". &Apache::lonlocal::mt('A newer testing version of LON-CAPA: [_1]'. ' is available from: [_2]', $testing.'-'.$testdate, "\n http://install.loncapa.org/\n"); } if ($update_toprod) { $message .= "\n\n". &Apache::lonlocal::mt('A newer version of LON-CAPA: [_1]'. ' is available from: [_2]', $production.'-'.$proddate, "\n http://install.loncapa.org/\n"); } } if ($docroot ne '') { if (open(my $fh,">$docroot/lon-status/checkLCupdates.txt")) { print $fh &Apache::lonlocal::mt('Update check result -- [_1]', &Apache::lonlocal::locallocaltime(time)). "\n\n". $message; close($fh); system("chown www:www $docroot/lon-status/checkLCupdates.txt"); chmod(0600,"$docroot/lon-status/checkLCupdates.txt"); if ($send) { # Determine who receives the e-mail my $emailto = &Apache::loncommon::build_recipient_list(undef,'updatesmail', $defdom,$origmail); if ($emailto) { my $subj = "LON-CAPA module check -- $lonhost"; if (-e "$docroot/lon-status/checkLCupdates.txt") { system(qq{mail -s '$subj' "$emailto" < $docroot/lon-status/checkLCupdates.txt}); } } } } } exit; sub latest_release { my ($production,$proddate,$testing,$testdate); if (-e "/tmp/latestLCrelease.txt") { unlink("/tmp/latestLCrelease.txt"); } my $rtncode = system("wget -O /tmp/latestLCrelease.txt ". "http://install.loncapa.org/versions/latest.txt ". "> /dev/null 2>&1"); if (!$rtncode) { if (open(my $fh,"; close($fh); foreach my $line (@info) { chomp($line); if ($line =~ /^\QLATEST-IS: \E([\w\-.]+):\d+$/) { $production = $1; } elsif ($line =~ /^\QLASTRELPROD: \E(\d+)$/) { $proddate = $1; } elsif ($line =~ /^\QLATEST-TESTING-IS: \E([\w\-.]+):\d+$/) { $testing = $1; } elsif ($line =~ /^\QLASTRELTEST: \E(\d+)$/) { $testdate = $1; } } } } return ($production,$proddate,$testing,$testdate); }