| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | # IMAP::Admin - perl module for helping ease the administration of imap servers | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | package IMAP::Admin; | 
| 4 |  |  |  |  |  |  |  | 
| 5 | 1 |  |  | 1 |  | 484 | use strict; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 22 |  | 
| 6 | 1 |  |  | 1 |  | 2 | use Carp; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 63 |  | 
| 7 | 1 |  |  | 1 |  | 458 | use IO::Select; | 
|  | 1 |  |  |  |  | 1166 |  | 
|  | 1 |  |  |  |  | 36 |  | 
| 8 | 1 |  |  | 1 |  | 404 | use IO::Socket; | 
|  | 1 |  |  |  |  | 15470 |  | 
|  | 1 |  |  |  |  | 5 |  | 
| 9 |  |  |  |  |  |  | #use IO::Socket::INET; | 
| 10 | 1 |  |  | 1 |  | 336 | use Cwd; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 75 |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 | 1 |  |  | 1 |  | 15 | use vars qw($VERSION); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 3422 |  | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | $VERSION = '1.6.8'; | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | sub new { | 
| 17 | 1 |  |  | 1 | 0 | 3648 | my $class = shift; | 
| 18 | 1 |  |  |  |  | 8 | my $self = {}; | 
| 19 | 1 |  |  |  |  | 8 | my @defaults = ( | 
| 20 |  |  |  |  |  |  | 'Port' => 143, | 
| 21 |  |  |  |  |  |  | 'Separator' => '.', | 
| 22 |  |  |  |  |  |  | 'CRAM' => 0, | 
| 23 |  |  |  |  |  |  | ); | 
| 24 |  |  |  |  |  |  |  | 
| 25 | 1 |  |  |  |  | 5 | bless $self, $class; | 
| 26 | 1 | 50 |  |  |  | 11 | if ((scalar(@_) % 2) != 0) { | 
| 27 | 0 |  |  |  |  | 0 | croak "$class called with incorrect number of arguments"; | 
| 28 |  |  |  |  |  |  | } | 
| 29 | 1 |  |  |  |  | 7 | unshift @_, @defaults; | 
| 30 | 1 |  |  |  |  | 4 | %{$self} = @_; # set up parameters; | 
|  | 1 |  |  |  |  | 29 |  | 
| 31 | 1 |  |  |  |  | 2 | $self->{'CLASS'} = $class; | 
| 32 | 1 |  |  |  |  | 7 | $self->_initialize; | 
| 33 | 0 |  |  |  |  | 0 | return $self; | 
| 34 |  |  |  |  |  |  | } | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | sub _initialize { | 
| 37 | 1 |  |  | 1 |  | 3 | my $self = shift; | 
| 38 |  |  |  |  |  |  |  | 
| 39 | 1 | 50 |  |  |  | 5 | if (!defined($self->{'Server'})) { | 
| 40 | 1 |  |  |  |  | 217 | croak "$self->{'CLASS'} not initialized properly : Server parameter missing"; | 
| 41 |  |  |  |  |  |  | } | 
| 42 | 0 | 0 |  |  |  |  | if (!defined($self->{'Login'})) { | 
| 43 | 0 |  |  |  |  |  | croak "$self->{'CLASS'} not initialized properly : Login parameter missing"; | 
| 44 |  |  |  |  |  |  | } | 
| 45 | 0 | 0 |  |  |  |  | if (!defined($self->{'Password'})) { | 
| 46 | 0 |  |  |  |  |  | croak "$self->{'CLASS'} not initialized properly : Password parameter missing"; | 
| 47 |  |  |  |  |  |  | } | 
| 48 | 0 | 0 |  |  |  |  | if ($self->{'CRAM'} != 0) { | 
| 49 | 0 |  |  |  |  |  | my $cram_try = "use Digest::HMAC; use Digest::MD5; use MIME::Base64;"; | 
| 50 | 0 |  |  |  |  |  | eval $cram_try; | 
| 51 |  |  |  |  |  |  | } | 
| 52 | 0 | 0 |  |  |  |  | if (defined($self->{'SSL'})) { # attempt SSL connection instead | 
| 53 |  |  |  |  |  |  | # construct array of ssl options | 
| 54 | 0 |  |  |  |  |  | my $cwd = cwd; | 
| 55 | 0 |  |  |  |  |  | my %ssl_defaults = ( | 
| 56 |  |  |  |  |  |  | 'SSL_use_cert' => 0, | 
| 57 |  |  |  |  |  |  | 'SSL_verify_mode' => 0x00, | 
| 58 |  |  |  |  |  |  | 'SSL_key_file' => $cwd."/certs/client-key.pem", | 
| 59 |  |  |  |  |  |  | 'SSL_cert_file' => $cwd."/certs/client-cert.pem", | 
| 60 |  |  |  |  |  |  | 'SSL_ca_path' => $cwd."/certs", | 
| 61 |  |  |  |  |  |  | 'SSL_ca_file' => $cwd."/certs/ca-cert.pem", | 
| 62 |  |  |  |  |  |  | ); | 
| 63 | 0 |  |  |  |  |  | my @ssl_options; | 
| 64 |  |  |  |  |  |  | my $ssl_key; | 
| 65 | 0 |  |  |  |  |  | my $key; | 
| 66 | 0 |  |  |  |  |  | foreach $ssl_key (keys(%ssl_defaults)) { | 
| 67 | 0 | 0 |  |  |  |  | if (!defined($self->{$ssl_key})) { | 
| 68 | 0 |  |  |  |  |  | $self->{$ssl_key} = $ssl_defaults{$ssl_key}; | 
| 69 |  |  |  |  |  |  | } | 
| 70 |  |  |  |  |  |  | } | 
| 71 | 0 |  |  |  |  |  | foreach $ssl_key (keys(%{$self})) { | 
|  | 0 |  |  |  |  |  |  | 
| 72 | 0 | 0 |  |  |  |  | if ($ssl_key =~ /^SSL_/) { | 
| 73 | 0 |  |  |  |  |  | push @ssl_options, $ssl_key, $self->{$ssl_key}; | 
| 74 |  |  |  |  |  |  | } | 
| 75 |  |  |  |  |  |  | } | 
| 76 | 0 |  |  |  |  |  | my $SSL_try = "use IO::Socket::SSL"; | 
| 77 |  |  |  |  |  |  |  | 
| 78 | 0 |  |  |  |  |  | eval $SSL_try; | 
| 79 |  |  |  |  |  |  | #	$IO::Socket::SSL::DEBUG = 1; | 
| 80 | 0 | 0 |  |  |  |  | if (!eval { | 
| 81 |  |  |  |  |  |  | $self->{'Socket'} = | 
| 82 |  |  |  |  |  |  | IO::Socket::SSL->new(PeerAddr => $self->{'Server'}, | 
| 83 | 0 |  |  |  |  |  | PeerPort => $self->{'Port'}, | 
| 84 |  |  |  |  |  |  | Proto => 'tcp', | 
| 85 |  |  |  |  |  |  | Reuse => 1, | 
| 86 |  |  |  |  |  |  | Timeout => 5, | 
| 87 |  |  |  |  |  |  | @ssl_options); }) { | 
| 88 |  |  |  |  |  |  | $self->_error("initialize", "couldn't establish SSL connection to", | 
| 89 | 0 |  |  |  |  |  | $self->{'Server'}, "[$!]"); | 
| 90 | 0 |  |  |  |  |  | delete $self->{'Socket'}; | 
| 91 | 0 |  |  |  |  |  | return; | 
| 92 |  |  |  |  |  |  | } | 
| 93 |  |  |  |  |  |  | } else { | 
| 94 | 0 | 0 |  |  |  |  | if ($self->{'Server'} =~ /^\//) { | 
| 95 | 0 | 0 |  |  |  |  | if (!eval { | 
| 96 |  |  |  |  |  |  | $self->{'Socket'} = | 
| 97 | 0 |  |  |  |  |  | IO::Socket::UNIX->new(Peer => $self->{'Server'}); }) | 
| 98 |  |  |  |  |  |  | { | 
| 99 | 0 |  |  |  |  |  | delete $self->{'Socket'}; | 
| 100 |  |  |  |  |  |  | $self->_error("initialize", "couldn't establish connection to", | 
| 101 | 0 |  |  |  |  |  | $self->{'Server'}); | 
| 102 | 0 |  |  |  |  |  | return; | 
| 103 |  |  |  |  |  |  | } | 
| 104 |  |  |  |  |  |  | } else { | 
| 105 | 0 | 0 |  |  |  |  | if (!eval { | 
| 106 |  |  |  |  |  |  | $self->{'Socket'} = | 
| 107 |  |  |  |  |  |  | IO::Socket::INET->new(PeerAddr => $self->{'Server'}, | 
| 108 | 0 |  |  |  |  |  | PeerPort => $self->{'Port'}, | 
| 109 |  |  |  |  |  |  | Proto => 'tcp', | 
| 110 |  |  |  |  |  |  | Reuse => 1, | 
| 111 |  |  |  |  |  |  | Timeout => 5); }) | 
| 112 |  |  |  |  |  |  | { | 
| 113 | 0 |  |  |  |  |  | delete $self->{'Socket'}; | 
| 114 |  |  |  |  |  |  | $self->_error("initialize", "couldn't establish connection to", | 
| 115 | 0 |  |  |  |  |  | $self->{'Server'}); | 
| 116 | 0 |  |  |  |  |  | return; | 
| 117 |  |  |  |  |  |  | } | 
| 118 |  |  |  |  |  |  | } | 
| 119 |  |  |  |  |  |  | } | 
| 120 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 121 | 0 |  |  |  |  |  | my $try = $self->_read; # get Banner | 
| 122 | 0 | 0 |  |  |  |  | if ($try !~ /\* OK/) { | 
| 123 | 0 |  |  |  |  |  | $self->close; | 
| 124 | 0 |  |  |  |  |  | $self->_error("initialize", "bad response from", $self->{'Server'}, | 
| 125 |  |  |  |  |  |  | "[", $try, "]"); | 
| 126 | 0 |  |  |  |  |  | return; | 
| 127 |  |  |  |  |  |  | } | 
| 128 |  |  |  |  |  |  | # this section was changed to accomodate motd's | 
| 129 | 0 |  |  |  |  |  | print $fh "try CAPABILITY\n"; | 
| 130 | 0 |  |  |  |  |  | $try = $self->_read; | 
| 131 | 0 |  |  |  |  |  | while ($try !~ /^\* CAPABILITY/) { # we have a potential lockup, should alarm this | 
| 132 | 0 |  |  |  |  |  | $try = $self->_read; | 
| 133 |  |  |  |  |  |  | } | 
| 134 | 0 |  |  |  |  |  | $self->{'Capability'} = $try; | 
| 135 | 0 |  |  |  |  |  | $try = $self->_read; | 
| 136 | 0 | 0 |  |  |  |  | if ($try !~ /^try OK/) { | 
| 137 | 0 |  |  |  |  |  | $self->close; | 
| 138 | 0 |  |  |  |  |  | $self->_error("initialize", "Couldn't do a capabilites check [", | 
| 139 |  |  |  |  |  |  | $try, "]"); | 
| 140 | 0 |  |  |  |  |  | return; | 
| 141 |  |  |  |  |  |  | } | 
| 142 | 0 | 0 |  |  |  |  | if ($self->{'CRAM'} > 0) { | 
| 143 | 0 | 0 |  |  |  |  | if ($self->{'Capability'} =~ /CRAM-MD5/) { | 
| 144 | 0 |  |  |  |  |  | _do_cram_login($self); | 
| 145 |  |  |  |  |  |  | } else { | 
| 146 | 0 | 0 |  |  |  |  | if ($self->{'CRAM'} > 1) { | 
| 147 | 0 |  |  |  |  |  | print $fh qq{try LOGIN "$self->{'Login'}" "$self->{'Password'}"\n}; | 
| 148 |  |  |  |  |  |  | } else { | 
| 149 | 0 |  |  |  |  |  | $self->close; | 
| 150 | 0 |  |  |  |  |  | $self->_error("initialize","CRAM not reported in Capability check and fallback to PLAIN not selected", $self->{'Server'}, "[", $self->{'Capability'}, "]"); | 
| 151 | 0 |  |  |  |  |  | return; | 
| 152 |  |  |  |  |  |  | } | 
| 153 |  |  |  |  |  |  | } | 
| 154 |  |  |  |  |  |  | } else { | 
| 155 | 0 |  |  |  |  |  | print $fh qq{try LOGIN "$self->{'Login'}" "$self->{'Password'}"\n}; | 
| 156 |  |  |  |  |  |  | } | 
| 157 | 0 |  |  |  |  |  | $try = $self->_read; | 
| 158 | 0 | 0 |  |  |  |  | if ($try !~ /^try OK/) { # should tr this response | 
| 159 | 0 |  |  |  |  |  | $self->close; | 
| 160 | 0 |  |  |  |  |  | $self->_error("initialize", $try); | 
| 161 | 0 |  |  |  |  |  | return; | 
| 162 |  |  |  |  |  |  | } else { | 
| 163 | 0 |  |  |  |  |  | $self->{'Error'} = "No Errors"; | 
| 164 | 0 |  |  |  |  |  | return; | 
| 165 |  |  |  |  |  |  | } | 
| 166 |  |  |  |  |  |  | # fall thru, can it be hit ? | 
| 167 | 0 |  |  |  |  |  | $self->{'Error'} = "No Errors"; | 
| 168 | 0 |  |  |  |  |  | return; | 
| 169 |  |  |  |  |  |  | } | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | # this routine uses evals to prevent errors regarding missing modules | 
| 172 |  |  |  |  |  |  | sub _do_cram_login { | 
| 173 | 0 |  |  | 0 |  |  | my $self = shift; | 
| 174 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 175 | 0 |  |  |  |  |  | my $ans; | 
| 176 |  |  |  |  |  |  |  | 
| 177 | 0 |  |  |  |  |  | print $fh "try AUTHENTICATE CRAM-MD5\n"; | 
| 178 | 0 |  |  |  |  |  | my $try = $self->_read; # gets back the postal string | 
| 179 | 0 |  |  |  |  |  | ($ans) = (split(' ', $try, 2))[1]; | 
| 180 | 0 |  |  |  |  |  | my $cram_eval = " | 
| 181 |  |  |  |  |  |  | my \$hmac = Digest::HMAC->new(\$self->{'Password'}, 'Digest::MD5'); | 
| 182 |  |  |  |  |  |  | \$hmac->add(decode_base64(\$ans)); | 
| 183 |  |  |  |  |  |  | \$ans = encode_base64(\$self->{'Login'}.' '.\$hmac->hexdigest, ''); | 
| 184 |  |  |  |  |  |  | "; | 
| 185 | 0 |  |  |  |  |  | eval $cram_eval; | 
| 186 | 0 |  |  |  |  |  | print $fh "$ans\n"; | 
| 187 | 0 |  |  |  |  |  | return; | 
| 188 |  |  |  |  |  |  | } | 
| 189 |  |  |  |  |  |  |  | 
| 190 |  |  |  |  |  |  | sub _error { | 
| 191 | 0 |  |  | 0 |  |  | my $self = shift; | 
| 192 | 0 |  |  |  |  |  | my $func = shift; | 
| 193 | 0 |  |  |  |  |  | my @error = @_; | 
| 194 |  |  |  |  |  |  |  | 
| 195 | 0 |  |  |  |  |  | $self->{'Error'} = join(" ",$self->{'CLASS'}, "[", $func, "]:", @error); | 
| 196 | 0 |  |  |  |  |  | return; | 
| 197 |  |  |  |  |  |  | } | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | sub error { | 
| 200 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 201 | 0 |  |  |  |  |  | return $self->{'Error'}; | 
| 202 |  |  |  |  |  |  | } | 
| 203 |  |  |  |  |  |  |  | 
| 204 |  |  |  |  |  |  | sub _read { | 
| 205 | 0 |  |  | 0 |  |  | my $self = shift; | 
| 206 | 0 |  |  |  |  |  | my $buffer = ""; | 
| 207 | 0 |  |  |  |  |  | my $char = ""; | 
| 208 | 0 |  |  |  |  |  | my $bytes = 1; | 
| 209 | 0 |  |  |  |  |  | while ($bytes == 1) { | 
| 210 | 0 |  |  |  |  |  | $bytes = sysread $self->{'Socket'}, $char, 1; | 
| 211 | 0 | 0 |  |  |  |  | if ($bytes == 0) { | 
| 212 | 0 | 0 |  |  |  |  | if (length ($buffer) != 0) { | 
| 213 | 0 |  |  |  |  |  | return $buffer; | 
| 214 |  |  |  |  |  |  | } else { | 
| 215 | 0 |  |  |  |  |  | return; | 
| 216 |  |  |  |  |  |  | } | 
| 217 |  |  |  |  |  |  | } else { | 
| 218 | 0 | 0 | 0 |  |  |  | if (($char eq "\n") or ($char eq "\r")) { | 
| 219 | 0 | 0 |  |  |  |  | if (length($buffer) == 0) { | 
| 220 |  |  |  |  |  |  | # cr or nl left over, just eat it | 
| 221 |  |  |  |  |  |  | } else { | 
| 222 | 0 |  |  |  |  |  | return $buffer; | 
| 223 |  |  |  |  |  |  | } | 
| 224 |  |  |  |  |  |  | } else { | 
| 225 |  |  |  |  |  |  | #		print "got char [$char]\n"; | 
| 226 | 0 |  |  |  |  |  | $buffer .= $char; | 
| 227 |  |  |  |  |  |  | } | 
| 228 |  |  |  |  |  |  | } | 
| 229 |  |  |  |  |  |  | } | 
| 230 |  |  |  |  |  |  | } | 
| 231 |  |  |  |  |  |  |  | 
| 232 |  |  |  |  |  |  | sub close { | 
| 233 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 234 |  |  |  |  |  |  |  | 
| 235 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 236 | 0 |  |  |  |  |  | return 0; | 
| 237 |  |  |  |  |  |  | } | 
| 238 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 239 | 0 |  |  |  |  |  | print $fh "try logout\n"; | 
| 240 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 241 | 0 |  |  |  |  |  | close($self->{'Socket'}); | 
| 242 | 0 |  |  |  |  |  | delete $self->{'Socket'}; | 
| 243 | 0 |  |  |  |  |  | return 0; | 
| 244 |  |  |  |  |  |  | } | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | sub create { | 
| 247 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 248 |  |  |  |  |  |  |  | 
| 249 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 250 | 0 |  |  |  |  |  | return 1; | 
| 251 |  |  |  |  |  |  | } | 
| 252 | 0 | 0 | 0 |  |  |  | if ((scalar(@_) != 1) && (scalar(@_) != 2)) { | 
| 253 | 0 |  |  |  |  |  | $self->_error("create", "incorrect number of arguments"); | 
| 254 | 0 |  |  |  |  |  | return 1; | 
| 255 |  |  |  |  |  |  | } | 
| 256 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 257 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 258 | 0 | 0 |  |  |  |  | if (scalar(@_) == 1) { # a partition exists | 
| 259 | 0 |  |  |  |  |  | print $fh qq{try CREATE "$mailbox" $_[0]\n}; | 
| 260 |  |  |  |  |  |  | } else { | 
| 261 | 0 |  |  |  |  |  | print $fh qq{try CREATE "$mailbox"\n}; | 
| 262 |  |  |  |  |  |  | } | 
| 263 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 264 | 0 | 0 |  |  |  |  | if ($try =~ /^try OK/) { | 
| 265 | 0 |  |  |  |  |  | $self->{'Error'} = 'No Errors'; | 
| 266 | 0 |  |  |  |  |  | return 0; | 
| 267 |  |  |  |  |  |  | } else { | 
| 268 | 0 |  |  |  |  |  | $self->_error("create", "couldn't create", $mailbox, ":", $try); | 
| 269 | 0 |  |  |  |  |  | return 1; | 
| 270 |  |  |  |  |  |  | } | 
| 271 |  |  |  |  |  |  | } | 
| 272 |  |  |  |  |  |  |  | 
| 273 |  |  |  |  |  |  | sub rename { | 
| 274 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 275 |  |  |  |  |  |  |  | 
| 276 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 277 | 0 |  |  |  |  |  | return 1; | 
| 278 |  |  |  |  |  |  | } | 
| 279 | 0 | 0 | 0 |  |  |  | if ((scalar(@_) != 2) && (scalar(@_) != 3)) { | 
| 280 | 0 |  |  |  |  |  | $self->_error("rename", "incorrect number of arguments"); | 
| 281 | 0 |  |  |  |  |  | return 1; | 
| 282 |  |  |  |  |  |  | } | 
| 283 | 0 |  |  |  |  |  | my $old_name = shift; | 
| 284 | 0 |  |  |  |  |  | my $new_name = shift; | 
| 285 | 0 |  |  |  |  |  | my $partition = shift; | 
| 286 |  |  |  |  |  |  |  | 
| 287 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 288 | 0 | 0 |  |  |  |  | if (defined $partition) { | 
| 289 | 0 |  |  |  |  |  | print $fh qq{try RENAME "$old_name" "$new_name" $partition\n}; | 
| 290 |  |  |  |  |  |  | } else { | 
| 291 | 0 |  |  |  |  |  | print $fh qq{try RENAME "$old_name" "$new_name"\n}; | 
| 292 |  |  |  |  |  |  | } | 
| 293 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 294 | 0 | 0 | 0 |  |  |  | if (($try =~ /^try OK/) || ($try =~ /^\* OK/)) { | 
| 295 | 0 |  |  |  |  |  | $self->{'Error'} = 'No Errors'; | 
| 296 | 0 |  |  |  |  |  | return 0; | 
| 297 |  |  |  |  |  |  | } else { | 
| 298 | 0 |  |  |  |  |  | $self->_error("rename", "couldn't rename", $old_name, "to", $new_name, | 
| 299 |  |  |  |  |  |  | ":", $try); | 
| 300 | 0 |  |  |  |  |  | return 1; | 
| 301 |  |  |  |  |  |  | } | 
| 302 |  |  |  |  |  |  | } | 
| 303 |  |  |  |  |  |  |  | 
| 304 |  |  |  |  |  |  | sub delete { | 
| 305 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 306 |  |  |  |  |  |  |  | 
| 307 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 308 | 0 |  |  |  |  |  | return 1; | 
| 309 |  |  |  |  |  |  | } | 
| 310 | 0 | 0 |  |  |  |  | if (scalar(@_) != 1) { | 
| 311 | 0 |  |  |  |  |  | $self->_error("delete", "incorrect number of arguments"); | 
| 312 | 0 |  |  |  |  |  | return 1; | 
| 313 |  |  |  |  |  |  | } | 
| 314 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 315 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 316 | 0 |  |  |  |  |  | print $fh qq{try DELETE "$mailbox"\n}; | 
| 317 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 318 | 0 | 0 |  |  |  |  | if ($try =~ /^try OK/) { | 
| 319 | 0 |  |  |  |  |  | $self->{'Error'} = 'No Errors'; | 
| 320 | 0 |  |  |  |  |  | return 0; | 
| 321 |  |  |  |  |  |  | } else { | 
| 322 | 0 |  |  |  |  |  | $self->_error("delete", "couldn't delete", $mailbox, ":", $try); | 
| 323 | 0 |  |  |  |  |  | return 1; | 
| 324 |  |  |  |  |  |  | } | 
| 325 |  |  |  |  |  |  | } | 
| 326 |  |  |  |  |  |  |  | 
| 327 |  |  |  |  |  |  | sub h_delete { | 
| 328 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 329 |  |  |  |  |  |  |  | 
| 330 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 331 | 0 |  |  |  |  |  | return 1; | 
| 332 |  |  |  |  |  |  | } | 
| 333 | 0 | 0 |  |  |  |  | if (scalar(@_) != 1) { | 
| 334 | 0 |  |  |  |  |  | $self->_error("h_delete", "incorrect number of arguments"); | 
| 335 | 0 |  |  |  |  |  | return 1; | 
| 336 |  |  |  |  |  |  | } | 
| 337 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 338 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 339 |  |  |  |  |  |  | # first get a list of all sub boxes then nuke them, accumulate errors | 
| 340 |  |  |  |  |  |  | # then do something intelligent with them (hmmmmm) | 
| 341 | 0 |  |  |  |  |  | my $box = join($self->{'Separator'}, $mailbox, "*"); | 
| 342 | 0 |  |  |  |  |  | my @sub_boxes = $self->list($box); | 
| 343 | 0 |  |  |  |  |  | push @sub_boxes, $mailbox; | 
| 344 |  |  |  |  |  |  | # uncomment following line if you are sanity checking h_delete | 
| 345 |  |  |  |  |  |  | # print "h_delete: got this list of sub boxes [@sub_boxes]\n"; | 
| 346 | 0 |  |  |  |  |  | foreach $box (@sub_boxes) { | 
| 347 | 0 |  |  |  |  |  | print $fh qq{try DELETE "$box"\n}; | 
| 348 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 349 | 0 | 0 |  |  |  |  | if ($try =~ /^try OK/) { | 
| 350 | 0 |  |  |  |  |  | $self->{'Error'} = 'No Errors'; | 
| 351 |  |  |  |  |  |  | } else { | 
| 352 | 0 |  |  |  |  |  | $self->_error("h_delete", "couldn't delete", | 
| 353 |  |  |  |  |  |  | $mailbox, ":", $try); | 
| 354 | 0 |  |  |  |  |  | return 1; # or just return on the first encountered error ? | 
| 355 |  |  |  |  |  |  | } | 
| 356 |  |  |  |  |  |  | } | 
| 357 | 0 |  |  |  |  |  | return 0; | 
| 358 |  |  |  |  |  |  | } | 
| 359 |  |  |  |  |  |  |  | 
| 360 |  |  |  |  |  |  | sub get_quotaroot { # returns an array or undef | 
| 361 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 362 | 0 |  |  |  |  |  | my (@quota, @info); | 
| 363 |  |  |  |  |  |  |  | 
| 364 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 365 | 0 |  |  |  |  |  | return 1; | 
| 366 |  |  |  |  |  |  | } | 
| 367 | 0 | 0 |  |  |  |  | if (!($self->{'Capability'} =~ /QUOTA/)) { | 
| 368 | 0 |  |  |  |  |  | $self->_error("get_quotaroot", "QUOTA not listed in server's capabilities"); | 
| 369 | 0 |  |  |  |  |  | return 1; | 
| 370 |  |  |  |  |  |  | } | 
| 371 | 0 | 0 |  |  |  |  | if (scalar(@_) != 1) { | 
| 372 | 0 |  |  |  |  |  | $self->_error("get_quotaroot", "incorrect number of arguments"); | 
| 373 | 0 |  |  |  |  |  | return 1; | 
| 374 |  |  |  |  |  |  | } | 
| 375 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 376 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 377 | 0 |  |  |  |  |  | print $fh qq{try GETQUOTAROOT "$mailbox"\n}; | 
| 378 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 379 | 0 |  |  |  |  |  | while ($try =~ /^\* QUOTA/) { | 
| 380 | 0 | 0 |  |  |  |  | if ($try !~ /QUOTAROOT/) { # some imap servers give this extra line | 
| 381 | 0 |  |  |  |  |  | @info = ($try =~ /QUOTA\s(.*?)\s\(STORAGE\s(\d+)\s(\d+)/); | 
| 382 | 0 |  |  |  |  |  | push @quota, @info; | 
| 383 |  |  |  |  |  |  | } | 
| 384 | 0 |  |  |  |  |  | $try = $self->_read; | 
| 385 |  |  |  |  |  |  | } | 
| 386 | 0 | 0 |  |  |  |  | if ($try =~ /^try OK/) { | 
| 387 | 0 |  |  |  |  |  | return @quota; | 
| 388 |  |  |  |  |  |  | } else { | 
| 389 | 0 |  |  |  |  |  | $self->_error("get_quotaroot", "couldn't get quota for", $mailbox, ":", $try); | 
| 390 | 0 |  |  |  |  |  | return; | 
| 391 |  |  |  |  |  |  | } | 
| 392 |  |  |  |  |  |  | } | 
| 393 |  |  |  |  |  |  |  | 
| 394 |  |  |  |  |  |  | sub get_quota { # returns an array or undef | 
| 395 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 396 | 0 |  |  |  |  |  | my (@quota, @info); | 
| 397 |  |  |  |  |  |  |  | 
| 398 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 399 | 0 |  |  |  |  |  | return; | 
| 400 |  |  |  |  |  |  | } | 
| 401 | 0 | 0 |  |  |  |  | if (!($self->{'Capability'} =~ /QUOTA/)) { | 
| 402 | 0 |  |  |  |  |  | $self->_error("get_quota", | 
| 403 |  |  |  |  |  |  | "QUOTA not listed in server's capabilities"); | 
| 404 | 0 |  |  |  |  |  | return; | 
| 405 |  |  |  |  |  |  | } | 
| 406 | 0 | 0 |  |  |  |  | if (scalar(@_) != 1) { | 
| 407 | 0 |  |  |  |  |  | $self->_error("get_quota", "incorrect number of arguments"); | 
| 408 | 0 |  |  |  |  |  | return; | 
| 409 |  |  |  |  |  |  | } | 
| 410 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 411 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 412 | 0 |  |  |  |  |  | print $fh qq{try GETQUOTA "$mailbox"\n}; | 
| 413 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 414 | 0 |  |  |  |  |  | while ($try =~ /^\* QUOTA/) { | 
| 415 | 0 |  |  |  |  |  | @info = ($try =~ /QUOTA\s(.*?)\s\(STORAGE\s(\d+)\s(\d+)/); | 
| 416 | 0 |  |  |  |  |  | push @quota, @info; | 
| 417 | 0 |  |  |  |  |  | $try = $self->_read; | 
| 418 |  |  |  |  |  |  | } | 
| 419 | 0 | 0 |  |  |  |  | if ($try =~ /^try OK/) { | 
| 420 | 0 |  |  |  |  |  | return @quota; | 
| 421 |  |  |  |  |  |  | } else { | 
| 422 | 0 |  |  |  |  |  | $self->_error("get_quota", "couldn't get quota for", $mailbox, ":", $try); | 
| 423 | 0 |  |  |  |  |  | return; | 
| 424 |  |  |  |  |  |  | } | 
| 425 |  |  |  |  |  |  | } | 
| 426 |  |  |  |  |  |  |  | 
| 427 |  |  |  |  |  |  | sub set_quota { | 
| 428 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 429 |  |  |  |  |  |  |  | 
| 430 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 431 | 0 |  |  |  |  |  | return 1; | 
| 432 |  |  |  |  |  |  | } | 
| 433 | 0 | 0 |  |  |  |  | if (!($self->{'Capability'} =~ /QUOTA/)) { | 
| 434 | 0 |  |  |  |  |  | $self->_error("set_quota", "QUOTA not listed in server's capabilities"); | 
| 435 | 0 |  |  |  |  |  | return 1; | 
| 436 |  |  |  |  |  |  | } | 
| 437 | 0 | 0 |  |  |  |  | if (scalar(@_) != 2) { | 
| 438 | 0 |  |  |  |  |  | $self->_error("set_quota", "incorrect number of arguments"); | 
| 439 | 0 |  |  |  |  |  | return 1; | 
| 440 |  |  |  |  |  |  | } | 
| 441 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 442 | 0 |  |  |  |  |  | my $quota = shift; | 
| 443 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 444 | 0 | 0 |  |  |  |  | if ($quota eq "none") { | 
| 445 | 0 |  |  |  |  |  | print $fh qq{try SETQUOTA "$mailbox" ()\n}; | 
| 446 |  |  |  |  |  |  | } else { | 
| 447 | 0 |  |  |  |  |  | print $fh qq{try SETQUOTA "$mailbox" (STORAGE $quota)\n}; | 
| 448 |  |  |  |  |  |  | } | 
| 449 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 450 | 0 | 0 |  |  |  |  | if ($try =~ /^try OK/) { | 
| 451 | 0 |  |  |  |  |  | $self->{'Error'} = "No Errors"; | 
| 452 | 0 |  |  |  |  |  | return 0; | 
| 453 |  |  |  |  |  |  | } else { | 
| 454 | 0 |  |  |  |  |  | $self->_error("set_quota", "couldn't set quota for", $mailbox, ":", $try); | 
| 455 | 0 |  |  |  |  |  | return 1; | 
| 456 |  |  |  |  |  |  | } | 
| 457 |  |  |  |  |  |  | } | 
| 458 |  |  |  |  |  |  |  | 
| 459 |  |  |  |  |  |  | sub subscribe { | 
| 460 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 461 |  |  |  |  |  |  |  | 
| 462 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 463 | 0 |  |  |  |  |  | return 1; | 
| 464 |  |  |  |  |  |  | } | 
| 465 | 0 | 0 |  |  |  |  | if (scalar(@_) != 1) { | 
| 466 | 0 |  |  |  |  |  | $self->_error("subscribe", "incorrect number of arguments"); | 
| 467 | 0 |  |  |  |  |  | return 1; | 
| 468 |  |  |  |  |  |  | } | 
| 469 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 470 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 471 | 0 |  |  |  |  |  | print $fh qq{try SUBSCRIBE "$mailbox"\n}; | 
| 472 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 473 | 0 | 0 |  |  |  |  | if ($try !~ /^try OK/) { | 
| 474 | 0 |  |  |  |  |  | $self->_error("subscribe", "couldn't suscribe ", $mailbox, ":", | 
| 475 |  |  |  |  |  |  | $try); | 
| 476 | 0 |  |  |  |  |  | return 1; | 
| 477 |  |  |  |  |  |  | } | 
| 478 | 0 |  |  |  |  |  | $self->{'Error'} = 'No Errors'; | 
| 479 | 0 |  |  |  |  |  | return 0; | 
| 480 |  |  |  |  |  |  | } | 
| 481 |  |  |  |  |  |  |  | 
| 482 |  |  |  |  |  |  | sub unsubscribe { | 
| 483 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 484 |  |  |  |  |  |  |  | 
| 485 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 486 | 0 |  |  |  |  |  | return 1; | 
| 487 |  |  |  |  |  |  | } | 
| 488 | 0 | 0 |  |  |  |  | if (scalar(@_) != 1) { | 
| 489 | 0 |  |  |  |  |  | $self->_error("unsubscribe", "incorrect number of arguments"); | 
| 490 | 0 |  |  |  |  |  | return 1; | 
| 491 |  |  |  |  |  |  | } | 
| 492 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 493 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 494 | 0 |  |  |  |  |  | print $fh qq{try UNSUBSCRIBE "$mailbox"\n}; | 
| 495 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 496 | 0 | 0 |  |  |  |  | if ($try !~ /^try OK/) { | 
| 497 | 0 |  |  |  |  |  | $self->_error("unsubscribe", "couldn't unsuscribe ", $mailbox, ":", | 
| 498 |  |  |  |  |  |  | $try); | 
| 499 | 0 |  |  |  |  |  | return 1; | 
| 500 |  |  |  |  |  |  | } | 
| 501 | 0 |  |  |  |  |  | $self->{'Error'} = 'No Errors'; | 
| 502 | 0 |  |  |  |  |  | return 0; | 
| 503 |  |  |  |  |  |  | } | 
| 504 |  |  |  |  |  |  |  | 
| 505 |  |  |  |  |  |  | sub select { # returns an array or undef | 
| 506 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 507 | 0 |  |  |  |  |  | my @info; | 
| 508 |  |  |  |  |  |  |  | 
| 509 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 510 | 0 |  |  |  |  |  | return 1; | 
| 511 |  |  |  |  |  |  | } | 
| 512 | 0 | 0 |  |  |  |  | if (scalar(@_) != 1) { | 
| 513 | 0 |  |  |  |  |  | $self->_error("select", "incorrect number of arguments"); | 
| 514 | 0 |  |  |  |  |  | return; | 
| 515 |  |  |  |  |  |  | } | 
| 516 |  |  |  |  |  |  |  | 
| 517 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 518 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 519 | 0 |  |  |  |  |  | print $fh qq{try SELECT "$mailbox"\n}; | 
| 520 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 521 | 0 |  |  |  |  |  | while ($try =~ /^\* (.*)/) { # danger danger (could lock up needs timeout) | 
| 522 | 0 |  |  |  |  |  | push @info, $1; | 
| 523 | 0 |  |  |  |  |  | $try = $self->_read; | 
| 524 |  |  |  |  |  |  | } | 
| 525 | 0 | 0 |  |  |  |  | if ($try =~ /^try OK/) { | 
| 526 | 0 |  |  |  |  |  | return @info; | 
| 527 |  |  |  |  |  |  | } else { | 
| 528 | 0 |  |  |  |  |  | $self->_error("select", "couldn't select", $mailbox, ":", $try); | 
| 529 | 0 |  |  |  |  |  | return; | 
| 530 |  |  |  |  |  |  | } | 
| 531 |  |  |  |  |  |  | } | 
| 532 |  |  |  |  |  |  |  | 
| 533 |  |  |  |  |  |  | sub expunge { # returns an array or undef | 
| 534 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 535 | 0 |  |  |  |  |  | my @info; | 
| 536 |  |  |  |  |  |  |  | 
| 537 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 538 | 0 |  |  |  |  |  | return 1; | 
| 539 |  |  |  |  |  |  | } | 
| 540 | 0 | 0 |  |  |  |  | if (scalar(@_) != 0) { | 
| 541 | 0 |  |  |  |  |  | $self->_error("expunge", "incorrect number of arguments"); | 
| 542 | 0 |  |  |  |  |  | return; | 
| 543 |  |  |  |  |  |  | } | 
| 544 |  |  |  |  |  |  |  | 
| 545 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 546 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 547 | 0 |  |  |  |  |  | print $fh qq{try EXPUNGE\n}; | 
| 548 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 549 | 0 |  |  |  |  |  | while ($try =~ /^\* (.*)/) { # danger danger (could lock up needs timeout) | 
| 550 | 0 |  |  |  |  |  | push @info, $1; | 
| 551 | 0 |  |  |  |  |  | $try = $self->_read; | 
| 552 |  |  |  |  |  |  | } | 
| 553 | 0 | 0 |  |  |  |  | if ($try =~ /^try OK/) { | 
| 554 | 0 |  |  |  |  |  | return @info; | 
| 555 |  |  |  |  |  |  | } else { | 
| 556 | 0 |  |  |  |  |  | $self->_error("expunge", "couldn't expunge", $mailbox, ":", $try); | 
| 557 | 0 |  |  |  |  |  | return; | 
| 558 |  |  |  |  |  |  | } | 
| 559 |  |  |  |  |  |  | } | 
| 560 |  |  |  |  |  |  |  | 
| 561 |  |  |  |  |  |  | sub get_acl { # returns an array or undef | 
| 562 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 563 |  |  |  |  |  |  |  | 
| 564 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 565 | 0 |  |  |  |  |  | return; | 
| 566 |  |  |  |  |  |  | } | 
| 567 | 0 | 0 |  |  |  |  | if (!($self->{'Capability'} =~ /ACL/)) { | 
| 568 | 0 |  |  |  |  |  | $self->_error("get_acl", "ACL not listed in server's capabilities"); | 
| 569 | 0 |  |  |  |  |  | return; | 
| 570 |  |  |  |  |  |  | } | 
| 571 | 0 | 0 |  |  |  |  | if (scalar(@_) != 1) { | 
| 572 | 0 |  |  |  |  |  | $self->_error("get_acl", "incorrect number of arguments"); | 
| 573 | 0 |  |  |  |  |  | return; | 
| 574 |  |  |  |  |  |  | } | 
| 575 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 576 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 577 | 0 |  |  |  |  |  | print $fh qq{try GETACL "$mailbox"\n}; | 
| 578 | 0 |  |  |  |  |  | delete $self->{'acl'}; | 
| 579 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 580 | 0 |  |  |  |  |  | while ($try =~ /^\*\s+ACL\s+/) { | 
| 581 | 0 |  |  |  |  |  | my $acls = ($try =~ /^\* ACL\s+(?:\".*?\"|\S*)\s+(.*)/)[0]; # separate out the acls | 
| 582 | 0 |  |  |  |  |  | my @acls = ($acls =~ /(\".*?\"|\S+)\s*/g); # split up over ws, unless quoted | 
| 583 | 0 |  |  |  |  |  | push @{$self->{'acl'}}, @acls; | 
|  | 0 |  |  |  |  |  |  | 
| 584 | 0 |  |  |  |  |  | $try = $self->_read; | 
| 585 |  |  |  |  |  |  | } | 
| 586 | 0 | 0 |  |  |  |  | if ($try =~ /^try OK/) { | 
| 587 | 0 |  |  |  |  |  | return @{$self->{'acl'}}; | 
|  | 0 |  |  |  |  |  |  | 
| 588 |  |  |  |  |  |  | } else { | 
| 589 | 0 |  |  |  |  |  | $self->_error("get_acl", "couldn't get acl for", $mailbox, ":", $try); | 
| 590 | 0 |  |  |  |  |  | return; | 
| 591 |  |  |  |  |  |  | } | 
| 592 |  |  |  |  |  |  | } | 
| 593 |  |  |  |  |  |  |  | 
| 594 |  |  |  |  |  |  | sub set_acl { | 
| 595 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 596 | 0 |  |  |  |  |  | my ($id, $acl); | 
| 597 |  |  |  |  |  |  |  | 
| 598 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 599 | 0 |  |  |  |  |  | return 1; | 
| 600 |  |  |  |  |  |  | } | 
| 601 | 0 | 0 |  |  |  |  | if (!($self->{'Capability'} =~ /ACL/)) { | 
| 602 | 0 |  |  |  |  |  | $self->_error("set_acl", "ACL not listed in server's capabilities"); | 
| 603 | 0 |  |  |  |  |  | return 1; | 
| 604 |  |  |  |  |  |  | } | 
| 605 | 0 | 0 |  |  |  |  | if (scalar(@_) < 2) { | 
| 606 | 0 |  |  |  |  |  | $self->_error("set_acl", "too few arguments"); | 
| 607 | 0 |  |  |  |  |  | return 1; | 
| 608 |  |  |  |  |  |  | } | 
| 609 | 0 | 0 |  |  |  |  | if ((scalar(@_) % 2) == 0) { | 
| 610 | 0 |  |  |  |  |  | $self->_error("set_acl", "incorrect number of arguments"); | 
| 611 | 0 |  |  |  |  |  | return 1; | 
| 612 |  |  |  |  |  |  | } | 
| 613 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 614 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 615 | 0 |  |  |  |  |  | while(@_) { | 
| 616 | 0 |  |  |  |  |  | $id = shift; | 
| 617 | 0 |  |  |  |  |  | $acl = shift; | 
| 618 | 0 |  |  |  |  |  | print $fh qq{try SETACL "$mailbox" "$id" "$acl"\n}; | 
| 619 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 620 | 0 | 0 |  |  |  |  | if ($try !~ /^try OK/) { | 
| 621 | 0 |  |  |  |  |  | $self->_error("set_acl", "couldn't set acl for", $mailbox, $id, | 
| 622 |  |  |  |  |  |  | $acl, ":", $try); | 
| 623 | 0 |  |  |  |  |  | return 1; | 
| 624 |  |  |  |  |  |  | } | 
| 625 |  |  |  |  |  |  | } | 
| 626 | 0 |  |  |  |  |  | $self->{'Error'} = 'No Errors'; | 
| 627 | 0 |  |  |  |  |  | return 0; | 
| 628 |  |  |  |  |  |  | } | 
| 629 |  |  |  |  |  |  |  | 
| 630 |  |  |  |  |  |  | sub delete_acl { | 
| 631 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 632 | 0 |  |  |  |  |  | my ($id, $acl); | 
| 633 |  |  |  |  |  |  |  | 
| 634 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 635 | 0 |  |  |  |  |  | return 1; | 
| 636 |  |  |  |  |  |  | } | 
| 637 | 0 | 0 |  |  |  |  | if (!($self->{'Capability'} =~ /ACL/)) { | 
| 638 | 0 |  |  |  |  |  | $self->_error("delete_acl", "ACL not listed in server's capabilities"); | 
| 639 | 0 |  |  |  |  |  | return 1; | 
| 640 |  |  |  |  |  |  | } | 
| 641 | 0 | 0 |  |  |  |  | if (scalar(@_) < 1) { | 
| 642 | 0 |  |  |  |  |  | $self->_error("delete_acl", "incorrect number of arguments"); | 
| 643 | 0 |  |  |  |  |  | return 1; | 
| 644 |  |  |  |  |  |  | } | 
| 645 | 0 |  |  |  |  |  | my $mailbox = shift; | 
| 646 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 647 | 0 |  |  |  |  |  | while(@_) { | 
| 648 | 0 |  |  |  |  |  | $id = shift; | 
| 649 | 0 |  |  |  |  |  | print $fh qq{try DELETEACL "$mailbox" "$id"\n}; | 
| 650 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 651 | 0 | 0 |  |  |  |  | if ($try !~ /^try OK/) { | 
| 652 | 0 |  |  |  |  |  | $self->_error("delete_acl", "couldn't delete acl for", $mailbox, | 
| 653 |  |  |  |  |  |  | $id, $acl, ":", $try); | 
| 654 | 0 |  |  |  |  |  | return 1; | 
| 655 |  |  |  |  |  |  | } | 
| 656 |  |  |  |  |  |  | } | 
| 657 | 0 |  |  |  |  |  | return 0; | 
| 658 |  |  |  |  |  |  | } | 
| 659 |  |  |  |  |  |  |  | 
| 660 |  |  |  |  |  |  | sub list { # wild cards are allowed, returns array or undef | 
| 661 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 662 | 0 |  |  |  |  |  | my (@info, @mail); | 
| 663 |  |  |  |  |  |  |  | 
| 664 | 0 | 0 |  |  |  |  | if (!defined($self->{'Socket'})) { | 
| 665 | 0 |  |  |  |  |  | return; | 
| 666 |  |  |  |  |  |  | } | 
| 667 | 0 | 0 |  |  |  |  | if (scalar(@_) != 1) { | 
| 668 | 0 |  |  |  |  |  | $self->_error("list", "incorrect number of arguments"); | 
| 669 | 0 |  |  |  |  |  | return; | 
| 670 |  |  |  |  |  |  | } | 
| 671 | 0 |  |  |  |  |  | my $list = shift; | 
| 672 | 0 |  |  |  |  |  | my $fh = $self->{'Socket'}; | 
| 673 | 0 |  |  |  |  |  | print $fh qq{try LIST "" "$list"\n}; | 
| 674 | 0 |  |  |  |  |  | my $try = $self->_read; | 
| 675 | 0 |  |  |  |  |  | while ($try =~ /^\* LIST.*?\) \".\" \"*(.*?)\"*$/) { # danger danger (could lock up needs timeout) " <- this quote makes emacs happy | 
| 676 | 0 |  |  |  |  |  | push @mail, $1; | 
| 677 | 0 |  |  |  |  |  | $try = $self->_read; | 
| 678 |  |  |  |  |  |  | } | 
| 679 | 0 | 0 |  |  |  |  | if ($try =~ /^try OK/) { | 
| 680 | 0 |  |  |  |  |  | return @mail; | 
| 681 |  |  |  |  |  |  | } else { | 
| 682 | 0 |  |  |  |  |  | $self->_error("list", "couldn't get list for", $list, ":", $try); | 
| 683 | 0 |  |  |  |  |  | return; | 
| 684 |  |  |  |  |  |  | } | 
| 685 |  |  |  |  |  |  | } | 
| 686 |  |  |  |  |  |  |  | 
| 687 |  |  |  |  |  |  |  | 
| 688 |  |  |  |  |  |  | # Autoload methods go after =cut, and are processed by the autosplit program. | 
| 689 |  |  |  |  |  |  |  | 
| 690 |  |  |  |  |  |  | 1; | 
| 691 |  |  |  |  |  |  | __END__ |