summaryrefslogtreecommitdiff
path: root/gnu/usr.sbin/sendmail/contrib/movemail.pl
blob: 86bcb20118e584f650fbd1dcd99b9ac9d3992918 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/perl -w
#
# Move old mail messages between queues by calling re-mqueue.pl.
#
# movemail.pl [config-script]
#
# Default config script is /usr/local/etc/movemail.conf.
#
# Graeme Hewson <graeme.hewson@oracle.com>, June 2000
#

use strict;

# Load external program as subroutine to avoid
# compilation overhead on each call

sub loadsub {
    my $fn = shift
    	or die "Filename not specified";
    my $len = (stat($fn))[7]
    	or die "Can't stat $fn: $!";
    open PROG, "< $fn"
    	or die "Can't open $fn: $!";
    my $prog;
    read PROG, $prog, $len
    	or die "Can't read $fn: $!";
    close PROG;
    eval join "",
	'return sub { my @ARGV = @_; $0 = $fn; no strict;',
    	"$prog",
	'};';
}

my $progname = $0;
my $lastage = -1;
my $LOCK_EX = 2;
my $LOCK_NB = 4;

# Load and eval config script

my $conffile = shift || "/usr/local/etc/movemail.conf";
my $len = (stat($conffile))[7]
    or die "Can't stat $conffile: $!";
open CONF, "< $conffile"
    or die "Can't open $conffile: $!";
my $conf;
read CONF, $conf, $len
    or die "Can't read $conffile: $!";
close CONF;
use vars qw(@queues $subqbase @ages $remqueue $lockfile);
eval $conf;

if ($#queues < 1) {
    print "$progname: there must be at least two queues\n";
    exit 1;
}

if ($#ages != ($#queues - 1)) {
    print "$progname: wrong number of ages (should be one less than number of queues)\n";
    exit 1;
}

# Get lock or exit quietly.  Useful when running from cron.

if ($lockfile) {
    open LOCK, ">>$lockfile"
	or die "Can't open lock file: $!";
    unless (flock LOCK, $LOCK_EX|$LOCK_NB) {
	close LOCK;
	exit 0;
    }
}

my $remsub = loadsub($remqueue);

# Go through directories in reverse order so as to check spool files only once

for (my $n = $#queues - 1; $n >= 0; $n--) {
    unless ($ages[$n] =~ /^\d+$/) {
	print "$progname: invalid number $ages[$n] in ages array\n";
	exit 1;
    }
    unless ($lastage < 0 || $ages[$n] < $lastage) {
	print "$progname: age $lastage is not > previous value $ages[$n]\n";
	exit 1;
    }
    $lastage = $ages[$n];
    if ($subqbase) {
	my $subdir;
	opendir(DIR, $queues[$n])
	    or die "Can't open $queues[$n]: $!";
	foreach $subdir ( grep { /^$subqbase/ } readdir DIR) {
	    &$remsub("$queues[$n]/$subdir", "$queues[$n+1]/$subdir",
		$ages[$n]);
	}
	closedir(DIR);
    } else {
	# Not using subdirectories
	&$remsub($queues[$n], $queues[$n+1], $ages[$n]);
    }
}

if ($lockfile) {
    unlink $lockfile;
    close LOCK;
}