mirror of
https://git.proxmox.com/git/proxmox-spamassassin
synced 2025-04-28 21:37:19 +00:00
229 lines
6.5 KiB
Perl
Executable File
229 lines
6.5 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
# <@LICENSE>
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership.
|
|
# The ASF licenses this file to you under the Apache License, Version 2.0
|
|
# (the "License"); you may not use this file except in compliance with
|
|
# the License. You may obtain a copy of the License at:
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
# </@LICENSE>
|
|
#
|
|
# This script isn't supposed to be run by hand, it's used by `make` as a pre-
|
|
# processor. It currently accepts these options on the command line:
|
|
#
|
|
# -M<module> Enables <module>
|
|
# -D<variable>=<value> Defines the <variable> to be <value>; if the value
|
|
# doesn't contain an equal sign, it is interpreted
|
|
# as a file and all of its lines containing equal
|
|
# signs are taken as <variable>=<value> pairs
|
|
#
|
|
# and some more to help with non-UNIX platforms, where command-line input
|
|
# and output redirection are not always available:
|
|
#
|
|
# -i<file> Read from input file <file>
|
|
# -o<file> Write to output file <file>
|
|
#
|
|
# -I<dir> Read from input directory <dir>
|
|
# -O<dir> Write to output directory <dir>
|
|
# <filename> ... Process named files from -I<dir> to -O<dir>
|
|
#
|
|
# -m<perm> Use chmod permissions <perm> for files
|
|
#
|
|
# Those modules are currently implemented:
|
|
# conditional Comments out every line containing the string
|
|
# REMOVEFORINST
|
|
# vars Replaces variables: upper case strings surrounded
|
|
# by double at-signs, eg. @@VERSION@@. The values are
|
|
# taken from the environment and can be overwritten with
|
|
# the -D switch. Empty/undefined variables are removed.
|
|
# sharpbang Does some sharpbang (#!) replacement. Uses PERL_BIN and
|
|
# PERL_WARN.
|
|
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
my %modules = ();
|
|
my %defines = ();
|
|
|
|
my @infiles = ();
|
|
my $infile;
|
|
my $outfile;
|
|
my $indir;
|
|
my $outdir;
|
|
my $mode;
|
|
|
|
|
|
# Each environment variable counts as an own defined var for us.
|
|
foreach (keys %ENV) {
|
|
$defines{$_} = $ENV{$_};
|
|
}
|
|
|
|
foreach (@ARGV) {
|
|
if (/^-M([a-z]+)$/) { $modules{$1} = 1; }
|
|
elsif (/^-D([A-Z0-9_]+)=(.*)$/) { $defines{$1} = $2; }
|
|
elsif (/^-D([^=]+)$/) { read_defs($1); }
|
|
elsif (/^-i(.+)$/) { $infile = $1; }
|
|
elsif (/^-o(.+)$/) { $outfile = $1; }
|
|
elsif (/^-I(.+)$/) { $indir = $1; }
|
|
elsif (/^-m(.*)$/) { $mode = '0'.$1; }
|
|
elsif (/^-O(.+)$/) { $outdir = $1; }
|
|
elsif (/^(.+)$/) { push (@infiles, $1); }
|
|
}
|
|
|
|
# On Windows, we get -m without an arg. avoid problems with that
|
|
# by just ignoring that switch.
|
|
$mode = undef unless $mode;
|
|
|
|
if (defined ($indir) && defined ($outdir) && scalar @infiles > 0) {
|
|
require File::Spec;
|
|
my $fname;
|
|
while ($fname = shift @infiles) {
|
|
my $in = File::Spec->catfile ($indir, $fname);
|
|
my $out = File::Spec->catfile ($outdir, $fname);
|
|
do_file ($in, $out);
|
|
}
|
|
}
|
|
elsif (defined ($infile) && defined($outfile)) {
|
|
do_file ($infile, $outfile);
|
|
}
|
|
else {
|
|
# just do STDIN/STDOUT . Not recommended for portability as
|
|
# it requires "<" and ">" for Makefile to do its work.
|
|
#
|
|
do_stdin();
|
|
}
|
|
|
|
|
|
sub read_defs {
|
|
my ($in) = @_;
|
|
open (DEFS, "<$in") or die "Cannot open $in: $!";
|
|
foreach (<DEFS>) {
|
|
$_ =~ s/^\s+|\s+$//g;
|
|
next if /^#/;
|
|
next unless /=/;
|
|
my ($var, $val) = split(/\s*=\s*/, $_, 2);
|
|
$var =~ tr/A-Z_//cd;
|
|
$defines{$var} = $val;
|
|
}
|
|
close (DEFS);
|
|
}
|
|
|
|
|
|
sub do_file {
|
|
my ($in, $out) = @_;
|
|
|
|
open (FOOIN, "<$in") or die "Cannot open $in: $!";
|
|
open (FOOOUT, ">$out") or die "Cannot open $out: $!";
|
|
|
|
do_it();
|
|
|
|
close (FOOIN);
|
|
close (FOOOUT);
|
|
|
|
if (defined $mode) {
|
|
chmod (oct $mode, $out) or die "Cannot chmod $mode $out: $!";
|
|
}
|
|
}
|
|
|
|
sub do_stdin {
|
|
open (FOOIN, "<&STDIN") or die "Cannot dup stdin: $!";
|
|
open (FOOOUT, ">&STDOUT") or die "Cannot dup stdout: $!";
|
|
|
|
do_it();
|
|
|
|
close (FOOIN);
|
|
close (FOOOUT);
|
|
}
|
|
|
|
|
|
sub do_it {
|
|
# The perlpath can be overwritten via -DPERL_BIN=<perlpath>
|
|
my $perl;
|
|
if($defines{'PERL_BIN'} && ($defines{PERL_BIN} ne 'this')) {
|
|
$perl = $defines{'PERL_BIN'};
|
|
unless(-x $perl) {
|
|
warn("No such PERL_BIN: $perl");
|
|
}
|
|
}
|
|
else {
|
|
# use eval so the module is not loaded unless needed; it's slow
|
|
eval 'use Config; $perl = $Config{"perlpath"};';
|
|
}
|
|
|
|
# Warnings are enabled per default
|
|
my $perl_warn = ' -w';
|
|
# The warnings can be overwritten via -DPERL_WARN=<yes|no>
|
|
if ($defines{'PERL_WARN'} and $defines{'PERL_WARN'} eq 'no') {
|
|
$perl_warn = '';
|
|
}
|
|
|
|
# Taint mode is enabled per default except on 5.005
|
|
my $perl_taint = ' -T';
|
|
# The taint mode can be disabled with -DPERL_TAINT=<yes|no>
|
|
if ($defines{'PERL_TAINT'} and $defines{'PERL_TAINT'} eq 'no') {
|
|
$perl_taint = '';
|
|
}
|
|
|
|
$defines{PERL_MAJOR_VER} = sub {
|
|
$] =~ /^(\d\.\d\d\d)/ or die "bad perl ver $]";
|
|
return $1;
|
|
};
|
|
|
|
$defines{PLUGIN_POD} = sub {
|
|
|
|
# Grab active plugin list
|
|
my @plugin_pod = ();
|
|
foreach my $pre (<rules/*.pre>) {
|
|
if (open(INIT, $pre)) {
|
|
while (<INIT>) {
|
|
if (/^loadplugin\s+(.*?)\s*$/) { push(@plugin_pod, " $1\n"); }
|
|
}
|
|
close(INIT);
|
|
}
|
|
}
|
|
return join('', sort @plugin_pod);
|
|
};
|
|
|
|
my $towrite = '';
|
|
while (<FOOIN>) {
|
|
$_ = pack("C0A*", $_); # turn off UTF8-ness
|
|
|
|
# Conditional compiling
|
|
if ($modules{'conditional'}) {
|
|
# DELETE lines carrying the REMOVE_ON_BUILD or (deprecated) REMOVEFORINST tag
|
|
if(/\bREMOVE(?:FORINST|_ON_BUILD)\b/) {
|
|
next;
|
|
}
|
|
}
|
|
|
|
$towrite .= $_;
|
|
}
|
|
|
|
# Sharpbang (#!) replacement (see also ExtUtils::MY->fixin)
|
|
if ($modules{'sharpbang'}) {
|
|
$towrite =~ s/^#![^\n]*perl[^\n]*\n/#!${perl}${perl_taint}${perl_warn}\n/;
|
|
}
|
|
|
|
# Variable replacement (do in one invocation)
|
|
if ($modules{'vars'}) {
|
|
# Replace all @@VARS@@
|
|
while ($towrite =~ /\@\@([A-Z][A-Z0-9_]*)\@\@/) {
|
|
my $what = $1;
|
|
my $d = $defines{$what} || '';
|
|
if (ref($d) =~ /^CODE/) { $d = $d->(); }
|
|
$towrite =~ s/\@\@${what}\@\@/$d/g;
|
|
}
|
|
}
|
|
|
|
print FOOOUT $towrite;
|
|
}
|