mirror of
https://github.com/imapsync/imapsync.git
synced 2025-06-05 12:17:16 +02:00
189 lines
5.5 KiB
Text
189 lines
5.5 KiB
Text
# Directives
|
|
# ( none)
|
|
# Start-up Actions
|
|
|
|
{
|
|
my $mibs = "Mail::IMAPClient::BodyStructure";
|
|
my $subpartCount = 0;
|
|
my $partCount = 0;
|
|
|
|
sub take_optional_items($$@)
|
|
{ my ($r, $items) = (shift, shift);
|
|
foreach (@_)
|
|
{ my $opt = $_ .'(?)';
|
|
exists $items->{$opt} or next;
|
|
$r->{$_} = UNIVERSAL::isa($items->{$opt}, 'ARRAY')
|
|
? $items->{$opt}[0] : $items->{$opt};
|
|
}
|
|
}
|
|
|
|
sub merge_hash($$)
|
|
{ my $to = shift;
|
|
my $from = shift or return;
|
|
while( my($k,$v) = each %$from) { $to->{$k} = $v }
|
|
}
|
|
}
|
|
|
|
# Atoms
|
|
|
|
TEXT: /^"TEXT"|^TEXT/i { $return = "TEXT" }
|
|
PLAIN: /^"PLAIN"|^PLAIN/i { $return = "PLAIN" }
|
|
HTML: /"HTML"|HTML/i { $return = "HTML" }
|
|
MESSAGE: /^"MESSAGE"|^MESSAGE/i { $return = "MESSAGE"}
|
|
RFC822: /^"RFC822"|^RFC822/i { $return = "RFC822" }
|
|
NIL: /^NIL/i { $return = "NIL" }
|
|
RFCNONCOMPLY: /^\(\)/i { $return = "NIL" }
|
|
NUMBER: /^(\d+)/ { $return = $item[1] }
|
|
|
|
# Strings:
|
|
|
|
SINGLE_QUOTED_STRING: "'" /(?:\\'|[^'])*/ "'" { $return = $item{__PATTERN1__} }
|
|
DOUBLE_QUOTED_STRING: '"' /(?:\\"|[^"])*/ '"' { $return = $item{__PATTERN1__} }
|
|
|
|
BARESTRING: ...!/^[)('"]/ /^(?!\(|\))(?:\\ |\S)+/
|
|
{ $return = $item{__PATTERN1__} }
|
|
|
|
STRING: DOUBLE_QUOTED_STRING | SINGLE_QUOTED_STRING | BARESTRING
|
|
|
|
STRINGS: "(" STRING(s) ")" { $return = $item{'STRING(s)'} }
|
|
|
|
textlines: NIL | NUMBER
|
|
|
|
rfc822message: MESSAGE RFC822 { $return = "MESSAGE RFC822" }
|
|
|
|
bodysubtype: PLAIN | HTML | NIL | STRING
|
|
|
|
key: STRING
|
|
value: NIL | NUMBER | STRING | KVPAIRS
|
|
|
|
kvpair: ...!")" key value
|
|
{ $return = { $item{key} => $item{value} } }
|
|
|
|
KVPAIRS: "(" kvpair(s) ")"
|
|
{ $return = { map { (%$_) } @{$item{'kvpair(s)'}} } }
|
|
|
|
bodytype: STRING
|
|
bodyparms: NIL | KVPAIRS
|
|
bodydisp: NIL | KVPAIRS
|
|
bodyid: ...!/[()]/ NIL | STRING
|
|
bodydesc: ...!/[()]/ NIL | STRING
|
|
bodysize: ...!/[()]/ NIL | NUMBER
|
|
bodyenc: NIL | STRING | KVPAIRS
|
|
bodyMD5: NIL | STRING
|
|
bodylang: NIL | STRING | STRINGS
|
|
bodyextra: NIL | STRING | STRINGS
|
|
bodyloc: NIL | STRING
|
|
|
|
personalname: NIL | STRING
|
|
sourceroute: NIL | STRING
|
|
mailboxname: NIL | STRING
|
|
hostname: NIL | STRING
|
|
|
|
addressstruct: "(" personalname sourceroute mailboxname hostname ")"
|
|
{ bless { personalname => $item{personalname}
|
|
, sourceroute => $item{sourceroute}
|
|
, mailboxname => $item{mailboxname}
|
|
, hostname => $item{hostname}
|
|
}, 'Mail::IMAPClient::BodyStructure::Address';
|
|
}
|
|
|
|
subject: NIL | STRING
|
|
inreplyto: NIL | STRING
|
|
messageid: NIL | STRING
|
|
date: NIL | STRING
|
|
|
|
ADDRESSES: NIL | RFCNONCOMPLY
|
|
| "(" addressstruct(s) ")" { $return = $item{'addressstruct(s)'} }
|
|
|
|
cc: ADDRESSES
|
|
bcc: ADDRESSES
|
|
from: ADDRESSES
|
|
replyto: ADDRESSES
|
|
sender: ADDRESSES
|
|
to: ADDRESSES
|
|
|
|
envelopestruct: "(" date subject from sender replyto to cc
|
|
bcc inreplyto messageid ")"
|
|
{ $return = bless {}, "Mail::IMAPClient::BodyStructure::Envelope";
|
|
$return->{$_} = $item{$_}
|
|
for qw/date subject from sender replyto to cc/
|
|
, qw/bcc inreplyto messageid/;
|
|
1;
|
|
}
|
|
|
|
basicfields: bodysubtype bodyparms(?) bodyid(?)
|
|
bodydesc(?) bodyenc(?) bodysize(?)
|
|
{ $return = { bodysubtype => $item{bodysubtype} };
|
|
take_optional_items($return, \%item,
|
|
qw/bodyparms bodyid bodydesc bodyenc bodysize/);
|
|
1;
|
|
}
|
|
|
|
textmessage: TEXT <commit> basicfields textlines(?) bodyMD5(?)
|
|
bodydisp(?) bodylang(?) bodyextra(?)
|
|
{
|
|
$return = $item{basicfields} || {};
|
|
$return->{bodytype} = 'TEXT';
|
|
take_optional_items($return, \%item
|
|
, qw/textlines bodyMD5 bodydisp bodylang bodyextra/);
|
|
1;
|
|
}
|
|
|
|
othertypemessage: bodytype basicfields bodyMD5(?) bodydisp(?)
|
|
bodylang(?) bodyextra(?)
|
|
{ $return = { bodytype => $item{bodytype} };
|
|
take_optional_items($return, \%item
|
|
, qw/bodyMD5 bodydisp bodylang bodyextra/ );
|
|
merge_hash($return, $item{basicfields});
|
|
1;
|
|
}
|
|
|
|
nestedmessage: rfc822message <commit> bodyparms bodyid bodydesc bodyenc
|
|
# bodysize envelopestruct bodystructure textlines
|
|
bodysize envelopestruct(?) bodystructure(?) textlines(?)
|
|
bodyMD5(?) bodydisp(?) bodylang(?) bodyextra(?)
|
|
{
|
|
$return = {};
|
|
$return->{$_} = $item{$_}
|
|
for qw/bodyparms bodyid bodydesc bodyenc bodysize/;
|
|
# envelopestruct bodystructure textlines/;
|
|
|
|
take_optional_items($return, \%item
|
|
, qw/envelopestruct bodystructure textlines/
|
|
, qw/bodyMD5 bodydisp bodylang bodyextra/);
|
|
|
|
merge_hash($return, $item{bodystructure}[0]);
|
|
merge_hash($return, $item{basicfields});
|
|
$return->{bodytype} = "MESSAGE" ;
|
|
$return->{bodysubtype} = "RFC822" ;
|
|
1;
|
|
}
|
|
|
|
multipart: subpart(s) <commit> bodysubtype
|
|
bodyparms(?) bodydisp(?) bodylang(?) bodyloc(?) bodyextra(?)
|
|
<defer: $subpartCount = 0>
|
|
{ $return =
|
|
{ bodysubtype => $item{bodysubtype}
|
|
, bodytype => 'MULTIPART'
|
|
, bodystructure => $item{'subpart(s)'}
|
|
};
|
|
take_optional_items($return, \%item
|
|
, qw/bodyparms bodydisp bodylang bodyloc bodyextra/);
|
|
1;
|
|
}
|
|
|
|
subpart: "(" part ")" {$return = $item{part}} <defer: ++$subpartCount;>
|
|
|
|
part: multipart { $return = bless $item{multipart}, $mibs }
|
|
| textmessage { $return = bless $item{textmessage}, $mibs }
|
|
| nestedmessage { $return = bless $item{nestedmessage}, $mibs }
|
|
| othertypemessage { $return = bless $item{othertypemessage}, $mibs }
|
|
|
|
bodystructure: "(" part(s) ")"
|
|
{ $return = $item{'part(s)'} }
|
|
|
|
start: /.*?\(.*?BODYSTRUCTURE \(/i part(1) /\).*\)\r?\n?/
|
|
{ $return = $item{'part(1)'}[0] }
|
|
|
|
envelope: /.*?\(.*?ENVELOPE/ envelopestruct /.*\)/
|
|
{ $return = $item{envelopestruct} }
|