line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
## Domain Registry Interface, Misc. useful functions |
2
|
|
|
|
|
|
|
## |
3
|
|
|
|
|
|
|
## Copyright (c) 2005-2015 Patrick Mevzek . All rights reserved. |
4
|
|
|
|
|
|
|
## |
5
|
|
|
|
|
|
|
## This file is part of Net::DRI |
6
|
|
|
|
|
|
|
## |
7
|
|
|
|
|
|
|
## Net::DRI is free software; you can redistribute it and/or modify |
8
|
|
|
|
|
|
|
## it under the terms of the GNU General Public License as published by |
9
|
|
|
|
|
|
|
## the Free Software Foundation; either version 2 of the License, or |
10
|
|
|
|
|
|
|
## (at your option) any later version. |
11
|
|
|
|
|
|
|
## |
12
|
|
|
|
|
|
|
## See the LICENSE file that comes with this distribution for more details. |
13
|
|
|
|
|
|
|
######################################################################################### |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
package Net::DRI::Util; |
16
|
|
|
|
|
|
|
|
17
|
79
|
|
|
79
|
|
56316
|
use utf8; |
|
79
|
|
|
|
|
704
|
|
|
79
|
|
|
|
|
396
|
|
18
|
79
|
|
|
79
|
|
2818
|
use strict; |
|
79
|
|
|
|
|
134
|
|
|
79
|
|
|
|
|
2477
|
|
19
|
79
|
|
|
79
|
|
361
|
use warnings; |
|
79
|
|
|
|
|
101
|
|
|
79
|
|
|
|
|
2487
|
|
20
|
|
|
|
|
|
|
|
21
|
79
|
|
|
79
|
|
46580
|
use Time::HiRes (); |
|
79
|
|
|
|
|
117544
|
|
|
79
|
|
|
|
|
2080
|
|
22
|
79
|
|
|
79
|
|
47309
|
use Encode (); |
|
79
|
|
|
|
|
766823
|
|
|
79
|
|
|
|
|
2375
|
|
23
|
79
|
|
|
79
|
|
43135
|
use Module::Load; |
|
79
|
|
|
|
|
76629
|
|
|
79
|
|
|
|
|
523
|
|
24
|
79
|
|
|
79
|
|
34316
|
use Net::DRI::Exception; |
|
79
|
|
|
|
|
185
|
|
|
79
|
|
|
|
|
252273
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=pod |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=head1 NAME |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
Net::DRI::Util - Various useful functions for Net::DRI operations |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
=head1 DESCRIPTION |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
Please see the README file for details. |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=head1 SUPPORT |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
For now, support questions should be sent to: |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
Enetdri@dotandco.comE |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
Please also see the SUPPORT file in the distribution. |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=head1 SEE ALSO |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
Ehttp://www.dotandco.com/services/software/Net-DRI/E |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=head1 AUTHOR |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
Patrick Mevzek, Enetdri@dotandco.comE |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
=head1 COPYRIGHT |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
Copyright (c) 2005-2015 Patrick Mevzek . |
55
|
|
|
|
|
|
|
All rights reserved. |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify |
58
|
|
|
|
|
|
|
it under the terms of the GNU General Public License as published by |
59
|
|
|
|
|
|
|
the Free Software Foundation; either version 2 of the License, or |
60
|
|
|
|
|
|
|
(at your option) any later version. |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
See the LICENSE file that comes with this distribution for more details. |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
=cut |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
#################################################################################################### |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
## See https://www.iso.org/obp/ui/#search , select 'Country codes', then 'Officially assigned', order by Alpha-2 code (last checked on 2015-05-24) |
70
|
|
|
|
|
|
|
## qw/.A .B .C .D .E .F .G .H .I .J .K .L .M .N .O .P .Q .R .S .T .U .V .W .X .Y .Z |
71
|
|
|
|
|
|
|
our %CCA2=map { $_ => 1 } qw/ AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ/, |
72
|
|
|
|
|
|
|
qw/BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR BS BT BV BW BY BZ/, |
73
|
|
|
|
|
|
|
qw/CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ/, |
74
|
|
|
|
|
|
|
qw/ DE DJ DK DM DO DZ/, |
75
|
|
|
|
|
|
|
qw/ EC EE EG EH ER ES ET /, |
76
|
|
|
|
|
|
|
qw/ FI FJ FK FM FO FR /, |
77
|
|
|
|
|
|
|
qw/GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY /, |
78
|
|
|
|
|
|
|
qw/ HK HM HN HR HT HU /, |
79
|
|
|
|
|
|
|
qw/ ID IE IL IM IN IO IQ IR IS IT /, |
80
|
|
|
|
|
|
|
qw/ JE JM JO JP /, |
81
|
|
|
|
|
|
|
qw/ KE KG KH KI KM KN KP KR KW KY KZ/, |
82
|
|
|
|
|
|
|
qw/LA LB LC LI LK LR LS LT LU LV LY /, |
83
|
|
|
|
|
|
|
qw/MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ/, |
84
|
|
|
|
|
|
|
qw/NA NC NE NF NG NI NL NO NP NR NU NZ/, |
85
|
|
|
|
|
|
|
qw/ OM /, |
86
|
|
|
|
|
|
|
qw/PA PE PF PG PH PK PL PM PN PR PS PT PW PY /, |
87
|
|
|
|
|
|
|
qw/QA /, |
88
|
|
|
|
|
|
|
qw/ RE RO RS RU RW /, |
89
|
|
|
|
|
|
|
qw/SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ/, |
90
|
|
|
|
|
|
|
qw/ TC TD TF TG TH TJ TK TL TM TN TO TR TT TV TW TZ/, |
91
|
|
|
|
|
|
|
qw/UA UG UM US UY UZ/, |
92
|
|
|
|
|
|
|
qw/VA VC VE VG VI VN VU /, |
93
|
|
|
|
|
|
|
qw/ WF WS /, |
94
|
|
|
|
|
|
|
qw/ YE YT /, |
95
|
|
|
|
|
|
|
qw/ZA ZM ZW /; |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub all_valid |
98
|
|
|
|
|
|
|
{ |
99
|
240
|
|
|
240
|
0
|
2593
|
my (@args)=@_; |
100
|
240
|
|
|
|
|
452
|
foreach (@args) |
101
|
|
|
|
|
|
|
{ |
102
|
539
|
100
|
66
|
|
|
2728
|
return 0 unless (defined($_) && (ref($_) || length($_))); |
|
|
|
66
|
|
|
|
|
103
|
|
|
|
|
|
|
} |
104
|
215
|
|
|
|
|
1421
|
return 1; |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub hash_merge |
108
|
|
|
|
|
|
|
{ |
109
|
3
|
|
|
3
|
0
|
7
|
my ($rmaster,$rtoadd)=@_; |
110
|
3
|
|
|
|
|
21
|
while(my ($k,$v)=each(%$rtoadd)) |
111
|
|
|
|
|
|
|
{ |
112
|
3
|
50
|
|
|
|
11
|
$rmaster->{$k}={} unless exists($rmaster->{$k}); |
113
|
3
|
|
|
|
|
13
|
while(my ($kk,$vv)=each(%$v)) |
114
|
|
|
|
|
|
|
{ |
115
|
18
|
50
|
|
|
|
47
|
$rmaster->{$k}->{$kk}=[] unless exists($rmaster->{$k}->{$kk}); |
116
|
18
|
|
|
|
|
31
|
my @t=@$vv; |
117
|
18
|
|
|
|
|
17
|
push @{$rmaster->{$k}->{$kk}},\@t; |
|
18
|
|
|
|
|
67
|
|
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
} |
120
|
3
|
|
|
|
|
8
|
return; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub deepcopy ## no critic (Subroutines::RequireFinalReturn) |
124
|
|
|
|
|
|
|
{ |
125
|
0
|
|
|
0
|
0
|
0
|
my $in=shift; |
126
|
0
|
0
|
|
|
|
0
|
return $in unless defined $in; |
127
|
0
|
|
|
|
|
0
|
my $ref=ref $in; |
128
|
0
|
0
|
|
|
|
0
|
return $in unless $ref; |
129
|
0
|
|
|
|
|
0
|
my $cname; |
130
|
0
|
0
|
|
|
|
0
|
($cname,$ref)=($1,$2) if ("$in"=~m/^(\S+)=([A-Z]+)\(0x/); |
131
|
|
|
|
|
|
|
|
132
|
0
|
0
|
|
|
|
0
|
if ($ref eq 'SCALAR') |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
133
|
|
|
|
|
|
|
{ |
134
|
0
|
|
|
|
|
0
|
my $tmp=$$in; |
135
|
0
|
|
|
|
|
0
|
return \$tmp; |
136
|
|
|
|
|
|
|
} elsif ($ref eq 'HASH') |
137
|
|
|
|
|
|
|
{ |
138
|
0
|
0
|
0
|
|
|
0
|
my $r={ map { $_ => (defined $in->{$_} && ref $in->{$_}) ? deepcopy($in->{$_}) : $in->{$_} } keys(%$in) }; |
|
0
|
|
|
|
|
0
|
|
139
|
0
|
0
|
|
|
|
0
|
bless($r,$cname) if defined $cname; |
140
|
0
|
|
|
|
|
0
|
return $r; |
141
|
|
|
|
|
|
|
} elsif ($ref eq 'ARRAY') |
142
|
|
|
|
|
|
|
{ |
143
|
0
|
0
|
0
|
|
|
0
|
return [ map { (defined $_ && ref $_)? deepcopy($_) : $_ } @$in ]; |
|
0
|
|
|
|
|
0
|
|
144
|
|
|
|
|
|
|
} else |
145
|
|
|
|
|
|
|
{ |
146
|
0
|
|
|
|
|
0
|
Net::DRI::Exception::usererr_invalid_parameters('Do not know how to deepcopy '.$in); |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub link_rs |
151
|
|
|
|
|
|
|
{ |
152
|
4
|
|
|
4
|
0
|
12
|
my (@rs)=@_; |
153
|
4
|
|
|
|
|
7
|
my %seen; |
154
|
4
|
|
|
|
|
13
|
foreach my $i (1..$#rs) |
155
|
|
|
|
|
|
|
{ |
156
|
0
|
0
|
|
|
|
0
|
$rs[$i-1]->_set_last($rs[$i]) unless exists $seen{$rs[$i]}; |
157
|
0
|
|
|
|
|
0
|
$seen{$rs[$i]}=1; |
158
|
|
|
|
|
|
|
} |
159
|
4
|
|
|
|
|
34
|
return $rs[0]; |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
#################################################################################################### |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
sub isint |
165
|
|
|
|
|
|
|
{ |
166
|
5
|
|
|
5
|
0
|
6
|
my $in=shift; |
167
|
5
|
100
|
|
|
|
41
|
return ($in=~m/^\d+$/)? 1 : 0; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
## eppcom:roidType |
171
|
|
|
|
|
|
|
sub is_roid |
172
|
|
|
|
|
|
|
{ |
173
|
0
|
|
|
0
|
0
|
0
|
my $in=shift; |
174
|
0
|
|
0
|
|
|
0
|
return xml_is_token($in,3,89) && $in=~m/^\w{1,80}-[0-9A-Za-z]{1,8}$/; |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub check_equal |
178
|
|
|
|
|
|
|
{ |
179
|
7
|
|
|
7
|
0
|
14
|
my ($input,$ra,$default)=@_; |
180
|
7
|
100
|
|
|
|
20
|
return $default unless defined($input); |
181
|
5
|
100
|
|
|
|
15
|
foreach my $a (ref($ra)? @$ra : ($ra)) |
182
|
|
|
|
|
|
|
{ |
183
|
6
|
100
|
|
|
|
50
|
return $a if ($a=~m/^${input}$/); |
184
|
|
|
|
|
|
|
} |
185
|
2
|
100
|
|
|
|
7
|
return $default if $default; |
186
|
1
|
|
|
|
|
4
|
return; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
sub check_isa |
190
|
|
|
|
|
|
|
{ |
191
|
17
|
|
|
17
|
0
|
282
|
my ($what,$isa)=@_; |
192
|
17
|
100
|
50
|
|
|
53
|
Net::DRI::Exception::usererr_invalid_parameters((${what} || 'parameter').' must be a '.$isa.' object') unless $what && is_class($what,$isa); |
|
|
|
66
|
|
|
|
|
193
|
16
|
|
|
|
|
35
|
return 1; |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
sub is_class |
197
|
|
|
|
|
|
|
{ |
198
|
35
|
|
|
35
|
0
|
80
|
my ($obj,$class)=@_; |
199
|
35
|
100
|
|
|
|
41
|
return eval { $obj->isa($class); } ? 1 : 0; |
|
35
|
|
|
|
|
363
|
|
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub isa_contactset |
203
|
|
|
|
|
|
|
{ |
204
|
0
|
|
|
0
|
0
|
0
|
my $cs=shift; |
205
|
0
|
0
|
0
|
|
|
0
|
return (defined $cs && is_class($cs,'Net::DRI::Data::ContactSet') && !$cs->is_empty())? 1 : 0; |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
sub isa_contact |
209
|
|
|
|
|
|
|
{ |
210
|
9
|
|
|
9
|
0
|
7
|
my ($c,$class)=@_; |
211
|
9
|
50
|
|
|
|
16
|
$class='Net::DRI::Data::Contact' unless defined $class; |
212
|
9
|
50
|
33
|
|
|
23
|
return (defined $c && is_class($c,$class))? 1 : 0; ## no way to check if it is empty or not ? Contact->validate() is too strong as it may die, Contact->roid() maybe not ok always |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
sub isa_hosts |
216
|
|
|
|
|
|
|
{ |
217
|
3
|
|
|
3
|
0
|
7
|
my ($h,$emptyok)=@_; |
218
|
3
|
100
|
|
|
|
10
|
$emptyok=0 unless defined $emptyok; |
219
|
3
|
50
|
33
|
|
|
16
|
return (defined $h && is_class($h,'Net::DRI::Data::Hosts') && ($emptyok || !$h->is_empty()) )? 1 : 0; |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
sub isa_nsgroup |
223
|
|
|
|
|
|
|
{ |
224
|
0
|
|
|
0
|
0
|
0
|
my $h=shift; |
225
|
0
|
0
|
0
|
|
|
0
|
return (defined $h && is_class($h,'Net::DRI::Data::Hosts'))? 1 : 0; |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
sub isa_changes |
229
|
|
|
|
|
|
|
{ |
230
|
3
|
|
|
3
|
0
|
5
|
my $c=shift; |
231
|
3
|
50
|
33
|
|
|
10
|
return (defined $c && is_class($c,'Net::DRI::Data::Changes') && !$c->is_empty())? 1 : 0; |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
sub isa_statuslist |
235
|
|
|
|
|
|
|
{ |
236
|
0
|
|
|
0
|
0
|
0
|
my $s=shift; |
237
|
0
|
0
|
0
|
|
|
0
|
return (defined $s && is_class($s,'Net::DRI::Data::StatusList') && !$s->is_empty())? 1 : 0; |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
sub has_key |
241
|
|
|
|
|
|
|
{ |
242
|
184
|
|
|
184
|
0
|
343
|
my ($rh,$key)=@_; |
243
|
184
|
50
|
33
|
|
|
935
|
return 0 unless (defined $key && $key); |
244
|
184
|
100
|
33
|
|
|
2459
|
return 0 unless (defined $rh && (ref $rh eq 'HASH') && exists $rh->{$key} && defined $rh->{$key}); |
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
245
|
75
|
|
|
|
|
876
|
return 1; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
sub has_contact |
249
|
|
|
|
|
|
|
{ |
250
|
0
|
|
|
0
|
0
|
0
|
my $rh=shift; |
251
|
0
|
|
0
|
|
|
0
|
return has_key($rh,'contact') && isa_contactset($rh->{contact}); |
252
|
|
|
|
|
|
|
} |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
sub has_ns |
255
|
|
|
|
|
|
|
{ |
256
|
1
|
|
|
1
|
0
|
2
|
my $rh=shift; |
257
|
1
|
|
33
|
|
|
2
|
return has_key($rh,'ns') && isa_hosts($rh->{ns}); |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
sub has_duration |
261
|
|
|
|
|
|
|
{ |
262
|
1
|
|
|
1
|
0
|
2
|
my $rh=shift; |
263
|
1
|
|
33
|
|
|
4
|
return has_key($rh,'duration') && check_isa($rh->{'duration'},'DateTime::Duration'); ## check_isa throws an Exception if not |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
sub has_auth |
267
|
|
|
|
|
|
|
{ |
268
|
0
|
|
|
0
|
0
|
0
|
my $rh=shift; |
269
|
0
|
0
|
0
|
|
|
0
|
return (has_key($rh,'auth') && ref $rh->{'auth'} eq 'HASH')? 1 : 0; |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
sub has_status |
273
|
|
|
|
|
|
|
{ |
274
|
0
|
|
|
0
|
0
|
0
|
my $rh=shift; |
275
|
0
|
0
|
0
|
|
|
0
|
return (has_key($rh,'status') && isa_statuslist($rh->{status}))? 1 : 0; |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
#################################################################################################### |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
sub microtime |
281
|
|
|
|
|
|
|
{ |
282
|
43
|
|
|
43
|
0
|
155
|
my ($t,$v)=Time::HiRes::gettimeofday(); |
283
|
43
|
|
|
|
|
219
|
return $t.sprintf('%06d',$v); |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
sub fulltime |
287
|
|
|
|
|
|
|
{ |
288
|
0
|
|
|
0
|
0
|
0
|
my ($t,$v)=Time::HiRes::gettimeofday(); |
289
|
0
|
|
|
|
|
0
|
my @t=localtime($t); |
290
|
0
|
|
|
|
|
0
|
return sprintf('%d-%02d-%02d %02d:%02d:%02d.%06d',1900+$t[5],1+$t[4],$t[3],$t[2],$t[1],$t[0],$v); |
291
|
|
|
|
|
|
|
} |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
## From EPP, trID=token from 3 to 64 characters |
294
|
|
|
|
|
|
|
sub create_trid_1 |
295
|
|
|
|
|
|
|
{ |
296
|
11
|
|
|
11
|
0
|
46
|
my ($name)=@_; |
297
|
11
|
|
|
|
|
30
|
my $mt=microtime(); ## length=16 |
298
|
11
|
|
|
|
|
77
|
return uc($name).'-'.$$.'-'.$mt; |
299
|
|
|
|
|
|
|
} |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
sub create_params |
302
|
|
|
|
|
|
|
{ |
303
|
7
|
|
|
7
|
0
|
21
|
my ($op,$rd)=@_; |
304
|
7
|
100
|
|
|
|
30
|
return {} unless defined $rd; |
305
|
2
|
50
|
|
|
|
8
|
Net::DRI::Exception::usererr_invalid_parameters('last parameter of '.$op.', if defined, must be a ref hash holding extra parameters as needed') unless ref $rd eq 'HASH'; |
306
|
2
|
|
|
|
|
15
|
return { %$rd }; |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
#################################################################################################### |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
sub is_hostname ## RFC952/1123 |
312
|
|
|
|
|
|
|
{ |
313
|
235
|
|
|
235
|
0
|
59198
|
my ($name,$unicode)=@_; |
314
|
235
|
100
|
|
|
|
544
|
return 0 unless defined $name; |
315
|
234
|
100
|
|
|
|
394
|
$unicode=0 unless defined $unicode; |
316
|
|
|
|
|
|
|
|
317
|
234
|
|
|
|
|
708
|
my @d=split(/\./,$name,-1); |
318
|
234
|
|
|
|
|
394
|
foreach my $d (@d) |
319
|
|
|
|
|
|
|
{ |
320
|
291
|
100
|
66
|
|
|
1038
|
return 0 unless (defined $d && $d ne ''); |
321
|
287
|
100
|
|
|
|
491
|
return 0 unless (length $d <= 63); |
322
|
286
|
100
|
100
|
|
|
1167
|
return 0 if (($d=~m/^-/) || ($d=~m/-$/)); |
323
|
284
|
100
|
66
|
|
|
1870
|
return 0 if (!$unicode && $d=~m/[^A-Za-z0-9\-]/); |
324
|
|
|
|
|
|
|
} |
325
|
33
|
|
|
|
|
110
|
return 1; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
sub is_ipv4 |
329
|
|
|
|
|
|
|
{ |
330
|
39
|
|
|
39
|
0
|
377
|
my ($ip,$checkpublic)=@_; |
331
|
|
|
|
|
|
|
|
332
|
39
|
100
|
|
|
|
77
|
return 0 unless defined $ip; |
333
|
38
|
|
|
|
|
186
|
my (@ip)=($ip=~m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/); |
334
|
38
|
100
|
|
|
|
91
|
return 0 unless (@ip==4); |
335
|
34
|
|
|
|
|
51
|
foreach my $s (@ip) |
336
|
|
|
|
|
|
|
{ |
337
|
133
|
100
|
66
|
|
|
457
|
return 0 unless (($s >= 0) && ($s <= 255)); |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
|
340
|
33
|
100
|
66
|
|
|
116
|
return 1 unless (defined $checkpublic && $checkpublic); |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
## Check if this IP is public (see RFC3330) |
343
|
32
|
100
|
|
|
|
61
|
return 0 if ($ip[0] == 0); ## 0.x.x.x [ RFC 1700 ] |
344
|
31
|
100
|
|
|
|
50
|
return 0 if ($ip[0] == 10); ## 10.x.x.x [ RFC 1918 ] |
345
|
30
|
100
|
|
|
|
49
|
return 0 if ($ip[0] == 127); ## 127.x.x.x [ RFC 1700 ] |
346
|
29
|
100
|
66
|
|
|
70
|
return 0 if (($ip[0] == 169) && ($ip[1]==254)); ## 169.254.0.0/16 link local |
347
|
28
|
100
|
66
|
|
|
72
|
return 0 if (($ip[0] == 172 ) && ($ip[1]>=16) && ($ip[1]<=31)); ## 172.16.x.x to 172.31.x.x [ RFC 1918 ] |
|
|
|
100
|
|
|
|
|
348
|
27
|
100
|
100
|
|
|
101
|
return 0 if (($ip[0] == 192 ) && ($ip[1]==0) && ($ip[2]==2)); ## 192.0.2.0/24 TEST-NET |
|
|
|
66
|
|
|
|
|
349
|
26
|
100
|
100
|
|
|
63
|
return 0 if (($ip[0] == 192 ) && ($ip[1]==168)); ## 192.168.x.x [ RFC 1918 ] |
350
|
25
|
100
|
66
|
|
|
60
|
return 0 if (($ip[0] >= 224) && ($ip[0] < 240 )); ## 224.0.0.0/4 Class D [ RFC 3171] |
351
|
24
|
50
|
|
|
|
34
|
return 0 if ($ip[0] >= 240); ## 240.0.0.0/4 Class E [ RFC 1700 ] |
352
|
24
|
|
|
|
|
78
|
return 1; |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
## Inspired by Net::IP which unfortunately requires Perl 5.8 |
356
|
|
|
|
|
|
|
sub is_ipv6 |
357
|
|
|
|
|
|
|
{ |
358
|
12
|
|
|
12
|
0
|
14
|
my ($ip,$checkpublic)=@_; |
359
|
12
|
50
|
|
|
|
24
|
return 0 unless defined $ip; |
360
|
|
|
|
|
|
|
|
361
|
12
|
|
|
|
|
30
|
my (@ip)=split(/:/,$ip); |
362
|
12
|
50
|
33
|
|
|
52
|
return 0 unless ((@ip > 0) && (@ip <= 8)); |
363
|
12
|
50
|
33
|
|
|
62
|
return 0 if (($ip=~m/^:[^:]/) || ($ip=~m/[^:]:$/)); |
364
|
12
|
50
|
|
|
|
25
|
return 0 if ($ip =~ s/:(?=:)//g > 1); |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
## We do not allow IPv4 in IPv6 |
367
|
12
|
100
|
|
|
|
16
|
return 0 if grep { ! /^[a-f\d]{0,4}$/i } @ip; |
|
19
|
|
|
|
|
91
|
|
368
|
|
|
|
|
|
|
|
369
|
1
|
50
|
33
|
|
|
6
|
return 1 unless (defined($checkpublic) && $checkpublic); |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
## Check if this IP is public |
372
|
1
|
|
|
|
|
5
|
my ($ip1,$ip2)=split(/::/,$ip); |
373
|
1
|
|
50
|
|
|
4
|
$ip1=join('',map { sprintf('%04s',$_) } split(/:/,$ip1 || '')); |
|
8
|
|
|
|
|
14
|
|
374
|
1
|
|
50
|
|
|
8
|
$ip2=join('',map { sprintf('%04s',$_) } split(/:/,$ip2 || '')); |
|
0
|
|
|
|
|
0
|
|
375
|
1
|
|
|
|
|
4
|
my $wip=$ip1.('0' x (32-length($ip1)-length($ip2))).$ip2; ## 32 chars |
376
|
1
|
|
|
|
|
12
|
my $bip=unpack('B128',pack('H32',$wip)); ## 128-bit array |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
## RFC 3513 §2.4 |
379
|
1
|
50
|
|
|
|
5
|
return 0 if ($bip=~m/^0{127}/); ## unspecified + loopback |
380
|
1
|
50
|
|
|
|
10
|
return 0 if ($bip=~m/^1{7}/); ## multicast + link-local unicast + site-local unicast |
381
|
|
|
|
|
|
|
## everything else is global unicast, |
382
|
|
|
|
|
|
|
## but see §4 and http://www.iana.org/assignments/ipv6-address-space |
383
|
1
|
50
|
|
|
|
5
|
return 0 if ($bip=~m/^000/); ## unassigned + reserved (first 6 lines) |
384
|
1
|
50
|
|
|
|
11
|
return 1 if ($bip=~m/^001/); ## global unicast (2000::/3) |
385
|
0
|
|
|
|
|
0
|
return 0; ## everything else is unassigned |
386
|
|
|
|
|
|
|
} |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
#################################################################################################### |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
sub compare_durations |
391
|
|
|
|
|
|
|
{ |
392
|
10
|
|
|
10
|
0
|
11
|
my ($dtd1,$dtd2)=@_; |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
## from DateTime::Duration module, internally are stored: months, days, minutes, seconds and nanoseconds |
395
|
|
|
|
|
|
|
## those are the keys of the hash ref given by the deltas method |
396
|
10
|
|
|
|
|
19
|
my %d1=$dtd1->deltas(); |
397
|
10
|
|
|
|
|
92
|
my %d2=$dtd2->deltas(); |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
## Not perfect, but should be enough for us |
400
|
10
|
|
33
|
|
|
141
|
return (($d1{months} <=> $d2{months}) || |
401
|
|
|
|
|
|
|
($d1{days} <=> $d2{days}) || |
402
|
|
|
|
|
|
|
($d1{minutes} <=> $d2{minutes}) || |
403
|
|
|
|
|
|
|
($d1{seconds} <=> $d2{seconds}) |
404
|
|
|
|
|
|
|
); |
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
#################################################################################################### |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
sub xml_is_normalizedstring |
410
|
|
|
|
|
|
|
{ |
411
|
10
|
|
|
10
|
0
|
318
|
my ($what,$min,$max)=@_; |
412
|
10
|
|
|
|
|
18
|
my $r=xml_is_string($what,$min,$max); |
413
|
10
|
100
|
|
|
|
25
|
return 0 if $r==0; |
414
|
6
|
100
|
|
|
|
16
|
return 0 if $what=~m/[\r\n\t]/; |
415
|
5
|
|
|
|
|
15
|
return 1; |
416
|
|
|
|
|
|
|
} |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
sub xml_is_string |
419
|
|
|
|
|
|
|
{ |
420
|
10
|
|
|
10
|
0
|
9
|
my ($what,$min,$max)=@_; |
421
|
10
|
100
|
|
|
|
25
|
return 0 unless defined $what; |
422
|
9
|
50
|
|
|
|
31
|
return 0 unless $what=~m/^[\x{0009}\x{000A}\x{000D}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]*$/; ## XML Char definition (all Unicode excluding the surrogate blocks, FFFE, and FFFF) |
423
|
9
|
|
|
|
|
12
|
my $l=length $what; |
424
|
9
|
100
|
100
|
|
|
30
|
return 0 if (defined $min && $l < $min); |
425
|
8
|
100
|
100
|
|
|
28
|
return 0 if (defined $max && $l > $max); |
426
|
6
|
|
|
|
|
8
|
return 1; |
427
|
|
|
|
|
|
|
} |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
sub xml_is_token |
430
|
|
|
|
|
|
|
{ |
431
|
13
|
|
|
13
|
0
|
22
|
my ($what,$min,$max)=@_; |
432
|
|
|
|
|
|
|
|
433
|
13
|
100
|
|
|
|
32
|
return 0 unless defined $what; |
434
|
12
|
100
|
|
|
|
29
|
return 0 if $what=~m/[\r\n\t]/; |
435
|
11
|
100
|
|
|
|
25
|
return 0 if $what=~m/^\s/; |
436
|
10
|
100
|
|
|
|
25
|
return 0 if $what=~m/\s$/; |
437
|
9
|
100
|
|
|
|
15
|
return 0 if $what=~m/\s\s/; |
438
|
|
|
|
|
|
|
|
439
|
8
|
|
|
|
|
11
|
my $l=length $what; |
440
|
8
|
100
|
100
|
|
|
32
|
return 0 if (defined $min && $l < $min); |
441
|
7
|
100
|
100
|
|
|
28
|
return 0 if (defined $max && $l > $max); |
442
|
5
|
|
|
|
|
13
|
return 1; |
443
|
|
|
|
|
|
|
} |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
sub xml_is_ncname ## xml:id is of this type |
446
|
|
|
|
|
|
|
{ |
447
|
0
|
|
|
0
|
0
|
0
|
my ($what)=@_; |
448
|
0
|
0
|
0
|
|
|
0
|
return 0 unless defined($what) && $what; |
449
|
79
|
|
|
79
|
|
1471
|
return ($what=~m/^\p{ID_Start}\p{ID_Continue}*$/) |
|
79
|
|
|
|
|
131
|
|
|
79
|
|
|
|
|
1906
|
|
|
0
|
|
|
|
|
0
|
|
450
|
|
|
|
|
|
|
} |
451
|
|
|
|
|
|
|
|
452
|
5
|
100
|
100
|
5
|
0
|
7
|
sub verify_ushort { my $in=shift; return (defined($in) && ($in=~m/^\d+$/) && ($in < 65536))? 1 : 0; } |
|
5
|
|
|
|
|
54
|
|
453
|
5
|
100
|
100
|
5
|
0
|
10
|
sub verify_ubyte { my $in=shift; return (defined($in) && ($in=~m/^\d+$/) && ($in < 256))? 1 : 0; } |
|
5
|
|
|
|
|
51
|
|
454
|
4
|
100
|
100
|
4
|
0
|
8
|
sub verify_hex { my $in=shift; return (defined($in) && ($in=~m/^[0-9A-F]+$/i))? 1 : 0; } |
|
4
|
|
|
|
|
34
|
|
455
|
|
|
|
|
|
|
sub verify_int |
456
|
|
|
|
|
|
|
{ |
457
|
13
|
|
|
13
|
0
|
19
|
my ($in,$min,$max)=@_; |
458
|
13
|
100
|
100
|
|
|
98
|
return 0 unless defined($in) && ($in=~m/^-?\d+$/); |
459
|
11
|
100
|
|
|
|
35
|
return 0 if ($in < (defined $min ? $min : -2147483648)); |
|
|
100
|
|
|
|
|
|
460
|
8
|
100
|
|
|
|
25
|
return 0 if ($in > (defined $max ? $max : 2147483647)); |
|
|
100
|
|
|
|
|
|
461
|
5
|
|
|
|
|
16
|
return 1; |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
sub verify_base64 |
465
|
|
|
|
|
|
|
{ |
466
|
31
|
|
|
31
|
0
|
61
|
my ($in,$min,$max)=@_; |
467
|
31
|
|
|
|
|
32
|
my $b04='[AQgw]'; |
468
|
31
|
|
|
|
|
29
|
my $b16='[AEIMQUYcgkosw048]'; |
469
|
31
|
|
|
|
|
29
|
my $b64='[A-Za-z0-9+/]'; |
470
|
31
|
100
|
|
|
|
444
|
return 0 unless ($in=~m/^(?:(?:$b64 ?$b64 ?$b64 ?$b64 ?)*(?:(?:$b64 ?$b64 ?$b64 ?$b64)|(?:$b64 ?$b64 ?$b16 ?=)|(?:$b64 ?$b04 ?= ?=)))?$/); |
471
|
27
|
100
|
100
|
|
|
86
|
return 0 if (defined $min && (length $in < $min)); |
472
|
24
|
100
|
100
|
|
|
50
|
return 0 if (defined $max && (length $in > $max)); |
473
|
23
|
|
|
|
|
96
|
return 1; |
474
|
|
|
|
|
|
|
} |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
## Same in XML and in RFC3066 |
477
|
|
|
|
|
|
|
sub xml_is_language |
478
|
|
|
|
|
|
|
{ |
479
|
3
|
|
|
3
|
0
|
4
|
my $in=shift; |
480
|
3
|
50
|
|
|
|
10
|
return 0 unless defined $in; |
481
|
3
|
100
|
|
|
|
23
|
return 1 if ($in=~m/^[a-zA-Z]{1,8}(?:-[a-zA-Z0-9]{1,8})*$/); |
482
|
1
|
|
|
|
|
4
|
return 0; |
483
|
|
|
|
|
|
|
} |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
sub xml_is_boolean |
486
|
|
|
|
|
|
|
{ |
487
|
6
|
|
|
6
|
0
|
9
|
my $in=shift; |
488
|
6
|
50
|
|
|
|
17
|
return 0 unless defined $in; |
489
|
6
|
100
|
|
|
|
38
|
return 1 if ($in=~m/^(?:1|0|true|false)$/); |
490
|
2
|
|
|
|
|
6
|
return 0; |
491
|
|
|
|
|
|
|
} |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
sub xml_parse_boolean |
494
|
|
|
|
|
|
|
{ |
495
|
0
|
|
|
0
|
0
|
0
|
my $in=shift; |
496
|
0
|
|
|
|
|
0
|
return {'true'=>1,1=>1,0=>0,'false'=>0}->{$in}; |
497
|
|
|
|
|
|
|
} |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
sub xml_escape |
500
|
|
|
|
|
|
|
{ |
501
|
0
|
|
|
0
|
0
|
0
|
my ($in)=@_; |
502
|
0
|
|
|
|
|
0
|
$in=~s/&/&/g; |
503
|
0
|
|
|
|
|
0
|
$in=~s/</g; |
504
|
0
|
|
|
|
|
0
|
$in=~s/>/>/g; |
505
|
0
|
|
|
|
|
0
|
return $in; |
506
|
|
|
|
|
|
|
} |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
sub xml_write |
509
|
|
|
|
|
|
|
{ |
510
|
0
|
|
|
0
|
0
|
0
|
my $rd=shift; |
511
|
0
|
|
|
|
|
0
|
my @t; |
512
|
0
|
0
|
|
|
|
0
|
foreach my $d (ref $rd->[0] ? @$rd : ($rd)) ## $d is a node=ref array |
513
|
|
|
|
|
|
|
{ |
514
|
0
|
|
|
|
|
0
|
my @c; ## list of children nodes |
515
|
|
|
|
|
|
|
my %attr; |
516
|
0
|
|
|
|
|
0
|
foreach my $e (grep { defined } @$d) |
|
0
|
|
|
|
|
0
|
|
517
|
|
|
|
|
|
|
{ |
518
|
0
|
0
|
|
|
|
0
|
if (ref $e eq 'HASH') |
519
|
|
|
|
|
|
|
{ |
520
|
0
|
|
|
|
|
0
|
while(my ($k,$v)=each(%$e)) { $attr{$k}=$v; } |
|
0
|
|
|
|
|
0
|
|
521
|
|
|
|
|
|
|
} else |
522
|
|
|
|
|
|
|
{ |
523
|
0
|
|
|
|
|
0
|
push @c,$e; |
524
|
|
|
|
|
|
|
} |
525
|
|
|
|
|
|
|
} |
526
|
0
|
|
|
|
|
0
|
my $tag=shift(@c); |
527
|
0
|
0
|
|
|
|
0
|
my $attr=keys(%attr)? ' '.join(' ',map { $_.'="'.$attr{$_}.'"' } sort { $a cmp $b } keys %attr) : ''; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
528
|
0
|
0
|
0
|
|
|
0
|
if (!@c || (@c==1 && !ref($c[0]) && ($c[0] eq ''))) |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
529
|
|
|
|
|
|
|
{ |
530
|
0
|
|
|
|
|
0
|
push @t,'<'.$tag.$attr.'/>'; |
531
|
|
|
|
|
|
|
} else |
532
|
|
|
|
|
|
|
{ |
533
|
0
|
|
|
|
|
0
|
push @t,'<'.$tag.$attr.'>'; |
534
|
0
|
0
|
0
|
|
|
0
|
push @t,(@c==1 && !ref($c[0]))? xml_escape($c[0]) : xml_write(\@c); |
535
|
0
|
|
|
|
|
0
|
push @t,''.$tag.'>'; |
536
|
|
|
|
|
|
|
} |
537
|
|
|
|
|
|
|
} |
538
|
0
|
|
|
|
|
0
|
return @t; |
539
|
|
|
|
|
|
|
} |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
sub xml_indent |
542
|
|
|
|
|
|
|
{ |
543
|
0
|
|
|
0
|
0
|
0
|
my $xml=shift; |
544
|
0
|
|
|
|
|
0
|
chomp $xml; |
545
|
0
|
|
|
|
|
0
|
my $r=''; |
546
|
|
|
|
|
|
|
|
547
|
0
|
|
|
|
|
0
|
$xml=~s!(<)!\n$1!g; |
548
|
0
|
|
|
|
|
0
|
$xml=~s!<(\S+)>(.+)\n\1>!<$1>$2$1>!g; |
549
|
0
|
|
|
|
|
0
|
$xml=~s!<(\S+)((?:\s+\S+=['"][^'"]+['"])+)>(.+)\n\1>!<$1$2>$3$1>!g; |
550
|
|
|
|
|
|
|
|
551
|
0
|
|
|
|
|
0
|
my $s=0; |
552
|
0
|
|
|
|
|
0
|
foreach my $m (split(/\n/,$xml)) |
553
|
|
|
|
|
|
|
{ |
554
|
0
|
0
|
|
|
|
0
|
next if $m=~m/^\s*$/; |
555
|
0
|
0
|
|
|
|
0
|
$s-- if ($m=~m!^\S+>$!); |
556
|
|
|
|
|
|
|
|
557
|
0
|
|
|
|
|
0
|
$r.=' ' x $s; |
558
|
0
|
|
|
|
|
0
|
$r.=$m."\n"; |
559
|
|
|
|
|
|
|
|
560
|
0
|
0
|
|
|
|
0
|
$s++ if ($m=~m!^<[^>?]+[^/](?:\s+\S+=['"][^'"]+['"])*>$!); |
561
|
0
|
0
|
|
|
|
0
|
$s-- if ($m=~m!^\S+>$!); |
562
|
|
|
|
|
|
|
} |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
## As xml_indent is used during logging, we do a final quick check (spaces should not be relevant anyway) |
565
|
|
|
|
|
|
|
## This test should probably be dumped as some point in the future when we are confident enough. But we got hit in the past by some subtleties, so... |
566
|
0
|
|
|
|
|
0
|
my $in=$xml; |
567
|
0
|
|
|
|
|
0
|
$in=~s/\s+//g; |
568
|
0
|
|
|
|
|
0
|
my $out=$r; |
569
|
0
|
|
|
|
|
0
|
$out=~s/\s+//g; |
570
|
0
|
0
|
|
|
|
0
|
if ($in ne $out) { Net::DRI::Exception::err_assert('xml_indent failed to do its job, please report !'); } |
|
0
|
|
|
|
|
0
|
|
571
|
|
|
|
|
|
|
|
572
|
0
|
|
|
|
|
0
|
return $r; |
573
|
|
|
|
|
|
|
} |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
sub xml_list_children |
576
|
|
|
|
|
|
|
{ |
577
|
0
|
|
|
0
|
0
|
0
|
my $node=shift; |
578
|
|
|
|
|
|
|
## '*' catch all element nodes being direct children of given node |
579
|
0
|
|
0
|
|
|
0
|
return map { [ $_->localname() || $_->nodeName(),$_ ] } grep { $_->nodeType() == 1 } $node->getChildrenByTagName('*'); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
580
|
|
|
|
|
|
|
} |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
sub xml_traverse |
583
|
|
|
|
|
|
|
{ |
584
|
0
|
|
|
0
|
0
|
0
|
my ($node,$ns,@nodes)=@_; |
585
|
0
|
|
|
|
|
0
|
my $p=sprintf('*[namespace-uri()="%s" and local-name()="%s"]',$ns,shift(@nodes)); |
586
|
0
|
0
|
|
|
|
0
|
$p.='/'.join('/',map { '*[local-name()="'.$_.'"]' } @nodes) if @nodes; |
|
0
|
|
|
|
|
0
|
|
587
|
0
|
|
|
|
|
0
|
my $r=$node->findnodes($p); |
588
|
0
|
0
|
|
|
|
0
|
return unless $r->size(); |
589
|
0
|
0
|
|
|
|
0
|
return ($r->size()==1)? $r->get_node(1) : $r->get_nodelist(); |
590
|
|
|
|
|
|
|
} |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
sub xml_child_content |
593
|
|
|
|
|
|
|
{ |
594
|
0
|
|
|
0
|
0
|
0
|
my ($node,$ns,$what)=@_; |
595
|
0
|
|
|
|
|
0
|
my $list=$node->getChildrenByTagNameNS($ns,$what); |
596
|
0
|
0
|
|
|
|
0
|
return undef unless $list->size()==1; ## no critic (Subroutines::ProhibitExplicitReturnUndef) |
597
|
0
|
|
|
|
|
0
|
my $n=$list->get_node(1); |
598
|
0
|
0
|
|
|
|
0
|
return defined $n ? $n->textContent() : undef; |
599
|
|
|
|
|
|
|
} |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
#################################################################################################### |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
sub remcam |
604
|
|
|
|
|
|
|
{ |
605
|
0
|
|
|
0
|
0
|
0
|
my $in=shift; |
606
|
0
|
|
|
|
|
0
|
$in=~s/ID/_id/g; |
607
|
0
|
|
|
|
|
0
|
$in=~s/([A-Z])/_$1/g; |
608
|
0
|
|
|
|
|
0
|
return lc($in); |
609
|
|
|
|
|
|
|
} |
610
|
|
|
|
|
|
|
|
611
|
0
|
0
|
|
0
|
0
|
0
|
sub encode { my ($cs,$data)=@_; return Encode::encode($cs,ref $data? $data->as_string() : $data,1); } ## Will croak on malformed data (a case that should not happen) |
|
0
|
|
|
|
|
0
|
|
612
|
0
|
|
|
0
|
0
|
0
|
sub encode_utf8 { return encode('UTF-8',$_[0]); } ## no critic (Subroutines::RequireArgUnpacking) |
613
|
0
|
|
|
0
|
0
|
0
|
sub encode_ascii { return encode('ascii',$_[0]); } ## no critic (Subroutines::RequireArgUnpacking) |
614
|
0
|
|
|
0
|
0
|
0
|
sub decode { my ($cs,$data)=@_; return Encode::decode($cs,$data,1); } ## Will croak on malformed data (a case that should not happen) |
|
0
|
|
|
|
|
0
|
|
615
|
0
|
|
|
0
|
0
|
0
|
sub decode_utf8 { return decode('UTF-8',$_[0]); } ## no critic (Subroutines::RequireArgUnpacking) |
616
|
0
|
|
|
0
|
0
|
0
|
sub decode_ascii { return decode('ascii',$_[0]); } ## no critic (Subroutines::RequireArgUnpacking) |
617
|
0
|
|
|
0
|
0
|
0
|
sub decode_latin1{ return decode('iso-8859-1',$_[0]); } ## no critic (Subroutines::RequireArgUnpacking) |
618
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
sub normalize_name |
620
|
|
|
|
|
|
|
{ |
621
|
15
|
|
|
15
|
0
|
22
|
my ($type,$key)=@_; |
622
|
15
|
|
|
|
|
28
|
$type=lc($type); |
623
|
|
|
|
|
|
|
## contact IDs may be case sensitive... |
624
|
|
|
|
|
|
|
## Will need to be redone differently with IDNs |
625
|
15
|
100
|
66
|
|
|
66
|
$key=lc $key if ($type eq 'domain' || $type eq 'nsgroup'); |
626
|
15
|
100
|
66
|
|
|
62
|
$key=lc $key if ($type eq 'host' && $key=~m/\./); ## last test part is done only to handle the pure mess created by Nominet .UK "EPP" implementation... |
627
|
15
|
|
|
|
|
49
|
return ($type,$key); |
628
|
|
|
|
|
|
|
} |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
## DateTime object to Zulu time stringified |
631
|
|
|
|
|
|
|
sub dto2zstring |
632
|
|
|
|
|
|
|
{ |
633
|
0
|
|
|
0
|
0
|
0
|
my ($dt)=@_; |
634
|
0
|
|
|
|
|
0
|
my $date=$dt->clone()->set_time_zone('UTC'); |
635
|
0
|
0
|
|
|
|
0
|
return $date->ymd('-').'T'.$date->hms(':').($date->microsecond() ? '.'.sprintf('%06s',$date->microsecond()) : '').'Z'; |
636
|
|
|
|
|
|
|
} |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
#################################################################################################### |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
## RFC2782 |
641
|
|
|
|
|
|
|
## (Net::DNS rrsort for SRV records does not seem to implement the same algorithm as the one specificied in the RFC, |
642
|
|
|
|
|
|
|
## as it just does a comparison on priority then weight) |
643
|
|
|
|
|
|
|
sub dns_srv_order |
644
|
|
|
|
|
|
|
{ |
645
|
0
|
|
|
0
|
0
|
0
|
my (@args)=@_; |
646
|
0
|
|
|
|
|
0
|
my (@r,%r); |
647
|
0
|
|
|
|
|
0
|
foreach my $ans (@args) |
648
|
|
|
|
|
|
|
{ |
649
|
0
|
|
|
|
|
0
|
push @{$r{$ans->priority()}},$ans; |
|
0
|
|
|
|
|
0
|
|
650
|
|
|
|
|
|
|
} |
651
|
0
|
|
|
|
|
0
|
foreach my $pri (sort { $a <=> $b } keys(%r)) |
|
0
|
|
|
|
|
0
|
|
652
|
|
|
|
|
|
|
{ |
653
|
0
|
|
|
|
|
0
|
my @o=@{$r{$pri}}; |
|
0
|
|
|
|
|
0
|
|
654
|
0
|
0
|
|
|
|
0
|
if (@o > 1) |
655
|
|
|
|
|
|
|
{ |
656
|
0
|
|
|
|
|
0
|
my $ts=0; |
657
|
0
|
|
|
|
|
0
|
foreach (@o) { $ts+=$_->weight(); } |
|
0
|
|
|
|
|
0
|
|
658
|
0
|
|
|
|
|
0
|
my $s=0; |
659
|
0
|
|
|
|
|
0
|
@o=map { $s+=$_->weight(); [ $s, $_ ] } (grep { $_->weight() == 0 } @o, grep { $_->weight() > 0 } @o); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
660
|
0
|
|
|
|
|
0
|
my $cs=0; |
661
|
0
|
|
|
|
|
0
|
while(@o > 1) |
662
|
|
|
|
|
|
|
{ |
663
|
0
|
|
|
|
|
0
|
my $r=int(rand($ts-$cs+1)); |
664
|
0
|
|
|
|
|
0
|
foreach my $i (0..$#o) |
665
|
|
|
|
|
|
|
{ |
666
|
0
|
0
|
|
|
|
0
|
next unless $o[$i]->[0] >= $r; |
667
|
0
|
|
|
|
|
0
|
$cs+=$o[$i]->[0]; |
668
|
0
|
|
|
|
|
0
|
foreach my $j (($i+1)..$#o) { $o[$j]->[0]-=$o[$i]->[0]; } |
|
0
|
|
|
|
|
0
|
|
669
|
0
|
|
|
|
|
0
|
push @r,$o[$i]->[1]; |
670
|
0
|
|
|
|
|
0
|
splice(@o,$i,1); |
671
|
0
|
|
|
|
|
0
|
last; |
672
|
|
|
|
|
|
|
} |
673
|
|
|
|
|
|
|
} |
674
|
|
|
|
|
|
|
} |
675
|
0
|
|
|
|
|
0
|
push @r,$o[0]->[1]; |
676
|
|
|
|
|
|
|
} |
677
|
0
|
|
|
|
|
0
|
return map { [$_->target(),$_->port()] } @r; |
|
0
|
|
|
|
|
0
|
|
678
|
|
|
|
|
|
|
} |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
#################################################################################################### |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
sub load_module |
683
|
|
|
|
|
|
|
{ |
684
|
235
|
|
|
235
|
0
|
518
|
my ($class,$etype)=@_; |
685
|
235
|
|
|
|
|
327
|
my $ok = eval { Module::Load::load($class); 1; }; |
|
235
|
|
|
|
|
835
|
|
|
177
|
|
|
|
|
2616
|
|
686
|
235
|
100
|
50
|
|
|
13645
|
Net::DRI::Exception::err_failed_load_module($etype,$class,$@ // 'unknown error') if ! defined $ok || ! $ok || $@; |
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
687
|
177
|
|
|
|
|
647
|
return; |
688
|
|
|
|
|
|
|
} |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
#################################################################################################### |
691
|
|
|
|
|
|
|
1; |