Annotation of loncom/debugging_tools/modify_config_files.pl, revision 1.14

1.1       matthew     1: #!/usr/bin/perl -w
                      2: #
                      3: # The LearningOnline Network
                      4: #
1.14    ! raeburn     5: # $Id: modify_config_files.pl,v 1.13 2017/06/05 21:06:25 raeburn Exp $
1.1       matthew     6: #
                      7: # Copyright Michigan State University Board of Trustees
                      8: #
                      9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                     10: #
                     11: # LON-CAPA is free software; you can redistribute it and/or modify
                     12: # it under the terms of the GNU General Public License as published by
                     13: # the Free Software Foundation; either version 2 of the License, or
                     14: # (at your option) any later version.
                     15: #
                     16: # LON-CAPA is distributed in the hope that it will be useful,
                     17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     19: # GNU General Public License for more details.
                     20: #
                     21: # You should have received a copy of the GNU General Public License
                     22: # along with LON-CAPA; if not, write to the Free Software
                     23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     24: #
                     25: # /home/httpd/html/adm/gpl.txt
                     26: #
                     27: # http://www.lon-capa.org/
                     28: #
                     29: ###
                     30: 
                     31: =pod
                     32: 
                     33: =head1 NAME
                     34: 
                     35: B<modify_config_files.pl>
                     36: 
                     37: =head1 SYNOPSIS
                     38: 
1.9       raeburn    39: This script modifies /etc/my.cnf and one of: /etc/yum.conf 
1.13      raeburn    40: (for CentOS/Scientific Linux/RHEL >=5), /etc/apt/sources.list
                     41: (for Debian/Ubuntu), /etc/sysconfig/rhn/sources (for RHEL4),
                     42: and /etc/yum.repos.d/loncapa.repo (Fedora >= 21).
1.1       matthew    43: 
                     44: =head1 DESCRIPTION
                     45: 
1.13      raeburn    46: This script modifies /etc/my.cnf, /etc/yum.conf, /etc/yum.repos.d/loncapa.repo,
                     47: /etc/apt/sources, or /etc/sysconfig/rhn/sources to ensure certain
                     48: parameters are set properly.
                     49: 
                     50: The LON-CAPA yum repositories are added to /etc/yum.conf, 
                     51: /etc/yum.repos.d/loncapa.repo, /etc/sysconfig/rhn/sources
                     52: and the LON-CAPA apt repositories are added to 
1.9       raeburn    53: /etc/apt/sources.list.
                     54: 
1.1       matthew    55: The /etc/my.cnf file is modified to set the wait_timeout to 1 year.  Backup
1.9       raeburn    56: copies of each file are made in /etc, /etc/apt, and /etc/sysconfig/rhn, as 
                     57: appropriate.
1.1       matthew    58: 
                     59: =cut
                     60: 
                     61: use strict;
                     62: use File::Copy;
1.3       matthew    63: use lib '/home/httpd/lib/perl/';
                     64: use LONCAPA::Configuration;
                     65: my $loncapa_config=LONCAPA::Configuration::read_conf('loncapa.conf');
1.1       matthew    66: 
1.6       raeburn    67: open(DSH,"$$loncapa_config{'lonDaemons'}/distprobe |");
                     68: my $dist = <DSH>;
                     69: chomp($dist);
                     70: close(DSH);
                     71: 
                     72: my $yum_status;
1.9       raeburn    73: my $loninst = 'http://install.loncapa.org';
                     74: my $loninst_re = 'http://install\.loncapa\.org';
                     75: if ($dist =~ /^fedora(\d+)$/) {
1.13      raeburn    76:     my $file = '/etc/yum.conf';
1.9       raeburn    77:     my $ver = $1;
1.10      raeburn    78:     my $gpgchk = '0';
1.9       raeburn    79:     my $gpg = "$loninst/versions/fedora/RPM-GPG-KEY-loncapa"; 
1.13      raeburn    80:     my $nobackup;
1.9       raeburn    81:     if ($ver > 6) {
1.10      raeburn    82:         $gpgchk = '1';
1.9       raeburn    83:     }
1.13      raeburn    84:     if ($ver >= 21) {
                     85:         $file = '/etc/yum.repos.d/loncapa.repo';
                     86:         $nobackup = 1;
                     87:     }
1.6       raeburn    88:     $yum_status =  
1.13      raeburn    89:         &update_file($file,
1.10      raeburn    90:              [{section => 'loncapa-updates-basearch',
1.1       matthew    91:                key     => 'name=',
1.6       raeburn    92:                value   => 'Fedora Core $releasever LON-CAPA $basearch Updates',
1.10      raeburn    93:            }, {section => 'loncapa-updates-basearch',
1.1       matthew    94:                key     => 'baseurl=',
1.9       raeburn    95:                value   => $loninst.'/fedora/linux/loncapa/$releasever/$basearch',
1.10      raeburn    96:            }, {section => 'loncapa-updates-basearch',
1.5       matthew    97:                key     => 'gpgcheck=',
1.9       raeburn    98:                value   =>  $gpgchk,
1.10      raeburn    99:            }, {section => 'loncapa-updates-basearch',
1.13      raeburn   100:                key     => 'gpgkey=',
1.9       raeburn   101:                value   => $gpg,
1.1       matthew   102:            }, {section => 'loncapa-updates-noarch',
                    103:                key     => 'name=',
                    104:                value   => 'Fedora Core $releasever LON-CAPA noarch Updates',
                    105:            }, {section => 'loncapa-updates-noarch',
                    106:                key     => 'baseurl=',
1.9       raeburn   107:                value   => $loninst.'/fedora/linux/loncapa/$releasever/noarch',
1.5       matthew   108:            }, {section => 'loncapa-updates-noarch',
                    109:                key     => 'gpgcheck=',
1.9       raeburn   110:                value   => $gpgchk,
                    111:            }, {section => 'loncapa-updates-noarch',
1.13      raeburn   112:                key     => 'gpgkey=',
1.9       raeburn   113:                value   => $gpg,
1.13      raeburn   114:            }],$nobackup);
1.9       raeburn   115: } elsif ($dist =~ /^(rhes|centos|scientific)(\d+)$/) {
                    116:     my $type = $1;
                    117:     my $ver = $2;
                    118:     my $longver = $ver;
                    119:     if ($type eq 'rhes') {
                    120:         if ($ver == 4) {
                    121:             $longver = '4ES';
                    122:         } elsif ($ver == 5) {
                    123:             $longver = '5Server';
                    124:         }
                    125:     }
                    126:     my %info = (
                    127:                  rhes => {
                    128:                            title => 'RHEL',
                    129:                            path => 'redhat/linux/enterprise/loncapa',
                    130:                            gpg => 'versions/redhat/RPM-GPG-KEY-loncapa',
                    131:                            gpgchk => 1,
                    132:                          },
                    133:                  centos => {
                    134:                              title => 'CentOS',
                    135:                              path => 'centos/loncapa',
                    136:                              gpg => 'versions/centos/RPM-GPG-KEY-loncapa',
                    137:                              gpgchk => 1,
                    138:                            },
                    139:                  scientific => {
                    140:                                  title => 'Scientific Linux',
                    141:                                  path => 'scientific/loncapa',
                    142:                                  gpg => 'versions/scientific/RPM-GPG-KEY-loncapa',
                    143:                                  gpgchk => 1,
                    144:                                },
                    145:                );
                    146:     if (ref($info{$type}) eq 'HASH') {
                    147:         if ($ver > 4) {
                    148:             $yum_status =
                    149:                 &update_file('/etc/yum.conf',
                    150:                      [{section => 'loncapa-updates-basearch',
                    151:                        key     => 'name=',
                    152:                        value   => $info{$type}{title}.' $releasever LON-CAPA $basearch Updates',
                    153:                       }, {section => "loncapa-updates-basearch",
                    154:                           key     => 'baseurl=',
                    155:                           value   => "$loninst/$info{$type}{path}/".'$releasever/$basearch',
                    156:                       }, {section => 'loncapa-updates-basearch',
                    157:                           key     => 'gpgcheck=',
1.11      raeburn   158:                           value   => $info{$type}{gpgchk},
1.10      raeburn   159:                       }, {section => 'loncapa-updates-basearch',
1.9       raeburn   160:                           key     => 'gpgkey=',
                    161:                           value   => "$loninst/$info{$type}{gpg}",
                    162:                       }, {section => 'loncapa-updates-noarch',
                    163:                           key     => 'name=',
                    164:                           value   => $info{$type}{title}.' $releasever LON-CAPA noarch Updates',
                    165:                       }, {section => 'loncapa-updates-noarch',
                    166:                           key     => 'baseurl=',
                    167:                           value   => "$loninst/$info{$type}{path}/".'$releasever/noarch',
                    168:                       }, {section => 'loncapa-updates-noarch',
                    169:                           key     => 'gpgcheck=',
1.11      raeburn   170:                           value   => $info{$type}{gpgchk},
1.9       raeburn   171:                       }, {section => 'loncapa-updates-noarch',
                    172:                           key     => 'gpgkey=',
                    173:                           value   => "$loninst/$info{$type}{gpg}",
                    174:                       }]);
                    175:         } elsif (($type eq 'rhes') && ($ver == 4)) {
                    176:             my %rhn = (
                    177:                         basearch => { 
                    178:                             regexp => '\s*yum\s+loncapa\-updates\-basearch\s+'.$loninst_re.'/'.$info{$type}{path}.'/'.$longver.'/\$ARCH',
                    179:                             text => "yum loncapa-updates-basearch $loninst/$info{$type}{path}/$longver/".'$ARCH',
                    180:                                     },
                    181:                         noarch =>  {
                    182:                             regexp => '\s*yum\s+loncapa\-updates\-noarch\s+'.$loninst_re.'/'.$info{$type}{path}.'/'.$longver.'/noarch',
                    183:                             text => "yum loncapa-updates-noarch $loninst/$info{$type}{path}/$longver/noarch",
                    184:                                    },
                    185:                       );
                    186:             $yum_status = &update_rhn_source(\%rhn); 
                    187:         }
                    188:     }
                    189: } elsif ($dist =~ /^(debian|ubuntu)\d+$/) {
                    190:     my %apt_get_source = (
                    191:                            debian5 => {
                    192:                                         regexp => '\s*deb\s+'.$loninst_re.'/debian/\s+lenny\s+main',
                    193:                                         text   => "deb $loninst/debian/ lenny main",
                    194:                                       },
                    195:                            ubuntu6 => {
                    196:                                         regexp => '\s*deb\s+'.$loninst_re.'/ubuntu/\s+dapper\s+main',
                    197:                                         text   => "deb $loninst/ubuntu/ dapper main",
                    198:                                       },
                    199:                            ubuntu8 => {
                    200:                                         regexp => '\s*deb\s+'.$loninst_re.'/ubuntu/\s+hardy\s+main',
                    201:                                         text   => "deb $loninst/ubuntu/ hardy main",
                    202:                                       },
1.14    ! raeburn   203:                            ubuntu10 => {
        !           204:                                         regexp => '\s*deb\s+'.$loninst_re.'/ubuntu/\s+lucid\s+main',
        !           205:                                         text   => "deb $loninst/ubuntu/ lucid main",
        !           206:                                        },
        !           207:                            ubuntu12 => {
        !           208:                                         regexp => '\s*deb\s+'.$loninst_re.'/ubuntu/\s+precise\s+main',
        !           209:                                         text   => "deb $loninst/ubuntu/ precise main",
        !           210:                                        },
        !           211:                            ubuntu14 => {
        !           212:                                         regexp => '\s*deb\s+'.$loninst_re.'/ubuntu/\s+trusty\s+main',
        !           213:                                         text   => "deb $loninst/ubuntu/ trusty main",
        !           214:                                        },
        !           215:                            ubuntu16 => {
        !           216:                                         regexp => '\s*deb\s+'.$loninst_re.'/ubuntu/\s+xenial\s+main',
        !           217:                                         text   => "deb $loninst/ubuntu/ xenial main",
        !           218:                                        },
        !           219:                            ubuntu18 => {
        !           220:                                         regexp => '\s*deb\s+'.$loninst_re.'/ubuntu/\s+bionic\s+main',
        !           221:                                         text   => "deb $loninst/ubuntu/ bionic main",
        !           222:                                        },
1.9       raeburn   223:                          );
                    224:     my $apt_status;
                    225:     if (defined($apt_get_source{$dist})) {
                    226:         $apt_status = &update_apt_source($apt_get_source{$dist},);
1.6       raeburn   227:     }
                    228: }
1.1       matthew   229: 
1.4       matthew   230: my $mysql_global_status =
                    231:     &update_file('/etc/my.cnf',
1.1       matthew   232:              [{section =>'mysqld',
1.12      raeburn   233:                key     =>'wait_timeout=',
1.1       matthew   234:                value   =>'31536000', }]);
                    235: 
1.3       matthew   236: my $local_my_cnf = '/home/www/.my.cnf';
                    237: if (! -e $local_my_cnf) {
1.4       matthew   238:     # Create a file so we can do something with it...
1.3       matthew   239:     system("touch $local_my_cnf");
                    240: }
1.4       matthew   241: my $mysql_www_status =
                    242:     &update_file($local_my_cnf,
1.3       matthew   243:              [{section =>'client',
                    244:                key     =>'user=',
                    245:                value   =>'www',},
                    246:               {section =>'client',
                    247:                key     =>'password=',
                    248:                value   =>$loncapa_config->{'lonSqlAccess'}},]);
                    249: 
1.4       matthew   250: my $exitvalue = 0;
                    251: 
                    252: if ($mysql_global_status) { $exitvalue = 1; }
                    253: 
                    254: exit $exitvalue;
1.1       matthew   255: 
                    256: 
                    257: sub update_file {
1.13      raeburn   258:     my ($file,$newdata,$nobackup) = @_;
1.1       matthew   259:     return 1 if (! -e $file);
1.13      raeburn   260:     unless ($nobackup) {
                    261:         my $backup = $file.'.backup';
                    262:         if (! copy($file,$backup)) {
                    263:             warn "**** Error: Unable to make backup of $file";
                    264:             return 0;
                    265:         }
1.1       matthew   266:     }
                    267:     my ($filedata) = &parse_config_file($file);
1.4       matthew   268:     if (! ref($filedata)) { warn "**** Error: $filedata"; return 0;}
                    269:     my $modified = 0;
1.1       matthew   270:     foreach my $data (@$newdata) {
                    271:         my $section = $data->{'section'};
                    272:         my $key = $data->{'key'};
                    273:         my $value = $data->{'value'};
1.4       matthew   274:         my $result = &modify_config_file($filedata,$section,$key,$value);
                    275:         if ($result) { $modified = 1; }
                    276:     }
                    277:     if ($modified) {
                    278:         my $result = &write_config_file($file,$filedata);
                    279:         if (defined($result)) { warn 'Error:'.$result; return 0; }
1.1       matthew   280:     }
1.4       matthew   281:     return $modified;
1.1       matthew   282: }
                    283: 
                    284: #################################################################
                    285: #################################################################
                    286: 
                    287: =pod
                    288: 
1.9       raeburn   289: =over 4
                    290: 
                    291: =item &parse_config_file()
1.1       matthew   292: 
                    293: Read a configuration file in and parse it into an internal data structure.
                    294: 
                    295: Input: filename
                    296: 
                    297: Output: array ref $filedata  OR  scalar error message
                    298: 
1.9       raeburn   299: =back 
                    300: 
1.1       matthew   301: =cut
                    302: 
                    303: #################################################################
                    304: #################################################################
                    305: sub parse_config_file {
                    306:     my ($file) = @_;
                    307:     open(INFILE,$file) || return ('Unable to open '.$file.' for reading');
                    308:     my @Input = <INFILE>;
                    309:     close(INFILE);
                    310:     my @Structure;
                    311:     my %Sections;
                    312:     while (my $line = shift(@Input)) {
                    313:         chomp($line);
                    314:         if ($line =~ /^\[([^\]]*)\]/) {
                    315:             my $section_id = $1;
                    316:             push(@Structure,'__section__'.$section_id);
                    317:             while ($line = shift(@Input)) {
1.4       matthew   318:                 chomp($line);
1.1       matthew   319:                 if ($line =~ /^\[([^\]]*)\]/) {
                    320:                     unshift(@Input,$line);
                    321:                     last;
                    322:                 } else {
                    323:                     push(@{$Sections{$section_id}},$line);
                    324:                 }
                    325:             }
                    326:         } else {
                    327:             push(@Structure,$line);
                    328:         }
                    329:     }
                    330:     my $filedata = [\@Structure,\%Sections];
                    331:     return $filedata;
                    332: }
                    333: 
                    334: #################################################################
                    335: #################################################################
                    336: 
                    337: =pod
                    338: 
1.9       raeburn   339: =over 4
                    340: 
1.1       matthew   341: =item
                    342: 
                    343: Write a configuration file out based on the internal data structure returned
                    344: by &parse_config_file
                    345: 
                    346: Inputs: filename, $filedata (the return value of &parse_config_file
                    347: 
                    348: Returns: undef on success, scalar error message on failure.
                    349: 
1.9       raeburn   350: =back
                    351: 
1.1       matthew   352: =cut
                    353: 
                    354: #################################################################
                    355: #################################################################
                    356: sub write_config_file {
                    357:     my ($file,$filedata) = @_;
                    358:     my ($structure,$sections) = @$filedata;
                    359:     if (! defined($structure) || ! ref($structure)) {
                    360:         return 'Bad subroutine inputs';
                    361:     }
                    362:     open(OUTPUT,'>'.$file) || return('Unable to open '.$file.' for writing');
                    363:     for (my $i=0;$i<scalar(@$structure);$i++) {
                    364:         my $line = $structure->[$i];
                    365:         chomp($line);
                    366:         if ($line =~ /^__section__(.*)$/) {
                    367:             my $section_id = $1;
                    368:             print OUTPUT ('['.$section_id.']'.$/);
                    369:             foreach my $section_line (@{$sections->{$section_id}}) {
                    370:                 chomp($section_line);
                    371:                 print OUTPUT $section_line.$/;
                    372:             }
                    373:             # Deal with blank lines
                    374:             if ($sections->{$section_id}->[-1] =~ /^\s*$/) {
                    375:                 # No need to output a blank line at the end if there is one 
                    376:                 # already
                    377:             } else {
                    378:                 print OUTPUT $/;
                    379:             }
                    380:         } else {
                    381:             print OUTPUT $line.$/;
                    382:         }
                    383:     }
                    384:     close OUTPUT;
                    385:     return undef;
                    386: }
                    387: 
                    388: #################################################################
                    389: #################################################################
                    390: 
                    391: =pod
                    392: 
1.9       raeburn   393: =over 4
                    394: 
                    395: =item &modify_config_file()
1.1       matthew   396: 
                    397: Modifies the internal data structure of a configuration file to include new
                    398: sections and/or new configuration directives.
                    399: 
                    400: Inputs: $filedata (see &parse_config_file
                    401: $section, the [section] the new entry is to reside in.  A value of undef will
                    402: cause the "outer" section (as in yum.conf) to be updated (or have the new
                    403: value prepended).
                    404: $newkey: A line which matches this will be replaced with $newkey.$newvalue
                    405: $newvalue: The new value to be placed with the new key.
                    406: 
1.4       matthew   407: Returns: 0 or 1, indicating if the file was modified(1) or not(0).
                    408: 
1.9       raeburn   409: =back 
1.4       matthew   410: 
1.1       matthew   411: =cut
                    412: 
                    413: #################################################################
                    414: #################################################################
                    415: sub modify_config_file {
                    416:     my ($filedata,$section,$newkey,$newvalue)=@_;
1.4       matthew   417:     my $modified = 0;    # returned value - set to true if the file is modified
1.1       matthew   418:     my ($structure,$sections) = @$filedata;
                    419:     if (! defined($newvalue)) {
                    420:         $newvalue = '';
                    421:     }
                    422:     my $newline = $newkey.$newvalue;
                    423:     #
                    424:     # Determine which array ref gets the item
                    425:     my $target;
                    426:     if (defined($section)) {
                    427:         if (! exists($sections->{$section})) {
                    428:             push(@$structure,'__section__'.$section);
                    429:             $sections->{$section}=[];
                    430:         }
                    431:         $target = $sections->{$section};
                    432:     } else {
                    433:         $target = $structure;
                    434:     }
                    435:     #
                    436:     # Put the item in or update it.
                    437:     my $key_is_new = 1;
                    438:     for (my $i=0;$i<scalar(@$target);$i++) {
                    439:         if ($target->[$i] =~/^$newkey/) {
1.4       matthew   440:             if ($target->[$i] ne $newline) {
                    441:                 $target->[$i]=$newline;
                    442:                 $modified = 1;
                    443:             }
1.1       matthew   444:             $key_is_new = 0;
                    445:             last;
                    446:         }
                    447:     }
                    448:     if ($key_is_new) {
                    449:         if (! defined($section)) {
                    450:             unshift(@$target,$newline);
                    451:         } else {
                    452:             # No need to put things after a blank line.
1.2       matthew   453:             if (defined($target->[-1]) && $target->[-1] =~ /^\s*$/) {
1.1       matthew   454:                 $target->[-1] = $newline;
1.4       matthew   455:                 $modified = 1;
1.1       matthew   456:             } else {
                    457:                 push(@$target,$newline);
1.4       matthew   458:                 $modified = 1;
1.1       matthew   459:             }
                    460:         }
                    461:     }
1.4       matthew   462:     return $modified;
1.1       matthew   463: }
                    464: 
1.9       raeburn   465: #################################################################
                    466: #################################################################
                    467: 
                    468: =pod
                    469: 
                    470: =over 4
                    471: 
                    472: =item &update_rhn_source()
                    473: 
                    474: Modifies the Red Hat 4 sources file which includes repositories used by up2date 
                    475: 
                    476: Inputs: 
                    477: $rhn_items - a reference to hash of a hash containing the regular expression
                    478: to test for, and the text string to append to the file, if an entry for the 
                    479: LON-CAPA RHEL repository is missing for two cases:
                    480: 
                    481: (a) basearch
                    482: (b) noarch 
                    483: 
                    484: Returns: 0 or 1, indicating if the file was modified(1) or not(0).
                    485: 
                    486: =back
                    487: 
                    488: =cut
                    489: 
                    490: #################################################################
                    491: #################################################################
                    492: sub update_rhn_source {
                    493:     my ($rhn_items) = @_;
                    494:     return 0 if (ref($rhn_items) ne 'HASH');
                    495:     return 0 if ((ref($rhn_items->{basearch}) ne 'HASH') || (ref($rhn_items->{noarch}) ne 'HASH'));
                    496:     my $file = '/etc/sysconfig/rhn/sources';
                    497:     return 0 if (! -e $file);
                    498:     my $backup = $file.'.backup';
                    499:     if (! copy($file,$backup)) {
                    500:         warn "**** Error: Unable to make backup of $file";
                    501:         return 0;
                    502:     }
                    503:     my $result = 0;
                    504:     my $fh;
                    505:     if (open($fh,"<$file")) {
                    506:         my $total = 0;
                    507:         my %found;
                    508:         foreach my $item (keys(%{$rhn_items})) {
                    509:             $found{$item} = 0;
                    510:         }
                    511:         while(<$fh>) {
                    512:             foreach my $item (keys(%{$rhn_items})) {
                    513:                 if (ref($rhn_items->{$item}) eq 'HASH') {
                    514:                     my $pattern = $rhn_items->{$item}->{regexp};
                    515:                     if ($pattern ne '') { 
                    516:                         if (m{^$pattern}) {
                    517:                             $found{$item} = 1;
                    518:                             $total ++;
                    519:                         }
                    520:                     }
                    521:                 }
                    522:             }
                    523:             last if $total == 2;
                    524:         }
                    525:         close($fh);
                    526:         if ($total < 2) {
                    527:             if (open($fh,">>$file")) {
                    528:                 foreach my $item (keys(%{$rhn_items})) {
                    529:                     unless ($found{$item}) {
                    530:                         if (ref($rhn_items->{$item}) eq 'HASH') {
                    531:                             if ($rhn_items->{$item}->{text} ne '') {
                    532:                                 print $fh "\n".$rhn_items->{$item}->{text}."\n";
                    533:                                 $result = 1;
                    534:                             }
                    535:                         }
                    536:                     }
                    537:                 }
                    538:                 close($fh);
                    539:             }
                    540:         }
                    541:     }
                    542:     return $result;
                    543: }
1.1       matthew   544: 
                    545: #################################################################
                    546: #################################################################
                    547: 
                    548: =pod
                    549: 
1.9       raeburn   550: =over 4
                    551: 
                    552: =item &update_apt_source()
                    553: 
                    554: Modifies the source.list file which includes repositories used by apt-get
                    555: 
                    556: Inputs:
                    557: $deb_row - a reference to containing the regular expression
                    558: to test for, and the text string to append to the file, if an entry for the
                    559: LON-CAPA Debian/ or Ubuntu repository is missing.
                    560: 
                    561: Returns: 0 or 1, indicating if the file was modified(1) or not(0).
                    562: 
1.1       matthew   563: =back
                    564: 
                    565: =cut
                    566: 
                    567: #################################################################
                    568: #################################################################
1.9       raeburn   569: sub update_apt_source {
                    570:     my ($deb_row) = @_;
                    571:     return 0 if (ref($deb_row) ne 'HASH');
                    572:     return 0 if (($deb_row->{regexp} eq '') || ($deb_row->{text} eq ''));
                    573:     my $file = '/etc/apt/sources.list';
                    574:     return 0 if (! -e $file);
                    575:     my $backup = $file.'.backup';
                    576:     if (! copy($file,$backup)) {
                    577:         warn "**** Error: Unable to make backup of $file";
                    578:         return 0;
                    579:     }
                    580:     my $result = 0;
                    581:     my $fh;
                    582:     if (open($fh,"<$file")) {
                    583:         my $found = 0;
                    584:         my $pattern = $deb_row->{regexp};
                    585:         while(<$fh>) {
                    586:             if (m{^$pattern}) {
                    587:                 $found = 1;
                    588:                 last;
                    589:             }
                    590:         }
                    591:         close($fh);
                    592:         if (!$found) {
                    593:             if (open($fh,">>$file")) {
                    594:                 print $fh "\n".$deb_row->{text}."\n";
                    595:                 close($fh);
                    596:                 $result = 1;
                    597:             }
                    598:         }
                    599:     }
                    600:     return $result;
                    601: }
                    602: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>