Handle hostnames with upper-case letters
[webmin.git] / copyconfig.pl
1 #!/usr/local/bin/perl
2 # copyconfig.pl
3 # Copy the appropriate config file for each module into the webmin config
4 # directory. If it is already there, merge in new directives. Called with
5 # <osname> <osversion> <install dir> <config dir> <module>+
6
7 @ARGV >= 4 || die "usage: copyconfig.pl <os>[/real-os] <version>[/real-version] <webmin-dir> <config-dir> [module ...]";
8 $os = $ARGV[0];
9 $ver = $ARGV[1];
10 $wadir = $ARGV[2];
11 $confdir = $ARGV[3];
12 ($os, $real_os) = split(/\//, $os);
13 ($ver, $real_ver) = split(/\//, $ver);
14 $real_os =~ s/ /-/g;
15 $real_ver =~ s/ /-/g;
16
17 # Find all clones
18 opendir(DIR, $wadir);
19 foreach $f (readdir(DIR)) {
20         if (readlink("$wadir/$f")) {
21                 @st = stat("$wadir/$f");
22                 push(@{$clone{$st[1]}}, $f);
23                 }
24         }
25 closedir(DIR);
26
27 # For each module, copy its config to itself and all clones
28 @mods = @ARGV[4..$#ARGV];
29 foreach $m (@mods) {
30         # Find any range-number config files. Search first by real OS type
31         # (ie Ubuntu 6.1), then by internal OS code (ie. debian-linux 3.1)
32         $srcdir = "$wadir/$m";
33         $rangefile = $real_rangefile = undef;
34         foreach $ov ([ $real_os, $real_ver, \$real_rangefile ],
35                      [ $os, $ver, \$rangefile ]) {
36                 my ($o, $v, $rf) = @$ov;
37                 opendir(DIR, $srcdir);
38                 while($f = readdir(DIR)) {
39                         if ($f =~ /^config\-\Q$o\E\-([0-9\.]+)\-([0-9\.]+)$/ &&
40                             $v >= $1 && $v <= $2) {
41                                 $$rf = "$srcdir/$f";
42                                 }
43                         elsif ($f =~ /^config\-\Q$o\E\-([0-9\.]+)\-(\*|ALL)$/ &&
44                                $v >= $1) {
45                                 $$rf = "$srcdir/$f";
46                                 }
47                         elsif ($f =~ /^config\-\Q$o\E\-(\*|ALL)\-([0-9\.]+)$/ &&
48                                $v <= $2) {
49                                 $$rf = "$srcdir/$f";
50                                 }
51                         }
52                 closedir(DIR);
53                 }
54
55         # Find the best-matching config file. Search first by real OS type,
56         # then by internal OS code
57
58         # Check for real OS match by name and version, version range, or
59         # name only
60         if (-r "$srcdir/config-$real_os-$real_ver") {
61                 $conf = "$srcdir/config-$real_os-$real_ver";
62                 }
63         elsif ($real_rangefile) {
64                 $conf = $real_rangefile;
65                 }
66         elsif (-r "$srcdir/config-$real_os") {
67                 $conf = "$srcdir/config-$real_os";
68                 }
69
70         # Check for OS code match by name and version, version range, or name
71         elsif (-r "$srcdir/config-$os-$ver") {
72                 $conf = "$srcdir/config-$os-$ver";
73                 }
74         elsif ($rangefile) {
75                 $conf = $rangefile;
76                 }
77         elsif (-r "$srcdir/config-$os") {
78                 $conf = "$srcdir/config-$os";
79                 }
80
81         # Check for config for an entire OS class, like *-linux
82         elsif ($os =~ /^(\S+)-(\S+)$/ && -r "$srcdir/config-ALL-$2") {
83                 $conf = "$srcdir/config-ALL-$2";
84                 }
85         elsif ($os =~ /^(\S+)-(\S+)$/ && -r "$srcdir/config-*-$2") {
86                 $conf = "$srcdir/config-*-$2";
87                 }
88
89         # Use default config file, if it exists
90         elsif (-r "$srcdir/config") {
91                 $conf = "$srcdir/config";
92                 }
93         else {
94                 $conf = "/dev/null";
95                 }
96
97         @st = stat($srcdir);
98         @copyto = ( @{$clone{$st[1]}}, $m );
99         foreach $c (@copyto) {
100                 if (!-d "$confdir/$c") {
101                         # New module .. need to create config dir
102                         mkdir("$confdir/$c", 0755);
103                         push(@newmods, $c);
104                         }
105                 undef(%oldconf); undef(%newconf);
106                 &read_file("$confdir/$c/config", \%oldconf);
107                 &read_file($conf, \%newconf);
108                 foreach $k (keys %oldconf) {
109                         $newconf{$k} = $oldconf{$k};
110                         }
111                 &write_file("$confdir/$c/config", \%newconf);
112                 }
113         }
114 print join(" ", @newmods),"\n";
115
116 # read_file(file, array)
117 # Fill an associative array with name=value pairs from a file
118 sub read_file
119 {
120 local($arr);
121 $arr = $_[1];
122 open(ARFILE, $_[0]) || return 0;
123 while(<ARFILE>) {
124         s/\r|\n//g;
125         if (!/^#/ && /^([^=]+)=(.*)$/) { $$arr{$1} = $2; }
126         }
127 close(ARFILE);
128 return 1;
129 }
130  
131 # write_file(file, array)
132 # Write out the contents of an associative array as name=value lines
133 sub write_file
134 {
135 local($arr);
136 $arr = $_[1];
137 open(ARFILE, "> $_[0]");
138 foreach $k (keys %$arr) {
139         print ARFILE "$k=$$arr{$k}\n";
140         }
141 close(ARFILE);
142 }