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>