sub
description {
'IPSWITCH IMail Server'
}
sub
make {
my
$class
=
shift
;
my
$mhead
=
shift
//
return
undef
;
my
$mbody
=
shift
//
return
undef
;
my
$match
= 0;
$match
||= 1
if
$mhead
->{
'subject'
} =~ /\AUndeliverable Mail[ ]*\z/;
$match
||= 1
if
defined
$mhead
->{
'x-mailer'
} &&
index
(
$mhead
->{
'x-mailer'
},
'<SMTP32 v'
) == 0;
return
undef
unless
$match
;
state
$rebackbone
=
qr|^Original[ ]message[ ]follows[.]|
m;
state
$startingof
= {
'error'
=> [
'Body of message generated response:'
] };
state
$recommands
= {
'conn'
=>
qr/(?:SMTP connection failed,|Unexpected connection response from server:)/
,
'ehlo'
=>
qr|Unexpected response to EHLO/HELO:|
,
'mail'
=>
qr|Server response to MAIL FROM:|
,
'rcpt'
=>
qr|Additional RCPT TO generated following response:|
,
'data'
=>
qr|DATA command generated response:|
,
};
state
$refailures
= {
'hostunknown'
=>
qr/Unknown host/
,
'userunknown'
=>
qr/\A(?:Unknown user|Invalid final delivery userid)/
,
'mailboxfull'
=>
qr/\AUser mailbox exceeds allowed size/
,
'virusdetected'
=>
qr/\ARequested action not taken: virus detected/
,
'undefined'
=>
qr/\Aundeliverable to/
,
'expired'
=>
qr/\ADelivery failed \d+ attempts/
,
};
my
$dscontents
= [__PACKAGE__->DELIVERYSTATUS];
my
$emailsteak
= Sisimai::RFC5322->fillet(
$mbody
,
$rebackbone
);
my
$recipients
= 0;
my
$v
=
undef
;
for
my
$e
(
split
(
"\n"
,
$emailsteak
->[0]) ) {
$v
=
$dscontents
->[-1];
if
(
$e
=~ /\A([^ ]+)[ ](.+)[:][ \t]*([^ ]+[@][^ ]+)/ ) {
if
(
$v
->{
'recipient'
} ) {
push
@$dscontents
, __PACKAGE__->DELIVERYSTATUS;
$v
=
$dscontents
->[-1];
}
$v
->{
'diagnosis'
} = $1.
' '
.$2;
$v
->{
'recipient'
} = $3;
$recipients
++;
}
elsif
(
$e
=~ /\Aundeliverable[ ]+to[ ]+(.+)\z/ ) {
if
(
$v
->{
'recipient'
} ) {
push
@$dscontents
, __PACKAGE__->DELIVERYSTATUS;
$v
=
$dscontents
->[-1];
}
$v
->{
'recipient'
} = Sisimai::Address->s3s4($1);
$recipients
++;
}
else
{
$v
->{
'alterrors'
} //=
''
;
$v
->{
'alterrors'
} .=
' '
.
$e
if
$v
->{
'alterrors'
};
$v
->{
'alterrors'
} =
$e
if
index
(
$e
,
$startingof
->{
'error'
}->[0]) > -1;
}
}
return
undef
unless
$recipients
;
for
my
$e
(
@$dscontents
) {
if
(
exists
$e
->{
'alterrors'
} &&
$e
->{
'alterrors'
} ) {
$e
->{
'diagnosis'
} =
$e
->{
'alterrors'
}.
' '
.
$e
->{
'diagnosis'
};
$e
->{
'diagnosis'
} = Sisimai::String->sweep(
$e
->{
'diagnosis'
});
delete
$e
->{
'alterrors'
};
}
$e
->{
'diagnosis'
} = Sisimai::String->sweep(
$e
->{
'diagnosis'
});
COMMAND:
for
my
$r
(
keys
%$recommands
) {
next
unless
$e
->{
'diagnosis'
} =~
$recommands
->{
$r
};
$e
->{
'command'
} =
uc
$r
;
last
;
}
SESSION:
for
my
$r
(
keys
%$refailures
) {
next
unless
$e
->{
'diagnosis'
} =~
$refailures
->{
$r
};
$e
->{
'reason'
} =
$r
;
last
;
}
}
return
{
'ds'
=>
$dscontents
,
'rfc822'
=>
$emailsteak
->[1] };
}
1;