3 # This is a Perl script that reads an Exim run-time configuration file for
4 # Exim 3. It makes what changes it can for Exim 4, and also output commentary
5 # on what it has done, and on things it cannot do.
7 # It is assumed that the input is a valid Exim 3 configuration file.
10 BEGIN { pop @INC if $INC[-1] eq '.' };
17 print basename($0) . ": $0\n",
18 "build: EXIM_RELEASE_VERSIONEXIM_VARIANT_VERSION\n",
19 "perl(runtime): $^V\n";
24 # These are lists of main options which are abolished in Exim 4.
25 # The first contains options that are used to construct new options.
29 "auth_over_tls_hosts",
31 "headers_check_syntax",
32 "headers_checks_fail",
33 "headers_sender_verify",
34 "headers_sender_verify_errmsg",
36 "host_auth_accept_relay",
37 "host_reject_recipients",
39 "local_domains_include_host",
40 "local_domains_include_host_literals",
46 "log_received_sender",
47 "log_received_recipients",
49 "log_sender_on_delivery",
50 "log_smtp_confirmation",
51 "log_smtp_connections",
52 "log_smtp_syntax_errors",
54 "log_queue_run_level",
57 "rbl_reject_recipients",
59 "receiver_verify_addresses",
60 "receiver_verify_hosts",
61 "receiver_verify_senders",
62 "recipients_reject_except",
63 "recipients_reject_except_senders",
65 "relay_domains_include_local_mx",
66 "sender_address_relay",
67 "sender_address_relay_hosts",
68 "sender_reject_recipients",
70 "sender_verify_hosts_callback",
71 "sender_verify_callback_domains",
72 "sender_verify_callback_timeout",
73 "sender_verify_hosts",
77 "tls_host_accept_relay",
84 # The second contains options that are completely abolished and have
87 @abolished_options = (
93 "log_refused_recipients",
94 "message_size_limit_count_recipients",
97 "receiver_try_verify",
99 "relay_match_host_or_sender",
101 "sender_verify_batch",
102 "sender_verify_fixup",
103 "sender_verify_reject",
104 "sender_verify_max_retry_rate",
107 # This is a list of options that are not otherwise handled, but which
108 # contain domain or host lists that have to be processed so that any
109 # regular expressions are marked "not for expansion".
112 "dns_again_means_nonexist",
114 "hosts_treat_as_local",
115 "percent_hack_domains",
116 "queue_smtp_domains",
117 "helo_accept_junk_hosts",
119 "ignore_fromline_hosts",
121 "sender_unqualified_hosts",
122 "smtp_reserve_hosts",
123 "tls_advertise_hosts",
129 ##################################################
130 # Output problem rubric once #
131 ##################################################
134 return if $rubric_output;
137 "** The following comments describe problems that have been encountered\n" .
138 " while converting an Exim 3 runtime file for Exim 4. More detail can\n" .
139 " be found in the file doc/Exim4.upgrade.\n";
143 ##################################################
145 ##################################################
150 return "comment" if $line =~ /^\s*(#|$)/;
151 return "end" if $line =~ /^\s*end\s*$/i;
153 # Macros are recognized only in the first section of the file.
155 return "macro" if $prefix eq "" && $line =~ /^\s*[A-Z]/;
157 # In retry and rewrite sections, the type is always "other"
159 return "other" if $prefix eq "=retry" || $prefix eq "=rewrite";
161 # Pick out the name at the start and the rest of the line (into global
162 # variables) and return whether the start of a driver or not.
164 ($hide,$name,$rest) = $line =~ /^\s*(hide\s+|)([a-z0-9_]+)\s*(.*?)\s*$/;
166 # If $rest begins with a colon, this is a driver name
168 return "driver" if $rest =~ /^:/;
170 # If $rest begins with an = the value of the option is given explicitly;
171 # remove the = from the start. Turn "yes"/"no" into "true"/"false".
176 $rest = "true" if $rest eq "yes";
177 $rest = "false" if $rest eq "no";
180 # Otherwise we have a boolean option. Set up a "true"/"false" value.
184 if ($name =~ /^not?_/) # Recognize "no_" or "not_"
200 ##################################################
201 # Negate a list of things #
202 ##################################################
204 # Can be tricky, because there may be comment lines in the list.
205 # Also, lists may have different delimiters.
212 return $list if ! defined $list;
214 ($list) = $list =~ /^"?(.*?)"?\s*$/s; # Remove surrounding quotes
215 $list =~ s/\\\s*\n\s*//g; # Remove continuation markers
217 if ($list =~ /^(\s*<(\S)\s*)(.*)/s)
225 $list =~ s/\Q$delim$delim/>%%%%</g;
226 @split = split /\s*\Q$delim\E\s*/s, $list;
228 foreach $item (@split)
230 $item =~ s/>%%%%</$delim$delim/g;
232 if ($item =~ /^\s*#/)
234 $item =~ s/((?:^\s*#[^\n]*\n)+\s*)/$1! /mg;
235 $item =~ s/!\s*!//sg;
239 if ($item =~ /^\s*!(.*)/)
242 { $item = "! " . $item; }
246 $" = " $delim \\\n ";
247 $leadin .= " " if $leadin !~ /(^|\s)$/;
248 return "$leadin@split";
253 ##################################################
254 # Prevent regex expansion in a list of things #
255 ##################################################
257 # Can be tricky, because there may be comment lines in the list.
258 # Also, lists may have different delimiters.
260 sub no_expand_regex {
265 return $list if ! defined $list;
267 $delim = $_[1] if (defined $_[1]);
269 my($is_route_list) = $delim eq ";";
271 ($list) = $list =~ /^"?(.*?)"?\s*$/s; # Remove surrounding quotes
272 $list =~ s/\\\s*\n\s*//g; # Remove continuation markers
274 if ($list =~ /^(\s*<(\S)\s*)(.*)/s)
282 $list =~ s/\Q$delim$delim/>%%%%</g;
283 @split = split /\s*\Q$delim\E\s*/s, $list;
286 foreach $item (@split)
288 $item =~ s/>%%%%</$delim$delim/g;
291 # Fudge for route_list items
295 $item = "\\N$item"; # Only one item ...
299 $item = "\\N$item\\N";
305 "#!!# Regular expressions enclosed in \\N...\\N to avoid expansion\n"
308 $" = " $delim \\\n ";
309 $leadin .= " " if $leadin !~ /(^|\s)$/;
310 return "$leadin@split";
315 ##################################################
316 # Sort out lookups in an address list #
317 ##################################################
319 # Can be tricky, because there may be comment lines in the list.
320 # Also, lists may have different delimiters.
322 sub sort_address_list {
329 return $list if ! defined $list;
331 if ($list =~ /^"(.*?)"\s*$/s) # Remove surrounding quotes
337 $list =~ s/\\\s*\n\s*//g; # Remove continuation markers
339 if ($list =~ /^(\s*<(\S)\s*)(.*)/s)
347 $list =~ s/\Q$delim$delim/>%%%%</g;
348 @split = split /\s*\Q$delim\E\s*/s, $list;
350 foreach $item (@split)
352 $item =~ s/>%%%%</$delim$delim/g;
353 if ($item =~ /^\s*(?:partial-)?(\w+;.*)$/)
356 if ($lookup =~ /^lsearch|^dbm|^cdb|^nis[^p]/)
360 "** The Exim 3 \"$name\" option specifies an address\n" .
361 " list that includes the item\n\n" .
363 " In Exim 4 address lists, single-key lookups without a local part just\n" .
364 " look up the complete address. They don't also try the domain, as\n" .
365 " happened in Exim 3. The item has been rewritten as two items to make\n" .
366 " it behave in the same way as Exim 3, but you should check to see if\n" .
367 " this is actually what you want.\n";
369 $item = "*\@$item $delim $lookup";
374 $" = " $delim \\\n ";
375 $leadin .= " " if $leadin !~ /(^|\s)$/;
377 return $quoted? "\"$leadin@split\"" : "$leadin@split";
382 ##################################################
383 # Quote a string against expansion #
384 ##################################################
386 # Used for setting up new "domains" options
391 $s =~ s/\\(?!\s*\n)/\\\\/sg;
397 ##################################################
398 # Dequote an option string #
399 ##################################################
401 # If the original list is not quoted, do nothing.
402 # If it is quoted, just get rid of the quotes.
406 $s =~ s/^"(.*)"$/$1/s;
411 ##################################################
412 # Quote/dequote an option string #
413 ##################################################
415 # If the original list is not quoted, quote it against expansion.
416 # If it is quoted, just get rid of the quotes. Also, indent any
421 $s = ($s =~ /^"(.*)"$/s)? $1 : &expquote($s);
423 $s =~ s/\n\s{11,}/\n /g;
428 ##################################################
429 # Handle abolished driver options #
430 ##################################################
433 my($hash) = shift @_;
434 my($name) = shift @_;
437 if (defined $$hash{$abolished})
441 "** $name used the \"$abolished\" option, which no\n".
442 " longer exists. The option has been removed.\n";
443 print STDOUT "#!!# $abolished option removed\n";
444 delete $$hash{$abolished};
451 ##################################################
452 # Handle renamed driver options #
453 ##################################################
456 my($hash,$old,$new) = @_;
457 if (defined $$hash{$old})
459 print STDOUT "#!!# $old renamed $new\n";
460 $$hash{$new} = $$hash{$old};
467 ##################################################
468 # Comment on user names in require_files #
469 ##################################################
472 my($string, $name) = @_;
474 $string =~ s/::/[[[]]]/g;
475 my(@list) = split /:/, $string;
480 if ($item =~ /^\s*[\w,]+\s*$/)
486 "** A setting of require_files in the $name contains\n" .
487 " what appears to be a user name ('$item'). The ability to check files\n" .
488 " as a specific user is done differently in Exim 4. In fact, because the\n" .
489 " routers run as root, you may not need this at all.\n"
495 ##################################################
496 # Handle current and home directory #
497 ##################################################
499 sub handle_current_and_home_directory {
500 my($hash,$driver,$name) = @_;
502 for ("current_directory", "home_directory")
504 if (defined $$hash{$_} && $$hash{$_} eq "check_local_user")
506 my($article) = (substr($driver, 0, 1) eq "a")? "an" : "a";
509 "** The Exim 3 configuration contains $article '$driver' director called\n" .
510 " '$name', which set '$_' to the special value\n" .
511 " 'check_local_user'. This facility has been abolished in Exim 4 because\n" .
512 " it is no longer necessary. The setting has therefore been omitted. See\n" .
518 &renamed($hash, $_, "transport_$_");
525 ##################################################
526 # Handle batch/bsmtp for appendfile/pipe #
527 ##################################################
529 sub handle_batch_and_bsmtp{
532 if (defined $$hash{"bsmtp"})
534 if ($$hash{"bsmtp"} ne "none")
536 $$hash{"use_bsmtp"} = "true";
537 $$hash{"message_prefix"} = "\"HELO \$primary_host_name\\n\""
538 if defined $$hash{"bsmtp_helo"} && $$hash{"bsmtp_helo"} eq "true";
541 if ($$hash{"bsmtp"} eq "one")
543 delete $$hash{"batch"};
547 $$hash{"batch"} = $$hash{"bsmtp"};
550 delete $$hash{"bsmtp"};
551 delete $$hash{"bsmtp_helo"};
554 if (defined $$hash{"batch"} && $$hash{"batch"} ne "none")
556 $$hash{"batch_max"} = "100" if !defined $$hash{"batch_max"};
557 $$hash{"batch_id"} = "\$domain" if $$hash{"batch"} eq "domain";
561 $$hash{"batch_max"} = "1" if defined $$hash{"batch_max"};
563 delete $$hash{"batch"};
568 ##################################################
569 # Output one option #
570 ##################################################
573 my($hash, $key, $no_expand) = @_;
574 my($data) = $$hash{$key};
576 print STDOUT "hide " if defined $$hash{"$key-hide"};
578 # Output booleans in the form that doesn't use "="
582 print STDOUT "$key\n";
584 elsif ($data eq "false")
586 print STDOUT "no_$key\n";
592 printf STDOUT ("$key = %s\n", &no_expand_regex($data));
596 print STDOUT "$key = $data\n";
603 ##################################################
604 # Output the options for one driver #
605 ##################################################
607 # Put the "driver" option first
611 print STDOUT " driver = $$hash{'driver'}\n";
612 foreach $key (sort keys %$hash)
614 next if $key eq "driver" || $key =~ /-hide$/;
616 &outopt($hash, $key, 0);
622 ##################################################
623 # Output a rewrite or a retry line #
624 ##################################################
626 # These lines start with patterns which are now always expanded. If the
627 # pattern is a regex, arrange for it not to expand.
629 sub print_no_expand {
637 "** You have a retry or rewrite pattern that is a regular expression. Because\n" .
638 " these patterns are now always expanded, you need to be sure that the\n" .
639 " special characters in the regex are not interpreted by the expander.\n" .
640 " \\N has been inserted at the start of the regex to prevent the rest of\n" .
641 " it from being expanded.\n";
651 ##################################################
652 # Test a boolean main option #
653 ##################################################
655 # This just saves a lot of typing
658 return defined $main{$_[0]} && $main{$_[0]} eq "true";
663 ##################################################
665 ##################################################
667 print STDERR "Runtime configuration file converter for Exim release 4.\n";
669 $transport_start = $director_start = $router_start = $retry_start
670 = $rewrite_start = $auth_start = 999999;
679 $add_caseful_local_part = 0;
680 $done_dns_check_names = 0;
682 $queue_only_load_was_present = 0;
683 $deliver_queue_load_max_was_present = 0;
685 # Read the entire file into an array
690 # Remove the standard comment that appears at the end of the default
692 if ($clen > 0 && $c[$clen-1] =~ /^#\s*End of Exim configuration file\s*/i)
698 # The first pass over the input fishes out all the options settings in the
699 # main, transport, director, and router sections, and places their values in
700 # associative arrays. It also notes the starting position of all the sections.
706 for ($i = 0; $i < $clen; $i++)
708 # Change references to +allow_unknown and +warn_unknown into +include_unknown
710 if ($c[$i] =~ /\+(?:allow|warn)_unknown/)
716 "** You have used '+allow_unknown' or '+warn_unknown' in a configuration\n" .
717 " option. This has been converted to '+include_unknown', but the action\n" .
718 " is different in Exim 4, so you should review all the relevant options.\n";
721 $c[$i] =~ s/\+(?:allow|warn)_unknown/+include_unknown/g;
724 # Any reference to $errmsg_recipient is changed to $bounce_recipient
726 if ($c[$i] =~ /\$errmsg_recipient/)
732 "** References to \$errmsg_recipient have been changed to \$bounce_recipient\n";
735 $c[$i] =~ s/\$errmsg_recipient/\$bounce_recipient/g;
739 # Analyse the type of line
741 $type = &checkline($c[$i]);
742 next if $type eq "comment";
744 # Output a warning if $key is used
746 if ($c[$i] =~ /\$key/ && !$key_output)
750 "** You have used '\$key' in a configuration option. This variable does not\n" .
751 " exist in Exim 4. Instead, the value you need for your lookup will be\n" .
752 " in one of the other variables such as '\$domain' or '\$host'. You will\n" .
753 " need to edit the new configuration to sort this out.\n";
757 # Save macro definitions so we can output them first; must handle
760 if ($type eq "macro")
762 $macro_output .= "$c[$i++]\n" while $c[$i] =~ /\\\s*$|^\s*#/;
763 $macro_output .= "$c[$i]\n";
766 # Handle end of section
768 elsif ($type eq "end")
770 if ($prefix eq "=rewrite")
773 $auth_start = $i + 1;
776 elsif ($prefix eq "=retry")
778 $prefix = "=rewrite";
779 $rewrite_start = $i + 1;
781 elsif ($prefix eq "r.")
784 $retry_start = $i + 1;
786 elsif ($prefix eq "d.")
789 $router_start = $i + 1;
791 elsif ($prefix eq "t.")
794 $director_start = $i + 1;
796 elsif ($prefix eq "")
799 $transport_start = $i + 1;
803 # Handle start of a new director, router or transport driver
805 elsif ($type eq "driver" && $prefix !~ /^=/)
808 if (defined $driverlist{"$prefix$name"})
810 die "*** There are two drivers with the name \"$name\"\n";
812 $driverlist{"$prefix$name"} = $hash;
813 $first_director = $name if !defined $first_director && $prefix eq "d.";
816 # Handle definition of an option; we must pull in any continuation
817 # strings, and save the value in the current hash. Note if the option
820 elsif ($type eq "option")
824 while ($i < $clen - 1 && ($rest =~ /\\\s*$/s || $nextline =~ /^\s*#/))
826 $nextline = $c[++$i];
827 $rest .= "\n$nextline";
830 $$hash{$name} = $rest;
831 $$hash{"$name-hide"} = 1 if $hide ne "";
836 # Generate the new configuration. Start with a warning rubric.
838 print STDOUT "#!!# This file is output from the convert4r4 script, which tries\n";
839 print STDOUT "#!!# to convert Exim 3 configurations into Exim 4 configurations.\n";
840 print STDOUT "#!!# However, it is not perfect, especially with non-simple\n";
841 print STDOUT "#!!# configurations. You must check it before running it.\n";
844 # Output the macro definitions
846 if ($macro_output ne "")
848 print STDOUT "#!!# All macro definitions have been gathered here to ensure\n";
849 print STDOUT "#!!# they precede any references to them.\n\n";
850 print STDOUT "$macro_output\n";
853 # Output some default pointers to ACLs for RCPT and DATA time. If no Exim 3
854 # options that apply are set, non-restricting ACLs are generated.
856 print STDOUT "#!!# These options specify the Access Control Lists (ACLs) that\n";
857 print STDOUT "#!!# are used for incoming SMTP messages - after the RCPT and DATA\n";
858 print STDOUT "#!!# commands, respectively.\n\n";
860 print STDOUT "acl_smtp_rcpt = check_recipient\n";
861 print STDOUT "acl_smtp_data = check_message\n\n";
863 if (defined $main{"auth_over_tls_hosts"})
865 print STDOUT "#!!# This option specifies the Access Control List (ACL) that\n";
866 print STDOUT "#!!# is used after an AUTH command.\n\n";
867 print STDOUT "acl_smtp_auth = check_auth\n\n";
870 if (&bool("smtp_verify") ||
871 defined $main{"smtp_etrn_hosts"} ||
872 defined $main{"smtp_expn_hosts"})
874 print STDOUT "#!!# These options specify the Access Control Lists (ACLs) that\n";
875 print STDOUT "#!!# are used to control the ETRN, EXPN, and VRFY commands.\n";
876 print STDOUT "#!!# Where no ACL is defined, the command is locked out.\n\n";
878 print STDOUT "acl_smtp_etrn = check_etrn\n" if defined $main{"smtp_etrn_hosts"};
879 print STDOUT "acl_smtp_expn = check_expn\n" if defined $main{"smtp_expn_hosts"};
880 print STDOUT "acl_smtp_vrfy = check_vrfy\n" if &bool("smtp_verify");
884 # If local_domains was set, get its value; otherwise set to "@". Add into it
885 # appropriate magic for local_domains_include_host[_literals].
887 $local_domains = (defined $main{"local_domains"})? $main{"local_domains"} : "@";
890 if ($local_domains =~ /^\s*<(.)\s*(.*)/s)
896 $local_domains = "\@[] $ldsep " . $local_domains
897 if defined $main{"local_domains_include_host_literals"} &&
898 $main{"local_domains_include_host_literals"} eq "true";
900 $local_domains = "\@ $ldsep " . $local_domains
901 if defined $main{"local_domains_include_host"} &&
902 $main{"local_domains_include_host"} eq "true";
904 $local_domains = "<$ldsep " . $local_domains if $ldsep ne ":";
906 # Output a domain list setting for these domains, provided something is defined
908 if ($local_domains !~ /^\s*$/)
910 print STDOUT "#!!# This setting defines a named domain list called\n";
911 print STDOUT "#!!# local_domains, created from the old options that\n";
912 print STDOUT "#!!# referred to local domains. It will be referenced\n";
913 print STDOUT "#!!# later on by the syntax \"+local_domains\".\n";
914 print STDOUT "#!!# Other domain and host lists may follow.\n\n";
916 printf STDOUT ("domainlist local_domains = %s\n\n",
917 &no_expand_regex($local_domains));
920 $relay_domains = (defined $main{"relay_domains"})? $main{"relay_domains"} : "";
923 if ($relay_domains =~ /^\s*<(.)\s*(.*)/s)
928 if (defined $main{"relay_domains_include_local_mx"})
930 $relay_domains .= ($relay_domains =~ /^\s*$/)? "\@mx_any" :
934 printf STDOUT ("domainlist relay_domains = %s\n",
935 &no_expand_regex($relay_domains))
936 if $relay_domains !~ /^\s*$/;
939 # If ignore_errmsg_errors is set, we are going to force 0s as the value
940 # for ignore_errmsg_errors_after, so arrange to skip any other value.
942 push @skipped_options, "ignore_errmsg_errors_after"
943 if &bool("ignore_errmsg_errors");
946 # If rbl_domains is set, split it up and generate six lists:
947 # rbl_warn_domains, rbl_warn_domains_skiprelay
948 # rbl_reject_domains, rbl_reject_domains_skiprelay
949 # rbl_accept_domains, rbl_accept_domains_skiprelay
951 if (defined $main{"rbl_domains"})
953 my($s) = &unquote($main{"rbl_domains"});
954 $s =~ s/\s*\\\s*\n\s*/ /g;
955 my(@list) = split /\s*:\s*/, $s;
959 my(@sublist) = split /\//, $d;
960 my($name) = shift @sublist;
962 if (defined $main{"rbl_reject_recipients"})
964 $warn = $main{"rbl_reject_recipients"} ne "true";
967 foreach $o (@sublist)
969 $warn = 1 if $o eq "warn";
970 $warn = 0 if $o eq "reject";
971 $warn = 2 if $o eq "accept";
972 $skiprelay = 1 if $o eq "skiprelay";
979 $rbl_reject_skiprelay .= ((defined $rbl_reject_skiprelay)? ":":"").$name;
983 $rbl_warn_skiprelay .= ((defined $rbl_warn_skiprelay)? ":":"").$name;
987 $rbl_accept_skiprelay .= ((defined $rbl_accept_skiprelay)? ":":"").$name;
994 $rbl_reject_domains .= ((defined $rbl_reject_domains)? ":":"").$name;
998 $rbl_warn_domains .= ((defined $rbl_warn_domains)? ":":"").$name;
1002 $rbl_accept_domains .= ((defined $rbl_accept_domains)? ":":"").$name;
1009 # Output host list settings
1011 printf STDOUT ("hostlist auth_hosts = %s\n",
1012 &no_expand_regex($main{"auth_hosts"}))
1013 if defined $main{"auth_hosts"};
1014 printf STDOUT ("hostlist rbl_hosts = %s\n",
1015 &no_expand_regex($main{"rbl_hosts"}))
1016 if defined $main{"rbl_hosts"};
1017 printf STDOUT ("hostlist relay_hosts = %s\n",
1018 &no_expand_regex($main{"host_accept_relay"}))
1019 if defined $main{"host_accept_relay"};
1020 printf STDOUT ("hostlist auth_relay_hosts = %s\n",
1021 &no_expand_regex($main{"host_auth_accept_relay"}))
1022 if defined $main{"host_auth_accept_relay"};
1024 printf STDOUT ("hostlist auth_over_tls_hosts = %s\n",
1025 &no_expand_regex($main{"auth_over_tls_hosts"}))
1026 if defined $main{"auth_over_tls_hosts"};
1027 printf STDOUT ("hostlist tls_hosts = %s\n",
1028 &no_expand_regex($main{"tls_hosts"}))
1029 if defined $main{"tls_hosts"};
1030 printf STDOUT ("hostlist tls_relay_hosts = %s\n",
1031 &no_expand_regex($main{"tls_host_accept_relay"}))
1032 if defined $main{"tls_host_accept_relay"};
1037 # Convert various logging options
1042 if (defined $main{"log_level"})
1044 my($level) = $main{"log_level"};
1045 $log_selector .= "$sep -retry_defer$sep -skip_delivery" if $level < 5;
1046 $log_selector .= "$sep -lost_incoming_connection$sep -smtp_syntax_error" .
1047 "$sep -delay_delivery" if $level < 4;
1048 $log_selector .= "$sep -size_reject" if $level < 2;
1051 $log_selector .= "$sep -queue_run"
1052 if defined $main{"log_queue_run_level"} &&
1053 defined $main{"log_level"} &&
1054 $main{"log_queue_run_level"} > $main{"log_level"};
1056 $log_selector .= "$sep +address_rewrite" if &bool("log_rewrites");
1057 $log_selector .= "$sep +all_parents" if &bool("log_all_parents");
1058 $log_selector .= "$sep +arguments" if &bool("log_arguments");
1059 $log_selector .= "$sep +incoming_port" if &bool("log_incoming_port");
1060 $log_selector .= "$sep +incoming_interface" if &bool("log_interface");
1061 $log_selector .= "$sep +received_sender" if &bool("log_received_sender");
1062 $log_selector .= "$sep +received_recipients" if &bool("log_received_recipients");
1063 $log_selector .= "$sep +sender_on_delivery" if &bool("log_sender_on_delivery");
1064 $log_selector .= "$sep +smtp_confirmation" if &bool("log_smtp_confirmation");
1065 $log_selector .= "$sep +smtp_connection" if &bool("log_smtp_connections");
1066 $log_selector .= "$sep +smtp_syntax_error" if &bool("log_smtp_syntax_errors");
1067 $log_selector .= "$sep +subject" if &bool("log_subject");
1068 $log_selector .= "$sep +tls_cipher" if &bool("tls_log_cipher");
1069 $log_selector .= "$sep +tls_peerdn" if &bool("tls_log_peerdn");
1072 if ($log_selector ne "")
1074 print STDOUT "#!!# All previous logging options are combined into a single\n"
1075 . "#!!# option in Exim 4. This setting is an approximation to\n"
1076 . "#!!# the previous state - some logging has changed.\n\n";
1077 print STDOUT "log_selector = $log_selector\n\n";
1080 # If deliver_load_max is set, replace it with queue_only_load (taking the
1081 # lower value if both set) and also set deliver_queue_load_max if it is
1082 # not already set. When scanning for output, deliver_load_max is skipped.
1084 if (defined $main{"deliver_load_max"})
1088 "** deliver_load_max is abolished in Exim 4.\n";
1090 if (defined $main{"queue_only_load"})
1092 $queue_only_load_was_present = 1;
1093 if ($main{"queue_only_load"} < $main{"deliver_load_max"})
1096 " As queue_only_load was set lower, deliver_load_max is just removed.\n";
1101 " As queue_only_load was set higher, it's value has been replaced by\n" .
1102 " the value of deliver_load_max.\n";
1103 $main{"queue_only_load"} = $main{"deliver_load_max"};
1109 " queue_only_load has been set to the load value.\n";
1110 $main{"queue_only_load"} = $main{"deliver_load_max"};
1113 if (!defined $main{"deliver_queue_load_max"})
1116 " deliver_queue_load_max has been set to the value of queue_only_load.\n";
1117 $main{"deliver_queue_load_max"} = $main{"queue_only_load"};
1121 $deliver_queue_load_max_was_present = 1;
1126 # Now we scan through the various parts of the file again, making changes
1129 # -------- The main configuration --------
1132 MainLine: for ($i = 0; $i < $clen; $i++)
1135 $type = &checkline($c[$i]);
1136 last if $type eq "end";
1138 if ($type eq "macro")
1140 $i++ while $c[$i] =~ /\\\s*$|^\s*#/;
1144 if ($type eq "comment") { print STDOUT "$c[$i]\n"; next; }
1146 # Collect any continuation lines for an option setting
1148 while ($rest =~ /\\\s*$/s || $nextline =~ /^\s*#/)
1150 $nextline = $c[++$i];
1151 $rest .= "\n$nextline";
1156 # Deal with main options that are skipped (they are used in other
1157 # options in other places).
1159 for $skipped (@skipped_options)
1161 next MainLine if $name eq $skipped;
1164 # Deal with main options that are totally abolished
1166 for $abolished (@abolished_options)
1168 if ($name eq $abolished)
1172 "** The $name option no longer exists, and has no equivalent\n" .
1178 # There is a special case for rbl_warn_header
1180 if ($name eq "rbl_warn_header")
1184 "** The $name option no longer exists. In Exim 4 you can achieve the\n" .
1185 " effect by adding a suitable \"message\" statement in the ACL.\n";
1188 # There is a special case for sender_reject and host_reject
1190 elsif ($name eq "sender_reject" || $name eq "host_reject")
1194 "** The $name option no longer exists. Its data has been used in\n" .
1195 " an Access Control List as if it were in ${name}_recipients.\n";
1198 # And a special message for prohibition_message
1200 elsif ($name eq "prohibition_message")
1204 "** The prohibition_message option no longer exists. The facility is\n" .
1205 " provided in a different way in Exim 4, via the \"message\" keyword\n" .
1206 " in Access Control Lists. It isn't possible to do an automatic conversion,\n" .
1207 " so the value of prohibition_message has been ignored. You will have to\n" .
1208 " modify the ACLs if you want to reinstate the feature.\n";
1211 # auth_always_advertise gets converted to auth_advertise_hosts
1213 elsif ($name eq "auth_always_advertise")
1215 print STDOUT "#!!# auth_always_advertise converted to auth_advertise_hosts\n";
1216 if (&bool("auth_always_advertise"))
1218 print STDOUT "auth_advertise_hosts = *\n";
1223 print STDOUT "auth_advertise_hosts =";
1224 if (defined $main{"auth_hosts"})
1226 print STDOUT "$sep +auth_hosts";
1229 if (defined $main{"host_accept_relay"})
1231 print STDOUT "$sep !+relay_hosts";
1234 if (defined $main{"host_auth_accept_relay"})
1236 print STDOUT "$sep +auth_relay_hosts";
1242 # Deal with main options that have to be rewritten
1244 elsif ($name eq "accept_timeout")
1246 print STDOUT "#!!# accept_timeout renamed receive_timeout\n";
1247 print STDOUT "receive_timeout = $rest\n";
1250 elsif ($name eq "collapse_source_routes")
1252 print STDOUT "#!!# collapse_source_routes removed\n";
1253 print STDOUT "#!!# It has been a no-op since 3.10.\n";
1256 elsif ($name eq "daemon_smtp_service")
1258 print STDOUT "#!!# daemon_smtp_service renamed daemon_smtp_port\n";
1259 print STDOUT "daemon_smtp_port = $rest\n";
1262 elsif ($name eq "dns_check_names" || $name eq "dns_check_names_pattern")
1264 if (!$done_dns_check_names)
1266 if (&bool("dns_check_names"))
1268 if (defined $main{"dns_check_names_pattern"})
1270 &outopt(\%main, "dns_check_names_pattern", 0);
1276 print STDOUT "#!!# dns_check_names has been abolished\n";
1277 print STDOUT "#!!# setting dns_check_pattern empty to turn off check\n";
1278 print STDOUT "dns_check_names_pattern =\n";
1281 $done_dns_check_names = 1;
1285 elsif ($name eq "deliver_load_max")
1287 print STDOUT "deliver_queue_load_max = $main{'deliver_queue_load_max'}\n"
1288 if !$deliver_queue_load_max_was_present;
1289 print STDOUT "queue_only_load = $main{'queue_only_load'}\n"
1290 if !$queue_only_load_was_present;
1293 elsif ($name eq "errmsg_file")
1295 print STDOUT "#!!# errmsg_file renamed bounce_message_file\n";
1296 print STDOUT "bounce_message_file = $rest\n";
1299 elsif ($name eq "errmsg_text")
1301 print STDOUT "#!!# errmsg_text renamed bounce_message_text\n";
1302 print STDOUT "bounce_message_text = $rest\n";
1305 elsif ($name eq "forbid_domain_literals")
1307 print STDOUT "#!!# forbid_domain_literals replaced by allow_domain_literals\n";
1308 print STDOUT "allow_domain_literals = ",
1309 &bool("forbid_domain_literals")? "false" : "true", "\n";
1312 elsif ($name eq "freeze_tell_mailmaster")
1314 print STDOUT "#!!# freeze_tell_mailmaster replaced by freeze_tell\n";
1315 if (&bool("freeze_tell_mailmaster"))
1317 print STDOUT "freeze_tell = ",
1318 ((defined $main{"errors_address"})?
1319 $main{"errors_address"} : "postmaster"), "\n";
1323 print STDOUT "#!!# freeze_tell is unset by default\n";
1327 elsif ($name eq "helo_verify")
1329 print STDOUT "#!!# helo_verify renamed helo_verify_hosts\n";
1330 printf STDOUT ("helo_verify_hosts = %s\n", &no_expand_regex($rest));
1333 elsif ($name eq "ignore_errmsg_errors")
1335 print STDOUT "ignore_bounce_errors_after = 0s\n";
1338 elsif ($name eq "ignore_errmsg_errors_after")
1340 print STDOUT "#!!# ignore_errmsg_errors_after renamed ignore_bounce_errors_after\n";
1341 print STDOUT "ignore_bounce_errors_after = $rest\n";
1344 elsif ($name eq "ipv4_address_lookup" || $name eq "dns_ipv4_lookup")
1346 print STDOUT "#!!# $name changed to dns_ipv4_lookup\n"
1347 if $name eq "ipv4_address_lookup";
1348 print STDOUT "#!!# dns_ipv4_lookup is now a domain list\n";
1351 print STDOUT "dns_ipv4_lookup = *\n";
1355 print STDOUT "#!!# default for dns_ipv4_lookup is unset\n";
1359 elsif ($name eq "locally_caseless")
1361 print STDOUT "#!!# locally_caseless removed\n";
1362 print STDOUT "#!!# caseful_local_part will be added to ex-directors\n";
1363 $add_caseful_local_part = 1;
1366 elsif ($name eq "message_filter_directory2_transport")
1368 print STDOUT "#!!# message_filter_directory2_transport removed\n";
1371 elsif ($name =~ /^message_filter(.*)/)
1373 print STDOUT "#!!# $name renamed system_filter$1\n";
1374 print STDOUT "system_filter$1 = $rest\n";
1377 elsif ($name eq "queue_remote_domains")
1379 print STDOUT "#!!# queue_remote_domains renamed queue_domains\n";
1380 printf STDOUT ("queue_domains = %s\n", &no_expand_regex($rest));
1383 elsif ($name eq "receiver_unqualified_hosts")
1385 print STDOUT "#!!# receiver_unqualified_hosts renamed recipient_unqualified_hosts\n";
1386 printf STDOUT ("recipient_unqualified_hosts = %s\n",
1387 &no_expand_regex($rest));
1390 elsif ($name eq "remote_sort")
1392 print STDOUT "#!!# remote_sort renamed remote_sort_domains\n";
1393 printf STDOUT ("remote_sort_domains = %s\n", &no_expand_regex($rest));
1396 elsif ($name eq "security")
1398 if ($rest eq "unprivileged")
1400 print STDOUT "#!!# security=unprivileged changed to deliver_drop_privilege\n";
1401 print STDOUT "deliver_drop_privilege\n";
1407 "** The 'security' option no longer exists.\n";
1411 elsif ($name eq "timestamps_utc")
1413 print STDOUT "#!!# timestamps_utc changed to use timezone\n";
1414 print STDOUT "timezone = utc\n";
1417 elsif ($name eq "untrusted_set_sender")
1419 print STDOUT "#!!# untrusted_set_sender is now a list of what can be set\n";
1420 print STDOUT "#!!# The default is an empty list.\n";
1421 if (&bool("untrusted_set_sender"))
1423 print STDOUT "untrusted_set_sender = *\n";
1427 elsif ($name eq "warnmsg_file")
1429 print STDOUT "#!!# warnmsg_file renamed warn_message_file\n";
1430 print STDOUT "warn_message_file = $rest\n";
1433 # Remaining options just get copied unless they are one of those that's
1434 # a list where any regular expressions have to be escaped.
1439 foreach $o (@list_options)
1447 &outopt(\%main, $name, $no_expand);
1452 # -------- The ACL configuration --------
1455 print STDOUT "#!!#######################################################!!#\n";
1456 print STDOUT "#!!# This new section of the configuration contains ACLs #!!#\n";
1457 print STDOUT "#!!# (Access Control Lists) derived from the Exim 3 #!!#\n";
1458 print STDOUT "#!!# policy control options. #!!#\n";
1459 print STDOUT "#!!#######################################################!!#\n";
1462 print STDOUT "#!!# These ACLs are crudely constructed from Exim 3 options.\n";
1463 print STDOUT "#!!# They are almost certainly not optimal. You should study\n";
1464 print STDOUT "#!!# them and rewrite as necessary.\n";
1466 print STDOUT "\nbegin acl\n\n";
1469 # Output an ACL for use after the RCPT command. This combines all the previous
1470 # policy checking options.
1472 print STDOUT "#!!# ACL that is used after the RCPT command\n";
1473 print STDOUT "check_recipient:\n";
1475 print STDOUT " # Exim 3 had no checking on -bs messages, so for compatibility\n";
1476 print STDOUT " # we accept if the source is local SMTP (i.e. not over TCP/IP).\n";
1477 print STDOUT " # We do this by testing for an empty sending host field.\n";
1478 print STDOUT " accept hosts = :\n";
1480 if (defined $main{"tls_verify_ciphers"})
1482 print STDOUT " deny ";
1483 print STDOUT "hosts = $main{'tls_verify_hosts'}\n "
1484 if defined $main{"tls_verify_hosts"};
1485 print STDOUT " encrypted = *\n ";
1486 print STDOUT "!encrypted = $main{'tls_verify_ciphers'}\n";
1489 print STDOUT " deny hosts = +auth_hosts\n" .
1490 " message = authentication required\n" .
1491 " !authenticated = *\n"
1492 if defined $main{"auth_hosts"};
1494 print STDOUT " deny hosts = +tls_hosts\n" .
1495 " message = encryption required\n" .
1497 if defined $main{"tls_hosts"};
1499 printf STDOUT (" accept recipients = %s\n",
1500 &acl_quote(&sort_address_list($main{"recipients_reject_except"},
1501 "recipients_reject_except")))
1502 if defined $main{"recipients_reject_except"};
1504 printf STDOUT (" accept senders = %s\n",
1505 &acl_quote(&sort_address_list($main{"recipients_reject_except_senders"},
1506 "recipients_reject_except_senders")))
1507 if defined $main{"recipients_reject_except_senders"};
1509 printf STDOUT (" deny hosts = %s\n", &acl_quote($main{"host_reject"}))
1510 if defined $main{"host_reject"};
1512 printf STDOUT (" deny hosts = %s\n",
1513 &acl_quote($main{"host_reject_recipients"}))
1514 if defined $main{"host_reject_recipients"};
1516 if (defined $main{"rbl_domains"})
1518 my($msg) = "message = host is listed in \$dnslist_domain\n ";
1519 my($hlist) = (defined $main{"rbl_hosts"})?
1520 "hosts = +rbl_hosts\n " : "";
1522 print STDOUT " accept ${hlist}dnslists = $rbl_accept_domains\n"
1523 if defined $rbl_accept_domains;
1524 print STDOUT " deny ${hlist}${msg}dnslists = $rbl_reject_domains\n"
1525 if defined $rbl_reject_domains;
1526 print STDOUT " warn ${hlist}" .
1527 "message = X-Warning: \$sender_host_address is listed at \$dnslist_domain\n" .
1528 " dnslists = $rbl_warn_domains\n"
1529 if defined $rbl_warn_domains;
1531 if (defined $main{"host_accept_relay"})
1533 $hlist .= "hosts = !+relay_hosts\n ";
1534 print STDOUT " accept ${hlist}dnslists = $rbl_accept_skiprelay\n"
1535 if defined $rbl_accept_skiprelay;
1536 print STDOUT " deny ${hlist}${msg}dnslists = $rbl_reject_skiprelay\n"
1537 if defined $rbl_reject_skiprelay;
1538 print STDOUT " warn ${hlist}" .
1539 "message = X-Warning: \$sender_host_address is listed at \$dnslist_domain\n" .
1540 " dnslists = $rbl_warn_skiprelay\n"
1541 if defined $rbl_warn_skiprelay;
1545 printf STDOUT (" deny senders = %s\n",
1546 &acl_quote(&sort_address_list($main{"sender_reject"}, "sender_reject")))
1547 if defined $main{"sender_reject"};
1549 printf STDOUT (" deny senders = %s\n",
1550 &acl_quote(&sort_address_list($main{"sender_reject_recipients"},
1551 "sender_reject_recipients")))
1552 if defined $main{"sender_reject_recipients"};
1554 if (&bool("sender_verify"))
1556 if (defined $main{"sender_verify_hosts_callback"} &&
1557 defined $main{"sender_verify_callback_domains"})
1559 printf STDOUT (" deny hosts = %s\n",
1560 &acl_quote($main{"sender_verify_hosts_callback"}));
1561 printf STDOUT (" sender_domains = %s\n",
1562 &acl_quote($main{"sender_verify_callback_domains"}));
1563 print STDOUT " !verify = sender/callout";
1564 print STDOUT "=$main{\"sender_verify_callback_timeout\"}"
1565 if defined $main{"sender_verify_callback_timeout"};
1569 if (defined $main{"sender_verify_hosts"})
1571 printf STDOUT (" deny hosts = %s\n",
1572 &acl_quote($main{"sender_verify_hosts"}));
1573 print STDOUT " !verify = sender\n";
1577 print STDOUT " require verify = sender\n";
1581 if (&bool("receiver_verify"))
1583 print STDOUT " deny message = unrouteable address\n";
1584 printf STDOUT (" recipients = %s\n",
1585 &acl_quote(&sort_address_list($main{"receiver_verify_addresses"},
1586 "receiver_verify_addresses")))
1587 if defined $main{"receiver_verify_addresses"};
1588 printf STDOUT (" hosts = %s\n",
1589 &acl_quote($main{"receiver_verify_hosts"}))
1590 if defined $main{"receiver_verify_hosts"};
1591 printf STDOUT (" senders = %s\n",
1592 &acl_quote(&sort_address_list($main{"receiver_verify_senders"},
1593 "receiver_verify_senders")))
1594 if defined $main{"receiver_verify_senders"};
1595 print STDOUT " !verify = recipient\n";
1598 print STDOUT " accept domains = +local_domains\n"
1599 if $local_domains !~ /^\s*$/;
1601 print STDOUT " accept domains = +relay_domains\n"
1602 if $relay_domains !~ /^\s*$/;
1604 if (defined $main{"host_accept_relay"})
1606 if (defined $main{"sender_address_relay"})
1608 if (defined $main{"sender_address_relay_hosts"})
1610 printf STDOUT (" accept hosts = %s\n",
1611 &acl_quote($main{"sender_address_relay_hosts"}));
1612 print STDOUT " endpass\n";
1613 print STDOUT " message = invalid sender\n";
1614 printf STDOUT (" senders = %s\n",
1615 &acl_quote(&sort_address_list($main{"sender_address_relay"},
1616 "sender_address_relay")));
1617 print STDOUT " accept hosts = +relay_hosts\n";
1621 print STDOUT " accept hosts = +relay_hosts\n";
1622 print STDOUT " endpass\n";
1623 print STDOUT " message = invalid sender\n";
1624 printf STDOUT (" senders = %s\n",
1625 &acl_quote(&sort_address_list($main{"sender_address_relay"},
1626 "sender_address_relay")));
1631 print STDOUT " accept hosts = +relay_hosts\n";
1635 print STDOUT " accept hosts = +auth_relay_hosts\n" .
1637 " message = authentication required\n" .
1638 " authenticated = *\n"
1639 if defined $main{"host_auth_accept_relay"};
1641 print STDOUT " accept hosts = +tls_relay_hosts\n" .
1643 " message = encryption required\n" .
1645 if defined $main{"tls_host_accept_relay"};
1647 print STDOUT " deny message = relay not permitted\n\n";
1650 # Output an ACL for use after the DATA command. This is concerned with
1653 print STDOUT "#!!# ACL that is used after the DATA command\n";
1654 print STDOUT "check_message:\n";
1656 # Default for headers_checks_fail is true
1658 if (!defined $main{"headers_checks_fail"} ||
1659 $main{"headers_checks_fail"} eq "true")
1661 print STDOUT " require verify = header_syntax\n"
1662 if &bool("headers_check_syntax");
1663 print STDOUT " require verify = header_sender\n"
1664 if &bool("headers_sender_verify");
1665 print STDOUT " accept senders = !:\n require verify = header_sender\n"
1666 if &bool("headers_sender_verify_errmsg");
1670 print STDOUT " warn !verify = header_syntax\n"
1671 if &bool("headers_check_syntax");
1672 print STDOUT " warn !verify = header_sender\n"
1673 if &bool("headers_sender_verify");
1674 print STDOUT " accept senders = !:\n warn !verify = header_sender\n"
1675 if &bool("headers_sender_verify_errmsg");
1678 print STDOUT " accept\n\n";
1681 # Output an ACL for AUTH if required
1683 if (defined $main{"auth_over_tls_hosts"})
1685 print STDOUT "#!!# ACL that is used after the AUTH command\n" .
1687 " accept hosts = +auth_over_tls_hosts\n" .
1689 " message = STARTTLS required before AUTH\n" .
1690 " encrypted = *\n" .
1695 # Output ACLs for ETRN, EXPN, and VRFY if required
1697 if (defined $main{"smtp_etrn_hosts"})
1699 print STDOUT "#!!# ACL that is used after the ETRN command\n" .
1701 print STDOUT " deny hosts = +auth_hosts\n" .
1702 " message = authentication required\n" .
1703 " !authenticated = *\n"
1704 if defined $main{"auth_hosts"};
1705 print STDOUT " accept hosts = $main{\"smtp_etrn_hosts\"}\n\n";
1708 if (defined $main{"smtp_expn_hosts"})
1710 print STDOUT "#!!# ACL that is used after the EXPN command\n" .
1712 print STDOUT " deny hosts = +auth_hosts\n" .
1713 " message = authentication required\n" .
1714 " !authenticated = *\n"
1715 if defined $main{"auth_hosts"};
1716 print STDOUT " accept hosts = $main{\"smtp_expn_hosts\"}\n\n";
1719 if (&bool("smtp_verify"))
1721 print STDOUT "#!!# ACL that is used after the VRFY command\n" .
1723 print STDOUT " deny hosts = +auth_hosts\n" .
1724 " message = authentication required\n" .
1725 " !authenticated = *\n"
1726 if defined $main{"auth_hosts"};
1727 print STDOUT " accept\n\n";
1730 # -------- The authenticators --------
1733 for ($i = $auth_start; $i < $clen; $i++)
1737 if ($c[$i] !~ /^\s*(#|$)/)
1739 print STDOUT "\nbegin authenticators\n\n";
1743 print STDOUT "$c[$i]\n";
1747 # -------- Rewrite section --------
1750 for ($i = $rewrite_start; $i < $clen && $i < $auth_start - 1; $i++)
1754 if ($c[$i] !~ /^\s*(#|$)/)
1756 print STDOUT "\nbegin rewrite\n\n";
1760 &print_no_expand($c[$i]);
1764 # -------- The routers configuration --------
1766 # The new routers configuration is created out of the old directors and routers
1767 # configuration. We put the old routers first, adding a "domains" option to
1768 # any that don't have one, to make them select the domains that do not match
1769 # the original local_domains. The routers get modified as necessary, and the
1770 # final one has "no_more" set, unless it has conditions. In that case we have
1771 # to add an extra router to be sure of failing all non-local addresses that
1772 # fall through. We do this also if there are no routers at all. The old
1773 # directors follow, modified as required.
1779 print STDOUT "#!!#######################################################!!#\n";
1780 print STDOUT "#!!# Here follow routers created from the old routers, #!!#\n";
1781 print STDOUT "#!!# for handling non-local domains. #!!#\n";
1782 print STDOUT "#!!#######################################################!!#\n";
1784 print STDOUT "\nbegin routers\n\n";
1786 for ($i = $router_start; $i < $clen; $i++)
1788 $type = &checkline($c[$i]);
1789 last if $type eq "end";
1791 if ($type eq "comment") { push(@comments, "$c[$i]\n"); next; }
1793 # When we hit the start of a driver, modify its options as necessary,
1794 # and then output it from the stored option settings, having first output
1795 # and previous comments.
1797 if ($type eq "driver")
1799 print STDOUT shift @comments while scalar(@comments) > 0;
1801 $hash = $driverlist{"$prefix$name"};
1802 $driver = $$hash{"driver"};
1803 print STDOUT "$name:\n";
1806 ! defined $$hash{"domains"} &&
1807 ! defined $$hash{"local_parts"} &&
1808 ! defined $$hash{"senders"} &&
1809 ! defined $$hash{"condition"} &&
1810 ! defined $$hash{"require_files"} &&
1811 (!defined $$hash{"verify_only"} || $$hash{"verify_only"} eq "false") &&
1812 (!defined $$hash{"verify"} || $$hash{"verify"} eq "true");
1814 # Create a "domains" setting if there isn't one, unless local domains
1815 # was explicitly empty.
1817 $$hash{"domains"} = "! +local_domains"
1818 if !defined $$hash{"domains"} && $local_domains !~ /^\s*$/;
1820 # If the router had a local_parts setting, add caseful_local_part
1822 $$hash{"caseful_local_part"} = "true" if defined $$hash{"local_parts"};
1824 # If the router has "self=local" set, change it to "self=pass", and
1825 # set pass_router to the router that was the first director. Change the
1826 # obsolete self settings of "fail_hard" and "fail_soft" to "fail" and
1829 if (defined $$hash{"self"})
1831 if ($$hash{"self"} eq "local")
1833 $$hash{"self"} = "pass";
1834 $$hash{"pass_router"} = $first_director;
1836 elsif ($$hash{"self"} eq "fail_hard")
1838 $$hash{"self"} = "fail";
1840 elsif ($$hash{"self"} eq "fail_soft")
1842 $$hash{"self"} = "pass";
1846 # If the router had a require_files setting, check it for user names
1847 # and colons that are part of expansion items
1849 if (defined $$hash{"require_files"})
1851 &check_require($$hash{"require_files"}, "'$name' router");
1852 if (($$hash{"require_files"} =~ s/(\$\{\w+):/$1::/g) > 0 ||
1853 ($$hash{"require_files"} =~ s/ldap:/ldap::/g) > 0)
1857 "*** A setting of require_files in the $name router contains\n" .
1858 " a colon in what appears to be an expansion item. In Exim 3, the\n" .
1859 " whole string was expanded before splitting the list, but in Exim 4\n" .
1860 " each item is expanded separately, so colons that are not list\n" .
1861 " item separators have to be doubled. One or more such colons in this\n" .
1862 " list have been doubled as a precaution. Please check the result.\n";
1866 # If the router had a "senders" setting, munge the address list
1868 $$hash{"senders"} = &sort_address_list($$hash{"senders"}, "senders")
1869 if defined $$hash{"senders"};
1871 # ---- Changes to domainlist router ----
1873 if ($driver eq "domainlist")
1875 &abolished($hash, "A domainlist router",
1876 "modemask", "owners", "owngroups",
1877 "qualify_single", "search_parents");
1879 # The name has changed
1881 $$hash{"driver"} = "manualroute";
1883 # Turn "route_file", "route_query" and "route_queries" into lookups for
1886 if (defined $$hash{"route_file"})
1888 $$hash{"route_data"} = "\${lookup\{\$domain\}$$hash{'search_type'}" .
1889 "\{$$hash{'route_file'}\}\}";
1891 elsif (defined $$hash{"route_query"})
1893 $$hash{"route_data"} = "\${lookup $$hash{'search_type'}" .
1894 "\{" . &unquote($$hash{'route_query'}) . "\}\}";
1896 elsif (defined $$hash{"route_queries"})
1899 $$hash{"route_data"} = "";
1900 $route_queries = $$hash{'route_queries'};
1901 $route_queries =~ s/^"(.*)"$/$1/s;
1902 $route_queries =~ s/::/++colons++/g;
1903 @qq = split(/:/, $route_queries);
1907 $q =~ s/\+\+colons\+\+/:/g;
1912 $$hash{"route_data"} .= "\\\n {";
1915 $$hash{"route_data"} .= "\${lookup $$hash{'search_type'} \{$q\}\{\$value\}";
1919 $$hash{"route_data"} .= "}" x $endkets;
1922 delete $$hash{"route_file"};
1923 delete $$hash{"route_query"};
1924 delete $$hash{"route_queries"};
1925 delete $$hash{"search_type"};
1927 # But we can't allow both route_data and route_list
1929 if (defined $$hash{"route_data"} && defined $$hash{"route_list"})
1933 "** An Exim 3 'domainlist' router called '$name' contained a 'route_list'\n" .
1934 " option as well as a setting of 'route_file', 'route_query', or\n" .
1935 " 'route_queries'. The latter has been turned into a 'route_data' setting,\n".
1936 " but in Exim 4 you can't have both 'route_data' and 'route_list'. You'll\n" .
1937 " have to rewrite this router; in the meantime, 'route_list' has been\n" .
1939 print STDOUT "#!!# route_list option removed\n";
1940 delete $$hash{"route_list"};
1943 # Change bydns_a into bydns in a route_list; also bydns_mx, but that
1944 # works differently.
1946 if (defined $$hash{"route_list"})
1948 $$hash{"route_list"} =~ s/bydns_a/bydns/g;
1949 if ($$hash{"route_list"} =~ /bydns_mx/)
1951 $$hash{"route_list"} =~ s/bydns_mx/bydns/g;
1954 "*** An Exim 3 'domainlist' router called '$name' contained a 'route_list'\n" .
1955 " option which used 'bydns_mx'. This feature no longer exists in Exim 4.\n" .
1956 " It has been changed to 'bydns', but it won't have the same effect,\n" .
1957 " because it will look for A rather than MX records. Use the 'dnslookup'\n" .
1958 " router to do MX lookups - if you want to override the hosts found from\n" .
1959 " MX records, you should route to a special 'smtp' transport which has\n" .
1960 " both 'hosts' and 'hosts_override' set.\n";
1964 # Arrange to not expand regex
1966 $$hash{"route_list"} = &no_expand_regex($$hash{"route_list"}, ";")
1967 if (defined $$hash{"route_list"})
1971 # ---- Changes to iplookup router ----
1973 elsif ($driver eq "iplookup")
1975 &renamed($hash, "service", "port");
1979 # ---- Changes to lookuphost router ----
1981 elsif ($driver eq "lookuphost")
1983 $$hash{"driver"} = "dnslookup";
1985 if (defined $$hash{"gethostbyname"})
1989 "** An Exim 3 'lookuphost' router called '$name' used the 'gethostbyname'\n" .
1990 " option, which no longer exists. You will have to rewrite it.\n";
1991 print STDOUT "#!!# gethostbyname option removed\n";
1992 delete $$hash{"gethostbyname"};
1995 $$hash{"mx_domains"} = &no_expand_regex($$hash{"mx_domains"})
1996 if defined $$hash{"mx_domains"};
2000 # ---- Changes to the queryprogram router ----
2002 elsif ($driver eq "queryprogram")
2006 "** The configuration contains a 'queryprogram' router. Please note that\n" .
2007 " the specification for the text that is returned by the program run\n" .
2008 " by this router has changed in Exim 4. You will need to modify your\n" .
2011 if (!defined $$hash{'command_user'})
2015 "** The 'queryprogram' router called '$name' does not have a setting for\n" .
2016 " the 'command_user' option. This is mandatory in Exim 4. A setting of\n" .
2017 " 'nobody' has been created.\n";
2018 $$hash{"command_user"} = "nobody";
2023 # -------------------------------------
2025 # Output the router's option settings
2031 # Skip past any continuation lines for an option setting
2032 while ($c[$i] =~ /\\\s*$/s && $i < $clen - 1)
2035 $i++ while ($c[$i] =~ /^\s*#/);
2039 # Add "no_more" to the final driver from the old routers, provided it had no
2040 # conditions. Otherwise, or if there were no routers, make up one to fail all
2041 # non-local domains.
2045 print STDOUT " no_more\n";
2046 print STDOUT shift @comments while scalar(@comments) > 0;
2050 print STDOUT shift @comments while scalar(@comments) > 0;
2051 print STDOUT "\n#!!# This new router is put here to fail all domains that\n";
2052 print STDOUT "#!!# were not in local_domains in the Exim 3 configuration.\n\n";
2053 print STDOUT "fail_remote_domains:\n";
2054 print STDOUT " driver = redirect\n";
2055 print STDOUT " domains = ! +local_domains\n";
2056 print STDOUT " allow_fail\n";
2057 print STDOUT " data = :fail: unrouteable mail domain \"\$domain\"\n\n";
2060 # Now copy the directors, making appropriate changes
2063 print STDOUT "#!!#######################################################!!#\n";
2064 print STDOUT "#!!# Here follow routers created from the old directors, #!!#\n";
2065 print STDOUT "#!!# for handling local domains. #!!#\n";
2066 print STDOUT "#!!#######################################################!!#\n";
2069 for ($i = $director_start; $i < $clen; $i++)
2071 $type = &checkline($c[$i]);
2072 last if $type eq "end";
2074 if ($type eq "comment") { print STDOUT "$c[$i]\n"; next; }
2076 undef $second_router;
2078 if ($type eq "driver")
2080 $hash = $driverlist{"$prefix$name"};
2081 $driver = $$hash{"driver"};
2082 print STDOUT "$name:\n";
2084 $$hash{"caseful_local_part"} = "true" if $add_caseful_local_part;
2086 if (defined $$hash{"local_parts"} &&
2087 (defined $$hash{"prefix"} || defined $hash{"suffix"}))
2091 "** The Exim 3 configuration contains a director called '$name' which has\n" .
2092 " 'local_parts' set, together with either or both of 'prefix' and 'suffix'\n".
2093 " This combination has a different effect in Exim 4, where the affix\n" .
2094 " is removed *before* 'local_parts' is tested. You will probably need\n" .
2095 " to make changes to this driver.\n";
2098 &renamed($hash, "prefix", "local_part_prefix");
2099 &renamed($hash, "prefix_optional", "local_part_prefix_optional");
2100 &renamed($hash, "suffix", "local_part_suffix");
2101 &renamed($hash, "suffix_optional", "local_part_suffix_optional");
2102 &renamed($hash, "new_director", "redirect_router");
2104 &handle_current_and_home_directory($hash, $driver, $name);
2106 # If the director had a require_files setting, check it for user names
2107 # and colons that are part of expansion items
2109 if (defined $$hash{"require_files"})
2111 &check_require($$hash{"require_files"}, "'$name' director");
2112 if (($$hash{"require_files"} =~ s/(\$\{\w+):/$1::/g) > 0 ||
2113 ($$hash{"require_files"} =~ s/ldap:/ldap::/g) > 0)
2117 "*** A setting of require_files in the $name director contains\n" .
2118 " a colon in what appears to be an expansion item. In Exim 3, the\n" .
2119 " whole string was expanded before splitting the list, but in Exim 4\n" .
2120 " each item is expanded separately, so colons that are not list\n" .
2121 " item separators have to be doubled. One or more such colons in this\n" .
2122 " list have been doubled as a precaution. Please check the result.\n";
2126 # If the director had a "senders" setting, munge the address list
2128 $$hash{"senders"} = &sort_address_list($$hash{"senders"}, "senders")
2129 if defined $$hash{"senders"};
2131 # ---- Changes to aliasfile director ----
2133 if ($driver eq "aliasfile")
2135 &abolished($hash, "An aliasfile director",
2136 "directory2_transport", "freeze_missing_include",
2137 "modemask", "owners", "owngroups");
2139 $$hash{"driver"} = "redirect";
2141 $key = "\$local_part";
2142 $key = "\$local_part\@\$domain"
2143 if defined $$hash{"include_domain"} &&
2144 $$hash{"include_domain"} eq "true";
2145 delete $$hash{"include_domain"};
2147 if (defined $$hash{"forbid_special"} && $$hash{"forbid_special"} eq "true")
2149 $$hash{"forbid_blackhole"} = "true";
2153 $$hash{"allow_defer"} = "true";
2154 $$hash{"allow_fail"} = "true";
2156 delete $$hash{"forbid_special"};
2158 # Deal with "file", "query", or "queries"
2160 if (defined $$hash{"file"})
2163 "\$\{lookup\{$key\}$$hash{'search_type'}\{$$hash{'file'}\}\}";
2164 if (defined $$hash{"optional"} && $$hash{"optional"} eq "true")
2167 "\$\{if exists\{$$hash{'file'}\}\{$$hash{'data'}\}\}";
2169 delete $$hash{"optional"};
2171 elsif (defined $$hash{"query"})
2173 &abolished($hash, "An aliasfile director", "optional");
2174 $$hash{"data"} = "\${lookup $$hash{'search_type'} " .
2175 "\{" . &unquote($$hash{'query'}) . "\}\}";
2177 else # Must be queries
2179 &abolished($hash, "An aliasfile director", "optional");
2181 $$hash{"data"} = "";
2182 $queries = $$hash{'queries'};
2183 $queries =~ s/^"(.*)"$/$1/s;
2184 $queries =~ s/::/++colons++/g;
2185 @qq = split(/:/, $queries);
2189 $q =~ s/\+\+colons\+\+/:/g;
2194 $$hash{"data"} .= "\\\n {";
2197 $$hash{"data"} .= "\${lookup $$hash{'search_type'} \{$q\}\{\$value\}";
2201 $$hash{"data"} .= "}" x $endkets;
2204 $$hash{"data"} = "\${expand:$$hash{'data'}\}"
2205 if (defined $$hash{"expand"} && $$hash{"expand"} eq "true");
2207 delete $$hash{"expand"};
2208 delete $$hash{"file"};
2209 delete $$hash{"query"};
2210 delete $$hash{"queries"};
2211 delete $$hash{"search_type"};
2213 # Turn aliasfile + transport into accept + condition
2215 if (defined $$hash{'transport'})
2218 if (!defined $$hash{'condition'})
2221 "** The Exim 3 configuration contains an aliasfile director called '$name',\n".
2222 " which has 'transport' set. This has been turned into an 'accept' router\n".
2223 " with a 'condition' setting, but should be carefully checked.\n";
2224 $$hash{'driver'} = "accept";
2225 $$hash{'condition'} =
2226 "\$\{if eq \{\}\{$$hash{'data'}\}\{no\}\{yes\}\}";
2227 delete $$hash{'data'};
2228 delete $$hash{'allow_defer'};
2229 delete $$hash{'allow_fail'};
2234 "** The Exim 3 configuration contains an aliasfile director called '$name',\n".
2235 " which has 'transport' set. This cannot be turned into an 'accept' router\n".
2236 " with a 'condition' setting, because there is already a 'condition'\n" .
2237 " setting. It has been left as 'redirect' with a transport, which is\n" .
2238 " invalid - you must sort this one out.\n";
2244 # ---- Changes to forwardfile director ----
2246 elsif ($driver eq "forwardfile")
2248 &abolished($hash, "A forwardfile director",
2249 "check_group", "directory2_transport",
2250 "freeze_missing_include", "match_directory",
2253 &renamed($hash, "filter", "allow_filter");
2255 $$hash{"driver"} = "redirect";
2256 $$hash{"check_local_user"} = "true"
2257 if !defined $$hash{"check_local_user"};
2259 if (defined $$hash{"forbid_pipe"} && $$hash{"forbid_pipe"} eq "true")
2261 print STDOUT "#!!# forbid_filter_run added because forbid_pipe is set\n";
2262 $$hash{"forbid_filter_run"} = "true";
2265 if (defined $$hash{'allow_system_actions'} &&
2266 $$hash{'allow_system_actions'} eq 'true')
2268 $$hash{'allow_freeze'} = "true";
2270 delete $$hash{'allow_system_actions'};
2272 # If file_directory is defined, use it to qualify relative paths; if not,
2273 # and check_local_user is defined, use $home. Remove file_directory from
2277 if (defined $$hash{"file_directory"})
2279 $dir = $$hash{"file_directory"} . "/";
2280 delete $$hash{"file_directory"};
2282 elsif ($$hash{"check_local_user"} eq "true")
2287 # If it begins with an upper case letter, guess that this is really
2290 if (defined $$hash{"file"} && $$hash{"file"} !~ /^[\/A-Z]/)
2292 $$hash{"file"} = $dir . $$hash{"file"};
2297 # ---- Changes to localuser director ----
2299 elsif ($driver eq "localuser")
2301 &abolished($hash, "A localuser director", "match_directory");
2302 $$hash{"driver"} = "accept";
2303 $$hash{"check_local_user"} = "true";
2307 # ---- Changes to smartuser director ----
2309 elsif ($driver eq "smartuser")
2311 &abolished($hash, "A smartuser director", "panic_expansion_fail");
2313 $transport = $$hash{"transport"};
2314 $new_address = $$hash{"new_address"};
2316 if (defined $transport && defined $new_address)
2320 "** The Exim 3 configuration contains a smartuser director called '$name',\n".
2321 " which has both 'transport' and 'new_address' set. This has been turned\n".
2322 " into two routers for Exim 4. However, if the new address contains a\n" .
2323 " reference to \$local_part, this won't work correctly. In any case, you\n".
2324 " may be able to make it tidier by rewriting.\n";
2325 $$hash{"driver"} = "redirect";
2326 $$hash{"data"} = $new_address;
2327 $$hash{"redirect_router"} = "${name}_part2";
2329 $second_router = "\n".
2330 "#!!# This router is invented to go with the previous one because\n".
2331 "#!!# in Exim 4 you can't have a change of address and a transport\n".
2332 "#!!# setting in the same router as you could in Exim 3.\n\n" .
2334 " driver = accept\n".
2335 " condition = \$\{if eq\{\$local_part@\$domain\}" .
2336 "\{$new_address\}\{yes\}\{no\}\}\n".
2337 " transport = $$hash{'transport'}\n";
2339 delete $$hash{"new_address"};
2340 delete $$hash{"transport"};
2342 elsif (defined $new_address)
2344 $$hash{"driver"} = "redirect";
2345 $$hash{"data"} = $new_address;
2346 $$hash{"allow_defer"} = "true";
2347 $$hash{"allow_fail"} = "true";
2348 delete $$hash{"new_address"};
2350 else # Includes the case of neither set (verify_only)
2352 $$hash{"driver"} = "accept";
2353 if (defined $$hash{"rewrite"})
2357 "** The Exim 3 configuration contains a setting of the 'rewrite' option on\n".
2358 " a smartuser director called '$name', but this director does not have\n".
2359 " a setting of 'new_address', so 'rewrite' has no effect. The director\n".
2360 " has been turned into an 'accept' router, and 'rewrite' has been discarded.";
2361 delete $$hash{"rewrite"};
2367 # -------------------------------------
2369 # For ex-directors that don't have check_local_user set, add
2370 # retry_use_local_part to imitate what Exim 3 would have done.
2372 $$hash{"retry_use_local_part"} = "true"
2373 if (!defined $$hash{"check_local_user"} ||
2374 $$hash{"check_local_user"} eq "false") ;
2376 # Output the router's option settings
2380 # Output an auxiliary router if one is needed
2382 print STDOUT $second_router if defined $second_router;
2387 # Skip past any continuation lines for an option setting
2388 while ($c[$i] =~ /\\\s*$/s)
2391 $i++ while ($c[$i] =~ /^\s*#/);
2397 # -------- The transports configuration --------
2401 for ($i = $transport_start; $i < $clen; $i++)
2403 $type = &checkline($c[$i]);
2404 last if $type eq "end";
2406 if ($type eq "comment") { print STDOUT "$c[$i]\n"; next; }
2410 print STDOUT "begin transports\n\n";
2414 if ($type eq "driver")
2416 $hash = $driverlist{"$prefix$name"};
2417 $driver = $$hash{"driver"};
2418 print STDOUT "$name:\n";
2420 # ---- Changes to the appendfile transport ----
2422 if ($driver eq "appendfile")
2424 &renamed($hash, "prefix", "message_prefix");
2425 &renamed($hash, "suffix", "message_suffix");
2426 &abolished($hash, "An appendfile transport",
2427 "require_lockfile");
2428 &handle_batch_and_bsmtp($hash);
2429 if (defined $$hash{"from_hack"} && $$hash{"from_hack"} eq "false")
2431 print STDOUT "#!!# no_from_hack replaced by check_string\n";
2432 $$hash{"check_string"} = "";
2434 delete $$hash{"from_hack"};
2437 # ---- Changes to the lmtp transport ----
2439 elsif ($driver eq "lmtp")
2441 if (defined $$hash{"batch"} && $$hash{"batch"} ne "none")
2443 $$hash{"batch_max"} = "100" if !defined $$hash{"batch_max"};
2444 $$hash{"batch_id"} = "\$domain" if $$hash{"batch"} eq "domain";
2448 $$hash{"batch_max"} = "1" if defined $$hash{"batch_max"};
2450 delete $$hash{"batch"};
2453 # ---- Changes to the pipe transport ----
2455 elsif ($driver eq "pipe")
2457 &renamed($hash, "prefix", "message_prefix");
2458 &renamed($hash, "suffix", "message_suffix");
2459 &handle_batch_and_bsmtp($hash);
2460 if (defined $$hash{"from_hack"} && $$hash{"from_hack"} eq "false")
2462 print STDOUT "#!!# no_from_hack replaced by check_string\n";
2463 $$hash{"check_string"} = "";
2465 delete $$hash{"from_hack"};
2468 # ---- Changes to the smtp transport ----
2470 elsif ($driver eq "smtp")
2472 &abolished($hash, "An smtp transport", "mx_domains");
2473 &renamed($hash, "service", "port");
2474 &renamed($hash, "tls_verify_ciphers", "tls_require_ciphers");
2475 &renamed($hash, "authenticate_hosts", "hosts_try_auth");
2477 if (defined $$hash{"batch_max"})
2479 print STDOUT "#!!# batch_max renamed connection_max_messages\n";
2480 $$hash{"connection_max_messages"} = $$hash{"batch_max"};
2481 delete $$hash{"batch_max"};
2484 foreach $o ("hosts_try_auth", "hosts_avoid_tls", "hosts_require_tls",
2485 "mx_domains", "serialize_hosts")
2487 $$hash{$o} = &no_expand_regex($$hash{$o}) if defined $$hash{$o};
2491 &outdriver($driverlist{"$prefix$name"});
2495 # Skip past any continuation lines for an option setting
2496 while ($c[$i] =~ /\\\s*$/s)
2499 $i++ while ($c[$i] =~ /^\s*#/);
2504 # -------- The retry configuration --------
2507 for ($i = $retry_start; $i < $clen && $i < $rewrite_start - 1; $i++)
2511 if ($c[$i] !~ /^\s*(#|$)/)
2513 print STDOUT "\nbegin retry\n\n";
2517 &print_no_expand($c[$i]);
2520 print STDOUT "\n# End of Exim 4 configuration\n";
2522 print STDERR "\n*******************************************************\n";
2523 print STDERR "***** Please review the generated file carefully. *****\n";
2524 print STDERR "*******************************************************\n\n";