line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/local/bin/perl |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# Copyright (c) 1997-1999 Kevin Johnson . |
4
|
|
|
|
|
|
|
# |
5
|
|
|
|
|
|
|
# All rights reserved. This program is free software; you can |
6
|
|
|
|
|
|
|
# redistribute it and/or modify it under the same terms as Perl |
7
|
|
|
|
|
|
|
# itself. |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
# $Id: IMAP.pm,v 1.2 1999/10/03 14:56:21 kjj Exp $ |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
require 5.005; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
package Net::IMAP; |
14
|
|
|
|
|
|
|
|
15
|
1
|
|
|
1
|
|
5110
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
43
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 NAME |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
Net::IMAP - A client interface to IMAP (Internet Message Access Protocol). |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
B
|
22
|
|
|
|
|
|
|
change release to release.> |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=cut |
25
|
|
|
|
|
|
|
|
26
|
1
|
|
|
1
|
|
578
|
use Net::xAP; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
41
|
|
27
|
1
|
|
|
1
|
|
16
|
use Carp; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
73
|
|
28
|
1
|
|
|
1
|
|
897
|
use MIME::Base64; |
|
1
|
|
|
|
|
847
|
|
|
1
|
|
|
|
|
65
|
|
29
|
1
|
|
|
1
|
|
1559
|
use Digest::HMAC_MD5 qw(hmac_md5 hmac_md5_hex); |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
use vars qw($VERSION @ISA $AUTOLOAD); |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
$VERSION = "0.02"; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
@ISA = qw(Net::xAP); |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
use constant ATOM => Net::xAP::ATOM; |
38
|
|
|
|
|
|
|
use constant ASTRING => Net::xAP::ASTRING; |
39
|
|
|
|
|
|
|
use constant PARENS => Net::xAP::PARENS; |
40
|
|
|
|
|
|
|
use constant SASLRESP => Net::xAP::SASLRESP; |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=head1 SYNOPSIS |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
C |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
=head1 DESCRIPTION |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
C provides a perl interface to the client portion of IMAP |
49
|
|
|
|
|
|
|
(Internet Message Access Protocol). |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
B
|
52
|
|
|
|
|
|
|
callbacks, convenience routines> |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=head1 METHODS |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=cut |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
use constant IMAP_STATE_NOT_AUTH => 1; |
59
|
|
|
|
|
|
|
use constant IMAP_STATE_AUTH => 2; |
60
|
|
|
|
|
|
|
use constant IMAP_STATE_SELECT => 4; |
61
|
|
|
|
|
|
|
use constant IMAP_STATE_ANY => 7; |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
my %untagged_callbacks = ( |
64
|
|
|
|
|
|
|
'ok' => [\&_default_aux_callback], |
65
|
|
|
|
|
|
|
'bye' => [\&_default_aux_callback], |
66
|
|
|
|
|
|
|
'bad' => [\&_default_aux_callback], |
67
|
|
|
|
|
|
|
'no' => [\&_default_aux_callback], |
68
|
|
|
|
|
|
|
'capability' => [undef], |
69
|
|
|
|
|
|
|
'list' => [undef], |
70
|
|
|
|
|
|
|
'lsub' => [undef], |
71
|
|
|
|
|
|
|
'status' => [undef], |
72
|
|
|
|
|
|
|
'search' => [undef], |
73
|
|
|
|
|
|
|
'flags' => [undef], |
74
|
|
|
|
|
|
|
'exists' => [undef], |
75
|
|
|
|
|
|
|
'recent' => [undef], |
76
|
|
|
|
|
|
|
'expunge' => [undef], |
77
|
|
|
|
|
|
|
'fetch' => [undef], |
78
|
|
|
|
|
|
|
'namespace' => [undef], |
79
|
|
|
|
|
|
|
'acl' => [undef], |
80
|
|
|
|
|
|
|
'listrights' => [undef], |
81
|
|
|
|
|
|
|
'myrights' => [undef], |
82
|
|
|
|
|
|
|
'quota' => [undef], |
83
|
|
|
|
|
|
|
'quotaroot' => [undef], |
84
|
|
|
|
|
|
|
); |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
my %cmd_callbacks = ( |
87
|
|
|
|
|
|
|
'noop' => [undef, IMAP_STATE_ANY], |
88
|
|
|
|
|
|
|
'capability' => [undef, IMAP_STATE_ANY], |
89
|
|
|
|
|
|
|
'logout' => [undef, IMAP_STATE_ANY], |
90
|
|
|
|
|
|
|
'authenticate' => ['_login_cmd_callback', |
91
|
|
|
|
|
|
|
IMAP_STATE_NOT_AUTH], |
92
|
|
|
|
|
|
|
'login' => ['_login_cmd_callback', IMAP_STATE_NOT_AUTH], |
93
|
|
|
|
|
|
|
'select' => ['_select_cmd_callback', |
94
|
|
|
|
|
|
|
IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
95
|
|
|
|
|
|
|
'examine' => ['_select_cmd_callback', |
96
|
|
|
|
|
|
|
IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
97
|
|
|
|
|
|
|
'create' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
98
|
|
|
|
|
|
|
'delete' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
99
|
|
|
|
|
|
|
'rename' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
100
|
|
|
|
|
|
|
'subscribe' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
101
|
|
|
|
|
|
|
'list' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
102
|
|
|
|
|
|
|
'lsub' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
103
|
|
|
|
|
|
|
'status' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
104
|
|
|
|
|
|
|
'append' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
105
|
|
|
|
|
|
|
'check' => [undef, IMAP_STATE_SELECT], |
106
|
|
|
|
|
|
|
'close' => ['_close_cmd_callback', IMAP_STATE_SELECT], |
107
|
|
|
|
|
|
|
'expunge' => [undef, IMAP_STATE_SELECT], |
108
|
|
|
|
|
|
|
'search' => [undef, IMAP_STATE_SELECT], |
109
|
|
|
|
|
|
|
'fetch' => [undef, IMAP_STATE_SELECT], |
110
|
|
|
|
|
|
|
'store' => [undef, IMAP_STATE_SELECT], |
111
|
|
|
|
|
|
|
'copy' => [undef, IMAP_STATE_SELECT], |
112
|
|
|
|
|
|
|
'uid copy' => [undef, IMAP_STATE_SELECT], |
113
|
|
|
|
|
|
|
'uid fetch' => [undef, IMAP_STATE_SELECT], |
114
|
|
|
|
|
|
|
'uid search' => [undef, IMAP_STATE_SELECT], |
115
|
|
|
|
|
|
|
'uid store' => [undef, IMAP_STATE_SELECT], |
116
|
|
|
|
|
|
|
# Extension commands: |
117
|
|
|
|
|
|
|
'namespace' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
118
|
|
|
|
|
|
|
'setacl' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
119
|
|
|
|
|
|
|
'getacl' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
120
|
|
|
|
|
|
|
'deleteacl' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
121
|
|
|
|
|
|
|
'listrights' => [undef, |
122
|
|
|
|
|
|
|
IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
123
|
|
|
|
|
|
|
'myrights' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
124
|
|
|
|
|
|
|
'getquota' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
125
|
|
|
|
|
|
|
'setquota' => [undef, IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
126
|
|
|
|
|
|
|
'getquotaroot' => [undef, |
127
|
|
|
|
|
|
|
IMAP_STATE_AUTH|IMAP_STATE_SELECT], |
128
|
|
|
|
|
|
|
'uid expunge' => [undef, IMAP_STATE_SELECT], |
129
|
|
|
|
|
|
|
); |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
my %_system_flags = ( |
132
|
|
|
|
|
|
|
'\seen' => 1, |
133
|
|
|
|
|
|
|
'\answered' => 1, |
134
|
|
|
|
|
|
|
'\flagged' => 1, |
135
|
|
|
|
|
|
|
'\deleted' => 1, |
136
|
|
|
|
|
|
|
'\draft' => 1, |
137
|
|
|
|
|
|
|
'\recent' => 1, |
138
|
|
|
|
|
|
|
); |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=head2 new $host, %options |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
Creates a new C object, connects to C<$host> on port 143, |
143
|
|
|
|
|
|
|
performs some preliminary setup of the session, and returns a |
144
|
|
|
|
|
|
|
reference to the object. |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
Once connected, it processes the connection banner sent by the server. |
147
|
|
|
|
|
|
|
If the considers the session to be preauthenticated, C notes the |
148
|
|
|
|
|
|
|
fact, allowing commands to be issued without logging in. |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
The method also issues a C command, and notes the result. |
151
|
|
|
|
|
|
|
If the server does support IMAP4rev1, the method closes the connection |
152
|
|
|
|
|
|
|
and returns C. |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
The client will use non-synchronizing literals if the server supports |
155
|
|
|
|
|
|
|
the C extension (RFC2088) and the C options is |
156
|
|
|
|
|
|
|
set to C<1>. |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
The following C options are relevant to C: |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=over 4 |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=item C 1> |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=item C 0> |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=item C 0> |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=item C 0> |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=back |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
C also understands the following options, specific to the module: |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=over 4 |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=item C 'lf'> |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
Controls what style of end-of-line processing to presented to the |
179
|
|
|
|
|
|
|
end-programmer. The default, C<'lf'>, assumes that the programemr |
180
|
|
|
|
|
|
|
wants to fling messages terminated with bare LFs when invoking append, |
181
|
|
|
|
|
|
|
and when fetching messages. In this case, the module will map to/from |
182
|
|
|
|
|
|
|
CRLF accordingly. |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
If C is set to C<'crlf'>, the assumption is that the programmer |
185
|
|
|
|
|
|
|
wants messages, or portions of messages, to be terminated with CRLF. |
186
|
|
|
|
|
|
|
It also assumes the programmer is providing messages terminated with |
187
|
|
|
|
|
|
|
the string when invoking the C method, and will not provide an |
188
|
|
|
|
|
|
|
EOL mapping. |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=back |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=cut |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub new { |
195
|
|
|
|
|
|
|
my $class = shift; |
196
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
197
|
|
|
|
|
|
|
my $host = shift if @_ % 2; |
198
|
|
|
|
|
|
|
my %options = @_; |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
my $self = Net::xAP->new($host, 'imap2(143)', Timeout => 10, %options) |
201
|
|
|
|
|
|
|
or return undef; |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
bless $self, $class; |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
$self->{Options}{EOL} ||= 'lf'; |
206
|
|
|
|
|
|
|
$self->{Options}{EOL} = lc($self->{Options}{EOL}); # force lower-case |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
$self->{PreAuth} = 0; |
209
|
|
|
|
|
|
|
$self->{Banner} = undef; |
210
|
|
|
|
|
|
|
$self->{Capabilities} = (); |
211
|
|
|
|
|
|
|
$self->_init_mailbox; |
212
|
|
|
|
|
|
|
$self->{Disconnect} = 0; |
213
|
|
|
|
|
|
|
$self->{State} = IMAP_STATE_NOT_AUTH; |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
$self->{ResponseCallback} = $self->imap_response_callback; |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
STDERR->autoflush(1); |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
$self->_get_banner or return undef; |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
# the little back-flip here with the Synchronous option ensures that |
222
|
|
|
|
|
|
|
# the capability command is issued in Synchronous mode |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
my $mode = $self->{Options}{Synchronous}; # save current sync mode |
225
|
|
|
|
|
|
|
$self->{Options}{Synchronous}++; # force sync mode on |
226
|
|
|
|
|
|
|
my $resp = $self->capability; |
227
|
|
|
|
|
|
|
$self->{Options}{Synchronous} = $mode; # restore previous sync mode |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
if ($resp->status ne 'ok') { |
230
|
|
|
|
|
|
|
carp "capability command failed on initial connection"; |
231
|
|
|
|
|
|
|
$self->close_connection or carp "error closing connection: $!"; |
232
|
|
|
|
|
|
|
$! = 5; # *sigh* error reporting needs to be improved |
233
|
|
|
|
|
|
|
return undef; |
234
|
|
|
|
|
|
|
} |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
return $self; |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub _init_mailbox { |
240
|
|
|
|
|
|
|
my $self = shift; |
241
|
|
|
|
|
|
|
$self->{Mailbox} = ''; |
242
|
|
|
|
|
|
|
$self->{MailboxStatus} = (); |
243
|
|
|
|
|
|
|
$self->{MailboxStatus}{'recent'} = 0; |
244
|
|
|
|
|
|
|
$self->{MailboxStatus}{'unseen'} = 0; |
245
|
|
|
|
|
|
|
$self->{MailboxStatus}{'exists'} = 0; |
246
|
|
|
|
|
|
|
$self->{MailboxStatus}{'uidvalidity'} = 0; |
247
|
|
|
|
|
|
|
$self->{MailboxStatus}{'uidnext'} = 0; |
248
|
|
|
|
|
|
|
$self->{MailboxStatus}{'flags'} = (); |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub debug_text { $_[2] =~ /^(\d+ LOGIN [^\s]+)/i ? "$1 ..." : $_[2] } |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
sub _get_banner { |
254
|
|
|
|
|
|
|
my $self = shift; |
255
|
|
|
|
|
|
|
my $str = $self->getline; |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
my $list = $self->parse_fields($str); |
258
|
|
|
|
|
|
|
return undef unless defined($list); |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
if (($list->[0] eq '*') && ($list->[1] =~ /^preauth$/i)) { |
261
|
|
|
|
|
|
|
$self->{PreAuth}++; |
262
|
|
|
|
|
|
|
$self->{State} = IMAP_STATE_AUTH; |
263
|
|
|
|
|
|
|
} elsif (($list->[0] ne '*') || ($list->[1] !~ /^ok$/i)) { |
264
|
|
|
|
|
|
|
return undef; |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
my $supports_imap4rev1 = 0; |
267
|
|
|
|
|
|
|
for my $item (@{$list}) { |
268
|
|
|
|
|
|
|
$supports_imap4rev1++ if ($item =~ /^imap4rev1$/i); |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
unless ($supports_imap4rev1) { |
271
|
|
|
|
|
|
|
$self->close_connection; |
272
|
|
|
|
|
|
|
return undef; |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
$self->{Banner} = $list; |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
return 1; |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
sub DESTROY { |
281
|
|
|
|
|
|
|
my $self = shift; |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
sub AUTOLOAD { |
285
|
|
|
|
|
|
|
my $self = shift; |
286
|
|
|
|
|
|
|
my $cmd = $AUTOLOAD; |
287
|
|
|
|
|
|
|
$cmd =~ s/^.*:://; |
288
|
|
|
|
|
|
|
carp("unknown command: $cmd"); |
289
|
|
|
|
|
|
|
return undef; |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
############################################################################### |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=head1 IMAP COMMAND METHODS |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
There are numerous commands in the IMAP protocol. Each of these are |
297
|
|
|
|
|
|
|
mapped to a corresponding method in the C module. |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
Some commands can only be issued in certain protocol states. Some |
300
|
|
|
|
|
|
|
commands alter the state of the session. These facts are indicated in |
301
|
|
|
|
|
|
|
the documentation for the individual command methods. |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
The following list enumerates the protocol states: |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=over 4 |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=item Non-authenticated |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
The client has not authenticated with the server. Most commands are |
310
|
|
|
|
|
|
|
unavailable in this state. |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=item Authenticated |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
The client has authenticated with the server. |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
=item Selected |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
The client has opened a mailbox on the server. |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=back |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=head2 noop |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
Sends a C command to the server. It is valid in any protocol state. |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
This method is useful for placating the auto-logout god, or for |
327
|
|
|
|
|
|
|
triggering pending unsolicited responses from the server. |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=cut |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
sub noop { $_[0]->imap_command('noop') } |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=head2 capability |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
The C method retrieves the capabilities the IMAP server |
336
|
|
|
|
|
|
|
supports. This method is valid in any protocol state. |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
The server sends a C response back to the client. |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
If the response does not indicate support for the C |
341
|
|
|
|
|
|
|
extension, the C option is forced off. |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
=cut |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
sub capability { $_[0]->imap_command('capability') } |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=head2 logout |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
Logs off of the server. This method is valid in any protocol state. |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
=cut |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
sub logout { |
354
|
|
|
|
|
|
|
$_[0]->{Disconnect}++; |
355
|
|
|
|
|
|
|
$_[0]->imap_command('logout'); |
356
|
|
|
|
|
|
|
} |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
=head2 login $user, $password |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
Logs into the server using a simple plaintext password. This method |
361
|
|
|
|
|
|
|
is only valid when the protocol is in the non-authenticated state. |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
If the server supports RFC2221 (IMAP4 Login Referrals), the completion |
364
|
|
|
|
|
|
|
response could include a referral. See RFC2221 for further |
365
|
|
|
|
|
|
|
information about login referrals. |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
If successful, the session state is changed to I. |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=cut |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
sub login { $_[0]->imap_command('login', ASTRING, $_[1], ASTRING, $_[2]) } |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=head2 authenticate $authtype, @authinfo |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
Logs into the server using the authentication mechanism specified in |
376
|
|
|
|
|
|
|
C<$authtype>. This method is only valid when the protocol is in the |
377
|
|
|
|
|
|
|
non-authenticated state. |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
The IMAP C command is the same as that documented in |
380
|
|
|
|
|
|
|
RFC2222 (Simple Authentication and Security Layer (SASL)), despite the |
381
|
|
|
|
|
|
|
fact that IMAP predates SASL. |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
If successful, the session state is changed to I. |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
The following authentication mechanisms are currently supported: |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=over 4 |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=item C<'login'> |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
This is a variation on the simple login technique, except that the |
392
|
|
|
|
|
|
|
information is transmitted in Base64. This does not provide any |
393
|
|
|
|
|
|
|
additional security, but does allow clients to use C. |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
=item C<'cram-md5'> |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
This implements the authentication mechanism defined in RFC2195 |
398
|
|
|
|
|
|
|
(IMAP/POP AUTHorize Extension for Simple Challenge/Response). It uses |
399
|
|
|
|
|
|
|
keyed MD5 to avoid sending the password over the wire. |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=item C<'anonymous'> |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
This implements the authentication mechanism defined in RFC2245 |
404
|
|
|
|
|
|
|
(Anonymous SASL Mechanism). Anonymous IMAP access is intended to |
405
|
|
|
|
|
|
|
provide access to public mailboxes or newsgroups. |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
=back |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
The method returns C is C<$authtype> specifies an unsupported |
410
|
|
|
|
|
|
|
mechanism or if the server does not advertise support for the |
411
|
|
|
|
|
|
|
mechanism. The C method can be used to see whether the |
412
|
|
|
|
|
|
|
server supports a particular authentication mechanism. |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
In general, if the server supports a mechanism supported by |
415
|
|
|
|
|
|
|
C, the C command should be used instead of |
416
|
|
|
|
|
|
|
the C method. |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
=cut |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
my %auth_funcs = ( |
421
|
|
|
|
|
|
|
'LOGIN' => \&authenticate_login, |
422
|
|
|
|
|
|
|
'CRAM-MD5' => \&authenticate_cram, |
423
|
|
|
|
|
|
|
'ANONYMOUS' => \&authenticate_anonymous, |
424
|
|
|
|
|
|
|
); |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
my @auth_strings; |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
sub authenticate { |
429
|
|
|
|
|
|
|
my $authtype = uc($_[1]); |
430
|
|
|
|
|
|
|
return undef unless defined($auth_funcs{$authtype}); |
431
|
|
|
|
|
|
|
return undef unless defined($_[0]->has_authtype($authtype)); |
432
|
|
|
|
|
|
|
my $func = $auth_funcs{$authtype}; |
433
|
|
|
|
|
|
|
@auth_strings = @_[2..$#_]; |
434
|
|
|
|
|
|
|
$_[0]->imap_command('authenticate', |
435
|
|
|
|
|
|
|
ATOM, $authtype, |
436
|
|
|
|
|
|
|
SASLRESP, $func); |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
sub authenticate_login { |
440
|
|
|
|
|
|
|
my $i = shift; |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
return undef unless defined($auth_strings[$i]); |
443
|
|
|
|
|
|
|
return encode_base64($auth_strings[$i], ''); |
444
|
|
|
|
|
|
|
} |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
sub authenticate_cram { |
447
|
|
|
|
|
|
|
my $i = shift; |
448
|
|
|
|
|
|
|
my $challenge = shift; |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
if ($i == 0) { |
451
|
|
|
|
|
|
|
$challenge = decode_base64($challenge); |
452
|
|
|
|
|
|
|
$challenge = hmac_md5_hex($challenge, $auth_strings[1]); |
453
|
|
|
|
|
|
|
$auth_strings[1] = undef; |
454
|
|
|
|
|
|
|
return(encode_base64("$auth_strings[0] $challenge", '')); |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
return undef; |
457
|
|
|
|
|
|
|
} |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
sub authenticate_anonymous { |
460
|
|
|
|
|
|
|
my $i = shift; |
461
|
|
|
|
|
|
|
return(encode_base64(join(' ', @auth_strings), '')) if ($i == 0); |
462
|
|
|
|
|
|
|
return undef; |
463
|
|
|
|
|
|
|
} |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
=head2 select $mailbox |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
Opens the specified mailbox with the intention of performing reading |
468
|
|
|
|
|
|
|
and writing. This method is valid only when the session is in the |
469
|
|
|
|
|
|
|
authenticated or selected states. |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
If successful, the server sends several responses: C, |
472
|
|
|
|
|
|
|
C, C, as well as C responses containing a |
473
|
|
|
|
|
|
|
C, C, C, and C codes. |
474
|
|
|
|
|
|
|
If also changes the session state to I. |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
If server returns a C response containing a C response |
477
|
|
|
|
|
|
|
code, this means C<$mailbox> does not exist but the server thinks this |
478
|
|
|
|
|
|
|
is because the folder was renamed. In this case, try specifiying the |
479
|
|
|
|
|
|
|
new folder name provided with the C response code. |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
=cut |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
sub select { |
484
|
|
|
|
|
|
|
$_[0]->{Mailbox} = $_[1]; |
485
|
|
|
|
|
|
|
my $ret = $_[0]->imap_command('select', ASTRING, _encode_mailbox($_[1])); |
486
|
|
|
|
|
|
|
$_[0]->{Mailbox} = '' unless defined($ret); |
487
|
|
|
|
|
|
|
return $ret; |
488
|
|
|
|
|
|
|
} |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
=head2 examine $mailbox |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
Opens the specified mailbox in read-only mode. This method is valid |
493
|
|
|
|
|
|
|
only when the session is in the authenticated or selected states. |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
=cut |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
sub examine { $_[0]->imap_command('examine', ASTRING, _encode_mailbox($_[1])) } |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=head2 create $mailbox [, $partition] |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
Creates the specified mailbox. This method is valid only when the |
502
|
|
|
|
|
|
|
session is in the authenticated or selected states. |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
The optional C<$partition> argument is only valid with the Cyrus IMAP |
505
|
|
|
|
|
|
|
daemon. Refer to the section 'Specifying Partitions with "create"' |
506
|
|
|
|
|
|
|
the C file for that package for further information. |
507
|
|
|
|
|
|
|
This feature can only be used by administrators creating new |
508
|
|
|
|
|
|
|
mailboxes. Other servers will probably reject the command if this |
509
|
|
|
|
|
|
|
argument is used. The results are undefined if another server accepts |
510
|
|
|
|
|
|
|
a second argument. |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
=cut |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
sub create { |
515
|
|
|
|
|
|
|
my @args = (ASTRING, _encode_mailbox($_[1])); |
516
|
|
|
|
|
|
|
push @args, ATOM, $_[2] if (defined($_[2])); |
517
|
|
|
|
|
|
|
$_[0]->imap_command('create', @args); |
518
|
|
|
|
|
|
|
} |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
=head2 delete $mailbox |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
Deletes the specified mailbox. Returns C if C<$mailbox> is the |
523
|
|
|
|
|
|
|
currently open mailbox. This method is valid only when the session is |
524
|
|
|
|
|
|
|
in the authenticated or selected states. |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=cut |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
sub delete { |
529
|
|
|
|
|
|
|
return undef if ($_[0]->{Mailbox} eq $_[1]); |
530
|
|
|
|
|
|
|
$_[0]->imap_command('delete', ASTRING, _encode_mailbox($_[1])); |
531
|
|
|
|
|
|
|
} |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
=head2 rename $oldmailboxname, $newmailboxname [, $partition] |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
Renames the mailbox specified in C<$oldmailbox> to the name specified |
536
|
|
|
|
|
|
|
in C<$newmailbox>. This method is valid only when the session is in |
537
|
|
|
|
|
|
|
the authenticated or selected states. |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
The optional C<$partition> argument is only valid with the Cyrus IMAP |
540
|
|
|
|
|
|
|
daemon. Refer to the section 'Specifying Partitions with "rename"' |
541
|
|
|
|
|
|
|
the C file for that package for further information. |
542
|
|
|
|
|
|
|
This feature can only be used by administrators. Other servers will |
543
|
|
|
|
|
|
|
probably reject the command if this argument is used. The results are |
544
|
|
|
|
|
|
|
undefined if another server accepts a third argument. |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=cut |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
sub rename { |
549
|
|
|
|
|
|
|
my @args = (ASTRING, _encode_mailbox($_[1]), ASTRING, _encode_mailbox($_[2])); |
550
|
|
|
|
|
|
|
push @args, ATOM, $_[3] if defined($_[3]); |
551
|
|
|
|
|
|
|
$_[0]->imap_command('rename', @args); |
552
|
|
|
|
|
|
|
} |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
=head2 subscribe $mailbox |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
Subscribe to the specified C<$mailbox>. Subscribing in IMAP is |
557
|
|
|
|
|
|
|
subscribing in Usenet News, except that the server maintains the |
558
|
|
|
|
|
|
|
subscription list. This method is valid only when the session is in |
559
|
|
|
|
|
|
|
the authenticated or selected states. |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
=cut |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
sub subscribe { $_[0]->imap_command('subscribe', |
564
|
|
|
|
|
|
|
ASTRING, _encode_mailbox($_[1])) } |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
=head2 unsubscribe $mailbox |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
Unsubscribe from the specified C<$mailbox>. This method is valid only |
569
|
|
|
|
|
|
|
when the session is in the authenticated or selected states. |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
=cut |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
sub unsubscribe { $_[0]->imap_command('unsubscribe', |
574
|
|
|
|
|
|
|
ASTRING, _encode_mailbox($_[1])) } |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
=head2 list $referencename, $mailbox_pattern |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
Send an IMAP C command to the server. This method is valid only |
579
|
|
|
|
|
|
|
when the session is in the authenticated or selected states. |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
Although IMAP folders do not need to be implemented as directories, |
582
|
|
|
|
|
|
|
think of an IMAP reference name as a parameter given to a C or |
583
|
|
|
|
|
|
|
C command, prior to checking for folders matching |
584
|
|
|
|
|
|
|
C<$mailbox_pattern>. |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
The C<$mailbox_pattern> parameter allows a couple wildcard characters |
587
|
|
|
|
|
|
|
to list subsets of the mailboxes on the server. |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
=over 4 |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
=item * |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
Matches zero or more characters at the specified location. |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
=item % |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
Like C<*>, matches zero or more characters at the specified location, |
598
|
|
|
|
|
|
|
but does not match hierarchy delimiter characters. |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
If the last character in C<$mailbox_pattern> is a C<%>, matching |
601
|
|
|
|
|
|
|
levels of hierarchy are also returned. In other words: subfolders. |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=back |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
This method will fail, returning C, if C<$mailbox_pattern> is |
606
|
|
|
|
|
|
|
C<*>. This behavior is not built into the IMAP protocol; it is wired |
607
|
|
|
|
|
|
|
into C. Doing otherwise could be rude to both the client |
608
|
|
|
|
|
|
|
and server machines. If you want to know why, imagine doing |
609
|
|
|
|
|
|
|
C on a machine with a full news feed. The C<%> |
610
|
|
|
|
|
|
|
character should be used to build up a folder tree incrementally. |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
If successful, the server sends a series of C responses. |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
Please note that the C<$referencename> is an IMAPism, not a Perl |
615
|
|
|
|
|
|
|
reference. Also note that the wildcards usable in C<$mailbox_pattern> |
616
|
|
|
|
|
|
|
are specific to IMAP. Perl regexps are not usable here. |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
=cut |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
sub list { |
621
|
|
|
|
|
|
|
return undef if ($_[2] eq '*'); |
622
|
|
|
|
|
|
|
$_[0]->imap_command('list', |
623
|
|
|
|
|
|
|
ASTRING, _encode_mailbox($_[1]), |
624
|
|
|
|
|
|
|
ASTRING, _encode_mailbox($_[2])); |
625
|
|
|
|
|
|
|
} |
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
=head2 lsub $referencename, $mailbox_pattern |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
Sends an IMAP C command to the server. The C command is |
630
|
|
|
|
|
|
|
similar to the C command, except that the server only returns |
631
|
|
|
|
|
|
|
subscribed mailboxes. This method is valid only when the session is |
632
|
|
|
|
|
|
|
in the authenticated or selected states. |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
The parameters are the same as those for the C method. |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
If successful, the server sends a series of C responses. |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
=cut |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
sub lsub { $_[0]->imap_command('lsub', |
641
|
|
|
|
|
|
|
ASTRING, _encode_mailbox($_[1]), |
642
|
|
|
|
|
|
|
ASTRING, _encode_mailbox($_[2])) } |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
=head2 status $mailbox, @statusattrs |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
Retrieves status information for the specified C<$mailbox>. This |
647
|
|
|
|
|
|
|
method is valid only when the session is in the authenticated or |
648
|
|
|
|
|
|
|
selected states. |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
Per RFC2060, the C<@statusattrs> can contain any of the following |
651
|
|
|
|
|
|
|
strings: |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
=over 4 |
654
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
=item * messages |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
The number of messages in the mailbox. |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
=item * recent |
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
The number of messages with the C<\recent> flag set. |
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
=item * uidnext |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
The UID expected to be assigned to the next mailbox appended to the |
666
|
|
|
|
|
|
|
mailbox. This requires some explanation. Rather than using this |
667
|
|
|
|
|
|
|
value for prefetching the next UID, it should be used to detect |
668
|
|
|
|
|
|
|
whether messages have been added to the mailbox. The value will not |
669
|
|
|
|
|
|
|
change until messages are appended to the mailbox. |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
=item * uidvalidity |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
The unique identifier validity value of the mailbox. |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
=item * unseen |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
The number of messages without the C<\seen> flag set. |
678
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
=back |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
This method will fail, returning C if C<$mailbox> is the |
682
|
|
|
|
|
|
|
currently open mailbox. |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
If successful, the server sends one or more C responses. |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
The status operation can be rather expensive on some folder |
687
|
|
|
|
|
|
|
implementations, so clients should use this method sparingly. |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
=cut |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
sub status { |
692
|
|
|
|
|
|
|
my $self = shift; |
693
|
|
|
|
|
|
|
my $mailbox = shift; |
694
|
|
|
|
|
|
|
return undef if ($self->{Mailbox} eq $mailbox); |
695
|
|
|
|
|
|
|
$self->imap_command('status', |
696
|
|
|
|
|
|
|
ASTRING, _encode_mailbox($mailbox), PARENS, [@_]); |
697
|
|
|
|
|
|
|
} |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
=head2 append $mailbox, $message [, Flags => $flaglistref] [, Date => $date] |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
Appends the email message specified in C<$message> to the mailbox |
702
|
|
|
|
|
|
|
specified in C<$mailbox>. This method is valid only when the session |
703
|
|
|
|
|
|
|
is in the authenticated or selected states. |
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
In general, the email message should be a real RFC822 message, |
706
|
|
|
|
|
|
|
although exceptions such as draft messages are reasonable in some |
707
|
|
|
|
|
|
|
situations. Also note that the line terminators in C<$message> need |
708
|
|
|
|
|
|
|
to be CRLF. |
709
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
The C option allows a set of flags to be specified for the |
711
|
|
|
|
|
|
|
message when it is appended. Servers are not required to honor this, |
712
|
|
|
|
|
|
|
but most, if not all, do so. |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
The C option forces the internaldate to the specified value. If |
715
|
|
|
|
|
|
|
C<$date> is a string, the format of the string is C
|
716
|
|
|
|
|
|
|
hh:mm:ss [-+]zzzz>, where C is the day of the month (starting from |
717
|
|
|
|
|
|
|
1), C is the three-character abbreviation for the month name, |
718
|
|
|
|
|
|
|
C is the 4-digit year, C is the hour, C is the minutes, |
719
|
|
|
|
|
|
|
C is the seconds, and C<[-+]zzzz> is the numeric timezone offset. |
720
|
|
|
|
|
|
|
This happens to be the same format returned by the C |
721
|
|
|
|
|
|
|
item from the C command. If C<$date> is a list reference, it is |
722
|
|
|
|
|
|
|
expected to contain two elements: a time integer and a timezone offset |
723
|
|
|
|
|
|
|
string. The timezone string is expected to be formatted as |
724
|
|
|
|
|
|
|
C<[-+]zzzz>. These two values will be used to synthesize a string in |
725
|
|
|
|
|
|
|
the format expected by the IMAP server. As with the C options, |
726
|
|
|
|
|
|
|
servers are not required to honor the C option, but most, if not |
727
|
|
|
|
|
|
|
all, do so. |
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
Note that the options are specified at the end of the list of method |
730
|
|
|
|
|
|
|
arguments. This is due to the fact that it is possible to have a |
731
|
|
|
|
|
|
|
C<$mailbox> named C or C. Processing the options at the |
732
|
|
|
|
|
|
|
end of the argument list simplifies argument processing. The order of |
733
|
|
|
|
|
|
|
the arguments will be changed if enough people complain. |
734
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
If server returns a C response containing a C response |
736
|
|
|
|
|
|
|
code, this means C<$mailbox> does not exist but the server thinks the |
737
|
|
|
|
|
|
|
command would have succeeded if the an appropriate C command |
738
|
|
|
|
|
|
|
was issued. On the other hand, failure with no C response |
739
|
|
|
|
|
|
|
code generally means that a C should not be attempted. |
740
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
=cut |
742
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
sub append { |
744
|
|
|
|
|
|
|
my $self = shift; |
745
|
|
|
|
|
|
|
my $mailbox = shift; |
746
|
|
|
|
|
|
|
my $lit = shift; |
747
|
|
|
|
|
|
|
my %options = @_; |
748
|
|
|
|
|
|
|
my @args; |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
push @args, ASTRING, _encode_mailbox($mailbox); |
751
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
if (defined($options{Flags})) { |
753
|
|
|
|
|
|
|
for my $flag (@{$options{Flags}}) { |
754
|
|
|
|
|
|
|
unless ($self->_valid_flag($flag)) { |
755
|
|
|
|
|
|
|
carp "$flag is not a system flag"; |
756
|
|
|
|
|
|
|
return undef; |
757
|
|
|
|
|
|
|
} |
758
|
|
|
|
|
|
|
} |
759
|
|
|
|
|
|
|
push @args, PARENS, [@{$options{Flags}}]; |
760
|
|
|
|
|
|
|
} |
761
|
|
|
|
|
|
|
if (defined($options{Date})) { |
762
|
|
|
|
|
|
|
my $date; |
763
|
|
|
|
|
|
|
if ((ref($options{Date}) eq 'ARRAY') |
764
|
|
|
|
|
|
|
&& defined($options{Date}->[1])){ |
765
|
|
|
|
|
|
|
my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); |
766
|
|
|
|
|
|
|
my @gmtime = gmtime($options{Date}->[0]); |
767
|
|
|
|
|
|
|
$date = sprintf("%02d-%2s-%4d %02d:%02d:%02d %s", |
768
|
|
|
|
|
|
|
$gmtime[3], $months[$gmtime[4]], $gmtime[5] + 1900, |
769
|
|
|
|
|
|
|
$gmtime[2], $gmtime[1], $gmtime[0], |
770
|
|
|
|
|
|
|
$options{Date}->[1]); |
771
|
|
|
|
|
|
|
} else { |
772
|
|
|
|
|
|
|
$date = $options{Date}; |
773
|
|
|
|
|
|
|
} |
774
|
|
|
|
|
|
|
if ($date !~ /^[ \d][\d]-[a-zA-Z]{3}-\d{4} \d\d:\d\d:\d\d [\+\-]\d{4}$/) { |
775
|
|
|
|
|
|
|
carp "invalid date value for append command"; |
776
|
|
|
|
|
|
|
return undef; |
777
|
|
|
|
|
|
|
} |
778
|
|
|
|
|
|
|
push @args, ATOM, "\"$date\""; |
779
|
|
|
|
|
|
|
} |
780
|
|
|
|
|
|
|
$lit =~ s/\n/\r\n/mg if ($self->{Options}{EOL} eq 'lf'); |
781
|
|
|
|
|
|
|
push @args, ASTRING, $lit; |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
$self->imap_command('append', @args); |
784
|
|
|
|
|
|
|
} |
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
=head2 check |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
Ask the server to perform a checkpoint of its data. This method is |
789
|
|
|
|
|
|
|
valid only when the session is in the selected state. |
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
While not always needed, this should be called if the client issues a |
792
|
|
|
|
|
|
|
large quantity of updates to a folder in an extended session. |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
=cut |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
sub check { $_[0]->imap_command('check') } |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
=head2 close |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
Close the current mailbox. This method is valid only when the session |
801
|
|
|
|
|
|
|
is in the selected state. |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
If successful, the session state is changed to I. |
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
=cut |
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
sub close { $_[0]->imap_command('close') } |
808
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
=head2 expunge |
810
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
Delete messages marked for deletion. This method is valid only when |
812
|
|
|
|
|
|
|
the session is in the selected state. |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
If successful, the server sends a series of C responses. |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
It will return C is the mailbox is marked read-only. |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
=cut |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
sub expunge { |
821
|
|
|
|
|
|
|
return undef if $_[0]->is_readonly; |
822
|
|
|
|
|
|
|
$_[0]->imap_command('expunge'); |
823
|
|
|
|
|
|
|
} |
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
=head2 search [Charset => $charset,] @searchkeys |
826
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
Searches the mailbox for messages matching the criteria contained in |
828
|
|
|
|
|
|
|
C<@searchkeys>. This method is valid only when the session is in the |
829
|
|
|
|
|
|
|
selected state. |
830
|
|
|
|
|
|
|
|
831
|
|
|
|
|
|
|
The C<@searchkeys> list contains strings matching the format described |
832
|
|
|
|
|
|
|
in Section 6.4.4 of RFC2060. |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
If successful, the server send zero or more C responses. Lack |
835
|
|
|
|
|
|
|
of a C response means the server found no matches. Note that |
836
|
|
|
|
|
|
|
the server can send the results of one search in multiple responses. |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
=cut |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
sub search { |
841
|
|
|
|
|
|
|
my $self = shift; |
842
|
|
|
|
|
|
|
my @args; |
843
|
|
|
|
|
|
|
if ($_[0] =~ /^charset$/i) { |
844
|
|
|
|
|
|
|
shift; |
845
|
|
|
|
|
|
|
my $charset = shift; |
846
|
|
|
|
|
|
|
push @args, ATOM, 'charset', ASTRING, $charset; |
847
|
|
|
|
|
|
|
} |
848
|
|
|
|
|
|
|
push @args, map { (ATOM, $_) } @_; |
849
|
|
|
|
|
|
|
$self->imap_command('search', @args); |
850
|
|
|
|
|
|
|
} |
851
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
=head2 fetch $msgset, 'all'|'full'|'fast'|$fetchattr|@fetchattrs |
853
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
Retrieves data about a set of messages. This method is valid only |
855
|
|
|
|
|
|
|
when the session is in the selected state. |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
The C<$msgset> parameter identifies the set of messages from which to |
858
|
|
|
|
|
|
|
retrieve the items of interest. The notation accepted is similar to |
859
|
|
|
|
|
|
|
that found in C<.newsrc> files, except that C<:> is used to specify |
860
|
|
|
|
|
|
|
ranges, instead of C<->. Thus, to specify messages 1, 2, 3, 5, 7, 8, |
861
|
|
|
|
|
|
|
9, the following string could be used: C<'1:3,5,7:9'>. The character |
862
|
|
|
|
|
|
|
C<*> can be used to indicate the highest message number in the |
863
|
|
|
|
|
|
|
mailbox. Thus, to specify the last 4 messages in an 8-message |
864
|
|
|
|
|
|
|
mailbox, you can use C<'5-*'>. |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
The following list enumerates the items that can be retrieved with |
867
|
|
|
|
|
|
|
C. Refer to Section 6.4.5 of RFC2060 for a description of each |
868
|
|
|
|
|
|
|
of these items. |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
=over 4 |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
=item * body[$section]E$partialE |
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
=item * body.peek[$section]E$partialE |
875
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
Important: the response item returned for a C is C. |
877
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
=item * bodystructure |
879
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
=item * body |
881
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
=item * envelope |
883
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
=item * flags |
885
|
|
|
|
|
|
|
|
886
|
|
|
|
|
|
|
=item * internaldate |
887
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
=item * rfc822 |
889
|
|
|
|
|
|
|
|
890
|
|
|
|
|
|
|
=item * rfc822.header |
891
|
|
|
|
|
|
|
|
892
|
|
|
|
|
|
|
=item * rfc822.size |
893
|
|
|
|
|
|
|
|
894
|
|
|
|
|
|
|
=item * rfc822.text |
895
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
=item * uid |
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
=back |
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
Please note that the items returning messages, or portion of messages, |
901
|
|
|
|
|
|
|
return strings terminated with CRLF. |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
RFC2060 also defines several items that are actually macros for other |
904
|
|
|
|
|
|
|
sets of items: |
905
|
|
|
|
|
|
|
|
906
|
|
|
|
|
|
|
=over 4 |
907
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
=item * all |
909
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
A macro equivalent to C<('flags', 'internaldate', 'rfc822.size', 'envelope')>. |
911
|
|
|
|
|
|
|
|
912
|
|
|
|
|
|
|
=item * full |
913
|
|
|
|
|
|
|
|
914
|
|
|
|
|
|
|
A macro equivalent to C<('flags', 'rfc822.size', 'envelope', 'body')>. |
915
|
|
|
|
|
|
|
|
916
|
|
|
|
|
|
|
=item * fast |
917
|
|
|
|
|
|
|
|
918
|
|
|
|
|
|
|
A macro equivalent to C<('flags', 'internaldate', 'rfc822.size')>. |
919
|
|
|
|
|
|
|
|
920
|
|
|
|
|
|
|
=back |
921
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
The C, C, and C items are not intended to be used |
923
|
|
|
|
|
|
|
with other items. |
924
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
If successful, the server responses with one or more C |
926
|
|
|
|
|
|
|
responses. |
927
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
If the completion response from a C command is C, the |
929
|
|
|
|
|
|
|
client should send a C command, to force any pending expunge |
930
|
|
|
|
|
|
|
responses from the server, and retry the C command with |
931
|
|
|
|
|
|
|
C<$msgset> adjusted accordingly. |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
=cut |
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
sub fetch { |
936
|
|
|
|
|
|
|
my $self = shift; |
937
|
|
|
|
|
|
|
my $msgset = shift; |
938
|
|
|
|
|
|
|
my @args; |
939
|
|
|
|
|
|
|
if (scalar(@_) == 1) { |
940
|
|
|
|
|
|
|
push @args, ATOM, shift; |
941
|
|
|
|
|
|
|
} else { |
942
|
|
|
|
|
|
|
push @args, PARENS, [@_]; |
943
|
|
|
|
|
|
|
} |
944
|
|
|
|
|
|
|
$self->imap_command('fetch', ATOM, $msgset, @args); |
945
|
|
|
|
|
|
|
} |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
=head2 store $msgset, $itemname, @storeattrflags |
948
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
Sets various attributes for the messages identified in C<$msgset>. |
950
|
|
|
|
|
|
|
This method is valid only when the session is in the selected state. |
951
|
|
|
|
|
|
|
|
952
|
|
|
|
|
|
|
The C<$msgset> parameter is described in the section describing C. |
953
|
|
|
|
|
|
|
|
954
|
|
|
|
|
|
|
The C<$itemname> can be one of the following: |
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
=over 4 |
957
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
=item * flags |
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
Replaces the current flags with the flags specified in C<@storeattrflags>. |
961
|
|
|
|
|
|
|
|
962
|
|
|
|
|
|
|
=item * +flags |
963
|
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
Adds the flags specified in C<@storeattrflags> to the current flags. |
965
|
|
|
|
|
|
|
|
966
|
|
|
|
|
|
|
=item * -flags |
967
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
Removes the flags specified in C<@storeattrflags> from the current |
969
|
|
|
|
|
|
|
flags. |
970
|
|
|
|
|
|
|
|
971
|
|
|
|
|
|
|
=back |
972
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
The C<$itemname> can also have C<.silent> appended, which causes the |
974
|
|
|
|
|
|
|
server to not send back update responses for the messages. |
975
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
If successful, and C<.silent> is used used in C<$itemname>, the server |
977
|
|
|
|
|
|
|
response with a series of C responses reflecting the updates to |
978
|
|
|
|
|
|
|
the specified messages. |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
If the completion response from a C command is C, the |
981
|
|
|
|
|
|
|
client should send a C command, to force any pending expunge |
982
|
|
|
|
|
|
|
responses from the server, and retry the C command with |
983
|
|
|
|
|
|
|
C<$msgset> adjusted accordingly. |
984
|
|
|
|
|
|
|
|
985
|
|
|
|
|
|
|
The C<@storeattrflags> is a list of flag strings. |
986
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
=cut |
988
|
|
|
|
|
|
|
|
989
|
|
|
|
|
|
|
sub store { |
990
|
|
|
|
|
|
|
my $self = shift; |
991
|
|
|
|
|
|
|
my $msgset = shift; |
992
|
|
|
|
|
|
|
my $itemname = shift; |
993
|
|
|
|
|
|
|
for my $flag (@_) { |
994
|
|
|
|
|
|
|
unless ($self->_valid_flag($flag)) { |
995
|
|
|
|
|
|
|
carp "$flag is not a system flag"; |
996
|
|
|
|
|
|
|
return undef; |
997
|
|
|
|
|
|
|
} |
998
|
|
|
|
|
|
|
} |
999
|
|
|
|
|
|
|
$self->imap_command('store', ATOM, $msgset, ATOM, $itemname, PARENS, [@_]); |
1000
|
|
|
|
|
|
|
} |
1001
|
|
|
|
|
|
|
|
1002
|
|
|
|
|
|
|
=head2 copy $msgset, $mailbox |
1003
|
|
|
|
|
|
|
|
1004
|
|
|
|
|
|
|
Copy the messages C<$msgset> to the specified mailbox. This method is |
1005
|
|
|
|
|
|
|
valid only when the session is in the selected state. |
1006
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
The C<$msgset> parameter is described in the section describing C. |
1008
|
|
|
|
|
|
|
|
1009
|
|
|
|
|
|
|
If server returns a C response containing a C response |
1010
|
|
|
|
|
|
|
code, this means C<$mailbox> does not exist but the server thinks the |
1011
|
|
|
|
|
|
|
command would have succeeded if the an appropriate C command |
1012
|
|
|
|
|
|
|
was issued. On the other hand, failure with no C response |
1013
|
|
|
|
|
|
|
code generally means that a C should not be attempted. |
1014
|
|
|
|
|
|
|
|
1015
|
|
|
|
|
|
|
=cut |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
sub copy { $_[0]->imap_command('copy', |
1018
|
|
|
|
|
|
|
ATOM, $_[1], ASTRING, _encode_mailbox($_[2])) } |
1019
|
|
|
|
|
|
|
|
1020
|
|
|
|
|
|
|
=head2 uid_copy $msgset, $mailbox |
1021
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
A variant of C that uses UIDs in C<$msgset>, instead of message |
1023
|
|
|
|
|
|
|
numbers. This method is valid only when the session is in the |
1024
|
|
|
|
|
|
|
selected state. |
1025
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
=cut |
1027
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
sub uid_copy { $_[0]->imap_command('uid copy', |
1029
|
|
|
|
|
|
|
ATOM, $_[1], |
1030
|
|
|
|
|
|
|
ASTRING, _encode_mailbox($_[2])) } |
1031
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
=head2 uid_fetch $msgset, 'all'|'full'|'fast'|$fetchattr|@fetchattrs |
1033
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
A variant of C that uses UIDs, instead of message numbers, in |
1035
|
|
|
|
|
|
|
C<$msgset> and C responses. This method is valid only when the |
1036
|
|
|
|
|
|
|
session is in the selected state. |
1037
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
=cut |
1039
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
sub uid_fetch { |
1041
|
|
|
|
|
|
|
my $self = shift; |
1042
|
|
|
|
|
|
|
my $msgset = shift; |
1043
|
|
|
|
|
|
|
my @args; |
1044
|
|
|
|
|
|
|
if (scalar(@_) == 1) { |
1045
|
|
|
|
|
|
|
push @args, ATOM, shift; |
1046
|
|
|
|
|
|
|
} else { |
1047
|
|
|
|
|
|
|
push @args, PARENS, [@_]; |
1048
|
|
|
|
|
|
|
} |
1049
|
|
|
|
|
|
|
$self->imap_command('uid fetch', ATOM, $msgset, @args); |
1050
|
|
|
|
|
|
|
} |
1051
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
=head2 uid_search [Charset => $charset,] @searchkeys |
1053
|
|
|
|
|
|
|
|
1054
|
|
|
|
|
|
|
A variant of C that uses UIDs, instead of message numbers, in |
1055
|
|
|
|
|
|
|
C<$msgset> and C responses. This method is valid only when |
1056
|
|
|
|
|
|
|
the session is in the selected state. |
1057
|
|
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
=cut |
1059
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
sub uid_search { |
1061
|
|
|
|
|
|
|
my $self = shift; |
1062
|
|
|
|
|
|
|
my @args; |
1063
|
|
|
|
|
|
|
if ($_[0] =~ /^charset$/i) { |
1064
|
|
|
|
|
|
|
shift; |
1065
|
|
|
|
|
|
|
my $charset = shift; |
1066
|
|
|
|
|
|
|
push @args, ATOM, 'charset', ASTRING, $charset; |
1067
|
|
|
|
|
|
|
} |
1068
|
|
|
|
|
|
|
push @args, map { (ATOM, $_) } @_; |
1069
|
|
|
|
|
|
|
$self->imap_command('uid search', @args); |
1070
|
|
|
|
|
|
|
} |
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
=head2 uid_store $msgset, $itemname, @storeattrflags |
1073
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
A variant of C that uses UIDs, instead of message numbers, in |
1075
|
|
|
|
|
|
|
C<$msgset> and C responses. This method is valid only when the |
1076
|
|
|
|
|
|
|
session is in the selected state. |
1077
|
|
|
|
|
|
|
|
1078
|
|
|
|
|
|
|
=cut |
1079
|
|
|
|
|
|
|
|
1080
|
|
|
|
|
|
|
sub uid_store { |
1081
|
|
|
|
|
|
|
my $self = shift; |
1082
|
|
|
|
|
|
|
my $msgset = shift; |
1083
|
|
|
|
|
|
|
my $itemname = shift; |
1084
|
|
|
|
|
|
|
for my $flag (@_) { |
1085
|
|
|
|
|
|
|
unless ($self->_valid_flag($flag)) { |
1086
|
|
|
|
|
|
|
carp "$flag is not a system flag"; |
1087
|
|
|
|
|
|
|
return undef; |
1088
|
|
|
|
|
|
|
} |
1089
|
|
|
|
|
|
|
} |
1090
|
|
|
|
|
|
|
$self->imap_command('uid store', |
1091
|
|
|
|
|
|
|
ATOM, $msgset, ATOM, $itemname, PARENS, [@_]); |
1092
|
|
|
|
|
|
|
} |
1093
|
|
|
|
|
|
|
############################################################################### |
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
=head1 CONVENIENCE ROUTINES |
1096
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
In addition to the core protocol methods, C provides |
1098
|
|
|
|
|
|
|
several methods for accessing various pieces of information. |
1099
|
|
|
|
|
|
|
|
1100
|
|
|
|
|
|
|
=head2 is_preauth |
1101
|
|
|
|
|
|
|
|
1102
|
|
|
|
|
|
|
Returns a boolean valud indicating whether the IMAP session is |
1103
|
|
|
|
|
|
|
preauthenticated. |
1104
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
=cut |
1106
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
sub is_preauth { $_[0]->{PreAuth} } |
1108
|
|
|
|
|
|
|
|
1109
|
|
|
|
|
|
|
=head2 banner |
1110
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
Returns the banner string issued by the server at connect time. |
1112
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
=cut |
1114
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
sub banner { $_[0]->{Banner} } |
1116
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
=head2 capabilities |
1118
|
|
|
|
|
|
|
|
1119
|
|
|
|
|
|
|
Returns the list of capabilities supported by the server, minus the |
1120
|
|
|
|
|
|
|
authentication capabilities. The list is not guaranteed to be in any |
1121
|
|
|
|
|
|
|
specific order. |
1122
|
|
|
|
|
|
|
|
1123
|
|
|
|
|
|
|
=cut |
1124
|
|
|
|
|
|
|
|
1125
|
|
|
|
|
|
|
sub capabilities { keys %{$_[0]->{Capabilities}} } |
1126
|
|
|
|
|
|
|
|
1127
|
|
|
|
|
|
|
=head2 has_capability $capname |
1128
|
|
|
|
|
|
|
|
1129
|
|
|
|
|
|
|
Returns a boolean value indicating whether the server supports the |
1130
|
|
|
|
|
|
|
specified capability. |
1131
|
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
=cut |
1133
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
sub has_capability { defined($_[0]->{Capabilities}{uc($_[1])}) } |
1135
|
|
|
|
|
|
|
|
1136
|
|
|
|
|
|
|
=head2 authtypes |
1137
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
Returns a list of authentication types supported by the server. |
1139
|
|
|
|
|
|
|
|
1140
|
|
|
|
|
|
|
=cut |
1141
|
|
|
|
|
|
|
|
1142
|
|
|
|
|
|
|
sub authtypes { keys %{$_[0]->{AuthTypes}} } |
1143
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
=head2 has_authtype $authname |
1145
|
|
|
|
|
|
|
|
1146
|
|
|
|
|
|
|
Returns a boolean value indicating whether the server supports the |
1147
|
|
|
|
|
|
|
specified authentication type. |
1148
|
|
|
|
|
|
|
|
1149
|
|
|
|
|
|
|
=cut |
1150
|
|
|
|
|
|
|
|
1151
|
|
|
|
|
|
|
sub has_authtype { defined($_[0]->{AuthTypes}{uc($_[1])}) } |
1152
|
|
|
|
|
|
|
|
1153
|
|
|
|
|
|
|
=head2 qty_messages |
1154
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
Returns the quantity of messages in the currently selected folder. |
1156
|
|
|
|
|
|
|
|
1157
|
|
|
|
|
|
|
=cut |
1158
|
|
|
|
|
|
|
|
1159
|
|
|
|
|
|
|
sub qty_messages { $_[0]->{MailboxStatus}{'exists'} } |
1160
|
|
|
|
|
|
|
|
1161
|
|
|
|
|
|
|
=head2 qty_recent |
1162
|
|
|
|
|
|
|
|
1163
|
|
|
|
|
|
|
Returns the quantity of recent messages in the currently selected folder. |
1164
|
|
|
|
|
|
|
|
1165
|
|
|
|
|
|
|
=cut |
1166
|
|
|
|
|
|
|
|
1167
|
|
|
|
|
|
|
sub qty_recent { $_[0]->{MailboxStatus}{'recent'} } |
1168
|
|
|
|
|
|
|
|
1169
|
|
|
|
|
|
|
=head2 first_unseen |
1170
|
|
|
|
|
|
|
|
1171
|
|
|
|
|
|
|
Returns the message number of the first unseen messages in the |
1172
|
|
|
|
|
|
|
currently selected folder. |
1173
|
|
|
|
|
|
|
|
1174
|
|
|
|
|
|
|
=cut |
1175
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
sub first_unseen { $_[0]->{MailboxStatus}{'unseen'} } |
1177
|
|
|
|
|
|
|
|
1178
|
|
|
|
|
|
|
=head2 uidvalidity |
1179
|
|
|
|
|
|
|
|
1180
|
|
|
|
|
|
|
Returns the C value for the currently selected folder. |
1181
|
|
|
|
|
|
|
This is useful for IMAP clients that cache data in persistent storage. |
1182
|
|
|
|
|
|
|
Cache data for a mailbox should only be considered valid if the |
1183
|
|
|
|
|
|
|
C is the same for both cached data and the remote |
1184
|
|
|
|
|
|
|
mailbox. See Section 2.3.1.1 of RFC2060 for further details. |
1185
|
|
|
|
|
|
|
|
1186
|
|
|
|
|
|
|
=cut |
1187
|
|
|
|
|
|
|
|
1188
|
|
|
|
|
|
|
sub uidvalidity { $_[0]->{MailboxStatus}{'uidvalidity'} } |
1189
|
|
|
|
|
|
|
|
1190
|
|
|
|
|
|
|
=head2 uidnext |
1191
|
|
|
|
|
|
|
|
1192
|
|
|
|
|
|
|
Returns the C value for the currently selected folder. |
1193
|
|
|
|
|
|
|
|
1194
|
|
|
|
|
|
|
=cut |
1195
|
|
|
|
|
|
|
|
1196
|
|
|
|
|
|
|
sub uidnext { $_[0]->{MailboxStatus}{'uidnext'} } |
1197
|
|
|
|
|
|
|
|
1198
|
|
|
|
|
|
|
=head2 permanentflags |
1199
|
|
|
|
|
|
|
|
1200
|
|
|
|
|
|
|
Returns the list of permanent flags the server has identified for the |
1201
|
|
|
|
|
|
|
currently open mailbox. |
1202
|
|
|
|
|
|
|
|
1203
|
|
|
|
|
|
|
If a C<\*> flag is present, the server allows new persistent keywords |
1204
|
|
|
|
|
|
|
to be created. |
1205
|
|
|
|
|
|
|
|
1206
|
|
|
|
|
|
|
=cut |
1207
|
|
|
|
|
|
|
|
1208
|
|
|
|
|
|
|
sub permanentflags { keys %{$_[0]->{MailboxStatus}{'permanentflags'}} } |
1209
|
|
|
|
|
|
|
|
1210
|
|
|
|
|
|
|
=head2 is_permanentflag $flag |
1211
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
Returns a boolean value indicating whether the server considers |
1213
|
|
|
|
|
|
|
C<$flag> to be a permanent flag. |
1214
|
|
|
|
|
|
|
|
1215
|
|
|
|
|
|
|
=cut |
1216
|
|
|
|
|
|
|
|
1217
|
|
|
|
|
|
|
sub is_permanentflag { |
1218
|
|
|
|
|
|
|
defined($_[0]->{MailboxStatus}{'permanentflags'}{lc($_[1])}); |
1219
|
|
|
|
|
|
|
} |
1220
|
|
|
|
|
|
|
|
1221
|
|
|
|
|
|
|
=head2 flags |
1222
|
|
|
|
|
|
|
|
1223
|
|
|
|
|
|
|
Returns a list of the flags associated with the mailbox. |
1224
|
|
|
|
|
|
|
|
1225
|
|
|
|
|
|
|
=cut |
1226
|
|
|
|
|
|
|
|
1227
|
|
|
|
|
|
|
sub flags { keys %{$_[0]->{MailboxStatus}{'flags'}} } |
1228
|
|
|
|
|
|
|
|
1229
|
|
|
|
|
|
|
=head2 has_flag $flag |
1230
|
|
|
|
|
|
|
|
1231
|
|
|
|
|
|
|
Returns a boolean value indicating whether the given $flag is defined |
1232
|
|
|
|
|
|
|
for the mailbox. |
1233
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
=cut |
1235
|
|
|
|
|
|
|
|
1236
|
|
|
|
|
|
|
sub has_flag { defined($_[0]->{MailboxStatus}{'flags'}{lc($_[1])}) } |
1237
|
|
|
|
|
|
|
|
1238
|
|
|
|
|
|
|
=head2 mailbox |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
Returns the name of the currently open mailbox. Returns C if |
1241
|
|
|
|
|
|
|
no mailbox is currently open. |
1242
|
|
|
|
|
|
|
|
1243
|
|
|
|
|
|
|
=cut |
1244
|
|
|
|
|
|
|
|
1245
|
|
|
|
|
|
|
sub mailbox { $_[0]->{Mailbox} } |
1246
|
|
|
|
|
|
|
|
1247
|
|
|
|
|
|
|
=head2 is_readonly |
1248
|
|
|
|
|
|
|
|
1249
|
|
|
|
|
|
|
Returns a boolean value indicating whether the currently open mailbox |
1250
|
|
|
|
|
|
|
is read-only. |
1251
|
|
|
|
|
|
|
|
1252
|
|
|
|
|
|
|
=cut |
1253
|
|
|
|
|
|
|
|
1254
|
|
|
|
|
|
|
sub is_readonly { $_[0]->{ReadOnly} } |
1255
|
|
|
|
|
|
|
|
1256
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1257
|
|
|
|
|
|
|
|
1258
|
|
|
|
|
|
|
sub _encode_mailbox { |
1259
|
|
|
|
|
|
|
my $str = $_[0]; |
1260
|
|
|
|
|
|
|
$str =~ s/&/&-/g; |
1261
|
|
|
|
|
|
|
return $str; |
1262
|
|
|
|
|
|
|
} |
1263
|
|
|
|
|
|
|
|
1264
|
|
|
|
|
|
|
sub _decode_mailbox { |
1265
|
|
|
|
|
|
|
my $str = $_[0]; |
1266
|
|
|
|
|
|
|
$str =~ s/&-/&/g; |
1267
|
|
|
|
|
|
|
return $str; |
1268
|
|
|
|
|
|
|
} |
1269
|
|
|
|
|
|
|
|
1270
|
|
|
|
|
|
|
############################################################################### |
1271
|
|
|
|
|
|
|
|
1272
|
|
|
|
|
|
|
=head1 NAMESPACE EXTENSION |
1273
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
The following methods are available if the server advertises support |
1275
|
|
|
|
|
|
|
for RFC2342 (IMAP4 Namespace). Refer to that RFC for additional |
1276
|
|
|
|
|
|
|
information. |
1277
|
|
|
|
|
|
|
|
1278
|
|
|
|
|
|
|
=head2 namespace |
1279
|
|
|
|
|
|
|
|
1280
|
|
|
|
|
|
|
Sends a C command to the server, if the server advertises |
1281
|
|
|
|
|
|
|
support for the extension extension. |
1282
|
|
|
|
|
|
|
|
1283
|
|
|
|
|
|
|
=cut |
1284
|
|
|
|
|
|
|
|
1285
|
|
|
|
|
|
|
sub namespace { |
1286
|
|
|
|
|
|
|
my $self = shift; |
1287
|
|
|
|
|
|
|
return undef unless $self->has_capability('NAMESPACE'); |
1288
|
|
|
|
|
|
|
$self->imap_command('namespace'); |
1289
|
|
|
|
|
|
|
} |
1290
|
|
|
|
|
|
|
|
1291
|
|
|
|
|
|
|
############################################################################### |
1292
|
|
|
|
|
|
|
|
1293
|
|
|
|
|
|
|
=head1 ACCESS CONTROL EXTENSION |
1294
|
|
|
|
|
|
|
|
1295
|
|
|
|
|
|
|
The following methods are available if the server advertises support |
1296
|
|
|
|
|
|
|
for RFC2086 (IMAP4 ACL Extension). Refer to that RFC for additional |
1297
|
|
|
|
|
|
|
information. |
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
=head2 setacl $mailbox, $identifier, $modrights |
1300
|
|
|
|
|
|
|
|
1301
|
|
|
|
|
|
|
Sets the access control list for C<$identifier> on C<$mailbox> |
1302
|
|
|
|
|
|
|
according to the rights contained in C<$modrights>. |
1303
|
|
|
|
|
|
|
|
1304
|
|
|
|
|
|
|
The C<$identifier> typically identifies an account name, but can also |
1305
|
|
|
|
|
|
|
specify abstract entities, such as groups. |
1306
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
The format for C<$modrights> is documented in RFC2086. |
1308
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
=cut |
1310
|
|
|
|
|
|
|
|
1311
|
|
|
|
|
|
|
sub setacl { |
1312
|
|
|
|
|
|
|
my $self = shift; |
1313
|
|
|
|
|
|
|
return undef unless $self->has_capability('ACL'); |
1314
|
|
|
|
|
|
|
$self->imap_command('setacl', |
1315
|
|
|
|
|
|
|
ASTRING, _encode_mailbox($_[0]), |
1316
|
|
|
|
|
|
|
ASTRING, $_[1], |
1317
|
|
|
|
|
|
|
ASTRING, $_[2]); |
1318
|
|
|
|
|
|
|
} |
1319
|
|
|
|
|
|
|
|
1320
|
|
|
|
|
|
|
=head2 getacl $mailbox |
1321
|
|
|
|
|
|
|
|
1322
|
|
|
|
|
|
|
Retrieves the access control list for C<$mailbox>. |
1323
|
|
|
|
|
|
|
|
1324
|
|
|
|
|
|
|
=cut |
1325
|
|
|
|
|
|
|
|
1326
|
|
|
|
|
|
|
sub getacl { |
1327
|
|
|
|
|
|
|
my $self = shift; |
1328
|
|
|
|
|
|
|
return undef unless $self->has_capability('ACL'); |
1329
|
|
|
|
|
|
|
$self->imap_command('getacl', ASTRING, _encode_mailbox($_[0])); |
1330
|
|
|
|
|
|
|
} |
1331
|
|
|
|
|
|
|
|
1332
|
|
|
|
|
|
|
=head2 deleteacl $mailbox, $identifier |
1333
|
|
|
|
|
|
|
|
1334
|
|
|
|
|
|
|
Deletes all access control list entries for C<$identifier> from |
1335
|
|
|
|
|
|
|
C<$mailbox>. |
1336
|
|
|
|
|
|
|
|
1337
|
|
|
|
|
|
|
=cut |
1338
|
|
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
sub deleteacl { |
1340
|
|
|
|
|
|
|
my $self = shift; |
1341
|
|
|
|
|
|
|
return undef unless $self->has_capability('ACL'); |
1342
|
|
|
|
|
|
|
$self->imap_command('deleteacl', |
1343
|
|
|
|
|
|
|
ASTRING, _encode_mailbox($_[0]), ASTRING, $_[1]); |
1344
|
|
|
|
|
|
|
} |
1345
|
|
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
=head2 listrights $mailbox, $identifier |
1347
|
|
|
|
|
|
|
|
1348
|
|
|
|
|
|
|
List the rights available to C<$identifier> for C<$mailbox>. |
1349
|
|
|
|
|
|
|
|
1350
|
|
|
|
|
|
|
=cut |
1351
|
|
|
|
|
|
|
|
1352
|
|
|
|
|
|
|
sub listrights { |
1353
|
|
|
|
|
|
|
my $self = shift; |
1354
|
|
|
|
|
|
|
return undef unless $self->has_capability('ACL'); |
1355
|
|
|
|
|
|
|
$self->imap_command('listrights', |
1356
|
|
|
|
|
|
|
ASTRING, _encode_mailbox($_[0]), ASTRING, $_[1]); |
1357
|
|
|
|
|
|
|
} |
1358
|
|
|
|
|
|
|
|
1359
|
|
|
|
|
|
|
=head2 myrights $mailbox |
1360
|
|
|
|
|
|
|
|
1361
|
|
|
|
|
|
|
List the rights the current user has for C<$mailbox>. |
1362
|
|
|
|
|
|
|
|
1363
|
|
|
|
|
|
|
=cut |
1364
|
|
|
|
|
|
|
|
1365
|
|
|
|
|
|
|
sub myrights { |
1366
|
|
|
|
|
|
|
my $self = shift; |
1367
|
|
|
|
|
|
|
return undef unless $self->has_capability('ACL'); |
1368
|
|
|
|
|
|
|
$self->imap_command('myrights', ASTRING, _encode_mailbox($_[0])); |
1369
|
|
|
|
|
|
|
} |
1370
|
|
|
|
|
|
|
|
1371
|
|
|
|
|
|
|
############################################################################### |
1372
|
|
|
|
|
|
|
|
1373
|
|
|
|
|
|
|
=head1 QUOTA EXTENSION |
1374
|
|
|
|
|
|
|
|
1375
|
|
|
|
|
|
|
The following methods are available if the server advertises support |
1376
|
|
|
|
|
|
|
for RFC2087 (IMAP4 Quota Extension). Refer to that RFC for additional |
1377
|
|
|
|
|
|
|
information. |
1378
|
|
|
|
|
|
|
|
1379
|
|
|
|
|
|
|
=head2 getquota $quotaroot |
1380
|
|
|
|
|
|
|
|
1381
|
|
|
|
|
|
|
Lists the resource usage and limits for C<$quotaroot>. |
1382
|
|
|
|
|
|
|
|
1383
|
|
|
|
|
|
|
=cut |
1384
|
|
|
|
|
|
|
|
1385
|
|
|
|
|
|
|
sub getquota { |
1386
|
|
|
|
|
|
|
my $self = shift; |
1387
|
|
|
|
|
|
|
return undef unless $self->has_capability('QUOTA'); |
1388
|
|
|
|
|
|
|
$self->imap_command('getquota', ASTRING, $_[0]); |
1389
|
|
|
|
|
|
|
} |
1390
|
|
|
|
|
|
|
|
1391
|
|
|
|
|
|
|
=head2 setquota $quotaroot, @setquotalist |
1392
|
|
|
|
|
|
|
|
1393
|
|
|
|
|
|
|
Sets the resource limits for C<$quotaroot> to C<@setquotalist>. |
1394
|
|
|
|
|
|
|
|
1395
|
|
|
|
|
|
|
Valid values for C<@setquotalist> are server-dependant. |
1396
|
|
|
|
|
|
|
|
1397
|
|
|
|
|
|
|
=cut |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
sub setquota { |
1400
|
|
|
|
|
|
|
my $self = shift; |
1401
|
|
|
|
|
|
|
my $quotaroot = shift; |
1402
|
|
|
|
|
|
|
return undef unless $self->has_capability('QUOTA'); |
1403
|
|
|
|
|
|
|
$self->imap_command('setquota', ASTRING, $quotaroot, PARENS, [@_]); |
1404
|
|
|
|
|
|
|
} |
1405
|
|
|
|
|
|
|
|
1406
|
|
|
|
|
|
|
=head2 getquotaroot $mailbox |
1407
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
Lists the quota roots for C<$mailbox>. |
1409
|
|
|
|
|
|
|
|
1410
|
|
|
|
|
|
|
=cut |
1411
|
|
|
|
|
|
|
|
1412
|
|
|
|
|
|
|
sub getquotaroot { |
1413
|
|
|
|
|
|
|
return undef unless $_[0]->has_capability('QUOTA'); |
1414
|
|
|
|
|
|
|
$_[0]->imap_command('getquotaroot', ASTRING, _encode_mailbox($_[1])); |
1415
|
|
|
|
|
|
|
} |
1416
|
|
|
|
|
|
|
|
1417
|
|
|
|
|
|
|
############################################################################### |
1418
|
|
|
|
|
|
|
|
1419
|
|
|
|
|
|
|
=head1 UIDPLUS EXTENSION |
1420
|
|
|
|
|
|
|
|
1421
|
|
|
|
|
|
|
The following method is available if the server advertises support for |
1422
|
|
|
|
|
|
|
RFC2359 (IMAP4 UIDPLUS Extension). Refer to that RFC for additional |
1423
|
|
|
|
|
|
|
information. |
1424
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
=head2 uid_expunge $msgset |
1426
|
|
|
|
|
|
|
|
1427
|
|
|
|
|
|
|
A variant of C that allows the operation to be narrowed to |
1428
|
|
|
|
|
|
|
the messages with UIDs specified in C<$msgset>. |
1429
|
|
|
|
|
|
|
|
1430
|
|
|
|
|
|
|
The C<$msgset> parameter is described in the section describing C. |
1431
|
|
|
|
|
|
|
|
1432
|
|
|
|
|
|
|
=cut |
1433
|
|
|
|
|
|
|
|
1434
|
|
|
|
|
|
|
sub uid_expunge { |
1435
|
|
|
|
|
|
|
return undef unless $_[0]->has_capability('UIDPLUS'); |
1436
|
|
|
|
|
|
|
$_[0]->imap_command('uid expunge', ATOM, $_[1]); |
1437
|
|
|
|
|
|
|
} |
1438
|
|
|
|
|
|
|
|
1439
|
|
|
|
|
|
|
############################################################################### |
1440
|
|
|
|
|
|
|
|
1441
|
|
|
|
|
|
|
sub imap_command { |
1442
|
|
|
|
|
|
|
my $self = shift; |
1443
|
|
|
|
|
|
|
if (!defined($cmd_callbacks{$_[0]})) { |
1444
|
|
|
|
|
|
|
carp("unknown imap command: $_[0]"); |
1445
|
|
|
|
|
|
|
return undef; |
1446
|
|
|
|
|
|
|
} |
1447
|
|
|
|
|
|
|
unless ($cmd_callbacks{$_[0]}->[1] & $self->{State}) { |
1448
|
|
|
|
|
|
|
carp("invalid state for issuing $_[0] command"); |
1449
|
|
|
|
|
|
|
return undef |
1450
|
|
|
|
|
|
|
} |
1451
|
|
|
|
|
|
|
$self->command($self->imap_cmd_callback($_[0]), @_); |
1452
|
|
|
|
|
|
|
} |
1453
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
############################################################################### |
1455
|
|
|
|
|
|
|
|
1456
|
|
|
|
|
|
|
=head1 CALLBACKS |
1457
|
|
|
|
|
|
|
|
1458
|
|
|
|
|
|
|
Many of the command methods result in the server sending back response |
1459
|
|
|
|
|
|
|
data. C processes each response by parsing the data, |
1460
|
|
|
|
|
|
|
packages it in an appropriate object, and optionally calls a |
1461
|
|
|
|
|
|
|
programmer-defined callback for the response. This callback mechanism |
1462
|
|
|
|
|
|
|
is how programmers get access to the data retrieved from the server. |
1463
|
|
|
|
|
|
|
|
1464
|
|
|
|
|
|
|
=head2 set_untagged_callback $item, $coderef |
1465
|
|
|
|
|
|
|
|
1466
|
|
|
|
|
|
|
Assigns a programmer-defined code reference to the associated untagged |
1467
|
|
|
|
|
|
|
response. When an untagged response matching C<$item> is received, |
1468
|
|
|
|
|
|
|
C<$coderef> is called, with the IMAP object and the associated |
1469
|
|
|
|
|
|
|
response object passed as parameters. |
1470
|
|
|
|
|
|
|
|
1471
|
|
|
|
|
|
|
The default callback for the C, C, C, and C untagged |
1472
|
|
|
|
|
|
|
responses includes code to output the text from C responses to |
1473
|
|
|
|
|
|
|
stderr, using C. If you set your own callback for these |
1474
|
|
|
|
|
|
|
responses, be sure to code handle C codes. Per Section 7.1 of |
1475
|
|
|
|
|
|
|
RFC2060, clients are required to clearly display C messages to |
1476
|
|
|
|
|
|
|
users. |
1477
|
|
|
|
|
|
|
|
1478
|
|
|
|
|
|
|
=cut |
1479
|
|
|
|
|
|
|
|
1480
|
|
|
|
|
|
|
sub set_untagged_callback { |
1481
|
|
|
|
|
|
|
my $self = shift; |
1482
|
|
|
|
|
|
|
my $item = shift; |
1483
|
|
|
|
|
|
|
my $funcref = shift; |
1484
|
|
|
|
|
|
|
|
1485
|
|
|
|
|
|
|
return undef unless defined($untagged_callbacks{$item}); |
1486
|
|
|
|
|
|
|
$untagged_callbacks{$item}->[0] = $funcref; |
1487
|
|
|
|
|
|
|
} |
1488
|
|
|
|
|
|
|
|
1489
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1490
|
|
|
|
|
|
|
|
1491
|
|
|
|
|
|
|
sub imap_cmd_callback { |
1492
|
|
|
|
|
|
|
my $self = shift; |
1493
|
|
|
|
|
|
|
my $cmd = shift; |
1494
|
|
|
|
|
|
|
return sub { |
1495
|
|
|
|
|
|
|
my $resp = shift; |
1496
|
|
|
|
|
|
|
return unless (defined($cmd_callbacks{$cmd}) |
1497
|
|
|
|
|
|
|
&& defined($cmd_callbacks{$cmd}->[0])); |
1498
|
|
|
|
|
|
|
my $func = $cmd_callbacks{$cmd}->[0]; |
1499
|
|
|
|
|
|
|
return $self->$func($resp); |
1500
|
|
|
|
|
|
|
} |
1501
|
|
|
|
|
|
|
} |
1502
|
|
|
|
|
|
|
|
1503
|
|
|
|
|
|
|
sub imap_response_callback { |
1504
|
|
|
|
|
|
|
my $self = shift; |
1505
|
|
|
|
|
|
|
# my $seq = $self->next_sequence; |
1506
|
|
|
|
|
|
|
return sub { |
1507
|
|
|
|
|
|
|
my $response = shift; |
1508
|
|
|
|
|
|
|
my ($tag, $rest) = split(/\s/, $response, 2); |
1509
|
|
|
|
|
|
|
if ($tag eq '*') { |
1510
|
|
|
|
|
|
|
return $self->_imap_process_untagged_response($rest); |
1511
|
|
|
|
|
|
|
} elsif ($tag =~ /^\d+$/) { |
1512
|
|
|
|
|
|
|
return $self->_imap_process_tagged_response($tag, $rest); |
1513
|
|
|
|
|
|
|
} else { |
1514
|
|
|
|
|
|
|
croak("gack! server returned bogus tag: [$tag]"); |
1515
|
|
|
|
|
|
|
} |
1516
|
|
|
|
|
|
|
} |
1517
|
|
|
|
|
|
|
} |
1518
|
|
|
|
|
|
|
|
1519
|
|
|
|
|
|
|
sub _imap_process_untagged_response { |
1520
|
|
|
|
|
|
|
my $self = shift; |
1521
|
|
|
|
|
|
|
my $str = shift; |
1522
|
|
|
|
|
|
|
my @args; |
1523
|
|
|
|
|
|
|
my $num; |
1524
|
|
|
|
|
|
|
|
1525
|
|
|
|
|
|
|
my ($cmd, $rest) = split(/\s/, $str, 2); |
1526
|
|
|
|
|
|
|
if ($cmd =~ /^\d+$/) { |
1527
|
|
|
|
|
|
|
push @args, $cmd; |
1528
|
|
|
|
|
|
|
($cmd, $rest) = split(/\s/, $rest, 2); |
1529
|
|
|
|
|
|
|
} |
1530
|
|
|
|
|
|
|
push @args, $rest if defined($rest); |
1531
|
|
|
|
|
|
|
$cmd = lc($cmd); |
1532
|
|
|
|
|
|
|
if (defined($untagged_callbacks{$cmd})) { |
1533
|
|
|
|
|
|
|
my $class = "Net::IMAP::" . ucfirst(lc($cmd)); |
1534
|
|
|
|
|
|
|
my $ret = $class->new($self, @args); |
1535
|
|
|
|
|
|
|
|
1536
|
|
|
|
|
|
|
# trigger a user callback, maybe - user callback is passed $self |
1537
|
|
|
|
|
|
|
# and the object created by the internal callback |
1538
|
|
|
|
|
|
|
|
1539
|
|
|
|
|
|
|
if (defined($ret)) { |
1540
|
|
|
|
|
|
|
if (defined($untagged_callbacks{$cmd}->[0])) { |
1541
|
|
|
|
|
|
|
&{$untagged_callbacks{$cmd}->[0]}($self, $ret); |
1542
|
|
|
|
|
|
|
} |
1543
|
|
|
|
|
|
|
$self->debug_print(0, "untagged resp callback returned $ret") |
1544
|
|
|
|
|
|
|
if $self->debug; |
1545
|
|
|
|
|
|
|
} else { |
1546
|
|
|
|
|
|
|
carp("untagged resp callback returned undef"); |
1547
|
|
|
|
|
|
|
} |
1548
|
|
|
|
|
|
|
return undef; |
1549
|
|
|
|
|
|
|
} else { |
1550
|
|
|
|
|
|
|
carp("received unknown response from server: [$cmd]\n"); |
1551
|
|
|
|
|
|
|
} |
1552
|
|
|
|
|
|
|
} |
1553
|
|
|
|
|
|
|
|
1554
|
|
|
|
|
|
|
sub _imap_process_tagged_response { |
1555
|
|
|
|
|
|
|
my $self = shift; |
1556
|
|
|
|
|
|
|
my $tag = shift; |
1557
|
|
|
|
|
|
|
my $str = shift; |
1558
|
|
|
|
|
|
|
|
1559
|
|
|
|
|
|
|
my $resp = Net::IMAP::Response->new; |
1560
|
|
|
|
|
|
|
|
1561
|
|
|
|
|
|
|
my ($cond, $text) = split(/\s/, $str, 2); |
1562
|
|
|
|
|
|
|
my $resp_code = undef; |
1563
|
|
|
|
|
|
|
if (substr($text, 0, 1) eq '[') { |
1564
|
|
|
|
|
|
|
($resp_code, $text) = _extract_resp_code($text); |
1565
|
|
|
|
|
|
|
} |
1566
|
|
|
|
|
|
|
$resp->{Sequence} = $tag; |
1567
|
|
|
|
|
|
|
$resp->{Status} = lc($cond); |
1568
|
|
|
|
|
|
|
$resp->{StatusCode} = $resp_code; |
1569
|
|
|
|
|
|
|
$resp->{Text} = $text; |
1570
|
|
|
|
|
|
|
|
1571
|
|
|
|
|
|
|
if ($self->{Disconnect}) { |
1572
|
|
|
|
|
|
|
$self->close_connection or carp "error closing connection: $!"; |
1573
|
|
|
|
|
|
|
} |
1574
|
|
|
|
|
|
|
return $resp; |
1575
|
|
|
|
|
|
|
} |
1576
|
|
|
|
|
|
|
############################################################################### |
1577
|
|
|
|
|
|
|
sub _select_cmd_callback { |
1578
|
|
|
|
|
|
|
my $self = shift; |
1579
|
|
|
|
|
|
|
my $resp = shift; |
1580
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
if ($resp->status eq 'ok') { |
1582
|
|
|
|
|
|
|
$self->{State} = IMAP_STATE_SELECT; |
1583
|
|
|
|
|
|
|
my $status = $resp->status_code; |
1584
|
|
|
|
|
|
|
$self->{ReadOnly} = (defined($status) && ($status->[0] eq 'read-only')); |
1585
|
|
|
|
|
|
|
} else { |
1586
|
|
|
|
|
|
|
$self->{State} = IMAP_STATE_AUTH; |
1587
|
|
|
|
|
|
|
$self->{Mailbox} = ''; |
1588
|
|
|
|
|
|
|
} |
1589
|
|
|
|
|
|
|
} |
1590
|
|
|
|
|
|
|
|
1591
|
|
|
|
|
|
|
sub _login_cmd_callback { |
1592
|
|
|
|
|
|
|
$_[0]->{State} = IMAP_STATE_AUTH if ($_[1]->status eq 'ok'); |
1593
|
|
|
|
|
|
|
} |
1594
|
|
|
|
|
|
|
|
1595
|
|
|
|
|
|
|
sub _close_cmd_callback { |
1596
|
|
|
|
|
|
|
if ($_[1]->status eq 'ok') { |
1597
|
|
|
|
|
|
|
$_[0]->_init_mailbox; |
1598
|
|
|
|
|
|
|
$_[0]->{State} = IMAP_STATE_AUTH; |
1599
|
|
|
|
|
|
|
} |
1600
|
|
|
|
|
|
|
} |
1601
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1602
|
|
|
|
|
|
|
|
1603
|
|
|
|
|
|
|
sub _default_aux_callback { |
1604
|
|
|
|
|
|
|
my $self = shift; |
1605
|
|
|
|
|
|
|
my $resp = shift; |
1606
|
|
|
|
|
|
|
|
1607
|
|
|
|
|
|
|
my $code = $resp->code; |
1608
|
|
|
|
|
|
|
if (defined($code) && ($code->[0] eq 'alert')) { |
1609
|
|
|
|
|
|
|
carp "Alert: ", $resp->text, "\n"; |
1610
|
|
|
|
|
|
|
} |
1611
|
|
|
|
|
|
|
} |
1612
|
|
|
|
|
|
|
|
1613
|
|
|
|
|
|
|
############################################################################### |
1614
|
|
|
|
|
|
|
sub _valid_flag { ((substr($_[1], 0, 1) ne "\\") |
1615
|
|
|
|
|
|
|
|| defined($_system_flags{lc($_[1])})) } |
1616
|
|
|
|
|
|
|
############################################################################### |
1617
|
|
|
|
|
|
|
sub _extract_resp_code { |
1618
|
|
|
|
|
|
|
my $line = shift; |
1619
|
|
|
|
|
|
|
$line =~ m{ |
1620
|
|
|
|
|
|
|
\[ |
1621
|
|
|
|
|
|
|
([^\]]+) # response code |
1622
|
|
|
|
|
|
|
\] |
1623
|
|
|
|
|
|
|
(?: |
1624
|
|
|
|
|
|
|
\s |
1625
|
|
|
|
|
|
|
(.*) # remainder of response line |
1626
|
|
|
|
|
|
|
)? |
1627
|
|
|
|
|
|
|
$ |
1628
|
|
|
|
|
|
|
}x; |
1629
|
|
|
|
|
|
|
my $resp_code = $1; |
1630
|
|
|
|
|
|
|
my $rest = $2; |
1631
|
|
|
|
|
|
|
my $resp_code_list = Net::xAP->parse_fields($resp_code); |
1632
|
|
|
|
|
|
|
$resp_code_list->[0] = lc($resp_code_list->[0]); |
1633
|
|
|
|
|
|
|
return($resp_code_list, $rest); |
1634
|
|
|
|
|
|
|
} |
1635
|
|
|
|
|
|
|
############################################################################### |
1636
|
|
|
|
|
|
|
# use Data::Dumper; |
1637
|
|
|
|
|
|
|
# sub _dump_internals { print STDERR "----\n", Dumper($_[0]), "----\n" } |
1638
|
|
|
|
|
|
|
############################################################################### |
1639
|
|
|
|
|
|
|
|
1640
|
|
|
|
|
|
|
=head1 RESPONSE OBJECTS |
1641
|
|
|
|
|
|
|
|
1642
|
|
|
|
|
|
|
As mention in the previous section, responses are parsed and packaged |
1643
|
|
|
|
|
|
|
into response objects, which are then passed to callbacks. Each type |
1644
|
|
|
|
|
|
|
of response has a corresponding object class. This section describes |
1645
|
|
|
|
|
|
|
the various response objects provided. |
1646
|
|
|
|
|
|
|
|
1647
|
|
|
|
|
|
|
All of the class names itemized below are prefixed with C. |
1648
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
As a general rule, IMAP C items are set to C in the parsed |
1650
|
|
|
|
|
|
|
data, and IMAP parenthetical lists are converted to list references |
1651
|
|
|
|
|
|
|
(of one form or another). In addition, atoms, quoted strings, and |
1652
|
|
|
|
|
|
|
literals are presented as Perl strings. |
1653
|
|
|
|
|
|
|
|
1654
|
|
|
|
|
|
|
The condition responses (C, C, C, C, and C) |
1655
|
|
|
|
|
|
|
can include a response code. Refer to Section 7.1 in RFC2060 for a |
1656
|
|
|
|
|
|
|
description of each of the standard response codes. |
1657
|
|
|
|
|
|
|
|
1658
|
|
|
|
|
|
|
=head1 Response |
1659
|
|
|
|
|
|
|
|
1660
|
|
|
|
|
|
|
This is the object class for completion responses. |
1661
|
|
|
|
|
|
|
|
1662
|
|
|
|
|
|
|
=head2 is_tagged |
1663
|
|
|
|
|
|
|
|
1664
|
|
|
|
|
|
|
Returns a boolean value indicating whether the response is tagged. In |
1665
|
|
|
|
|
|
|
the case of tagged completion responses, this value is always C<1>. |
1666
|
|
|
|
|
|
|
|
1667
|
|
|
|
|
|
|
=cut |
1668
|
|
|
|
|
|
|
|
1669
|
|
|
|
|
|
|
package Net::IMAP::Response; |
1670
|
|
|
|
|
|
|
use vars qw(@ISA); |
1671
|
|
|
|
|
|
|
@ISA = qw(Net::xAP::Response); |
1672
|
|
|
|
|
|
|
|
1673
|
|
|
|
|
|
|
sub is_tagged { 1 } |
1674
|
|
|
|
|
|
|
|
1675
|
|
|
|
|
|
|
=head2 has_trycreate |
1676
|
|
|
|
|
|
|
|
1677
|
|
|
|
|
|
|
Returns a boolean value indicating whether the C response |
1678
|
|
|
|
|
|
|
code is present in the response. This can be used after a failed |
1679
|
|
|
|
|
|
|
C or C command to determine whether the server thinks |
1680
|
|
|
|
|
|
|
the operation would succeed if a C was issued for the |
1681
|
|
|
|
|
|
|
associated mailbox. |
1682
|
|
|
|
|
|
|
|
1683
|
|
|
|
|
|
|
=cut |
1684
|
|
|
|
|
|
|
|
1685
|
|
|
|
|
|
|
sub has_trycreate { |
1686
|
|
|
|
|
|
|
my $status_code = $_[0]->status_code; |
1687
|
|
|
|
|
|
|
return (defined($status_code) && (lc($status_code->[0]) eq 'trycreate')); |
1688
|
|
|
|
|
|
|
} |
1689
|
|
|
|
|
|
|
|
1690
|
|
|
|
|
|
|
############################################################################### |
1691
|
|
|
|
|
|
|
|
1692
|
|
|
|
|
|
|
=head1 UntaggedResponse |
1693
|
|
|
|
|
|
|
|
1694
|
|
|
|
|
|
|
This class is common to all untagged server responses. |
1695
|
|
|
|
|
|
|
|
1696
|
|
|
|
|
|
|
=head2 tag |
1697
|
|
|
|
|
|
|
|
1698
|
|
|
|
|
|
|
Returns a string containing the tag associated with the response. In |
1699
|
|
|
|
|
|
|
the case of untagged responses, this is always C<*>. |
1700
|
|
|
|
|
|
|
|
1701
|
|
|
|
|
|
|
=head2 is_tagged |
1702
|
|
|
|
|
|
|
|
1703
|
|
|
|
|
|
|
Returns a boolean value indicating whether the response is tagged. |
1704
|
|
|
|
|
|
|
Obviously, in the case of untagged responses, this value is always |
1705
|
|
|
|
|
|
|
C<0>. |
1706
|
|
|
|
|
|
|
|
1707
|
|
|
|
|
|
|
=head2 parent |
1708
|
|
|
|
|
|
|
|
1709
|
|
|
|
|
|
|
Returns a reference to the parent IMAP object. |
1710
|
|
|
|
|
|
|
|
1711
|
|
|
|
|
|
|
=cut |
1712
|
|
|
|
|
|
|
|
1713
|
|
|
|
|
|
|
package Net::IMAP::UntaggedResponse; |
1714
|
|
|
|
|
|
|
|
1715
|
|
|
|
|
|
|
sub tag { '*' } |
1716
|
|
|
|
|
|
|
sub is_tagged { 0 } |
1717
|
|
|
|
|
|
|
sub parent { $_[0]->{Parent} } |
1718
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1719
|
|
|
|
|
|
|
package Net::IMAP::Cond; |
1720
|
|
|
|
|
|
|
use vars qw(@ISA); |
1721
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
1722
|
|
|
|
|
|
|
use Carp; |
1723
|
|
|
|
|
|
|
|
1724
|
|
|
|
|
|
|
sub new { |
1725
|
|
|
|
|
|
|
my $class = shift; |
1726
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
1727
|
|
|
|
|
|
|
my $parent = shift; |
1728
|
|
|
|
|
|
|
my $str = shift; |
1729
|
|
|
|
|
|
|
|
1730
|
|
|
|
|
|
|
my $self = {}; |
1731
|
|
|
|
|
|
|
|
1732
|
|
|
|
|
|
|
bless $self, $class; |
1733
|
|
|
|
|
|
|
|
1734
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
1735
|
|
|
|
|
|
|
|
1736
|
|
|
|
|
|
|
my $resp_code = undef; |
1737
|
|
|
|
|
|
|
|
1738
|
|
|
|
|
|
|
if (substr($str, 0, 1) eq '[') { |
1739
|
|
|
|
|
|
|
($resp_code, $str) = Net::IMAP::_extract_resp_code($str); |
1740
|
|
|
|
|
|
|
} |
1741
|
|
|
|
|
|
|
$self->{RespCode} = $resp_code; |
1742
|
|
|
|
|
|
|
$self->{Text} = $str; |
1743
|
|
|
|
|
|
|
|
1744
|
|
|
|
|
|
|
carp "Alert: $str\n" if (defined($resp_code) && $resp_code->[0] eq 'alert'); |
1745
|
|
|
|
|
|
|
|
1746
|
|
|
|
|
|
|
if (($self->name eq 'bye') && !$self->parent->{Disconnect}) { |
1747
|
|
|
|
|
|
|
# a logout command wasn't issued, so it's probably the result of |
1748
|
|
|
|
|
|
|
# an autologout timer expiring |
1749
|
|
|
|
|
|
|
$self->parent->close_connection or carp "error closing connection: $!"; |
1750
|
|
|
|
|
|
|
} |
1751
|
|
|
|
|
|
|
|
1752
|
|
|
|
|
|
|
return $self; |
1753
|
|
|
|
|
|
|
} |
1754
|
|
|
|
|
|
|
|
1755
|
|
|
|
|
|
|
sub code { $_[0]->{RespCode} } |
1756
|
|
|
|
|
|
|
|
1757
|
|
|
|
|
|
|
sub name { undef } |
1758
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1759
|
|
|
|
|
|
|
|
1760
|
|
|
|
|
|
|
=head1 Ok |
1761
|
|
|
|
|
|
|
|
1762
|
|
|
|
|
|
|
This is a container for untagged C responses from the server. |
1763
|
|
|
|
|
|
|
|
1764
|
|
|
|
|
|
|
=head2 code |
1765
|
|
|
|
|
|
|
|
1766
|
|
|
|
|
|
|
Returns a list reference containing response code elements in the |
1767
|
|
|
|
|
|
|
response. Returns C if no response code is present. |
1768
|
|
|
|
|
|
|
|
1769
|
|
|
|
|
|
|
=head2 name |
1770
|
|
|
|
|
|
|
|
1771
|
|
|
|
|
|
|
Returns the name of the response. In the case of C, this returns |
1772
|
|
|
|
|
|
|
'ok'. This method is provided as a convenience for end-programmers |
1773
|
|
|
|
|
|
|
wanting to write one common subroutine for one or more of the |
1774
|
|
|
|
|
|
|
responses C, C, C, and C. |
1775
|
|
|
|
|
|
|
|
1776
|
|
|
|
|
|
|
=cut |
1777
|
|
|
|
|
|
|
|
1778
|
|
|
|
|
|
|
package Net::IMAP::Ok; |
1779
|
|
|
|
|
|
|
use vars qw(@ISA); |
1780
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::Cond); |
1781
|
|
|
|
|
|
|
sub name { 'ok' }; |
1782
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1783
|
|
|
|
|
|
|
|
1784
|
|
|
|
|
|
|
=head1 No |
1785
|
|
|
|
|
|
|
|
1786
|
|
|
|
|
|
|
This is a container for untagged C responses from the server. |
1787
|
|
|
|
|
|
|
|
1788
|
|
|
|
|
|
|
=cut |
1789
|
|
|
|
|
|
|
|
1790
|
|
|
|
|
|
|
package Net::IMAP::No; |
1791
|
|
|
|
|
|
|
use vars qw(@ISA); |
1792
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::Cond); |
1793
|
|
|
|
|
|
|
sub name { 'no' }; |
1794
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1795
|
|
|
|
|
|
|
|
1796
|
|
|
|
|
|
|
=head1 Bad |
1797
|
|
|
|
|
|
|
|
1798
|
|
|
|
|
|
|
This is a container for untagged C responses from the server. |
1799
|
|
|
|
|
|
|
|
1800
|
|
|
|
|
|
|
=cut |
1801
|
|
|
|
|
|
|
|
1802
|
|
|
|
|
|
|
package Net::IMAP::Bad; |
1803
|
|
|
|
|
|
|
use vars qw(@ISA); |
1804
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::Cond); |
1805
|
|
|
|
|
|
|
sub name { 'bad' }; |
1806
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1807
|
|
|
|
|
|
|
|
1808
|
|
|
|
|
|
|
=head1 Bye |
1809
|
|
|
|
|
|
|
|
1810
|
|
|
|
|
|
|
This is a container for untagged C responses from the server. |
1811
|
|
|
|
|
|
|
|
1812
|
|
|
|
|
|
|
=cut |
1813
|
|
|
|
|
|
|
|
1814
|
|
|
|
|
|
|
package Net::IMAP::Bye; |
1815
|
|
|
|
|
|
|
use vars qw(@ISA); |
1816
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::Cond); |
1817
|
|
|
|
|
|
|
sub name { 'bye' }; |
1818
|
|
|
|
|
|
|
############################################################################### |
1819
|
|
|
|
|
|
|
|
1820
|
|
|
|
|
|
|
=head1 Expunge |
1821
|
|
|
|
|
|
|
|
1822
|
|
|
|
|
|
|
This is a container for C responses from the server. |
1823
|
|
|
|
|
|
|
|
1824
|
|
|
|
|
|
|
The information returned by C is automatically updated |
1825
|
|
|
|
|
|
|
when C responses are received. |
1826
|
|
|
|
|
|
|
|
1827
|
|
|
|
|
|
|
=head2 msgnum |
1828
|
|
|
|
|
|
|
|
1829
|
|
|
|
|
|
|
Returns the message number specified in the C response. |
1830
|
|
|
|
|
|
|
|
1831
|
|
|
|
|
|
|
=cut |
1832
|
|
|
|
|
|
|
|
1833
|
|
|
|
|
|
|
package Net::IMAP::Expunge; |
1834
|
|
|
|
|
|
|
use vars qw(@ISA); |
1835
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
1836
|
|
|
|
|
|
|
|
1837
|
|
|
|
|
|
|
sub name { 'expunge' } |
1838
|
|
|
|
|
|
|
|
1839
|
|
|
|
|
|
|
sub new { |
1840
|
|
|
|
|
|
|
my $class = shift; |
1841
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
1842
|
|
|
|
|
|
|
my $parent = shift; |
1843
|
|
|
|
|
|
|
my $str = shift; |
1844
|
|
|
|
|
|
|
|
1845
|
|
|
|
|
|
|
my $self = {}; |
1846
|
|
|
|
|
|
|
|
1847
|
|
|
|
|
|
|
bless $self, $class; |
1848
|
|
|
|
|
|
|
|
1849
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
1850
|
|
|
|
|
|
|
|
1851
|
|
|
|
|
|
|
$self->{Msgnum} = $str; |
1852
|
|
|
|
|
|
|
|
1853
|
|
|
|
|
|
|
return $self; |
1854
|
|
|
|
|
|
|
} |
1855
|
|
|
|
|
|
|
|
1856
|
|
|
|
|
|
|
sub msgnum { $_->{Msgnum} } |
1857
|
|
|
|
|
|
|
|
1858
|
|
|
|
|
|
|
############################################################################### |
1859
|
|
|
|
|
|
|
|
1860
|
|
|
|
|
|
|
=head1 Capability |
1861
|
|
|
|
|
|
|
|
1862
|
|
|
|
|
|
|
This is a container for C responses. |
1863
|
|
|
|
|
|
|
|
1864
|
|
|
|
|
|
|
=head2 capabilities |
1865
|
|
|
|
|
|
|
|
1866
|
|
|
|
|
|
|
Returns the list of capabilities supported by the server, minus the |
1867
|
|
|
|
|
|
|
authentication capabilities. The list is not guaranteed to be in any |
1868
|
|
|
|
|
|
|
specific order. |
1869
|
|
|
|
|
|
|
|
1870
|
|
|
|
|
|
|
=head2 has_capability $capname |
1871
|
|
|
|
|
|
|
|
1872
|
|
|
|
|
|
|
Returns a boolean value indicating whether the server supports the |
1873
|
|
|
|
|
|
|
specified capability. |
1874
|
|
|
|
|
|
|
|
1875
|
|
|
|
|
|
|
=head2 authtypes |
1876
|
|
|
|
|
|
|
|
1877
|
|
|
|
|
|
|
Returns a list of authentication types supported by the server. |
1878
|
|
|
|
|
|
|
|
1879
|
|
|
|
|
|
|
=head2 has_authtype $authname |
1880
|
|
|
|
|
|
|
|
1881
|
|
|
|
|
|
|
Returns a boolean value indicating whether the server supports the |
1882
|
|
|
|
|
|
|
specified authentication type. |
1883
|
|
|
|
|
|
|
|
1884
|
|
|
|
|
|
|
=cut |
1885
|
|
|
|
|
|
|
|
1886
|
|
|
|
|
|
|
package Net::IMAP::Capability; |
1887
|
|
|
|
|
|
|
use vars qw(@ISA); |
1888
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
1889
|
|
|
|
|
|
|
|
1890
|
|
|
|
|
|
|
sub name { 'capability' } |
1891
|
|
|
|
|
|
|
|
1892
|
|
|
|
|
|
|
sub new { |
1893
|
|
|
|
|
|
|
my $class = shift; |
1894
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
1895
|
|
|
|
|
|
|
my $parent = shift; |
1896
|
|
|
|
|
|
|
my $str = shift; |
1897
|
|
|
|
|
|
|
|
1898
|
|
|
|
|
|
|
my $self = {}; |
1899
|
|
|
|
|
|
|
|
1900
|
|
|
|
|
|
|
bless $self, $class; |
1901
|
|
|
|
|
|
|
|
1902
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
1903
|
|
|
|
|
|
|
|
1904
|
|
|
|
|
|
|
undef $self->{Parent}{Capabilities}; # needs to be repopulated each time |
1905
|
|
|
|
|
|
|
undef $self->{Parent}{AuthTypes}; # needs to be repopulated each time |
1906
|
|
|
|
|
|
|
|
1907
|
|
|
|
|
|
|
for my $cap (split(/\s/, $str)) { |
1908
|
|
|
|
|
|
|
$cap = uc($cap); |
1909
|
|
|
|
|
|
|
$self->{Parent}{Capabilities}{$cap}++; |
1910
|
|
|
|
|
|
|
$self->{Parent}{AuthTypes}{$1}++ if $cap =~ /^AUTH=(.*)$/; |
1911
|
|
|
|
|
|
|
$self->{Capabilities}{$cap}++; |
1912
|
|
|
|
|
|
|
$self->{AuthTypes}{$1}++ if $cap =~ /^AUTH=(.*)$/; |
1913
|
|
|
|
|
|
|
} |
1914
|
|
|
|
|
|
|
|
1915
|
|
|
|
|
|
|
# force the non-synchronous literals option off if the server |
1916
|
|
|
|
|
|
|
# doesn't support it |
1917
|
|
|
|
|
|
|
$self->{Parent}{Options}{NonSyncLits} = 0 |
1918
|
|
|
|
|
|
|
unless defined($self->{Parent}{Capabilities}{'LITERAL+'}); |
1919
|
|
|
|
|
|
|
|
1920
|
|
|
|
|
|
|
return $self; |
1921
|
|
|
|
|
|
|
} |
1922
|
|
|
|
|
|
|
|
1923
|
|
|
|
|
|
|
sub capabilities { keys %{$_[0]->{Capabilities}} } |
1924
|
|
|
|
|
|
|
|
1925
|
|
|
|
|
|
|
sub has_capability { defined($_[0]->{Capabilities}{uc($_[1])}) } |
1926
|
|
|
|
|
|
|
|
1927
|
|
|
|
|
|
|
sub authtypes { keys %{$_[0]->{AuthTypes}} } |
1928
|
|
|
|
|
|
|
|
1929
|
|
|
|
|
|
|
sub has_authtype { defined($_[0]->{AuthTypes}{uc($_[1])}) } |
1930
|
|
|
|
|
|
|
|
1931
|
|
|
|
|
|
|
############################################################################### |
1932
|
|
|
|
|
|
|
|
1933
|
|
|
|
|
|
|
=head1 List |
1934
|
|
|
|
|
|
|
|
1935
|
|
|
|
|
|
|
This is a container for C responses. |
1936
|
|
|
|
|
|
|
|
1937
|
|
|
|
|
|
|
=head2 mailbox |
1938
|
|
|
|
|
|
|
|
1939
|
|
|
|
|
|
|
Returns the name of the mailbox contained in the object. |
1940
|
|
|
|
|
|
|
|
1941
|
|
|
|
|
|
|
=head2 delimiter |
1942
|
|
|
|
|
|
|
|
1943
|
|
|
|
|
|
|
Returns the hierarchy delimiter associated with the mailbox. |
1944
|
|
|
|
|
|
|
|
1945
|
|
|
|
|
|
|
=head2 flags |
1946
|
|
|
|
|
|
|
|
1947
|
|
|
|
|
|
|
Returns a list of the flags associated with the mailbox. |
1948
|
|
|
|
|
|
|
|
1949
|
|
|
|
|
|
|
=head2 has_flag $flag |
1950
|
|
|
|
|
|
|
|
1951
|
|
|
|
|
|
|
Returns a boolean value indicating whether the given $flag is defined |
1952
|
|
|
|
|
|
|
for the mailbox. |
1953
|
|
|
|
|
|
|
|
1954
|
|
|
|
|
|
|
=cut |
1955
|
|
|
|
|
|
|
|
1956
|
|
|
|
|
|
|
package Net::IMAP::List; |
1957
|
|
|
|
|
|
|
use vars qw(@ISA); |
1958
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
1959
|
|
|
|
|
|
|
|
1960
|
|
|
|
|
|
|
sub name { 'list' } |
1961
|
|
|
|
|
|
|
|
1962
|
|
|
|
|
|
|
sub new { |
1963
|
|
|
|
|
|
|
my $class = shift; |
1964
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
1965
|
|
|
|
|
|
|
my $parent = shift; |
1966
|
|
|
|
|
|
|
my $str = shift; |
1967
|
|
|
|
|
|
|
|
1968
|
|
|
|
|
|
|
my $self = {}; |
1969
|
|
|
|
|
|
|
|
1970
|
|
|
|
|
|
|
bless $self, $class; |
1971
|
|
|
|
|
|
|
|
1972
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
1973
|
|
|
|
|
|
|
|
1974
|
|
|
|
|
|
|
my $fields = Net::xAP->parse_fields($str); |
1975
|
|
|
|
|
|
|
for my $flag (@{$fields->[0]}) { |
1976
|
|
|
|
|
|
|
$self->{Flags}{lc($flag)}++; |
1977
|
|
|
|
|
|
|
} |
1978
|
|
|
|
|
|
|
$self->{Delim} = $fields->[1]; |
1979
|
|
|
|
|
|
|
$self->{Mailbox} = Net::IMAP::_decode_mailbox($fields->[2]); |
1980
|
|
|
|
|
|
|
|
1981
|
|
|
|
|
|
|
return $self; |
1982
|
|
|
|
|
|
|
} |
1983
|
|
|
|
|
|
|
|
1984
|
|
|
|
|
|
|
sub mailbox { $_[0]->{Mailbox} } |
1985
|
|
|
|
|
|
|
sub delimiter { $_[0]->{Delim} } |
1986
|
|
|
|
|
|
|
sub flags { keys %{$_[0]->{Flags}} } |
1987
|
|
|
|
|
|
|
sub has_flag { defined($_[0]->{Flags}{lc($_[1])}) } |
1988
|
|
|
|
|
|
|
|
1989
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
1990
|
|
|
|
|
|
|
|
1991
|
|
|
|
|
|
|
=head1 List |
1992
|
|
|
|
|
|
|
|
1993
|
|
|
|
|
|
|
This is a container for C responses. It provides the same |
1994
|
|
|
|
|
|
|
interface as the C class. |
1995
|
|
|
|
|
|
|
|
1996
|
|
|
|
|
|
|
=cut |
1997
|
|
|
|
|
|
|
|
1998
|
|
|
|
|
|
|
package Net::IMAP::Lsub; |
1999
|
|
|
|
|
|
|
use vars qw(@ISA); |
2000
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::List); |
2001
|
|
|
|
|
|
|
|
2002
|
|
|
|
|
|
|
sub name { 'lsub' } |
2003
|
|
|
|
|
|
|
|
2004
|
|
|
|
|
|
|
############################################################################### |
2005
|
|
|
|
|
|
|
|
2006
|
|
|
|
|
|
|
=head1 Fetch |
2007
|
|
|
|
|
|
|
|
2008
|
|
|
|
|
|
|
This is a container for C responses. |
2009
|
|
|
|
|
|
|
|
2010
|
|
|
|
|
|
|
Responses for partial fetches bear special mention. While both the |
2011
|
|
|
|
|
|
|
starting byte and quantity of bytes are specified when doing partial |
2012
|
|
|
|
|
|
|
fetches with the C command, the corresponding response will |
2013
|
|
|
|
|
|
|
only show the starting byte. In other words, the command |
2014
|
|
|
|
|
|
|
C<$imap-Efetch(1, 'body[]E0.1024E'> will, if successful, |
2015
|
|
|
|
|
|
|
result in a fetch response item of C0E> containing a |
2016
|
|
|
|
|
|
|
1024 octet value. To match a given response for a partial fetch, you |
2017
|
|
|
|
|
|
|
might need to use C to match it up with the corresponding item |
2018
|
|
|
|
|
|
|
specified in the C command. |
2019
|
|
|
|
|
|
|
|
2020
|
|
|
|
|
|
|
=head2 msgnum |
2021
|
|
|
|
|
|
|
|
2022
|
|
|
|
|
|
|
Returns the message number identified in the response. |
2023
|
|
|
|
|
|
|
|
2024
|
|
|
|
|
|
|
=head2 items |
2025
|
|
|
|
|
|
|
|
2026
|
|
|
|
|
|
|
Returns the list of data item names contained in the response. The |
2027
|
|
|
|
|
|
|
list is not guaranteed to be in any specific order. |
2028
|
|
|
|
|
|
|
|
2029
|
|
|
|
|
|
|
=head2 item $item |
2030
|
|
|
|
|
|
|
|
2031
|
|
|
|
|
|
|
Returns the data associated with the specified data item. |
2032
|
|
|
|
|
|
|
|
2033
|
|
|
|
|
|
|
The following list enumerates the data types associated with each |
2034
|
|
|
|
|
|
|
fetch item: |
2035
|
|
|
|
|
|
|
|
2036
|
|
|
|
|
|
|
=over 14 |
2037
|
|
|
|
|
|
|
|
2038
|
|
|
|
|
|
|
=item envelope |
2039
|
|
|
|
|
|
|
|
2040
|
|
|
|
|
|
|
Net::IMAP::Envelope |
2041
|
|
|
|
|
|
|
|
2042
|
|
|
|
|
|
|
=item bodystructure |
2043
|
|
|
|
|
|
|
|
2044
|
|
|
|
|
|
|
Net::IMAP::BodyStructure |
2045
|
|
|
|
|
|
|
|
2046
|
|
|
|
|
|
|
=item body |
2047
|
|
|
|
|
|
|
|
2048
|
|
|
|
|
|
|
Net::IMAP::BodyStructure |
2049
|
|
|
|
|
|
|
|
2050
|
|
|
|
|
|
|
=item flags |
2051
|
|
|
|
|
|
|
|
2052
|
|
|
|
|
|
|
Net::IMAP::Flags |
2053
|
|
|
|
|
|
|
|
2054
|
|
|
|
|
|
|
=item UID |
2055
|
|
|
|
|
|
|
|
2056
|
|
|
|
|
|
|
Integer |
2057
|
|
|
|
|
|
|
|
2058
|
|
|
|
|
|
|
=item rfc822.size |
2059
|
|
|
|
|
|
|
|
2060
|
|
|
|
|
|
|
Integer |
2061
|
|
|
|
|
|
|
|
2062
|
|
|
|
|
|
|
=item I |
2063
|
|
|
|
|
|
|
|
2064
|
|
|
|
|
|
|
String |
2065
|
|
|
|
|
|
|
|
2066
|
|
|
|
|
|
|
=back |
2067
|
|
|
|
|
|
|
|
2068
|
|
|
|
|
|
|
=cut |
2069
|
|
|
|
|
|
|
|
2070
|
|
|
|
|
|
|
package Net::IMAP::Fetch; |
2071
|
|
|
|
|
|
|
use vars qw(@ISA); |
2072
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2073
|
|
|
|
|
|
|
|
2074
|
|
|
|
|
|
|
sub name { 'fetch' } |
2075
|
|
|
|
|
|
|
|
2076
|
|
|
|
|
|
|
sub new { |
2077
|
|
|
|
|
|
|
my $class = shift; |
2078
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2079
|
|
|
|
|
|
|
my $parent = shift; |
2080
|
|
|
|
|
|
|
my $msgnum = shift; |
2081
|
|
|
|
|
|
|
my $str = shift; |
2082
|
|
|
|
|
|
|
|
2083
|
|
|
|
|
|
|
my $self = {}; |
2084
|
|
|
|
|
|
|
|
2085
|
|
|
|
|
|
|
bless $self, $class; |
2086
|
|
|
|
|
|
|
|
2087
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2088
|
|
|
|
|
|
|
|
2089
|
|
|
|
|
|
|
$self->{Msgnum} = $msgnum; |
2090
|
|
|
|
|
|
|
|
2091
|
|
|
|
|
|
|
my %hash = @{Net::xAP->parse_fields($str)->[0]}; |
2092
|
|
|
|
|
|
|
for my $key (keys %hash) { |
2093
|
|
|
|
|
|
|
my $lckey = lc($key); |
2094
|
|
|
|
|
|
|
print "$lckey $hash{$key}\n"; |
2095
|
|
|
|
|
|
|
if ($lckey eq 'envelope') { |
2096
|
|
|
|
|
|
|
$self->{Items}{$lckey} = Net::IMAP::Envelope->new($hash{$key}); |
2097
|
|
|
|
|
|
|
} elsif (($lckey eq 'bodystructure') || ($lckey eq 'body')) { |
2098
|
|
|
|
|
|
|
$self->{Items}{$lckey} = Net::IMAP::BodyStructure->new($hash{$key}); |
2099
|
|
|
|
|
|
|
} elsif ($lckey eq 'flags') { |
2100
|
|
|
|
|
|
|
$self->{Items}{$lckey} = Net::IMAP::Flags->new($parent); |
2101
|
|
|
|
|
|
|
for my $flag (@{$hash{$key}}) { |
2102
|
|
|
|
|
|
|
$self->{Items}{$lckey}{Flags}{lc($flag)}++; |
2103
|
|
|
|
|
|
|
} |
2104
|
|
|
|
|
|
|
} else { |
2105
|
|
|
|
|
|
|
if ($self->{Parent}{Options}{EOL} eq 'lf') { |
2106
|
|
|
|
|
|
|
if ((substr($lckey, 0, 5) eq 'body[') |
2107
|
|
|
|
|
|
|
|| ($lckey eq 'rfc822') |
2108
|
|
|
|
|
|
|
|| ($lckey eq 'rfc822.header') |
2109
|
|
|
|
|
|
|
|| ($lckey eq 'rfc822.text')) { |
2110
|
|
|
|
|
|
|
$hash{$key} =~ s/\r\n/\n/mg; |
2111
|
|
|
|
|
|
|
} |
2112
|
|
|
|
|
|
|
} |
2113
|
|
|
|
|
|
|
$self->{Items}{$lckey} = $hash{$key}; |
2114
|
|
|
|
|
|
|
} |
2115
|
|
|
|
|
|
|
} |
2116
|
|
|
|
|
|
|
|
2117
|
|
|
|
|
|
|
return $self; |
2118
|
|
|
|
|
|
|
} |
2119
|
|
|
|
|
|
|
|
2120
|
|
|
|
|
|
|
sub msgnum { $_[0]->{Msgnum} } |
2121
|
|
|
|
|
|
|
sub items { keys %{$_[0]->{Items}} } |
2122
|
|
|
|
|
|
|
sub item { $_[0]->{Items}{lc($_[1])} } |
2123
|
|
|
|
|
|
|
|
2124
|
|
|
|
|
|
|
############################################################################### |
2125
|
|
|
|
|
|
|
|
2126
|
|
|
|
|
|
|
=head1 Status |
2127
|
|
|
|
|
|
|
|
2128
|
|
|
|
|
|
|
This is a container for C responses. |
2129
|
|
|
|
|
|
|
|
2130
|
|
|
|
|
|
|
=head2 mailbox |
2131
|
|
|
|
|
|
|
|
2132
|
|
|
|
|
|
|
Returns a string containing the mailbox the status information is |
2133
|
|
|
|
|
|
|
associated with. |
2134
|
|
|
|
|
|
|
|
2135
|
|
|
|
|
|
|
=head2 items |
2136
|
|
|
|
|
|
|
|
2137
|
|
|
|
|
|
|
Returns the list of status items contains in the status response. |
2138
|
|
|
|
|
|
|
|
2139
|
|
|
|
|
|
|
=head2 item $item |
2140
|
|
|
|
|
|
|
|
2141
|
|
|
|
|
|
|
Returns the value of the C<$item> status item. |
2142
|
|
|
|
|
|
|
|
2143
|
|
|
|
|
|
|
=cut |
2144
|
|
|
|
|
|
|
|
2145
|
|
|
|
|
|
|
package Net::IMAP::Status; |
2146
|
|
|
|
|
|
|
use vars qw(@ISA); |
2147
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2148
|
|
|
|
|
|
|
|
2149
|
|
|
|
|
|
|
sub name { 'status' } |
2150
|
|
|
|
|
|
|
|
2151
|
|
|
|
|
|
|
sub new { |
2152
|
|
|
|
|
|
|
my $class = shift; |
2153
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2154
|
|
|
|
|
|
|
my $parent = shift; |
2155
|
|
|
|
|
|
|
my $str = shift; |
2156
|
|
|
|
|
|
|
|
2157
|
|
|
|
|
|
|
my $self = {}; |
2158
|
|
|
|
|
|
|
|
2159
|
|
|
|
|
|
|
bless $self, $class; |
2160
|
|
|
|
|
|
|
|
2161
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2162
|
|
|
|
|
|
|
|
2163
|
|
|
|
|
|
|
my $fields = Net::xAP->parse_fields($str); |
2164
|
|
|
|
|
|
|
$self->{Mailbox} = Net::IMAP::_decode_mailbox($fields->[0]); |
2165
|
|
|
|
|
|
|
my %hash = @{$fields->[1]}; |
2166
|
|
|
|
|
|
|
for my $key (keys %hash) { |
2167
|
|
|
|
|
|
|
$self->{Items}{lc($key)} = $hash{$key}; |
2168
|
|
|
|
|
|
|
} |
2169
|
|
|
|
|
|
|
|
2170
|
|
|
|
|
|
|
return $self; |
2171
|
|
|
|
|
|
|
} |
2172
|
|
|
|
|
|
|
|
2173
|
|
|
|
|
|
|
sub mailbox { $_[0]->{Mailbox} } |
2174
|
|
|
|
|
|
|
sub items { keys %{$_[0]->{Items}} } |
2175
|
|
|
|
|
|
|
sub item { $_[0]->{Items}{lc($_[1])} } |
2176
|
|
|
|
|
|
|
|
2177
|
|
|
|
|
|
|
############################################################################### |
2178
|
|
|
|
|
|
|
|
2179
|
|
|
|
|
|
|
=head1 Search |
2180
|
|
|
|
|
|
|
|
2181
|
|
|
|
|
|
|
This is a container for C responses. |
2182
|
|
|
|
|
|
|
|
2183
|
|
|
|
|
|
|
=head2 msgnums |
2184
|
|
|
|
|
|
|
|
2185
|
|
|
|
|
|
|
Returns the list of message numbers contained in the response. |
2186
|
|
|
|
|
|
|
|
2187
|
|
|
|
|
|
|
=cut |
2188
|
|
|
|
|
|
|
|
2189
|
|
|
|
|
|
|
package Net::IMAP::Search; |
2190
|
|
|
|
|
|
|
use vars qw(@ISA); |
2191
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2192
|
|
|
|
|
|
|
|
2193
|
|
|
|
|
|
|
sub name { 'search' } |
2194
|
|
|
|
|
|
|
|
2195
|
|
|
|
|
|
|
sub new { |
2196
|
|
|
|
|
|
|
my $class = shift; |
2197
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2198
|
|
|
|
|
|
|
my $parent = shift; |
2199
|
|
|
|
|
|
|
my $str = shift; |
2200
|
|
|
|
|
|
|
|
2201
|
|
|
|
|
|
|
my $self = {}; |
2202
|
|
|
|
|
|
|
|
2203
|
|
|
|
|
|
|
bless $self, $class; |
2204
|
|
|
|
|
|
|
|
2205
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2206
|
|
|
|
|
|
|
|
2207
|
|
|
|
|
|
|
for my $item (split(/\s/, $str)) { |
2208
|
|
|
|
|
|
|
$self->{Msgnums}{$item}++; |
2209
|
|
|
|
|
|
|
} |
2210
|
|
|
|
|
|
|
|
2211
|
|
|
|
|
|
|
return $self; |
2212
|
|
|
|
|
|
|
} |
2213
|
|
|
|
|
|
|
|
2214
|
|
|
|
|
|
|
sub msgnums { keys %{$_[0]->{Msgnums}} } |
2215
|
|
|
|
|
|
|
|
2216
|
|
|
|
|
|
|
############################################################################### |
2217
|
|
|
|
|
|
|
|
2218
|
|
|
|
|
|
|
=head1 Flags |
2219
|
|
|
|
|
|
|
|
2220
|
|
|
|
|
|
|
This is a container for C responses. |
2221
|
|
|
|
|
|
|
|
2222
|
|
|
|
|
|
|
=head2 flags |
2223
|
|
|
|
|
|
|
|
2224
|
|
|
|
|
|
|
Returns the list of flags contained in the response. |
2225
|
|
|
|
|
|
|
|
2226
|
|
|
|
|
|
|
=head2 has_flag $flag |
2227
|
|
|
|
|
|
|
|
2228
|
|
|
|
|
|
|
Returns a boolean value indicating whether the specified flag is |
2229
|
|
|
|
|
|
|
contained in the response. |
2230
|
|
|
|
|
|
|
|
2231
|
|
|
|
|
|
|
As a convenience, the information from the C response is also |
2232
|
|
|
|
|
|
|
stored in the parent C object, and is available via |
2233
|
|
|
|
|
|
|
C versions of the C and C methods. |
2234
|
|
|
|
|
|
|
|
2235
|
|
|
|
|
|
|
=cut |
2236
|
|
|
|
|
|
|
|
2237
|
|
|
|
|
|
|
package Net::IMAP::Flags; |
2238
|
|
|
|
|
|
|
use vars qw(@ISA); |
2239
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2240
|
|
|
|
|
|
|
|
2241
|
|
|
|
|
|
|
sub name { 'flags' } |
2242
|
|
|
|
|
|
|
|
2243
|
|
|
|
|
|
|
sub new { |
2244
|
|
|
|
|
|
|
my $class = shift; |
2245
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2246
|
|
|
|
|
|
|
my $parent = shift; |
2247
|
|
|
|
|
|
|
my $str = shift; |
2248
|
|
|
|
|
|
|
|
2249
|
|
|
|
|
|
|
my $self = {}; |
2250
|
|
|
|
|
|
|
|
2251
|
|
|
|
|
|
|
bless $self, $class; |
2252
|
|
|
|
|
|
|
|
2253
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2254
|
|
|
|
|
|
|
|
2255
|
|
|
|
|
|
|
if (defined($str)) { |
2256
|
|
|
|
|
|
|
for my $flag (@{Net::xAP->parse_fields($str)->[0]}) { |
2257
|
|
|
|
|
|
|
$self->{Flags}{lc($flag)}++; |
2258
|
|
|
|
|
|
|
$self->{Parent}{MailboxStatus}{'flags'}{lc($flag)}++; |
2259
|
|
|
|
|
|
|
} |
2260
|
|
|
|
|
|
|
} |
2261
|
|
|
|
|
|
|
|
2262
|
|
|
|
|
|
|
return $self; |
2263
|
|
|
|
|
|
|
} |
2264
|
|
|
|
|
|
|
|
2265
|
|
|
|
|
|
|
sub flags { keys %{$_[0]->{Flags}} } |
2266
|
|
|
|
|
|
|
sub has_flag { defined($_[0]->{Flags}{lc($_[1])}) } |
2267
|
|
|
|
|
|
|
|
2268
|
|
|
|
|
|
|
############################################################################### |
2269
|
|
|
|
|
|
|
|
2270
|
|
|
|
|
|
|
=head1 Exists |
2271
|
|
|
|
|
|
|
|
2272
|
|
|
|
|
|
|
This is a container for C responses. |
2273
|
|
|
|
|
|
|
|
2274
|
|
|
|
|
|
|
=head2 exists |
2275
|
|
|
|
|
|
|
|
2276
|
|
|
|
|
|
|
Returns the quantity of messages in the currently selected mailbox. |
2277
|
|
|
|
|
|
|
|
2278
|
|
|
|
|
|
|
This is information is also available in the C method in |
2279
|
|
|
|
|
|
|
the C class. |
2280
|
|
|
|
|
|
|
|
2281
|
|
|
|
|
|
|
=cut |
2282
|
|
|
|
|
|
|
|
2283
|
|
|
|
|
|
|
package Net::IMAP::Exists; |
2284
|
|
|
|
|
|
|
use vars qw(@ISA); |
2285
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2286
|
|
|
|
|
|
|
|
2287
|
|
|
|
|
|
|
sub name { 'exists' } |
2288
|
|
|
|
|
|
|
|
2289
|
|
|
|
|
|
|
sub new { |
2290
|
|
|
|
|
|
|
my $class = shift; |
2291
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2292
|
|
|
|
|
|
|
my $parent = shift; |
2293
|
|
|
|
|
|
|
my $str = shift; |
2294
|
|
|
|
|
|
|
|
2295
|
|
|
|
|
|
|
my $self = {}; |
2296
|
|
|
|
|
|
|
|
2297
|
|
|
|
|
|
|
bless $self, $class; |
2298
|
|
|
|
|
|
|
|
2299
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2300
|
|
|
|
|
|
|
|
2301
|
|
|
|
|
|
|
$self->{Parent}{MailboxStatus}{'exists'} = $str; |
2302
|
|
|
|
|
|
|
$self->{Value} = $str; |
2303
|
|
|
|
|
|
|
|
2304
|
|
|
|
|
|
|
return $self; |
2305
|
|
|
|
|
|
|
} |
2306
|
|
|
|
|
|
|
|
2307
|
|
|
|
|
|
|
sub exists { $_[0]->{Value} } |
2308
|
|
|
|
|
|
|
|
2309
|
|
|
|
|
|
|
############################################################################### |
2310
|
|
|
|
|
|
|
|
2311
|
|
|
|
|
|
|
=head1 Recent |
2312
|
|
|
|
|
|
|
|
2313
|
|
|
|
|
|
|
This is a container for C responses. |
2314
|
|
|
|
|
|
|
|
2315
|
|
|
|
|
|
|
=head2 recent |
2316
|
|
|
|
|
|
|
|
2317
|
|
|
|
|
|
|
Returns the number of messages with the C<\recent> flag set. |
2318
|
|
|
|
|
|
|
|
2319
|
|
|
|
|
|
|
This information is also available in the C method in the |
2320
|
|
|
|
|
|
|
C class. |
2321
|
|
|
|
|
|
|
|
2322
|
|
|
|
|
|
|
=cut |
2323
|
|
|
|
|
|
|
|
2324
|
|
|
|
|
|
|
package Net::IMAP::Recent; |
2325
|
|
|
|
|
|
|
use vars qw(@ISA); |
2326
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2327
|
|
|
|
|
|
|
|
2328
|
|
|
|
|
|
|
sub name { 'recent' } |
2329
|
|
|
|
|
|
|
|
2330
|
|
|
|
|
|
|
sub new { |
2331
|
|
|
|
|
|
|
my $class = shift; |
2332
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2333
|
|
|
|
|
|
|
my $parent = shift; |
2334
|
|
|
|
|
|
|
my $str = shift; |
2335
|
|
|
|
|
|
|
|
2336
|
|
|
|
|
|
|
my $self = {}; |
2337
|
|
|
|
|
|
|
|
2338
|
|
|
|
|
|
|
bless $self, $class; |
2339
|
|
|
|
|
|
|
|
2340
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2341
|
|
|
|
|
|
|
|
2342
|
|
|
|
|
|
|
$self->{Parent}{MailboxStatus}{'recent'} = $str; |
2343
|
|
|
|
|
|
|
$self->{Value} = $str; |
2344
|
|
|
|
|
|
|
|
2345
|
|
|
|
|
|
|
return $self; |
2346
|
|
|
|
|
|
|
} |
2347
|
|
|
|
|
|
|
|
2348
|
|
|
|
|
|
|
sub recent { $_[0]->{Value} } |
2349
|
|
|
|
|
|
|
|
2350
|
|
|
|
|
|
|
############################################################################### |
2351
|
|
|
|
|
|
|
|
2352
|
|
|
|
|
|
|
=head1 Namespace |
2353
|
|
|
|
|
|
|
|
2354
|
|
|
|
|
|
|
This is a container for C responses. |
2355
|
|
|
|
|
|
|
|
2356
|
|
|
|
|
|
|
=head2 personal [$namespace] |
2357
|
|
|
|
|
|
|
|
2358
|
|
|
|
|
|
|
With no argument specified, returns a list of personal namespaces. If |
2359
|
|
|
|
|
|
|
C<$namespace> is specified, returns the delimiter character for the |
2360
|
|
|
|
|
|
|
specific personal namespace. |
2361
|
|
|
|
|
|
|
|
2362
|
|
|
|
|
|
|
=head2 other_users [$namespace] |
2363
|
|
|
|
|
|
|
|
2364
|
|
|
|
|
|
|
With no argument specified, returns a list of other users' namespaces. |
2365
|
|
|
|
|
|
|
If C<$namespace> is specified, returns the delimiter character for the |
2366
|
|
|
|
|
|
|
specific other users' namespace. |
2367
|
|
|
|
|
|
|
|
2368
|
|
|
|
|
|
|
=head2 shared [$namespace] |
2369
|
|
|
|
|
|
|
|
2370
|
|
|
|
|
|
|
With no argument specified, returns a list of shared namespaces. If |
2371
|
|
|
|
|
|
|
C<$namespace> is specified, returns the delimiter character for the |
2372
|
|
|
|
|
|
|
specific shared namespace. |
2373
|
|
|
|
|
|
|
|
2374
|
|
|
|
|
|
|
=cut |
2375
|
|
|
|
|
|
|
|
2376
|
|
|
|
|
|
|
package Net::IMAP::Namespace; |
2377
|
|
|
|
|
|
|
use vars qw(@ISA); |
2378
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2379
|
|
|
|
|
|
|
|
2380
|
|
|
|
|
|
|
sub name { 'namespace' } |
2381
|
|
|
|
|
|
|
|
2382
|
|
|
|
|
|
|
my @namespace_types = qw(personal other_users shared); |
2383
|
|
|
|
|
|
|
|
2384
|
|
|
|
|
|
|
sub new { |
2385
|
|
|
|
|
|
|
my $class = shift; |
2386
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2387
|
|
|
|
|
|
|
my $parent = shift; |
2388
|
|
|
|
|
|
|
my $str = shift; |
2389
|
|
|
|
|
|
|
|
2390
|
|
|
|
|
|
|
my $self = {}; |
2391
|
|
|
|
|
|
|
|
2392
|
|
|
|
|
|
|
bless $self, $class; |
2393
|
|
|
|
|
|
|
|
2394
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2395
|
|
|
|
|
|
|
|
2396
|
|
|
|
|
|
|
my $fields = Net::xAP->parse_fields($str); |
2397
|
|
|
|
|
|
|
for my $n (0 .. 2) { |
2398
|
|
|
|
|
|
|
my $field = $fields->[$n]; |
2399
|
|
|
|
|
|
|
for my $item (@{$field}) { |
2400
|
|
|
|
|
|
|
$item->[1] = '' if (lc($item->[1]) eq 'nil'); |
2401
|
|
|
|
|
|
|
$self->{Namespaces}{$namespace_types[$n]}{$item->[0]} = $item->[1]; |
2402
|
|
|
|
|
|
|
} |
2403
|
|
|
|
|
|
|
} |
2404
|
|
|
|
|
|
|
|
2405
|
|
|
|
|
|
|
return $self; |
2406
|
|
|
|
|
|
|
} |
2407
|
|
|
|
|
|
|
|
2408
|
|
|
|
|
|
|
sub personal { |
2409
|
|
|
|
|
|
|
return $_[0]->{Namespaces}{'personal'}{lc($_[1])} if (defined($_[1])); |
2410
|
|
|
|
|
|
|
keys %{$_[0]->{Namespaces}{'personal'}}; |
2411
|
|
|
|
|
|
|
} |
2412
|
|
|
|
|
|
|
|
2413
|
|
|
|
|
|
|
sub other_users { |
2414
|
|
|
|
|
|
|
return $_[0]->{Namespaces}{'other_users'}{lc($_[1])} if (defined($_[1])); |
2415
|
|
|
|
|
|
|
keys %{$_[0]->{Namespaces}{'other_users'}}; |
2416
|
|
|
|
|
|
|
} |
2417
|
|
|
|
|
|
|
|
2418
|
|
|
|
|
|
|
sub shared { |
2419
|
|
|
|
|
|
|
return $_[0]->{Namespaces}{'shared'}{lc($_[1])} if (defined($_[1])); |
2420
|
|
|
|
|
|
|
keys %{$_[0]->{Namespaces}{'shared'}}; |
2421
|
|
|
|
|
|
|
} |
2422
|
|
|
|
|
|
|
|
2423
|
|
|
|
|
|
|
############################################################################### |
2424
|
|
|
|
|
|
|
|
2425
|
|
|
|
|
|
|
=head1 ACL |
2426
|
|
|
|
|
|
|
|
2427
|
|
|
|
|
|
|
This is a container for C responses> |
2428
|
|
|
|
|
|
|
|
2429
|
|
|
|
|
|
|
=head2 mailbox |
2430
|
|
|
|
|
|
|
|
2431
|
|
|
|
|
|
|
Returns the name of the mailbox associated with the given ACL data. |
2432
|
|
|
|
|
|
|
|
2433
|
|
|
|
|
|
|
=head2 identifiers |
2434
|
|
|
|
|
|
|
|
2435
|
|
|
|
|
|
|
Returns a list of identifiers contained in the ACL data. |
2436
|
|
|
|
|
|
|
|
2437
|
|
|
|
|
|
|
=head2 identifier $identifier |
2438
|
|
|
|
|
|
|
|
2439
|
|
|
|
|
|
|
=cut |
2440
|
|
|
|
|
|
|
|
2441
|
|
|
|
|
|
|
package Net::IMAP::Acl; |
2442
|
|
|
|
|
|
|
use vars qw(@ISA); |
2443
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2444
|
|
|
|
|
|
|
|
2445
|
|
|
|
|
|
|
sub name { 'acl' } |
2446
|
|
|
|
|
|
|
|
2447
|
|
|
|
|
|
|
sub new { |
2448
|
|
|
|
|
|
|
my $class = shift; |
2449
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2450
|
|
|
|
|
|
|
my $parent = shift; |
2451
|
|
|
|
|
|
|
my $str = shift; |
2452
|
|
|
|
|
|
|
|
2453
|
|
|
|
|
|
|
my $self = {}; |
2454
|
|
|
|
|
|
|
|
2455
|
|
|
|
|
|
|
bless $self, $class; |
2456
|
|
|
|
|
|
|
|
2457
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2458
|
|
|
|
|
|
|
|
2459
|
|
|
|
|
|
|
my @fields = @{Net::xAP->parse_fields($str)}; |
2460
|
|
|
|
|
|
|
$self->{Mailbox} = shift(@fields); |
2461
|
|
|
|
|
|
|
my %hash = @fields; |
2462
|
|
|
|
|
|
|
for my $key (keys %hash) { |
2463
|
|
|
|
|
|
|
$self->{Identifiers}{lc{$key}} = $hash{$key}; |
2464
|
|
|
|
|
|
|
} |
2465
|
|
|
|
|
|
|
|
2466
|
|
|
|
|
|
|
return $self; |
2467
|
|
|
|
|
|
|
} |
2468
|
|
|
|
|
|
|
|
2469
|
|
|
|
|
|
|
sub mailbox { $_[0]->{Mailbox} } |
2470
|
|
|
|
|
|
|
sub identifiers { keys %{$_[0]->{Identifiers}} } |
2471
|
|
|
|
|
|
|
sub identifier { $_[0]->{Identifiers}{lc($_[1])} } |
2472
|
|
|
|
|
|
|
|
2473
|
|
|
|
|
|
|
############################################################################### |
2474
|
|
|
|
|
|
|
|
2475
|
|
|
|
|
|
|
=head1 Listrights |
2476
|
|
|
|
|
|
|
|
2477
|
|
|
|
|
|
|
This is a container for C responses. |
2478
|
|
|
|
|
|
|
|
2479
|
|
|
|
|
|
|
=head2 mailbox |
2480
|
|
|
|
|
|
|
|
2481
|
|
|
|
|
|
|
Returns the name of the mailbox associated with the given rights. |
2482
|
|
|
|
|
|
|
|
2483
|
|
|
|
|
|
|
=head2 identifier |
2484
|
|
|
|
|
|
|
|
2485
|
|
|
|
|
|
|
Returns a string containing the identifier associated with the rights. |
2486
|
|
|
|
|
|
|
|
2487
|
|
|
|
|
|
|
=head2 rights |
2488
|
|
|
|
|
|
|
|
2489
|
|
|
|
|
|
|
Returns a string containing the rights contained in the response. |
2490
|
|
|
|
|
|
|
|
2491
|
|
|
|
|
|
|
=cut |
2492
|
|
|
|
|
|
|
|
2493
|
|
|
|
|
|
|
package Net::IMAP::Listrights; |
2494
|
|
|
|
|
|
|
use vars qw(@ISA); |
2495
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2496
|
|
|
|
|
|
|
|
2497
|
|
|
|
|
|
|
sub name { 'listrights' } |
2498
|
|
|
|
|
|
|
|
2499
|
|
|
|
|
|
|
sub new { |
2500
|
|
|
|
|
|
|
my $class = shift; |
2501
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2502
|
|
|
|
|
|
|
my $parent = shift; |
2503
|
|
|
|
|
|
|
my $str = shift; |
2504
|
|
|
|
|
|
|
|
2505
|
|
|
|
|
|
|
my $self = {}; |
2506
|
|
|
|
|
|
|
|
2507
|
|
|
|
|
|
|
bless $self, $class; |
2508
|
|
|
|
|
|
|
|
2509
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2510
|
|
|
|
|
|
|
|
2511
|
|
|
|
|
|
|
my @fields = @{Net::xAP->parse_fields($str)}; |
2512
|
|
|
|
|
|
|
$self->{Mailbox} = shift(@fields); |
2513
|
|
|
|
|
|
|
$self->{Identifier} = shift(@fields); |
2514
|
|
|
|
|
|
|
$self->{Rights} = [@fields]; |
2515
|
|
|
|
|
|
|
|
2516
|
|
|
|
|
|
|
return $self; |
2517
|
|
|
|
|
|
|
} |
2518
|
|
|
|
|
|
|
|
2519
|
|
|
|
|
|
|
sub mailbox { $_[0]->{Mailbox} } |
2520
|
|
|
|
|
|
|
sub identifier { $_[0]->{Identifier} } |
2521
|
|
|
|
|
|
|
sub rights { (wantarray) ? @{$_[0]->{Rights}} : $_[0]->{Rights} } |
2522
|
|
|
|
|
|
|
|
2523
|
|
|
|
|
|
|
############################################################################### |
2524
|
|
|
|
|
|
|
|
2525
|
|
|
|
|
|
|
=head1 Myrights |
2526
|
|
|
|
|
|
|
|
2527
|
|
|
|
|
|
|
This is a container for C responses> |
2528
|
|
|
|
|
|
|
|
2529
|
|
|
|
|
|
|
=head2 mailbox |
2530
|
|
|
|
|
|
|
|
2531
|
|
|
|
|
|
|
Returns the name of the mailbox associated with the given rights. |
2532
|
|
|
|
|
|
|
|
2533
|
|
|
|
|
|
|
=head2 rights |
2534
|
|
|
|
|
|
|
|
2535
|
|
|
|
|
|
|
Returns a string containing the rights contained in the response. |
2536
|
|
|
|
|
|
|
|
2537
|
|
|
|
|
|
|
=cut |
2538
|
|
|
|
|
|
|
|
2539
|
|
|
|
|
|
|
package Net::IMAP::Myrights; |
2540
|
|
|
|
|
|
|
use vars qw(@ISA); |
2541
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2542
|
|
|
|
|
|
|
|
2543
|
|
|
|
|
|
|
sub name { 'myrights' } |
2544
|
|
|
|
|
|
|
|
2545
|
|
|
|
|
|
|
sub new { |
2546
|
|
|
|
|
|
|
my $class = shift; |
2547
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2548
|
|
|
|
|
|
|
my $parent = shift; |
2549
|
|
|
|
|
|
|
my $str = shift; |
2550
|
|
|
|
|
|
|
|
2551
|
|
|
|
|
|
|
my $self = {}; |
2552
|
|
|
|
|
|
|
|
2553
|
|
|
|
|
|
|
bless $self, $class; |
2554
|
|
|
|
|
|
|
|
2555
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2556
|
|
|
|
|
|
|
|
2557
|
|
|
|
|
|
|
my $fields = Net::xAP->parse_fields($str); |
2558
|
|
|
|
|
|
|
$self->{Mailbox} = $fields->[0]; |
2559
|
|
|
|
|
|
|
$self->{Rights} = $fields->[1]; |
2560
|
|
|
|
|
|
|
|
2561
|
|
|
|
|
|
|
return $self; |
2562
|
|
|
|
|
|
|
} |
2563
|
|
|
|
|
|
|
|
2564
|
|
|
|
|
|
|
sub mailbox { $_[0]->{Mailbox} } |
2565
|
|
|
|
|
|
|
sub rights { $_[0]->{Rights} } |
2566
|
|
|
|
|
|
|
|
2567
|
|
|
|
|
|
|
############################################################################### |
2568
|
|
|
|
|
|
|
|
2569
|
|
|
|
|
|
|
=head1 Quota |
2570
|
|
|
|
|
|
|
|
2571
|
|
|
|
|
|
|
This is a container for C responses. |
2572
|
|
|
|
|
|
|
|
2573
|
|
|
|
|
|
|
=head2 quotaroot |
2574
|
|
|
|
|
|
|
|
2575
|
|
|
|
|
|
|
Returns a string containing the name of the quota root in the response. |
2576
|
|
|
|
|
|
|
|
2577
|
|
|
|
|
|
|
=head2 quotas |
2578
|
|
|
|
|
|
|
|
2579
|
|
|
|
|
|
|
Returns a list of the quotas contained in the response. |
2580
|
|
|
|
|
|
|
|
2581
|
|
|
|
|
|
|
=head2 usage $quota |
2582
|
|
|
|
|
|
|
|
2583
|
|
|
|
|
|
|
Returns the usage value associated with the given C<$quota>. Returns |
2584
|
|
|
|
|
|
|
C is the given C<$quota> is not present in the response. |
2585
|
|
|
|
|
|
|
|
2586
|
|
|
|
|
|
|
=head2 limit $quota |
2587
|
|
|
|
|
|
|
|
2588
|
|
|
|
|
|
|
Returns the usage limit associated with the given C<$quota>. Returns |
2589
|
|
|
|
|
|
|
C is the given C<$quota> is not present in the response. |
2590
|
|
|
|
|
|
|
|
2591
|
|
|
|
|
|
|
=cut |
2592
|
|
|
|
|
|
|
|
2593
|
|
|
|
|
|
|
package Net::IMAP::Quota; |
2594
|
|
|
|
|
|
|
use vars qw(@ISA); |
2595
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2596
|
|
|
|
|
|
|
|
2597
|
|
|
|
|
|
|
sub name { 'quota' } |
2598
|
|
|
|
|
|
|
|
2599
|
|
|
|
|
|
|
sub new { |
2600
|
|
|
|
|
|
|
my $class = shift; |
2601
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2602
|
|
|
|
|
|
|
my $parent = shift; |
2603
|
|
|
|
|
|
|
my $str = shift; |
2604
|
|
|
|
|
|
|
|
2605
|
|
|
|
|
|
|
my $self = {}; |
2606
|
|
|
|
|
|
|
|
2607
|
|
|
|
|
|
|
bless $self, $class; |
2608
|
|
|
|
|
|
|
|
2609
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2610
|
|
|
|
|
|
|
|
2611
|
|
|
|
|
|
|
my @fields = @{Net::xAP->parse_fields($str)}; |
2612
|
|
|
|
|
|
|
$self->{QuotaRoot} = shift(@fields); |
2613
|
|
|
|
|
|
|
while (@fields) { |
2614
|
|
|
|
|
|
|
my ($resource, $usage, $limit) = splice(@fields, 0, 3); |
2615
|
|
|
|
|
|
|
$self->{Quota}{lc($resource)} = [$usage, $limit]; |
2616
|
|
|
|
|
|
|
} |
2617
|
|
|
|
|
|
|
|
2618
|
|
|
|
|
|
|
return $self; |
2619
|
|
|
|
|
|
|
} |
2620
|
|
|
|
|
|
|
|
2621
|
|
|
|
|
|
|
sub quotaroot { $_[0]->{QuotaRoot} } |
2622
|
|
|
|
|
|
|
sub quotas { keys %{$_[0]->{Quotas}} } |
2623
|
|
|
|
|
|
|
sub usage { $_[0]->{Quotas}{lc($_[1])}->[0] } |
2624
|
|
|
|
|
|
|
sub limit { $_[0]->{Quotas}{lc($_[1])}->[1] } |
2625
|
|
|
|
|
|
|
|
2626
|
|
|
|
|
|
|
############################################################################### |
2627
|
|
|
|
|
|
|
|
2628
|
|
|
|
|
|
|
=head1 Quotaroot |
2629
|
|
|
|
|
|
|
|
2630
|
|
|
|
|
|
|
This is a container for C responses. |
2631
|
|
|
|
|
|
|
|
2632
|
|
|
|
|
|
|
=head2 mailbox |
2633
|
|
|
|
|
|
|
|
2634
|
|
|
|
|
|
|
Returns the name of the mailbox associated with the quotaroot data. |
2635
|
|
|
|
|
|
|
|
2636
|
|
|
|
|
|
|
=head2 quotaroots |
2637
|
|
|
|
|
|
|
|
2638
|
|
|
|
|
|
|
If called in an array context, returns the list of quotaroots |
2639
|
|
|
|
|
|
|
associated with the mailbox. If called in a scalar context, returns a |
2640
|
|
|
|
|
|
|
list reference. |
2641
|
|
|
|
|
|
|
|
2642
|
|
|
|
|
|
|
=cut |
2643
|
|
|
|
|
|
|
|
2644
|
|
|
|
|
|
|
package Net::IMAP::Quotaroot; |
2645
|
|
|
|
|
|
|
use vars qw(@ISA); |
2646
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::UntaggedResponse); |
2647
|
|
|
|
|
|
|
|
2648
|
|
|
|
|
|
|
sub name { 'quotaroot' } |
2649
|
|
|
|
|
|
|
|
2650
|
|
|
|
|
|
|
sub new { |
2651
|
|
|
|
|
|
|
my $class = shift; |
2652
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2653
|
|
|
|
|
|
|
my $parent = shift; |
2654
|
|
|
|
|
|
|
my $str = shift; |
2655
|
|
|
|
|
|
|
|
2656
|
|
|
|
|
|
|
my $self = {}; |
2657
|
|
|
|
|
|
|
|
2658
|
|
|
|
|
|
|
bless $self, $class; |
2659
|
|
|
|
|
|
|
|
2660
|
|
|
|
|
|
|
$self->{Parent} = $parent; |
2661
|
|
|
|
|
|
|
|
2662
|
|
|
|
|
|
|
my @fields = @{Net::xAP->parse_fields($str)}; |
2663
|
|
|
|
|
|
|
$self->{Mailbox} = shift(@fields); |
2664
|
|
|
|
|
|
|
$self->{Quotaroots} = [@fields]; |
2665
|
|
|
|
|
|
|
|
2666
|
|
|
|
|
|
|
return $self; |
2667
|
|
|
|
|
|
|
} |
2668
|
|
|
|
|
|
|
|
2669
|
|
|
|
|
|
|
sub mailbox { $_[0]->{Mailbox} } |
2670
|
|
|
|
|
|
|
sub quotaroots { (wantarray) ? @{$_[0]->{Quotaroots}} : $_[0]->{Quotaroots} } |
2671
|
|
|
|
|
|
|
|
2672
|
|
|
|
|
|
|
############################################################################### |
2673
|
|
|
|
|
|
|
|
2674
|
|
|
|
|
|
|
=head1 MISC FETCH OBJECTS |
2675
|
|
|
|
|
|
|
|
2676
|
|
|
|
|
|
|
A C response can be relatively complicated. This section |
2677
|
|
|
|
|
|
|
documents various classes and methods associated with the various |
2678
|
|
|
|
|
|
|
pieces of information available in C responses. |
2679
|
|
|
|
|
|
|
|
2680
|
|
|
|
|
|
|
=cut |
2681
|
|
|
|
|
|
|
|
2682
|
|
|
|
|
|
|
package Net::IMAP::FetchData; |
2683
|
|
|
|
|
|
|
|
2684
|
|
|
|
|
|
|
sub new { |
2685
|
|
|
|
|
|
|
my $class = shift; |
2686
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2687
|
|
|
|
|
|
|
my $self = []; |
2688
|
|
|
|
|
|
|
if (defined($_[0])) { |
2689
|
|
|
|
|
|
|
push(@{$self}, |
2690
|
|
|
|
|
|
|
map { |
2691
|
|
|
|
|
|
|
(lc($_) eq 'nil') ? undef : Net::xAP->dequote($_) |
2692
|
|
|
|
|
|
|
} @{$_[0]}); |
2693
|
|
|
|
|
|
|
} |
2694
|
|
|
|
|
|
|
bless $self, $class; |
2695
|
|
|
|
|
|
|
} |
2696
|
|
|
|
|
|
|
|
2697
|
|
|
|
|
|
|
############################################################################### |
2698
|
|
|
|
|
|
|
|
2699
|
|
|
|
|
|
|
=head1 BodyStructure |
2700
|
|
|
|
|
|
|
|
2701
|
|
|
|
|
|
|
This is a container for C items in C responses. |
2702
|
|
|
|
|
|
|
|
2703
|
|
|
|
|
|
|
=head2 type |
2704
|
|
|
|
|
|
|
|
2705
|
|
|
|
|
|
|
Returns a string containing the MIME type of the message. This is the |
2706
|
|
|
|
|
|
|
left-hand portion of a MIME media type. For example, the type of |
2707
|
|
|
|
|
|
|
C is C. |
2708
|
|
|
|
|
|
|
|
2709
|
|
|
|
|
|
|
=head2 subtype |
2710
|
|
|
|
|
|
|
|
2711
|
|
|
|
|
|
|
Returns a string containing the MIME subtype of the message. This is |
2712
|
|
|
|
|
|
|
the right-hand portion of a MIME media type. For example, the subtype |
2713
|
|
|
|
|
|
|
of C is C. |
2714
|
|
|
|
|
|
|
|
2715
|
|
|
|
|
|
|
=head2 parameters |
2716
|
|
|
|
|
|
|
|
2717
|
|
|
|
|
|
|
Returns a reference to a hash containing the key/value attribute pairs |
2718
|
|
|
|
|
|
|
in the C field. |
2719
|
|
|
|
|
|
|
|
2720
|
|
|
|
|
|
|
If, for example, the C field was: |
2721
|
|
|
|
|
|
|
|
2722
|
|
|
|
|
|
|
Content-Type: text/plain; charset=us-ascii |
2723
|
|
|
|
|
|
|
|
2724
|
|
|
|
|
|
|
The hash would contain one entry the a key of C, and a value |
2725
|
|
|
|
|
|
|
of C. The key is always forced to be lowercase, but the |
2726
|
|
|
|
|
|
|
case of the value is retained from the server. |
2727
|
|
|
|
|
|
|
|
2728
|
|
|
|
|
|
|
=head2 disposition |
2729
|
|
|
|
|
|
|
|
2730
|
|
|
|
|
|
|
Returns the disposition type in the C field. |
2731
|
|
|
|
|
|
|
Returns C if no such field exists. |
2732
|
|
|
|
|
|
|
|
2733
|
|
|
|
|
|
|
=head2 disp_parameters |
2734
|
|
|
|
|
|
|
|
2735
|
|
|
|
|
|
|
Returns a reference to a hash containing the key/value attributer |
2736
|
|
|
|
|
|
|
pairs in the C field. A reference to an empty |
2737
|
|
|
|
|
|
|
hash is returned if no such field exists, or if there are no |
2738
|
|
|
|
|
|
|
parameters in the field. |
2739
|
|
|
|
|
|
|
|
2740
|
|
|
|
|
|
|
=head2 language |
2741
|
|
|
|
|
|
|
|
2742
|
|
|
|
|
|
|
Returns a reference to a list of the language tags present in the |
2743
|
|
|
|
|
|
|
C field. Returns a reference to an empty hash if no |
2744
|
|
|
|
|
|
|
such field is present. |
2745
|
|
|
|
|
|
|
|
2746
|
|
|
|
|
|
|
=cut |
2747
|
|
|
|
|
|
|
|
2748
|
|
|
|
|
|
|
package Net::IMAP::BodyStructure; |
2749
|
|
|
|
|
|
|
|
2750
|
|
|
|
|
|
|
sub new { |
2751
|
|
|
|
|
|
|
my $class = shift; |
2752
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2753
|
|
|
|
|
|
|
my $data = shift; |
2754
|
|
|
|
|
|
|
|
2755
|
|
|
|
|
|
|
return Net::IMAP::Multipart->new($data) if (ref($data->[0]) eq 'ARRAY'); |
2756
|
|
|
|
|
|
|
return Net::IMAP::Bodypart->new($data); |
2757
|
|
|
|
|
|
|
} |
2758
|
|
|
|
|
|
|
|
2759
|
|
|
|
|
|
|
sub subtype { $_[0]->{Subtype} } |
2760
|
|
|
|
|
|
|
sub parameters { $_[0]->{Parms} } |
2761
|
|
|
|
|
|
|
sub disposition { $_[0]->{Disp} } |
2762
|
|
|
|
|
|
|
sub disp_parameters { $_[0]->{DispParms} } |
2763
|
|
|
|
|
|
|
sub language { $_[0]->{Lang} } |
2764
|
|
|
|
|
|
|
|
2765
|
|
|
|
|
|
|
sub _parse_parms { |
2766
|
|
|
|
|
|
|
my $self = shift; |
2767
|
|
|
|
|
|
|
my $data = shift; |
2768
|
|
|
|
|
|
|
if (ref($data) eq 'ARRAY') { |
2769
|
|
|
|
|
|
|
my @parms = @{$data}; |
2770
|
|
|
|
|
|
|
while (@parms) { |
2771
|
|
|
|
|
|
|
my ($key, $value) = splice(@parms, 0, 2); |
2772
|
|
|
|
|
|
|
$self->{Parms}{lc($key)} = $value; |
2773
|
|
|
|
|
|
|
} |
2774
|
|
|
|
|
|
|
} |
2775
|
|
|
|
|
|
|
} |
2776
|
|
|
|
|
|
|
|
2777
|
|
|
|
|
|
|
sub _parse_disp { |
2778
|
|
|
|
|
|
|
my $self = shift; |
2779
|
|
|
|
|
|
|
my $data = shift; |
2780
|
|
|
|
|
|
|
|
2781
|
|
|
|
|
|
|
$self->{Disp} = lc($data); |
2782
|
|
|
|
|
|
|
if (ref($data) eq 'ARRAY') { |
2783
|
|
|
|
|
|
|
if (lc($data->[1]) ne 'nil') { |
2784
|
|
|
|
|
|
|
my @parms = @{$data->[1]}; |
2785
|
|
|
|
|
|
|
while (@parms) { |
2786
|
|
|
|
|
|
|
my ($key, $value) = splice(@parms, 0, 2); |
2787
|
|
|
|
|
|
|
$self->{DispParms}{lc($key)} = $value; |
2788
|
|
|
|
|
|
|
} |
2789
|
|
|
|
|
|
|
} |
2790
|
|
|
|
|
|
|
} |
2791
|
|
|
|
|
|
|
} |
2792
|
|
|
|
|
|
|
|
2793
|
|
|
|
|
|
|
sub _parse_lang { |
2794
|
|
|
|
|
|
|
my $self = shift; |
2795
|
|
|
|
|
|
|
my $data = shift; |
2796
|
|
|
|
|
|
|
|
2797
|
|
|
|
|
|
|
$data = lc($data); |
2798
|
|
|
|
|
|
|
if ($data ne 'nil') { |
2799
|
|
|
|
|
|
|
if (ref($data) eq 'ARRAY') { |
2800
|
|
|
|
|
|
|
$self->{Lang} = [map { lc($_) } @{$data}]; |
2801
|
|
|
|
|
|
|
} else { |
2802
|
|
|
|
|
|
|
$self->{Lang} = [lc($data)]; |
2803
|
|
|
|
|
|
|
} |
2804
|
|
|
|
|
|
|
} |
2805
|
|
|
|
|
|
|
} |
2806
|
|
|
|
|
|
|
|
2807
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
2808
|
|
|
|
|
|
|
|
2809
|
|
|
|
|
|
|
=head1 Multipart |
2810
|
|
|
|
|
|
|
|
2811
|
|
|
|
|
|
|
This is a container for C
|
2812
|
|
|
|
|
|
|
|
2813
|
|
|
|
|
|
|
=head2 parts |
2814
|
|
|
|
|
|
|
|
2815
|
|
|
|
|
|
|
Returns a list reference of the body parts contained in the multipart |
2816
|
|
|
|
|
|
|
entity. |
2817
|
|
|
|
|
|
|
|
2818
|
|
|
|
|
|
|
=cut |
2819
|
|
|
|
|
|
|
|
2820
|
|
|
|
|
|
|
package Net::IMAP::Multipart; |
2821
|
|
|
|
|
|
|
use vars qw(@ISA); |
2822
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::BodyStructure); |
2823
|
|
|
|
|
|
|
|
2824
|
|
|
|
|
|
|
sub new { |
2825
|
|
|
|
|
|
|
my $class = shift; |
2826
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2827
|
|
|
|
|
|
|
my $data = shift; |
2828
|
|
|
|
|
|
|
|
2829
|
|
|
|
|
|
|
my $self = {}; |
2830
|
|
|
|
|
|
|
|
2831
|
|
|
|
|
|
|
bless $self, $class; |
2832
|
|
|
|
|
|
|
|
2833
|
|
|
|
|
|
|
$self->{Parts} = []; |
2834
|
|
|
|
|
|
|
|
2835
|
|
|
|
|
|
|
my $i = 0; |
2836
|
|
|
|
|
|
|
for my $item (@{$data}) { |
2837
|
|
|
|
|
|
|
last if (ref($item) ne 'ARRAY'); |
2838
|
|
|
|
|
|
|
if (ref($item->[0]) eq 'ARRAY') { |
2839
|
|
|
|
|
|
|
push @{$self->{Parts}}, Net::IMAP::Multipart->new($item); |
2840
|
|
|
|
|
|
|
} else { |
2841
|
|
|
|
|
|
|
push @{$self->{Parts}}, Net::IMAP::Bodypart->new($item); |
2842
|
|
|
|
|
|
|
} |
2843
|
|
|
|
|
|
|
$i++; |
2844
|
|
|
|
|
|
|
} |
2845
|
|
|
|
|
|
|
|
2846
|
|
|
|
|
|
|
$self->{Subtype} = lc(Net::xAP->dequote($data->[$i++])); |
2847
|
|
|
|
|
|
|
|
2848
|
|
|
|
|
|
|
$self->{Parms} = {}; |
2849
|
|
|
|
|
|
|
$self->{Disp} = undef; |
2850
|
|
|
|
|
|
|
$self->{DispParms} = {}; |
2851
|
|
|
|
|
|
|
$self->{Lang} = undef; |
2852
|
|
|
|
|
|
|
|
2853
|
|
|
|
|
|
|
if (defined($data->[$i])) { |
2854
|
|
|
|
|
|
|
$self->_parse_parms($data->[$i++]); |
2855
|
|
|
|
|
|
|
if (defined($data->[$i])) { |
2856
|
|
|
|
|
|
|
$self->_parse_disp($data->[$i++]); |
2857
|
|
|
|
|
|
|
if (defined($data->[$i])) { |
2858
|
|
|
|
|
|
|
$self->_parse_lang($data->[$i++]); |
2859
|
|
|
|
|
|
|
if (defined($data->[$i])) { |
2860
|
|
|
|
|
|
|
carp("Note: bodystructure contains unknown extension fields\n"); |
2861
|
|
|
|
|
|
|
} |
2862
|
|
|
|
|
|
|
} |
2863
|
|
|
|
|
|
|
} |
2864
|
|
|
|
|
|
|
} |
2865
|
|
|
|
|
|
|
|
2866
|
|
|
|
|
|
|
return $self; |
2867
|
|
|
|
|
|
|
} |
2868
|
|
|
|
|
|
|
|
2869
|
|
|
|
|
|
|
sub type { 'multipart' } |
2870
|
|
|
|
|
|
|
sub parts { $_[0]->{Parts} } |
2871
|
|
|
|
|
|
|
|
2872
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
2873
|
|
|
|
|
|
|
|
2874
|
|
|
|
|
|
|
=head1 Bodypart |
2875
|
|
|
|
|
|
|
|
2876
|
|
|
|
|
|
|
This is a container for singlepart entities in C and |
2877
|
|
|
|
|
|
|
C objects. |
2878
|
|
|
|
|
|
|
|
2879
|
|
|
|
|
|
|
=head2 id |
2880
|
|
|
|
|
|
|
|
2881
|
|
|
|
|
|
|
Return a string containing the contents of the C field, if |
2882
|
|
|
|
|
|
|
one is present, otherwise returns undef. |
2883
|
|
|
|
|
|
|
|
2884
|
|
|
|
|
|
|
=head2 description |
2885
|
|
|
|
|
|
|
|
2886
|
|
|
|
|
|
|
Return a string containing the contents of the C |
2887
|
|
|
|
|
|
|
field, if one is present, otherwise returns undef. |
2888
|
|
|
|
|
|
|
|
2889
|
|
|
|
|
|
|
=head2 encoding |
2890
|
|
|
|
|
|
|
|
2891
|
|
|
|
|
|
|
Returns a string containing the contents of the |
2892
|
|
|
|
|
|
|
C field. Returns C if no such field |
2893
|
|
|
|
|
|
|
is in the entity. |
2894
|
|
|
|
|
|
|
|
2895
|
|
|
|
|
|
|
=head2 size |
2896
|
|
|
|
|
|
|
|
2897
|
|
|
|
|
|
|
Returns the number of octets in the entity. |
2898
|
|
|
|
|
|
|
|
2899
|
|
|
|
|
|
|
=head2 lines |
2900
|
|
|
|
|
|
|
|
2901
|
|
|
|
|
|
|
If the MIME content type is C or the major type is |
2902
|
|
|
|
|
|
|
C, returns the number of lines in the entity, else returns C. |
2903
|
|
|
|
|
|
|
|
2904
|
|
|
|
|
|
|
=head2 envelope |
2905
|
|
|
|
|
|
|
|
2906
|
|
|
|
|
|
|
If the MIME content type is C
|
2907
|
|
|
|
|
|
|
C object, otherwise returns undef. |
2908
|
|
|
|
|
|
|
|
2909
|
|
|
|
|
|
|
=head2 bodystructure |
2910
|
|
|
|
|
|
|
|
2911
|
|
|
|
|
|
|
If the MIME content type is C
|
2912
|
|
|
|
|
|
|
C object, otherwise returns undef. |
2913
|
|
|
|
|
|
|
|
2914
|
|
|
|
|
|
|
=head2 md5 |
2915
|
|
|
|
|
|
|
|
2916
|
|
|
|
|
|
|
Returns a string containing the contents of the C field. |
2917
|
|
|
|
|
|
|
Returns C if no such field is in the entity. |
2918
|
|
|
|
|
|
|
|
2919
|
|
|
|
|
|
|
=cut |
2920
|
|
|
|
|
|
|
|
2921
|
|
|
|
|
|
|
package Net::IMAP::Bodypart; |
2922
|
|
|
|
|
|
|
use vars qw(@ISA); |
2923
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::BodyStructure); |
2924
|
|
|
|
|
|
|
use Carp; |
2925
|
|
|
|
|
|
|
|
2926
|
|
|
|
|
|
|
sub new { |
2927
|
|
|
|
|
|
|
my $class = shift; |
2928
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
2929
|
|
|
|
|
|
|
my $data = shift; |
2930
|
|
|
|
|
|
|
|
2931
|
|
|
|
|
|
|
my $self = {}; |
2932
|
|
|
|
|
|
|
|
2933
|
|
|
|
|
|
|
bless $self, $class; |
2934
|
|
|
|
|
|
|
|
2935
|
|
|
|
|
|
|
my $i = 0; |
2936
|
|
|
|
|
|
|
|
2937
|
|
|
|
|
|
|
$self->{Type} = lc(Net::xAP->dequote($data->[$i++])); |
2938
|
|
|
|
|
|
|
$self->{Subtype} = lc(Net::xAP->dequote($data->[$i++])); |
2939
|
|
|
|
|
|
|
$self->{Parms} = {}; |
2940
|
|
|
|
|
|
|
$self->_parse_parms($data->[$i++]); |
2941
|
|
|
|
|
|
|
$self->{Id} = Net::xAP->dequote($data->[$i++]); |
2942
|
|
|
|
|
|
|
$self->{Description} = Net::xAP->dequote($data->[$i++]); |
2943
|
|
|
|
|
|
|
$self->{Encoding} = lc(Net::xAP->dequote($data->[$i++])); |
2944
|
|
|
|
|
|
|
$self->{Size} = $data->[$i++]; |
2945
|
|
|
|
|
|
|
|
2946
|
|
|
|
|
|
|
if (($self->{Type} eq 'message') && ($self->{Subtype} eq 'rfc822')) { |
2947
|
|
|
|
|
|
|
$self->{Envelope} = Net::IMAP::Envelope->new($data->[$i++]); |
2948
|
|
|
|
|
|
|
$self->{Bodystructure} = Net::IMAP::BodyStructure->new($data->[$i++]); |
2949
|
|
|
|
|
|
|
$self->{Lines} = $data->[$i++]; |
2950
|
|
|
|
|
|
|
} elsif ($self->{Type} eq 'text') { |
2951
|
|
|
|
|
|
|
$self->{Lines} = $data->[$i++]; |
2952
|
|
|
|
|
|
|
} |
2953
|
|
|
|
|
|
|
|
2954
|
|
|
|
|
|
|
$self->{Envelope} ||= undef; |
2955
|
|
|
|
|
|
|
$self->{BodyStructure} ||= undef; |
2956
|
|
|
|
|
|
|
$self->{Lines} ||= undef; |
2957
|
|
|
|
|
|
|
|
2958
|
|
|
|
|
|
|
if (defined($data->[$i])) { |
2959
|
|
|
|
|
|
|
$self->{MD5} = Net::xAP->dequote($data->[$i++]); |
2960
|
|
|
|
|
|
|
if (defined($data->[$i])) { |
2961
|
|
|
|
|
|
|
$self->_parse_disp($data->[$i++]); |
2962
|
|
|
|
|
|
|
if (defined($data->[$i])) { |
2963
|
|
|
|
|
|
|
$self->_parse_lang($data->[$i++]); |
2964
|
|
|
|
|
|
|
if (defined($data->[$i])) { |
2965
|
|
|
|
|
|
|
carp("Note: bodystructure contains unknown extension fields\n"); |
2966
|
|
|
|
|
|
|
} |
2967
|
|
|
|
|
|
|
} |
2968
|
|
|
|
|
|
|
} |
2969
|
|
|
|
|
|
|
} |
2970
|
|
|
|
|
|
|
|
2971
|
|
|
|
|
|
|
$self->{MD5} ||= undef; |
2972
|
|
|
|
|
|
|
$self->{Disp} ||= undef; |
2973
|
|
|
|
|
|
|
$self->{DispParms} ||= {}; |
2974
|
|
|
|
|
|
|
$self->{Lang} ||= undef; |
2975
|
|
|
|
|
|
|
|
2976
|
|
|
|
|
|
|
return $self; |
2977
|
|
|
|
|
|
|
} |
2978
|
|
|
|
|
|
|
|
2979
|
|
|
|
|
|
|
sub type { $_[0]->{Type} } |
2980
|
|
|
|
|
|
|
sub id { $_[0]->{Id} } |
2981
|
|
|
|
|
|
|
sub description { $_[0]->{Description} } |
2982
|
|
|
|
|
|
|
sub encoding { $_[0]->{Encoding} } |
2983
|
|
|
|
|
|
|
sub size { $_[0]->{Size} } |
2984
|
|
|
|
|
|
|
sub lines { $_[0]->{Lines} } # message/rfc822 and text/* |
2985
|
|
|
|
|
|
|
sub envelope { $_[0]->{Envelope} } # message/rfc822 |
2986
|
|
|
|
|
|
|
sub bodystructure { $_[0]->{Bodystructure} } # message/rfc822 |
2987
|
|
|
|
|
|
|
sub md5 { $_[0]->{MD5} } |
2988
|
|
|
|
|
|
|
|
2989
|
|
|
|
|
|
|
############################################################################### |
2990
|
|
|
|
|
|
|
|
2991
|
|
|
|
|
|
|
=head1 Envelope |
2992
|
|
|
|
|
|
|
|
2993
|
|
|
|
|
|
|
This is a container for envelope data in C responses. |
2994
|
|
|
|
|
|
|
|
2995
|
|
|
|
|
|
|
For those familiar with SMTP, this is not the same type envelope. |
2996
|
|
|
|
|
|
|
Rather, it is a composite structure containing key source, |
2997
|
|
|
|
|
|
|
destination, and reference information in the message. When retrieved |
2998
|
|
|
|
|
|
|
from the server, it is populated into a C object. |
2999
|
|
|
|
|
|
|
The following methods are available. |
3000
|
|
|
|
|
|
|
|
3001
|
|
|
|
|
|
|
=head2 date |
3002
|
|
|
|
|
|
|
|
3003
|
|
|
|
|
|
|
Returns a string with the contents of the C field. |
3004
|
|
|
|
|
|
|
|
3005
|
|
|
|
|
|
|
=head2 subject |
3006
|
|
|
|
|
|
|
|
3007
|
|
|
|
|
|
|
Returns a string with the contents of the C field. |
3008
|
|
|
|
|
|
|
|
3009
|
|
|
|
|
|
|
=head2 from |
3010
|
|
|
|
|
|
|
|
3011
|
|
|
|
|
|
|
Returns a list reference of C objects with the |
3012
|
|
|
|
|
|
|
contents of the C field. |
3013
|
|
|
|
|
|
|
|
3014
|
|
|
|
|
|
|
=head2 sender |
3015
|
|
|
|
|
|
|
|
3016
|
|
|
|
|
|
|
Returns a list reference of C objects with the |
3017
|
|
|
|
|
|
|
contents of the C field. If no C field is present in |
3018
|
|
|
|
|
|
|
the message, the server will default it to the contents of the C |
3019
|
|
|
|
|
|
|
field. |
3020
|
|
|
|
|
|
|
|
3021
|
|
|
|
|
|
|
=head2 reply_to |
3022
|
|
|
|
|
|
|
|
3023
|
|
|
|
|
|
|
Returns a list reference of C objects with the |
3024
|
|
|
|
|
|
|
contents of the C field. If no C field is present |
3025
|
|
|
|
|
|
|
in the message, the server will default it to the contents of the |
3026
|
|
|
|
|
|
|
C field. |
3027
|
|
|
|
|
|
|
|
3028
|
|
|
|
|
|
|
=head2 to |
3029
|
|
|
|
|
|
|
|
3030
|
|
|
|
|
|
|
Returns a list reference of C objects with the |
3031
|
|
|
|
|
|
|
contents of the Cfield. Will return C if no C field |
3032
|
|
|
|
|
|
|
exists in the message. |
3033
|
|
|
|
|
|
|
|
3034
|
|
|
|
|
|
|
=head2 cc |
3035
|
|
|
|
|
|
|
|
3036
|
|
|
|
|
|
|
Returns a list reference of C objects with the |
3037
|
|
|
|
|
|
|
contents of the C field. Will return C if no C field |
3038
|
|
|
|
|
|
|
exists in the message. |
3039
|
|
|
|
|
|
|
|
3040
|
|
|
|
|
|
|
=head2 bcc |
3041
|
|
|
|
|
|
|
|
3042
|
|
|
|
|
|
|
Returns a list reference of C objects with the |
3043
|
|
|
|
|
|
|
contents of the C field. Will return C if no C field |
3044
|
|
|
|
|
|
|
exists in the message. |
3045
|
|
|
|
|
|
|
|
3046
|
|
|
|
|
|
|
=head2 in_reply_to |
3047
|
|
|
|
|
|
|
|
3048
|
|
|
|
|
|
|
Returns a string with the contents of the C field. |
3049
|
|
|
|
|
|
|
Returns C if no such field is present in the message. |
3050
|
|
|
|
|
|
|
|
3051
|
|
|
|
|
|
|
=head2 message_id |
3052
|
|
|
|
|
|
|
|
3053
|
|
|
|
|
|
|
Returns a string with the contents of the C field. Returns |
3054
|
|
|
|
|
|
|
C if no such field is present in the message. |
3055
|
|
|
|
|
|
|
|
3056
|
|
|
|
|
|
|
=cut |
3057
|
|
|
|
|
|
|
|
3058
|
|
|
|
|
|
|
package Net::IMAP::Envelope; |
3059
|
|
|
|
|
|
|
use vars qw(@ISA); |
3060
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::FetchData); |
3061
|
|
|
|
|
|
|
|
3062
|
|
|
|
|
|
|
sub new { |
3063
|
|
|
|
|
|
|
my $class = shift; |
3064
|
|
|
|
|
|
|
my $type = ref($class) || $class; |
3065
|
|
|
|
|
|
|
my $data = shift; |
3066
|
|
|
|
|
|
|
|
3067
|
|
|
|
|
|
|
my $self = Net::IMAP::FetchData->new |
3068
|
|
|
|
|
|
|
or return undef; |
3069
|
|
|
|
|
|
|
|
3070
|
|
|
|
|
|
|
bless $self, $class; |
3071
|
|
|
|
|
|
|
|
3072
|
|
|
|
|
|
|
$self->[0] = Net::xAP->dequote($data->[0]); |
3073
|
|
|
|
|
|
|
$self->[1] = Net::xAP->dequote($data->[1]); |
3074
|
|
|
|
|
|
|
for my $i (2 .. 7) { |
3075
|
|
|
|
|
|
|
if (lc($data->[$i]) eq 'nil') { |
3076
|
|
|
|
|
|
|
$self->[$i] = undef; |
3077
|
|
|
|
|
|
|
next; |
3078
|
|
|
|
|
|
|
} |
3079
|
|
|
|
|
|
|
push @{$self->[$i]}, map { Net::IMAP::Addr->new($_) } @{$data->[$i]}; |
3080
|
|
|
|
|
|
|
} |
3081
|
|
|
|
|
|
|
$self->[8] = Net::xAP->dequote($data->[8]); |
3082
|
|
|
|
|
|
|
$self->[9] = Net::xAP->dequote($data->[9]); |
3083
|
|
|
|
|
|
|
|
3084
|
|
|
|
|
|
|
return $self; |
3085
|
|
|
|
|
|
|
} |
3086
|
|
|
|
|
|
|
|
3087
|
|
|
|
|
|
|
sub date { $_[0]->[0] } |
3088
|
|
|
|
|
|
|
sub subject { $_[0]->[1] } |
3089
|
|
|
|
|
|
|
sub from { $_[0]->[2] } |
3090
|
|
|
|
|
|
|
sub sender { $_[0]->[3] } |
3091
|
|
|
|
|
|
|
sub reply_to { $_[0]->[4] } |
3092
|
|
|
|
|
|
|
sub to { $_[0]->[5] } |
3093
|
|
|
|
|
|
|
sub cc { $_[0]->[6] } |
3094
|
|
|
|
|
|
|
sub bcc { $_[0]->[7] } |
3095
|
|
|
|
|
|
|
sub in_reply_to { $_[0]->[8] } |
3096
|
|
|
|
|
|
|
sub message_id { $_[0]->[9] } |
3097
|
|
|
|
|
|
|
|
3098
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
3099
|
|
|
|
|
|
|
|
3100
|
|
|
|
|
|
|
=head1 Addr |
3101
|
|
|
|
|
|
|
|
3102
|
|
|
|
|
|
|
This is a container for address structures in C objects. |
3103
|
|
|
|
|
|
|
|
3104
|
|
|
|
|
|
|
=head2 phrase |
3105
|
|
|
|
|
|
|
|
3106
|
|
|
|
|
|
|
Returns a string containing the phrase portion of the address, or |
3107
|
|
|
|
|
|
|
C if no phrase is present. |
3108
|
|
|
|
|
|
|
|
3109
|
|
|
|
|
|
|
=head2 route |
3110
|
|
|
|
|
|
|
|
3111
|
|
|
|
|
|
|
Returns a string containing the route portion of the address, or |
3112
|
|
|
|
|
|
|
C if no route information is present. |
3113
|
|
|
|
|
|
|
|
3114
|
|
|
|
|
|
|
=head2 localpart |
3115
|
|
|
|
|
|
|
|
3116
|
|
|
|
|
|
|
Returns a string containing the localpart portion of the address, or |
3117
|
|
|
|
|
|
|
C if no localpart is present. |
3118
|
|
|
|
|
|
|
|
3119
|
|
|
|
|
|
|
=head2 domain |
3120
|
|
|
|
|
|
|
|
3121
|
|
|
|
|
|
|
Returns a string containing the domain portion of the address, or |
3122
|
|
|
|
|
|
|
C if no domain is present. |
3123
|
|
|
|
|
|
|
|
3124
|
|
|
|
|
|
|
=head2 as_string |
3125
|
|
|
|
|
|
|
|
3126
|
|
|
|
|
|
|
Returns a string representation of the contents of the object. |
3127
|
|
|
|
|
|
|
|
3128
|
|
|
|
|
|
|
=cut |
3129
|
|
|
|
|
|
|
|
3130
|
|
|
|
|
|
|
package Net::IMAP::Addr; |
3131
|
|
|
|
|
|
|
use vars qw(@ISA); |
3132
|
|
|
|
|
|
|
@ISA = qw(Net::IMAP::FetchData); |
3133
|
|
|
|
|
|
|
|
3134
|
|
|
|
|
|
|
sub phrase { $_[0]->[0] } |
3135
|
|
|
|
|
|
|
sub route { $_[0]->[1] } |
3136
|
|
|
|
|
|
|
sub localpart { $_[0]->[2] } |
3137
|
|
|
|
|
|
|
sub domain { $_[0]->[3] } |
3138
|
|
|
|
|
|
|
|
3139
|
|
|
|
|
|
|
sub as_string { |
3140
|
|
|
|
|
|
|
my $self = shift; |
3141
|
|
|
|
|
|
|
my $str; |
3142
|
|
|
|
|
|
|
my $domain = $self->domain; |
3143
|
|
|
|
|
|
|
my $localpart = $self->localpart; |
3144
|
|
|
|
|
|
|
my $route = $self->route; |
3145
|
|
|
|
|
|
|
my $phrase = $self->phrase; |
3146
|
|
|
|
|
|
|
|
3147
|
|
|
|
|
|
|
return undef if (!defined($domain)); # part of a group list |
3148
|
|
|
|
|
|
|
return undef if (!defined($localpart)); |
3149
|
|
|
|
|
|
|
|
3150
|
|
|
|
|
|
|
$str = "$localpart\@$domain"; |
3151
|
|
|
|
|
|
|
if (defined($route) || defined($phrase)) { |
3152
|
|
|
|
|
|
|
$str = "$route:$str" if defined($route); |
3153
|
|
|
|
|
|
|
$str = "<$str>"; # route-addrs and phrases need <> |
3154
|
|
|
|
|
|
|
$str = "$phrase $str" if defined($phrase); |
3155
|
|
|
|
|
|
|
} |
3156
|
|
|
|
|
|
|
return $str; |
3157
|
|
|
|
|
|
|
} |
3158
|
|
|
|
|
|
|
|
3159
|
|
|
|
|
|
|
############################################################################### |
3160
|
|
|
|
|
|
|
|
3161
|
|
|
|
|
|
|
=head1 CAVEATS |
3162
|
|
|
|
|
|
|
|
3163
|
|
|
|
|
|
|
Minimal testing has been done against the various IMAP server |
3164
|
|
|
|
|
|
|
implementations. Refer to C for known bugs/malfeatures. |
3165
|
|
|
|
|
|
|
|
3166
|
|
|
|
|
|
|
=head1 AUTHOR |
3167
|
|
|
|
|
|
|
|
3168
|
|
|
|
|
|
|
Kevin Johnson EFE |
3169
|
|
|
|
|
|
|
|
3170
|
|
|
|
|
|
|
=head1 COPYRIGHT |
3171
|
|
|
|
|
|
|
|
3172
|
|
|
|
|
|
|
Copyright (c) 1997-1999 Kevin Johnson . |
3173
|
|
|
|
|
|
|
|
3174
|
|
|
|
|
|
|
All rights reserved. This program is free software; you can |
3175
|
|
|
|
|
|
|
redistribute it and/or modify it under the same terms as Perl itself. |
3176
|
|
|
|
|
|
|
|
3177
|
|
|
|
|
|
|
=cut |
3178
|
|
|
|
|
|
|
|
3179
|
|
|
|
|
|
|
1; |