line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::Google::SafeBrowsing3::Storage; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
|
4
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
24
|
|
5
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
19
|
|
6
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
12
|
use Carp; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
1107
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '0.1'; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 NAME |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
Net::Google::SafeBrowsing3::Storage - Base class for storing the Google Safe Browsing v2 database |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 SYNOPSIS |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
package Net::Google::SafeBrowsing3::Sqlite; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
use base 'Net::Google::SafeBrowsing3::Storage'; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 DESCRIPTION |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
This is the base class for implementing a storage mechanism for the Google Safe Browsing v3 database. See L for an example of implementation. |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
This module cannot be used on its own as it does not actually store anything. All methods should redefined. Check the code to see which arguments are used, and what should be returned. |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=cut |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=head1 CONSTRUCTOR |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=over 4 |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=back |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=head2 new() |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
Create a Net::Google::SafeBrowsing3::Storage object |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
my $storage => Net::Google::SafeBrowsing3::Storage->new(); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=cut |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub new { |
46
|
1
|
|
|
1
|
1
|
3
|
my ($class, %args) = @_; |
47
|
|
|
|
|
|
|
|
48
|
1
|
|
|
|
|
2
|
my $self = { |
49
|
|
|
|
|
|
|
%args, |
50
|
|
|
|
|
|
|
}; |
51
|
|
|
|
|
|
|
|
52
|
1
|
50
|
|
|
|
4
|
bless $self, $class or croak "Can't bless $class: $!"; |
53
|
1
|
|
|
|
|
3
|
return $self; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head1 PUBLIC FUNCTIONS |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=over 4 |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=back |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=head2 add_chunks() |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
Add chunk information to the local database |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
$storage->add_chunks(type => 'a', chunknum => 2154, chunks => [{host => HEX, prefix => ''}], list => 'goog-malware-shavar'); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
Does not return anything. |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
Arguments |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=over 4 |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=item type |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
Required. Type of chunk: 'a' (add chunk) or 's' (sub chunk). |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=item chunknum |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
Required. Chunk number. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=item chunks |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
Required. Array of chunks |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
For add chunks, each element of the array is an hash reference in the following format: |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
{ |
90
|
|
|
|
|
|
|
host => HEX, |
91
|
|
|
|
|
|
|
prefix => HEX |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
For sub chunks, each element of the array is an hash reference in the following format: |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
{ |
97
|
|
|
|
|
|
|
host => HEX, |
98
|
|
|
|
|
|
|
prefix => HEX, |
99
|
|
|
|
|
|
|
add_chunknum => INTEGER |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=item list |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
Required. Google Safe Browsing list name. |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=back |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=cut |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub add_chunks { |
112
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
113
|
0
|
|
0
|
|
|
|
my $type = $args{type} || 'a'; |
114
|
0
|
|
0
|
|
|
|
my $chunknum = $args{chunknum} || 0; |
115
|
0
|
|
0
|
|
|
|
my $chunks = $args{chunks} || []; |
116
|
0
|
|
0
|
|
|
|
my $list = $args{'list'} || ''; |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# Save { type => $type, host => $chunk->{host}, prefix => $chunk->{prefix}, chunknum => $chunknum, list => $list } |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=head2 get_add_chunks() |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
Returns a list of chunks for a given prefix for all lists. |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
my @chunks = $storage->get_add_chunks(prefix => HEX); |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
Arguments |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=over 4 |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=item hostkey. |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
Required. Host key. |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=back |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
Return value |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=over 4 |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
Array of add chunks in the same format as described above: |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
( |
147
|
|
|
|
|
|
|
{ |
148
|
|
|
|
|
|
|
chunknum => 25121, |
149
|
|
|
|
|
|
|
prefix => hex('2fc96b9f2fc96b9f2fc96b9f2fc96b9f'), |
150
|
|
|
|
|
|
|
list => 'goog-malware-shavar' |
151
|
|
|
|
|
|
|
}, |
152
|
|
|
|
|
|
|
{ |
153
|
|
|
|
|
|
|
chunknum => '25121', |
154
|
|
|
|
|
|
|
prefix => hex('2fc96b9f'), |
155
|
|
|
|
|
|
|
list => 'goog-malware-shavar' |
156
|
|
|
|
|
|
|
}, |
157
|
|
|
|
|
|
|
); |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=back |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=cut |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub get_add_chunks { |
164
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
165
|
0
|
|
0
|
|
|
|
my $prefix = $args{prefix} || ''; |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
return ( |
168
|
|
|
|
|
|
|
{ |
169
|
0
|
|
|
|
|
|
chunknum => 25121, |
170
|
|
|
|
|
|
|
prefix => '', |
171
|
|
|
|
|
|
|
list => 'goog-malware-shavar' |
172
|
|
|
|
|
|
|
}, |
173
|
|
|
|
|
|
|
{ |
174
|
|
|
|
|
|
|
chunknum => '25121', |
175
|
|
|
|
|
|
|
prefix => $self->ascii_to_hex('2fc96b9f'), |
176
|
|
|
|
|
|
|
list => 'goog-malware-shavar' |
177
|
|
|
|
|
|
|
}, |
178
|
|
|
|
|
|
|
); |
179
|
|
|
|
|
|
|
} |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=head2 get_sub_chunks() |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
Returns a list of sub chunks for a given prefix for all lists. |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
my @chunks = $storage->get_sub_chunks(prefix => HEX); |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
Arguments |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=over 4 |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=item hostkey |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
Required. Host key. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
=back |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
Return value |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=over 4 |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
Array of add chunks in the same format as described above: |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
( |
206
|
|
|
|
|
|
|
{ |
207
|
|
|
|
|
|
|
chunknum => 37441, |
208
|
|
|
|
|
|
|
prefix => '', |
209
|
|
|
|
|
|
|
addchunknum => 23911, |
210
|
|
|
|
|
|
|
list => 'goog-malware-shavar' |
211
|
|
|
|
|
|
|
}, |
212
|
|
|
|
|
|
|
{ |
213
|
|
|
|
|
|
|
chunknum => 37441, |
214
|
|
|
|
|
|
|
prefix => '', |
215
|
|
|
|
|
|
|
addchunknum => 22107, |
216
|
|
|
|
|
|
|
list => 'goog-malware-shavar' |
217
|
|
|
|
|
|
|
}, |
218
|
|
|
|
|
|
|
); |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=back |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
=cut |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
sub get_sub_chunks { |
225
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
226
|
0
|
|
0
|
|
|
|
my $prefix = $args{prefix} || ''; |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
return ( |
230
|
|
|
|
|
|
|
{ |
231
|
0
|
|
|
|
|
|
chunknum => 37441, |
232
|
|
|
|
|
|
|
prefix => '', |
233
|
|
|
|
|
|
|
addchunknum => 23911, |
234
|
|
|
|
|
|
|
list => 'goog-malware-shavar' |
235
|
|
|
|
|
|
|
}, |
236
|
|
|
|
|
|
|
{ |
237
|
|
|
|
|
|
|
chunknum => 37441, |
238
|
|
|
|
|
|
|
prefix => '', |
239
|
|
|
|
|
|
|
addchunknum => 22107, |
240
|
|
|
|
|
|
|
list => 'goog-malware-shavar' |
241
|
|
|
|
|
|
|
}, |
242
|
|
|
|
|
|
|
); |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=head2 get_add_chunks_nums() |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
Returns a list of unique add chunk numbers for a specific list. |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
B: this list should be sorted in ascendant order. |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
my @ids = $storage->get_add_chunks_nums(list => 'goog-malware-shavar'); |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
Arguments |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=over 4 |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=item list |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
Required. Google Safe Browsing list name |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=back |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
Return value |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
=over 4 |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
Array of integers sorted in ascendant order: |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
qw(25121 25122 25123 25124 25125 25126) |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
=back |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=cut |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
sub get_add_chunks_nums { |
278
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
279
|
0
|
|
0
|
|
|
|
my $list = $args{'list'} || ''; |
280
|
|
|
|
|
|
|
|
281
|
0
|
|
|
|
|
|
return qw(25121 25122 25123 25124 25125 25126); |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
=head2 get_sub_chunks_nums() |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
Returns a list of unique sub chunk numbers for a specific list. |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
B: this list should be sorted in ascendant order. |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
my @ids = $storage->get_sub_chunks_nums(list => 'goog-malware-shavar'); |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
Arguments |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=over 4 |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=item list |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
Required. Google Safe Browsing list name |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
=back |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
Return value |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=over 4 |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
Array of integers sorted in ascendant order: |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
qw(37441 37442 37443 37444 37445 37446 37447 37448 37449 37450) |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=back |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=cut |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
sub get_sub_chunks_nums { |
317
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
318
|
0
|
|
0
|
|
|
|
my $list = $args{'list'} || ''; |
319
|
|
|
|
|
|
|
|
320
|
0
|
|
|
|
|
|
return qw(37441 37442 37443 37444 37445 37446 37447 37448 37449 37450); |
321
|
|
|
|
|
|
|
} |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=head2 delete_add_chunks() |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
Delete add chunks from the local database |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
$storage->delete_add_chunks(chunknums => [qw/37444 37445 37446/], list => 'goog-malware-shavar'); |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
Arguments |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=over 4 |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=item chunknums |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
Required. Array of chunk numbers |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=item list |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
Required. Google Safe Browsing list name |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=back |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
No return value |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=cut |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
sub delete_add_ckunks { |
351
|
0
|
|
|
0
|
0
|
|
my ($self, %args) = @_; |
352
|
0
|
|
0
|
|
|
|
my $chunknums = $args{chunknums} || []; |
353
|
0
|
|
0
|
|
|
|
my $list = $args{'list'} || ''; |
354
|
|
|
|
|
|
|
|
355
|
0
|
|
|
|
|
|
foreach my $num (@$chunknums) { |
356
|
|
|
|
|
|
|
# DELETE FROM [...] WHERE chunknumber = $num AND list = $list |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
} |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
=head2 delete_sub_chunks() |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
Delete sub chunks from the local database |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
$storage->delete_sub_chunks(chunknums => [qw/37444 37445 37446/], list => 'goog-malware-shavar'); |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
Arguments |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=over 4 |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
=item chunknums |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
Required. Array of chunk numbers |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
=item list |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
Required. Google Safe Browsing list name |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=back |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
No return value |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=cut |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
sub delete_sub_ckunks { |
388
|
0
|
|
|
0
|
0
|
|
my ($self, %args) = @_; |
389
|
0
|
|
0
|
|
|
|
my $chunknums = $args{chunknums} || []; |
390
|
0
|
|
0
|
|
|
|
my $list = $args{'list'} || ''; |
391
|
|
|
|
|
|
|
|
392
|
0
|
|
|
|
|
|
foreach my $num (@$chunknums) { |
393
|
|
|
|
|
|
|
# DELETE FROM [...] WHERE chunknumber = $num AND list = $list |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
=head2 get_full_hashes() |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
Return a list of full hashes |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
$storage->get_full_hashes(hash => AAAAAAAA..., list => 'goog-malware-shavar'); |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
Arguments |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
=over 4 |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
=item hash |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
Required. 32-bit hash |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
=item list |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
Required. Google Safe Browsing list name |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
=back |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
Return value |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
=over 4 |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
Array of full hashes: |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
({ hash => HEX, type => 0 }, { hash => HEX, type => 1 }, { hash => HEX, type => 0 }) |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
=back |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
=cut |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
sub get_full_hashes { |
433
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
434
|
0
|
|
0
|
|
|
|
my $hash = $args{hash} || ''; |
435
|
0
|
|
0
|
|
|
|
my $list = $args{list} || ''; |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
return ( |
438
|
0
|
|
|
|
|
|
{ hash => $self->ascii_to_hex('eb9744c011d332ad9c92442d18d5a0f913328ad5623983822fc86fad1aab649d'), type => 0 }, |
439
|
|
|
|
|
|
|
{ hash => $self->ascii_to_hex('2ae11a967a5517e24c7be3fa0b8f56e7a13358ce3b07556dc251bc6b650f0f59'), type => 1 } |
440
|
|
|
|
|
|
|
); |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=head2 updated() |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
Save information about a successful database update |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
$storage->updated('time' => time(), wait => 1800, list => 'goog-malware-shavar'); |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
Arguments |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
=over 4 |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=item time |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
Required. Time of the update. |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
=item wait |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
Required. Number of seconds to wait before doing the next update. |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
=item list |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
Required. Google Safe Browsing list name. |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
=back |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
No return value |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
=cut |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
sub updated { |
474
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
475
|
0
|
|
0
|
|
|
|
my $time = $args{'time'} || time(); |
476
|
0
|
|
0
|
|
|
|
my $wait = $args{'wait'} || 1800; |
477
|
0
|
|
0
|
|
|
|
my $list = $args{'list'} || ''; |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
# INSERT INTO [...] (last, wait, errors, list) VALUES (?, ?, 0, ?)", $time, $wait, $list); |
480
|
|
|
|
|
|
|
} |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
=head2 update_error() |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
Save information about a failed database update |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
$storage->update_error('time' => time(), wait => 60, list => 'goog-malware-shavar', errors => 1); |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
Arguments |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=over 4 |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=item time |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
Required. Time of the update. |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
=item wait |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
Required. Number of seconds to wait before doing the next update. |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
=item list |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
Required. Google Safe Browsing list name. |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
=item errors |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
Required. Number of errors. |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
=back |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
No return value |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
=cut |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
sub update_error { |
517
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
518
|
0
|
|
0
|
|
|
|
my $time = $args{'time'} || time(); |
519
|
0
|
|
0
|
|
|
|
my $list = $args{'list'} || ''; |
520
|
0
|
|
0
|
|
|
|
my $wait = $args{'wait'} || 60; |
521
|
0
|
|
0
|
|
|
|
my $errors = $args{errors} || 1; |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
# UPDATE updates SET last = $time, wait = $wait, errors = $errors, list = $list |
524
|
|
|
|
|
|
|
} |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=head2 last_update() |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
Return information about the last database update |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
my $info = $storage->last_update(list => 'goog-malware-shavar'); |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
Arguments |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
=over 4 |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
=item list |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
Required. Google Safe Browsing list name. |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
=back |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
Return value |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=over 4 |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
Hash reference |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
{ |
551
|
|
|
|
|
|
|
time => time(), |
552
|
|
|
|
|
|
|
wait => 1800, |
553
|
|
|
|
|
|
|
errors => 0 |
554
|
|
|
|
|
|
|
} |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
=back |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
=cut |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
sub last_update { |
561
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
562
|
0
|
|
0
|
|
|
|
my $list = $args{'list'} || ''; |
563
|
|
|
|
|
|
|
|
564
|
0
|
|
|
|
|
|
return {'time' => time(), 'wait' => 1800, errors => 0}; |
565
|
|
|
|
|
|
|
} |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
=head2 add_full_hashes() |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
Add full hashes to the local database |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
$storage->add_full_hashes(timestamp => time(), full_hashes => [{life => 900, hash => HEX, list => 'goog-malware-shavar', type => 1}]); |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
Arguments |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
=over 4 |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
=item timestamp |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
Required. Time when the full hash was retrieved. |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
=item full_hashes |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
Required. Array of full hashes. Each element is an hash reference in the following format: |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
{ |
587
|
|
|
|
|
|
|
life => INTEGER, |
588
|
|
|
|
|
|
|
hash => HEX, |
589
|
|
|
|
|
|
|
list => 'goog-malware-shavar', |
590
|
|
|
|
|
|
|
type => 1 |
591
|
|
|
|
|
|
|
} |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
=back |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
No return value |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
=cut |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
sub add_full_hashes { |
602
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
603
|
0
|
|
0
|
|
|
|
my $timestamp = $args{timestamp} || time(); |
604
|
0
|
|
0
|
|
|
|
my $full_hashes = $args{full_hashes} || []; |
605
|
|
|
|
|
|
|
|
606
|
0
|
|
|
|
|
|
foreach my $hash (@$full_hashes) { |
607
|
|
|
|
|
|
|
# INSERT INTO [...] (hash, list, timestamp, end,type ) VALUES ($hash->{chunknum}, $hash->{hash}, $hash->{list}, $timestamp, $timestamp + $hash->{life}, $hash->{type}); |
608
|
|
|
|
|
|
|
} |
609
|
|
|
|
|
|
|
} |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
=head2 full_hash_error() |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
Save information about failed attempt to retrieve a full hash |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
$storage->full_hash_error(timestamp => time(), prefix => HEX); |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
Arguments |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
=over 4 |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
=item timestamp |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
Required. Time when the Google returned an error. |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
=item prefix |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
Required. Host prefix. |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
=back |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
No return value |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
=cut |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
sub full_hash_error { |
639
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
640
|
0
|
|
0
|
|
|
|
my $timestamp = $args{timestamp} || time(); |
641
|
0
|
|
0
|
|
|
|
my $prefix = $args{prefix} || ''; |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
# Add 1 to existing error count |
644
|
|
|
|
|
|
|
} |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
=head2 full_hash_ok() |
647
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
Save information about a successful attempt to retrieve a full hash |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
$storage->full_hash_ok(timestamp => time(), prefix => HEX); |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
Arguments |
654
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
=over 4 |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
=item timestamp |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
Required. Time when the Google returned an error. |
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
=item prefix |
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
Required. Host prefix. |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
=back |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
No return value |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
=cut |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
sub full_hash_ok { |
674
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
675
|
0
|
|
0
|
|
|
|
my $timestamp = $args{timestamp} || time(); |
676
|
0
|
|
0
|
|
|
|
my $prefix = $args{prefix} || ''; |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
# UPDATE full_hashes_errors SET errors = 0, timestamp = $timestamp WHERE prefix = $prefix |
679
|
|
|
|
|
|
|
} |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
=head2 get_full_hash_error() |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
Save information about a successful attempt to retrieve a full hash |
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
my $info = $storage->get_full_hash_error(prefix => HEX); |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
Arguments |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
=over 4 |
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
=item prefix |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
Required. Host prefix. |
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
=back |
697
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
Return value |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
=over 4 |
702
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
undef if there was no error |
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
Hash reference in the following format if there was an error: |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
{ |
708
|
|
|
|
|
|
|
timestamp => time(), |
709
|
|
|
|
|
|
|
errors => 3 |
710
|
|
|
|
|
|
|
} |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
=back |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
=cut |
716
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
sub get_full_hash_error { |
718
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
719
|
0
|
|
0
|
|
|
|
my $prefix = $args{prefix} || ''; |
720
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
# no error |
723
|
0
|
|
|
|
|
|
return undef; |
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
# some error |
726
|
|
|
|
|
|
|
# return { timestamp => time(), errors => 3 } |
727
|
|
|
|
|
|
|
} |
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
=head2 reset() |
732
|
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
Remove all local data |
734
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
$storage->reset(); |
736
|
|
|
|
|
|
|
|
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
Arguments |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
=over 4 |
741
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
=item list |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
Required. Google Safe Browsing list name. |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
=back |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
No return value |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
=cut |
751
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
sub reset { |
753
|
0
|
|
|
0
|
1
|
|
my ($self, %args) = @_; |
754
|
0
|
|
0
|
|
|
|
my $list = $args{'list'} || ''; |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
# DELETE FROM s_chunks WHERE list = $list |
757
|
|
|
|
|
|
|
# DELETE FROM a_chunks WHERE list = $list |
758
|
|
|
|
|
|
|
# DELETE FROM full_hashes WHERE list = $list |
759
|
|
|
|
|
|
|
# DELETE FROM full_hashes_errors WHERE list = $list |
760
|
|
|
|
|
|
|
# DELETE FROM updates WHERE list = $list |
761
|
|
|
|
|
|
|
} |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
=head1 PRIVATE FUNCTIONS |
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
These functions are not intended for debugging purpose. |
767
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
=over 4 |
769
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
=back |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
=head2 hex_to_ascii() |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
Transform hexadecimal strings to printable ASCII strings. Used mainly for debugging. |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
print $storage->hex_to_ascii('hex value'); |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
=cut |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
sub hex_to_ascii { |
781
|
0
|
|
|
0
|
1
|
|
my ($self, $hex) = @_; |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
|
784
|
0
|
|
|
|
|
|
my $ascii = ''; |
785
|
|
|
|
|
|
|
|
786
|
0
|
|
|
|
|
|
while (length $hex > 0) { |
787
|
0
|
|
|
|
|
|
$ascii .= sprintf("%02x", ord( substr($hex, 0, 1, '') ) ); |
788
|
|
|
|
|
|
|
} |
789
|
|
|
|
|
|
|
|
790
|
0
|
|
|
|
|
|
return $ascii; |
791
|
|
|
|
|
|
|
} |
792
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
=head2 ascii_to_hex() |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
Transform ASCII strings to hexadecimal strings. |
796
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
print $storage->ascii_to_hex('ascii value'); |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
=cut |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
sub ascii_to_hex { |
802
|
0
|
|
|
0
|
1
|
|
my ($self, $ascii) = @_; |
803
|
|
|
|
|
|
|
|
804
|
0
|
|
|
|
|
|
my $hex = ''; |
805
|
0
|
|
|
|
|
|
for (my $i = 0; $i < int(length($ascii) / 2); $i++) { |
806
|
0
|
|
|
|
|
|
$hex .= chr hex( substr($ascii, $i * 2, 2) ); |
807
|
|
|
|
|
|
|
} |
808
|
|
|
|
|
|
|
|
809
|
0
|
|
|
|
|
|
return $hex; |
810
|
|
|
|
|
|
|
} |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
=head2 debug() |
814
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
Print debug output. |
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
=cut |
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
sub debug { |
820
|
0
|
|
|
0
|
1
|
|
my ($self, @messages) = @_; |
821
|
|
|
|
|
|
|
|
822
|
0
|
0
|
|
|
|
|
print join('', @messages) if ($self->{debug} > 0); |
823
|
|
|
|
|
|
|
} |
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
=head2 error() |
827
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
Print error message. |
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
=cut |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
sub error { |
833
|
0
|
|
|
0
|
1
|
|
my ($self, $message) = @_; |
834
|
|
|
|
|
|
|
|
835
|
0
|
0
|
0
|
|
|
|
print "ERROR - ", $message if ($self->{debug} > 0 || $self->{errors} > 0); |
836
|
0
|
|
|
|
|
|
$self->{last_error} = $message; |
837
|
|
|
|
|
|
|
} |
838
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
=head1 CHANGELOG |
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
=over 4 |
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
=item 0.1 |
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
Initial release. |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
=back |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
=head1 SEE ALSO |
851
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
See L for handling Google Safe Browsing v3. |
853
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
See L or L for an example of storing and managing the Google Safe Browsing database. |
855
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
Google Safe Browsing v3 API: L |
857
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
=head1 AUTHOR |
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
Julien Sobrier, Ejulien@sobrier.netE |
861
|
|
|
|
|
|
|
|
862
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
863
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
Copyright (C) 2015 by Julien Sobrier |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
867
|
|
|
|
|
|
|
it under the same terms as Perl itself, either Perl version 5.8.8 or, |
868
|
|
|
|
|
|
|
at your option, any later version of Perl 5 you may have available. |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
=cut |
872
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
1; |