3 ## $Id: innupgrade.in 6458 2003-09-03 02:58:51Z rra $
5 ## Convert INN configuration files to the current syntax.
7 ## Intended to be run during a major version upgrade, this script tries to
8 ## convert existing INN configuration files to the syntax expected by the
9 ## current version, if that's changed.
11 ## Note that this script cannot use innshellvars.pl, since loading that file
12 ## requires innconfval be able to parse inn.conf, and until this script runs,
13 ## inn.conf may not be valid.
15 ## Currently handles the following conversions:
17 ## * Clean up inn.conf for the new parser in INN 2.4.
18 ## * Add the hismethod parameter to inn.conf if not found.
24 use subs qw(fix_inn_conf);
26 use Getopt::Long qw(GetOptions);
28 # The mappings of file names to fixes.
29 %FIXES = ('inn.conf' => \&fix_inn_conf);
31 # Clean up inn.conf for the new parser in INN 2.4. Null keys (keys without
32 # values) need to be commented out since they're no longer allowed (don't just
33 # remove them entirely since people may want them there as examples), and
34 # string values must be quoted if they contain any special characters. Takes
35 # a reference to an array containing the contents of the file, a reference to
36 # an array into which the output should be put, and the file name for error
39 my ($input, $output, $file) = @_;
41 my ($raw, $hismethod);
46 if (/^\s*\#/ || /^\s*$/) {
51 unless (/^(\s*)(\S+):(\s*)(.*)/) {
52 warn "$file:$line: cannot parse line: $_\n";
56 my ($indent, $key, $space, $value) = ($1, $2, $3, $4);
58 push (@$output, "#$_\n");
61 $hismethod = 1 if $key eq 'hismethod';
63 if ($value =~ /[\s;\"<>\[\]\\{}]/ && $value !~ /^\".*\"\s*$/) {
64 $value =~ s/([\"\\])/\\$1/g;
65 $value = '"' . $value . '"';
67 push (@$output, "$indent$key:$space$value\n");
70 # Add a setting of hismethod if one wasn't present in the original file.
72 push (@$output, "\n# Added by innupgrade\nhismethod: hisv6\n");
76 # Upgrade a particular file. Open the file, read it into an array, and then
77 # run the fix function on it. If the fix function generates different output
78 # than the current contents of the file, change the file.
80 my ($file, $function) = @_;
81 open (INPUT, $file) or die "$file: cannot open: $!\n";
85 &$function (\@input, \@output, $file);
86 if (join ('', @input) ne join ('', @output)) {
89 print "$file.OLD already exists, overwrite (y/N)? ";
91 if ($answer !~ /y/i) {
92 die "$file: backup $file.OLD already exists, aborting\n";
95 die "$file: backup $file.OLD already exists\n";
98 print "Updating $file, old version saved as $file.OLD\n";
99 my ($user, $group) = (stat $file)[4,5];
100 open (OUTPUT, "> $file.new.$$")
101 or die "$file: cannot create $file.new.$$: $!\n";
102 print OUTPUT @output;
103 close OUTPUT or die "$file: cannot flush new file: $!\n";
104 unless (link ($file, "$file.OLD")) {
105 rename ($file, "$file.OLD")
106 or die "$file: cannot rename to $file.OLD: $!\n";
109 if (defined ($user) && defined ($group)) {
110 chown ($user, $group, "$file.new.$$")
111 or warn "$file: cannot chown $file.new.$$: $!\n";
113 warn "$file: cannot find owner and group of $file\n";
116 rename ("$file.new.$$", $file)
117 or die "$file: cannot replace with $file.new.$$: $!\n";
121 # Upgrade a directory. Scan the directory for files that have upgrade rules
122 # defined and for each one of those, try running the upgrade rule.
123 sub upgrade_directory {
124 my $directory = shift;
125 chdir $directory or die "Can't chdir to $directory: $!\n";
126 opendir (DIR, ".") or die "Can't opendir $directory: $!\n";
129 upgrade_file ($_, $FIXES{$_});
136 # The main routine. Parse command-line options to figure out what we're
139 Getopt::Long::config ('bundling');
140 GetOptions ('file|f=s' => \$file,
141 'type|t=s' => \$type) or exit 1;
143 my $basename = $file;
144 $basename =~ s%.*/%%;
146 if (!$FIXES{$type}) { die "No upgrade rules defined for $basename\n" }
147 upgrade_file ($file, $FIXES{$type});
149 if (@ARGV != 1) { die "Usage: innupgrade <directory>\n" }
150 my $directory = shift;
151 upgrade_directory ($directory);