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

1.1       matthew     1: #!/usr/bin/perl -w
                      2: #
                      3: # The LearningOnline Network
                      4: #
1.4     ! matthew     5: # $Id: modify_config_files.pl,v 1.3 2004/08/11 17:32:53 matthew 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: 
                     39: This script modifies /etc/yum.conf and /etc/my.cnf.
                     40: 
                     41: =head1 DESCRIPTION
                     42: 
                     43: This script modifies /etc/yum.conf and /etc/my.cnf to ensure certain parameters
                     44: are set properly.  The LON-CAPA yum repositories are added to /etc/yum.conf.
                     45: The /etc/my.cnf file is modified to set the wait_timeout to 1 year.  Backup
                     46: copies of each file are made in /etc.
                     47: 
                     48: =cut
                     49: 
                     50: use strict;
                     51: use File::Copy;
1.3       matthew    52: use lib '/home/httpd/lib/perl/';
                     53: use LONCAPA::Configuration;
                     54: my $loncapa_config=LONCAPA::Configuration::read_conf('loncapa.conf');
1.1       matthew    55: 
1.4     ! matthew    56: my $yum_status = 
        !            57:     &update_file('/etc/yum.conf',
1.1       matthew    58:              [{section => 'loncapa-updates-i386',
                     59:                key     => 'name=',
                     60:                value   => 'Fedora Core $releasever LON-CAPA i386 Updates',
                     61:            }, {section => 'loncapa-updates-i386',
                     62:                key     => 'baseurl=',
                     63:                value   => 'http://install.loncapa.org/fedora/linux/loncapa/'.
                     64:                    '$releasever/i386',
                     65:            }, {section => 'loncapa-updates-noarch',
                     66:                key     => 'name=',
                     67:                value   => 'Fedora Core $releasever LON-CAPA noarch Updates',
                     68:            }, {section => 'loncapa-updates-noarch',
                     69:                key     => 'baseurl=',
                     70:                value   => 'http://install.loncapa.org/fedora/linux/loncapa/'.
                     71:                    '$releasever/noarch',
                     72:            }]);
                     73: 
1.4     ! matthew    74: my $mysql_global_status =
        !            75:     &update_file('/etc/my.cnf',
1.1       matthew    76:              [{section =>'mysqld',
                     77:                key     =>'set-variable=wait_timeout=',
                     78:                value   =>'31536000', }]);
                     79: 
1.3       matthew    80: my $local_my_cnf = '/home/www/.my.cnf';
                     81: if (! -e $local_my_cnf) {
1.4     ! matthew    82:     # Create a file so we can do something with it...
1.3       matthew    83:     system("touch $local_my_cnf");
                     84: }
1.4     ! matthew    85: my $mysql_www_status =
        !            86:     &update_file($local_my_cnf,
1.3       matthew    87:              [{section =>'client',
                     88:                key     =>'user=',
                     89:                value   =>'www',},
                     90:               {section =>'client',
                     91:                key     =>'password=',
                     92:                value   =>$loncapa_config->{'lonSqlAccess'}},]);
                     93: 
1.4     ! matthew    94: my $exitvalue = 0;
        !            95: 
        !            96: if ($mysql_global_status) { $exitvalue = 1; }
        !            97: 
        !            98: exit $exitvalue;
1.1       matthew    99: 
                    100: 
                    101: 
                    102: #################################################################
                    103: #################################################################
                    104: 
                    105: =pod
                    106: 
                    107: =over 4
                    108: 
                    109: =cut
                    110: 
                    111: #################################################################
                    112: #################################################################
                    113: sub update_file {
                    114:     my ($file,$newdata) = @_;
                    115:     return 1 if (! -e $file);
                    116:     my $backup = $file.'.backup';
                    117:     if (! copy($file,$backup)) {
1.4     ! matthew   118:         warn "**** Error: Unable to make backup of $file";
1.1       matthew   119:         return 0;
                    120:     }
                    121:     my ($filedata) = &parse_config_file($file);
1.4     ! matthew   122:     if (! ref($filedata)) { warn "**** Error: $filedata"; return 0;}
        !           123:     my $modified = 0;
1.1       matthew   124:     foreach my $data (@$newdata) {
                    125:         my $section = $data->{'section'};
                    126:         my $key = $data->{'key'};
                    127:         my $value = $data->{'value'};
1.4     ! matthew   128:         my $result = &modify_config_file($filedata,$section,$key,$value);
        !           129:         if ($result) { $modified = 1; }
        !           130:     }
        !           131:     if ($modified) {
        !           132:         my $result = &write_config_file($file,$filedata);
        !           133:         if (defined($result)) { warn 'Error:'.$result; return 0; }
1.1       matthew   134:     }
1.4     ! matthew   135:     return $modified;
1.1       matthew   136: }
                    137: 
                    138: #################################################################
                    139: #################################################################
                    140: 
                    141: =pod
                    142: 
                    143: =item &parse_config_file
                    144: 
                    145: Read a configuration file in and parse it into an internal data structure.
                    146: 
                    147: Input: filename
                    148: 
                    149: Output: array ref $filedata  OR  scalar error message
                    150: 
                    151: =cut
                    152: 
                    153: #################################################################
                    154: #################################################################
                    155: sub parse_config_file {
                    156:     my ($file) = @_;
                    157:     open(INFILE,$file) || return ('Unable to open '.$file.' for reading');
                    158:     my @Input = <INFILE>;
                    159:     close(INFILE);
                    160:     my @Structure;
                    161:     my %Sections;
                    162:     while (my $line = shift(@Input)) {
                    163:         chomp($line);
                    164:         if ($line =~ /^\[([^\]]*)\]/) {
                    165:             my $section_id = $1;
                    166:             push(@Structure,'__section__'.$section_id);
                    167:             while ($line = shift(@Input)) {
1.4     ! matthew   168:                 chomp($line);
1.1       matthew   169:                 if ($line =~ /^\[([^\]]*)\]/) {
                    170:                     unshift(@Input,$line);
                    171:                     last;
                    172:                 } else {
                    173:                     push(@{$Sections{$section_id}},$line);
                    174:                 }
                    175:             }
                    176:         } else {
                    177:             push(@Structure,$line);
                    178:         }
                    179:     }
                    180:     my $filedata = [\@Structure,\%Sections];
                    181:     return $filedata;
                    182: }
                    183: 
                    184: #################################################################
                    185: #################################################################
                    186: 
                    187: =pod
                    188: 
                    189: =item
                    190: 
                    191: Write a configuration file out based on the internal data structure returned
                    192: by &parse_config_file
                    193: 
                    194: Inputs: filename, $filedata (the return value of &parse_config_file
                    195: 
                    196: Returns: undef on success, scalar error message on failure.
                    197: 
                    198: =cut
                    199: 
                    200: #################################################################
                    201: #################################################################
                    202: sub write_config_file {
                    203:     my ($file,$filedata) = @_;
                    204:     my ($structure,$sections) = @$filedata;
                    205:     if (! defined($structure) || ! ref($structure)) {
                    206:         return 'Bad subroutine inputs';
                    207:     }
                    208:     open(OUTPUT,'>'.$file) || return('Unable to open '.$file.' for writing');
                    209:     for (my $i=0;$i<scalar(@$structure);$i++) {
                    210:         my $line = $structure->[$i];
                    211:         chomp($line);
                    212:         if ($line =~ /^__section__(.*)$/) {
                    213:             my $section_id = $1;
                    214:             print OUTPUT ('['.$section_id.']'.$/);
                    215:             foreach my $section_line (@{$sections->{$section_id}}) {
                    216:                 chomp($section_line);
                    217:                 print OUTPUT $section_line.$/;
                    218:             }
                    219:             # Deal with blank lines
                    220:             if ($sections->{$section_id}->[-1] =~ /^\s*$/) {
                    221:                 # No need to output a blank line at the end if there is one 
                    222:                 # already
                    223:             } else {
                    224:                 print OUTPUT $/;
                    225:             }
                    226:         } else {
                    227:             print OUTPUT $line.$/;
                    228:         }
                    229:     }
                    230:     close OUTPUT;
                    231:     return undef;
                    232: }
                    233: 
                    234: #################################################################
                    235: #################################################################
                    236: 
                    237: =pod
                    238: 
                    239: =item &modify_config_file
                    240: 
                    241: Modifies the internal data structure of a configuration file to include new
                    242: sections and/or new configuration directives.
                    243: 
                    244: Inputs: $filedata (see &parse_config_file
                    245: $section, the [section] the new entry is to reside in.  A value of undef will
                    246: cause the "outer" section (as in yum.conf) to be updated (or have the new
                    247: value prepended).
                    248: $newkey: A line which matches this will be replaced with $newkey.$newvalue
                    249: $newvalue: The new value to be placed with the new key.
                    250: 
1.4     ! matthew   251: Returns: 0 or 1, indicating if the file was modified(1) or not(0).
        !           252: 
        !           253: 
1.1       matthew   254: =cut
                    255: 
                    256: #################################################################
                    257: #################################################################
                    258: sub modify_config_file {
                    259:     my ($filedata,$section,$newkey,$newvalue)=@_;
1.4     ! matthew   260:     my $modified = 0;    # returned value - set to true if the file is modified
1.1       matthew   261:     my ($structure,$sections) = @$filedata;
                    262:     if (! defined($newvalue)) {
                    263:         $newvalue = '';
                    264:     }
                    265:     my $newline = $newkey.$newvalue;
                    266:     #
                    267:     # Determine which array ref gets the item
                    268:     my $target;
                    269:     if (defined($section)) {
                    270:         if (! exists($sections->{$section})) {
                    271:             push(@$structure,'__section__'.$section);
                    272:             $sections->{$section}=[];
                    273:         }
                    274:         $target = $sections->{$section};
                    275:     } else {
                    276:         $target = $structure;
                    277:     }
                    278:     #
                    279:     # Put the item in or update it.
                    280:     my $key_is_new = 1;
                    281:     for (my $i=0;$i<scalar(@$target);$i++) {
                    282:         if ($target->[$i] =~/^$newkey/) {
1.4     ! matthew   283:             if ($target->[$i] ne $newline) {
        !           284:                 $target->[$i]=$newline;
        !           285:                 $modified = 1;
        !           286:             }
1.1       matthew   287:             $key_is_new = 0;
                    288:             last;
                    289:         }
                    290:     }
                    291:     if ($key_is_new) {
                    292:         if (! defined($section)) {
                    293:             unshift(@$target,$newline);
                    294:         } else {
                    295:             # No need to put things after a blank line.
1.2       matthew   296:             if (defined($target->[-1]) && $target->[-1] =~ /^\s*$/) {
1.1       matthew   297:                 $target->[-1] = $newline;
1.4     ! matthew   298:                 $modified = 1;
1.1       matthew   299:             } else {
                    300:                 push(@$target,$newline);
1.4     ! matthew   301:                 $modified = 1;
1.1       matthew   302:             }
                    303:         }
                    304:     }
1.4     ! matthew   305:     return $modified;
1.1       matthew   306: }
                    307: 
                    308: 
                    309: #################################################################
                    310: #################################################################
                    311: 
                    312: =pod
                    313: 
                    314: =back
                    315: 
                    316: =cut
                    317: 
                    318: #################################################################
                    319: #################################################################

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