File Coverage

blib/lib/Mail/POP3/Folder/mbox/parse_to_disk.pm
Criterion Covered Total %
statement 87 89 97.7
branch 15 22 68.1
condition n/a
subroutine 14 14 100.0
pod 5 5 100.0
total 121 130 93.0


line stmt bran cond sub pod time code
1             package Mail::POP3::Folder::mbox::parse_to_disk;
2              
3 4     4   25 use strict;
  4         6  
  4         103  
4 4     4   16 use IO::File;
  4         7  
  4         433  
5 4     4   21 use Fcntl ':flock';
  4         8  
  4         332  
6              
7 4     4   22 use vars qw(@ISA);
  4         8  
  4         3191  
8             @ISA = qw(Mail::POP3::Folder::mbox);
9              
10             my $CRLF = "\015\012";
11              
12             sub new {
13             my (
14 2     2 1 2401 $class,
15             $user_name,
16             $password,
17             $user_id,
18             $mailgroup,
19             $spoolfile,
20             $message_start,
21             $message_end,
22             $tmpdir,
23             $debug,
24             ) = @_;
25 2         37 my $self = $class->SUPER::new(
26             $user_name,
27             $password,
28             $user_id,
29             $mailgroup,
30             $spoolfile,
31             $message_start,
32             $message_end,
33             );
34 2         8 $self->{TMPDIR} = $tmpdir;
35 2         11 $self->{DEBUG} = $debug;
36 2         8 $self;
37             }
38              
39             sub _start_new_message {
40 6     6   15 my ($self, $newmessageno, $fromline) = @_;
41 6         87 $self->SUPER::_start_new_message($newmessageno, $fromline);
42 6         33 $> = 0;
43 6 50       66 unless (-d $self->{TMPDIR}) {
44 0 0       0 mkdir $self->{TMPDIR}, 0700
45             or die "Couldn't create spool dir '$self->{TMPDIR}': $!\n";
46             }
47 6         128 my $file = $self->_tmpdir_lockfile;
48 6         79 $self->{TMPDIRLOCK} = IO::File->new(">$file");
49 6 50       537 unless (flock $self->{TMPDIRLOCK}, LOCK_EX|LOCK_NB) {
50 0         0 die "Could not flock $file\n";
51             }
52 6         22 $file = $self->_msg2filename($newmessageno);
53 6 50       71 $self->{MESSAGE_FH} = IO::File->new(">$file")
54             or die "Couldn't create spool file: $!\n";
55 6         517 chmod 0600, $file;
56 6         59 $> = $self->{CLIENT_USER_ID};
57             }
58              
59             sub _close_old_message {
60 8     8   20 my ($self, $oldmessageno, $messageuidl, $messageoctets) = @_;
61 8 100       22 return if $oldmessageno <= 0;
62 6         34 $self->SUPER::_close_old_message(
63             $oldmessageno, $messageuidl, $messageoctets
64             );
65 6         21 $> = 0;
66 6 50       124 close $self->{MESSAGE_FH} if $self->{MESSAGE_FH};
67 6         34 $> = $self->{CLIENT_USER_ID};
68             }
69              
70             sub lock_release {
71 2     2 1 7 my $self = shift;
72 2         26 close $self->{TMPDIRLOCK};
73 2         12 unlink $self->_tmpdir_lockfile;
74 2         107 $self->SUPER::lock_release;
75             }
76              
77             # Build message arrays or write the next line to disk
78             sub _push_message {
79 68     68   117 my ($self, $messagecnt, $data) = @_;
80 68         226 $> = 0;
81 68         219 $self->{MESSAGE_FH}->print("$data\n");
82 68         539 $> = $self->{CLIENT_USER_ID};
83             }
84              
85             sub _tmpdir_lockfile {
86 8     8   23 my ($self, $message) = @_;
87 8         29 "$self->{TMPDIR}/.mpopd.lock";
88             }
89              
90             sub _msg2filename {
91 20     20   54 my ($self, $message) = @_;
92 20         124 "$self->{TMPDIR}/$message";
93             }
94              
95             # $message starts at 1
96             # returns number of bytes
97             sub top {
98 2     2 1 662 my ($self, $message, $output_fh, $body_lines) = @_;
99 2         4 my $top_bytes = 0;
100 2         12 $> = 0;
101 2         10 local *MSG;
102 2         8 open MSG, $self->_msg2filename($message);
103             # print the headers
104 2         106 while () {
105 20         43 chomp;
106 20         65 $self->_lock_update;
107 20         54 my $out = "$_$CRLF";
108 20         61 $output_fh->print($out);
109 20         171 $top_bytes += length($out);
110 20 100       146 last if /^\s*$/;
111             }
112 2         9 my $cnt = 0;
113             # print the TOP arg number of body lines
114 2         13 while () {
115 6         14 chomp;
116 6 100       17 last if ++$cnt > $body_lines;
117             # byte-stuff lines starting with .
118 4         12 s/^\./\.\./o;
119 4         15 $self->_lock_update;
120 4         11 my $out = "$_$CRLF";
121 4         26 $output_fh->print($out);
122 4         41 $top_bytes += length($out);
123             }
124 2         18 close MSG;
125 2         15 $> = $self->{CLIENT_USER_ID};
126 2         13 $top_bytes;
127             }
128              
129             sub flush_delete {
130 2     2 1 7 my ($self) = @_;
131 2         24 $self->SUPER::flush_delete;
132 2 50       19 if (not $self->{DEBUG}) {
133 2         18 foreach my $cnt (1..$self->{MESSAGECNT}) {
134 6         236 unlink $self->_msg2filename($cnt);
135             }
136             }
137             }
138              
139             sub retrieve {
140 6     6 1 1158 my ($self, $message, $output_fh, $mbox_destined) = @_;
141 6         45 $> = 0;
142 6         21 local *MSG;
143 6         19 open MSG, $self->_msg2filename($message);
144 6         233 while () {
145 76         591 chomp;
146 76 100       163 s/^\./\.\./o unless $mbox_destined;
147 76         218 $self->_lock_update;
148 76 100       233 my $line = $mbox_destined ? "$_\n" : "$_$CRLF";
149 76         176 $output_fh->print($line);
150             }
151 6         89 close MSG;
152 6         59 $> = $self->{CLIENT_USER_ID};
153             }
154              
155             1;
156              
157             __END__