diff --git a/postfix/acl_security.pl b/postfix/acl_security.pl index 5e195dfcb..f7cc55d66 100755 --- a/postfix/acl_security.pl +++ b/postfix/acl_security.pl @@ -1,5 +1,8 @@ -require 'postfix-lib.pl'; +require 'postfix-lib.pl'; ## no critic +use strict; +use warnings; +our (@acl_pages, %in, %text); @acl_pages = ("resource", "address_rewriting", "aliases", "general", "canonical", "virtual", "transport", "relocated", "header", "body", "bcc", "dependent", "sni", "local_delivery", "smtpd", @@ -9,8 +12,7 @@ require 'postfix-lib.pl'; # Print the form for security options of postfix module sub acl_security_form { -local $o; -foreach $o (@acl_pages) { +foreach my $o (@acl_pages) { print &ui_table_row($text{'acl_'.$o} || $o, &ui_yesno_radio($o, $_[0]->{$o} ? 1 : 0)); } @@ -23,8 +25,7 @@ print &ui_table_row($text{'acl_dir'}, # Parse the form for security options for the postfix module sub acl_security_save { -local $o; -foreach $o (@acl_pages) { +foreach my $o (@acl_pages) { $_[0]->{$o} = $in{$o}; } $_[0]->{'dir'} = $in{'dir'}; diff --git a/postfix/address_rewriting.cgi b/postfix/address_rewriting.cgi index 2b8c3a3e6..85ba75e68 100755 --- a/postfix/address_rewriting.cgi +++ b/postfix/address_rewriting.cgi @@ -7,7 +7,10 @@ # # << Here are all options seen in Postfix sample-rewrite.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($default, $no_, $none, %access, %text); $access{'address_rewriting'} || &error($text{'address_rewriting_ecannot'}); &ui_print_header(undef, $text{'address_rewriting_title'}, ""); diff --git a/postfix/aliases.cgi b/postfix/aliases.cgi index 243d5e3c3..40c37a989 100755 --- a/postfix/aliases.cgi +++ b/postfix/aliases.cgi @@ -8,7 +8,10 @@ # << Here are all options seen in Postfix sample-aliases.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($al, $anum, $astr, $i, $lines, $mid, $midline, %access, @aline, %config, @grid, @links, %text); $access{'aliases'} || &error($text{'aliases_ecannot'}); &ui_print_header(undef, $text{'aliases_title'}, "", "aliases"); @@ -93,8 +96,8 @@ foreach my $a (@_) { push(@cols, "{'num'}\">". ($a->{'enabled'} ? "" : "").&html_escape($a->{'name'}). ($a->{'enabled'} ? "" : "").""); - local $vstr; - foreach $v (@{$a->{'values'}}) { + my $vstr; + foreach my $v (@{$a->{'values'}}) { ($anum, $astr) = &alias_type($v); $vstr .= &text("aliases_type$anum", "".&html_escape($astr)."")."
\n"; diff --git a/postfix/backup_config.pl b/postfix/backup_config.pl index 9ad02c838..150262906 100755 --- a/postfix/backup_config.pl +++ b/postfix/backup_config.pl @@ -1,4 +1,5 @@ - +use strict; +use warnings; do 'postfix-lib.pl'; # backup_config_files() @@ -12,21 +13,21 @@ return &get_all_config_files(); # Called before the files are actually read sub pre_backup { -return undef; +return; } # post_backup(&files) # Called after the files are actually read sub post_backup { -return undef; +return; } # pre_restore(&files) # Called before the files are restored from a backup sub pre_restore { -return undef; +return; } # post_restore(&files) @@ -36,7 +37,7 @@ sub post_restore if (&is_postfix_running()) { return &reload_postfix(); } -return undef; +return; } 1; diff --git a/postfix/bcc.cgi b/postfix/bcc.cgi index 257fe72b4..4b15d41be 100755 --- a/postfix/bcc.cgi +++ b/postfix/bcc.cgi @@ -1,6 +1,9 @@ #!/usr/local/bin/perl -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our (%access, %in, %text); $access{'bcc'} || &error($text{'bcc_ecannot'}); &ui_print_header(undef, $text{'bcc_title'}, "", "bcc"); diff --git a/postfix/body.cgi b/postfix/body.cgi index 35e3dac9a..cda05d5ce 100755 --- a/postfix/body.cgi +++ b/postfix/body.cgi @@ -8,7 +8,10 @@ # << Here are all options seen in Postfix sample-virtual.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our (%access, %text); &ReadParse(); $access{'body'} || &error($text{'body_ecannot'}); diff --git a/postfix/canonical.cgi b/postfix/canonical.cgi index b7bb62c88..e03e73352 100755 --- a/postfix/canonical.cgi +++ b/postfix/canonical.cgi @@ -8,7 +8,10 @@ # << Here are all options seen in Postfix sample-canonical.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our (%access, %text); $access{'canonical'} || &error($text{'canonical_ecannot'}); &ui_print_header(undef, $text{'canonical_title'}, "", "canonical"); diff --git a/postfix/canonical_edit.cgi b/postfix/canonical_edit.cgi index 003c8068b..f7957471a 100755 --- a/postfix/canonical_edit.cgi +++ b/postfix/canonical_edit.cgi @@ -5,7 +5,10 @@ # # Edit one category of canonical maps -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our (%in, %text); &ReadParse(); &ui_print_header(undef, $text{'canonical_edit_title'}, "", "canonical"); diff --git a/postfix/client.cgi b/postfix/client.cgi index 5805c235c..f41408468 100755 --- a/postfix/client.cgi +++ b/postfix/client.cgi @@ -2,7 +2,10 @@ # A single page just for editing smtpd_client_restrictions # XXX editing access maps? -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($default, $has_client_access, $no_, $none, $vals, %access, %done, @grid, %opts, @opts, @rest, %text, @v); $access{'client'} || &error($text{'client_ecannot'}); &ui_print_header(undef, $text{'client_title'}, ""); @@ -24,15 +27,15 @@ for(my $i=0; $i<@opts; $i++) { # Add binary restrictions to list @grid = ( ); %done = ( ); -foreach $r (&list_client_restrictions()) { +foreach my $r (&list_client_restrictions()) { push(@grid, &ui_checkbox("client", $r, $text{'sasl_'.$r}, defined($opts{$r})), undef); $done{$r} = 1; } # Add restrictions with values -foreach $r (&list_multi_client_restrictions()) { - @v = @{$opts{$r}}; +foreach my $r (&list_multi_client_restrictions()) { + @v = $opts{$r} ? @{$opts{$r}} : (); $vals = undef; if (scalar(@v)) { $vals = join(" ", map { $opts[$_+1] } @v); @@ -43,7 +46,7 @@ foreach $r (&list_multi_client_restrictions()) { ($r eq "check_client_access" ? " ".&map_chooser_button("value_$r", $r) : "")); $done{$r} = 1; - foreach $v (@v) { + foreach my $v (@v) { $done{$opts[$v+1]} = 1; } if ($r eq "check_client_access" && @v) { diff --git a/postfix/debug.cgi b/postfix/debug.cgi index 8e5f77651..01b05137c 100755 --- a/postfix/debug.cgi +++ b/postfix/debug.cgi @@ -7,7 +7,10 @@ # # << Here are all options seen in Postfix sample-debug.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($default, $no_, $none, %access, %text); $access{'debug'} || &error($text{'debug_ecannot'}); diff --git a/postfix/delete_aliases.cgi b/postfix/delete_aliases.cgi index 650fb40f2..41cdccc41 100755 --- a/postfix/delete_aliases.cgi +++ b/postfix/delete_aliases.cgi @@ -1,8 +1,11 @@ #!/usr/local/bin/perl # Delete several mail aliases -require './postfix-lib.pl'; -require './aliases-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($alias, $err, %access, @afiles, @aliases, @d, @delaliases, %in, %text); +require './aliases-lib.pl'; ## no critic &ReadParse(); &error_setup($text{'adelete_err'}); $access{'aliases'} || &error($text{'aliases_ecannot'}); @@ -13,7 +16,7 @@ $access{'aliases'} || &error($text{'aliases_ecannot'}); @d = split(/\0/, $in{'d'}); @d || &error($text{'adelete_enone'}); @aliases = &list_postfix_aliases(); -foreach $d (@d) { +foreach my $d (@d) { ($alias) = grep { $_->{'name'} eq $d } @aliases; if ($alias) { push(@delaliases, $alias); @@ -21,7 +24,7 @@ foreach $d (@d) { } # Delete the aliases -foreach $alias (@delaliases) { +foreach my $alias (@delaliases) { &delete_postfix_alias($alias); } &unlock_alias_files(\@afiles); diff --git a/postfix/delete_mappings.cgi b/postfix/delete_mappings.cgi index deb1211c0..b002fa1b2 100755 --- a/postfix/delete_mappings.cgi +++ b/postfix/delete_mappings.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Delete multiple mappings -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, $map, $maps, @d, %in, %text); &ReadParse(); &error_setup($text{'delete_err'}); @@ -9,7 +12,7 @@ require './postfix-lib.pl'; @d || &error($text{'delete_enone'}); $maps = &get_maps($in{'map_name'}); -foreach $d (@d) { +foreach my $d (@d) { ($map) = grep { $_->{'name'} eq $d } @$maps; if ($map) { &lock_file($map->{'file'}); diff --git a/postfix/delete_queues.cgi b/postfix/delete_queues.cgi index 4a7cc5227..bc6596bdf 100755 --- a/postfix/delete_queues.cgi +++ b/postfix/delete_queues.cgi @@ -2,27 +2,30 @@ # delete_queues.cgi # Delete multiple messages from the postfix queue -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($postfix_version, %access, %config, @files, %in, @qfiles, %text); $access{'mailq'} || &error($text{'mailq_ecannot'}); &ReadParse(); if ($in{'move'}) { # Re-queuing messages - foreach $f (split(/\0/, $in{'file'})) { + foreach my $f (split(/\0/, $in{'file'})) { &system_logged("$config{'postfix_super_command'} -r ". quotemeta($f)." >/dev/null 2>&1 /dev/null 2>&1 /dev/null 2>&1 = 0) { &system_logged("$config{'postfix_super_command'} -d ".quotemeta($f)." >/dev/null 2>&1 {'number'} == $num) { %alias = %{$trans}; } } diff --git a/postfix/edit_manual.cgi b/postfix/edit_manual.cgi index 41bfb9ab7..bfd2590a2 100755 --- a/postfix/edit_manual.cgi +++ b/postfix/edit_manual.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Show a form for editing a mapping file -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($data, $file, %access, @files, %in, %text); &ReadParse(); $access{'manual'} || &error($text{'manual_ecannot'}); &ui_print_header(undef, $text{'manual_title'}, ""); diff --git a/postfix/edit_mapping.cgi b/postfix/edit_mapping.cgi index 5e5cde689..3309dfa20 100755 --- a/postfix/edit_mapping.cgi +++ b/postfix/edit_mapping.cgi @@ -5,7 +5,10 @@ # # Edit a mapping -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($nfunc, $vfunc, $virtual_maps, %in, %text); &ReadParse(); &ui_print_header(undef, $text{'edit_map_title'}, ""); @@ -28,7 +31,7 @@ else my $maps = &get_maps($in{'map_name'}); my %map; -foreach $trans (@{$maps}) +foreach my $trans (@{$maps}) { if ($trans->{'number'} == $num) { %map = %{$trans}; } } diff --git a/postfix/edit_master.cgi b/postfix/edit_master.cgi index 176e13054..8d83d95e6 100755 --- a/postfix/edit_master.cgi +++ b/postfix/edit_master.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Edit or create a server process -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($host, $master, $pmode, $prog, $wmode, $wused, %access, %in, %text); $access{'master'} || &error($text{'master_ecannot'}); &ReadParse(); $master = &get_master_config(); diff --git a/postfix/flushq.cgi b/postfix/flushq.cgi index f2240448e..521b370a2 100755 --- a/postfix/flushq.cgi +++ b/postfix/flushq.cgi @@ -2,7 +2,10 @@ # flushq.cgi # Run postqueue -f and display the output -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($cmd, $config_dir, $out, %config, %text); &ui_print_unbuffered_header(undef, $text{'flushq_title'}, ""); $cmd = "$config{'postfix_queue_command'} -c $config_dir -f"; diff --git a/postfix/general.cgi b/postfix/general.cgi index 6aae831aa..80cc975f0 100755 --- a/postfix/general.cgi +++ b/postfix/general.cgi @@ -7,7 +7,10 @@ # # << Here are all options seen in Postfix sample-misc.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($default, $no_, $none, $postfix_version, $v, %access, %text, @v); $access{'general'} || &error($text{'general_ecannot'}); diff --git a/postfix/header.cgi b/postfix/header.cgi index cbd7a90f9..04f25c111 100755 --- a/postfix/header.cgi +++ b/postfix/header.cgi @@ -8,7 +8,10 @@ # << Here are all options seen in Postfix sample-virtual.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our (%access, %text); &ReadParse(); $access{'header'} || &error($text{'header_ecannot'}); diff --git a/postfix/index.cgi b/postfix/index.cgi index 918d14e94..5eba35345 100755 --- a/postfix/index.cgi +++ b/postfix/index.cgi @@ -23,7 +23,10 @@ # -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, $lnk, $module_config_directory, $module_name, $postfix_version, %access, %config, @oicons, @olinks, @onames, @otitles, %text); &ui_print_header(undef, $text{'index_title'}, "", "intro", 1, 1, 0, &help_search_link("postfix", "man", "doc", "google"), @@ -31,9 +34,10 @@ require './postfix-lib.pl'; &text('index_version', $postfix_version) : undef); # Save the version for use by other CGIs -&open_tempfile(VERSION, ">$module_config_directory/version", 0, 1); -&print_tempfile(VERSION, "$postfix_version\n"); -&close_tempfile(VERSION); +my $verfh = "VERSION"; +&open_tempfile($verfh, ">$module_config_directory/version", 0, 1); +&print_tempfile($verfh, "$postfix_version\n"); +&close_tempfile($verfh); # Verify the postfix control command if (!&valid_postfix_command($config{'postfix_control_command'})) { @@ -92,7 +96,7 @@ if ($config{'index_check'} && ($err = &check_postfix())) { "master", "mailq", "postfinger", "boxes", "manual" ); $access{'boxes'} = &foreign_available("mailboxes"); -foreach $oitem (@onames) +foreach my $oitem (@onames) { if ($access{$oitem}) { push (@olinks, $oitem eq "boxes" ? "../mailboxes/" @@ -101,8 +105,8 @@ foreach $oitem (@onames) : $text{$oitem . "_title"}); if ($oitem eq 'mailq' && !$config{'mailq_count'}) { # Count the queue - local @mqueue = &list_queue(0); - local $mcount = scalar(@mqueue); + my @mqueue = &list_queue(0); + my $mcount = scalar(@mqueue); $otitles[$#otitles] .= "
".&text('mailq_count', $mcount); } diff --git a/postfix/install_check.pl b/postfix/install_check.pl index 96c3ef127..0985547d5 100755 --- a/postfix/install_check.pl +++ b/postfix/install_check.pl @@ -1,6 +1,9 @@ # install_check.pl +use strict; +use warnings; do 'postfix-lib.pl'; +our (%config); # is_installed(mode) # For mode 1, returns 2 if the server is installed and configured for use by diff --git a/postfix/ldap.cgi b/postfix/ldap.cgi index 7baad3059..6a5417c74 100755 --- a/postfix/ldap.cgi +++ b/postfix/ldap.cgi @@ -7,7 +7,10 @@ # # << Here are all options seen in Postfix sample-ldap.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($cb, $default, $ldap_timeout, $no_, $none, $tb, %access, %text); $access{'ldap'} || &error($text{'ldap_ecannot'}); diff --git a/postfix/local_delivery.cgi b/postfix/local_delivery.cgi index 7b44e88cf..0563cb9e8 100755 --- a/postfix/local_delivery.cgi +++ b/postfix/local_delivery.cgi @@ -7,7 +7,10 @@ # # << Here are all options seen in Postfix sample-local.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($default, $no_, $none, %access, %text); $access{'local_delivery'} || &error($text{'local_delivery_ecannot'}); diff --git a/postfix/log_parser.pl b/postfix/log_parser.pl index 27b1b9a43..cf47308d3 100755 --- a/postfix/log_parser.pl +++ b/postfix/log_parser.pl @@ -1,13 +1,16 @@ # log_parser.pl # Functions for parsing this module's logs +use strict; +use warnings; do 'postfix-lib.pl'; +our (%text); # parse_webmin_log(user, script, action, type, object, ¶ms) # Converts logged information from this module into human-readable form sub parse_webmin_log { -local ($user, $script, $action, $type, $object, $p) = @_; +my ($user, $script, $action, $type, $object, $p) = @_; if ($action eq 'delete' || $action eq 'modify' || $action eq 'create') { return &text("log_${type}_${action}", "".&html_escape($object)."") || diff --git a/postfix/mailq.cgi b/postfix/mailq.cgi index 4b8eb80d8..f0a153e7b 100755 --- a/postfix/mailq.cgi +++ b/postfix/mailq.cgi @@ -2,8 +2,11 @@ # mailq.cgi # Display messages currently in the queue. -require './postfix-lib.pl'; -require './boxes-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($e, $in, $s, %access, %config, %in, @qfiles, %text); +require './boxes-lib.pl'; ## no critic &ReadParse(); $access{'mailq'} || &error($text{'mailq_ecannot'}); diff --git a/postfix/mailq_search.cgi b/postfix/mailq_search.cgi index 26c6e2171..954e5dd2b 100755 --- a/postfix/mailq_search.cgi +++ b/postfix/mailq_search.cgi @@ -2,8 +2,11 @@ # mailq_search.cgi # Display some messages from the mail queue -require './postfix-lib.pl'; -require './boxes-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($neg, %access, %in, @qfiles, %text); +require './boxes-lib.pl'; ## no critic &ReadParse(); $access{'mailq'} || &error($text{'mailq_ecannot'}); &ui_print_header(undef, $text{'searchq_title'}, ""); @@ -17,7 +20,8 @@ $neg = ($in{'field'} =~ s/^!//); $neg ? !$r : $r } @qfiles; print "

",&text($in{'field'} =~ /^\!/ ? 'search_results3' : - 'search_results2', scalar(@qfiles), "$in{'match'}"),"

\n"; + 'search_results2', scalar(@qfiles), + "".&html_escape($in{'match'}).""),"

\n"; if (@qfiles) { # Show matching messages &mailq_table(\@qfiles); diff --git a/postfix/manual.cgi b/postfix/manual.cgi index 2aa2299c2..946ed948b 100755 --- a/postfix/manual.cgi +++ b/postfix/manual.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Show a page for manually editing the Postfix config file -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($data, %access, @files, %in, %text); $access{'manual'} || &error($text{'cmanual_ecannot'}); &ReadParse(); &ui_print_header(undef, $text{'cmanual_title'}, ""); diff --git a/postfix/manual_update.cgi b/postfix/manual_update.cgi index a0ba41e42..4eba46a1a 100755 --- a/postfix/manual_update.cgi +++ b/postfix/manual_update.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Update a manually edited config file -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our (%access, @files, %in, %text); &error_setup($text{'cmanual_err'}); $access{'manual'} || &error($text{'cmanual_ecannot'}); &ReadParseMime(); @@ -15,9 +18,10 @@ if ($in{'file'} eq $files[0]) { } # Write to it -&open_lock_tempfile(DATA, ">$in{'file'}"); -&print_tempfile(DATA, $in{'data'}); -&close_tempfile(DATA); +my $datafh = "DATA"; +&open_lock_tempfile($datafh, ">$in{'file'}"); +&print_tempfile($datafh, $in{'data'}); +&close_tempfile($datafh); &webmin_log("manual", undef, $in{'file'}); &redirect(""); diff --git a/postfix/map_chooser.cgi b/postfix/map_chooser.cgi index bccc2b838..5da68eca2 100755 --- a/postfix/map_chooser.cgi +++ b/postfix/map_chooser.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Show a form for selecting the source for a map -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($i, $lconf, $ltable, $mtable, $myconf, $postfix_version, $t, %in, @maps, @opts, @sources, %text); &ReadParse(); &popup_header($text{'chooser_title'}); @@ -14,7 +17,7 @@ print &ui_form_start("map_chooser_save.cgi", "post"); print &ui_hidden("map", $in{'map'}); print &ui_hidden("mapname", $in{'mapname'}); $i = 0; -foreach $tv (@maps) { +foreach my $tv (@maps) { print &ui_hidden_table_start(&text('chooser_header', $i+1), "width=100%", 2, "section$i", $tv->[0] || $i == 0, [ "width=30%" ]); diff --git a/postfix/map_chooser_save.cgi b/postfix/map_chooser_save.cgi index ebf986338..cd747dd72 100755 --- a/postfix/map_chooser_save.cgi +++ b/postfix/map_chooser_save.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Show a form for selecting the source for a map -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($file, $i, $postfix_version, $str, $t, @files, %in, @maps, @newfiles, @oldmaps, %text); &ReadParse(); &error_setup($text{'chooser_err'}); @oldmaps = &get_maps_types_files($in{'map'}); @@ -225,14 +228,14 @@ for($i=0; defined($t = $in{"type_".$i}); $i++) { # Write out mysql and LDAP files @files = &unique(@files); @newfiles = map { !-r $_ } @files; -foreach $f (@files) { +foreach my $f (@files) { &lock_file($f); } &flush_file_lines(@files); -foreach $f (@newfiles) { +foreach my $f (@newfiles) { &set_ownership_permissions(undef, undef, 0700, $f); } -foreach $f (@files) { +foreach my $f (@files) { &unlock_file($f); } diff --git a/postfix/master.cgi b/postfix/master.cgi index a4767a597..768847a07 100755 --- a/postfix/master.cgi +++ b/postfix/master.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Show a table of Postfix server processes -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($master, %access, %text); $access{'master'} || &error($text{'master_ecannot'}); &ui_print_header(undef, $text{'master_title'}, "", "master"); @@ -15,7 +18,7 @@ print &ui_columns_start([ $text{'master_name'}, $text{'master_unpriv'}, $text{'master_chroot'}, $text{'master_max'} ], "100%"); -foreach $m (@$master) { +foreach my $m (@$master) { print &ui_columns_row([ "{'enabled'}'>". diff --git a/postfix/postfinger.cgi b/postfix/postfinger.cgi index 4718756b5..79abd0ba7 100755 --- a/postfix/postfinger.cgi +++ b/postfix/postfinger.cgi @@ -2,7 +2,11 @@ # postfinger.cgi # check postfix configuration -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($Defaultsinmain, $err, $Libraries, $Locking, $Main, $Master, $Package, $Permissions, $postf1, $postf2, $postf3, $postf4, $postf5, $postf6, $postf7, $postf8, $postfix_version, $System, $Tables, $Warn, %access, %config, %text); +my $mailq; &ReadParse(); @@ -38,12 +42,12 @@ if ($System eq 1 ) { print ""; print "
"; print ""; - open(MAILQ, "/bin/hostname 2>/dev/null |"); - while (my $hostname = ) { print ""; } - close(MAILQ); - open(MAILQ, "/bin/uname -a 2>/dev/null |"); - while (my $uname = ) { print ""; } - close(MAILQ); + open($mailq, "-|", "/bin/hostname 2>/dev/null"); + while (my $hostname = <$mailq>) { print ""; } + close($mailq); + open($mailq, "-|", "/bin/uname -a 2>/dev/null"); + while (my $uname = <$mailq>) { print ""; } + close($mailq); } print "
Hostname $hostname
System $uname
Hostname $hostname
System $uname

"; } @@ -51,10 +55,10 @@ if ($System eq 1 ) { if ($Locking eq 1 ) { print '

Mailbox locking methods

'; print ''; - open(MAILQ, "$config{'postfix_config_command'} -l 2>/dev/null |"); - while (my $locking_methods = ) { + open($mailq, "-|", "$config{'postfix_config_command'} -l 2>/dev/null"); + while (my $locking_methods = <$mailq>) { print ""; } - close(MAILQ); + close($mailq); print "
$locking_methods

"; } @@ -62,10 +66,10 @@ if ($Tables eq 1 ) { print '

Supported Lookup Tables

'; print ''; # print '
--Supported Lookup tables--

'; - open(MAILQ, "$config{'postfix_config_command'} -m 2>/dev/null |"); - while (my $lookup_tables = ) { + open($mailq, "-|", "$config{'postfix_config_command'} -m 2>/dev/null"); + while (my $lookup_tables = <$mailq>) { print ""; } - close(MAILQ); + close($mailq); print "
$lookup_tables

"; } @@ -82,12 +86,12 @@ if ($Main eq 1 ) { print '

main.cf


non-default parameters

'; print ''; # print '
--main.cf non-default parameters--

'; - open(MAILQ, "/usr/bin/comm -13 postfinger.$$.d postfinger.$$.n 2>/dev/null |"); - while (my $postfinger = ) { + open($mailq, "-|", "/usr/bin/comm -13 postfinger.$$.d postfinger.$$.n 2>/dev/null"); + while (my $postfinger = <$mailq>) { ($postf1,$postf2)=split(/=/,$postfinger,2); print ""; print ""; } - close(MAILQ); + close($mailq); print "
$postf1$postf2

"; } @@ -95,12 +99,12 @@ if ($Defaultsinmain eq 1 ) { print '

main.cf


parameters defined as per defaults

'; print ''; # print '
--main.cf parameters defined as per defaults--

'; - open(MAILQ, "/usr/bin/comm -12 postfinger.$$.d postfinger.$$.n 2>/dev/null |"); - while (my $postfinger = ) { + open($mailq, "-|", "/usr/bin/comm -12 postfinger.$$.d postfinger.$$.n 2>/dev/null"); + while (my $postfinger = <$mailq>) { ($postf1,$postf2)=split(/=/,$postfinger,2); print ""; print ""; } - close(MAILQ); + close($mailq); print "
$postf1$postf2

"; } unlink "postfinger.*.d, postfinger.*.n"; @@ -113,8 +117,8 @@ if ($Master eq 1 ) { "privateunpriv", "chrootwakeup", "maxproccommand + args"; - open(MAILQ, "/bin/cat `$config{'postfix_config_command'} -h config_directory`/master.cf 2>/dev/null |"); - while (my $postfinger = ) { + open($mailq, "-|", "/bin/cat `$config{'postfix_config_command'} -h config_directory`/master.cf 2>/dev/null"); + while (my $postfinger = <$mailq>) { ($postf1,$postf2,$postf3,$postf4,$postf5,$postf6,$postf7,$postf8)=split(/\s+/,$postfinger,8); if ($postfinger =~ /\-o/) { print "", @@ -136,7 +140,7 @@ if ($Master eq 1 ) { if ( !grep(/^#|^\[ \]*$/,$postfinger)); } } - close(MAILQ); + close($mailq); print "
"; } @@ -144,74 +148,74 @@ if ($Permissions eq 1 ) { print '

Specific file and directory permissions


'; print ''; print ""; - open(MAILQ, "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/maildrop 2>/dev/null |"); - while (my $postfinger = ) { + open($mailq, "-|", "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/maildrop 2>/dev/null"); + while (my $postfinger = <$mailq>) { print "" if ( !grep(/total|^#|^\[ \]*$/,$postfinger)); } - close(MAILQ); + close($mailq); print ""; - open(MAILQ, "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/public 2>/dev/null |"); - while (my $postfinger = ) { + open($mailq, "-|", "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/public 2>/dev/null"); + while (my $postfinger = <$mailq>) { print "" if ( !grep(/total|^#|^\[ \]*$/,$postfinger)); } - close(MAILQ); + close($mailq); print ""; - if (! open(MAILQ, "/bin/ls -l `$config{'postfix_config_command'} -h queue_directory`/public 2>/dev/null |")) { + if (! open($mailq, "-|", "/bin/ls -l `$config{'postfix_config_command'} -h queue_directory`/public 2>/dev/null")) { print '
WARNING: No access to $queue_directory/public
Try running postfinger as user root or postfix

'; } else { - while (my $postfinger = ) { + while (my $postfinger = <$mailq>) { print "" if ( !grep(/total|^#|^\[ \]*$/,$postfinger)); } - close(MAILQ); + close($mailq); print ""; } - open(MAILQ, "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/private 2>/dev/null |"); - while (my $postfinger = ) { + open($mailq, "-|", "/bin/ls -ld `$config{'postfix_config_command'} -h queue_directory`/private 2>/dev/null"); + while (my $postfinger = <$mailq>) { print "" if ( !grep(/total|^#|^\[ \]*$/,$postfinger)); } - close(MAILQ); + close($mailq); print ""; - if (! open(MAILQ, "/bin/ls -l `$config{'postfix_config_command'} -h queue_directory`/private 2>/dev/null |")) { + if (! open($mailq, "-|", "/bin/ls -l `$config{'postfix_config_command'} -h queue_directory`/private 2>/dev/null")) { print '
WARNING: No access to $queue_directory/private
Try running postfinger as user root or postfix

'; } else { - while (my $postfinger = ) { + while (my $postfinger = <$mailq>) { print "" if ( !grep(/total|^#|^\[ \]*$/,$postfinger)); } - close(MAILQ); + close($mailq); print ""; } - open(MAILQ, "/bin/ls -l `$config{'postfix_config_command'} -h command_directory`/postdrop 2>/dev/null |"); - while (my $postfinger = ) { + open($mailq, "-|", "/bin/ls -l `$config{'postfix_config_command'} -h command_directory`/postdrop 2>/dev/null"); + while (my $postfinger = <$mailq>) { print "" if ( !grep(/total|^#|^\[ \]*$/,$postfinger)); } - close(MAILQ); + close($mailq); print ""; - open(MAILQ, "/bin/ls -l `$config{'postfix_config_command'} -h command_directory`/postqueue 2>/dev/null |"); - while (my $postfinger = ) { + open($mailq, "-|", "/bin/ls -l `$config{'postfix_config_command'} -h command_directory`/postqueue 2>/dev/null"); + while (my $postfinger = <$mailq>) { print "" if ( !grep(/total|^#|^\[ \]*$/,$postfinger)); } - close(MAILQ); + close($mailq); print "
Permission Deep Owner Group Size Date Directory/File
$postfinger
$postfinger
$postfinger
$postfinger
$postfinger
$postfinger
$postfinger

"; } if ($Libraries eq 1 ) { print '

Library dependencies

'; print ''; - if (! open(MAILQ, "/usr/bin/ldd `$config{'postfix_config_command'} -h daemon_directory`/smtpd 2>/dev/null |")) { + if (! open($mailq, "-|", "/usr/bin/ldd `$config{'postfix_config_command'} -h daemon_directory`/smtpd 2>/dev/null")) { print '
WARNING: Can not find ldd. Check you have it installed and in your path

'; } else { - while (my $postfinger = ) { + while (my $postfinger = <$mailq>) { ($postf1,$postf2)=split(/=/,$postfinger,2); print ""; print ""; } - close(MAILQ); + close($mailq); print "
$postf1=$postf2

"; } } diff --git a/postfix/postfix-lib.pl b/postfix/postfix-lib.pl index d73f4d161..7836c4afe 100755 --- a/postfix/postfix-lib.pl +++ b/postfix/postfix-lib.pl @@ -3,10 +3,26 @@ # postfix-module by Guillaume Cottenceau , # for webmin by Jamie Cameron -$POSTFIX_MODULE_VERSION = 5; +use strict; +use warnings; +no warnings 'redefine'; +no warnings 'uninitialized'; + +our $POSTFIX_MODULE_VERSION = 5; BEGIN { push(@INC, ".."); }; use WebminCore; + +# Package globals: Webmin-provided config/text/acl, plus module state and +# caches that persist or are shared across the subs below. +our (%config, %text, %access, $module_name, $module_config_directory); +our ($postfix_version, $version_file, $postfix_config_command, + $has_postfix_config_command, $config_dir, $virtual_maps, $ldap_timeout, + $save_file); +our (%maps_cache, @master_config_cache, @mail_system_cache, + @supports_map_type_cache, $connect_ldap_db_cache); +our (@header_checks_actions, @check_sender_actions); + &init_config(); %access = &get_module_acl(); $access{'postfinger'} = 0 if (&is_readonly_mode()); @@ -15,12 +31,13 @@ do 'aliases-lib.pl'; $config{'perpage'} ||= 20; # a value of 0 can cause problems # Get the saved version number +my $version_fh = "VERSION"; $version_file = "$module_config_directory/version"; $postfix_config_command = $config{'postfix_config_command'}; $has_postfix_config_command = &has_command($postfix_config_command); -if (&open_readfile(VERSION, $version_file)) { - chop($postfix_version = ); - close(VERSION); +if (&open_readfile($version_fh, $version_file)) { + chop($postfix_version = <$version_fh>); + close($version_fh); my @vst = stat($version_file); my @cst = stat($postfix_config_command); if (@cst && $cst[9] > $vst[9]) { @@ -38,9 +55,9 @@ if (!$postfix_version) { } # And save for other callers - &open_tempfile(VERSION, ">$version_file", 0, 1); - &print_tempfile(VERSION, "$postfix_version\n"); - &close_tempfile(VERSION); + &open_tempfile($version_fh, ">$version_file", 0, 1); + &print_tempfile($version_fh, "$postfix_version\n"); + &close_tempfile($version_fh); } if (&compare_version_numbers($postfix_version, 2) >= 0) { @@ -144,7 +161,7 @@ if (!defined($out) && !$nodef) { } elsif ($out =~ /warning:.*unknown\s+parameter/ || $err =~ /warning:.*unknown\s+parameter/) { - return undef; + return; } chop($out); } @@ -178,8 +195,16 @@ my $compatibility_level = &get_current_value("compatibility_level"); if ($raw_value =~ /\{\{\$compatibility_level\}\s*([<>=!]+)\s*\{(\d+)\}\s*\?\s*\{(.*?)\}\s*:\s*\{(.*?)\}\}/) { my ($op, $lvl, $tval, $fval) = ($1, $2, $3, $4); - return undef if ($op !~ /^([<>]=?|==|!=)$/); - return eval "\$compatibility_level $op $lvl" ? $tval : $fval; + my %compare = ( + '<' => sub { $_[0] < $_[1] }, + '<=' => sub { $_[0] <= $_[1] }, + '>' => sub { $_[0] > $_[1] }, + '>=' => sub { $_[0] >= $_[1] }, + '==' => sub { $_[0] == $_[1] }, + '!=' => sub { $_[0] != $_[1] }, + ); + return if (!$compare{$op}); + return $compare{$op}->($compatibility_level, $lvl) ? $tval : $fval; } return $raw_value; @@ -288,16 +313,16 @@ sub reload_postfix $cmd = $config{'reload_cmd'}; } my $ex = &system_logged("$cmd >/dev/null 2>&1"); - return $ex ? ($out || "$cmd failed") : undef; + return $ex ? "$cmd failed" : undef; } - return undef; + return; } # get_bootup_action() # Returns the name of the init script to start and stop Postfix, if found. sub get_bootup_action { -return undef if (!&foreign_check("init")); +return if (!&foreign_check("init")); &foreign_require("init"); my $name = $config{'init_name'} || 'postfix'; my $st = &init::action_status($name); @@ -481,11 +506,11 @@ sub get_aliases_files # gives a new number of alias sub init_new_alias { - $aliases = &get_aliases(); + my $aliases = &get_aliases(); my $max_number = 0; - foreach $trans (@{$aliases}) + foreach my $trans (@{$aliases}) { if ($trans->{'number'} > $max_number) { $max_number = $trans->{'number'}; } } @@ -498,11 +523,12 @@ sub init_new_alias # be taken from a MySQL or LDAP backend sub list_postfix_aliases { -local @rv; +my @rv; +my @maps; foreach my $f (&get_maps_types_files(&get_current_value("alias_maps"))) { if (&file_map_type($f->[0])) { # We can read this file directly - local $sofar = scalar(@rv); + my $sofar = scalar(@rv); foreach my $a (&list_aliases([ $f->[1] ])) { $a->{'num'} += $sofar; push(@rv, $a); @@ -515,10 +541,10 @@ foreach my $f (&get_maps_types_files(&get_current_value("alias_maps"))) { } if (@maps) { # Convert values from MySQL and LDAP maps into alias structures - local $maps = &get_maps("alias_maps", undef, join(",", @maps)); + my $maps = &get_maps("alias_maps", undef, join(",", @maps)); foreach my $m (@$maps) { - local $v = $m->{'value'}; - local @values; + my $v = $m->{'value'}; + my @values; while($v =~ /^\s*,?\s*()"([^"]+)"(.*)$/ || $v =~ /^\s*,?\s*(\|)"([^"]+)"(.*)$/ || $v =~ /^\s*,?\s*()([^,\s]+)(.*)$/) { @@ -544,10 +570,10 @@ return @rv; # Adds a new alias, either to the local file or another backend sub create_postfix_alias { -local ($alias) = @_; -local @afiles = &get_maps_types_files(&get_current_value("alias_maps")); -local $last_type = $afiles[$#afiles]->[0]; -local $last_file = $afiles[$#afiles]->[1]; +my ($alias) = @_; +my @afiles = &get_maps_types_files(&get_current_value("alias_maps")); +my $last_type = $afiles[$#afiles]->[0]; +my $last_file = $afiles[$#afiles]->[1]; if (&file_map_type($last_type)) { # Just adding to a file &create_alias($alias, [ $last_file ], 1); @@ -567,7 +593,7 @@ else { # Delete an alias, either from the files or from a MySQL or LDAP map sub delete_postfix_alias { -local ($alias) = @_; +my ($alias) = @_; if ($alias->{'map_type'}) { # This was from a map &delete_mapping("alias_maps", $alias); @@ -582,7 +608,7 @@ else { # Update an alias, either in a file or in a map sub modify_postfix_alias { -local ($oldalias, $alias) = @_; +my ($oldalias, $alias) = @_; if ($oldalias->{'map_type'}) { # In the map if (!$alias->{'enabled'}) { @@ -602,8 +628,7 @@ else { sub renumber_list { return if (!$_[2]); -local $e; -foreach $e (@{$_[0]}) { +foreach my $e (@{$_[0]}) { next if (defined($e->{'alias_file'}) && $e->{'alias_file'} ne $_[1]->{'alias_file'}); next if (defined($e->{'map_file'}) && @@ -622,7 +647,7 @@ sub save_options my %options = %{$_[0]}; - foreach $key (keys %options) + foreach my $key (keys %options) { if ($key =~ /_def$/) { @@ -648,7 +673,7 @@ sub save_options # sub regenerate_aliases { - local $out; + my $out; $access{'aliases'} || error($text{'regenerate_ecannot'}); if (get_current_value("alias_maps") eq "") { @@ -657,8 +682,7 @@ sub regenerate_aliases } else { - local $map; - foreach $map (get_maps_types_files(get_real_value("alias_maps"))) + foreach my $map (get_maps_types_files(get_real_value("alias_maps"))) { if (&file_map_type($map->[0])) { my $cmd = $config{'postfix_aliases_table_command'}; @@ -782,7 +806,7 @@ sub regenerate_any_table next unless $map; if (&file_map_type($map->[0]) && $map->[0] ne 'regexp' && $map->[0] ne 'pcre') { - local $out = &backquote_logged( + my $out = &backquote_logged( $config{'postfix_lookup_table_command'}. " -c $config_dir". ($base64 ? " -F" : ""). @@ -832,11 +856,12 @@ sub get_maps if (&file_map_type($maps_type)) { # Read a file on disk - &open_readfile(MAPS, $maps_file); + my $mapsfh = "MAPS"; + &open_readfile($mapsfh, $maps_file); my $i = 0; my $cmt; my $lastmap; - while () + while (<$mapsfh>) { s/\r|\n//g; # remove newlines if (/^\s*#+\s*(.*)/) { @@ -871,14 +896,14 @@ sub get_maps } $i++; } - close(MAPS); + close($mapsfh); } elsif ($maps_type eq "mysql") { # Get from a MySQL database - local $conf = &mysql_value_to_conf($maps_file); - local $dbh = &connect_mysql_db($conf); + my $conf = &mysql_value_to_conf($maps_file); + my $dbh = &connect_mysql_db($conf); ref($dbh) || &error($dbh); - local $cmd = $dbh->prepare( + my $cmd = $dbh->prepare( "select ".$conf->{'where_field'}. ",".$conf->{'select_field'}. " from ".$conf->{'table'}. @@ -904,12 +929,12 @@ sub get_maps } elsif ($maps_type eq "ldap") { # Get from an LDAP database - local $conf = &ldap_value_to_conf($maps_file); - local $ldap = &connect_ldap_db($conf); + my $conf = &ldap_value_to_conf($maps_file); + my $ldap = &connect_ldap_db($conf); ref($ldap) || &error($ldap); - local ($name_attr, $filter) = &get_ldap_key($conf); - local $scope = $conf->{'scope'} || 'sub'; - local $rv = $ldap->search(base => $conf->{'search_base'}, + my ($name_attr, $filter) = &get_ldap_key($conf); + my $scope = $conf->{'scope'} || 'sub'; + my $rv = $ldap->search(base => $conf->{'search_base'}, scope => $scope, filter => $filter); if (!$rv || $rv->code) { @@ -969,7 +994,7 @@ sub generate_map_edit my $nt = $_[3] || $text{'mapping_name'}; my $vt = $_[4] || $text{'mapping_value'}; - local @links = ( &ui_link("edit_mapping.cgi?map_name=$_[0]", + my @links = ( &ui_link("edit_mapping.cgi?map_name=$_[0]", $text{'new_mapping'}),); if ($access{'manual'} && &can_map_manual($_[0])) { push(@links, &ui_link("edit_manual.cgi?map_name=$_[0]", @@ -1126,10 +1151,10 @@ if (&file_map_type($maps_type)) { } elsif ($maps_type eq "mysql") { # Adding to a MySQL table - local $conf = &mysql_value_to_conf($maps_file); - local $dbh = &connect_mysql_db($conf); + my $conf = &mysql_value_to_conf($maps_file); + my $dbh = &connect_mysql_db($conf); ref($dbh) || &error($dbh); - local $cmd = $dbh->prepare("insert into ".$conf->{'table'}." ". + my $cmd = $dbh->prepare("insert into ".$conf->{'table'}." ". "(".$conf->{'where_field'}.",". $conf->{'select_field'}.") values (". "?, ?)"); @@ -1143,18 +1168,18 @@ elsif ($maps_type eq "mysql") { } elsif ($maps_type eq "ldap") { # Adding to an LDAP database - local $conf = &ldap_value_to_conf($maps_file); - local $ldap = &connect_ldap_db($conf); + my $conf = &ldap_value_to_conf($maps_file); + my $ldap = &connect_ldap_db($conf); ref($ldap) || &error($ldap); - local @classes = split(/\s+/, $config{'ldap_class'} || + my @classes = split(/\s+/, $config{'ldap_class'} || "inetLocalMailRecipient"); - local @attrs = ( "objectClass", \@classes ); - local $name_attr = &get_ldap_key($conf); + my @attrs = ( "objectClass", \@classes ); + my $name_attr = &get_ldap_key($conf); push(@attrs, $name_attr, $map->{'name'}); push(@attrs, $conf->{'result_attribute'} || "maildrop", $map->{'value'}); push(@attrs, &split_props($config{'ldap_attrs'})); - local $dn = &make_map_ldap_dn($map, $conf); + my $dn = &make_map_ldap_dn($map, $conf); if ($dn =~ /^([^=]+)=([^, ]+)/ && !&in_props(\@attrs, $1)) { push(@attrs, $1, $2); } @@ -1163,7 +1188,7 @@ elsif ($maps_type eq "ldap") { &ensure_ldap_parent($ldap, $dn); # Actually add - local $rv = $ldap->add($dn, attr => \@attrs); + my $rv = $ldap->add($dn, attr => \@attrs); if ($rv->code) { &error(&text('ldap_eadd', "$dn", "".&html_escape($rv->error)."")); @@ -1185,9 +1210,9 @@ sub delete_mapping { if (&file_map_type($_[1]->{'map_type'}) || !$_[1]->{'map_type'}) { # Deleting from a file - local $lref = &read_file_lines($_[1]->{'map_file'}); - local $dl = $lref->[$_[1]->{'eline'}]; - local $len = $_[1]->{'eline'} - $_[1]->{'line'} + 1; + my $lref = &read_file_lines($_[1]->{'map_file'}); + my $dl = $lref->[$_[1]->{'eline'}]; + my $len = $_[1]->{'eline'} - $_[1]->{'line'} + 1; if (($dl =~ /^\s*(\/[^\/]*\/[a-z]*)\s+([^#]*)/ || $dl =~ /^\s*([^\s]+)\s+([^#]*)/) && $1 eq $_[1]->{'name'}) { @@ -1201,7 +1226,7 @@ if (&file_map_type($_[1]->{'map_type'}) || !$_[1]->{'map_type'}) { } &flush_file_lines($_[1]->{'map_file'}); &renumber_list($maps_cache{$_[0]}, $_[1], -$len); - local $idx = &indexof($_[1], @{$maps_cache{$_[0]}}); + my $idx = &indexof($_[1], @{$maps_cache{$_[0]}}); if ($idx >= 0) { # Take out of cache splice(@{$maps_cache{$_[0]}}, $idx, 1); @@ -1209,10 +1234,10 @@ if (&file_map_type($_[1]->{'map_type'}) || !$_[1]->{'map_type'}) { } elsif ($_[1]->{'map_type'} eq 'mysql') { # Deleting from MySQL - local $conf = &mysql_value_to_conf($_[1]->{'map_file'}); - local $dbh = &connect_mysql_db($conf); + my $conf = &mysql_value_to_conf($_[1]->{'map_file'}); + my $dbh = &connect_mysql_db($conf); ref($dbh) || &error($dbh); - local $cmd = $dbh->prepare("delete from ".$conf->{'table'}. + my $cmd = $dbh->prepare("delete from ".$conf->{'table'}. " where ".$conf->{'where_field'}." = ?". " ".$conf->{'additional_conditions'}); if (!$cmd || !$cmd->execute($_[1]->{'key'})) { @@ -1224,10 +1249,10 @@ elsif ($_[1]->{'map_type'} eq 'mysql') { } elsif ($_[1]->{'map_type'} eq 'ldap') { # Deleting from LDAP - local $conf = &ldap_value_to_conf($_[1]->{'map_file'}); - local $ldap = &connect_ldap_db($conf); + my $conf = &ldap_value_to_conf($_[1]->{'map_file'}); + my $ldap = &connect_ldap_db($conf); ref($ldap) || &error($ldap); - local $rv = $ldap->delete($_[1]->{'dn'}); + my $rv = $ldap->delete($_[1]->{'dn'}); if ($rv->code) { my $err = $rv->error; if ($err !~ /No such object/i) { @@ -1238,7 +1263,7 @@ elsif ($_[1]->{'map_type'} eq 'ldap') { } # Delete from in-memory cache -local $idx = &indexof($_[1], @{$maps_cache{$_[0]}}); +my $idx = &indexof($_[1], @{$maps_cache{$_[0]}}); splice(@{$maps_cache{$_[0]}}, $idx, 1) if ($idx != -1); } @@ -1248,15 +1273,15 @@ sub modify_mapping { if (&file_map_type($_[1]->{'map_type'}) || !$_[1]->{'map_type'}) { # Modifying in a file - local $lref = &read_file_lines($_[1]->{'map_file'}); - local $oldlen = $_[1]->{'eline'} - $_[1]->{'line'} + 1; - local @newlines; + my $lref = &read_file_lines($_[1]->{'map_file'}); + my $oldlen = $_[1]->{'eline'} - $_[1]->{'line'} + 1; + my @newlines; push(@newlines, &make_table_comment($_[2]->{'cmt'})); push(@newlines, "$_[2]->{'name'}\t$_[2]->{'value'}"); splice(@$lref, $_[1]->{'line'}, $oldlen, @newlines); &flush_file_lines($_[1]->{'map_file'}); &renumber_list($maps_cache{$_[0]}, $_[1], scalar(@newlines)-$oldlen); - local $idx = &indexof($_[1], @{$maps_cache{$_[0]}}); + my $idx = &indexof($_[1], @{$maps_cache{$_[0]}}); if ($idx >= 0) { # Update in cache $_[2]->{'map_file'} = $_[1]->{'map_file'}; @@ -1268,10 +1293,10 @@ if (&file_map_type($_[1]->{'map_type'}) || !$_[1]->{'map_type'}) { } elsif ($_[1]->{'map_type'} eq 'mysql') { # Updating in MySQL - local $conf = &mysql_value_to_conf($_[1]->{'map_file'}); - local $dbh = &connect_mysql_db($conf); + my $conf = &mysql_value_to_conf($_[1]->{'map_file'}); + my $dbh = &connect_mysql_db($conf); ref($dbh) || &error($dbh); - local $cmd = $dbh->prepare("update ".$conf->{'table'}. + my $cmd = $dbh->prepare("update ".$conf->{'table'}. " set ".$conf->{'where_field'}." = ?,". " ".$conf->{'select_field'}." = ?". " where ".$conf->{'where_field'}." = ?". @@ -1286,25 +1311,25 @@ elsif ($_[1]->{'map_type'} eq 'mysql') { } elsif ($_[1]->{'map_type'} eq 'ldap') { # Updating in LDAP - local $conf = &ldap_value_to_conf($_[1]->{'map_file'}); - local $ldap = &connect_ldap_db($conf); + my $conf = &ldap_value_to_conf($_[1]->{'map_file'}); + my $ldap = &connect_ldap_db($conf); ref($ldap) || &error($ldap); # Work out attribute changes - local %replace; - local $name_attr = &get_ldap_key($conf); + my %replace; + my $name_attr = &get_ldap_key($conf); $replace{$name_attr} = [ $_[2]->{'name'} ]; $replace{$conf->{'result_attribute'} || "maildrop"} = [ $_[2]->{'value'} ]; # Work out new DN, if needed - local $newdn = &make_map_ldap_dn($_[2], $conf); + my $newdn = &make_map_ldap_dn($_[2], $conf); if ($_[1]->{'name'} ne $_[2]->{'name'} && $_[1]->{'dn'} ne $newdn) { # Changed .. update the object in LDAP &ensure_ldap_parent($ldap, $newdn); - local ($newprefix, $newrest) = split(/,/, $newdn, 2); - local $rv = $ldap->moddn($_[1]->{'dn'}, + my ($newprefix, $newrest) = split(/,/, $newdn, 2); + my $rv = $ldap->moddn($_[1]->{'dn'}, newrdn => $newprefix, newsuperior => $newrest); if ($rv->code) { @@ -1323,7 +1348,7 @@ elsif ($_[1]->{'map_type'} eq 'ldap') { } # Modify attributes - local $rv = $ldap->modify($_[2]->{'dn'}, replace => \%replace); + my $rv = $ldap->modify($_[2]->{'dn'}, replace => \%replace); if ($rv->code) { &error(&text('ldap_emodify', "$_[2]->{'dn'}", @@ -1332,7 +1357,7 @@ elsif ($_[1]->{'map_type'} eq 'ldap') { } # Update in-memory cache -local $idx = &indexof($_[1], @{$maps_cache{$_[0]}}); +my $idx = &indexof($_[1], @{$maps_cache{$_[0]}}); $_[2]->{'map_file'} = $_[1]->{'map_file'}; $_[2]->{'map_type'} = $_[1]->{'map_type'}; $_[2]->{'file'} = $_[1]->{'file'}; @@ -1345,11 +1370,11 @@ $maps_cache{$_[0]}->[$idx] = $_[2] if ($idx != -1); # Work out an LDAP DN for a map sub make_map_ldap_dn { -local ($map, $conf) = @_; -local $dn; -local $scope = $conf->{'scope'} || 'sub'; +my ($map, $conf) = @_; +my $dn; +my $scope = $conf->{'scope'} || 'sub'; $scope = 'base' if (!$config{'ldap_doms'}); # Never create sub-domains -local $id = $config{'ldap_id'} || 'cn'; +my $id = $config{'ldap_id'} || 'cn'; if ($map->{'name'} =~ /^(\S+)\@(\S+)$/ && $scope ne 'base') { # Within a domain $dn = "$id=$1,cn=$2,$conf->{'search_base'}"; @@ -1369,8 +1394,8 @@ return $dn; # Returns the attribute name for the LDAP key. May call &error sub get_ldap_key { -local ($conf) = @_; -local ($filter, $name_attr) = @_; +my ($conf) = @_; +my ($filter, $name_attr) = @_; if ($conf->{'query_filter'}) { $filter = $conf->{'query_filter'}; $conf->{'query_filter'} =~ /([a-z0-9]+)=\%[su]/i || @@ -1391,17 +1416,17 @@ return wantarray ? ( $name_attr, $filter ) : $name_attr; # Create the parent of some DN if needed sub ensure_ldap_parent { -local ($ldap, $dn) = @_; -local $pdn = $dn; +my ($ldap, $dn) = @_; +my $pdn = $dn; $pdn =~ s/^([^,]+),//; -local $rv = $ldap->search(base => $pdn, scope => 'base', +my $rv = $ldap->search(base => $pdn, scope => 'base', filter => "(objectClass=top)", sizelimit => 1); if (!$rv || $rv->code || !$rv->all_entries) { # Does not .. so add it - local @pclasses = ( "top" ); - local @pattrs = ( "objectClass", \@pclasses ); - local $rv = $ldap->add($pdn, attr => \@pattrs); + my @pclasses = ( "top" ); + my @pattrs = ( "objectClass", \@pclasses ); + my $rv = $ldap->add($pdn, attr => \@pattrs); } } @@ -1411,7 +1436,7 @@ sub init_new_mapping { my $maps = &get_maps($_[0]); my $max_number = 0; -foreach $trans (@{$maps}) { +foreach my $trans (@{$maps}) { if ($trans->{'number'} > $max_number) { $max_number = $trans->{'number'}; } @@ -1422,7 +1447,7 @@ return $max_number+1; # postfix_mail_file(user|user-details-list) sub postfix_mail_file { -local @s = &postfix_mail_system(); +my @s = &postfix_mail_system(); if ($s[0] == 0) { return "$s[1]/$_[0]"; } @@ -1430,7 +1455,7 @@ elsif (@_ > 1) { return "$_[7]/$s[1]"; } else { - local @u = getpwnam($_[0]); + my @u = getpwnam($_[0]); return "$u[7]/$s[1]"; } } @@ -1442,13 +1467,13 @@ else { sub postfix_mail_system { if (!scalar(@mail_system_cache)) { - local $home_mailbox = &get_current_value("home_mailbox"); + my $home_mailbox = &get_current_value("home_mailbox"); if ($home_mailbox) { @mail_system_cache = $home_mailbox =~ /^(.*)\/$/ ? (2, $1) : (1, $home_mailbox); } else { - local $mail_spool_directory = + my $mail_spool_directory = &get_current_value("mail_spool_directory"); @mail_system_cache = (0, $mail_spool_directory); } @@ -1460,18 +1485,18 @@ return wantarray ? @mail_system_cache : $mail_system_cache[0]; # Returns a list of strutures, each containing details of one queued message sub list_queue { -local ($throw) = @_; -local @qfiles; -local $out = &backquote_command("$config{'mailq_cmd'} 2>&1 &1 $1, 'size' => $2, + my $q = { 'id' => $1, 'size' => $2, 'date' => $3, 'from' => $4 }; if (defined(&parse_mail_date)) { - local $t = &parse_mail_date($q->{'date'}); + my $t = &parse_mail_date($q->{'date'}); if ($t) { $q->{'date'} = &make_date($t, 0, 'yyyy/mm/dd'); $q->{'time'} = $t; @@ -1482,7 +1507,7 @@ foreach my $l (split(/\r?\n/, $out)) { my $path = "$config{'mailq_dir'}/$dir/$f/$q->{'id'}"; if (-r $path) { $q->{'dir'} = $dir; - $q->{'file'} = $file; + $q->{'file'} = $path; last; } } @@ -1507,15 +1532,16 @@ return ("active", "incoming", "deferred", "corrupt", "hold", "maildrop"); # Parses a postfix mail queue file into a standard mail structure sub parse_queue_file { -local ($f) = @_; -local @qfiles = map { &recurse_files("$config{'mailq_dir'}/$_") } +my ($f) = @_; +my @qfiles = map { &recurse_files("$config{'mailq_dir'}/$_") } &list_mailq_directories(); -local ($file) = grep { $_ =~ /\/$f$/ } @qfiles; -return undef if (!$file); -local $mode = 0; -local ($mail, @headers); -&open_execute_command(QUEUE, "$config{'postcat_cmd'} ".quotemeta($file), 1, 1); -while() { +my ($file) = grep { $_ =~ /\/$f$/ } @qfiles; +return if (!$file); +my $mode = 0; +my ($mail, @headers); +my $queuefh = "QUEUE"; +&open_execute_command($queuefh, "$config{'postcat_cmd'} ".quotemeta($file), 1, 1); +while(<$queuefh>) { if (/^\*\*\*\s+MESSAGE\s+CONTENTS/ && !$mode) { # Start of headers $mode = 1; } @@ -1536,9 +1562,9 @@ while() { $mail->{'body'} .= $_; } } -close(QUEUE); +close($queuefh); $mail->{'headers'} = \@headers; -foreach $h (@headers) { +foreach my $h (@headers) { $mail->{'header'}->{lc($h->[0])} = $h->[1]; } $mail->{'file'} = $file; @@ -1553,11 +1579,11 @@ return $mail; # recurse_files(dir) sub recurse_files { -opendir(DIR, &translate_filename($_[0])) || return ( $_[0] ); -local @dir = readdir(DIR); -closedir(DIR); -local ($f, @rv); -foreach $f (@dir) { +opendir(my $dirh, &translate_filename($_[0])) || return ( $_[0] ); +my @dir = readdir($dirh); +closedir($dirh); +my @rv; +foreach my $f (@dir) { push(@rv, &recurse_files("$_[0]/$f")) if ($f !~ /^\./); } return @rv; @@ -1565,7 +1591,7 @@ return @rv; sub sort_by_domain { -local ($a1, $a2, $b1, $b2); +my ($a1, $a2, $b1, $b2); if ($a->{'name'} =~ /^(.*)\@(.*)$/ && (($a1, $a2) = ($1, $2)) && $b->{'name'} =~ /^(.*)\@(.*)$/ && (($b1, $b2) = ($1, $2))) { return $a2 cmp $b2 ? $a2 cmp $b2 : $a1 cmp $b1; @@ -1589,7 +1615,7 @@ if ($config{'check_config'} && !defined($save_file)) { sub after_save { if (defined($save_file)) { - local $err = &check_postfix(); + my $err = &check_postfix(); if ($err) { ©_source_dest($save_file, $config{'postfix_config_file'}); &unlink_file($save_file); @@ -1627,9 +1653,10 @@ sub ensure_map { foreach my $mf (&get_maps_files(&get_real_value($_[0]))) { if ($mf =~ /^\// && !-e $mf) { - &open_lock_tempfile(TOUCH, ">$mf", 1) || + my $touchfh = "TOUCH"; + &open_lock_tempfile($touchfh, ">$mf", 1) || &error(&text("efilewrite", $mf, $!)); - &close_tempfile(TOUCH); + &close_tempfile($touchfh); &set_ownership_permissions(undef, undef, 0755, $mf); } } @@ -1650,7 +1677,7 @@ return $_[1]->{'name'}; sub edit_value_header_checks { -local ($act, $dest) = split(/\s+/, $_[0]->{'value'}, 2); +my ($act, $dest) = split(/\s+/, $_[0]->{'value'}, 2); return &ui_table_row($text{'header_value'}, &ui_select("action", $act, [ map { [ $_, $text{'header_'.lc($_)} ] } @@ -1660,7 +1687,7 @@ return &ui_table_row($text{'header_value'}, sub parse_value_header_checks { -local $rv = $_[1]->{'action'}; +my $rv = $_[1]->{'action'}; if ($_[1]->{'value'}) { $rv .= " ".$_[1]->{'value'}; } @@ -1716,7 +1743,7 @@ return "$text{'access_addresses'}\n". sub edit_value_check_sender_access { -local ($act, $dest) = split(/\s+/, $_[0]->{'value'}, 2); +my ($act, $dest) = split(/\s+/, $_[0]->{'value'}, 2); return "$text{'header_value'}\n". "".&ui_select("action", $act, [ map { [ $_, $text{'header_'.lc($_)} ] } @@ -1742,10 +1769,11 @@ sub get_master_config { if (!scalar(@master_config_cache)) { @master_config_cache = ( ); - local $lnum = 0; - local $prog; - open(MASTER, "<".$config{'postfix_master'}); - while() { + my $lnum = 0; + my $prog; + open(my $masterfh, "<", $config{'postfix_master'}) || + return \@master_config_cache; + while(<$masterfh>) { s/\r|\n//g; if (/^(#?)\s*(\S+)\s+(inet|unix|fifo)\s+(y|n|\-)\s+(y|n|\-)\s+(y|n|\-)\s+(\S+)\s+(\S+)\s+(.*)$/) { # A program line @@ -1772,7 +1800,7 @@ if (!scalar(@master_config_cache)) { } $lnum++; } - close(MASTER); + close($masterfh); } return \@master_config_cache; } @@ -1781,9 +1809,9 @@ return \@master_config_cache; # Adds a new Postfix server process sub create_master { -local ($master) = @_; -local $conf = &get_master_config(); -local $lref = &read_file_lines($config{'postfix_master'}); +my ($master) = @_; +my $conf = &get_master_config(); +my $lref = &read_file_lines($config{'postfix_master'}); push(@$lref, &master_line($master)); &flush_file_lines($config{'postfix_master'}); $master->{'line'} = scalar(@$lref)-1; @@ -1795,10 +1823,10 @@ push(@$conf, $master); # Removes one Postfix server process sub delete_master { -local ($master) = @_; -local $conf = &get_master_config(); -local $lref = &read_file_lines($config{'postfix_master'}); -local $lines = $master->{'eline'} - $master->{'line'} + 1; +my ($master) = @_; +my $conf = &get_master_config(); +my $lref = &read_file_lines($config{'postfix_master'}); +my $lines = $master->{'eline'} - $master->{'line'} + 1; splice(@$lref, $master->{'line'}, $lines); &flush_file_lines($config{'postfix_master'}); @$conf = grep { $_ ne $master } @$conf; @@ -1814,10 +1842,10 @@ foreach my $c (@$conf) { # Updates one Postfix server process sub modify_master { -local ($master) = @_; -local $conf = &get_master_config(); -local $lref = &read_file_lines($config{'postfix_master'}); -local $lines = $master->{'eline'} - $master->{'line'} + 1; +my ($master) = @_; +my $conf = &get_master_config(); +my $lref = &read_file_lines($config{'postfix_master'}); +my $lines = $master->{'eline'} - $master->{'line'} + 1; splice(@$lref, $master->{'line'}, $lines, &master_line($master)); &flush_file_lines($config{'postfix_master'}); @@ -1832,7 +1860,7 @@ foreach my $c (@$conf) { # master_line(&master) sub master_line { -local ($prog) = @_; +my ($prog) = @_; return ($prog->{'enabled'} ? "" : "#"). join("\t", $prog->{'name'}, $prog->{'type'}, $prog->{'private'}, $prog->{'unpriv'}, $prog->{'chroot'}, $prog->{'wakeup'}, @@ -1841,7 +1869,7 @@ return ($prog->{'enabled'} ? "" : "#"). sub redirect_to_map_list { -local ($map_name) = @_; +my ($map_name) = @_; if ($map_name =~ /sender_dependent_default_transport_maps/) { redirect("dependent.cgi"); } @@ -1861,7 +1889,7 @@ else { &redirect(""); } sub regenerate_map_table { -local ($map_name) = @_; +my ($map_name) = @_; if ($map_name =~ /canonical/) { ®enerate_canonical_table(); } if ($map_name =~ /relocated/) { ®enerate_relocated_table(); } if ($map_name =~ /virtual/) { ®enerate_virtual_table(); } @@ -1889,16 +1917,16 @@ if ($map_name =~ /smtpd_sender_restrictions/) { # Print a table of queued mail messages sub mailq_table { -local ($qfiles) = @_; +my ($qfiles) = @_; # Build table data my @table; foreach my $q (@$qfiles) { - local @cols; + my @cols; push(@cols, { 'type' => 'checkbox', 'name' => 'file', 'value' => $q->{'id'} }); push(@cols, &ui_link("view_mailq.cgi?id=$q->{'id'}",$q->{'id'})); - local $size = &nice_size($q->{'size'}); + my $size = &nice_size($q->{'size'}); push(@cols, $q->{'date'}); push(@cols, &html_escape($q->{'from'})); push(@cols, &html_escape($q->{'to'})); @@ -1931,7 +1959,7 @@ print &ui_form_columns_table("delete_queues.cgi", # Returns the comment text if a line contains a comment, like # foo sub is_table_comment { -local ($line, $force) = @_; +my ($line, $force) = @_; if ($config{'prefix_cmts'} || $force) { return $line =~ /^\s*#+\s*Webmin:\s*(.*)/ ? $1 : undef; } @@ -1944,7 +1972,7 @@ else { # Returns an array of lines for a comment in a map file, like # foo sub make_table_comment { -local ($cmt, $force) = @_; +my ($cmt, $force) = @_; if (!$cmt) { return ( ); } @@ -1976,7 +2004,7 @@ sub unlock_postfix_files # Returns HTML for a button for popping up a map file chooser sub map_chooser_button { -local ($name, $mapname) = @_; +my ($name, $mapname) = @_; return &popup_window_button("map_chooser.cgi?mapname=$mapname", 1024, 600, 1, [ [ "ifield", $name, "map" ] ]); } @@ -2000,7 +2028,7 @@ return @rv; # Returns a list of global MySQL source names in main.cf sub list_mysql_sources { -local @rv; +my @rv; my $lref = &read_file_lines($config{'postfix_config_file'}); foreach my $l (@$lref) { if ($l =~ /^\s*(\S+)_dbname\s*=/) { @@ -2015,9 +2043,9 @@ return @rv; # config file. sub get_backend_config { -local ($file) = @_; -local %rv; -local $lref = &read_file_lines($file, 1); +my ($file) = @_; +my %rv; +my $lref = &read_file_lines($file, 1); foreach my $l (@$lref) { if ($l =~ /^\s*([a-z0-9\_]+)\s*=\s*(.*)/i) { $rv{$1} = $2; @@ -2030,9 +2058,9 @@ return \%rv; # Updates one setting in a backend config file sub save_backend_config { -local ($file, $name, $value) = @_; -local $lref = &read_file_lines($file); -local $found = 0; +my ($file, $name, $value) = @_; +my $lref = &read_file_lines($file); +my $found = 0; for(my $i=0; $i<@$lref; $i++) { if ($lref->[$i] =~ /^\s*([a-z0-9\_]+)\s*=\s*(.*)/i && $1 eq $name) { @@ -2056,16 +2084,16 @@ if (!$found && defined($value)) { # Checks if some map (such as a database) can be accessed sub can_access_map { -local ($type, $value) = @_; +my ($type, $value) = @_; if (&file_map_type($type)) { - return undef; # Always can + return; # Always can } elsif ($type eq "mysql") { # Parse config, connect to DB - local $conf; + my $conf; if ($value =~ /^[\/\.]/) { # Config file - local $cfile = $value; + my $cfile = $value; if ($cfile !~ /^\//) { $cfile = &guess_config_dir()."/".$cfile; } @@ -2085,11 +2113,11 @@ elsif ($type eq "mysql") { } } # Try a connect, and a query - local $dbh = &connect_mysql_db($conf); + my $dbh = &connect_mysql_db($conf); if (!ref($dbh)) { return $dbh; } - local $cmd = $dbh->prepare("select ".$conf->{'select_field'}." ". + my $cmd = $dbh->prepare("select ".$conf->{'select_field'}." ". "from ".$conf->{'table'}." ". "where ".$conf->{'where_field'}." = ". $conf->{'where_field'}." ". @@ -2101,21 +2129,21 @@ elsif ($type eq "mysql") { } $cmd->finish(); $dbh->disconnect(); - return undef; + return; } elsif ($type eq "ldap") { # Parse config, connect to LDAP server - local $conf = &ldap_value_to_conf($value); + my $conf = &ldap_value_to_conf($value); $conf->{'search_base'} || return &text('ldap_esource', $value); # Try a connect and a search - local $ldap = &connect_ldap_db($conf); + my $ldap = &connect_ldap_db($conf); if (!ref($ldap)) { return $ldap; } - local @classes = split(/\s+/, $config{'ldap_class'} || + my @classes = split(/\s+/, $config{'ldap_class'} || "inetLocalMailRecipient"); - local $rv = $ldap->search(base => $conf->{'search_base'}, + my $rv = $ldap->search(base => $conf->{'search_base'}, filter => "(objectClass=$classes[0])", sizelimit => 1); if (!$rv || $rv->code && !$rv->all_entries) { @@ -2123,7 +2151,7 @@ elsif ($type eq "ldap") { $rv ? $rv->error : "Unknown search error"); } - return undef; + return; } else { return &text('map_unknown', "$type"); @@ -2135,21 +2163,16 @@ else { # a driver handle on success, or an error message string on failure. sub connect_mysql_db { -local ($conf) = @_; -local $driver = "mysql"; -local $drh; -eval <install_driver(\$driver); -EOF -if ($@) { - return &text('mysql_edriver', "DBD::$driver"); - } -local @hosts = split(/\s+/, $config{'mysql_hosts'} || $conf->{'hosts'}); +my ($conf) = @_; +my $driver = "mysql"; +my $drh; +eval { require DBI; DBI->import; $drh = DBI->install_driver($driver); 1 } + or return &text('mysql_edriver', "DBD::$driver"); +my @hosts = split(/\s+/, $config{'mysql_hosts'} || $conf->{'hosts'}); @hosts = ( undef ) if (!@hosts); # Localhost only -local $dbh; +my $dbh; foreach my $host (@hosts) { - local $dbistr = "database=$conf->{'dbname'}"; + my $dbistr = "database=$conf->{'dbname'}"; if ($host =~ /^unix:(.*)$/) { # Socket file $dbistr .= ";mysql_socket=$1"; @@ -2174,19 +2197,17 @@ return $dbh; # a driver handle on success, or an error message string on failure. sub connect_ldap_db { -local ($conf) = @_; +my ($conf) = @_; if (defined($connect_ldap_db_cache)) { return $connect_ldap_db_cache; } -eval "use Net::LDAP"; -if ($@) { - return &text('ldap_eldapmod', "Net::LDAP"); - } -local @servers = split(/\s+/, $config{'ldap_host'} || +eval { require Net::LDAP; Net::LDAP->import; 1 } + or return &text('ldap_eldapmod', "Net::LDAP"); +my @servers = split(/\s+/, $config{'ldap_host'} || $conf->{'server_host'} || "localhost"); -local ($ldap, $lasterr); +my ($ldap, $lasterr); foreach my $server (@servers) { - local ($host, $port, $tls); + my ($host, $port, $tls); if ($server =~ /^(\S+):(\d+)$/) { # Host and port ($host, $port) = ($1, $2); @@ -2213,7 +2234,7 @@ foreach my $server (@servers) { $ldap->start_tls; } if ($conf->{'bind'} eq 'yes' || $config{'ldap_user'}) { - local $mesg = $ldap->bind( + my $mesg = $ldap->bind( dn => $config{'ldap_user'} || $conf->{'bind_dn'}, password => $config{'ldap_pass'} || $conf->{'bind_pw'}); if (!$mesg || $mesg->code) { @@ -2242,11 +2263,11 @@ else { # Converts a MySQL config file or source name to a config hash ref sub mysql_value_to_conf { -local ($value) = @_; -local $conf; +my ($value) = @_; +my $conf; if ($value =~ /^[\/\.]/) { # Config file - local $cfile = $value; + my $cfile = $value; if ($cfile !~ /^\//) { $cfile = &guess_config_dir()."/".$cfile; } @@ -2268,7 +2289,7 @@ else { foreach my $k ("hosts", "dbname", "user", "password", "query", "table", "where_field", "select_field", "additional_conditions") { - local $v = &get_real_value($value."_".$k); + my $v = &get_real_value($value."_".$k); $conf->{$k} = $v; } if ($conf->{'query'} =~ /^select\s+(\S+)\s+from\s+(\S+)\s+where\s+(\S+)\s*=\s*'\%s'\s*(.*)/i && !$conf->{'table'}) { @@ -2286,9 +2307,9 @@ return $conf; # Converts an LDAP config file name to a config hash ref sub ldap_value_to_conf { -local ($value) = @_; -local $conf; -local $cfile = $value; +my ($value) = @_; +my $conf; +my $cfile = $value; if ($cfile !~ /^\//) { $cfile = &guess_config_dir()."/".$cfile; } @@ -2300,7 +2321,7 @@ return &get_backend_config($cfile); # Returns 1 if some map can have comments. Not allowed for MySQL and LDAP. sub can_map_comments { -local ($name) = @_; +my ($name) = @_; foreach my $tv (&get_maps_types_files(&get_real_value($name))) { return 0 if (!&file_map_type($tv->[0])); } @@ -2311,7 +2332,7 @@ return 1; # Returns 1 if osme map has a file that can be manually edited sub can_map_manual { -local ($name) = @_; +my ($name) = @_; foreach my $tv (&get_maps_types_files(&get_real_value($name))) { return 0 if (!&file_map_type($tv->[0])); } @@ -2322,15 +2343,15 @@ return 1; # Returns 1 if a map of some type is supported by Postfix sub supports_map_type { -local ($type) = @_; +my ($type) = @_; if (!scalar(@supports_map_type_cache)) { - @supports_map_type = ( ); - open(POSTCONF, "$config{'postfix_config_command'} -m |"); - while() { + @supports_map_type_cache = ( ); + open(my $postconffh, "-|", "$config{'postfix_config_command'} -m"); + while(<$postconffh>) { s/\r|\n//g; push(@supports_map_type_cache, $_); } - close(POSTCONF); + close($postconffh); } return &indexoflc($type, @supports_map_type_cache) >= 0; } @@ -2339,17 +2360,16 @@ return &indexoflc($type, @supports_map_type_cache) >= 0; # Converts multiple lines of text into LDAP attributes sub split_props { -local ($text) = @_; -local %pmap; -foreach $p (split(/\t+/, $text)) { +my ($text) = @_; +my %pmap; +foreach my $p (split(/\t+/, $text)) { if ($p =~ /^(\S+):\s*(.*)/) { push(@{$pmap{$1}}, $2); } } -local @rv; -local $k; -foreach $k (keys %pmap) { - local $v = $pmap{$k}; +my @rv; +foreach my $k (keys %pmap) { + my $v = $pmap{$k}; if (@$v == 1) { push(@rv, $k, $v->[0]); } @@ -2402,7 +2422,7 @@ return ( "check_client_access", sub file_map_type { -local ($type) = @_; +my ($type) = @_; return 1 if ($type eq 'hash' || $type eq 'regexp' || $type eq 'pcre' || $type eq 'btree' || $type eq 'dbm' || $type eq 'cidr' || $type eq 'lmdb'); @@ -2413,13 +2433,13 @@ return 0; # Looks up the value of a named property in a list sub in_props { -local ($props, $name) = @_; +my ($props, $name) = @_; for(my $i=0; $i<@$props; $i++) { if (lc($props->[$i]) eq lc($name)) { return $props->[$i+1]; } } -return undef; +return; } # For calling from aliases-lib only @@ -2460,13 +2480,13 @@ push(@rv, &get_maps_files("relay_recipient_maps")); push(@rv, &get_maps_files("smtpd_sender_restrictions")); # Add other files in /etc/postfix -local $cdir = &guess_config_dir(); -opendir(DIR, $cdir); -foreach $f (readdir(DIR)) { +my $cdir = &guess_config_dir(); +opendir(my $cdirh, $cdir); +foreach my $f (readdir($cdirh)) { next if ($f eq "." || $f eq ".." || $f =~ /\.(db|dir|pag)$/i); push(@rv, "$cdir/$f"); } -closedir(DIR); +closedir($cdirh); # Add TLS files foreach my $o ("smtpd_tls_cert_file", "smtpd_tls_key_file","smtpd_tls_CAfile") { diff --git a/postfix/postinstall.pl b/postfix/postinstall.pl index 9868e8e00..e5dccb485 100644 --- a/postfix/postinstall.pl +++ b/postfix/postinstall.pl @@ -1,4 +1,7 @@ -require 'postfix-lib.pl'; +require 'postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($version_file); sub module_install { diff --git a/postfix/rate.cgi b/postfix/rate.cgi index 10177941b..968f9e14a 100755 --- a/postfix/rate.cgi +++ b/postfix/rate.cgi @@ -7,7 +7,10 @@ # # << Here are all options seen in Postfix sample-rate.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($default, $no_, $none, %access, %text); $access{'rate'} || &error($text{'rate_ecannot'}); diff --git a/postfix/reload.cgi b/postfix/reload.cgi index bf914aad0..28f60e8f7 100755 --- a/postfix/reload.cgi +++ b/postfix/reload.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Have Postfix re-read its config -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %text); $access{'startstop'} || &error($text{'reload_ecannot'}); &error_setup($text{'reload_efailed'}); diff --git a/postfix/relocated.cgi b/postfix/relocated.cgi index 9207ac74e..dcf1c8c3f 100755 --- a/postfix/relocated.cgi +++ b/postfix/relocated.cgi @@ -8,7 +8,10 @@ # << Here are all options seen in Postfix sample-relocated.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our (%access, %text); &ReadParse(); $access{'relocated'} || &error($text{'relocated_ecannot'}); diff --git a/postfix/resource.cgi b/postfix/resource.cgi index 03b48b0b0..3add23440 100755 --- a/postfix/resource.cgi +++ b/postfix/resource.cgi @@ -7,7 +7,10 @@ # # << Here are all options seen in Postfix sample-resource.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($default, $no_, $none, %access, %text); $access{'resource'} || &error($text{'resource_ecannot'}); diff --git a/postfix/sasl.cgi b/postfix/sasl.cgi index 863751487..0009f4a2d 100755 --- a/postfix/sasl.cgi +++ b/postfix/sasl.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Show SMTP authentication related parameters -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($default, $level, $no_, $none, $pmap, $postfix_version, $rh, $rpass, $ruser, %access, @cbs, %opts, %recip, %relay, %text); $access{'sasl'} || &error($text{'sasl_ecannot'}); &ui_print_header(undef, $text{'sasl_title'}, ""); @@ -23,7 +26,7 @@ print &ui_table_start($text{'sasl_title'}, "width=100%", 2); %opts = map { $_, 1 } split(/[\s,]+/, &get_current_value("smtpd_sasl_security_options")); @cbs = ( ); -foreach $o ("noanonymous", "noplaintext", "noactive", "nodictionary", "forward_secrecy") { +foreach my $o ("noanonymous", "noplaintext", "noactive", "nodictionary", "forward_secrecy") { push(@cbs, &ui_checkbox("sasl_opts", $o, $text{'sasl_'.$o}, $opts{$o})); } print &ui_table_row($text{'sasl_opts'}, join("
\n", @cbs), 3); @@ -32,7 +35,7 @@ print &ui_table_row($text{'sasl_opts'}, join("
\n", @cbs), 3); %recip = map { $_, 1 } split(/[\s,]+/, &get_current_value("smtpd_recipient_restrictions")); @cbs = ( ); -foreach $o (&list_smtpd_restrictions()) { +foreach my $o (&list_smtpd_restrictions()) { push(@cbs, &ui_checkbox("sasl_recip", $o, $text{'sasl_'.$o}, $recip{$o})); } @@ -42,7 +45,7 @@ print &ui_table_row($text{'sasl_recip'}, join("
\n", @cbs), 3); %relay = map { $_, 1 } split(/[\s,]+/, &get_current_value("smtpd_relay_restrictions")); @cbs = ( ); -foreach $o (&list_smtpd_restrictions()) { +foreach my $o (&list_smtpd_restrictions()) { push(@cbs, &ui_checkbox("sasl_relay", $o, $text{'sasl_'.$o}, $relay{$o})); } diff --git a/postfix/save_alias.cgi b/postfix/save_alias.cgi index 75dd700f6..ebe35bfc7 100755 --- a/postfix/save_alias.cgi +++ b/postfix/save_alias.cgi @@ -6,7 +6,10 @@ # Save, modify, delete an alias for Postfix -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, $i, $loga, $module_config_directory, $t, $v, %access, @afiles, @aliases, %in, %newa, %text, @values); &ReadParse(); $access{'aliases'} || &error($text{'aliases_ecannot'}); @@ -15,21 +18,22 @@ $access{'aliases'} || &error($text{'aliases_ecannot'}); # Get the alias (if editing or deleting) @afiles = &get_aliases_files(&get_current_value("alias_maps")); @aliases = &list_postfix_aliases(); +my $alias; if (!$in{'new'}) { - $a = $aliases[$in{'num'}]; + $alias = $aliases[$in{'num'}]; } &lock_alias_files(\@afiles); if ($in{'delete'}) { # delete some alias - &delete_postfix_alias($a); - $loga = $a; + &delete_postfix_alias($alias); + $loga = $alias; } else { # saving or creating .. check inputs $in{'name'} =~ /^[^:@ ]+$/ || &error(&text('asave_eaddr', $in{'name'})); - if ($in{'new'} || uc($a->{'name'}) ne uc($in{'name'})) { + if ($in{'new'} || uc($alias->{'name'}) ne uc($in{'name'})) { # is this name taken? for($i=0; $i<@aliases; $i++) { if (uc($in{'name'}) eq uc($aliases[$i]->{'name'})) { @@ -86,7 +90,7 @@ else { &create_postfix_alias(\%newa); } else { - &modify_postfix_alias($a, \%newa); + &modify_postfix_alias($alias, \%newa); } $loga = \%newa; } diff --git a/postfix/save_client.cgi b/postfix/save_client.cgi index b5ccd2852..fc14789c8 100755 --- a/postfix/save_client.cgi +++ b/postfix/save_client.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Save SMTP authentication options -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %in, %newopts, %oldopts, @opts, %text, @v); &ReadParse(); @@ -23,7 +26,7 @@ else { %newopts = map { $_, 1 } split(/\0/, $in{'client'}); # Save boolean options - foreach $o (&list_client_restrictions()) { + foreach my $o (&list_client_restrictions()) { if ($newopts{$o} && !$oldopts{$o}) { push(@opts, $o); } @@ -33,9 +36,9 @@ else { } # Save options with values - foreach $o (&list_multi_client_restrictions()) { + foreach my $o (&list_multi_client_restrictions()) { # Find all current positions - local @pos; + my @pos; for(my $i=0; $i<@opts; $i++) { push(@pos, $i) if ($opts[$i] eq $o); } diff --git a/postfix/save_manual.cgi b/postfix/save_manual.cgi index 57718ac0d..0a0229476 100755 --- a/postfix/save_manual.cgi +++ b/postfix/save_manual.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Update a manually edited map file -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, @files, %in, %text); &ReadParseMime(); &error_setup($text{'manual_err'}); $access{'manual'} || &error($text{'manual_ecannot'}); @@ -10,9 +13,10 @@ $access{'manual'} || &error($text{'manual_ecannot'}); # Save the data $in{'data'} =~ s/\r//g; -&open_lock_tempfile(FILE, ">$in{'file'}"); -&print_tempfile(FILE, $in{'data'}); -&close_tempfile(FILE); +my $filefh = "FILE"; +&open_lock_tempfile($filefh, ">$in{'file'}"); +&print_tempfile($filefh, $in{'data'}); +&close_tempfile($filefh); # Regenerate map ®enerate_map_table($in{'map_name'}); diff --git a/postfix/save_map.cgi b/postfix/save_map.cgi index 62e88533a..a70b5ae9e 100755 --- a/postfix/save_map.cgi +++ b/postfix/save_map.cgi @@ -6,7 +6,10 @@ # Save, modify, delete a map for Postfix -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($action, $err, $logmap, $nfunc, $vfunc, $whatfailed, %access, %in, %text); &ReadParse(); @@ -21,7 +24,7 @@ my $add = 1; my %map; ## added to split main_parameter:sub_parameter my ($mainparm,$subparm)=split /:/,$in{'map_name'}; -foreach $trans (@{$maps}) +foreach my $trans (@{$maps}) { if ($trans->{'number'} == $in{'num'}) { $add = 0; %map = %{$trans}; } } @@ -75,7 +78,7 @@ if ($in{'delete'}) elsif ($add == 0) { # modify an existing map - local %newmap = ( 'name' => $in{'name'}, + my %newmap = ( 'name' => $in{'name'}, 'value' => $in{'value'}, 'cmt' => $in{'cmt'} ); &modify_mapping($in{'map_name'}, \%map, \%newmap); @@ -85,7 +88,7 @@ elsif ($add == 0) else { # add a new map -- much more easy! :-) - local %newmap = ( 'name' => $in{'name'}, + my %newmap = ( 'name' => $in{'name'}, 'value' => $in{'value'}, 'cmt' => $in{'cmt'} ); &create_mapping($in{'map_name'}, \%newmap); diff --git a/postfix/save_master.cgi b/postfix/save_master.cgi index b24365b73..243c7d379 100755 --- a/postfix/save_master.cgi +++ b/postfix/save_master.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Create, update or delete a server process -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($clash, $err, $master, $prog, %access, %config, %in, %text); $access{'master'} || &error($text{'master_ecannot'}); &ReadParse(); &error_setup($text{'master_err'}); diff --git a/postfix/save_opts.cgi b/postfix/save_opts.cgi index 8fd04612f..9000a82e7 100755 --- a/postfix/save_opts.cgi +++ b/postfix/save_opts.cgi @@ -6,7 +6,10 @@ # Save Postfix options -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %in, %text); &ReadParse(); diff --git a/postfix/save_opts_aliases.cgi b/postfix/save_opts_aliases.cgi index 3aa4e8eb5..19f936160 100755 --- a/postfix/save_opts_aliases.cgi +++ b/postfix/save_opts_aliases.cgi @@ -6,7 +6,10 @@ # Save Postfix options ; special because for aliases -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %in, %text); &ReadParse(); diff --git a/postfix/save_opts_bcc.cgi b/postfix/save_opts_bcc.cgi index 924116142..7b699e71f 100755 --- a/postfix/save_opts_bcc.cgi +++ b/postfix/save_opts_bcc.cgi @@ -1,6 +1,9 @@ #!/usr/local/bin/perl -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %in, %text); &ReadParse(); diff --git a/postfix/save_opts_body.cgi b/postfix/save_opts_body.cgi index 09d85119e..7aaa88bd8 100755 --- a/postfix/save_opts_body.cgi +++ b/postfix/save_opts_body.cgi @@ -6,7 +6,10 @@ # Save Postfix options ; special because for virtual tables -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %in, %text); &ReadParse(); diff --git a/postfix/save_opts_canonical.cgi b/postfix/save_opts_canonical.cgi index f59f1d577..530e5c074 100755 --- a/postfix/save_opts_canonical.cgi +++ b/postfix/save_opts_canonical.cgi @@ -6,7 +6,10 @@ # Save Postfix options ; special because for canonical tables -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %in, %text); &ReadParse(); diff --git a/postfix/save_opts_dependent.cgi b/postfix/save_opts_dependent.cgi index f9ee4af8b..12b733030 100755 --- a/postfix/save_opts_dependent.cgi +++ b/postfix/save_opts_dependent.cgi @@ -6,7 +6,10 @@ # Save Postfix options ; special because for sender transport maps -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %in, %text); &ReadParse(); diff --git a/postfix/save_opts_header.cgi b/postfix/save_opts_header.cgi index b3551a163..25bdd62a3 100755 --- a/postfix/save_opts_header.cgi +++ b/postfix/save_opts_header.cgi @@ -6,7 +6,10 @@ # Save Postfix options ; special because for virtual tables -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %in, %text); &ReadParse(); diff --git a/postfix/save_opts_misc.cgi b/postfix/save_opts_misc.cgi index d2e5c6a09..95d57fb97 100755 --- a/postfix/save_opts_misc.cgi +++ b/postfix/save_opts_misc.cgi @@ -6,7 +6,10 @@ # Save Postfix options ; special case in which we need to regenerate the relocated table -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %in, %text); &ReadParse(); diff --git a/postfix/save_opts_relocated.cgi b/postfix/save_opts_relocated.cgi index a35558e42..001a9cc96 100755 --- a/postfix/save_opts_relocated.cgi +++ b/postfix/save_opts_relocated.cgi @@ -6,7 +6,10 @@ # Save Postfix options ; special because for relocated tables -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %in, %text); &ReadParse(); diff --git a/postfix/save_opts_sni.cgi b/postfix/save_opts_sni.cgi index 1d5b4645a..e5d78213b 100755 --- a/postfix/save_opts_sni.cgi +++ b/postfix/save_opts_sni.cgi @@ -6,7 +6,10 @@ # Save Postfix options ; special because for sni tables -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %in, %text); &ReadParse(); diff --git a/postfix/save_opts_transport.cgi b/postfix/save_opts_transport.cgi index cc64860fe..75d7179a6 100755 --- a/postfix/save_opts_transport.cgi +++ b/postfix/save_opts_transport.cgi @@ -6,7 +6,10 @@ # Save Postfix options ; special because for transport tables -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %in, %text); &ReadParse(); diff --git a/postfix/save_opts_virtual.cgi b/postfix/save_opts_virtual.cgi index c22c102c5..eba22e3e5 100755 --- a/postfix/save_opts_virtual.cgi +++ b/postfix/save_opts_virtual.cgi @@ -6,7 +6,10 @@ # Save Postfix options ; special because for virtual tables -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, $virtual_maps, %access, %in, %text); &ReadParse(); diff --git a/postfix/save_sasl.cgi b/postfix/save_sasl.cgi index e0d529529..c57cc52e1 100755 --- a/postfix/save_sasl.cgi +++ b/postfix/save_sasl.cgi @@ -1,7 +1,10 @@ #!/usr/local/bin/perl # Save SMTP authentication options -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, $newmap, $old, $pmap, $postfix_version, $rh, %access, %in, %newrecip, %newrelay, @opts, @recip, @relay, %text); &ReadParse(); @@ -36,7 +39,7 @@ if (!$in{'login_none'}) { # Save recipient options that we care about @recip = split(/[\s,]+/, &get_current_value("smtpd_recipient_restrictions")); %newrecip = map { $_, 1 } split(/\0/, $in{'sasl_recip'}); -foreach $o (&list_smtpd_restrictions()) { +foreach my $o (&list_smtpd_restrictions()) { if ($newrecip{$o}) { push(@recip, $o) if (&indexof($o, @recip) < 0); } @@ -49,7 +52,7 @@ foreach $o (&list_smtpd_restrictions()) { # Save relay options that we care about @relay = split(/[\s,]+/, &get_current_value("smtpd_relay_restrictions")); %newrelay = map { $_, 1 } split(/\0/, $in{'sasl_relay'}); -foreach $o (&list_smtpd_restrictions()) { +foreach my $o (&list_smtpd_restrictions()) { if ($newrelay{$o}) { push(@relay, $o) if (&indexof($o, @relay) < 0); } diff --git a/postfix/smtp.cgi b/postfix/smtp.cgi index 2dfb09d01..ee86e79b5 100755 --- a/postfix/smtp.cgi +++ b/postfix/smtp.cgi @@ -7,7 +7,10 @@ # # << Here are all options seen in Postfix sample-smtp.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($default, $inet, $level, $no_, $none, $postfix_version, $pref, %access, %inet, @opts, %text); $access{'smtp'} || &error($text{'smtp_ecannot'}); diff --git a/postfix/smtpd.cgi b/postfix/smtpd.cgi index c855c8191..698bfd4cb 100755 --- a/postfix/smtpd.cgi +++ b/postfix/smtpd.cgi @@ -8,7 +8,10 @@ # # << Here are all options seen in Postfix sample-smtpd.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($default, $no_, $none, %access, %text); &ReadParse(); $access{'smtpd'} || &error($text{'smtpd_ecannot'}); diff --git a/postfix/sni.cgi b/postfix/sni.cgi index 414f6064d..4802f70bc 100755 --- a/postfix/sni.cgi +++ b/postfix/sni.cgi @@ -8,7 +8,10 @@ # << Here are all options seen in Postfix sample-sni.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our (%access, %text); &ReadParse(); $access{'sni'} || &error($text{'sni_ecannot'}); diff --git a/postfix/start.cgi b/postfix/start.cgi index 60808424a..7d1e229b7 100755 --- a/postfix/start.cgi +++ b/postfix/start.cgi @@ -5,7 +5,10 @@ # # Start postfix -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %text); $access{'startstop'} || &error($text{'start_ecannot'}); &error_setup($text{'start_efailed'}); diff --git a/postfix/stop.cgi b/postfix/stop.cgi index 8f102b606..4eaafb3f6 100755 --- a/postfix/stop.cgi +++ b/postfix/stop.cgi @@ -5,7 +5,10 @@ # # Stop postfix -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($err, %access, %text); $access{'startstop'} || &error($text{'stop_ecannot'}); &error_setup($text{'stop_efailed'}); diff --git a/postfix/t/perlcritic.t b/postfix/t/perlcritic.t new file mode 100644 index 000000000..57f011f1e --- /dev/null +++ b/postfix/t/perlcritic.t @@ -0,0 +1,72 @@ +#!/usr/bin/perl +use strict; +use warnings; +use Test::More; + +BEGIN { + eval { require Perl::Critic; 1 } + or plan skip_all => 'Perl::Critic not installed'; +} + +use File::Find; + +sub script_dir +{ + my $path = $0; + if ($path =~ m{^/}) { + $path =~ s{/[^/]+$}{}; + return $path; + } + my $cwd = `pwd`; + chomp($cwd); + if ($path =~ m{/}) { + $path =~ s{/[^/]+$}{}; + return $cwd.'/'.$path; + } + return $cwd; +} + +my $bindir = script_dir(); +my $module_dir = "$bindir/.."; +chdir($module_dir) or die "chdir: $!"; + +my @files; +find( + sub { + # Skip symlinks: several postfix files (aliases-lib.pl, autoreply.pl, + # filter.pl, edit_*file.cgi, save_*file.cgi, boxes-lib.pl) are symlinks + # into the sendmail and mailboxes modules. Those belong to other + # modules and are linted by their own test suites. + return if -l; + return if -d; + return unless /\.(pl|cgi)\z/; + # ".pl" is also the Polish translation suffix in Webmin. Skip + # ".pl" when a sibling "" (no extension) exists, so + # data files like config.info.pl and module.info.pl are not linted + # as Perl. (Same heuristic as the repo-root compile.t.) + if (/^(.*)\.pl\z/ && -e $1) { + return; + } + push(@files, $File::Find::name); + }, + '.' +); + +@files = sort @files; +if (!@files) { + plan skip_all => 'no perl files to check'; +} + +my $critic = Perl::Critic->new( + -profile => "$bindir/../../.perlcriticrc", +); + +foreach my $file (@files) { + my @violations = $critic->critique($file); + is(scalar @violations, 0, "$file perlcritic"); + if (@violations) { + diag join("", @violations); + } +} + +done_testing(); diff --git a/postfix/t/run-tests.t b/postfix/t/run-tests.t new file mode 100644 index 000000000..4b0fdfbb7 --- /dev/null +++ b/postfix/t/run-tests.t @@ -0,0 +1,249 @@ +#!/usr/bin/perl +use strict; +use warnings; +use Test::More; +use Cwd qw(abs_path); +use File::Temp qw(tempdir); + +sub script_dir +{ + my $path = $0; + if ($path =~ m{^/}) { + $path =~ s{/[^/]+$}{}; + return $path; + } + my $cwd = `pwd`; + chomp($cwd); + if ($path =~ m{/}) { + $path =~ s{/[^/]+$}{}; + return $cwd.'/'.$path; + } + return $cwd; +} + +my $bindir = script_dir(); +my $rootdir = abs_path("$bindir/../..") or die "rootdir: $!"; + +my $confdir = tempdir(CLEANUP => 1); +my $vardir = tempdir(CLEANUP => 1); + +# Global Webmin config +open(my $cfh, ">", "$confdir/config") or die "config: $!"; +print $cfh "os_type=linux\nos_version=0\n"; +close($cfh); +open(my $vfh, ">", "$confdir/var-path") or die "var-path: $!"; +print $vfh "$vardir\n"; +close($vfh); + +# A main.cf to drive the config parser +my $maincf = "$confdir/main.cf"; +my $mastercf = "$confdir/master.cf"; +open(my $mc, ">", $maincf) or die "main.cf: $!"; +print $mc <<'EOF'; +myhostname = mail.example.com +mydestination = example.com, + mail.example.com, + localhost +compatibility_level = 2 +util_lt = {{$compatibility_level} < {3} ? {old} : {new}} +util_ge = {{$compatibility_level} >= {3} ? {high} : {low}} +util_eq = {{$compatibility_level} == {2} ? {match} : {nomatch}} +subtest = key1 valueA key2 valueB +alias_maps = hash:/etc/postfix/aliases, hash:/etc/aliases +EOF +close($mc); + +# A master.cf with one enabled and one disabled service, plus a continuation +open(my $ms, ">", $mastercf) or die "master.cf: $!"; +print $ms <<'EOF'; +smtp inet n - y - - smtpd +#qmgr unix n - n 300 1 qmgr +pickup unix n - y 60 1 pickup + -o content_filter=foo +EOF +close($ms); + +# Per-module config +mkdir "$confdir/postfix" or die "postfix confdir: $!"; +open(my $mod, ">", "$confdir/postfix/config") or die "module config: $!"; +print $mod "postfix_config_file=$maincf\n"; +print $mod "postfix_master=$mastercf\n"; +print $mod "postfix_config_command=/bin/true\n"; +print $mod "postfix_control_command=/bin/true\n"; +print $mod "prefix_cmts=0\n"; +close($mod); + +# Pre-seed the version file so loading the lib does not shell out to postconf. +open(my $ver, ">", "$confdir/postfix/version") or die "version: $!"; +print $ver "3.4.0\n"; +close($ver); + +$ENV{'WEBMIN_CONFIG'} = $confdir; +$ENV{'WEBMIN_VAR'} = $vardir; +$ENV{'FOREIGN_MODULE_NAME'} = 'postfix'; +$ENV{'FOREIGN_ROOT_DIRECTORY'} = $rootdir; + +chdir("$bindir/..") or die "chdir: $!"; + +require "$bindir/../postfix-lib.pl"; +our (%config, $postfix_version, $virtual_maps, $ldap_timeout, $config_dir); + +# --- load-time globals ----------------------------------------------------- +is($postfix_version, '3.4.0', 'postfix_version read from version file'); +is($virtual_maps, 'virtual_alias_maps', 'virtual_maps for >= 2.x'); +is($ldap_timeout, 'ldap_timeout', 'ldap_timeout for >= 2.x'); +is($config_dir, $confdir, 'guess_config_dir is dirname of main.cf'); + +# --- file_map_type --------------------------------------------------------- +ok(file_map_type('hash'), 'hash is a file map type'); +ok(file_map_type('pcre'), 'pcre is a file map type'); +ok(file_map_type('cidr'), 'cidr is a file map type'); +ok(!file_map_type('mysql'),'mysql is not a file map type'); +ok(!file_map_type('ldap'), 'ldap is not a file map type'); + +# --- get_maps_types_files -------------------------------------------------- +is_deeply([ get_maps_types_files('hash:/etc/postfix/canonical') ], + [ [ 'hash', '/etc/postfix/canonical' ] ], + 'single type:file parsed'); +is_deeply([ get_maps_types_files( + 'hash:/etc/postfix/canonical, proxy:pcre:/etc/postfix/x') ], + [ [ 'hash', '/etc/postfix/canonical' ], + [ 'pcre', '/etc/postfix/x' ] ], + 'multiple maps and proxy: prefix parsed'); +is_deeply([ get_maps_types_files('mysql:/etc/postfix/m.cf') ], + [ [ 'mysql', '/etc/postfix/m.cf' ] ], + 'mysql backend type:file parsed'); +is_deeply([ get_maps_types_files('') ], [], + 'empty value yields no maps'); +is_deeply([ get_maps_types_files('garbage-without-colon') ], [], + 'unparseable value yields no maps'); + +# --- get_maps_files (path extraction) -------------------------------------- +is_deeply([ get_maps_files('hash:/etc/postfix/aliases,hash:/etc/aliases') ], + [ '/etc/postfix/aliases', '/etc/aliases' ], + 'get_maps_files extracts both file paths'); +is_deeply([ get_maps_files('static:foo') ], [], + 'get_maps_files ignores non-path map values'); + +# --- get_current_value (main.cf parser) ------------------------------------ +is(get_current_value('myhostname', 1), 'mail.example.com', + 'single-line parameter parsed'); +my $dest = get_current_value('mydestination', 1); +like($dest, qr/example\.com/, 'continuation line: first value present'); +like($dest, qr/localhost/, 'continuation line: trailing value joined'); +is(get_current_value('no_such_param', 1), undef, + 'unknown parameter with nodef returns undef (no postconf fallback)'); +is(get_current_value('subtest:key1', 1), 'valueA', + 'sub-parameter extraction (foo:bar) returns value after the key'); + +# --- resolve_current_value (compatibility_level conditionals) -------------- +# Exercises the operator-dispatch rewrite of the old stringy eval. +is(resolve_current_value('util_lt'), 'old', + 'resolve "<": level 2 is < 3, takes true branch'); +is(resolve_current_value('util_ge'), 'low', + 'resolve ">=": level 2 is not >= 3, takes false branch'); +is(resolve_current_value('util_eq'), 'match', + 'resolve "==": level 2 == 2, takes true branch'); +is(resolve_current_value('myhostname'), 'mail.example.com', + 'resolve passes through a plain value unchanged'); + +# --- master.cf parser + serializer ----------------------------------------- +my $master = get_master_config(); +is(ref($master), 'ARRAY', 'get_master_config returns array ref'); +is(scalar(@$master), 3, 'three service entries parsed'); + +my ($smtp) = grep { $_->{'name'} eq 'smtp' } @$master; +my ($qmgr) = grep { $_->{'name'} eq 'qmgr' } @$master; +my ($pickup) = grep { $_->{'name'} eq 'pickup' } @$master; + +ok($smtp, 'smtp service parsed'); +ok($smtp->{'enabled'}, 'smtp is enabled'); +is($smtp->{'type'}, 'inet', 'smtp type'); +is($smtp->{'chroot'}, 'y', 'smtp chroot column'); +is($smtp->{'command'}, 'smtpd','smtp command'); + +ok($qmgr, 'commented service still parsed'); +ok(!$qmgr->{'enabled'}, 'commented service is disabled'); + +ok($pickup, 'pickup service parsed'); +is($pickup->{'command'}, 'pickup -o content_filter=foo', + 'continuation line appended to command'); + +# master_line round-trips an entry back to its on-disk form +is(master_line($smtp), + "smtp\tinet\tn\t-\ty\t-\t-\tsmtpd", + 'master_line serializes an enabled service with tabs'); +is(master_line($qmgr), + "#qmgr\tunix\tn\t-\tn\t300\t1\tqmgr", + 'master_line prefixes a disabled service with #'); + +# --- is_table_comment / make_table_comment --------------------------------- +{ + local $config{'prefix_cmts'} = 0; + is(is_table_comment('# hello world'), 'hello world', + 'plain comment text extracted when prefix_cmts off'); + is_deeply([ make_table_comment('a note') ], [ '# a note' ], + 'make_table_comment emits a plain # line'); + is_deeply([ make_table_comment('') ], [], + 'make_table_comment emits nothing for empty comment'); +} +{ + local $config{'prefix_cmts'} = 1; + is(is_table_comment('# Webmin: tagged'), 'tagged', + 'Webmin-tagged comment extracted when prefix_cmts on'); + is(is_table_comment('# untagged'), undef, + 'untagged comment ignored when prefix_cmts on'); + is_deeply([ make_table_comment('z') ], [ '# Webmin: z' ], + 'make_table_comment emits a Webmin-tagged line when prefix_cmts on'); +} + +# --- in_props -------------------------------------------------------------- +is(in_props([ qw(cn foo objectClass top) ], 'objectClass'), 'top', + 'in_props returns value following a matched name'); +is(in_props([ qw(cn foo) ], 'mail'), undef, + 'in_props returns undef for an absent name'); +is(in_props([ qw(CN foo) ], 'cn'), 'foo', + 'in_props matches case-insensitively'); + +# --- get_ldap_key ---------------------------------------------------------- +is_deeply([ get_ldap_key({}) ], + [ 'mailacceptinggeneralid', '(mailacceptinggeneralid=*)' ], + 'get_ldap_key default attribute and filter'); +is_deeply([ get_ldap_key({ 'query_filter' => 'mail=%s' }) ], + [ 'mail', '(mail=*)' ], + 'get_ldap_key derives attribute and filter from query_filter'); + +# --- make_map_ldap_dn ------------------------------------------------------ +{ + local $config{'ldap_doms'} = 1; # allow sub-domain DNs + local $config{'ldap_id'} = undef; # default to cn + my $conf = { 'search_base' => 'dc=example,dc=com', 'scope' => 'sub' }; + is(make_map_ldap_dn({ 'name' => 'user@dom.com' }, $conf), + 'cn=user,cn=dom.com,dc=example,dc=com', + 'make_map_ldap_dn builds a per-user DN inside a domain'); + is(make_map_ldap_dn({ 'name' => '@dom.com' }, $conf), + 'cn=default,cn=dom.com,dc=example,dc=com', + 'make_map_ldap_dn builds a catch-all DN for a domain'); + is(make_map_ldap_dn({ 'name' => 'literal' }, $conf), + 'cn=literal,dc=example,dc=com', + 'make_map_ldap_dn builds a flat DN for a non-address name'); +} + +# --- get_backend_config ---------------------------------------------------- +my $backend = "$confdir/mysql.cf"; +open(my $bfh, ">", $backend) or die "backend: $!"; +print $bfh "user = postfix\npassword = secret\n# a comment\nhosts = localhost\n"; +close($bfh); +my $bc = get_backend_config($backend); +is($bc->{'user'}, 'postfix', 'backend config user parsed'); +is($bc->{'password'}, 'secret', 'backend config password parsed'); +is($bc->{'hosts'}, 'localhost', 'backend config hosts parsed'); + +# --- list_smtpd_restrictions (version-dependent constant) ------------------ +my @restr = list_smtpd_restrictions(); +ok((grep { $_ eq 'permit_mynetworks' } @restr), + 'smtpd restrictions include permit_mynetworks'); +ok((grep { $_ eq 'reject_unknown_reverse_client_hostname' } @restr), + '>= 2.3 uses reject_unknown_reverse_client_hostname'); + +done_testing(); diff --git a/postfix/transport.cgi b/postfix/transport.cgi index 6f06e8894..a341fc107 100755 --- a/postfix/transport.cgi +++ b/postfix/transport.cgi @@ -8,7 +8,10 @@ # << Here are all options seen in Postfix sample-transport.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our (%access, %text); &ReadParse(); $access{'transport'} || &error($text{'transport_ecannot'}); diff --git a/postfix/view_mailq.cgi b/postfix/view_mailq.cgi index ed6b9ced7..35851bb7d 100755 --- a/postfix/view_mailq.cgi +++ b/postfix/view_mailq.cgi @@ -2,8 +2,11 @@ # view_mailq.cgi # Display some message from the mail queue -require './postfix-lib.pl'; -require './boxes-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($body, $bodyhtml, $desc, $mail, $rlink, $subs, %access, @attach, %config, %in, @sub, %text); +require './boxes-lib.pl'; ## no critic &ReadParse(); $access{'mailq'} || &error($text{'mailq_ecannot'}); @@ -12,9 +15,9 @@ $mail || &error($text{'mailq_egone'}); &parse_mail($mail); @sub = split(/\0/, $in{'sub'}); $subs = join("", map { "&sub=$_" } @sub); -foreach $s (@sub) { +foreach my $s (@sub) { # We are looking at a mail within a mail .. - local $amail = &extract_mail($mail->{'attach'}->[$s]->{'data'}); + my $amail = &extract_mail($mail->{'attach'}->[$s]->{'data'}); &parse_mail($amail); $mail = $amail; } @@ -49,7 +52,7 @@ if ($in{'headers'}) { print &ui_table_row($text{'mail_rfc'}, &html_escape($mail->{'fromline'})); } - foreach $h (@{$mail->{'headers'}}) { + foreach my $h (@{$mail->{'headers'}}) { print &ui_table_row($h->[0], &html_escape(&decode_mimewords($h->[1])), 1, [ "nowrap" ]); } @@ -84,7 +87,7 @@ print &ui_table_end(); # Find body attachment @attach = @{$mail->{'attach'}}; -foreach $a (@attach) { +foreach my $a (@attach) { if ($a->{'type'} eq 'text/plain') { $body = $a; last; @@ -93,7 +96,7 @@ foreach $a (@attach) { if ($body) { print &ui_table_start($text{'view_body'}, "width=100%", 2); $bodyhtml = ""; - foreach $l (&wrap_lines($body->{'data'}, $config{'wrap_width'})) { + foreach my $l (&wrap_lines($body->{'data'}, $config{'wrap_width'})) { $bodyhtml .= &link_urls_and_escape($l)."\n"; } print &ui_table_row(undef, "
".$bodyhtml."
", 2); @@ -107,7 +110,7 @@ if (@attach) { print &ui_columns_start([ $text{'view_afile'}, $text{'view_atype'}, $text{'view_asize'} ], 100, 0); my $attachment_id; - foreach $a (@attach) { + foreach my $a (@attach) { $attachment_id++; if ($a->{'type'} eq 'message/rfc822') { print &ui_columns_row([ diff --git a/postfix/virtual.cgi b/postfix/virtual.cgi index aa8ed9420..db13e44e6 100755 --- a/postfix/virtual.cgi +++ b/postfix/virtual.cgi @@ -8,7 +8,10 @@ # << Here are all options seen in Postfix sample-virtual.cf >> -require './postfix-lib.pl'; +require './postfix-lib.pl'; ## no critic +use strict; +use warnings; +our ($postfix_version, $virtual_maps, %access, %text); &ReadParse(); $access{'virtual'} || &error($text{'virtual_ecannot'});