Import Debian changes 4.89-2+deb9u4
[hcoop/debian/exim4.git] / src / convert4r3.src
CommitLineData
2813c06e 1#! PERL_COMMAND
420a0d19
CE
2
3# This is a Perl script that reads an Exim run-time configuration file and
4# checks for settings that were valid prior to release 3.00 but which were
5# obsoleted by that release. It writes a new file with suggested changes to
6# the standard output, and commentary about what it has done to stderr.
7
8# It is assumed that the input is a valid Exim configuration file.
9
2813c06e
CE
10use warnings;
11BEGIN { pop @INC if $INC[-1] eq '.' };
420a0d19
CE
12
13##################################################
14# Analyse one line #
15##################################################
16
17# This is called for the main and the driver sections, not for retry
18# or rewrite sections (which are unmodified).
19
20sub checkline{
21my($line) = $_[0];
22
23return "comment" if $line =~ /^\s*(#|$)/;
24return "end" if $line =~ /^\s*end\s*$/;
25
26# Macros are recognized only in the first section of the file.
27
28return "macro" if $prefix eq "" && $line =~ /^\s*[A-Z]/;
29
30# Pick out the name at the start and the rest of the line (into global
31# variables) and return whether the start of a driver or not.
32
33($i1,$name,$i2,$rest) = $line =~ /^(\s*)([a-z0-9_]+)(\s*)(.*?)\s*$/;
34return ($rest =~ /^:/)? "driver" : "option";
35}
36
37
38
39
40##################################################
41# Add transport setting to a director #
42##################################################
43
44# This function adds a transport setting to an aliasfile or forwardfile
45# director if a global setting exists and a local one does not. If neither
46# exist, it adds file/pipe/reply, but not the directory ones.
47
48sub add_transport{
49my($option) = @_;
50
51my($key) = "$prefix$driver.${option}_transport";
52if (!exists $o{$key})
53 {
54 if (exists $o{"address_${option}_transport"})
55 {
56 print STDOUT "# >> Option added by convert4r3\n";
57 printf STDOUT "${i1}${option}_transport = %s\n",
58 $o{"address_${option}_transport"};
59 printf STDERR
60 "\n%03d ${option}_transport added to $driver director.\n",
61 ++$count;
62 }
63 else
64 {
65 if ($option eq "pipe" || $option eq "file" || $option eq "reply")
66 {
67 print STDOUT "# >> Option added by convert4r3\n";
68 printf STDOUT "${i1}${option}_transport = address_${option}\n";
69 printf STDERR
70 "\n%03d ${option}_transport added to $driver director.\n",
71 ++$count;
72 }
73 }
74 }
75}
76
77
78
79
80##################################################
81# Negate a list of things #
82##################################################
83
84sub negate {
85my($list) = $_[0];
86
87return $list if ! defined $list;
88
89($list) = $list =~ /^"?(.*?)"?\s*$/s;
90
91# Under Perl 5.005 we can split very nicely at colons, ignoring double
92# colons, like this:
93#
94# @split = split /\s*(?<!:):(?!:)\s*(?:\\\s*)?/s, $list;
95#
96# However, we'd better make this work under Perl 5.004, since there is
97# a lot of that about.
98
99$list =~ s/::/>%%%%</g;
100@split = split /\s*:\s*(?:\\\s*)?/s, $list;
101foreach $item (@split)
102 {
103 $item =~ s/>%%%%</::/g;
104 }
105
106$" = " : \\\n ! ";
107return "! @split";
108}
109
110
111
112
113
114##################################################
115# Skip blank lines #
116##################################################
117
118# This function is called after we have generated no output for an option;
119# it skips subsequent blank lines if the previous line was blank.
120
121sub skipblanks {
122my($i) = $_[0];
123if ($last_was_blank)
124 {
125 $i++ while $c[$i+1] =~ /^\s*$/;
126 }
127return $i;
128}
129
130
131
132
133
134##################################################
135# Get base name of data key #
136##################################################
137
138sub base {
139return "$_[0]" if $_[0] !~ /^(?:d|r|t)\.[^.]+\.(.*)/;
140return $1;
141}
142
143
144
145##################################################
146# Amalgamate accept/reject/reject_except #
147##################################################
148
149# This function amalgamates the three previous kinds of
150# option into a single list, using negation for the middle one if
151# the final argument is "+", or for the outer two if the final
152# argument is "-".
153
154sub amalgamate {
155my($accept,$reject,$reject_except,$name);
156my($last_was_negated) = 0;
157my($join) = "";
158
159$accept = $o{$_[0]};
160$reject = $o{$_[1]};
161$reject_except = $o{$_[2]};
162$name = $_[3];
163
164if ($_[4] eq "+")
165 {
166 ($accept) = $accept =~ /^"?(.*?)"?\s*$/s if defined $accept;
167 $reject = &negate($reject) if defined $reject;
168 ($reject_except) = $reject_except =~ /^"?(.*?)"?\s*$/s if defined $reject_except;
169 }
170else
171 {
172 $accept = &negate($accept) if defined $accept;
173 ($reject) = $reject =~ /^"?(.*?)"?\s*$/s if defined $reject;
174 $reject_except = &negate($reject_except) if defined $reject_except;
175 }
176
177print STDOUT "# >> Option rewritten by convert4r3\n";
178print STDOUT "${i1}$name = \"";
179
180if (defined $reject_except)
181 {
182 print STDOUT "$reject_except";
183 $join = " : \\\n ";
184 $last_was_negated = ($_[4] ne "+");
185 }
186if (defined $reject)
187 {
188 print STDOUT "$join$reject";
189 $join = " : \\\n ";
190 $last_was_negated = ($_[4] eq "+");
191 }
192if (defined $accept)
193 {
194 print STDOUT "$join$accept";
195 $last_was_negated = ($_[4] ne "+");
196 $join = " : \\\n ";
197 }
198
199print STDOUT "$join*" if $last_was_negated;
200
201print STDOUT "\"\n";
202
203my($driver_name);
204my($driver_type) = "";
205
206if ($_[0] =~ /^(d|r|t)\.([^.]+)\./ ||
207 $_[1] =~ /^(d|r|t)\.([^.]+)\./ ||
208 $_[2] =~ /^(d|r|t)\.([^.]+)\./)
209 {
210 $driver_type = ($1 eq 'd')? "director" : ($1 eq 'r')? "router" : "transport";
211 $driver_name = $2;
212 }
213
214my($x) = ($driver_type ne "")? " in \"$driver_name\" $driver_type" : "";
215
216my($l0) = &base($_[0]);
217my($l1) = &base($_[1]);
218my($l2) = &base($_[2]);
219
220
221if ($l2 eq "")
222 {
223 if ($l0 eq "")
224 {
225 printf STDERR "\n%03d $l1 converted to $name$x.\n", ++$count;
226 }
227 else
228 {
229 printf STDERR "\n%03d $l0 and $l1\n amalgamated into $name$x.\n",
230 ++$count;
231 }
232 }
233else
234 {
235 if ($l1 eq "")
236 {
237 printf STDERR "\n%03d $l0 and $l2\n amalgamated into $name$x.\n",
238 ++$count;
239 }
240 else
241 {
242 printf STDERR "\n%03d $l0, $l1 and $l2\n amalgamated into " .
243 "$name$x.\n", ++$count;
244 }
245 }
246}
247
248
249
250
251##################################################
252# Join two lists, if they exist #
253##################################################
254
255sub pair{
256my($l1) = $o{"$_[0]"};
257my($l2) = $o{"$_[1]"};
258
259return $l2 if (!defined $l1);
260return $l1 if (!defined $l2);
261
262($l1) = $l1 =~ /^"?(.*?)"?\s*$/s;
263($l2) = $l2 =~ /^"?(.*?)"?\s*$/s;
264
265return "$l1 : $l2";
266}
267
268
269
270
271##################################################
272# Amalgamate accept/reject/reject_except pairs #
273##################################################
274
275# This is like amalgamate, but it combines pairs of arguments, and
276# doesn't output commentary (easier to write a generic one for the few
277# cases).
278
279sub amalgamatepairs {
280my($accept) = &pair($_[0], $_[1]);
281my($reject) = &pair($_[2], $_[3]);
282my($reject_except) = &pair($_[4], $_[5]);
283my($last_was_negated) = 0;
284my($join) = "";
285
286if ($_[7] eq "+")
287 {
288 ($accept) = $accept =~ /^"?(.*?)"?\s*$/s if defined $accept;
289 $reject = &negate($reject) if defined $reject;
290 ($reject_except) = $reject_except =~ /^"?(.*?)"?\s*$/s if defined $reject_except;
291 }
292else
293 {
294 $accept = &negate($accept) if defined $accept;
295 ($reject) = $reject =~ /^"?(.*?)"?$/s if defined $reject;
296 $reject_except = &negate($reject_except) if defined $reject_except;
297 }
298
299print STDOUT "# >> Option rewritten by convert4r3\n";
300print STDOUT "${i1}$_[6] = \"";
301
302if (defined $reject_except)
303 {
304 print STDOUT "$reject_except";
305 $join = " : \\\n ";
306 $last_was_negated = ($_[7] ne "+");
307 }
308if (defined $reject)
309 {
310 print STDOUT "$join$reject";
311 $join = " : \\\n ";
312 $last_was_negated = ($_[7] eq "+");
313 }
314if (defined $accept)
315 {
316 print STDOUT "$join$accept";
317 $last_was_negated = ($_[7] ne "+");
318 $join = " : \\\n ";
319 }
320
321print STDOUT "$join*" if $last_was_negated;
322print STDOUT "\"\n";
323}
324
325
326
327##################################################
328# Amalgamate boolean and exception list(s) #
329##################################################
330
331sub amalgboolandlist {
332my($name,$bool,$e1,$e2) = @_;
333
334print STDOUT "# >> Option rewritten by convert4r3\n";
335if ($bool eq "false")
336 {
337 printf STDOUT "$i1$name =\n";
338 }
339else
340 {
341 printf STDOUT "$i1$name = ";
342 my($n1) = &negate($o{$e1});
343 my($n2) = &negate($o{$e2});
344 if (!defined $n1 && !defined $n2)
345 {
346 print STDOUT "*\n";
347 }
348 elsif (!defined $n1)
349 {
350 print STDOUT "\"$n2 : \\\n *\"\n";
351 }
352 elsif (!defined $n2)
353 {
354 print STDOUT "\"$n1 : \\\n *\"\n";
355 }
356 else
357 {
358 print STDOUT "\"$n1 : \\\n $n2 : \\\n *\"\n";
359 }
360 }
361}
362
363
364
365##################################################
366# Convert mask format #
367##################################################
368
369# This function converts an address and mask in old-fashioned dotted-quad
370# format into an address plus a new format mask.
371
372@byte_list = (0, 128, 192, 224, 240, 248, 252, 254, 255);
373
374sub mask {
375my($address,$mask) = @_;
376my($length) = 0;
377my($i, $j);
378
379my(@bytes) = split /\./, $mask;
380
381for ($i = 0; $i < 4; $i++)
382 {
383 for ($j = 0; $j <= 8; $j++)
384 {
385 if ($bytes[$i] == $byte_list[$j])
386 {
387 $length += $j;
388 if ($j != 8)
389 {
390 for ($i++; $i < 4; $i++)
391 {
392 $j = 9 if ($bytes[$i] != 0);
393 }
394 }
395 last;
396 }
397 }
398
399 if ($j > 8)
400 {
401 print STDERR "*** IP mask $mask cannot be converted to /n format. ***\n";
402 return "$address/$mask";
403 }
404 }
405
406if (!defined $masks{$mask})
407 {
408 printf STDERR "\n%03d IP address mask $mask converted to /$length\n",
409 ++$count, $mask, $length;
410 $masks{$mask} = 1;
411 }
412
413return sprintf "$address/%d", $length;
414}
415
416
417
418
419
420##################################################
421# Main program #
422##################################################
423
424print STDERR "Exim pre-release 3.00 configuration file converter.\n";
425
426$count = 0;
427$seen_helo_accept_junk = 0;
428$seen_hold_domains = 0;
429$seen_receiver_unqualified = 0;
430$seen_receiver_verify_except = 0;
431$seen_receiver_verify_senders = 0;
432$seen_rfc1413_except = 0;
433$seen_sender_accept = 0;
434$seen_sender_accept_recipients = 0;
435$seen_sender_host_accept = 0;
436$seen_sender_host_accept_recipients = 0;
437$seen_sender_host_accept_relay = 0;
438$seen_sender_unqualified = 0;
439$seen_sender_verify_except_hosts = 0;
440$seen_smtp_etrn = 0;
441$seen_smtp_expn = 0;
442$seen_smtp_reserve = 0;
443$semicomma = 0;
444
445# Read the entire file into an array
446
447chomp(@c = <STDIN>);
448
449# First, go through the input and covert any net masks in the old dotted-quad
450# style into the new /n style.
451
452for ($i = 0; $i < scalar(@c); $i++)
453 {
454 $c[$i] =~
455 s"((?:\d{1,3}\.){3}\d{1,3})/((?:\d{1,3}\.){3}\d{1,3})"&mask($1,$2)"eg;
456 }
457
458# We now make two more passes over the input. In the first pass, we place all
459# the option values into an associative array. Main options are keyed by their
460# names; options for drivers are keyed by a driver type letter, the driver
461# name, and the option name, dot-separated. In the second pass we modify
462# the options if necessary, and write the output file.
463
464for ($pass = 1; $pass < 3; $pass++)
465 {
466 $prefix = "";
467 $driver = "";
468 $last_was_blank = 0;
469
470 for ($i = 0; $i < scalar(@c); $i++)
471 {
472 # Everything after the router section is just copied in pass 2 and
473 # ignored in pass 1.
474
475 if ($prefix eq "end")
476 {
477 print STDOUT "$c[$i]\n" if $pass == 2;
478 next;
479 }
480
481 # Analyze the line
482
483 $type = &checkline($c[$i]);
484
485 # Skip comments in pass 1; copy in pass 2
486
487 if ($type eq "comment")
488 {
489 $last_was_blank = ($c[$i] =~ /^\s*$/)? 1 : 0;
490 print STDOUT "$c[$i]\n" if $pass == 2;
491 next;
492 }
493
494 # Skip/copy macro definitions, but must handle continuations
495
496 if ($type eq "macro")
497 {
498 print STDOUT "$c[$i]\n" if $pass == 2;
499 while ($c[$i] =~ /\\\s*$/)
500 {
501 $i++;
502 print STDOUT "$c[$i]\n" if $pass == 2;
503 }
504 $last_was_blank = 0;
505 next;
506 }
507
508 # Handle end of section
509
510 if ($type eq "end")
511 {
512 $prefix = "end"if $prefix eq "r.";
513 $prefix = "r." if $prefix eq "d.";
514 $prefix = "d." if $prefix eq "t.";
515 $prefix = "t." if $prefix eq "";
516 print STDOUT "$c[$i]\n" if $pass == 2;
517 $last_was_blank = 0;
518 next;
519 }
520
521 # Handle start of a new driver
522
523 if ($type eq "driver")
524 {
525 $driver = $name;
526 print STDOUT "$c[$i]\n" if $pass == 2;
527 $last_was_blank = 0;
528 $seen_domains = 0;
529 $seen_local_parts = 0;
530 $seen_senders = 0;
531 $seen_mx_domains = 0;
532 $seen_serialize = 0;
533 next;
534 }
535
536 # Handle definition of an option
537
538 if ($type eq "option")
539 {
540 # Handle continued strings
541
542 if ($rest =~ /^=\s*".*\\$/)
543 {
544 for (;;)
545 {
546 $rest .= "\n$c[++$i]";
547 last unless $c[$i] =~ /(\\\s*$|^\s*#)/;
548 }
549 }
550
551 # Remove any terminating commas and semicolons in pass 2
552
553 if ($pass == 2 && $rest =~ /[;,]\s*$/)
554 {
555 $rest =~ s/\s*[;,]\s*$//;
556 if (!$semicomma)
557 {
558 printf STDERR
559 "\n%03d Terminating semicolons and commas removed from driver " .
560 "options.\n", ++$count;
561 $semicomma = 1;
562 }
563 }
564
565 # Convert all booleans to "x = true/false" format, but save the
566 # original so that it can be reproduced unchanged for options that
567 # are not of interest.
568
569 $origname = $name;
570 $origrest = $rest;
571
572 if ($name =~ /^not?_(.*)/)
573 {
574 $name = $1;
575 $rest = "= false";
576 }
577 elsif ($rest !~ /^=/)
578 {
579 $rest = "= true";
580 }
581
582 # Set up the associative array key, and get rid of the = on the data
583
584 $key = ($prefix eq "")? "$name" : "$prefix$driver.$name";
585 ($rest) = $rest =~ /^=\s*(.*)/s;
586
587 # Create the associative array of values in pass 1
588
589 if ($pass == 1)
590 {
591 $o{$key} = $rest;
592 }
593
594 # In pass 2, test for interesting options and do the necessary; copy
595 # all the rest.
596
597 else
598 {
599 ########## Global configuration ##########
600
601 # These global options are abolished
602
603 if ($name eq "address_directory_transport" ||
604 $name eq "address_directory2_transport" ||
605 $name eq "address_file_transport" ||
606 $name eq "address_pipe_transport" ||
607 $name eq "address_reply_transport")
608 {
609 ($n2) = $name =~ /^address_(.*)/;
610 printf STDERR "\n%03d $name option deleted.\n", ++$count;
611 printf STDERR " $n2 will be added to appropriate directors.\n";
612 $i = &skipblanks($i);
613 next;
614 }
615
616 # This debugging option is abolished
617
618 elsif ($name eq "sender_verify_log_details")
619 {
620 printf STDERR "\n%03d $name option deleted.\n", ++$count;
621 printf STDERR " (Little used facility abolished.)\n";
622 }
623
624 # This option has been renamed
625
626 elsif ($name eq "check_dns_names")
627 {
628 $origname =~ s/check_dns/dns_check/;
629 print STDOUT "# >> Option rewritten by convert4r3\n";
630 print STDOUT "$i1$origname$i2$origrest\n";
631 printf STDERR "\n%03d check_dns_names renamed as dns_check_names.\n",
632 ++$count;
633 }
634
635 # helo_accept_junk_nets is abolished
636
637 elsif ($name eq "helo_accept_junk_nets" ||
638 $name eq "helo_accept_junk_hosts")
639 {
640 if (!$seen_helo_accept_junk)
641 {
642 &amalgamate("helo_accept_junk_nets", "",
643 "helo_accept_junk_hosts", "helo_accept_junk_hosts", "+");
644 $seen_helo_accept_junk = 1;
645 }
646 else
647 {
648 $i = &skipblanks($i);
649 next;
650 }
651 }
652
653 # helo_verify_except_{hosts,nets} are abolished, and helo_verify
654 # is now a host list instead of a boolean.
655
656 elsif ($name eq "helo_verify")
657 {
658 &amalgboolandlist("helo_verify", $rest, "helo_verify_except_hosts",
659 "helo_verify_except_nets");
660 printf STDERR "\n%03d helo_verify converted to host list.\n",
661 ++$count;
662 }
663 elsif ($name eq "helo_verify_except_hosts" ||
664 $name eq "helo_verify_except_nets")
665 {
666 $i = &skipblanks($i);
667 next;
668 }
669
670 # helo_verify_nets was an old synonym for host_lookup_nets; only
671 # one of them will be encountered. Change to a new name.
672
673 elsif ($name eq "helo_verify_nets" ||
674 $name eq "host_lookup_nets")
675 {
676 print STDOUT "# >> Option rewritten by convert4r3\n";
677 print STDOUT "${i1}host_lookup$i2$origrest\n";
678 printf STDERR "\n%03d $name renamed as host_lookup.\n", ++$count;
679 }
680
681 # hold_domains_except is abolished; add as negated items to
682 # hold_domains.
683
684 elsif ($name eq "hold_domains_except" ||
685 $name eq "hold_domains")
686 {
687 if ($seen_hold_domains) # If already done with these
688 { # omit, and following blanks.
689 $i = &skipblanks($i);
690 next;
691 }
692 $seen_hold_domains = 1;
693
694 if (exists $o{"hold_domains_except"})
695 {
696 &amalgamate("hold_domains", "hold_domains_except", "",
697 "hold_domains", "+");
698 }
699 else
700 {
701 print STDOUT "$i1$origname$i2$origrest\n";
702 }
703 }
704
705 # ignore_fromline_nets is renamed as ignore_fromline_hosts
706
707 elsif ($name eq "ignore_fromline_nets")
708 {
709 $origname =~ s/_nets/_hosts/;
710 print STDOUT "# >> Option rewritten by convert4r3\n";
711 print STDOUT "$i1$origname$i2$origrest\n";
712 printf STDERR
713 "\n%03d ignore_fromline_nets renamed as ignore_fromline_hosts.\n",
714 ++$count;
715 }
716
717 # Output a warning for message filters with no transports set
718
719 elsif ($name eq "message_filter")
720 {
721 print STDOUT "$i1$origname$i2$origrest\n";
722
723 if (!exists $o{"message_filter_directory_transport"} &&
724 !exists $o{"message_filter_directory2_transport"} &&
725 !exists $o{"message_filter_file_transport"} &&
726 !exists $o{"message_filter_pipe_transport"} &&
727 !exists $o{"message_filter_reply_transport"})
728 {
729 printf STDERR
730 "\n%03d message_filter is set, but no message_filter transports "
731 . "are defined.\n"
732 . " If your filter generates file or pipe deliveries, or "
733 . "auto-replies,\n"
734 . " you will need to define "
735 . "message_filter_{file,pipe,reply}_transport\n"
736 . " options, as required.\n", ++$count;
737 }
738 }
739
740 # queue_remote_except is abolished, and queue_remote is replaced by
741 # queue_remote_domains, which is a host list.
742
743 elsif ($name eq "queue_remote")
744 {
745 &amalgboolandlist("queue_remote_domains", $rest,
746 "queue_remote_except", "");
747 printf STDERR
748 "\n%03d queue_remote converted to domain list queue_remote_domains.\n",
749 ++$count;
750 }
751 elsif ($name eq "queue_remote_except")
752 {
753 $i = &skipblanks($i);
754 next;
755 }
756
757 # queue_smtp_except is abolished, and queue_smtp is replaced by
758 # queue_smtp_domains, which is a host list.
759
760 elsif ($name eq "queue_smtp")
761 {
762 &amalgboolandlist("queue_smtp_domains", $rest,
763 "queue_smtp_except", "");
764 printf STDERR
765 "\n%03d queue_smtp converted to domain list queue_smtp_domains.\n",
766 ++$count;
767 }
768 elsif ($name eq "queue_smtp_except")
769 {
770 $i = &skipblanks($i);
771 next;
772 }
773
774 # rbl_except_nets is replaced by rbl_hosts
775
776 elsif ($name eq "rbl_except_nets")
777 {
778 &amalgamate("", "rbl_except_nets", "", "rbl_hosts", "+");
779 }
780
781 # receiver_unqualified_nets is abolished
782
783 elsif ($name eq "receiver_unqualified_nets" ||
784 $name eq "receiver_unqualified_hosts")
785 {
786 if (!$seen_receiver_unqualified)
787 {
788 &amalgamate("receiver_unqualified_nets", "",
789 "receiver_unqualified_hosts", "receiver_unqualified_hosts", "+");
790 $seen_receiver_unqualified = 1;
791 }
792 else
793 {
794 $i = &skipblanks($i);
795 next;
796 }
797 }
798
799 # receiver_verify_except_{hosts,nets} are replaced by
800 # receiver_verify_hosts.
801
802 elsif ($name eq "receiver_verify_except_hosts" ||
803 $name eq "receiver_verify_except_nets")
804 {
805 if (!$seen_receiver_verify_except)
806 {
807 &amalgboolandlist("receiver_verify_hosts", "true",
808 "receiver_verify_except_hosts", "receiver_verify_except_nets");
809 printf STDERR
810 "\n%03d receiver_verify_except_{hosts,nets} converted to " .
811 "receiver_verify_hosts.\n",
812 ++$count;
813 $seen_receiver_verify_except = 1;
814 }
815 else
816 {
817 $i = &skipblanks($i);
818 next;
819 }
820 }
821
822 # receiver_verify_senders_except is abolished
823
824 elsif ($name eq "receiver_verify_senders" ||
825 $name eq "receiver_verify_senders_except")
826 {
827 if (defined $o{"receiver_verify_senders_except"})
828 {
829 if (!$seen_receiver_verify_senders)
830 {
831 &amalgamate("receiver_verify_senders",
832 "receiver_verify_senders_except", "",
833 "receiver_verify_senders", "+");
834 $seen_receiver_verify_senders = 1;
835 }
836 else
837 {
838 $i = &skipblanks($i);
839 next;
840 }
841 }
842 else
843 {
844 print STDOUT "$i1$origname$i2$origrest\n";
845 }
846 }
847
848 # rfc1413_except_{hosts,nets} are replaced by rfc1413_hosts.
849
850 elsif ($name eq "rfc1413_except_hosts" ||
851 $name eq "rfc1413_except_nets")
852 {
853 if (!$seen_rfc1413_except)
854 {
855 &amalgboolandlist("rfc1413_hosts", "true",
856 "rfc1413_except_hosts", "rfc1413_except_nets");
857 printf STDERR
858 "\n%03d rfc1413_except_{hosts,nets} converted to rfc1413_hosts.\n",
859 ++$count;
860 $seen_rfc1413_except = 1;
861 }
862 else
863 {
864 $i = &skipblanks($i);
865 next;
866 }
867 }
868
869 # sender_accept and sender_reject_except are abolished
870
871 elsif ($name eq "sender_accept" ||
872 $name eq "sender_reject")
873 {
874 if (!$seen_sender_accept)
875 {
876 &amalgamate("sender_accept", "sender_reject",
877 "sender_reject_except", "sender_reject", "-");
878 $seen_sender_accept = 1;
879 }
880 else
881 {
882 $i = &skipblanks($i);
883 next;
884 }
885 }
886
887 # sender_accept_recipients is also abolished; sender_reject_except
888 # also used to apply to this, so we include it here as well.
889
890 elsif ($name eq "sender_accept_recipients" ||
891 $name eq "sender_reject_recipients")
892 {
893 if (!$seen_sender_accept_recipients)
894 {
895 &amalgamate("sender_accept_recipients", "sender_reject_recipients",
896 "sender_reject_except", "sender_reject_recipients", "-");
897 $seen_sender_accept_recipients = 1;
898 }
899 else
900 {
901 $i = &skipblanks($i);
902 next;
903 }
904 }
905
906 # sender_reject_except must be removed
907
908 elsif ($name eq "sender_reject_except")
909 {
910 $i = &skipblanks($i);
911 next;
912 }
913
914 # sender_{host,net}_{accept,reject}[_except] all collapse into
915 # host_reject.
916
917 elsif ($name eq "sender_host_accept" ||
918 $name eq "sender_net_accept" ||
919 $name eq "sender_host_reject" ||
920 $name eq "sender_net_reject")
921 {
922 if (!$seen_sender_host_accept)
923 {
924 &amalgamatepairs("sender_host_accept", "sender_net_accept",
925 "sender_host_reject", "sender_net_reject",
926 "sender_host_reject_except", "sender_net_reject_except",
927 "host_reject", "-");
928 printf STDERR "\n%03d sender_{host,net}_{accept,reject} and " .
929 "sender_{host_net}_reject_except\n" .
930 " amalgamated into host_reject.\n", ++$count;
931 $seen_sender_host_accept = 1;
932 }
933 else
934 {
935 $i = &skipblanks($i);
936 next;
937 }
938 }
939
940 # sender_{host,net}_{accept,reject}_recipients all collapse into
941 # host_reject_recipients.
942
943 elsif ($name eq "sender_host_accept_recipients" ||
944 $name eq "sender_net_accept_recipients" ||
945 $name eq "sender_host_reject_recipients" ||
946 $name eq "sender_net_reject_recipients")
947 {
948 if (!$seen_sender_host_accept_recipients)
949 {
950 &amalgamatepairs("sender_host_accept_recipients",
951 "sender_net_accept_recipients",
952 "sender_host_reject_recipients",
953 "sender_net_reject_recipients",
954 "sender_host_reject_except", "sender_net_reject_except",
955 "host_reject_recipients", "-");
956 printf STDERR "\n%03d sender_{host,net}_{accept,reject}_recipients"
957 . "\n and sender_{host_net}_reject_except"
958 . "\n amalgamated into host_reject_recipients.\n", ++$count;
959 $seen_sender_host_accept_recipients = 1;
960 }
961 else
962 {
963 $i = &skipblanks($i);
964 next;
965 }
966 }
967
968 # sender_{host,net}_reject_except must be removed
969
970 elsif ($name eq "sender_host_reject_except" ||
971 $name eq "sender_net_reject_except")
972 {
973 $i = &skipblanks($i);
974 next;
975 }
976
977 # sender_{host,net}_{accept,reject}_relay all collapse into
978 # host_accept_relay.
979
980 elsif ($name eq "sender_host_accept_relay" ||
981 $name eq "sender_net_accept_relay" ||
982 $name eq "sender_host_reject_relay" ||
983 $name eq "sender_net_reject_relay")
984 {
985 if (!$seen_sender_host_accept_relay)
986 {
987 &amalgamatepairs("sender_host_accept_relay",
988 "sender_net_accept_relay",
989 "sender_host_reject_relay",
990 "sender_net_reject_relay",
991 "sender_host_reject_relay_except",
992 "sender_net_reject_relay_except",
993 "host_accept_relay", "+");
994 printf STDERR "\n%03d sender_{host,net}_{accept,reject}_relay"
995 . "\n and sender_{host_net}_reject_relay_except"
996 . "\n amalgamated into host_accept_relay.\n", ++$count;
997 $seen_sender_host_accept_relay = 1;
998 }
999 else
1000 {
1001 $i = &skipblanks($i);
1002 next;
1003 }
1004 }
1005
1006 # sender_{host,net}_reject_relay_except must be removed
1007
1008 elsif ($name eq "sender_host_reject_relay_except" ||
1009 $name eq "sender_net_reject_relay_except")
1010 {
1011 $i = &skipblanks($i);
1012 next;
1013 }
1014
1015
1016 # sender_unqualified_nets is abolished
1017
1018 elsif ($name eq "sender_unqualified_nets" ||
1019 $name eq "sender_unqualified_hosts")
1020 {
1021 if (!$seen_sender_unqualified)
1022 {
1023 &amalgamate("sender_unqualified_nets", "",
1024 "sender_unqualified_hosts", "sender_unqualified_hosts", "+");
1025 $seen_sender_unqualified = 1;
1026 }
1027 else
1028 {
1029 $i = &skipblanks($i);
1030 next;
1031 }
1032 }
1033
1034 # sender_verify_except_{hosts,nets} are replaced by sender_verify_hosts.
1035
1036 elsif ($name eq "sender_verify_except_hosts" ||
1037 $name eq "sender_verify_except_nets")
1038 {
1039 if (!$seen_sender_verify_except_hosts)
1040 {
1041 &amalgboolandlist("sender_verify_hosts", "true",
1042 "sender_verify_except_hosts", "sender_verify_except_nets");
1043 printf STDERR
1044 "\n%03d sender_verify_except_{hosts,nets} converted to " .
1045 "sender_verify_hosts.\n",
1046 ++$count;
1047 $seen_sender_verify_except_hosts = 1;
1048 }
1049 else
1050 {
1051 $i = &skipblanks($i);
1052 next;
1053 }
1054 }
1055
1056 # smtp_etrn_nets is abolished
1057
1058 elsif ($name eq "smtp_etrn_nets" ||
1059 $name eq "smtp_etrn_hosts")
1060 {
1061 if (!$seen_smtp_etrn)
1062 {
1063 &amalgamate("smtp_etrn_nets", "",
1064 "smtp_etrn_hosts", "smtp_etrn_hosts", "+");
1065 $seen_smtp_etrn = 1;
1066 }
1067 else
1068 {
1069 $i = &skipblanks($i);
1070 next;
1071 }
1072 }
1073
1074 # smtp_expn_nets is abolished
1075
1076 elsif ($name eq "smtp_expn_nets" ||
1077 $name eq "smtp_expn_hosts")
1078 {
1079 if (!$seen_smtp_expn)
1080 {
1081 &amalgamate("smtp_expn_nets", "",
1082 "smtp_expn_hosts", "smtp_expn_hosts", "+");
1083 $seen_smtp_expn = 1;
1084 }
1085 else
1086 {
1087 $i = &skipblanks($i);
1088 next;
1089 }
1090 }
1091
1092 # This option has been renamed
1093
1094 elsif ($name eq "smtp_log_connections")
1095 {
1096 $origname =~ s/smtp_log/log_smtp/;
1097 print STDOUT "# >> Option rewritten by convert4r3\n";
1098 print STDOUT "$i1$origname$i2$origrest\n";
1099 printf STDERR "\n%03d smtp_log_connections renamed as " .
1100 "log_smtp_connections.\n",
1101 ++$count;
1102 }
1103
1104 # smtp_reserve_nets is abolished
1105
1106 elsif ($name eq "smtp_reserve_nets" ||
1107 $name eq "smtp_reserve_hosts")
1108 {
1109 if (!$seen_smtp_reserve)
1110 {
1111 &amalgamate("smtp_reserve_nets", "",
1112 "smtp_reserve_hosts", "smtp_reserve_hosts", "+");
1113 $seen_smtp_reserve = 1;
1114 }
1115 else
1116 {
1117 $i = &skipblanks($i);
1118 next;
1119 }
1120 }
1121
1122 ########### Driver configurations ##########
1123
1124 # For aliasfile and forwardfile directors, add file, pipe, and
1125 # reply transports - copying from the globals if they are set.
1126
1127 elsif ($name eq "driver")
1128 {
1129 $driver_type = $rest;
1130 print STDOUT "$i1$origname$i2$origrest\n";
1131 if ($rest eq "aliasfile" || $rest eq "forwardfile")
1132 {
1133 &add_transport("directory");
1134 &add_transport("directory2");
1135 &add_transport("file");
1136 &add_transport("pipe");
1137 &add_transport("reply") if $rest eq "forwardfile";
1138 }
1139 }
1140
1141 # except_domains is abolished; add as negated items to domains.
1142
1143 elsif ($name eq "except_domains" ||
1144 $name eq "domains")
1145 {
1146 if ($seen_domains) # If already done with these
1147 { # omit, and following blanks.
1148 $i = &skipblanks($i);
1149 next;
1150 }
1151 $seen_domains = 1;
1152
1153 if (exists $o{"$prefix$driver.except_domains"})
1154 {
1155 &amalgamate("$prefix$driver.domains",
1156 "$prefix$driver.except_domains", "",
1157 "domains", "+");
1158 }
1159 else
1160 {
1161 print STDOUT "$i1$origname$i2$origrest\n";
1162 }
1163 }
1164
1165 # except_local_parts is abolished; add as negated items to
1166 # local_parts.
1167
1168 elsif ($name eq "except_local_parts" ||
1169 $name eq "local_parts")
1170 {
1171 if ($seen_local_parts) # If already done with these
1172 { # omit, and following blanks.
1173 $i = &skipblanks($i);
1174 next;
1175 }
1176 $seen_local_parts = 1;
1177
1178 if (exists $o{"$prefix$driver.except_local_parts"})
1179 {
1180 &amalgamate("$prefix$driver.local_parts",
1181 "$prefix$driver.except_local_parts", "",
1182 "local_parts", "+");
1183 }
1184 else
1185 {
1186 print STDOUT "$i1$origname$i2$origrest\n";
1187 }
1188 }
1189
1190 # except_senders is abolished; add as negated items to senders
1191
1192 elsif ($name eq "except_senders" ||
1193 $name eq "senders")
1194 {
1195 if ($seen_senders) # If already done with these
1196 { # omit, and following blanks.
1197 $i = &skipblanks($i);
1198 next;
1199 }
1200 $seen_senders = 1;
1201
1202 if (exists $o{"$prefix$driver.except_senders"})
1203 {
1204 &amalgamate("$prefix$driver.senders",
1205 "$prefix$driver.except_senders", "",
1206 "senders", "+");
1207 }
1208 else
1209 {
1210 print STDOUT "$i1$origname$i2$origrest\n";
1211 }
1212 }
1213
1214 # This option has been renamed
1215
1216 elsif ($name eq "directory" && $driver_type eq "aliasfile")
1217 {
1218 $origname =~ s/directory/home_directory/;
1219 print STDOUT "# >> Option rewritten by convert4r3\n";
1220 print STDOUT "$i1$origname$i2$origrest\n";
1221 printf STDERR "\n%03d directory renamed as " .
1222 "home_directory in \"$driver\" director.\n",
1223 ++$count;
1224 }
1225
1226 # This option has been renamed
1227
1228 elsif ($name eq "directory" && $driver_type eq "forwardfile")
1229 {
1230 $origname =~ s/directory/file_directory/;
1231 print STDOUT "# >> Option rewritten by convert4r3\n";
1232 print STDOUT "$i1$origname$i2$origrest\n";
1233 printf STDERR "\n%03d directory renamed as " .
1234 "file_directory in \"$driver\" director.\n",
1235 ++$count;
1236 }
1237
1238 # This option has been renamed
1239
1240 elsif ($name eq "forbid_filter_log" && $driver_type eq "forwardfile")
1241 {
1242 $origname =~ s/log/logwrite/;
1243 print STDOUT "# >> Option rewritten by convert4r3\n";
1244 print STDOUT "$i1$origname$i2$origrest\n";
1245 printf STDERR "\n%03d forbid_filter_log renamed as " .
1246 "forbid_filter_logwrite in \"$driver\" director.\n",
1247 ++$count;
1248 }
1249
1250 # This option has been renamed
1251
1252 elsif ($name eq "directory" && $driver_type eq "localuser")
1253 {
1254 $origname =~ s/directory/match_directory/;
1255 print STDOUT "# >> Option rewritten by convert4r3\n";
1256 print STDOUT "$i1$origname$i2$origrest\n";
1257 printf STDERR "\n%03d directory renamed as " .
1258 "match_directory in \"$driver\" director.\n",
1259 ++$count;
1260 }
1261
1262 # mx_domains_except (and old synonym non_mx_domains) are abolished
1263 # (both lookuphost router and smtp transport)
1264
1265 elsif ($name eq "mx_domains" ||
1266 $name eq "mx_domains_except" ||
1267 $name eq "non_mx_domains")
1268 {
1269 if ($seen_mx_domains) # If already done with these
1270 { # omit, and following blanks.
1271 $i = &skipblanks($i);
1272 next;
1273 }
1274 $seen_mx_domains = 1;
1275
1276 if (exists $o{"$prefix$driver.mx_domains_except"} ||
1277 exists $o{"$prefix$driver.non_mx_domains"})
1278 {
1279 $o{"$prefix$driver.mx_domains_except"} =
1280 &pair("$prefix$driver.mx_domains_except",
1281 "$prefix$driver.non_mx_domains");
1282
1283 &amalgamate("$prefix$driver.mx_domains",
1284 "$prefix$driver.mx_domains_except", "",
1285 "mx_domains", "+");
1286 }
1287 else
1288 {
1289 print STDOUT "$i1$origname$i2$origrest\n";
1290 }
1291 }
1292
1293 # This option has been renamed
1294
1295 elsif ($name eq "directory" && $driver_type eq "pipe")
1296 {
1297 $origname =~ s/directory/home_directory/;
1298 print STDOUT "# >> Option rewritten by convert4r3\n";
1299 print STDOUT "$i1$origname$i2$origrest\n";
1300 printf STDERR "\n%03d directory renamed as " .
1301 "home_directory in \"$driver\" director.\n",
1302 ++$count;
1303 }
1304
1305 # serialize_nets is abolished
1306
1307 elsif ($name eq "serialize_nets" ||
1308 $name eq "serialize_hosts")
1309 {
1310 if (!$seen_serialize)
1311 {
1312 &amalgamate("$prefix$driver.serialize_nets", "",
1313 "$prefix$driver.serialize_hosts", "serialize_hosts", "+");
1314 $seen_serialize = 1;
1315 }
1316 else
1317 {
1318 $i = &skipblanks($i);
1319 next;
1320 }
1321 }
1322
1323
1324 # Option not of interest; reproduce verbatim
1325
1326 else
1327 {
1328 print STDOUT "$i1$origname$i2$origrest\n";
1329 }
1330
1331
1332 $last_was_blank = 0;
1333 }
1334 }
1335 }
1336
1337 }
1338
1339# Debugging: show the associative array
1340# foreach $key (sort keys %o) { print STDERR "$key = $o{$key}\n"; }
1341
1342print STDERR "\nEnd of configuration file conversion.\n";
1343print STDERR "\n*******************************************************\n";
1344print STDERR "***** Please review the generated file carefully. *****\n";
1345print STDERR "*******************************************************\n\n";
1346
1347print STDERR "In particular:\n\n";
1348
1349print STDERR "(1) If you use regular expressions in any options that have\n";
1350print STDERR " been rewritten by this script, they might have been put\n";
1351print STDERR " inside quotes, when then were not previously quoted. This\n";
1352print STDERR " means that any backslashes in them must now be escaped.\n\n";
1353
1354print STDERR "(2) If your configuration refers to any external files that\n";
1355print STDERR " contain lists of network addresses, check that the masks\n";
1356print STDERR " are specified as single numbers, e.g. /24 and NOT as dotted\n";
1357print STDERR " quads (e.g. 255.255.255.0) because Exim release 3.00 does\n";
1358print STDERR " not recognize the dotted quad form.\n\n";
1359
1360print STDERR "(3) If your configuration uses macros for lists of domains or\n";
1361print STDERR " hosts or addresses, check to see if any of the references\n";
1362print STDERR " have been negated. If so, you will have to rework things,\n";
1363print STDERR " because the negation will apply only to the first item in\n";
1364print STDERR " the macro-generated list.\n\n";
1365
1366print STDERR "(4) If you do not generate deliveries to pipes, files, or\n";
1367print STDERR " auto-replies in your aliasfile and forwardfile directors,\n";
1368print STDERR " you can remove the added transport settings.\n\n";
1369
1370# End of convert4r3