#===================================================================== # POP3Auth.pm : Simple POP3 Authenticate module # # Copyright(c) N.Oishi (BSC CONSULTING CGI-Laboratory). # # e-mail : bigstone@my.email.ne.jp # support: http://www.din.or.jp/~bigstone/cgilab/index.html # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED. # # ver 1.0.2 : updated last on 2002/02/14 # #===================================================================== package POP3Auth; use TCP; use strict; use integer; use vars qw($VERSION); $VERSION = '1.0.2'; sub new { my $class = shift; my $self = {}; my($k, $v); while (($k, $v) = splice(@_, 0, 2)){ $self->{lc($k)} = $v; } $self->{socket} = TCP->connect($self->{host}, $self->{port} || 110, $self->{timeout}) || return undef; bless $self, ref $class || $class; unless($self->_command()){ $self->close(); return undef; } if($self->{status} =~ /(<[^>]+>)/o){ $self->{banner} = $1; } return $self; } sub login { my $self = shift; my($user, $pass) = @_; $self->{user} = $user; $self->user($user) and $self->pass($pass); } sub user { shift->_command('USER', $_[0]); } sub pass { my $self = shift; my $status = $self->_command('PASS', $_[0]) || return undef; $self->stat(); $status; } sub apop { my $self = shift; eval { require Digest::MD5; Digest::MD5->import('md5_hex'); }; if($@){ return undef; } my($user, $pass) = @_; my $banner = $self->{banner} || return undef; my $status = $self->_command('APOP', $user, md5_hex($banner, $pass)) || return undef; $self->stat(); $status; } sub stat { my $self = shift; unless(defined $self->{count}){ my $status = $self->_command('STAT') || return undef; my($count, $size) = $status =~ /(\d+)\D+(\d+)/o; $self->{count} = $count || 0; $self->{size} = $size || 0; } return wantarray ? ($self->{count}, $self->{size}) : $self->{count}; } sub quit { my $self = shift; my $status = $self->_command('QUIT') || return undef; $self->close(); return $status; } sub close { my $self = shift; if(my $sock = delete $self->{socket}){ $sock->close(); } } sub status { shift->{status}; } sub is_success { shift->{status} =~ /^\+OK/o; } sub _command { my $self = shift; my $cmd = shift; my $sock = $self->{socket} || return undef; $self->{status} = undef; if($cmd){ $cmd = join(' ', $cmd, @_) if @_; unless($sock->write("$cmd\n")){ return undef; } } my $status = $sock->read() || return undef; $status =~ s/[\r\n]//sgo; $self->{status} = $status; return ($status =~ /^\+OK/o) ? $status : undef; } 1; __END__