Ticket #770: update-apachemodules.pl

File update-apachemodules.pl, 6.8 KB (added by bchesneau@…, 21 years ago)

files/update-apachemodules.pl

Line 
1#!/opt/local/bin/perl
2#
3# update-apachemodules.pl - Apache module installation for darwinports
4# Copyright (C) Benoit Chesneau <bchesneau@mac.com>
5
6# This program is free software; you can redistribute it and/or
7# modify it under the terms of the GNU General Public License
8# as published by the Free Software Foundation; either version 2
9# of the License, or (at your option) any later version.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19#
20#
21
22
23
24
25require 5.003;
26use strict;
27no strict 'vars';
28
29
30#
31# config var
32#
33
34my      $prefix                 =       "__PREFIX";
35my      $modules_path   =       "libexec/__NAME";
36my      $modulesd_path  =       "etc/__NAME/modules.d";
37my      $config_path    =       "etc/__NAME";
38my      $config_file    =       "httpd.conf";
39
40
41#
42# main
43#
44
45my $file='';
46my %modconf;
47my @lmd = ();
48my @amd = ();
49my @imd = ();
50
51
52
53#parse files
54opendir (REP, "$prefix/$modulesd_path") or die " $modulesd_path doesn't exist";
55while (defined ($file = readdir(REP))) {
56        next if $file=~ /^\.\.?$/;
57        %modconf = parse_conffile($file);
58       
59        if ($modconf{'name'}) {
60               
61                my $cname='';
62                if ((!$modconf{'cname'}) || ($modconf{'cname'} eq '')) {
63                        $cname='mod_' . $modconf{'name'} . '.c';
64                } else {
65                        $cname=$modconf{'cname'};
66                }
67               
68                if (($modconf{'load'}) && ($modconf{'load'} eq 'no')) {
69                        push (@lmd, sprintf('#LoadModule %-18s %s', $modconf{'name'} . "_module",  "$modules_path/" . $modconf{'dso_name'} . ".so"));
70                        push (@amd, sprintf('#AddModule %s', $cname));
71                } else {
72                        push (@lmd, sprintf('LoadModule %-18s %s',$modconf{'name'} . "_module", "$modules_path/" . $modconf{'dso_name'} . ".so"));
73                        push (@amd, sprintf('AddModule %s', $cname));
74                }
75               
76                if ($modconf{'conf_file'}) {
77                        push (@imd, sprintf("Include '$prefix/$config_path/extras-conf/%s'", $modconf{'conf_file'}));
78                }
79        }
80               
81       
82        print "Parsed " . $modconf{"name"} . "\n";
83}
84closedir (REP);
85
86
87# activate modules (code based on apache apxs)
88
89if (not -f "$prefix/$config_path/$config_file") {
90        print STDERR "Error: Config file $config_file not foud!\n";
91        exit(1);
92}
93
94open (FP, "< $prefix/$config_path/$config_file") or die "can't open $config_file \n";
95my $content = join ('', <FP>);
96close (FP);
97
98if ($content !~ m|\n#?\s*LoadModule\s+|) {
99        print STDERR "Error: Activation failed for custom $config_file file.\n";
100        print STDERR "Error: At least one `LoadModule' directive already has to exist.\n";
101        exit(1);
102}
103
104foreach $lmd (@lmd) {
105       
106        print $lmd . "\n";
107        if (substr($lmd,0,1) eq "#") {
108                substr($lmd, 0, 1) = "";
109                $c = '#';
110        }
111       
112       
113        if ($content !~ m|\n#?\s*$lmd|) {
114                # check for open <containers>, so that the new LoadModule
115                # directive always appears *outside* of an <container>.
116
117                my $before = ($content =~ m|^(.*\n)#?\s*LoadModule\s+[^\n]+\n|s)[0];
118
119                # the '()=' trick forces list context and the scalar
120                # assignment counts the number of list members (aka number
121                # of matches) then
122                my $cntopen = () = ($before =~ m|^\s*<[^/].*$|mg);
123                my $cntclose = () = ($before =~ m|^\s*</.*$|mg);
124
125                if ($cntopen == $cntclose) {
126                    # fine. Last LoadModule is contextless.
127                    $content =~ s|^(.*\n#?\s*LoadModule\s+[^\n]+\n)|$1$c$lmd\n|s;
128                } elsif ($cntopen < $cntclose) {
129                    print STDERR 'Configuration file is not valid. There are '
130                                 . "sections closed before opened.\n";
131                    exit(1);
132                } else {
133                    # put our cmd after the section containing the last
134                    # LoadModule.
135                    my $found =
136                    $content =~ s!\A (               # string and capture start
137                                  (?:(?:
138                                    ^\s*             # start of conf line with a
139                                    (?:[^<]|<[^/])   # directive which does not
140                                                     # start with '</'
141
142                                    .*(?:$)\n        # rest of the line.
143                                                     # the '$' is in parentheses
144                                                     # to avoid misinterpreting
145                                                     # the string "$\" as
146                                                     # perl variable.
147
148                                    )*               # catch as much as possible
149                                                     # of such lines. (including
150                                                     # zero)
151
152                                    ^\s*</.*(?:$)\n? # after the above, we
153                                                     # expect a config line with
154                                                     # a closing container (</)
155
156                                  ) {$cntopen}       # the whole pattern (bunch
157                                                     # of lines that end up with
158                                                     # a closing directive) must
159                                                     # be repeated $cntopen
160                                                     # times. That's it.
161                                                     # Simple, eh? ;-)
162
163                                  )               # capture end
164                                 !$1$c$lmd\n!mx;
165
166                    unless ($found) {
167                        print STDERR 'Configuration file is not valid. There '
168                                     . "are sections opened and not closed.\n";
169                        exit(1);
170                    }
171                }
172        } else {
173                # replace already existing LoadModule line
174                $content =~ s|^(.*\n)#?\s*$lmd[^\n]*\n|$1$c$lmd\n|s;
175    }
176        $lmd =~ m|LoadModule\s+(.+?)_module.*|;
177    #print STDERR "[$what module `$1' in $config_file]\n";
178       
179}
180
181my $amd;
182foreach $amd (@amd) {
183        if (substr($amd,0,1) eq "#") {
184                substr($amd, 0, 1) = "";
185                $c = '#';
186        }
187       
188        if ($content !~ m|\n#?\s*$amd|) {
189                # check for open <containers> etc. see above for explanations.
190
191                my $before = ($content =~ m|^(.*\n)#?\s*AddModule\s+[^\n]+\n|s)[0];
192                my $cntopen = () = ($before =~ m|^\s*<[^/].*$|mg);
193                my $cntclose = () = ($before =~ m|^\s*</.*$|mg);
194
195                if ($cntopen == $cntclose) {
196                    $content =~ s|^(.*\n#?\s*AddModule\s+[^\n]+\n)|$1$c$amd\n|s;
197                } elsif ($cntopen < $cntclose) {
198                    # cannot happen here, but who knows ...
199                    print STDERR 'Configuration file is not valid. There are '
200                                 . "sections closed before opened.\n";
201                    exit(1);
202                } else {
203                    unless ($content =~ s!\A((?:(?:^\s*(?:[^<]|<[^/]).*(?:$)\n)*
204                                          ^\s*</.*(?:$)\n?){$cntopen})
205                                         !$1$c$amd\n!mx) {
206                        # cannot happen here, anyway.
207                        print STDERR 'Configuration file is not valid. There '
208                                     . "are sections opened and not closed.\n";
209                        exit(1);
210                    }
211                }
212        } else {
213                # replace already existing AddModule line
214                $content =~ s|^(.*\n)#?\s*$amd[^\n]*\n|$1$c$amd\n|s;
215        }
216}
217       
218
219my $imd;
220foreach $imd (@imd) {
221        if ($content !~ m|\n#?\s*$imd|) {
222                $content .= $imd;
223        }
224}
225
226
227       
228       
229if (@lmd or @amd) {
230        if (open(FP, "> $prefix/$config_path/$config_file.new")) {
231                print FP $content;
232                close(FP);
233               
234                system ("cp $prefix/$config_path/$config_file $prefix/$config_path/$config_file.bak");
235                system ("cp $prefix/$config_path/$config_file.new $prefix/$config_path/$config_file");
236                #push(@cmds, "del \"$prefix/$config_path/$config_file.new\"");
237        } else {
238            print STDERR "Error: unable to open configuration file\n";
239    }
240}
241#
242# subs
243#
244
245
246sub parse_conffile () {
247        $file = shift;
248        my %data;
249       
250        open (CONFFILE, "$prefix/$modulesd_path/$file") or die "can't open $file \n";
251        while (<CONFFILE>) {
252                chomp;
253                s/#.*//;
254                s/^\s+//;
255                s/\s+$//;
256                next unless length;
257                my ($k,$v) = split(/\s*=\s*/,$_, 2);
258                $data{$k}=$v;
259        }
260        close (CONFFILE)        ;
261        return %data;   
262                       
263}
264
265
266