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 my ($configref, $file, $module, $canconfig, $cbox, $section) = @_;
36 my %config = %$configref;
38 # Read the .info file in the right language
39 my (%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
53 foreach my $c (@info_order) {
56 # Show checkbox to allow configuring
57 $checkhtml = &ui_checkbox($cbox, $c, "",
58 !$canconfig || $canconfig->{$c});
61 # Skip those not allowed to be configured
62 next if ($canconfig && !$canconfig->{$c});
64 my @p = split(/,/, $info{$c});
65 my @ep = split(/,/, $einfo{$c});
66 if (scalar(@ep) > scalar(@p)) {
67 push(@p, @ep[scalar(@p) .. @ep-1]);
70 $module || &error($text{'config_ewebmin'});
71 &foreign_require($module, "config_info.pl");
72 my @newp = &foreign_call($module, $p[2], @p);
78 print &ui_table_row(undef, "<b>$p[0]</b>", 2, [ undef, $tb ]);
81 if ($p[1] == 16 && $gconfig{'config_16_insecure'}) {
86 if ($module && -r &help_file($module, "config_$c")) {
87 $label = $checkhtml." ".
88 &hlink($p[0], "config_$c", $module);
91 $label = $checkhtml." ".$p[0];
96 $field = &ui_textbox($c, $config{$c}, $p[2] || 40, 0, $p[3]).
102 for(my $i=2; $i<@p; $i++) {
103 $p[$i] =~ /^(\S*)\-(.*)$/;
107 for($i=2; $i<@p; $i++) {
108 $p[$i] =~ /^(\S*)\-(.*)$/;
109 push(@opts, [ $1, $2.($len > 50 ? "<br>" : "") ]);
111 $field = &ui_radio($c, $config{$c}, \@opts);
116 map { $sel{$_}++ } split(/,/, $config{$c});
117 for($i=2; $i<@p; $i++) {
118 $p[$i] =~ /^(\S*)\-(.*)$/;
119 $field .= &ui_checkbox($c, $1, $2, $sel{$1});
124 my $none = $p[2] || $text{'config_none'};
125 $field = &ui_opt_textbox($c, $config{$c}, $p[3] || 20, $none,
126 $p[6], 0, undef, $p[4])." ".$p[5];
131 for($i=2; $i<@p; $i++) {
132 $p[$i] =~ /^(\S*)\-(.*)$/;
133 push(@opts, [ $1, $2 ]);
135 $field = &ui_select($c, $config{$c}, \@opts);
140 $field = &ui_radio($c."_def", $config{$c} ? 0 : 1,
141 [ [ 1, $p[2] ], [ 0, " " ] ]);
144 $field .= &ui_textbox($c, $config{$c}, 30)." ".
145 &user_chooser_button($c, 1);
148 $field .= &unix_user_input($c, $config{$c});
154 $field = &ui_radio($c."_def", $config{$c} ? 0 : 1,
155 [ [ 1, $p[2] ], [ 0, " " ] ]);
158 $field .= &ui_textbox($c, $config{$c}, 30)." ".
159 &group_chooser_button($c, 1);
162 $field .= &unix_group_input($c, $config{$c});
167 $field = &ui_textbox($c, $config{$c}, 40)." ".
168 &file_chooser_button($c, 1);
172 $field = &ui_textbox($c, $config{$c}, 40)." ".
173 &file_chooser_button($c, 0);
177 my $cols = $p[2] || 40;
178 my $rows = $p[3] || 5;
179 my $sp = $p[4] ? eval "\"$p[4]\"" : " ";
180 $field = &ui_textarea($c, join("\n", split(/$sp/, $config{$c})),
183 elsif ($p[1] == 10) {
184 # Radios with freetext option
186 for(my $i=2; $i<@p; $i++) {
187 if ($p[$i] =~ /^(\S*)\-(.*)$/) {
191 $len += length($p[$i]);
194 my $fv = $config{$c};
196 for(my $i=2; $i<@p; $i++) {
197 ($p[$i] =~ /^(\S*)\-(.*)$/) || next;
198 push(@opts, [ $1, $2.($len > 50 ? "<br>" : "") ]);
199 $fv = undef if ($config{$c} eq $1);
201 push(@opts, [ "free", $p[$#p] !~ /^(\S*)\-(.*)$/ ? $p[$#p]
203 $field = &ui_radio($c, $fv ? "free" : $config{$c}, \@opts)." ".
204 &ui_textbox($c."_free", $fv, 20);
206 elsif ($p[1] == 12) {
208 $field = &ui_radio($c."_nochange", 1,
209 [ [ 1, $text{'config_nochange'} ],
210 [ 0, $text{'config_setto'} ] ])." ".
211 &ui_password($c, undef, $p[2] || 40, 0, $p[3]);
213 elsif ($p[1] == 13) {
214 # Multiple selections from menu
215 my @sel = split(/,/, $config{$c});
217 for($i=2; $i<@p; $i++) {
218 $p[$i] =~ /^(\S*)\-(.*)$/;
219 push(@opts, [ $1, $2 ]);
221 $field = &ui_select($c, \@sel, \@opts, 5, 1);
223 elsif ($p[1] == 15) {
224 # Input generated by function
225 $module || &error($text{'config_ewebmin'});
226 &foreign_require($module, "config_info.pl");
227 $field = &foreign_call($module, "show_".$p[2],
230 elsif ($p[1] == 16) {
232 $field = &ui_password($c, undef, $p[2] || 40, 0, $p[3]);
234 $label = "<a name=$c>$label</a>";
235 print &ui_table_row($label, $field, 1, [ "width=30% nowrap" ]);
239 # parse_config(&config, info-file, [module], [&canconfig], [section])
240 # Updates the specified configuration with values from %in
243 my ($config, $file, $module, $canconfig, $section) = @_;
245 # Read the .info file
246 my (%info, @info_order, $o);
247 &read_file($file, \%info, \@info_order);
248 foreach $o (@lang_order_list) {
249 &read_file("$file.$o", \%info, \@info_order);
251 @info_order = &unique(@info_order);
254 # Limit to settings in one section
255 @info_order = &config_in_section($section, \@info_order, \%info);
258 # Actually parse the inputs
259 foreach my $c (@info_order) {
260 next if ($canconfig && !$canconfig->{$c});
261 my @p = split(/,/, $info{$c});
263 $_[2] || &error($text{'config_ewebmin'});
264 &foreign_require($_[2], "config_info.pl");
265 my @newp = &foreign_call($_[2], $p[2]);
269 if ($p[1] == 16 && $gconfig{'config_16_insecure'}) {
270 # Don't allow mode 16
273 if ($p[1] == 0 || $p[1] == 7 || $p[1] == 8 || $p[1] == 16) {
275 $config->{$c} = $in{$c};
277 elsif ($p[1] == 1 || $p[1] == 4) {
279 $config->{$c} = $in{$c};
281 elsif ($p[1] == 5 || $p[1] == 6) {
283 $config->{$c} = ($p[2] && $in{$c."_def"} ? "" : $in{$c});
285 elsif ($p[1] == 2 || $p[1] == 13) {
288 $config->{$c} = $in{$c};
292 if ($in{$c."_def"}) { $config->{$c} = ""; }
293 else { $config->{$c} = $in{$c}; }
296 # Multilines of free text
297 my $sp = $p[4] ? eval "\"$p[4]\"" : " ";
299 $in{$c} =~ s/\n/$sp/g;
301 $config->{$c} = $in{$c};
303 elsif ($p[1] == 10) {
304 # One of many or free text
305 if ($in{$c} eq 'free') {
306 $config->{$c} = $in{$c.'_free'};
309 $config->{$c} = $in{$c};
312 elsif ($p[1] == 12) {
313 # Optionally changed password
314 if (!$in{"${c}_nochange"}) {
315 $config->{$c} = $in{$c};
318 elsif ($p[1] == 15) {
319 # Parse custom HTML field
320 $_[2] || &error($text{'config_ewebmin'});
321 &foreign_require($_[2], "config_info.pl");
322 $config->{$c} = &foreign_call($_[2], "parse_".$p[2],
328 # config_in_section(§ion, &order, &config-info)
329 # Returns a list of config names that are in some section
330 sub config_in_section
332 my ($section, $info_order, $info) = @_;
335 foreach my $c (@$info_order) {
336 my @p = split(/,/, $info->{$c});
337 if ($p[1] == 11 && $c eq $section) {
340 elsif ($p[1] == 11 && $c ne $section) {
343 elsif ($in_section) {
344 push(@new_order, $c);