#!/usr/bin/perl -w # -- # bin/PostMasterPOP3.pl - the global eMail handle for email2db # Copyright (C) 2001-2007 OTRS GmbH, http://otrs.org/ # -- # $Id: PostMasterPOP3.pl,v 1.25 2007/03/19 22:27:19 martin Exp $ # -- # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -- # use ../ as lib location use File::Basename; use FindBin qw($RealBin); use lib dirname($RealBin); use lib dirname($RealBin)."/Kernel/cpan-lib"; use vars qw($VERSION); $VERSION = '$Revision: 1.25 $'; $VERSION =~ s/^\$.*:\W(.*)\W.+?$/$1/; use strict; use Net::POP3; use Getopt::Std; use Kernel::Config; use Kernel::System::Log; use Kernel::System::Main; use Kernel::System::Time; use Kernel::System::DB; use Kernel::System::PID; use Kernel::System::PostMaster; use Kernel::System::POP3Account; # get options my %Opts = (); getopt('upshdf', \%Opts); if ($Opts{'h'}) { print "PostMasterPOP3.pl - POP3 to OTRS\n"; print "Copyright (c) 2001-2006 OTRS GmbH, http://otrs.org/\n"; print "usage: PostMasterPOP3.pl -s -u -p [-d 1-2] [-f force]\n"; exit 1; } if (!$Opts{'t'}) { $Opts{'t'} = 60; } if (!$Opts{'d'}) { $Opts{'d'} = 0; } if (!$Opts{'popd'}) { $Opts{'popd'} = 0; } # create common objects my %CommonObject = (); $CommonObject{ConfigObject} = Kernel::Config->new(); $CommonObject{LogObject} = Kernel::System::Log->new( LogPrefix => 'OTRS-PM3', %CommonObject, ); $CommonObject{MainObject} = Kernel::System::Main->new(%CommonObject); $CommonObject{TimeObject} = Kernel::System::Time->new(%CommonObject); $CommonObject{DBObject} = Kernel::System::DB->new(%CommonObject); $CommonObject{PIDObject} = Kernel::System::PID->new(%CommonObject); $CommonObject{POP3Account} = Kernel::System::POP3Account->new(%CommonObject); # MaxEmailSize my $MaxEmailSize = $CommonObject{ConfigObject}->Get('PostMasterPOP3MaxEmailSize') || 1024 * 6; # MaxPopEmailSession my $MaxPopEmailSession = $CommonObject{ConfigObject}->Get('PostMasterPOP3ReconnectMessage') || 20; # create pid lock if (!$Opts{'f'} && !$CommonObject{PIDObject}->PIDCreate(Name => 'PostMasterPOP3')) { print "Notice: PostMasterPOP3.pl is already running (use '-f 1' if you want to start it forced)!\n"; exit 1; } elsif ($Opts{'f'} && !$CommonObject{PIDObject}->PIDCreate(Name => 'PostMasterPOP3')) { print "Notice: PostMasterPOP3.pl is already running but is starting again!\n"; } # debug info if ($Opts{'d'} > 1) { $CommonObject{LogObject}->Log( Priority => 'debug', Message => 'Global OTRS email handle (PostMasterPOP3.pl) started...', ); } my %List = (); if ($Opts{'s'} || $Opts{'u'} || $Opts{'p'}) { if (!$Opts{'s'}) { # delete pid lock $CommonObject{PIDObject}->PIDDelete(Name => 'PostMasterPOP3'); print STDERR "ERROR: Need -s \n"; exit 1; } if (!$Opts{'u'}) { # delete pid lock $CommonObject{PIDObject}->PIDDelete(Name => 'PostMasterPOP3'); print STDERR "ERROR: Need -u \n"; exit 1; } if (!$Opts{'p'}) { # delete pid lock $CommonObject{PIDObject}->PIDDelete(Name => 'PostMasterPOP3'); print STDERR "ERROR: Need -p \n"; exit 1; } FetchMail( Login => $Opts{'u'}, Password => $Opts{'p'}, Host => $Opts{'s'}, ); } else { %List = $CommonObject{POP3Account}->POP3AccountList(Valid => 1); foreach (keys %List) { my %Data = $CommonObject{POP3Account}->POP3AccountGet(ID => $_); FetchMail(%Data); } } # debug info if ($Opts{'d'} > 1) { $CommonObject{LogObject}->Log( Priority => 'debug', Message => 'Global OTRS email handle (PostMasterPOP3.pl) stoped.', ); } # delete pid lock $CommonObject{PIDObject}->PIDDelete(Name => 'PostMasterPOP3'); exit (0); sub FetchMail { my %Param = @_; my $User = $Param{Login}; my $Password = $Param{Password}; my $Host = $Param{Host}; my $QueueID = $Param{QueueID} || 0; my $Trusted = $Param{Trusted} || 0; my $FetchCounter = 0; my $Reconnect = 0; # connect to host my $PopObject = Net::POP3->new($Host, Timeout => $Opts{'t'}, Debug => $Opts{'popd'}); if (!$PopObject) { $CommonObject{LogObject}->Log( Priority => 'error', Message => "Can't connect to $Host", ); return; } # authentcation my $NOM = $PopObject->login($User, $Password); if (!defined($NOM)) { $PopObject->quit(); $CommonObject{LogObject}->Log( Priority => 'error', Message => "Auth for user $User\@$Host failed!", ); return; } # fetch messages if ($NOM > 0) { foreach my $Messageno ( sort { $a <=> $b } keys %{$PopObject->list()}) { # check if reconnect is needed if (($FetchCounter+1) > $MaxPopEmailSession) { $Reconnect = 1; print "Reconnect Session after $MaxPopEmailSession messages...\n"; last; } print "Message $Messageno/$NOM ($User\@$Host)\n"; # check message size my $MessageSize = int($PopObject->list($Messageno) / 1024); if ($MessageSize > $MaxEmailSize) { $CommonObject{LogObject}->Log( Priority => 'error', Message => "Can't fetch email $NOM from $User\@$Host. Email to ". "big ($MessageSize KB - max $MaxEmailSize KB)!", ); } else { # safety protection $FetchCounter++; if ($FetchCounter > 10 && $FetchCounter < 25) { print "Safety protection waiting 2 second till processing next mail...\n"; sleep 2; } elsif ($FetchCounter > 25) { print "Safety protection waiting 3 seconds till processing next mail...\n"; sleep 3; } # get message (header and body) my $Lines = $PopObject->get($Messageno); $CommonObject{PostMaster} = Kernel::System::PostMaster->new( %CommonObject, Email => $Lines, Trusted => $Trusted, Debug => $Opts{'d'}, ); my @Return = $CommonObject{PostMaster}->Run( QueueID => $QueueID, ); if (!$Return[0]) { $CommonObject{LogObject}->Log( Priority => 'error', Message => "Can't process mail, see log sub system!", ); } undef $CommonObject{PostMaster}; $PopObject->delete($Messageno); } print "\n"; } } else { print "No messages ($User\@$Host)\n"; } # log status if ($Opts{'d'} > 0 || $FetchCounter) { $CommonObject{LogObject}->Log( Priority => 'notice', Message => "Fetched $FetchCounter email(s) from $User\@$Host.", ); } $PopObject->quit(); print "Connection to $Host closed.\n\n"; # fetch again if still messages on the account if ($Reconnect) { FetchMail(%Param); } }