Mail-POP3
view release on metacpan or search on metacpan
lib/Mail/POP3/Folder/mbox.pm view on Meta::CPAN
if (!-s $self->_spoolfile) {
# no mail
return;
}
my $seen_message_end = 1; # the end of fake "message 0"...
my $messagecnt = 0;
my $messageoctets = 0;
my $messageuidl = '';
local *MDROP;
open MDROP, $self->_spoolfile;
while (<MDROP>) {
$self->_lock_update;
s/\r|\n//g;
if ($seen_message_end and /$self->{MESSAGE_START}/) {
# tick over
$self->_close_old_message(
$messagecnt,
$messageuidl,
$messageoctets,
);
$messagecnt++;
$messageuidl = '';
$messageoctets = 0;
$self->_start_new_message($messagecnt, $_);
} else {
$seen_message_end = 0;
if (/$self->{MESSAGE_END}/) {
$seen_message_end = 1;
}
if (/^Message-Id:\s*(.+)/ and not $messageuidl) {
# only take first Message-ID; cf such a header appearing in body
$messageuidl = $1;
}
$self->_push_message($messagecnt, $_);
$messageoctets += length ($_.$CRLF);
}
}
# catch the last one
$self->_close_old_message($messagecnt, $messageuidl, $messageoctets);
$self->{MESSAGECNT} = $messagecnt;
}
sub _spoolfile {
my $self = shift;
$self->{SPOOLFILE};
}
sub lock_acquire {
my $self = shift;
my $lockfile = $self->_lock_filename;
return if -f $lockfile;
$self->{LINE} = 0;
$self->{LOCK_FH} = IO::File->new(
">$lockfile"
) or die "open >$lockfile: $!\n";
unless (flock $self->{LOCK_FH}, LOCK_EX|LOCK_NB) {
unlink $lockfile;
return;
}
chmod 0600, $lockfile;
chown $self->{CLIENT_USER_ID}, $self->{MAILGROUP}, $lockfile;
my $oldfh = select $self->{LOCK_FH};
$| = 1;
select $oldfh;
$self->_lock_refresh;
# stat the file to get its size, this is checked before closing
# the mailbox.
# If the size has changed the lock may have been compromised, so a
# backup is then made.
my @filestat = stat $self->_spoolfile;
$self->{MAILBOX_TIMESTAMP_OPEN} = $filestat[9];
# set effective UID to user for the rest of the session;
$> = $self->{CLIENT_USER_ID};
$self->_list_messages;
die unless $self->{LOCK_FH};
1;
}
sub lock_release {
my $self = shift;
close $self->{LOCK_FH};
$> = 0;
unlink $self->_lock_filename;
$> = $self->{CLIENT_USER_ID};
}
sub _lock_filename {
my ($self) = @_;
"$self->{SPOOLFILE}.lock";
}
sub _lock_refresh {
# This is to update the m time on the <user>.lock mbox lock file.
# It may seem paranoid but I have seen lock files removed by impatient
# MDA's, so the file is written-to, unbuffered, as often as is
# practicable.
my $self = shift;
$> = 0;
die unless $self->{LOCK_FH};
seek $self->{LOCK_FH}, 0, SEEK_SET;
$self->{LOCK_FH}->print("\0");
$> = $self->{CLIENT_USER_ID};
}
sub _lock_update {
my $self = shift;
if (++$self->{LINE} == 1000) {
$self->_lock_refresh;
$self->{LINE} = 0;
}
}
sub _push_message_line {
my ($self, $messagecnt, $data) = @_;
push @{ $self->{MSG2TEXT}->{$messagecnt} }, "$data$CRLF";
}
sub _set_message_line {
my ($self, $messagecnt, $lineno, $data) = @_;
$self->{MSG2TEXT}->{$messagecnt}->[$lineno] = $data;
}
( run in 0.518 second using v1.01-cache-2.11-cpan-71847e10f99 )