Annotation of loncom/configuration/Checksumming.pm, revision 1.1
1.1 ! raeburn 1: # The LearningOnline Network with CAPA
! 2: # Checksum installed LON-CAPA modules and some configuration files
! 3: #
! 4: # $Id: Checksumming.pm,v 1.1 2013/01/29 21:43:41 raeburn Exp $
! 5: #
! 6: # The LearningOnline Network with CAPA
! 7: #
! 8: # Copyright Michigan State University Board of Trustees
! 9: #
! 10: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
! 11: #
! 12: # LON-CAPA is free software; you can redistribute it and/or modify
! 13: # it under the terms of the GNU General Public License as published by
! 14: # the Free Software Foundation; either version 2 of the License, or
! 15: # (at your option) any later version.
! 16: #
! 17: # LON-CAPA is distributed in the hope that it will be useful,
! 18: # but WITHOUT ANY WARRANTY; without even the implied warranty of
! 19: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 20: # GNU General Public License for more details.
! 21: #
! 22: # You should have received a copy of the GNU General Public License
! 23: # along with LON-CAPA; if not, write to the Free Software
! 24: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
! 25: #
! 26: # /home/httpd/html/adm/gpl.txt
! 27: #
! 28: # http://www.lon-capa.org/
! 29: #
! 30:
! 31: package LONCAPA::Checksumming;
! 32:
! 33: use strict;
! 34: use lib '/home/httpd/lib/perl/';
! 35: use Apache::lonlocal();
! 36: use Apache::loncommon();
! 37:
! 38: sub get_checksums {
! 39: my ($distro,$londaemons,$lonlib,$lonincludes,$lontabdir) = @_;
! 40: my $output;
! 41: my (%versions,%chksums);
! 42: my $dirh;
! 43: my $revtag = '$Id:';
! 44: my @paths;
! 45: if ($londaemons) {
! 46: push(@paths,($londaemons.'/*',
! 47: $londaemons.'/debug/*.pl'));
! 48: }
! 49: if ($lonlib) {
! 50: push(@paths,($lonlib.'/perl/Apache/*.pm',
! 51: $lonlib.'/perl/Apache/localize/*.pm',
! 52: $lonlib.'/perl/LONCAPA/*.pm',
! 53: $lonlib.'/perl/AlgParser.pm',
! 54: $lonlib.'/perl/LONCAPA.pm',
! 55: $lonlib.'/perl/Safe.pm',
! 56: $lonlib.'/perl/*-std.pm',
! 57: $lonlib.'/perl/HTML/*.pm',
! 58: $lonlib.'/perl/Safe.pm'));
! 59: }
! 60: if ($lonincludes) {
! 61: push(@paths,$lonincludes.'/*.lcpm');
! 62: }
! 63: push(@paths,('/home/httpd/cgi-bin/*.pl','/home/httpd/cgi-bin/*.png'));
! 64: my $confdir = '/etc/httpd/conf';
! 65: my $sha = 'SHA1';
! 66: if ($distro =~ /^(ubuntu|debian)(\d+)$/) {
! 67: $confdir = '/etc/apache2';
! 68: if (($1 eq 'ubuntu') && ($2 >= 12)) {
! 69: $sha = 'SHA';
! 70: }
! 71: } elsif ($distro =~ /^sles(\d+)$/) {
! 72: if ($1 >= 10) {
! 73: $confdir = '/etc/apache2';
! 74: }
! 75: } elsif ($distro =~ /^suse(\d+\.\d+)$/) {
! 76: if ($1 >= 10.0) {
! 77: $confdir = '/etc/apache2';
! 78: }
! 79: }
! 80: push(@paths,("$confdir/loncapa_apache.conf","$confdir/startup.pl"));
! 81: if ($sha eq 'SHA1') {
! 82: require Digest::SHA1;
! 83: } else {
! 84: require Digest::SHA;
! 85: }
! 86: if (@paths) {
! 87: my $pathstr = join (' ',@paths);
! 88: if (open($dirh,"grep '$revtag' $pathstr |")) {
! 89: while (my $line=<$dirh>) {
! 90: if ($line =~ m{^([^#]+):#\s\$Id:\s[\w.]+,v\s([\d.]+)\s}) {
! 91: $versions{$1} = $2;
! 92: }
! 93: }
! 94: close($dirh);
! 95: }
! 96: foreach my $key (sort(keys(%versions))) {
! 97: next if ($key =~ /\.lpmlsave$/);
! 98: my $sum;
! 99: if (open(my $fh,"<$key")) {
! 100: binmode $fh;
! 101: my $sha_obj;
! 102: if ($sha eq 'SHA') {
! 103: $sha_obj = Digest::SHA->new();
! 104: } else {
! 105: $sha_obj = Digest::SHA1->new();
! 106: }
! 107: $sha_obj->addfile($fh);
! 108: $sum = $sha_obj->hexdigest;
! 109: close($fh);
! 110: $chksums{$key} = $sum;
! 111: }
! 112: $output .= "$key,$versions{$key},$sum\n";
! 113: }
! 114: }
! 115: if ($lontabdir ne '') {
! 116: if (open(my $tabfh,">$lontabdir/lonchksums.tab")) {
! 117: print $tabfh '# Last written: '.localtime(time)."\n";
! 118: print $tabfh "$output\n";
! 119: close($tabfh);
! 120: }
! 121: }
! 122: return (\%chksums,\%versions);
! 123: }
! 124:
! 125: sub compare_checksums {
! 126: my ($target,$lonhost,$version,$serversums,$serverversions) = @_;
! 127: my ($message,$numchg);
! 128: if ((ref($serversums) eq 'HASH') && (keys(%{$serversums}))) {
! 129: my $checksums = &Apache::lonnet::fetch_dns_checksums();
! 130: my (%extra,%missing,%diffs,%stdsums,%stdversions);
! 131: if (ref($checksums) eq 'HASH') {
! 132: if (ref($checksums->{'sums'}) eq 'HASH') {
! 133: %stdsums = %{$checksums->{'sums'}};
! 134: }
! 135: if (ref($checksums->{'versions'}) eq 'HASH') {
! 136: %stdversions = %{$checksums->{'versions'}};
! 137: }
! 138: if (keys(%stdsums)) {
! 139: foreach my $key (keys(%stdsums)) {
! 140: if (exists($serversums->{$key})) {
! 141: if ($serversums->{$key} ne $stdsums{$key}) {
! 142: $diffs{$key} = 1;
! 143: $numchg ++;
! 144: }
! 145: } else {
! 146: $missing{$key} = 1;
! 147: $numchg ++;
! 148: }
! 149: }
! 150: foreach my $key (keys(%{$serversums})) {
! 151: unless (exists($stdsums{$key})) {
! 152: $extra{$key} = 1;
! 153: $numchg ++;
! 154: }
! 155: }
! 156: }
! 157: if ($numchg) {
! 158: $message =
! 159: &Apache::lonlocal::mt('[quant,_1,difference was,differences were] found'.
! 160: ' between LON-CAPA modules installed on your server ([_2])'.
! 161: ' and those expected for the LON-CAPA version ([_3])'.
! 162: ' which you are running.',$numchg,$lonhost,$version);
! 163: if ($target eq 'web') {
! 164: $message = '<p>'.$message.'</p>';
! 165: } else {
! 166: $message .= "\n\n";
! 167: }
! 168: my (@diffversion,@modified);
! 169: if (keys(%diffs) > 0) {
! 170: foreach my $file (sort(keys(%diffs))) {
! 171: if ($serverversions->{$file} ne $stdversions{$file}) {
! 172: push(@diffversion,$file);
! 173: } else {
! 174: push(@modified,$file);
! 175: }
! 176: }
! 177: if (@diffversion > 0) {
! 178: my $text =
! 179: &Apache::lonlocal::mt('The following [quant,_1,local file is a,local files are]'.
! 180: ' different version(s) from that expected for LON-CAPA [_2]:',
! 181: scalar(@diffversion),$version);
! 182: if ($target eq 'web') {
! 183: $message .= '<p>'.$text.'</p>'.
! 184: &Apache::loncommon::start_data_table().
! 185: &Apache::loncommon::start_data_table_header_row()."\n".
! 186: '<th>'.&Apache::lonlocal::mt('File').'</th>'."\n".
! 187: '<th>'.&Apache::lonlocal::mt('Server version').'</th>'."\n".
! 188: '<th>'.&Apache::lonlocal::mt('Expected version').'</th>'."\n".
! 189: &Apache::loncommon::end_data_table_header_row()."\n";
! 190: } else {
! 191: $message .= "$text\n";
! 192: }
! 193: foreach my $file (sort(@diffversion)) {
! 194: my $revnum = $stdversions{$file};
! 195: if ($target eq 'web') {
! 196: $message .= &Apache::loncommon::start_data_table_row().
! 197: '<td>'.$file.'<td>'."\n".
! 198: '<td>'.$serverversions->{$file}.'</td>'."\n".
! 199: '<td>'.$revnum.'</td>'."\n".
! 200: &Apache::loncommon::end_data_table_row()."\n";
! 201: } else {
! 202: $message .= $file.' '.
! 203: &Apache::lonlocal::mt('(local rev: [_1])',
! 204: $serverversions->{$file});
! 205: if ($revnum) {
! 206: $message .= '; '.
! 207: &Apache::lonlocal::mt('(expected rev: [_1])',
! 208: $revnum);
! 209: }
! 210: $message .= "\n";
! 211: }
! 212: }
! 213: }
! 214: if (@modified > 0) {
! 215: my $text =
! 216: &Apache::lonlocal::mt('The following [quant,_1,file appears,files appear]'.
! 217: ' to have been modified locally:',scalar(@modified));
! 218: if ($target eq 'web') {
! 219: $message .= '<p>'.$text.'</p>'.
! 220: &Apache::loncommon::start_data_table().
! 221: &Apache::loncommon::start_data_table_header_row()."\n".
! 222: '<th>'.&Apache::lonlocal::mt('File').'</th>'."\n".
! 223: '<th>'.&Apache::lonlocal::mt('Version').'</th>'."\n".
! 224: &Apache::loncommon::end_data_table_header_row()."\n";
! 225: } else {
! 226: $message .= "$text\n";
! 227: }
! 228: foreach my $file (sort(@modified)) {
! 229: if ($target eq 'web') {
! 230: $message .= &Apache::loncommon::start_data_table_row()."\n".
! 231: '<td>'.$file.'</td>'."\n".
! 232: '<td>'.$serverversions->{$file}.'</td>'."\n".
! 233: &Apache::loncommon::end_data_table_row()."\n";
! 234: } else {
! 235: $message .= $file.' '.
! 236: &Apache::lonlocal::mt('(local rev: [_1])',
! 237: $serverversions->{$file}).
! 238: "\n";
! 239: }
! 240: }
! 241: }
! 242: }
! 243: if (keys(%missing) > 0) {
! 244: my $text =
! 245: &Apache::lonlocal::mt('The following [quant,_1,local file appears,local files appear]'.
! 246: ' to be missing:',scalar(keys(%missing)));
! 247: if ($target eq 'web') {
! 248: $message .= '<p>'.$text.'</p>'.
! 249: &Apache::loncommon::start_data_table().
! 250: &Apache::loncommon::start_data_table_header_row()."\n".
! 251: '<th>'.&Apache::lonlocal::mt('File').'</th>'."\n".
! 252: '<th>'.&Apache::lonlocal::mt('Expected version').'</th>'."\n".
! 253: &Apache::loncommon::end_data_table_header_row()."\n";
! 254: } else {
! 255: $message .= "$text\n";
! 256: }
! 257: foreach my $file (sort(keys(%missing))) {
! 258: my $revnum = $stdversions{$file};
! 259: if ($target eq 'web') {
! 260: $message .= '<td>'.$file.'<td>'."\n".
! 261: '<td>'.$revnum.'</td>'."\n".
! 262: &Apache::loncommon::end_data_table_row()."\n";
! 263: } else {
! 264: $message .= $file;
! 265: if ($revnum) {
! 266: $message .= ' '.
! 267: &Apache::lonlocal::mt('(expected rev: [_1])',
! 268: $revnum);
! 269: }
! 270: $message .= "\n";
! 271: }
! 272: }
! 273: }
! 274: if (keys(%extra) > 0) {
! 275: my $text =
! 276: &Apache::lonlocal::mt('The following [quant,_1,file is,files are]'.
! 277: ' not required by the release you have installed:',
! 278: scalar(keys(%extra)));
! 279: if ($target eq 'web') {
! 280: $message .= '<p>'.$text.'</p>'.
! 281: &Apache::loncommon::start_data_table().
! 282: &Apache::loncommon::start_data_table_header_row()."\n".
! 283: '<th>'.&Apache::lonlocal::mt('File').'</th>'."\n".
! 284: '<th>'.&Apache::lonlocal::mt('Version').'</th>'."\n".
! 285: &Apache::loncommon::end_data_table_header_row()."\n";
! 286: } else {
! 287: $message .= "$text\n";
! 288: }
! 289: foreach my $file (sort(keys(%extra))) {
! 290: if ($target eq 'web') {
! 291: $message .= '<td>'.$file.'<td>'."\n".
! 292: '<td>'.$serverversions->{$file}.'</td>'."\n".
! 293: &Apache::loncommon::end_data_table_row()."\n";
! 294: } else {
! 295: $message .= $file.' '.
! 296: &Apache::lonlocal::mt('(local rev: [_1])',
! 297: $serverversions->{$file}).
! 298: "\n";
! 299: }
! 300: }
! 301: }
! 302: } else {
! 303: $message = &Apache::lonlocal::mt('No differences detected between installed files and files expected for LON-CAPA [_1]',$version);
! 304: }
! 305: } else {
! 306: $message = &Apache::lonlocal::mt('No comparison attempted - failed to retrieve checksums for installed files.');
! 307: }
! 308: } else {
! 309: $message = &Apache::lonlocal::mt('No comparison attempted - failed to retrieve checksums for installed files.');
! 310: }
! 311: unless ($message) {
! 312: $message = &Apache::lonlocal::mt('LON-CAPA module check found no file changes.')."\n";
! 313: }
! 314: return ($message,$numchg);
! 315: }
! 316:
! 317: 1;
! 318:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>