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
18opendir(DIR, $wadir);
19foreach $f (readdir(DIR)) {
20	if (readlink("$wadir/$f")) {
21		@st = stat("$wadir/$f");
22		push(@{$clone{$st[1]}}, $f);
23		}
24	}
25closedir(DIR);
26
27# For each module, copy its config to itself and all clones
28@mods = @ARGV[4..$#ARGV];
29foreach $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	}
114print join(" ", @newmods),"\n";
115
116# read_file(file, array)
117# Fill an associative array with name=value pairs from a file
118sub read_file
119{
120local($arr);
121$arr = $_[1];
122open(ARFILE, "<".$_[0]) || return 0;
123while(<ARFILE>) {
124	s/\r|\n//g;
125        if (!/^#/ && /^([^=]+)=(.*)$/) { $$arr{$1} = $2; }
126        }
127close(ARFILE);
128return 1;
129}
130
131# write_file(file, array)
132# Write out the contents of an associative array as name=value lines
133sub write_file
134{
135local($arr);
136$arr = $_[1];
137open(ARFILE, ">".$_[0]);
138foreach $k (keys %$arr) {
139        print ARFILE "$k=$$arr{$k}\n";
140        }
141close(ARFILE);
142}
143