#!/usr/bin/perl
#
# Post-Installation script to complete the installation process.
#
# In case of e.g. Solaris pkg systems, this should be run as one of
# post-installation steps at those packages!
#
# - To move into place (conditionally) various prototype files
# - To fill in configuration information into MAILSHARE/db/
# files, if nothing in there to begin with...
#
# Long ago this was a SH script, hence its source file name...
#
# - MAILSHARE/forms/proto --> MAILSHARE/forms (conditionally)
# - MAILSHARE/proto/*.{conf,cf} --> MAILSHARE/ (conditionally)
# - MAILSHARE/cf/proto/*.cf --> MAILSHARE/cf/ (conditionally)
# - MAILVAR/db/proto/* --> MAILVAR/db/ (conditionally)
my $DESTDIR = '';
# ------------------------------------------
# Common file comparison sub-program
# Args: - base directory
#
sub compare_files {
local ($DIR) = @_;
local ($x);
if ($DRYRUN) {
printf "compare_files(%s)\n",$DIR;
return;
}
chdir "${DIR}/proto" || die ("Can't chdir('${DIR}/proto/')");
opendir DH, "." || die ("Opendir('.') failed!");
local(@files) = readdir(DH);
closedir(DH);
foreach $x (@files) {
next if ($x eq '.' || $x eq '..');
next if ($x =~ m/^.*\.md5$/o);
& compare_file($x);
}
}
sub compare_file {
local($x) = @_;
local($s1,$s2,$y);
local($wrote) = 0;
if ($DRYRUN) {
# printf "cmpfile: %s\n",$x;
return;
}
return if ( -d $x );
return if ($x =~ m/^\./); # Ignore fot-files.
if ( ! -f $x.'.md5' ) {
# No MD5 sum filed ??? Ok, lets calculate it..
if ( ! -f '../'.$x ) {
# A new file, easy to know that we can recalc the MD5SUM.
mysystem('cp', '-p', $x, '../'.$x);
$wrote = 1;
mysystem("$MD5SUM -b ../$x > ${x}.md5");
} else {
# # Don't overwrite!
# if (!mysystem("cmp -s $x ../$x")) {
# # MATCH of the files (sum either of them..)
# mysystem("$MD5SUM -b ../$x > ${x}.md5");
# } else {
# # Non-match of the files, sum the NEW file!
mysystem("$MD5SUM -b $x > ${x}.md5");
# }
}
}
if ( ! -f '../'.$x ) {
# Ok, we have MD5 sum, but don't have the file
# in its proper place!
mysystem('cp', '-p', $x, '../'.$x);
$wrote = 1;
}
if ( ! $wrote ) {
# We didn't write, so there exists an old file..
# Lets compare MD5 sums
# Destination file
local($md1,$md2,$l,$junk);
$l=`$MD5SUM -b "../${x}"`; # BACKTICK DANGER!
($md1,$junk) = split(' ',$l);
# And its associated MD5 signature file
$l=`cat "${x}.md5"`; # BACKTICK DANGER!
($md2,$junk) = split(' ',$l);
# printf(STDERR "File: $x MD1=$md1 MD2=$md2\n");
if ( $md1 eq $md2 ) {
# They do match! We overwrite old file with new
unlink('../'.$x);
mysystem('cp', '-p', $x, '../'.$x);
mysystem("$MD5SUM -b ../${x} > ${x}.md5");
$wrote = 1;
}
}
if ( ! $wrote ) {
$y = $x;
$y =~ s!/proto/!/!;
printf(STDERR "File $DIR/$y has mismatching MD5 sum.\n");
printf(STDERR " won't overwrite it with $DIR/$x.\n");
}
}
# ---------- POSTOFFICE DIRECTORY BUILDER ------------
sub dirprealloc {
local($DIR,$DSIZE,$DFILES) = @_;
local(@st);
$DSIZE *= 1000;
local($NAME) = "filenamefilenamefilenamefilenamefilenamefilenamefilenamefilenamefilename";
local($NUM) = 2;
open(OFP, "> $DIR/filename.0");
close(OFP);
# Just in case the names in directories are limited...
$NAME = "filenam" unless(link("$DIR/filename.0","$DIR/$NAME.1"));
@st = stat("${DIR}/."); # Can't fail ( -- eh ? )
local($SIZE) = $st[7];
while ($SIZE < $DSIZE && $NUM < $DFILES) {
# Link as long as you can -- or size is desired..
link("$DIR/filename.0","$DIR/$NAME.$NUM") || last;
@st = stat("${DIR}/."); # Can't fail ( -- eh ? )
$SIZE = $st[7];
++$NUM;
}
# Now clean up after allocations..
opendir DH, "$DIR/." || die ("Opendir('$DIR/.') failed!");
local(@files) = readdir(DH);
closedir(DH);
local($x);
foreach $x (@files) {
next if ($x eq '.' || $x eq '..');
unlink("$DIR/$x");
}
}
sub mkpostofficedir {
local($DIR,$MOD,$HASH,$DSIZE,$DFILES) = @_;
$MOD = 02000 + oct($MOD);
chdir($POSTOFFICE);
if ( ! -d "${DIR}/." ) {
printf(STDERR "Constructing dir: %s hash=%s\n",$DIR,$HASH);
return if ($DRYRUN);
mkdir $DIR, $MOD || die "mkdir ${DIR} failed!";
chmod $MOD, $DIR || die "chmod ${DIR} failed!";
& dirprealloc($DIR, $DSIZE, $DFILES);
local($xx,$yy);
if ($HASH eq 'HASH') {
printf(STDERR " HASH: ");
foreach $xx ('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') {
printf(STDERR " %s", $xx);
mkdir "$DIR/$xx", $MOD || die "mkdir ${DIR}/$xx failed!";
chmod $MOD, "$DIR/$xx" || die "chmod ${DIR}/$xx failed!";
& dirprealloc("$DIR/$xx", $DSIZE, $DFILES);
}
printf(STDERR "\n");
}
if ($HASH eq 'HASH2') {
printf(STDERR " HASH2: ");
foreach $xx ('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') {
printf(STDERR " %s", $xx);
mkdir "$DIR/$xx", $MOD || die "mkdir ${DIR}/$xx failed!";
chmod $MOD, "$DIR/$xx" || die "chmod ${DIR}/$xx failed!";
& dirprealloc("$DIR/$xx", $DSIZE, $DFILES);
}
printf(STDERR "\n");
foreach $xx ('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') {
printf(STDERR " HASH2/%s: ",$xx);
foreach $yy ('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') {
printf(STDERR " %s", $yy);
mkdir "$DIR/$xx/$yy", $MOD || die "mkdir ${DIR}/$xx/$yy failed!";
chmod $MOD, "$DIR/$xx/$yy" || die "chmod ${DIR}/$xx/$yy failed!";
& dirprealloc("$DIR/$xx/$yy", $DSIZE, $DFILES);
}
printf(STDERR "\n");
}
}
}
}
sub mysystem {
my (@cmd) = @_;
if ($DRYRUN) {
printf "cmd: %s\n",join(' ',@cmd);
return 0;
} else {
return system(@cmd);
}
}
# ----------------- pick_zenv() ----------------------
sub pick_zenv {
my($ZCONFIG) = @_;
open(ZZ, "< ".$ZCONFIG) || die "No ZCONFIG file at '$ZCONFIG'";
while (<ZZ>) {
chomp;
local($n,$l) = split(/=/,$_,2);
$ZENV{$n} = $l if ($n =~ m/^[A-Z0-9a-z]/);
}
close(ZZ);
}
# ------------------ MAIN PROGRAM --------------------
select STDOUT; $| = 1;
select STDERR; $| = 1;
%ZENV = ();
$ZCONFIG = '/opt/mail/zmailer.conf';
$STYLE = 'MD5';
$DRYRUN = 0;
while (defined $ARGV[0]) {
if ($ARGV[0] eq '-MD5') {
$STYLE = 'MD5';
shift @ARGV;
next;
}
if ($ARGV[0] eq '-OLDSTYLE') {
$STYLE = 'OLD';
shift @ARGV;
next;
}
if ($ARGV[0] eq '--zconfig') {
shift @ARGV;
$ZCONFIG = $ARGV[0];
shift @ARGV;
next;
}
if ($ARGV[0] eq '--dryrun' or $ARGV[0] eq '-n') {
shift @ARGV;
$DRYRUN = 1;
next;
}
if ($ARGV[0] eq '--destdir') {
shift @ARGV;
$DESTDIR = $ARGV[0];
shift @ARGV;
next;
}
printf(STDERR "unknown parameter: %s\n", $ARGV[0]);
printf(STDERR "post-install [-n|--dryrun] [--destdir /virtual/root] [--zconfig /opt/mail/zmailer.conf] [-MD5[|-OLDSTYLE]]\n");
exit(64);
}
$MKDIR = "mkdir -p";
#if ($STYLE eq '') {
# printf(STDERR "post-install [-MD5[|-OLDSTYLE]]\n");
# exit 1;
#}
if ($STYLE eq '') {
printf(STDERR "post-install [-n|--dryrun] [--destdir /virtual/root] [--zconfig /opt/mail/zmailer.conf] [-MD5[|-OLDSTYLE]]\n");
exit 1;
}
& pick_zenv( $DESTDIR.$ZCONFIG );
$POSTOFFICE = $DESTDIR.$ZENV{'POSTOFFICE'};
$MAILSHARE = $DESTDIR.$ZENV{'MAILSHARE'};
$MAILVAR = $DESTDIR.$ZENV{'MAILVAR'};
$MAILBIN = $DESTDIR.$ZENV{'MAILBIN'};
die "Failed to pick POSTOFFICE from ${DESTDIR}${ZCONFIG} !?"
if (!defined $POSTOFFICE || $POSTOFFICE eq '');
$MD5SUM = "/usr/bin/md5sum"; # Either system md5sum, or our own...
$MD5SUM = $DESTDIR.$MD5SUM if ($DESTDIR.$MD5SUM eq $MAILBIN.'/md5sum');
# trap 'echo "Directory access failure; DIR=$DIR/proto"' 0
# exit 99 # Sorry, not yet!
if ( ! -d "$MAILSHARE/bak" ) {
mysystem("$MKDIR $MAILSHARE/bak");
}
foreach $x ("$MAILSHARE", "$MAILSHARE/forms", "$MAILSHARE/cf", "$MAILVAR/db") {
& compare_files($x);
}
# ----------------------------
# Database prototypes ???
foreach $x (qw("$MAILSHARE/proto/router.cf $MAILSHARE/proto/scheduler.conf
$MAILSHARE/proto/smtpserver.conf $MAILSHARE/proto/sm.conf
$MAILSHARE/proto/smtp-tls.conf
$MAILVAR/db/proto/dbases.conf
$MAILVAR/db/proto/aliases $MAILVAR/db/proto/localnames
$MAILVAR/db/proto/fqdnaliases $MAILVAR/db/proto/fqdnroutes
$MAILVAR/db/proto/routes
$MAILVAR/db/proto/smtp-policy.src $MAILVAR/db/proto/smtp-policy.mx
$MAILVAR/db/proto/smtp-policy.relay")) {
$y = $x;
$y =~ s!/proto/!/!;
if ( -f $x ) {
printf(STDERR "**** Verify $y file!\n")
unless (system("cmp -s $x $y"));
}
}
if ($DESTDIR eq '') {
mysystem("$MAILBIN/zmailer newdb");
mysystem("$MAILBIN/policy-builder.sh -n");
}
printf(STDERR "
***
*** Will create directory hierarchies into %s
*** This is potentially VERY LENGTHY PROCESS
*** please be patient...
***
", $POSTOFFICE);
if (! -d "$POSTOFFICE/.") {
mymysystem("$MKDIR -p $POSTOFFICE");
}
mysystem("chmod 2755 $POSTOFFICE/.");
mysystem("chmod g+s $POSTOFFICE/.");
# subdir protchmod "no"/"HASH"/"HASH2" dirpreallocsize
& mkpostofficedir('deferred', '750', 'no', 6, 9999);
& mkpostofficedir('TLSsrvrcache', '700', 'HASH', 6, 9999);
& mkpostofficedir('TLSclntcache', '700', 'HASH', 6, 9999);
& mkpostofficedir('freezer', '750', 'no', 6, 9999);
& mkpostofficedir('postman', '750', 'no', 6, 9999);
& mkpostofficedir('public', '1777', 'no', 6, 9999);
& mkpostofficedir('queue', '750', 'HASH2', 6, 9999);
& mkpostofficedir('transport', '750', 'HASH2', 6, 9999);
& mkpostofficedir('router', '1777', 'HASH', 6, 9999);
printf(STDERR "
***
*** Remember to verify input databases, and then execute commands:
*** $MAILBIN/zmailer newdb
*** $MAILBIN/policy-builder.sh (-n)
***
");
#trap "" 0
exit 0;
1;
syntax highlighted by Code2HTML, v. 0.9.1