2 # Common functions for parsing config.info files
3 # Each module has a number of configurable parameters (stored in the config and
4 # config-* files in the module directory). Descriptions and possible values for
5 # each option are stored in the file config.info in the module directory.
6 # Each line of config.info looks like
7 # name=desc,type[,options]
8 # desc - A description of the parameter
9 # type - Possible types (and options) are
11 # 1 - One of many (options are possibilities)
12 # 2 - Many of many (options are possibilities)
13 # 3 - Optional free text
14 # 4 - Like 1, but uses a pulldown menu
20 # 10 - Like 1, but with free text option
22 # 12 - Password free text, with don't change option
23 # 13 - Like 2, but uses a list box
24 # 14 - Parameter is the name of a function in config_info.pl that
25 # returns an alternate set of config.info values.
26 # 15 - Parameter is the suffix for a pair of functions with show_
27 # and parse_ prepended.
28 # 16 - Password free text
30 # generate_config(&config, info-file, [module], [&can-config], [checkbox-name],
35 local ($configref, $file, $module, $canconfig, $cbox, $section) = @_;
36 local %config = %$configref;
38 # Read the .info file in the right language
39 local (%info, @info_order, %einfo, $o);
40 &read_file($file, \%info, \@info_order);
42 foreach $o (@lang_order_list) {
43 &read_file("$file.$o", \%info, \@info_order);
45 @info_order = &unique(@info_order);
48 # Limit to settings in one section
49 @info_order = &config_in_section($section, \@info_order, \%info);
52 # Show the parameter editors
54 foreach $c (@info_order) {
57 # Show checkbox to allow configuring
58 $checkhtml = &ui_checkbox($cbox, $c, "",
59 !$canconfig || $canconfig->{$c});
62 # Skip those not allowed to be configured
63 next if ($canconfig && !$canconfig->{$c});
65 local @p = split(/,/, $info{$c});
66 local @ep = split(/,/, $einfo{$c});
67 if (scalar(@ep) > scalar(@p)) {
68 push(@p, @ep[scalar(@p) .. @ep-1]);
71 $module || &error($text{'config_ewebmin'});
72 &foreign_require($module, "config_info.pl");
73 local @newp = &foreign_call($module, $p[2], @p);
79 print &ui_table_row(undef, "<b>$p[0]</b>", 2, [ undef, $tb ]);
82 if ($p[1] == 16 && $gconfig{'config_16_insecure'}) {
87 if ($module && -r &help_file($module, "config_$c")) {
88 $label = $checkhtml." ".
89 &hlink($p[0], "config_$c", $module);
92 $label = $checkhtml." ".$p[0];
95 print "<td nowrap>\n";
98 $field = &ui_textbox($c, $config{$c}, $p[2] || 40, 0, $p[3]).
104 for($i=2; $i<@p; $i++) {
105 $p[$i] =~ /^(\S*)\-(.*)$/;
109 for($i=2; $i<@p; $i++) {
110 $p[$i] =~ /^(\S*)\-(.*)$/;
111 push(@opts, [ $1, $2.($len > 50 ? "<br>" : "") ]);
113 $field = &ui_radio($c, $config{$c}, \@opts);
118 map { $sel{$_}++ } split(/,/, $config{$c});
119 for($i=2; $i<@p; $i++) {
120 $p[$i] =~ /^(\S*)\-(.*)$/;
121 $field .= &ui_checkbox($c, $1, $2, $sel{$1});
126 local $none = $p[2] ? $p[2] : $text{'config_none'};
127 $field = &ui_opt_textbox($c, $config{$c}, $p[3] || 20, $none,
128 undef, 0, undef, $p[4])." ".$p[5];
133 for($i=2; $i<@p; $i++) {
134 $p[$i] =~ /^(\S*)\-(.*)$/;
135 push(@opts, [ $1, $2 ]);
137 $field = &ui_select($c, $config{$c}, \@opts);
142 $field = &ui_radio($c."_def", $config{$c} ? 0 : 1,
143 [ [ 1, $p[2] ], [ 0, " " ] ]);
146 $field .= &ui_textbox($c, $config{$c}, 30)." ".
147 &user_chooser_button($c, 1);
150 $field .= &unix_user_input($c, $config{$c});
156 $field = &ui_radio($c."_def", $config{$c} ? 0 : 1,
157 [ [ 1, $p[2] ], [ 0, " " ] ]);
160 $field .= &ui_textbox($c, $config{$c}, 30)." ".
161 &group_chooser_button($c, 1);
164 $field .= &unix_group_input($c, $config{$c});
169 $field = &ui_textbox($c, $config{$c}, 40)." ".
170 &file_chooser_button($c, 1);
174 $field = &ui_textbox($c, $config{$c}, 40)." ".
175 &file_chooser_button($c, 0);
179 local $cols = $p[2] || 40;
180 local $rows = $p[3] || 5;
181 local $sp = $p[4] ? eval "\"$p[4]\"" : " ";
182 $field = &ui_textarea($c, join("\n", split(/$sp/, $config{$c})),
185 elsif ($p[1] == 10) {
186 # Radios with freetext option
188 for($i=2; $i<@p; $i++) {
189 if ($p[$i] =~ /^(\S*)\-(.*)$/) {
193 $len += length($p[$i]);
196 local $fv = $config{$c};
198 for($i=2; $i<@p; $i++) {
199 ($p[$i] =~ /^(\S*)\-(.*)$/) || next;
200 push(@opts, [ $1, $2.($len > 50 ? "<br>" : "") ]);
201 $fv = undef if ($config{$c} eq $1);
203 push(@opts, [ "free", $p[$#p] !~ /^(\S*)\-(.*)$/ ? $p[$#p]
205 $field = &ui_radio($c, $fv ? "free" : $config{$c}, \@opts)." ".
206 &ui_textbox($c."_free", $fv, 20);
208 elsif ($p[1] == 12) {
210 $field = &ui_radio($c."_nochange", 1,
211 [ [ 1, $text{'config_nochange'} ],
212 [ 0, $text{'config_setto'} ] ])." ".
213 &ui_password($c, undef, $p[2] || 40, 0, $p[3]);
215 elsif ($p[1] == 13) {
216 # Multiple selections from menu
217 local @sel = split(/,/, $config{$c});
219 for($i=2; $i<@p; $i++) {
220 $p[$i] =~ /^(\S*)\-(.*)$/;
221 push(@opts, [ $1, $2 ]);
223 $field = &ui_select($c, \@sel, \@opts, 5, 1);
225 elsif ($p[1] == 15) {
226 # Input generated by function
227 $module || &error($text{'config_ewebmin'});
228 &foreign_require($module, "config_info.pl");
229 $field = &foreign_call($module, "show_".$p[2],
232 elsif ($p[1] == 16) {
234 $field = &ui_password($c, undef, $p[2] || 40, 0, $p[3]);
236 print &ui_table_row($label, $field, 1, [ "width=30% nowrap" ]);
240 # parse_config(&config, info-file, [module], [&canconfig], [section])
241 # Updates the specified configuration with values from %in
244 local ($config, $file, $module, $canconfig, $section) = @_;
246 # Read the .info file
247 local (%info, @info_order, $o);
248 &read_file($file, \%info, \@info_order);
249 foreach $o (@lang_order_list) {
250 &read_file("$file.$o", \%info, \@info_order);
252 @info_order = &unique(@info_order);
255 # Limit to settings in one section
256 @info_order = &config_in_section($section, \@info_order, \%info);
259 # Actually parse the inputs
261 foreach $c (@info_order) {
262 next if ($canconfig && !$canconfig->{$c});
263 local @p = split(/,/, $info{$c});
265 $_[2] || &error($text{'config_ewebmin'});
266 &foreign_require($_[2], "config_info.pl");
267 local @newp = &foreign_call($_[2], $p[2]);
271 if ($p[1] == 16 && $gconfig{'config_16_insecure'}) {
272 # Don't allow mode 16
275 if ($p[1] == 0 || $p[1] == 7 || $p[1] == 8 || $p[1] == 16) {
277 $config->{$c} = $in{$c};
279 elsif ($p[1] == 1 || $p[1] == 4) {
281 $config->{$c} = $in{$c};
283 elsif ($p[1] == 5 || $p[1] == 6) {
285 $config->{$c} = ($p[2] && $in{$c."_def"} ? "" : $in{$c});
287 elsif ($p[1] == 2 || $p[1] == 13) {
290 $config->{$c} = $in{$c};
294 if ($in{$c."_def"}) { $config->{$c} = ""; }
295 else { $config->{$c} = $in{$c}; }
298 # Multilines of free text
299 local $sp = $p[4] ? eval "\"$p[4]\"" : " ";
301 $in{$c} =~ s/\n/$sp/g;
303 $config->{$c} = $in{$c};
305 elsif ($p[1] == 10) {
306 # One of many or free text
307 if ($in{$c} eq 'free') {
308 $config->{$c} = $in{$c.'_free'};
311 $config->{$c} = $in{$c};
314 elsif ($p[1] == 12) {
315 # Optionally changed password
316 if (!$in{"${c}_nochange"}) {
317 $config->{$c} = $in{$c};
320 elsif ($p[1] == 15) {
321 # Parse custom HTML field
322 $_[2] || &error($text{'config_ewebmin'});
323 &foreign_require($_[2], "config_info.pl");
325 $pkg =~ s/[^A-Za-z0-9]/_/g;
326 eval "\%${pkg}::in = \%in";
327 $config->{$c} = &foreign_call($_[2], "parse_".$p[2],
333 # config_in_section(§ion, &order, &config-info)
334 # Returns a list of config names that are in some section
335 sub config_in_section
337 local ($section, $info_order, $info) = @_;
340 foreach my $c (@$info_order) {
341 local @p = split(/,/, $info->{$c});
342 if ($p[1] == 11 && $c eq $section) {
345 elsif ($p[1] == 11 && $c ne $section) {
348 elsif ($in_section) {
349 push(@new_order, $c);