#! /usr/bin/perl -w use Getopt::Std; # This program checks that all the version numbers scattered # throughout LVM match. The data section at the end of this file # contains lines which specify the locations of these version numbers. # These specifications are of the form: # :: # Where: # 'file' is the name of the file relative to the top of the LVM tree # 'line' is the line number (numeric) or a regular expression that # uniquely selects the line. # 'pattern' is a regular expression used to extract the version number # from the line. After this pattern has run $1 (ie, the expression # contained within the first set of brackets) should contain the # version number. # Run this program from the root of the LVM tree, an optional argument # tells it what version number should be present. If this argument # isn't present it lists all version numbers; The argument is specified # with the '-t' flag # You can also do a search and replace on targets using the combination of # the '-t', '-s', and '-d' flags. Specify the target of your search with '-t' # the destination of your search with '-d', and the fact that you want to # search with '-s'. By default, the seach-and-replace feature backs up all # files it touches to $file.$TIMESTAMP. You can shut this feature off by # specifying the -bn flag at the command line. # cd ~/develop/LVM # scripts/check_version_numbers # scripts/check_version_numbers -t 0.9.1_beta2 # scripts/check_version_numbers -s -t 0.9.1_beta2 -d 0.9.1_beta3 $err = getopts('b:t:d:hs'); if($err == 0) { $opt_h = 1; } $name = $0; $name =~ s/(.*\/)(.*)/$2/; # Hurrah for complex command line flag dependancies! if(defined($opt_t)) { $target = $opt_t; if(defined($opt_s)) { if(defined($opt_d)) { $destination = $opt_d; } else { $opt_h = 1; } } else { if(defined($opt_d)) { $opt_h = 1; } } } if(defined($opt_h)) { die "usage: $name [-h -t Target [-s -d Destination -b n]]\n\t-h\tthis help message\n\t-t\tVersion string we're looking for\n\t-s\tSearch-and-replace: Destination for Target\n\t-d\tChange target to destination if -s flag is given\n\t-b\tBackup modified files? (default: y)\n"; } # default is to backup all files with a time and date stamp if(!defined($opt_b)) { $opt_b = "y"; } $ret = 0; # scan through the regexps at the bottom of the file while() { chomp; next if(m/^\s*$/); ($file, $line, $pattern) = split(':', $_); if(!defined($file) || !defined($line) || !defined($pattern)) { print "Malformed line: '$_'\n"; next; } # if we're doing a target destination substitution... if(defined($opt_s)) { # do a backup unless explicitly requested not to if($opt_b ne "n") { local ($sec,$min,$hour,$mday,$mon,$year) = localtime(time()); local $thisdate = "$mday$mon$year\_$hour\:$min\.$sec"; system "cp $file $file.$thisdate"; } # open a temporary output file open(OUT, ">$file.tmp") or die("couldn't open '$file.tmp'\n"); } open(IN, "$file") or die("couldn't open '$file'\n"); $match = 0; $count = 0; $number = ($line =~ /^[0-9]+$/) ? 1 : 0; while(!$match && ($in = )) { chomp $in; $count++; if($number) { if($count == $line) {$match = 1;} else { if(defined($opt_s)) {print IN "$in\n";} } } else { if($in =~ m/$line/) {$match = 1;} else { if(defined($opt_s)) {print OUT "$in\n";} } } } if(!$match) { print STDOUT "Couldn't find line matching $file:$line\n"; } else { # if we're doing a search and replace if(defined($opt_s)) { local $orig_line = $in; # put the modified line in if we find the search target if($in =~ s/$target/$destination/) { print OUT "$in\n"; } # otherwise put in the unmodified line else { print OUT "$orig_line\n"; } } else { if($in =~ m/$pattern/) { if(defined($target)) { if(!($1 eq $target)) { print "$file:$count:$1\n"; $ret = 1; } } else { print "$file:$count:$1\n"; } } else { print "couldn't match pattern on $file:$line:$pattern\n"; } } } # we handle cleanup differently for the search-and-replace option if(defined($opt_s)){ if($match) { while(($in = )) { chomp $in; print OUT "$in\n"; } system "cp $file.tmp $file;"; } close(OUT); system "rm $file.tmp"; } close(IN); } exit($ret); __DATA__ README:1:LVM\s+(\S+) README:This directory contains:version\s+(\S+)\s+release README:\.tar\.gz:lvm_(.+)\.tar\.gz INSTALL:1:LVM\s+(\S+) INSTALL: LVM\/:\/([^\/ ]+) FAQ:1:LVM\s+(\S+) KNOWN_BUGS:1:LVM\s+(\S+) KNOWN_BUGS:Known bugs in LVM:LVM\s+(.+).\s* LVM-HOWTO:1:LVM\s+(\S+) TODO:1:LVM\s+(\S+) WHATSNEW:1:LVM\s+-\s+(\S+) WHATSNEW:What is new in LVM:LVM\s+-\s+(\S+) lvm_input_msg:bugfixes coming with:LVM\s+(\S+) tools/lvmcreate_initrd:Logical Volume Manager:er (.*) by Heinz kernel/lvm.h:define LVM_RELEASE_NAME\s+\":"(\S+)"