Commit e766df5a authored by sikeda's avatar sikeda
Browse files

[-dev] sympa.pl and upgrade_send_spool.pl would lock mesaages in msg and automatic spools.

ToDo: would lock messages in digest spool, too.


git-svn-id: https://subversion.renater.fr/sympa/branches/sympa-6.2-branch@11590 05aa8bb8-cd2b-0410-b1d7-8918dfa770ce
parent 7e7cb421
......@@ -34,6 +34,7 @@ use Pod::Usage;
use Sympa::Bulk;
use Sympa::Constants;
use Conf;
use Sympa::LockedFile;
use Log;
my %options;
......@@ -64,12 +65,14 @@ unless (($GID == (getgrnam(Sympa::Constants::GROUP))[2])
"Failed to change process user ID and group ID. Note that on some OS Perl scripts can't change their real UID. In such circumstances Sympa should be run via sudo.";
}
# Sets the UMASK
umask(oct($Conf::Conf{'umask'}));
my $bulk = Sympa::Bulk->new;
umask oct $Conf::Conf{'umask'};
my $bulk = Sympa::Bulk->new;
my $spool_dir = $Conf::Conf{'queue'};
mkdir "$spool_dir/bad", 0755 unless -d "$spool_dir/bad";
mkdir "$spool_dir/moved", 0755 unless -d "$spool_dir/moved";
my ($dh, $filename);
unless (open $dh, $spool_dir) {
printf STDERR "Cannot open directory %s.\n", $spool_dir;
......@@ -82,28 +85,32 @@ while ($filename = readdir $dh) {
next unless /\ABAD-/;
next unless /\A\.+/;
my $lock_fh =
Sympa::LockedFile->new($spool_dir . '/' . $filename, -1, '+<');
next unless $lock_fh;
my $metadata = tools::unmarshal_metadata(
$spool_dir, $filename,
qr{\A([^\s\@]+)(?:\@([\w\.\-]+))?\.(\d+)\.(\w+)(?:,.*)?\z},
[qw(localpart domainpart date pid)]
);
next unless $metadata;
unless ($metadata) {
$lock_fh->close;
next;
}
my $fh;
next unless open $fh, '<', "$spool_dir/$filename";
my $msg_string = do { local $RS; <$fh> };
close $fh;
my $msg_string = do { local $RS; <$lock_fh> };
my $message = Sympa::Message->new($msg_string, %$metadata);
next unless $message;
next unless $message->{checksum};
unless ($message and $message->{checksum}) {
$lock_fh->close;
next;
}
unless (process($message)) {
rename $spool_dir . '/' . $filename, $spool_dir . '/bad/' . $filename
$lock_fh->rename($spool_dir . '/bad/' . $filename)
unless $options{dry_run};
} else {
rename $spool_dir . '/' . $filename,
$spool_dir . '/moved/' . $filename
$lock_fh->rename($spool_dir . '/moved/' . $filename)
unless $options{dry_run};
}
}
......
......@@ -317,6 +317,9 @@ In both cases returns false value.
Closes filehandle and releases lock on it.
Note that destruction of instance will safely close filehandle and release
lock.
Parameters:
None.
......@@ -373,6 +376,7 @@ Returns:
If renaming succeeded, returns true value, otherwise false value
and does not release lock.
In both cases filehandle is closed anyway.
If filehandle had not been locked by current process,
this method will die doing nothing.
......
......@@ -43,6 +43,7 @@ use Sympa::Crash; # Show traceback.
use Sympa::Family;
use Sympa::Language;
use Sympa::List;
use Sympa::LockedFile;
use Log;
use Sympa::Mailer;
use Sympa::Message;
......@@ -202,7 +203,8 @@ if ($main::options{'help'}) {
foreach my $file (@files) {
unless (File::Copy::move("$old_dir/$file", "$dir/$file")) {
die "Could not move $old_dir/$file to $dir/$file : $!";
die sprintf 'Could not move %s/%s to %s/%s: %s', $old_dir, $file,
$dir, $file, $ERRNO;
}
}
......@@ -348,7 +350,7 @@ while ($signal ne 'term') { #as long as a signal is not received }
## Main program
if (!chdir($Conf::Conf{'home'})) {
die sprintf 'Can\'t chdir to %s: %s', $Conf::Conf{'home'}, $!;
die sprintf 'Can\'t chdir to %s: %s', $Conf::Conf{'home'}, $ERRNO;
## Function never returns.
}
......@@ -620,7 +622,8 @@ while ($signal ne 'term') { #as long as a signal is not received }
foreach my $sympa_aliases (values %sympa_aliases) {
my $fh;
unless (open $fh, '>', $sympa_aliases) { # truncate if exists
printf STDERR "Unable to create %s: %s\n", $sympa_aliases, $!;
printf STDERR "Unable to create %s: %s\n", $sympa_aliases,
$ERRNO;
exit 1;
}
close $fh;
......@@ -634,7 +637,8 @@ while ($signal ne 'term') { #as long as a signal is not received }
my $fh;
unless (open $fh, '>>', $sympa_aliases) { # append
printf STDERR "Unable to create %s: %s\n", $sympa_aliases, $!;
printf STDERR "Unable to create %s: %s\n", $sympa_aliases,
$ERRNO;
exit 1;
}
printf $fh "#\n#\tAliases for all Sympa lists open on %s\n#\n",
......@@ -1352,12 +1356,17 @@ while ($signal ne 'term') { #as long as a signal is not received }
# Process grouped notifications
Sympa::Alarm->instance->flush;
if (!opendir(DIR, $spool)) {
die sprintf 'Can\'t open dir %s: %s', $spool, $!;
my $dh;
unless (opendir $dh, $spool) {
die sprintf 'Can\'t open dir %s: %s', $spool, $ERRNO;
## No return.
}
@qfile = sort tools::by_date grep (!/^\./, readdir(DIR));
closedir(DIR);
@qfile = sort tools::by_date grep {
!/,lock/
and !/\A(?:\.|T\.|BAD-)/
and -f ($spool . '/' . $_)
} readdir $dh;
closedir $dh;
unless ($main::daemon_usage == Conf::DAEMON_COMMAND) {
# process digest only in distribution mode
......@@ -1431,24 +1440,6 @@ while ($signal ne 'term') { #as long as a signal is not received }
## Scans files in queue
## Search file with highest priority
foreach my $t_filename (@qfile) {
next unless -f "$t_spool/$t_filename";
next if $t_filename =~ /,lock/; # Skip lock.
## test ever if it is an old bad file
if ($t_filename =~ /^BAD\-/i) {
if (Sympa::Tools::File::get_mtime("$t_spool/$t_filename") <
time - $Conf::Conf{'clean_delay_queue'} * 86400) {
unlink("$t_spool/$t_filename");
Log::do_log('notice',
"Deleting bad message %s because too old",
$t_filename);
}
next;
}
## Don't process temporary files created by queue (T.xxx)
next if ($t_filename =~ /^T\./);
my $t_metadata;
if ($main::daemon_usage == Conf::DAEMON_CREATION) {
$t_metadata = tools::unmarshal_metadata(
......@@ -1479,9 +1470,12 @@ while ($signal ne 'term') { #as long as a signal is not received }
next;
}
my $message =
Sympa::Message->new_from_file($t_spool . '/' . $filename,
%$metadata);
my $lock_fh =
Sympa::LockedFile->new($t_spool . '/' . $filename, -1, '+<');
next unless $lock_fh;
my $msg_string = do { local $RS; <$lock_fh> };
my $message = Sympa::Message->new($msg_string, %$metadata);
# Compatibility: Message with checksum by Sympa <=6.2a.40
# They should be migrated.
......@@ -1507,7 +1501,7 @@ while ($signal ne 'term') { #as long as a signal is not received }
# Appel de la fonction de traitement des mails entrants
my $status = process_message($message);
if (defined($status)) {
if (defined $status) {
Log::do_log('debug', "Finished %s", "$t_spool/$filename");
if ($main::options{'keepcopy'}) {
......@@ -1519,32 +1513,32 @@ while ($signal ne 'term') { #as long as a signal is not received }
) {
Log::do_log(
'notice',
'Could not rename %s to %s: %s',
"$t_spool/$filename",
$main::options{'keepcopy'} . "/$filename",
$!
'Could not rename %s/%s to %s/%s: %m',
$t_spool,
$filename,
$main::options{'keepcopy'},
$filename
);
}
}
unlink("$t_spool/$filename");
$lock_fh->unlink;
} else {
my $bad_dir = "$t_spool/bad";
if (-d $bad_dir) {
unless (rename("$t_spool/$filename", "$bad_dir/$filename")) {
unless ($lock_fh->rename($bad_dir . '/' . $filename)) {
die sprintf
'Unable to rename bad file %s to %s/%s: %s',
$filename, $bad_dir, $filename, $!;
$filename, $bad_dir, $filename, $lock_fh->last_error;
}
Log::do_log('notice', "Moving bad file %s to bad/",
$filename);
} else {
Log::do_log('notice', 'Missing directory "%s"', $bad_dir);
unless (
rename("$t_spool/$filename", "$t_spool/BAD-$filename")) {
unless ($lock_fh->rename($t_spool . '/BAD-' . $filename)) {
die sprintf
'Unable to rename bad file %s to BAD-%s: %s',
$filename, $filename, $!;
$filename, $filename, $lock_fh->last_error;
}
Log::do_log('notice', "Renaming bad file %s to BAD-%s",
$filename, $filename);
......@@ -3503,7 +3497,7 @@ sub SendDigest {
if (!opendir(DIR, $Conf::Conf{'queuedigest'})) {
die sprintf 'Unable to access directory %s : %s',
$Conf::Conf{'queuedigest'}, $!;
$Conf::Conf{'queuedigest'}, $ERRNO;
## No return.
}
my @dfile = (sort grep (!/^\./, readdir(DIR)));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment