line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Win32::Outlook::IAF;
|
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
45329
|
use warnings;
|
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
61
|
|
4
|
2
|
|
|
2
|
|
10
|
use strict;
|
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
68
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
require Exporter;
|
7
|
2
|
|
|
2
|
|
11
|
use Carp;
|
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
174
|
|
8
|
|
|
|
|
|
|
|
9
|
2
|
|
|
2
|
|
10
|
use vars qw($VERSION @ISA @EXPORT $AUTOLOAD);
|
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
296
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
$VERSION='0.96';
|
13
|
|
|
|
|
|
|
@ISA=qw(Exporter);
|
14
|
|
|
|
|
|
|
@EXPORT=qw();
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# export enum constants
|
18
|
|
|
|
|
|
|
my %const;
|
19
|
2
|
|
|
|
|
616
|
use constant +{%const=(
|
20
|
|
|
|
|
|
|
# ConnectionType enums
|
21
|
|
|
|
|
|
|
IAF_CT_LAN => 0,
|
22
|
|
|
|
|
|
|
IAF_CT_DIALER => 1,
|
23
|
|
|
|
|
|
|
IAF_CT_DIALUP => 2,
|
24
|
|
|
|
|
|
|
IAF_CT_IE_DEFAULT => 3,
|
25
|
|
|
|
|
|
|
# AuthMethod enums
|
26
|
|
|
|
|
|
|
IAF_AM_NONE => 0,
|
27
|
|
|
|
|
|
|
IAF_AM_SPA => 1,
|
28
|
|
|
|
|
|
|
IAF_AM_USE_INCOMING => 2,
|
29
|
|
|
|
|
|
|
IAF_AM_PLAIN => 3,
|
30
|
|
|
|
|
|
|
# NNTP PostingFormat enums
|
31
|
|
|
|
|
|
|
IAF_PF_USE_OPTIONS => 0,
|
32
|
|
|
|
|
|
|
IAF_PF_PLAIN => 1,
|
33
|
|
|
|
|
|
|
IAF_PF_HTML => 2,
|
34
|
2
|
|
|
2
|
|
12
|
)};
|
|
2
|
|
|
|
|
3
|
|
35
|
|
|
|
|
|
|
push(@EXPORT,keys %const);
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
use constant {
|
39
|
2
|
|
|
|
|
6340
|
HEADER => "\x66\x4D\x41\x49\x00\x00\x05\x00\x01\x00\x00\x00",
|
40
|
|
|
|
|
|
|
PASSWORD_SEED => "\x75\x18\x15\x14",
|
41
|
|
|
|
|
|
|
PASSWORD_HEADER => "\x01\x01",
|
42
|
|
|
|
|
|
|
MAX_FIELD_LENGTH => 4096,
|
43
|
2
|
|
|
2
|
|
11
|
};
|
|
2
|
|
|
|
|
4
|
|
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# field value regexes
|
47
|
|
|
|
|
|
|
my $bool_re=qr/^[01]$/; # boolean
|
48
|
|
|
|
|
|
|
my $num_re=qr/^\d+$/; # numeric
|
49
|
|
|
|
|
|
|
my $regkey_re=qr/^[0-9a-z]*$/i; # registry key
|
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
my $iaf_ct_re=qr/^[${\IAF_CT_LAN}-${\IAF_CT_IE_DEFAULT}]$/;
|
52
|
|
|
|
|
|
|
my $iaf_am_re=qr/^[${\IAF_AM_NONE}-${\IAF_AM_PLAIN}]$/;
|
53
|
|
|
|
|
|
|
my $iaf_pf_re=qr/^[${\IAF_PF_USE_OPTIONS}-${\IAF_PF_HTML}]$/;
|
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
# field binary formats
|
56
|
|
|
|
|
|
|
my $ulong_le_fmt='V'; # an unsigned long in portable little-endian order
|
57
|
|
|
|
|
|
|
my $nullstr_fmt='Z*'; # a null terminated string
|
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
my %fields=(
|
61
|
|
|
|
|
|
|
# name # id # binary format # value regex # callback
|
62
|
|
|
|
|
|
|
'AccountName' => [305464304, $nullstr_fmt, ],
|
63
|
|
|
|
|
|
|
'TemporaryAccount' => [305595369, $ulong_le_fmt, $bool_re, ],
|
64
|
|
|
|
|
|
|
'ConnectionType' => [305726441, $ulong_le_fmt, $iaf_ct_re, ],
|
65
|
|
|
|
|
|
|
'ConnectionName' => [305791984, $nullstr_fmt, ],
|
66
|
|
|
|
|
|
|
'ConnectionFlags' => [305857513, $ulong_le_fmt, $num_re, ],
|
67
|
|
|
|
|
|
|
'AccountID' => [305988592, $nullstr_fmt, $regkey_re, ],
|
68
|
|
|
|
|
|
|
'BackupConnectionName' => [306054128, $nullstr_fmt, ],
|
69
|
|
|
|
|
|
|
'MakeAvailableOffline' => [306185193, $ulong_le_fmt, $bool_re, ],
|
70
|
|
|
|
|
|
|
'ServerReadOnly' => [306316277, $ulong_le_fmt, $bool_re, ],
|
71
|
|
|
|
|
|
|
'IMAPServer' => [311952368, $nullstr_fmt, ],
|
72
|
|
|
|
|
|
|
'IMAPUserName' => [312017904, $nullstr_fmt, ],
|
73
|
|
|
|
|
|
|
'IMAPPassword' => [312083446, $nullstr_fmt, '', \&_iaf_password ],
|
74
|
|
|
|
|
|
|
'IMAPAuthUseSPA' => [312214517, $ulong_le_fmt, $bool_re, ],
|
75
|
|
|
|
|
|
|
'IMAPPort' => [312280041, $ulong_le_fmt, $num_re, ],
|
76
|
|
|
|
|
|
|
'IMAPSecureConnection' => [312345589, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
77
|
|
|
|
|
|
|
'IMAPTimeout' => [312411113, $ulong_le_fmt, $num_re, ],
|
78
|
|
|
|
|
|
|
'IMAPRootFolder' => [312476656, $nullstr_fmt, ],
|
79
|
|
|
|
|
|
|
'IMAPUseLSUB' => [312673269, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
80
|
|
|
|
|
|
|
'IMAPPolling' => [312738805, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
81
|
|
|
|
|
|
|
'IMAPFullList' => [312804341, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
82
|
|
|
|
|
|
|
'IMAPStoreSpecialFolders' => [313000949, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
83
|
|
|
|
|
|
|
'IMAPSentItemsFolder' => [313066480, $nullstr_fmt, ],
|
84
|
|
|
|
|
|
|
'IMAPDraftsFolder' => [313197552, $nullstr_fmt, ],
|
85
|
|
|
|
|
|
|
'IMAPPasswordPrompt' => [313525237, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
86
|
|
|
|
|
|
|
'IMAPDirty' => [313590761, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
87
|
|
|
|
|
|
|
'IMAPPollAllFolders' => [313656309, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
88
|
|
|
|
|
|
|
'HTTPServer' => [321782768, $nullstr_fmt, ],
|
89
|
|
|
|
|
|
|
'HTTPUserName' => [321848304, $nullstr_fmt, ],
|
90
|
|
|
|
|
|
|
'HTTPPassword' => [321913846, $nullstr_fmt, '', \&_iaf_password ],
|
91
|
|
|
|
|
|
|
'HTTPPasswordPrompt' => [321979381, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
92
|
|
|
|
|
|
|
'HTTPAuthUseSPA' => [322044905, $ulong_le_fmt, $bool_re, ],
|
93
|
|
|
|
|
|
|
'HTTPFriendlyName' => [322110448, $nullstr_fmt, ],
|
94
|
|
|
|
|
|
|
'DomainIsMSN' => [322175989, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
95
|
|
|
|
|
|
|
'HTTPPolling' => [322241525, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
96
|
|
|
|
|
|
|
'AdBarURL' => [322307056, $nullstr_fmt, ],
|
97
|
|
|
|
|
|
|
'ShowAdBar' => [322372597, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
98
|
|
|
|
|
|
|
'MinPollingInterval' => [322438135, $ulong_le_fmt, $num_re, ],
|
99
|
|
|
|
|
|
|
'GotPollingInterval' => [322503669, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
100
|
|
|
|
|
|
|
'LastPolledTime' => [322569207, $ulong_le_fmt, $num_re, ],
|
101
|
|
|
|
|
|
|
'NNTPServer' => [325059568, $nullstr_fmt, ],
|
102
|
|
|
|
|
|
|
'NNTPUserName' => [325125104, $nullstr_fmt, ],
|
103
|
|
|
|
|
|
|
'NNTPPassword' => [325190646, $nullstr_fmt, '', \&_iaf_password ],
|
104
|
|
|
|
|
|
|
'NNTPAuthMethod' => [325321717, $ulong_le_fmt, $iaf_am_re, ],
|
105
|
|
|
|
|
|
|
'NNTPPort' => [325387241, $ulong_le_fmt, $num_re, ],
|
106
|
|
|
|
|
|
|
'NNTPSecureConnection' => [325452789, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
107
|
|
|
|
|
|
|
'NNTPTimeout' => [325518313, $ulong_le_fmt, $num_re, ],
|
108
|
|
|
|
|
|
|
'NNTPDisplayName' => [325583856, $nullstr_fmt, ],
|
109
|
|
|
|
|
|
|
'NNTPOrganizationName' => [325649392, $nullstr_fmt, ],
|
110
|
|
|
|
|
|
|
'NNTPEmailAddress' => [325714928, $nullstr_fmt, ],
|
111
|
|
|
|
|
|
|
'NNTPReplyToEmailAddress' => [325780464, $nullstr_fmt, ],
|
112
|
|
|
|
|
|
|
'NNTPSplitMessages' => [325846005, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
113
|
|
|
|
|
|
|
'NNTPSplitMessageSize' => [325911529, $ulong_le_fmt, $num_re, ],
|
114
|
|
|
|
|
|
|
'NNTPUseGroupDescriptions' => [325977077, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
115
|
|
|
|
|
|
|
'NNTPPolling' => [326108149, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
116
|
|
|
|
|
|
|
'NNTPPostingFormat' => [326173673, $ulong_le_fmt, $iaf_pf_re, ],
|
117
|
|
|
|
|
|
|
'NNTPSignature' => [326239216, $nullstr_fmt, $regkey_re, ],
|
118
|
|
|
|
|
|
|
'NNTPPasswordPrompt' => [326304757, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
119
|
|
|
|
|
|
|
'POP3Server' => [331613168, $nullstr_fmt, ],
|
120
|
|
|
|
|
|
|
'POP3UserName' => [331678704, $nullstr_fmt, ],
|
121
|
|
|
|
|
|
|
'POP3Password' => [331744246, $nullstr_fmt, '', \&_iaf_password ],
|
122
|
|
|
|
|
|
|
'POP3AuthUseSPA' => [331875317, $ulong_le_fmt, $bool_re, ],
|
123
|
|
|
|
|
|
|
'POP3Port' => [331940841, $ulong_le_fmt, $num_re, ],
|
124
|
|
|
|
|
|
|
'POP3SecureConnection' => [332006389, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
125
|
|
|
|
|
|
|
'POP3Timeout' => [332071913, $ulong_le_fmt, $num_re, ],
|
126
|
|
|
|
|
|
|
'POP3LeaveMailOnServer' => [332137461, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
127
|
|
|
|
|
|
|
'POP3RemoveWhenDeleted' => [332202997, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
128
|
|
|
|
|
|
|
'POP3RemoveWhenExpired' => [332268533, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
129
|
|
|
|
|
|
|
'POP3ExpireDays' => [332334057, $ulong_le_fmt, $num_re, ],
|
130
|
|
|
|
|
|
|
'POP3SkipAccount' => [332399605, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
131
|
|
|
|
|
|
|
'POP3PasswordPrompt' => [332530677, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
132
|
|
|
|
|
|
|
'SMTPServer' => [338166768, $nullstr_fmt, ],
|
133
|
|
|
|
|
|
|
'SMTPUserName' => [338232304, $nullstr_fmt, ],
|
134
|
|
|
|
|
|
|
'SMTPPassword' => [338297846, $nullstr_fmt, '', \&_iaf_password ],
|
135
|
|
|
|
|
|
|
'SMTPAuthMethod' => [338428905, $ulong_le_fmt, $iaf_am_re, ],
|
136
|
|
|
|
|
|
|
'SMTPPort' => [338494441, $ulong_le_fmt, $num_re, ],
|
137
|
|
|
|
|
|
|
'SMTPSecureConnection' => [338559989, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
138
|
|
|
|
|
|
|
'SMTPTimeout' => [338625513, $ulong_le_fmt, $num_re, ],
|
139
|
|
|
|
|
|
|
'SMTPDisplayName' => [338691056, $nullstr_fmt, ],
|
140
|
|
|
|
|
|
|
'SMTPOrganizationName' => [338756592, $nullstr_fmt, ],
|
141
|
|
|
|
|
|
|
'SMTPEmailAddress' => [338822128, $nullstr_fmt, ],
|
142
|
|
|
|
|
|
|
'SMTPReplyToEmailAddress' => [338887664, $nullstr_fmt, ],
|
143
|
|
|
|
|
|
|
'SMTPSplitMessages' => [338953205, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
144
|
|
|
|
|
|
|
'SMTPSplitMessageSize' => [339018729, $ulong_le_fmt, $num_re, ],
|
145
|
|
|
|
|
|
|
'SMTPSignature' => [339149808, $nullstr_fmt, $regkey_re, ],
|
146
|
|
|
|
|
|
|
'SMTPPasswordPrompt' => [339215349, $ulong_le_fmt, $bool_re, \&_iaf_bool ],
|
147
|
|
|
|
|
|
|
);
|
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub new {
|
151
|
5
|
|
|
5
|
1
|
1628
|
my ($class,%args)=@_;
|
152
|
5
|
|
|
|
|
11
|
my $self={};
|
153
|
5
|
|
|
|
|
30
|
while (my ($field_name,$field_def)=each %fields) {
|
154
|
409
|
100
|
|
|
|
1257
|
next unless exists $args{$field_name};
|
155
|
1
|
|
|
|
|
3
|
my $field=delete $args{$field_name};
|
156
|
1
|
50
|
|
|
|
6
|
$field=$field_def->[3]->($field,'set') if $field_def->[3]; # call callback() as 'set'
|
157
|
1
|
|
|
|
|
3
|
_check_field($field_name,$field);
|
158
|
0
|
|
|
|
|
0
|
$self->{"_$field_name"}=$field;
|
159
|
|
|
|
|
|
|
}
|
160
|
4
|
100
|
|
|
|
253
|
confess('Unknown argument: '.(keys %args)[0]) if scalar keys %args;
|
161
|
3
|
|
|
|
|
11
|
bless($self,$class);
|
162
|
3
|
|
|
|
|
22
|
return $self;
|
163
|
|
|
|
|
|
|
}
|
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub AUTOLOAD {
|
167
|
20
|
|
100
|
20
|
|
135
|
my ($self,$field)=($_[0],@_>1 && \$_[1]);
|
168
|
20
|
50
|
|
|
|
70
|
confess('Not an object!') unless ref $self;
|
169
|
20
|
|
|
|
|
24
|
my $field_name;
|
170
|
20
|
|
|
|
|
123
|
($field_name=$AUTOLOAD)=~s/^.*:://; # trim package name
|
171
|
20
|
50
|
|
|
|
51
|
return if $field_name eq 'DESTROY'; # let DESTROY fall through
|
172
|
20
|
100
|
|
|
|
190
|
confess("Can't access '$field_name' field in $self") unless exists $fields{$field_name};
|
173
|
19
|
|
|
|
|
33
|
my $field_def=$fields{$field_name};
|
174
|
19
|
|
|
|
|
22
|
my $new_field;
|
175
|
19
|
100
|
|
|
|
53
|
unless (ref $field) { # get
|
|
|
100
|
|
|
|
|
|
176
|
13
|
|
|
|
|
43
|
$new_field=$self->{"_$field_name"};
|
177
|
13
|
100
|
|
|
|
48
|
$new_field=$field_def->[3]->($new_field,'get') if $field_def->[3]; # call callback() as 'get'
|
178
|
|
|
|
|
|
|
} elsif (defined $$field) { # set
|
179
|
5
|
|
|
|
|
11
|
$new_field=$$field;
|
180
|
5
|
100
|
|
|
|
31
|
$new_field=$field_def->[3]->($new_field,'set') if $field_def->[3]; # call callback() as 'set'
|
181
|
5
|
|
|
|
|
13
|
_check_field($field_name,$new_field);
|
182
|
5
|
|
|
|
|
17
|
$self->{"_$field_name"}=$new_field;
|
183
|
|
|
|
|
|
|
} else { # delete
|
184
|
1
|
|
|
|
|
4
|
$new_field=$self->{"_$field_name"};
|
185
|
1
|
50
|
|
|
|
6
|
$new_field=$field_def->[3]->($new_field,'delete') if $field_def->[3]; # call callback() as 'delete'
|
186
|
1
|
|
|
|
|
4
|
delete $self->{"_$field_name"};
|
187
|
|
|
|
|
|
|
}
|
188
|
19
|
|
|
|
|
113
|
return $new_field;
|
189
|
|
|
|
|
|
|
}
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# build a reverse hash for read/write/text operations
|
193
|
|
|
|
|
|
|
my %lookup=map {
|
194
|
|
|
|
|
|
|
my $field_def=$fields{$_};
|
195
|
|
|
|
|
|
|
# id # name # binary format # value regex # callback
|
196
|
|
|
|
|
|
|
$field_def->[0], [$_, $field_def->[1], $field_def->[2] || '', $field_def->[3] || '']
|
197
|
|
|
|
|
|
|
} keys %fields;
|
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
sub read_iaf {
|
201
|
2
|
|
50
|
2
|
1
|
789
|
my ($self,$data)=($_[0],@_>1 && \$_[1]);
|
202
|
2
|
|
|
|
|
4
|
my $pos=0;
|
203
|
2
|
|
|
|
|
8
|
my $len=length($$data);
|
204
|
2
|
50
|
|
|
|
10
|
confess('Premature end of data while reading header') if $pos+length(HEADER)>$len;
|
205
|
2
|
|
|
|
|
4
|
$pos+=length(HEADER); # read header
|
206
|
|
|
|
|
|
|
# read fields
|
207
|
2
|
|
|
|
|
6
|
while ($pos<$len) {
|
208
|
104
|
50
|
|
|
|
498
|
confess('Premature end of data while reading field_id') if $pos+4>$len;
|
209
|
104
|
|
|
|
|
755
|
my $field_id=unpack('V',substr($$data,$pos,4));
|
210
|
104
|
|
|
|
|
222
|
$pos+=4;
|
211
|
104
|
50
|
|
|
|
277
|
confess('Premature end of data while reading field_len') if $pos+4>$len;
|
212
|
104
|
|
|
|
|
1077
|
my $field_len=unpack('V',substr($$data,$pos,4));
|
213
|
104
|
|
|
|
|
187
|
$pos+=4;
|
214
|
104
|
50
|
|
|
|
281
|
confess('Premature end of data while reading field') if $pos+$field_len>$len;
|
215
|
104
|
50
|
|
|
|
239
|
confess('Excessive field length: '.$field_len) if $field_len>MAX_FIELD_LENGTH;
|
216
|
104
|
|
|
|
|
631
|
my $field=substr($$data,$pos,$field_len);
|
217
|
104
|
|
|
|
|
166
|
$pos+=$field_len;
|
218
|
104
|
50
|
|
|
|
506
|
confess('Unknown field: '.$field_id) unless exists $lookup{$field_id};
|
219
|
104
|
|
|
|
|
175
|
my $field_def=$lookup{$field_id};
|
220
|
104
|
100
|
|
|
|
299
|
$field=$field_def->[3]->($field,'read','packed') if $field_def->[3]; # call callback() as 'read packed'
|
221
|
104
|
50
|
|
|
|
624
|
$field=unpack($field_def->[1],$field) if $field_def->[1]; # apply binary format
|
222
|
104
|
100
|
|
|
|
1271
|
$field=$field_def->[3]->($field,'read','unpacked') if $field_def->[3]; # call callback() as 'read unpacked'
|
223
|
104
|
|
|
|
|
370
|
my $field_name=$field_def->[0];
|
224
|
104
|
|
|
|
|
243
|
_check_field($field_name,$field);
|
225
|
104
|
|
|
|
|
2867
|
$self->{"_$field_name"}=$field;
|
226
|
|
|
|
|
|
|
}
|
227
|
2
|
|
|
|
|
16
|
return 1;
|
228
|
|
|
|
|
|
|
}
|
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
sub write_iaf {
|
232
|
1
|
|
50
|
1
|
1
|
11
|
my ($self,$data)=($_[0],@_>1 && \$_[1]);
|
233
|
1
|
|
|
|
|
3
|
$$data=HEADER; # write header
|
234
|
|
|
|
|
|
|
# write fields
|
235
|
1
|
|
|
|
|
11
|
while (my ($field_id,$field_def)=each %lookup) {
|
236
|
85
|
|
|
|
|
134
|
my $field_name=$field_def->[0];
|
237
|
85
|
100
|
|
|
|
319
|
next unless exists $self->{"_$field_name"};
|
238
|
52
|
|
|
|
|
130
|
my $field=$self->{"_$field_name"};
|
239
|
52
|
100
|
|
|
|
147
|
$field=$field_def->[3]->($field,'write','unpacked') if $field_def->[3]; # call callback() as 'write unpacked'
|
240
|
52
|
50
|
|
|
|
234
|
$field=pack($field_def->[1],$field) if $field_def->[1]; # apply binary format
|
241
|
52
|
100
|
|
|
|
139
|
$field=$field_def->[3]->($field,'write','packed') if $field_def->[3]; # call callback() as 'write packed'
|
242
|
52
|
|
|
|
|
144
|
my $field_len=pack('V',length($field));
|
243
|
52
|
|
|
|
|
108
|
$field_id=pack('V',$field_id);
|
244
|
52
|
|
|
|
|
299
|
$$data.="$field_id$field_len$field";
|
245
|
|
|
|
|
|
|
}
|
246
|
1
|
|
|
|
|
10
|
return 1;
|
247
|
|
|
|
|
|
|
}
|
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
sub text_iaf {
|
251
|
0
|
|
0
|
0
|
1
|
0
|
my ($self,$data,$delimiter)=($_[0],@_>1 && \$_[1],$_[2]);
|
252
|
0
|
|
0
|
|
|
0
|
$delimiter||="\t"; # assume 'tab' delimiter
|
253
|
0
|
|
|
|
|
0
|
$$data=''; # write header
|
254
|
|
|
|
|
|
|
# write sorted fields (name value)
|
255
|
0
|
|
|
|
|
0
|
foreach my $field_id (sort keys %lookup) {
|
256
|
0
|
|
|
|
|
0
|
my $field_def=$lookup{$field_id};
|
257
|
0
|
|
|
|
|
0
|
my $field_name=$field_def->[0];
|
258
|
0
|
0
|
|
|
|
0
|
next unless exists $self->{"_$field_name"};
|
259
|
0
|
|
|
|
|
0
|
my $field=$self->{"_$field_name"};
|
260
|
0
|
0
|
|
|
|
0
|
$field=$field_def->[3]->($field,'text','') if $field_def->[3]; # call callback() as 'text'
|
261
|
0
|
|
|
|
|
0
|
$$data.="$field_name$delimiter$field\n";
|
262
|
|
|
|
|
|
|
}
|
263
|
0
|
|
|
|
|
0
|
return 1;
|
264
|
|
|
|
|
|
|
}
|
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
sub _check_field {
|
268
|
110
|
|
50
|
110
|
|
428
|
my ($field_name,$field)=($_[0],@_>1 && \$_[1]);
|
269
|
110
|
|
|
|
|
775
|
my $field_def=$fields{$field_name};
|
270
|
110
|
50
|
|
|
|
338
|
my $field_re=$field_def->[2] ? ref $field_def->[2] eq 'Regexp' ? $field_def->[2] : qr/$field_def->[2]/ : '';
|
|
|
100
|
|
|
|
|
|
271
|
110
|
100
|
66
|
|
|
1152
|
$$field!~$field_re && confess('Invalid field value: '.$$field) if $field_re;
|
272
|
|
|
|
|
|
|
}
|
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
# turn parameters into boolean 0/1 values
|
276
|
|
|
|
|
|
|
sub _iaf_bool {
|
277
|
130
|
|
50
|
130
|
|
536
|
my ($value,$operation,$phase)=(@_>0 && \$_[0],$_[1],$_[2]);
|
278
|
|
|
|
|
|
|
# this callback runs only during 'get' or 'set' operations
|
279
|
130
|
100
|
100
|
|
|
805
|
return $$value unless $operation eq 'get' || $operation eq 'set';
|
280
|
4
|
100
|
|
|
|
18
|
return $$value ? 1 : 0;
|
281
|
|
|
|
|
|
|
}
|
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
# encrypt/decrypt passwords
|
285
|
|
|
|
|
|
|
sub _iaf_password {
|
286
|
15
|
|
50
|
15
|
|
74
|
my ($password,$operation,$phase)=(@_>0 && \$_[0],$_[1],$_[2]);
|
287
|
|
|
|
|
|
|
# protect sensitive data
|
288
|
15
|
50
|
|
|
|
35
|
return '********' if $operation eq 'text';
|
289
|
|
|
|
|
|
|
# this callback runs only during 'read' or 'write' operations
|
290
|
15
|
100
|
100
|
|
|
78
|
return $$password unless $operation eq 'read' || $operation eq 'write';
|
291
|
|
|
|
|
|
|
# this callback operates only on 'packed' data
|
292
|
12
|
100
|
|
|
|
39
|
return $$password unless $phase eq 'packed';
|
293
|
6
|
|
|
|
|
21
|
my ($ret,$pos,$len)=('',0,length($$password));
|
294
|
6
|
|
|
|
|
11
|
my $seed=PASSWORD_SEED;
|
295
|
6
|
|
|
|
|
8
|
my $fill;
|
296
|
6
|
100
|
|
|
|
15
|
if ($operation eq 'read') {
|
297
|
4
|
50
|
|
|
|
13
|
confess('Premature end of data while reading password header') if $pos+length(PASSWORD_HEADER)>$len;
|
298
|
4
|
|
|
|
|
6
|
$pos+=length(PASSWORD_HEADER);
|
299
|
4
|
50
|
|
|
|
20
|
confess('Premature end of data while reading password_len') if $pos+4>$len;
|
300
|
4
|
|
|
|
|
23
|
my $password_len=unpack('V',substr($$password,$pos,4));
|
301
|
4
|
|
|
|
|
7
|
$pos+=4;
|
302
|
4
|
50
|
|
|
|
16
|
confess('Malformed password record') if $pos+$password_len!=$len;
|
303
|
|
|
|
|
|
|
} else {
|
304
|
2
|
|
|
|
|
4
|
$ret=PASSWORD_HEADER;
|
305
|
2
|
|
|
|
|
10
|
$ret.=pack('V',$len);
|
306
|
|
|
|
|
|
|
}
|
307
|
6
|
|
|
|
|
19
|
while ($pos<$len) {
|
308
|
9
|
100
|
|
|
|
37
|
$fill=$pos+4>$len ? $pos+4-$len : 0;
|
309
|
9
|
|
|
|
|
46
|
$seed=unpack('V',("\x00" x $fill).substr($seed,$fill));
|
310
|
9
|
|
|
|
|
41
|
my $d=unpack('V',("\x00" x $fill).substr($$password,$pos,4-$fill));
|
311
|
9
|
|
|
|
|
22
|
$pos+=4-$fill;
|
312
|
9
|
|
|
|
|
35
|
$ret.=substr(pack('V',$d^$seed),$fill);
|
313
|
9
|
100
|
|
|
|
58
|
$seed=pack('V',$operation eq 'read' ? $d^$seed : $d);
|
314
|
|
|
|
|
|
|
}
|
315
|
6
|
|
|
|
|
26
|
return $ret;
|
316
|
|
|
|
|
|
|
}
|
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
1; # End of Win32::Outlook::IAF
|
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
__DATA__
|