Fix GNU/Hurd build. Bug 3044
[exim.git] / src / src / transport-filter.src
1 #! PERL_COMMAND
2
3 # Copyright (c) The Exim Maintainers 2023
4 # See the file NOTICE for conditions of use and distribution.
5 # SPDX-License-Identifier: GPL-2.0-or-later
6
7
8 # This is a Perl script to demonstrate the possibilities of on-the-fly
9 # delivery filtering in Exim. It is presented with a message on its standard
10 # input, and must copy it to the standard output, transforming it as it
11 # pleases, but of course it must keep to the syntax of RFC 822 for the headers.
12
13 # The filter is run before any SMTP-specific processing, such as turning
14 # \n into \r\n and escaping lines beginning with a dot.
15 #
16 # Philip Hazel, May 1997
17 #############################################################################
18
19 use warnings;
20 BEGIN { pop @INC if $INC[-1] eq '.' };
21 use File::Basename;
22
23 if ($ARGV[0] eq '--version' || $ARGV[0] eq '-v') {
24     print basename($0) . ": $0\n",
25         "build: EXIM_RELEASE_VERSIONEXIM_VARIANT_VERSION\n",
26         "perl(runtime): $]\n";
27         exit 0;
28 }
29
30 # If the filter is called with any arguments, insert them into the message
31 # as X-Arg headers, just to verify what they are.
32
33 for ($ac = 0; $ac < @ARGV; $ac++)
34   {
35   printf("X-Arg%d: %s\n", $ac, $ARGV[$ac]);
36   }
37
38 # Now read the header portion of the message; this is easy to do in Perl
39
40 $/ = "";                    # set paragraph mode
41 chomp($headers = <STDIN>);  # read a paragraph, remove trailing newlines
42 $/ = "\n";                  # unset paragraph mode
43
44 # Splitting up a sequence of unique headers is easy to do in Perl, but a
45 # message may contain duplicate headers of various kinds. It is better
46 # to extract the headers one wants from the whole paragraph, do any appropriate
47 # munging, and then put them back (unless removing them altogether). Messing
48 # with "Received:" headers is not in any case to be encouraged.
49
50 # As a demonstration, we extract the "From:" header, add a textual comment
51 # to it, and put it back.
52
53 ($pre, $from, $post) =
54   $headers =~ /^(|(?:.|\n)+\n)   (?# Stuff preceding the From header,
55                                      which is either null, or any number
56                                      of characters, including \n, ending
57                                      with \n.)
58                From:[\s\t]*      (?# Header name, with optional space or tab.)
59                ((?:.|\n)*?)      (?# Header body, which contains any chars,
60                                      including \n, but we want to make it as
61                                      short as possible so as not to include
62                                      following headers by mistake.)
63                (|\n\S(?:.|\n)*)$ (?# Header terminates at end or at \n followed
64                                      by a non-whitespace character and
65                                      remaining headers.)
66               /ix;                #  case independent, regular expression,
67                                   #  use extended features (ignore whitespace)
68
69 # Only do something if there was a From: header, of course. It has been
70 # extracted without the final \n, which is on the front of the $post
71 # variable.
72
73 if ($pre)
74   {
75   $headers = $pre . "From: $from (this is an added comment)" . $post;
76   }
77
78 # Add a new header to the end of the headers; remember that the final
79 # \n isn't there.
80
81 $headers .= "\nX-Comment: Message munged";
82
83 # Write out the processed headers, plus a blank line to separate them from
84 # the body.
85
86 printf(STDOUT "%s\n\n", $headers);
87
88 # As a demonstration of munging the body of a message, reverse all the
89 # characters in each line.
90
91 while (<STDIN>)
92   {
93   chomp;
94   $_ = reverse($_);
95   printf(STDOUT "%s\n", $_);
96   }
97
98 # End