Filename | /var/www/foswikidev/core/lib/Foswiki/Configure/Load.pm |
Statements | Executed 4581 statements in 20.2ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
876 | 1 | 1 | 8.95ms | 12.1ms | _expandValue (recurses: max depth 5, inclusive time 23.8ms) | Foswiki::Configure::Load::
1 | 1 | 1 | 8.30ms | 20.7ms | readConfig | Foswiki::Configure::Load::
1 | 1 | 1 | 4.49ms | 32.8ms | BEGIN@26 | Foswiki::Configure::Load::
1 | 1 | 1 | 4.31ms | 7.29ms | BEGIN@24 | Foswiki::Configure::Load::
1 | 1 | 1 | 4.02ms | 8.75ms | BEGIN@21 | Foswiki::Configure::Load::
876 | 4 | 2 | 2.45ms | 12.2ms | expandValue (recurses: max depth 5, inclusive time 26.2ms) | Foswiki::Configure::Load::
1 | 1 | 1 | 1.78ms | 1.96ms | BEGIN@22 | Foswiki::Configure::Load::
34 | 1 | 1 | 762µs | 762µs | _handleExpand | Foswiki::Configure::Load::
1 | 1 | 1 | 19µs | 39µs | BEGIN@17 | Foswiki::Configure::Load::
1 | 1 | 1 | 15µs | 42µs | BEGIN@19 | Foswiki::Configure::Load::
1 | 1 | 1 | 13µs | 21µs | BEGIN@18 | Foswiki::Configure::Load::
1 | 1 | 1 | 12µs | 46µs | BEGIN@20 | Foswiki::Configure::Load::
1 | 1 | 1 | 12µs | 12µs | _workOutOS | Foswiki::Configure::Load::
1 | 1 | 1 | 11µs | 48µs | BEGIN@29 | Foswiki::Configure::Load::
1 | 1 | 1 | 8µs | 8µs | BEGIN@23 | Foswiki::Configure::Load::
0 | 0 | 0 | 0s | 0s | _bootstrapSiteSettings | Foswiki::Configure::Load::
0 | 0 | 0 | 0s | 0s | _bootstrapStoreSettings | Foswiki::Configure::Load::
0 | 0 | 0 | 0s | 0s | bootstrapConfig | Foswiki::Configure::Load::
0 | 0 | 0 | 0s | 0s | bootstrapWebSettings | Foswiki::Configure::Load::
0 | 0 | 0 | 0s | 0s | expanded | Foswiki::Configure::Load::
0 | 0 | 0 | 0s | 0s | findDependencies | Foswiki::Configure::Load::
0 | 0 | 0 | 0s | 0s | setBootstrap | Foswiki::Configure::Load::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # See bottom of file for license and copyright information | ||||
2 | |||||
3 | =begin TML | ||||
4 | |||||
5 | ---+ package Foswiki::Configure::Load | ||||
6 | |||||
7 | Handling for loading configuration information (Foswiki.spec, Config.spec and | ||||
8 | LocalSite.cfg) as efficiently and flexibly as possible. | ||||
9 | |||||
10 | This reads *values* from these files and does *not* parse the | ||||
11 | structured comments or build a spec database. For that, see LoadSpec.pm | ||||
12 | |||||
13 | =cut | ||||
14 | |||||
15 | package Foswiki::Configure::Load; | ||||
16 | |||||
17 | 2 | 40µs | 2 | 58µs | # spent 39µs (19+19) within Foswiki::Configure::Load::BEGIN@17 which was called:
# once (19µs+19µs) by Foswiki::BEGIN@53 at line 17 # spent 39µs making 1 call to Foswiki::Configure::Load::BEGIN@17
# spent 19µs making 1 call to strict::import |
18 | 2 | 41µs | 2 | 28µs | # spent 21µs (13+7) within Foswiki::Configure::Load::BEGIN@18 which was called:
# once (13µs+7µs) by Foswiki::BEGIN@53 at line 18 # spent 21µs making 1 call to Foswiki::Configure::Load::BEGIN@18
# spent 7µs making 1 call to warnings::import |
19 | 2 | 37µs | 2 | 70µs | # spent 42µs (15+28) within Foswiki::Configure::Load::BEGIN@19 which was called:
# once (15µs+28µs) by Foswiki::BEGIN@53 at line 19 # spent 42µs making 1 call to Foswiki::Configure::Load::BEGIN@19
# spent 28µs making 1 call to Exporter::import |
20 | 2 | 34µs | 2 | 79µs | # spent 46µs (12+33) within Foswiki::Configure::Load::BEGIN@20 which was called:
# once (12µs+33µs) by Foswiki::BEGIN@53 at line 20 # spent 46µs making 1 call to Foswiki::Configure::Load::BEGIN@20
# spent 33µs making 1 call to Exporter::import |
21 | 2 | 132µs | 2 | 8.80ms | # spent 8.75ms (4.02+4.73) within Foswiki::Configure::Load::BEGIN@21 which was called:
# once (4.02ms+4.73ms) by Foswiki::BEGIN@53 at line 21 # spent 8.75ms making 1 call to Foswiki::Configure::Load::BEGIN@21
# spent 52µs making 1 call to Exporter::import |
22 | 2 | 199µs | 2 | 1.99ms | # spent 1.96ms (1.78+173µs) within Foswiki::Configure::Load::BEGIN@22 which was called:
# once (1.78ms+173µs) by Foswiki::BEGIN@53 at line 22 # spent 1.96ms making 1 call to Foswiki::Configure::Load::BEGIN@22
# spent 38µs making 1 call to Exporter::import |
23 | 2 | 34µs | 1 | 8µs | # spent 8µs within Foswiki::Configure::Load::BEGIN@23 which was called:
# once (8µs+0s) by Foswiki::BEGIN@53 at line 23 # spent 8µs making 1 call to Foswiki::Configure::Load::BEGIN@23 |
24 | 2 | 141µs | 2 | 8.47ms | # spent 7.29ms (4.31+2.98) within Foswiki::Configure::Load::BEGIN@24 which was called:
# once (4.31ms+2.98ms) by Foswiki::BEGIN@53 at line 24 # spent 7.29ms making 1 call to Foswiki::Configure::Load::BEGIN@24
# spent 1.17ms making 1 call to POSIX::import |
25 | |||||
26 | 2 | 141µs | 1 | 32.8ms | # spent 32.8ms (4.49+28.3) within Foswiki::Configure::Load::BEGIN@26 which was called:
# once (4.49ms+28.3ms) by Foswiki::BEGIN@53 at line 26 # spent 32.8ms making 1 call to Foswiki::Configure::Load::BEGIN@26 |
27 | |||||
28 | # Enable to trace auto-configuration (Bootstrap) | ||||
29 | 2 | 3.58ms | 2 | 84µs | # spent 48µs (11+37) within Foswiki::Configure::Load::BEGIN@29 which was called:
# once (11µs+37µs) by Foswiki::BEGIN@53 at line 29 # spent 48µs making 1 call to Foswiki::Configure::Load::BEGIN@29
# spent 36µs making 1 call to constant::import |
30 | |||||
31 | # This should be the one place in Foswiki that knows the syntax of valid | ||||
32 | # configuration item keys. Only simple scalar hash keys are supported. | ||||
33 | # | ||||
34 | 1 | 7µs | our $ITEMREGEX = qr/(?:\{(?:'(?:\\.|[^'])+'|"(?:\\.|[^"])+"|[A-Za-z0-9_]+)\})+/; | ||
35 | |||||
36 | # Generic booleans, used in some older LSC's | ||||
37 | 1 | 400ns | our $TRUE = 1; | ||
38 | 1 | 200ns | our $FALSE = 0; | ||
39 | |||||
40 | # Configuration items that have been deprecated and must be mapped to | ||||
41 | # new configuration items. The value is mapped unchanged. | ||||
42 | 1 | 6µs | our %remap = ( | ||
43 | '{StoreImpl}' => '{Store}{Implementation}', | ||||
44 | '{AutoAttachPubFiles}' => '{RCS}{AutoAttachPubFiles}', | ||||
45 | '{QueryAlgorithm}' => '{Store}{QueryAlgorithm}', | ||||
46 | '{SearchAlgorithm}' => '{Store}{SearchAlgorithm}', | ||||
47 | '{Site}{CharSet}' => '{Store}{Encoding}', | ||||
48 | '{RCS}{FgrepCmd}' => '{Store}{FgrepCmd}', | ||||
49 | '{RCS}{EgrepCmd}' => '{Store}{EgrepCmd}', | ||||
50 | '{RCS}{overrideUmask}' => '{Store}{overrideUmask}', | ||||
51 | '{RCS}{dirPermission}' => '{Store}{dirPermission}', | ||||
52 | '{RCS}{filePermission}' => '{Store}{filePermission}', | ||||
53 | '{RCS}{WorkAreaDir}' => '{Store}{WorkAreaDir}' | ||||
54 | ); | ||||
55 | |||||
56 | # spent 12µs within Foswiki::Configure::Load::_workOutOS which was called:
# once (12µs+0s) by Foswiki::Configure::Load::readConfig at line 148 | ||||
57 | 1 | 600ns | unless ( $Foswiki::cfg{DetailedOS} ) { | ||
58 | 1 | 5µs | $Foswiki::cfg{DetailedOS} = $^O; | ||
59 | 1 | 500ns | unless ( $Foswiki::cfg{DetailedOS} ) { | ||
60 | |||||
61 | # SMELL: the perlvar doc for $^O says "The value is identical | ||||
62 | # to $Config{'osname'}" so this would appear redundant. | ||||
63 | require Config; | ||||
64 | $Foswiki::cfg{DetailedOS} = $Config::Config{'osname'}; | ||||
65 | |||||
66 | # SMELL: is it really worth continuing if we still can't | ||||
67 | # work it out? Proceed with a null string unless someone knows | ||||
68 | # better. | ||||
69 | } | ||||
70 | } | ||||
71 | 1 | 300ns | return if $Foswiki::cfg{OS}; | ||
72 | 1 | 9µs | if ( $Foswiki::cfg{DetailedOS} =~ m/darwin/i ) { # MacOS X | ||
73 | $Foswiki::cfg{OS} = 'UNIX'; | ||||
74 | } | ||||
75 | elsif ( $Foswiki::cfg{DetailedOS} =~ m/Win/i ) { | ||||
76 | $Foswiki::cfg{OS} = 'WINDOWS'; | ||||
77 | } | ||||
78 | elsif ( $Foswiki::cfg{DetailedOS} =~ m/vms/i ) { | ||||
79 | $Foswiki::cfg{OS} = 'VMS'; | ||||
80 | } | ||||
81 | elsif ( $Foswiki::cfg{DetailedOS} =~ m/bsdos/i ) { | ||||
82 | $Foswiki::cfg{OS} = 'UNIX'; | ||||
83 | } | ||||
84 | elsif ( $Foswiki::cfg{DetailedOS} =~ m/solaris/i ) { | ||||
85 | $Foswiki::cfg{OS} = 'UNIX'; | ||||
86 | } | ||||
87 | elsif ( $Foswiki::cfg{DetailedOS} =~ m/dos/i ) { | ||||
88 | $Foswiki::cfg{OS} = 'DOS'; | ||||
89 | } | ||||
90 | elsif ( $Foswiki::cfg{DetailedOS} =~ m/^MacOS$/i ) { | ||||
91 | |||||
92 | # MacOS 9 or earlier | ||||
93 | $Foswiki::cfg{OS} = 'MACINTOSH'; | ||||
94 | } | ||||
95 | elsif ( $Foswiki::cfg{DetailedOS} =~ m/os2/i ) { | ||||
96 | $Foswiki::cfg{OS} = 'OS2'; | ||||
97 | } | ||||
98 | else { | ||||
99 | |||||
100 | # Erm..... | ||||
101 | 1 | 800ns | $Foswiki::cfg{OS} = 'UNIX'; | ||
102 | } | ||||
103 | } | ||||
104 | |||||
105 | =begin TML | ||||
106 | |||||
107 | ---++ StaticMethod readConfig([$noexpand][,$nospec][,$config_spec][,$noLocal) | ||||
108 | |||||
109 | In normal Foswiki operations as a web server this method is called by the | ||||
110 | =BEGIN= block of =Foswiki.pm=. However, when benchmarking/debugging it can be | ||||
111 | replaced by custom code which sets the configuration hash. To prevent us from | ||||
112 | overriding the custom code again, we use an "unconfigurable" key | ||||
113 | =$cfg{ConfigurationFinished}= as an indicator. | ||||
114 | |||||
115 | Note that this method is called by Foswiki and configure, and normally reads | ||||
116 | =Foswiki.spec= to get defaults. Other spec files (those for extensions) are | ||||
117 | *not* read unless the $config_spec flag is set. | ||||
118 | |||||
119 | The assumption is that =configure= will be run when an extension is installed, | ||||
120 | and that will add the config values to LocalSite.cfg, so no defaults are | ||||
121 | needed. Foswiki.spec is still read because so much of the core code doesn't | ||||
122 | provide defaults, and it would be silly to have them in two places anyway. | ||||
123 | |||||
124 | * =$noexpand= - suppress expansion of $Foswiki vars embedded in | ||||
125 | values. | ||||
126 | * =$nospec= - can be set when the caller knows that Foswiki.spec | ||||
127 | has already been read. | ||||
128 | * =$config_spec= - if set, will also read Config.spec files located | ||||
129 | using the standard methods (iff !$nospec). Slow. | ||||
130 | * =$noLocal= - if set, Load will not re-read an existing LocalSite.cfg. | ||||
131 | this is needed when testing the bootstrap. If it rereads an existing | ||||
132 | config, it overlays all the bootstrapped settings. | ||||
133 | =cut | ||||
134 | |||||
135 | # spent 20.7ms (8.30+12.4) within Foswiki::Configure::Load::readConfig which was called:
# once (8.30ms+12.4ms) by Foswiki::BEGIN@176 at line 355 of /var/www/foswikidev/core/lib/Foswiki.pm | ||||
136 | 1 | 900ns | my ( $noexpand, $nospec, $config_spec, $noLocal ) = @_; | ||
137 | |||||
138 | # To prevent us from overriding the custom code in test mode | ||||
139 | 1 | 600ns | return 1 if $Foswiki::cfg{ConfigurationFinished}; | ||
140 | |||||
141 | # Assume LocalSite.cfg is valid - will be set false if errors detected. | ||||
142 | 1 | 200ns | my $validLSC = 1; | ||
143 | |||||
144 | # Read Foswiki.spec and LocalSite.cfg | ||||
145 | # (Suppress Foswiki.spec if already read) | ||||
146 | |||||
147 | # Old configs might not bootstrap the OS settings, so set if needed. | ||||
148 | 1 | 2µs | 1 | 12µs | _workOutOS() unless ( $Foswiki::cfg{OS} && $Foswiki::cfg{DetailedOS} ); # spent 12µs making 1 call to Foswiki::Configure::Load::_workOutOS |
149 | |||||
150 | 1 | 200ns | my @files; | ||
151 | 1 | 800ns | unless ($nospec) { | ||
152 | push @files, 'Foswiki.spec'; | ||||
153 | } | ||||
154 | 1 | 400ns | if ( !$nospec && $config_spec ) { | ||
155 | foreach my $dir (@INC) { | ||||
156 | foreach my $subdir ( 'Foswiki/Plugins', 'Foswiki/Contrib' ) { | ||||
157 | my $d; | ||||
158 | next unless opendir( $d, "$dir/$subdir" ); | ||||
159 | my %read; | ||||
160 | foreach | ||||
161 | my $extension ( grep { !/^\./ && !/^Empty/ } readdir $d ) | ||||
162 | { | ||||
163 | next if $read{$extension}; | ||||
164 | $extension =~ m/(.*)/; # untaint | ||||
165 | my $file = "$dir/$subdir/$1/Config.spec"; | ||||
166 | next unless -e $file; | ||||
167 | push( @files, $file ); | ||||
168 | $read{$extension} = 1; | ||||
169 | } | ||||
170 | closedir($d); | ||||
171 | } | ||||
172 | } | ||||
173 | } | ||||
174 | 1 | 500ns | unless ($noLocal) { | ||
175 | push @files, 'LocalSite.cfg'; | ||||
176 | } | ||||
177 | |||||
178 | 1 | 1µs | for my $file (@files) { | ||
179 | 2 | 3.30ms | my $return = do $file; | ||
180 | |||||
181 | 2 | 5µs | unless ( defined $return && $return eq '1' ) { | ||
182 | |||||
183 | my $errorMessage; | ||||
184 | if ($@) { | ||||
185 | $errorMessage = "Failed to parse $file: $@"; | ||||
186 | warn "couldn't parse $file: $@" if $@; | ||||
187 | } | ||||
188 | next if ( !DEBUG && ( $file =~ m/Config\.spec$/ ) ); | ||||
189 | if ( not defined $return ) { | ||||
190 | unless ( $! == 2 && $file eq 'LocalSite.cfg' ) { | ||||
191 | |||||
192 | # LocalSite.cfg doesn't exist, which is OK | ||||
193 | warn "couldn't do $file: $!"; | ||||
194 | $errorMessage = "Could not do $file: $!"; | ||||
195 | } | ||||
196 | $validLSC = 0; | ||||
197 | } | ||||
198 | |||||
199 | # Pointless (says CDot), Config.spec does not need 1; at the end | ||||
200 | #elsif ( not $return eq '1' ) { | ||||
201 | # print STDERR | ||||
202 | # "Running file $file returned unexpected results: $return \n"; | ||||
203 | #} | ||||
204 | if ($errorMessage) { | ||||
205 | die <<GOLLYGOSH; | ||||
206 | Content-type: text/plain | ||||
207 | |||||
208 | $errorMessage | ||||
209 | Please inform the site admin. | ||||
210 | GOLLYGOSH | ||||
211 | exit 1; | ||||
212 | } | ||||
213 | } | ||||
214 | } | ||||
215 | |||||
216 | # Patch deprecated config settings | ||||
217 | # TODO: remove this in version 2.0 | ||||
218 | 1 | 500ns | if ( exists $Foswiki::cfg{StoreImpl} ) { | ||
219 | $Foswiki::cfg{Store}{Implementation} = | ||||
220 | 'Foswiki::Store::' . $Foswiki::cfg{StoreImpl}; | ||||
221 | delete $Foswiki::cfg{StoreImpl}; | ||||
222 | } | ||||
223 | 1 | 4µs | foreach my $el ( keys %remap ) { | ||
224 | |||||
225 | # Only remap if the old key extsts, and the new key does NOT exist | ||||
226 | 11 | 323µs | if ( ( eval("exists \$Foswiki::cfg$el") ) ) { # spent 3µs executing statements in string eval
# spent 3µs executing statements in string eval
# spent 2µs executing statements in string eval
# spent 2µs executing statements in string eval
# spent 2µs executing statements in string eval
# spent 2µs executing statements in string eval
# spent 2µs executing statements in string eval
# spent 2µs executing statements in string eval
# spent 2µs executing statements in string eval
# spent 2µs executing statements in string eval
# spent 2µs executing statements in string eval | ||
227 | 1 | 38µs | eval( <<CODE ); # spent 5µs executing statements in string eval | ||
228 | \$Foswiki::cfg$remap{$el}=\$Foswiki::cfg$el unless ( exists \$Foswiki::cfg$remap{$el} ); | ||||
229 | delete \$Foswiki::cfg$el; | ||||
230 | CODE | ||||
231 | 1 | 300ns | print STDERR "REMAP failed $@" if ($@); | ||
232 | } | ||||
233 | } | ||||
234 | |||||
235 | # Expand references to $Foswiki::cfg vars embedded in the values of | ||||
236 | # other $Foswiki::cfg vars. | ||||
237 | 1 | 3µs | 1 | 12.1ms | expandValue( \%Foswiki::cfg ) unless $noexpand; # spent 12.1ms making 1 call to Foswiki::Configure::Load::expandValue |
238 | |||||
239 | 1 | 800ns | $Foswiki::cfg{ConfigurationFinished} = 1; | ||
240 | |||||
241 | 1 | 1µs | if ( $^O eq 'MSWin32' ) { | ||
242 | |||||
243 | #force paths to use '/' | ||||
244 | $Foswiki::cfg{PubDir} =~ s|\\|/|g; | ||||
245 | $Foswiki::cfg{DataDir} =~ s|\\|/|g; | ||||
246 | $Foswiki::cfg{ToolsDir} =~ s|\\|/|g; | ||||
247 | $Foswiki::cfg{ScriptDir} =~ s|\\|/|g; | ||||
248 | $Foswiki::cfg{TemplateDir} =~ s|\\|/|g; | ||||
249 | $Foswiki::cfg{LocalesDir} =~ s|\\|/|g; | ||||
250 | $Foswiki::cfg{WorkingDir} =~ s|\\|/|g; | ||||
251 | } | ||||
252 | |||||
253 | # Alias TWiki cfg to Foswiki cfg for plugins and contribs | ||||
254 | 1 | 1µs | *TWiki::cfg = \%Foswiki::cfg; | ||
255 | |||||
256 | # Add explicit {Site}{CharSet} for older extensions. Default to utf-8. | ||||
257 | # Explanation is in http://foswiki.org/Tasks/Item13435 | ||||
258 | 1 | 800ns | $Foswiki::cfg{Site}{CharSet} = 'utf-8'; | ||
259 | |||||
260 | # Explicit return true if we've completed the load | ||||
261 | 1 | 4µs | return $validLSC; | ||
262 | } | ||||
263 | |||||
264 | =begin TML | ||||
265 | |||||
266 | ---++ StaticMethod expanded($value) -> $expanded | ||||
267 | |||||
268 | Given a value of a configuration item, expand references to | ||||
269 | $Foswiki::cfg configuration items within strings in the value. | ||||
270 | |||||
271 | If an embedded $Foswiki::cfg reference is not defined, it will | ||||
272 | be expanded as 'undef'. | ||||
273 | |||||
274 | =cut | ||||
275 | |||||
276 | sub expanded { | ||||
277 | my $val = shift; | ||||
278 | return undef unless defined $val; | ||||
279 | expandValue($val); | ||||
280 | return $val; | ||||
281 | } | ||||
282 | |||||
283 | =begin TML | ||||
284 | |||||
285 | ---++ StaticMethod expandValue($datum [, $mode]) | ||||
286 | |||||
287 | Expands references to Foswiki configuration items which occur in the | ||||
288 | values configuration items contained within the datum, which may be a | ||||
289 | hash or array reference, or a scalar value. The replacement is done in-place. | ||||
290 | |||||
291 | $mode - How to handle undefined values: | ||||
292 | * false: 'undef' (string) is returned when an undefined value is | ||||
293 | encountered. | ||||
294 | * 1 : return undef if any undefined value is encountered. | ||||
295 | * 2 : return '' for any undefined value (including embedded) | ||||
296 | * 3 : die if an undefined value is encountered. | ||||
297 | |||||
298 | =cut | ||||
299 | |||||
300 | # spent 12.2ms (2.45+9.71) within Foswiki::Configure::Load::expandValue which was called 876 times, avg 14µs/call:
# 788 times (2.20ms+-2.20ms) by Foswiki::Configure::Load::_expandValue at line 312, avg 0s/call
# 86 times (234µs+-234µs) by Foswiki::Configure::Load::_expandValue at line 315, avg 0s/call
# once (4µs+12.1ms) by Foswiki::Configure::Load::readConfig at line 237
# once (7µs+7µs) by Foswiki::Logger::PlainFile::_getLogsForLevel at line 270 of /var/www/foswikidev/core/lib/Foswiki/Logger/PlainFile.pm | ||||
301 | 876 | 74µs | my $undef; | ||
302 | 876 | 646µs | 876 | 12.1ms | _expandValue( $_[0], ( $_[1] || 0 ), $undef ); # spent 35.9ms making 876 calls to Foswiki::Configure::Load::_expandValue, avg 41µs/call, recursion: max depth 5, sum of overlapping time 23.8ms |
303 | |||||
304 | 876 | 6.72ms | $_[0] = undef if ($undef); | ||
305 | } | ||||
306 | |||||
307 | # $_[0] - value being expanded | ||||
308 | # $_[1] - $mode | ||||
309 | # $_[2] - $undef (return) | ||||
310 | # spent 12.1ms (8.95+3.20) within Foswiki::Configure::Load::_expandValue which was called 876 times, avg 14µs/call:
# 876 times (8.95ms+3.20ms) by Foswiki::Configure::Load::expandValue at line 302, avg 14µs/call | ||||
311 | 876 | 1.69ms | if ( ref( $_[0] ) eq 'HASH' ) { | ||
312 | 196 | 1.18ms | 788 | 0s | expandValue( $_, $_[1] ) foreach ( values %{ $_[0] } ); # spent 25.4ms making 788 calls to Foswiki::Configure::Load::expandValue, avg 32µs/call, recursion: max depth 5, sum of overlapping time 25.4ms |
313 | } | ||||
314 | elsif ( ref( $_[0] ) eq 'ARRAY' ) { | ||||
315 | 6 | 102µs | 86 | 0s | expandValue( $_, $_[1] ) foreach ( @{ $_[0] } ); # spent 813µs making 86 calls to Foswiki::Configure::Load::expandValue, avg 9µs/call, recursion: max depth 5, sum of overlapping time 813µs |
316 | |||||
317 | # Can't do this, because Windows uses an object (Regexp) for regular | ||||
318 | # expressions. | ||||
319 | # } elsif (ref($_[0])) { | ||||
320 | # die("Can't handle a ".ref($_[0])); | ||||
321 | } | ||||
322 | else { | ||||
323 | 34 | 50µs | 34 | 762µs | 1 while ( defined( $_[0] ) # spent 762µs making 34 calls to Foswiki::Configure::Load::_handleExpand, avg 22µs/call |
324 | && $_[0] =~ | ||||
325 | 674 | 874µs | s/(\$Foswiki::cfg$ITEMREGEX)/_handleExpand($1, @_[1,2])/ges ); | ||
326 | } | ||||
327 | } | ||||
328 | |||||
329 | # Used to expand the $Foswiki::cfg variable in the expand* routines. | ||||
330 | # $_[0] - $item | ||||
331 | # $_[1] - $mode | ||||
332 | # $_[2] - $undef | ||||
333 | # spent 762µs within Foswiki::Configure::Load::_handleExpand which was called 34 times, avg 22µs/call:
# 34 times (762µs+0s) by Foswiki::Configure::Load::_expandValue at line 323, avg 22µs/call | ||||
334 | 34 | 631µs | my $val = eval( $_[0] ); # spent 34µs executing statements in 14 string evals (merged)
# spent 12µs executing statements in 4 string evals (merged)
# spent 10µs executing statements in 4 string evals (merged)
# spent 9µs executing statements in 4 string evals (merged)
# spent 8µs executing statements in 4 string evals (merged)
# spent 5µs executing statements in 2 string evals (merged)
# spent 3µs executing statements in string eval
# spent 2µs executing statements in string eval | ||
335 | 34 | 5µs | die "Error expanding $_[0]: $@" if ($@); | ||
336 | |||||
337 | 34 | 105µs | return $val if ( defined $val ); | ||
338 | return 'undef' if ( !$_[1] ); | ||||
339 | return '' if ( $_[1] == 2 ); | ||||
340 | die "Undefined value in expanded string $_[0]\n" if ( $_[1] == 3 ); | ||||
341 | $_[2] = 1; | ||||
342 | return ''; | ||||
343 | } | ||||
344 | |||||
345 | =begin TML | ||||
346 | |||||
347 | ---++ StaticMethod setBootstrap() | ||||
348 | |||||
349 | This routine is called to initialize the bootstrap process. It sets the list of | ||||
350 | configuration parameters that will need to be set and "protected" during bootstrap. | ||||
351 | |||||
352 | If any keys will be set during bootstrap / initial creation of LocalSite.cfg, they | ||||
353 | should be added here so that they are preserved when the %Foswiki::cfg hash is | ||||
354 | wiped and re-initialized from the Foswiki spec. | ||||
355 | |||||
356 | =cut | ||||
357 | |||||
358 | sub setBootstrap { | ||||
359 | |||||
360 | # Bootstrap works out the correct values of these keys | ||||
361 | my @BOOTSTRAP = | ||||
362 | qw( {DataDir} {DefaultUrlHost} {DetailedOS} {OS} {PubUrlPath} {ToolsDir} {WorkingDir} | ||||
363 | {PubDir} {TemplateDir} {ScriptDir} {ScriptUrlPath} {ScriptUrlPaths}{view} | ||||
364 | {ScriptSuffix} {LocalesDir} {Store}{Implementation} | ||||
365 | {Store}{SearchAlgorithm} {Site}{Locale} ); | ||||
366 | |||||
367 | $Foswiki::cfg{isBOOTSTRAPPING} = 1; | ||||
368 | push( @{ $Foswiki::cfg{BOOTSTRAP} }, @BOOTSTRAP ); | ||||
369 | } | ||||
370 | |||||
371 | =begin TML | ||||
372 | |||||
373 | ---++ StaticMethod bootstrapConfig() | ||||
374 | |||||
375 | This routine is called from Foswiki.pm BEGIN block to discover the mandatory | ||||
376 | settings for operation when a LocalSite.cfg could not be found. | ||||
377 | |||||
378 | =cut | ||||
379 | |||||
380 | sub bootstrapConfig { | ||||
381 | |||||
382 | print STDERR "AUTOCONFIG: Bootstrap Phase 1: " | ||||
383 | . Data::Dumper::Dumper( \%ENV ) | ||||
384 | if (TRAUTO); | ||||
385 | |||||
386 | # Failed to read LocalSite.cfg | ||||
387 | # Clear out $Foswiki::cfg to allow variable expansion to work | ||||
388 | # when reloading Foswiki.spec et al. | ||||
389 | # SMELL: have to keep {Engine} as this is defined by the | ||||
390 | # script (smells of a hack). | ||||
391 | %Foswiki::cfg = ( Engine => $Foswiki::cfg{Engine} ); | ||||
392 | |||||
393 | # Try to create $Foswiki::cfg in a minimal configuration, | ||||
394 | # using paths and URLs relative to this request. If URL | ||||
395 | # rewriting is happening in the web server this is likely | ||||
396 | # to go down in flames, but it gives us the best chance of | ||||
397 | # recovering. We need to guess values for all the vars that | ||||
398 | |||||
399 | # would trigger "undefined" errors | ||||
400 | my $bin; | ||||
401 | my $script = ''; | ||||
402 | if ( defined $ENV{FOSWIKI_SCRIPTS} ) { | ||||
403 | $bin = $ENV{FOSWIKI_SCRIPTS}; | ||||
404 | } | ||||
405 | else { | ||||
406 | eval('require FindBin'); | ||||
407 | die "Could not load FindBin to support configuration recovery: $@" | ||||
408 | if $@; | ||||
409 | FindBin::again(); # in case we are under mod_perl or similar | ||||
410 | $FindBin::Bin =~ m/^(.*)$/; | ||||
411 | $bin = $1; | ||||
412 | $FindBin::Script =~ m/^(.*)$/; | ||||
413 | $script = $1; | ||||
414 | } | ||||
415 | |||||
416 | print STDERR "AUTOCONFIG: Found Bin dir: " | ||||
417 | . Encode::decode_utf8($bin) | ||||
418 | . ", Script name: $script using FindBin\n" | ||||
419 | if (TRAUTO); | ||||
420 | |||||
421 | $Foswiki::cfg{ScriptSuffix} = ( fileparse( $script, qr/\.[^.]*/ ) )[2]; | ||||
422 | $Foswiki::cfg{ScriptSuffix} = '' | ||||
423 | if ( $Foswiki::cfg{ScriptSuffix} eq '.fcgi' ); | ||||
424 | print STDERR | ||||
425 | "AUTOCONFIG: Found SCRIPT SUFFIX $Foswiki::cfg{ScriptSuffix} \n" | ||||
426 | if ( TRAUTO && $Foswiki::cfg{ScriptSuffix} ); | ||||
427 | |||||
428 | my %rel_to_root = ( | ||||
429 | DataDir => { dir => 'data', required => 0 }, | ||||
430 | LocalesDir => { dir => 'locale', required => 0 }, | ||||
431 | PubDir => { dir => 'pub', required => 0 }, | ||||
432 | ToolsDir => { dir => 'tools', required => 0 }, | ||||
433 | WorkingDir => { | ||||
434 | dir => 'working', | ||||
435 | required => 1, | ||||
436 | validate_file => 'README' | ||||
437 | }, | ||||
438 | TemplateDir => { | ||||
439 | dir => 'templates', | ||||
440 | required => 1, | ||||
441 | validate_file => 'foswiki.tmpl' | ||||
442 | }, | ||||
443 | ScriptDir => { | ||||
444 | dir => 'bin', | ||||
445 | required => 1, | ||||
446 | validate_file => 'setlib.cfg' | ||||
447 | } | ||||
448 | ); | ||||
449 | |||||
450 | # Note that we don't resolve x/../y to y, as this might | ||||
451 | # confuse soft links | ||||
452 | my $root = File::Spec->catdir( $bin, File::Spec->updir() ); | ||||
453 | $root =~ s{\\}{/}g; | ||||
454 | my $fatal = ''; | ||||
455 | my $warn = ''; | ||||
456 | while ( my ( $key, $def ) = each %rel_to_root ) { | ||||
457 | $Foswiki::cfg{$key} = File::Spec->rel2abs( $def->{dir}, $root ); | ||||
458 | $Foswiki::cfg{$key} = abs_path( $Foswiki::cfg{$key} ); | ||||
459 | ( $Foswiki::cfg{$key} ) = $Foswiki::cfg{$key} =~ m/^(.*)$/; # untaint | ||||
460 | |||||
461 | # Need to decode utf8 back to perl characters. The file path operations | ||||
462 | # all worked with bytes, but Foswiki needs characters. | ||||
463 | $Foswiki::cfg{$key} = Encode::decode_utf8( $Foswiki::cfg{$key} ); | ||||
464 | |||||
465 | print STDERR "AUTOCONFIG: $key = $Foswiki::cfg{$key} \n" | ||||
466 | if (TRAUTO); | ||||
467 | |||||
468 | if ( -d $Foswiki::cfg{$key} ) { | ||||
469 | if ( $def->{validate_file} | ||||
470 | && !-e "$Foswiki::cfg{$key}/$def->{validate_file}" ) | ||||
471 | { | ||||
472 | $fatal .= | ||||
473 | "\n{$key} (guessed $Foswiki::cfg{$key}) $Foswiki::cfg{$key}/$def->{validate_file} not found"; | ||||
474 | } | ||||
475 | } | ||||
476 | elsif ( $def->{required} ) { | ||||
477 | $fatal .= "\n{$key} (guessed $Foswiki::cfg{$key})"; | ||||
478 | } | ||||
479 | else { | ||||
480 | $warn .= | ||||
481 | "\n * Note: {$key} could not be guessed. Set it manually!"; | ||||
482 | } | ||||
483 | } | ||||
484 | |||||
485 | # Bootstrap the Site Locale and CharSet | ||||
486 | _bootstrapSiteSettings(); | ||||
487 | |||||
488 | # Bootstrap the store related settings. | ||||
489 | _bootstrapStoreSettings(); | ||||
490 | |||||
491 | if ($fatal) { | ||||
492 | die <<EPITAPH; | ||||
493 | Unable to bootstrap configuration. LocalSite.cfg could not be loaded, | ||||
494 | and Foswiki was unable to guess the locations of the following critical | ||||
495 | directories: $fatal | ||||
496 | EPITAPH | ||||
497 | } | ||||
498 | |||||
499 | # Re-read Foswiki.spec *and Config.spec*. We need the Config.spec's | ||||
500 | # to get a true picture of our defaults (notably those from | ||||
501 | # JQueryPlugin. Without the Config.spec, no plugins get registered) | ||||
502 | # Don't load LocalSite.cfg if it exists (should normally not exist when bootstrapping) | ||||
503 | Foswiki::Configure::Load::readConfig( 0, 0, 1, 1 ); | ||||
504 | |||||
505 | _workOutOS(); | ||||
506 | print STDERR | ||||
507 | "AUTOCONFIG: Detected OS $Foswiki::cfg{OS}: DetailedOS: $Foswiki::cfg{DetailedOS} \n" | ||||
508 | if (TRAUTO); | ||||
509 | |||||
510 | $Foswiki::cfg{isVALID} = 1; | ||||
511 | Foswiki::Configure::Load::setBootstrap(); | ||||
512 | |||||
513 | # Note: message is not I18N'd because there is no point; there | ||||
514 | # is no localisation in a default cfg derived from Foswiki.spec | ||||
515 | my $system_message = <<BOOTS; | ||||
516 | *WARNING !LocalSite.cfg could not be found* (This is normal for a new installation) %BR% | ||||
517 | This Foswiki is running using a bootstrap configuration worked | ||||
518 | out by detecting the layout of the installation. | ||||
519 | BOOTS | ||||
520 | |||||
521 | if ($warn) { | ||||
522 | chomp $system_message; | ||||
523 | $system_message .= $warn . "\n"; | ||||
524 | } | ||||
525 | return ( $system_message || '' ); | ||||
526 | |||||
527 | } | ||||
528 | |||||
529 | =begin TML | ||||
530 | |||||
531 | ---++ StaticMethod _bootstrapSiteSettings() | ||||
532 | |||||
533 | Called by bootstrapConfig. This handles the {Site} settings. | ||||
534 | |||||
535 | =cut | ||||
536 | |||||
537 | sub _bootstrapSiteSettings { | ||||
538 | |||||
539 | # Guess a locale first. This isn't necessarily used, but helps guess a CharSet, which is always used. | ||||
540 | |||||
541 | require locale; | ||||
542 | $Foswiki::cfg{Site}{Locale} = setlocale(LC_CTYPE); | ||||
543 | |||||
544 | print STDERR | ||||
545 | "AUTOCONFIG: Set initial {Site}{Locale} to $Foswiki::cfg{Site}{Locale}\n"; | ||||
546 | } | ||||
547 | |||||
548 | =begin TML | ||||
549 | |||||
550 | ---++ StaticMethod _bootstrapStoreSettings() | ||||
551 | |||||
552 | Called by bootstrapConfig. This handles the store specific settings. This in turn | ||||
553 | tests each Store Contib to determine if it's capable of bootstrapping. | ||||
554 | |||||
555 | =cut | ||||
556 | |||||
557 | sub _bootstrapStoreSettings { | ||||
558 | |||||
559 | # Ask each installed store to bootstrap itself. | ||||
560 | |||||
561 | my @stores = Foswiki::Configure::FileUtil::findPackages( | ||||
562 | 'Foswiki::Contrib::*StoreContrib'); | ||||
563 | |||||
564 | foreach my $store (@stores) { | ||||
565 | eval("require $store"); | ||||
566 | print STDERR $@ if ($@); | ||||
567 | unless ($@) { | ||||
568 | my $ok; | ||||
569 | eval('$ok = $store->can(\'bootstrapStore\')'); | ||||
570 | if ($@) { | ||||
571 | print STDERR $@; | ||||
572 | } | ||||
573 | else { | ||||
574 | $store->bootstrapStore() if ($ok); | ||||
575 | } | ||||
576 | } | ||||
577 | } | ||||
578 | |||||
579 | # Handle the common store settings managed by Core. Important ones | ||||
580 | # guessed/checked here include: | ||||
581 | # - $Foswiki::cfg{Store}{SearchAlgorithm} | ||||
582 | |||||
583 | # Set PurePerl search on Windows, or FastCGI systems. | ||||
584 | if ( | ||||
585 | ( | ||||
586 | $Foswiki::cfg{Engine} | ||||
587 | && $Foswiki::cfg{Engine} =~ m/(FastCGI|Apache)/ | ||||
588 | ) | ||||
589 | || $^O eq 'MSWin32' | ||||
590 | ) | ||||
591 | { | ||||
592 | $Foswiki::cfg{Store}{SearchAlgorithm} = | ||||
593 | 'Foswiki::Store::SearchAlgorithms::PurePerl'; | ||||
594 | print STDERR | ||||
595 | "AUTOCONFIG: Detected FastCGI, mod_perl or MS Windows. {Store}{SearchAlgorithm} set to PurePerl\n" | ||||
596 | if (TRAUTO); | ||||
597 | } | ||||
598 | else { | ||||
599 | |||||
600 | # SMELL: The fork to `grep goes into a loop in the unit tests | ||||
601 | # Not sure why, for now just default to pure perl bootstrapping | ||||
602 | # in the unit tests. | ||||
603 | if ( !$Foswiki::inUnitTestMode ) { | ||||
604 | |||||
605 | # Untaint PATH so we can check for grep on the path | ||||
606 | my $x = $ENV{PATH} || ''; | ||||
607 | $x =~ m/^(.*)$/; | ||||
608 | $ENV{PATH} = $1; | ||||
609 | `grep -V 2>&1`; | ||||
610 | if ($!) { | ||||
611 | print STDERR | ||||
612 | "AUTOCONFIG: Unable to find a valid 'grep' on the path. Forcing PurePerl search\n" | ||||
613 | if (TRAUTO); | ||||
614 | $Foswiki::cfg{Store}{SearchAlgorithm} = | ||||
615 | 'Foswiki::Store::SearchAlgorithms::PurePerl'; | ||||
616 | } | ||||
617 | else { | ||||
618 | $Foswiki::cfg{Store}{SearchAlgorithm} = | ||||
619 | 'Foswiki::Store::SearchAlgorithms::Forking'; | ||||
620 | print STDERR | ||||
621 | "AUTOCONFIG: {Store}{SearchAlgorithm} set to Forking\n" | ||||
622 | if (TRAUTO); | ||||
623 | } | ||||
624 | $ENV{PATH} = $x; # re-taint | ||||
625 | } | ||||
626 | else { | ||||
627 | $Foswiki::cfg{Store}{SearchAlgorithm} = | ||||
628 | 'Foswiki::Store::SearchAlgorithms::PurePerl'; | ||||
629 | } | ||||
630 | } | ||||
631 | } | ||||
632 | |||||
633 | =begin TML | ||||
634 | |||||
635 | ---++ StaticMethod bootstrapWebSettings($script) | ||||
636 | |||||
637 | Called by bootstrapConfig. This handles the web environment specific settings only: | ||||
638 | |||||
639 | * ={DefaultUrlHost}= | ||||
640 | * ={ScriptUrlPath}= | ||||
641 | * ={ScriptUrlPaths}{view}= | ||||
642 | * ={PubUrlPath}= | ||||
643 | |||||
644 | =cut | ||||
645 | |||||
646 | sub bootstrapWebSettings { | ||||
647 | my $script = shift; | ||||
648 | |||||
649 | print STDERR "AUTOCONFIG: Bootstrap Phase 2: " | ||||
650 | . Data::Dumper::Dumper( \%ENV ) | ||||
651 | if (TRAUTO); | ||||
652 | |||||
653 | # Cannot bootstrap the web side from CLI environments | ||||
654 | if ( $Foswiki::cfg{Engine} eq 'Foswiki::Engine::CLI' ) { | ||||
655 | $Foswiki::cfg{DefaultUrlHost} = 'http://localhost'; | ||||
656 | $Foswiki::cfg{ScriptUrlPath} = '/bin'; | ||||
657 | $Foswiki::cfg{PubUrlPath} = '/pub'; | ||||
658 | print STDERR | ||||
659 | "AUTOCONFIG: Bootstrap Phase 2 bypassed! n/a in the CLI Environment\n" | ||||
660 | if (TRAUTO); | ||||
661 | return 'Phase 2 boostrap bypassed - n/a in CLI environment\n'; | ||||
662 | } | ||||
663 | |||||
664 | my $protocol = $ENV{HTTPS} ? 'https' : 'http'; | ||||
665 | |||||
666 | # Figure out the DefaultUrlHost | ||||
667 | if ( $ENV{HTTP_HOST} ) { | ||||
668 | $Foswiki::cfg{DefaultUrlHost} = "$protocol://$ENV{HTTP_HOST}"; | ||||
669 | print STDERR | ||||
670 | "AUTOCONFIG: Set DefaultUrlHost $Foswiki::cfg{DefaultUrlHost} from HTTP_HOST $ENV{HTTP_HOST} \n" | ||||
671 | if (TRAUTO); | ||||
672 | } | ||||
673 | elsif ( $ENV{SERVER_NAME} ) { | ||||
674 | $Foswiki::cfg{DefaultUrlHost} = "$protocol://$ENV{SERVER_NAME}"; | ||||
675 | print STDERR | ||||
676 | "AUTOCONFIG: Set DefaultUrlHost $Foswiki::cfg{DefaultUrlHost} from SERVER_NAME $ENV{SERVER_NAME} \n" | ||||
677 | if (TRAUTO); | ||||
678 | } | ||||
679 | elsif ( $ENV{SCRIPT_URI} ) { | ||||
680 | ( $Foswiki::cfg{DefaultUrlHost} ) = | ||||
681 | $ENV{SCRIPT_URI} =~ m#^(https?://[^/]+)/#; | ||||
682 | print STDERR | ||||
683 | "AUTOCONFIG: Set DefaultUrlHost $Foswiki::cfg{DefaultUrlHost} from SCRIPT_URI $ENV{SCRIPT_URI} \n" | ||||
684 | if (TRAUTO); | ||||
685 | } | ||||
686 | else { | ||||
687 | |||||
688 | # OK, so this is barfilicious. Think of something better. | ||||
689 | $Foswiki::cfg{DefaultUrlHost} = "$protocol://localhost"; | ||||
690 | print STDERR | ||||
691 | "AUTOCONFIG: barfilicious: Set DefaultUrlHost $Foswiki::cfg{DefaultUrlHost} \n" | ||||
692 | if (TRAUTO); | ||||
693 | } | ||||
694 | |||||
695 | # Examine the CGI path. The 'view' script it typically removed from the | ||||
696 | # URL when using "Short URLs. If this BEGIN block is being run by | ||||
697 | # 'view', then $Foswiki::cfg{ScriptUrlPaths}{view} will be correctly | ||||
698 | # bootstrapped. If run for any other script, it will be set to a | ||||
699 | # reasonable though probably incorrect default. | ||||
700 | # | ||||
701 | # In order to recover the correct view path when the script is 'configure', | ||||
702 | # the ConfigurePlugin stashes the path to the view script into a session variable. | ||||
703 | # and then recovers it. When the jsonrpc script is called to save the configuration | ||||
704 | # it then has the VIEWPATH parameter available. If "view" was never called during | ||||
705 | # configuration, then it will not be set correctly. | ||||
706 | my $path_info = $ENV{'PATH_INFO'} | ||||
707 | || ''; #SMELL Sometimes PATH_INFO appears to be undefined. | ||||
708 | print STDERR "AUTOCONFIG: REQUEST_URI is " | ||||
709 | . ( $ENV{REQUEST_URI} || '(undef)' ) . "\n" | ||||
710 | if (TRAUTO); | ||||
711 | print STDERR "AUTOCONFIG: SCRIPT_URI is " | ||||
712 | . ( $ENV{SCRIPT_URI} || '(undef)' ) . " \n" | ||||
713 | if (TRAUTO); | ||||
714 | print STDERR "AUTOCONFIG: PATH_INFO is $path_info \n" if (TRAUTO); | ||||
715 | print STDERR "AUTOCONFIG: ENGINE is $Foswiki::cfg{Engine}\n" | ||||
716 | if (TRAUTO); | ||||
717 | |||||
718 | # This code tries to break the url up into <prefix><script><path> ... The script may or may not | ||||
719 | # be present. Short URLs will omit the script from view operations, and *may* omit the | ||||
720 | # <prefix> for all operations. Examples of URLs and shortening. | ||||
721 | # | ||||
722 | # Full: /foswiki/bin/view/Main/WebHome /foswiki/bin/edit/Main/WebHome | ||||
723 | # Full: /bin/view/Main/WebHome /bin/edit/Main/WebHome omitting prefix | ||||
724 | # Short: /foswiki/Main/WebHome /foswiki/bin/edit/Main/WebHome omitting bin/view | ||||
725 | # Short: /Main/WebHome /bin/edit/Main/WebHome omitting prefix and bin/view | ||||
726 | # Shorter: /Main/WebHome /edit/Main/WebHome omitting prefix and bin in all cases. | ||||
727 | # | ||||
728 | # Note that some of this can't be done as part of the view script. The only way to know if "bin" is omitted in | ||||
729 | # all cases is when a script other than view runs, like jsonrpc. | ||||
730 | |||||
731 | my $pfx; | ||||
732 | |||||
733 | my $suffix = | ||||
734 | ( defined $ENV{SCRIPT_URL} | ||||
735 | && length( $ENV{SCRIPT_URL} ) < length($path_info) ) | ||||
736 | ? $ENV{SCRIPT_URL} | ||||
737 | : $path_info; | ||||
738 | |||||
739 | # Try to Determine the prefix of the script part of the URI. | ||||
740 | if ( $ENV{SCRIPT_URI} && $ENV{SCRIPT_URL} ) { | ||||
741 | if ( index( $ENV{SCRIPT_URI}, $Foswiki::cfg{DefaultUrlHost} ) eq 0 ) { | ||||
742 | $pfx = | ||||
743 | substr( $ENV{SCRIPT_URI}, | ||||
744 | length( $Foswiki::cfg{DefaultUrlHost} ) ); | ||||
745 | $pfx =~ s#$suffix$##; | ||||
746 | print STDERR | ||||
747 | "AUTOCONFIG: Calculated prefix $pfx from SCRIPT_URI and SCRIPT_URL\n" | ||||
748 | if (TRAUTO); | ||||
749 | } | ||||
750 | } | ||||
751 | |||||
752 | unless ( defined $pfx ) { | ||||
753 | if ( my $idx = index( $ENV{REQUEST_URI}, $path_info ) ) { | ||||
754 | $pfx = substr( $ENV{REQUEST_URI}, 0, $idx + 1 ); | ||||
755 | } | ||||
756 | $pfx = '' unless ( defined $pfx ); | ||||
757 | print STDERR "AUTOCONFIG: URI Prefix is $pfx\n" if (TRAUTO); | ||||
758 | } | ||||
759 | |||||
760 | # Work out the URL path for Short and standard URLs | ||||
761 | if ( $ENV{REQUEST_URI} =~ m{^(.*?)/$script(\b|$)} ) { | ||||
762 | print STDERR | ||||
763 | "AUTOCONFIG: SCRIPT $script fully contained in REQUEST_URI $ENV{REQUEST_URI}, Not short URLs\n" | ||||
764 | if (TRAUTO); | ||||
765 | |||||
766 | # Conventional URLs with path and script | ||||
767 | $Foswiki::cfg{ScriptUrlPath} = $1; | ||||
768 | $Foswiki::cfg{ScriptUrlPaths}{view} = | ||||
769 | $1 . '/view' . $Foswiki::cfg{ScriptSuffix}; | ||||
770 | |||||
771 | # This might not work, depending on the websrver config, | ||||
772 | # but it's the best we can do | ||||
773 | $Foswiki::cfg{PubUrlPath} = "$1/../pub"; | ||||
774 | } | ||||
775 | else { | ||||
776 | print STDERR "AUTOCONFIG: Building Short URL paths using prefix $pfx \n" | ||||
777 | if (TRAUTO); | ||||
778 | $Foswiki::cfg{ScriptUrlPath} = $pfx . '/bin'; | ||||
779 | $Foswiki::cfg{ScriptUrlPaths}{view} = $pfx; | ||||
780 | $Foswiki::cfg{PubUrlPath} = $pfx . '/pub'; | ||||
781 | } | ||||
782 | |||||
783 | if (TRAUTO) { | ||||
784 | print STDERR | ||||
785 | "AUTOCONFIG: Using ScriptUrlPath $Foswiki::cfg{ScriptUrlPath} \n"; | ||||
786 | print STDERR "AUTOCONFIG: Using {ScriptUrlPaths}{view} " | ||||
787 | . ( | ||||
788 | ( defined $Foswiki::cfg{ScriptUrlPaths}{view} ) | ||||
789 | ? $Foswiki::cfg{ScriptUrlPaths}{view} | ||||
790 | : 'undef' | ||||
791 | ) . "\n"; | ||||
792 | print STDERR | ||||
793 | "AUTOCONFIG: Using PubUrlPath: $Foswiki::cfg{PubUrlPath} \n"; | ||||
794 | } | ||||
795 | |||||
796 | # Note: message is not I18N'd because there is no point; there | ||||
797 | # is no localisation in a default cfg derived from Foswiki.spec | ||||
798 | my $vp = ''; | ||||
799 | $vp = '?VIEWPATH=' . $Foswiki::cfg{ScriptUrlPaths}{view} | ||||
800 | if ( defined $Foswiki::cfg{ScriptUrlPaths}{view} ); | ||||
801 | my $system_message = <<BOOTS; | ||||
802 | *WARNING !LocalSite.cfg could not be found* (This is normal for a new installation) %BR% | ||||
803 | This Foswiki is running using a bootstrap configuration worked | ||||
804 | out by detecting the layout of the installation. | ||||
805 | To complete the bootstrap process you should either: | ||||
806 | * Restore the missing !LocalSite.cfg from a backup, *or* | ||||
807 | * Complete the new Foswiki installation: | ||||
808 | * visit [[%SCRIPTURL{configure}%$vp][configure]] and save a new configuration. | ||||
809 | * Register a user and add it to the %USERSWEB%.AdminGroup | ||||
810 | %BR% *You have been logged in as a temporary administrator.* | ||||
811 | Any requests made to this Foswiki will be treated as requests made by an administrator with full rights | ||||
812 | Your temporary administrator rights will "stick" until you've logged out from this session. | ||||
813 | BOOTS | ||||
814 | |||||
815 | return ( $system_message || '' ); | ||||
816 | } | ||||
817 | |||||
818 | =begin TML | ||||
819 | |||||
820 | ---++ StaticMethod findDependencies(\%cfg) -> \%deps | ||||
821 | |||||
822 | * =\%cfg= configuration hash to scan; defaults to %Foswiki::cfg | ||||
823 | |||||
824 | Recursively locate references to other keys in the values of keys. | ||||
825 | Returns a hash containing two keys: | ||||
826 | * =forward= => a hash mapping keys to a list of the keys that depend | ||||
827 | on their value | ||||
828 | * =reverse= => a hash mapping keys to a list of keys whose value they | ||||
829 | depend on. | ||||
830 | |||||
831 | =cut | ||||
832 | |||||
833 | sub findDependencies { | ||||
834 | my ( $fwcfg, $deps, $extend_keypath, $keypath ) = @_; | ||||
835 | |||||
836 | unless ( defined $fwcfg ) { | ||||
837 | ( $fwcfg, $extend_keypath, $keypath ) = ( \%Foswiki::cfg, 1, '' ); | ||||
838 | } | ||||
839 | |||||
840 | $deps ||= { forward => {}, reverse => {} }; | ||||
841 | |||||
842 | if ( ref($fwcfg) eq 'HASH' ) { | ||||
843 | while ( my ( $k, $v ) = each %$fwcfg ) { | ||||
844 | if ( defined $v ) { | ||||
845 | my $subkey = $extend_keypath ? "$keypath\{$k\}" : $keypath; | ||||
846 | findDependencies( $v, $deps, $extend_keypath, $subkey ); | ||||
847 | } | ||||
848 | } | ||||
849 | } | ||||
850 | elsif ( ref($fwcfg) eq 'ARRAY' ) { | ||||
851 | foreach my $v (@$fwcfg) { | ||||
852 | if ( defined $v ) { | ||||
853 | findDependencies( $v, $deps, 0, $keypath ); | ||||
854 | } | ||||
855 | } | ||||
856 | } | ||||
857 | else { | ||||
858 | while ( $fwcfg =~ m/\$Foswiki::cfg(({[^}]*})+)/g ) { | ||||
859 | push( @{ $deps->{forward}->{$1} }, $keypath ); | ||||
860 | push( @{ $deps->{reverse}->{$keypath} }, $1 ); | ||||
861 | } | ||||
862 | } | ||||
863 | return $deps; | ||||
864 | } | ||||
865 | |||||
866 | 1 | 6µs | 1; | ||
867 | __END__ |