line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# mt-aws-glacier - Amazon Glacier sync client |
2
|
|
|
|
|
|
|
# Copyright (C) 2012-2014 Victor Efimov |
3
|
|
|
|
|
|
|
# http://mt-aws.com (also http://vs-dev.com) vs@vs-dev.com |
4
|
|
|
|
|
|
|
# License: GPLv3 |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# This file is part of "mt-aws-glacier" |
7
|
|
|
|
|
|
|
# |
8
|
|
|
|
|
|
|
# mt-aws-glacier is free software: you can redistribute it and/or modify |
9
|
|
|
|
|
|
|
# it under the terms of the GNU General Public License as published by |
10
|
|
|
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or |
11
|
|
|
|
|
|
|
# (at your option) any later version. |
12
|
|
|
|
|
|
|
# |
13
|
|
|
|
|
|
|
# mt-aws-glacier is distributed in the hope that it will be useful, |
14
|
|
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
|
|
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
|
|
|
|
|
|
|
# GNU General Public License for more details. |
17
|
|
|
|
|
|
|
# |
18
|
|
|
|
|
|
|
# You should have received a copy of the GNU General Public License |
19
|
|
|
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
package App::MtAws::Utils; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
our $VERSION = '1.114_2'; |
24
|
|
|
|
|
|
|
|
25
|
113
|
|
|
113
|
|
103741
|
use strict; |
|
113
|
|
|
|
|
170
|
|
|
113
|
|
|
|
|
3607
|
|
26
|
113
|
|
|
113
|
|
537
|
use warnings; |
|
113
|
|
|
|
|
172
|
|
|
113
|
|
|
|
|
4320
|
|
27
|
113
|
|
|
113
|
|
1355
|
use utf8; |
|
113
|
|
|
|
|
204
|
|
|
113
|
|
|
|
|
707
|
|
28
|
113
|
|
|
113
|
|
2754
|
use File::Spec; |
|
113
|
|
|
|
|
158
|
|
|
113
|
|
|
|
|
2724
|
|
29
|
113
|
|
|
113
|
|
516
|
use Cwd; |
|
113
|
|
|
|
|
142
|
|
|
113
|
|
|
|
|
7499
|
|
30
|
113
|
|
|
113
|
|
77739
|
use File::stat; |
|
113
|
|
|
|
|
875232
|
|
|
113
|
|
|
|
|
637
|
|
31
|
113
|
|
|
113
|
|
8069
|
use Carp; |
|
113
|
|
|
|
|
192
|
|
|
113
|
|
|
|
|
6747
|
|
32
|
113
|
|
|
113
|
|
602
|
use Encode; |
|
113
|
|
|
|
|
185
|
|
|
113
|
|
|
|
|
9380
|
|
33
|
113
|
|
|
113
|
|
97534
|
use LWP::UserAgent; |
|
113
|
|
|
|
|
5380583
|
|
|
113
|
|
|
|
|
4762
|
|
34
|
113
|
|
|
113
|
|
1182
|
use Time::Local; |
|
113
|
|
|
|
|
217
|
|
|
113
|
|
|
|
|
8494
|
|
35
|
113
|
|
|
113
|
|
636
|
use Config; |
|
113
|
|
|
|
|
170
|
|
|
113
|
|
|
|
|
4664
|
|
36
|
113
|
|
|
113
|
|
559
|
use bytes (); |
|
113
|
|
|
|
|
202
|
|
|
113
|
|
|
|
|
2269
|
|
37
|
|
|
|
|
|
|
|
38
|
113
|
|
|
113
|
|
496
|
use Exporter 'import'; |
|
113
|
|
|
|
|
166
|
|
|
113
|
|
|
|
|
3282
|
|
39
|
|
|
|
|
|
|
|
40
|
113
|
|
|
113
|
|
519
|
use constant INVENTORY_TYPE_CSV => 'CSV'; |
|
113
|
|
|
|
|
171
|
|
|
113
|
|
|
|
|
8420
|
|
41
|
113
|
|
|
113
|
|
616
|
use constant INVENTORY_TYPE_JSON => 'JSON'; |
|
113
|
|
|
|
|
170
|
|
|
113
|
|
|
|
|
14717
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
our @EXPORT = qw/set_filename_encoding get_filename_encoding binaryfilename |
44
|
|
|
|
|
|
|
sanity_relative_filename is_relative_filename abs2rel binary_abs_path open_file sysreadfull syswritefull sysreadfull_chk syswritefull_chk |
45
|
|
|
|
|
|
|
hex_dump_string is_wide_string |
46
|
|
|
|
|
|
|
characterfilename try_drop_utf8_flag dump_request_response file_size file_mtime file_exists file_inodev |
47
|
|
|
|
|
|
|
is_64bit_os is_64bit_time is_y2038_supported |
48
|
|
|
|
|
|
|
INVENTORY_TYPE_JSON INVENTORY_TYPE_CSV/; |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
BEGIN { |
52
|
113
|
50
|
|
113
|
|
182320
|
if ($File::Spec::VERSION lt '3.13') { |
53
|
0
|
|
|
|
|
0
|
our $__orig_abs_to_rel = File::Spec->can("abs2rel"); |
54
|
113
|
|
|
113
|
|
617
|
no warnings 'once'; |
|
113
|
|
|
|
|
176
|
|
|
113
|
|
|
|
|
11604
|
|
55
|
|
|
|
|
|
|
*File::Spec::abs2rel = sub { |
56
|
0
|
|
|
|
|
0
|
my $r = $__orig_abs_to_rel->(@_); |
57
|
0
|
0
|
|
|
|
0
|
return '.' if $r eq ''; |
58
|
0
|
|
|
|
|
0
|
$r; |
59
|
0
|
|
|
|
|
0
|
}; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# Does not work with directory names |
65
|
|
|
|
|
|
|
sub sanity_relative_filename |
66
|
|
|
|
|
|
|
{ |
67
|
3694
|
|
|
3694
|
0
|
6862
|
my ($filename) = @_; |
68
|
3694
|
100
|
|
|
|
7425
|
return undef unless defined $filename; |
69
|
1496
|
100
|
|
|
|
3659
|
return undef if $filename =~ m!^//!g; |
70
|
1477
|
|
|
|
|
1886
|
$filename =~ s!^/!!; |
71
|
1477
|
100
|
|
|
|
4075
|
return undef if $filename =~ m![\r\n\t]!g; |
72
|
1472
|
100
|
|
|
|
7630
|
$filename = File::Spec->catdir( map {return undef if m!^\.\.?$!; $_; } split('/', File::Spec->canonpath($filename)) ); |
|
2955
|
|
|
|
|
4553
|
|
|
2946
|
|
|
|
|
9173
|
|
73
|
|
|
|
|
|
|
return undef |
74
|
1463
|
100
|
66
|
|
|
6910
|
if !defined($filename) || # workaround https://rt.cpan.org/Public/Bug/Display.html?id=86624 |
75
|
|
|
|
|
|
|
$filename eq ''; |
76
|
1461
|
|
|
|
|
3997
|
return $filename; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub is_relative_filename |
80
|
|
|
|
|
|
|
{ |
81
|
4538
|
|
|
4538
|
0
|
339449
|
my ($filename) = @_; |
82
|
4538
|
100
|
100
|
|
|
16384
|
return unless (defined($filename) && length($filename)); |
83
|
2339
|
100
|
100
|
|
|
17206
|
return if $filename =~ tr{\r\n\t}{} or index($filename, '//') != -1 or substr($filename, 0, 1) eq '/'; |
|
|
|
100
|
|
|
|
|
84
|
2303
|
100
|
|
|
|
7565
|
return undef if $filename =~ m{ |
85
|
|
|
|
|
|
|
(^|/)\.\.?(/|$) |
86
|
|
|
|
|
|
|
}x; |
87
|
2285
|
|
|
|
|
6173
|
1; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# TODO: test |
91
|
|
|
|
|
|
|
sub binary_abs_path |
92
|
|
|
|
|
|
|
{ |
93
|
99
|
|
|
99
|
0
|
2473
|
my ($path) = @_; |
94
|
|
|
|
|
|
|
|
95
|
99
|
|
|
0
|
|
601
|
local $SIG{__WARN__}=sub{}; |
96
|
|
|
|
|
|
|
|
97
|
99
|
|
|
|
|
227
|
my $orig_id = file_inodev($path, use_filename_encoding => 0); |
98
|
|
|
|
|
|
|
|
99
|
98
|
|
|
|
|
2806
|
my $abspath = Cwd::abs_path($path); |
100
|
|
|
|
|
|
|
|
101
|
98
|
50
|
|
|
|
208
|
return undef unless defined $abspath; |
102
|
98
|
50
|
|
|
|
189
|
return undef if $abspath eq ''; # workaround RT#47755 |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
# workaround RT#47755 - in case perms problem it tries to return File::Spec->rel2abs |
105
|
103
|
50
|
33
|
|
|
1164
|
return undef unless -e $abspath && file_inodev($abspath, use_filename_encoding => 0) eq $orig_id; |
106
|
|
|
|
|
|
|
|
107
|
102
|
|
|
|
|
1515
|
return $abspath; |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
our $_filename_encoding = 'UTF-8'; # global var |
111
|
|
|
|
|
|
|
|
112
|
617
|
|
|
621
|
0
|
129922
|
sub set_filename_encoding($) { $_filename_encoding = shift }; |
113
|
12880
|
100
|
|
12901
|
0
|
69111
|
sub get_filename_encoding() { $_filename_encoding || confess }; |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub binaryfilename(;$) |
116
|
|
|
|
|
|
|
{ |
117
|
7284
|
100
|
|
7301
|
0
|
44581
|
encode(get_filename_encoding, @_ ? shift : $_, Encode::DIE_ON_ERR|Encode::LEAVE_SRC); |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub characterfilename(;$) |
121
|
|
|
|
|
|
|
{ |
122
|
2850
|
100
|
|
2849
|
0
|
8512
|
decode(get_filename_encoding, @_ ? shift : $_, Encode::DIE_ON_ERR|Encode::LEAVE_SRC); |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
# TODO: test |
126
|
|
|
|
|
|
|
sub abs2rel |
127
|
|
|
|
|
|
|
{ |
128
|
2818
|
|
|
2803
|
0
|
4141
|
my ($path, $base) = (shift, shift); |
129
|
2818
|
50
|
33
|
|
|
11123
|
confess "too few arguments" unless defined($path) && defined($base); |
130
|
2802
|
|
|
|
|
7296
|
my (%args) = (use_filename_encoding => 1, @_); |
131
|
2802
|
100
|
|
|
|
4537
|
if ($args{use_filename_encoding}) { |
132
|
2753
|
|
|
|
|
3485
|
$path = binaryfilename $path; |
133
|
2753
|
|
|
|
|
63578
|
$base = binaryfilename $base; |
134
|
|
|
|
|
|
|
} |
135
|
2803
|
50
|
66
|
|
|
58154
|
$args{allow_rel_base} or $base =~ m{^/} or confess "relative basedir not allowed"; |
136
|
2803
|
|
|
|
|
145955
|
my $result = File::Spec->abs2rel($path, $base); |
137
|
2803
|
100
|
|
|
|
6804
|
$args{use_filename_encoding} ? characterfilename($result) : $result; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=pod |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
open_file(my $f, $filename, %args) |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
$args{mode} - mode to open, <, > or >> |
146
|
|
|
|
|
|
|
$args{use_filename_encoding} - (TRUE) - encode to binary string, (FALSE) - don't tocuh (already a binary string). Default TRUE |
147
|
|
|
|
|
|
|
$args{file_encoding} or $args{binary} - file content encoding or it's a binary file (mutual exclusive) |
148
|
|
|
|
|
|
|
$args{not_empty} - assert that file is not empty after open |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
Assertions made (using "confess"): |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
1) Bad arguments (programmer's error) |
153
|
|
|
|
|
|
|
2) File is not a plain file |
154
|
|
|
|
|
|
|
3) File is not a plain file, but after open (race conditions) |
155
|
|
|
|
|
|
|
4) File is empty and not_empty specified |
156
|
|
|
|
|
|
|
5) File is empty and not_empty specified, but after open (race conditions) |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
NOTE: If you want exceptions for (2) and (4) - check it before open_file. And additional checks inside open_file will |
159
|
|
|
|
|
|
|
prevent race conditions |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=cut |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub open_file($$%) |
164
|
|
|
|
|
|
|
{ |
165
|
224
|
|
|
223
|
0
|
20715
|
(undef, my $filename, my %args) = @_; |
166
|
224
|
|
|
|
|
996
|
%args = (use_filename_encoding => 1, %args); |
167
|
224
|
|
|
|
|
449
|
my $original_filename = $filename; |
168
|
|
|
|
|
|
|
|
169
|
225
|
|
|
|
|
577
|
my %checkargs = %args; |
170
|
225
|
|
66
|
|
|
2110
|
defined $checkargs{$_} && delete $checkargs{$_} for qw/use_filename_encoding mode file_encoding not_empty binary/; |
171
|
225
|
100
|
|
|
|
665
|
confess "Unknown argument(s) to open_file: ".join(';', keys %checkargs) if %checkargs; |
172
|
|
|
|
|
|
|
|
173
|
224
|
100
|
|
|
|
827
|
confess 'Argument "mode" is required' unless defined($args{mode}); |
174
|
223
|
100
|
|
|
|
1661
|
confess "unknown mode $args{mode}" unless $args{mode} =~ m!^\+?(<|>>?)$!; |
175
|
221
|
|
|
|
|
356
|
my $mode = $args{mode}; |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
confess "not_empty can be used in read mode only" |
178
|
221
|
100
|
100
|
|
|
758
|
if ($args{not_empty} && $args{mode} ne '<'); |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
|
181
|
220
|
100
|
|
|
|
536
|
if (defined($args{file_encoding})) { |
|
|
100
|
|
|
|
|
|
182
|
184
|
|
|
|
|
444
|
$mode .= ":encoding($args{file_encoding})"; |
183
|
184
|
100
|
|
|
|
578
|
confess "cannot use binary and file_encoding at same time'" if $args{binary}; |
184
|
|
|
|
|
|
|
} elsif (!$args{binary}) { |
185
|
3
|
|
|
|
|
205
|
confess "there should be file encoding or 'binary'"; |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
219
|
100
|
|
|
|
517
|
if ($args{use_filename_encoding}) { |
189
|
218
|
|
|
|
|
545
|
$filename = binaryfilename $filename; |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
218
|
100
|
100
|
|
|
12392
|
confess "File is not a plain file" if -e $filename && (! -f $filename); |
193
|
216
|
100
|
100
|
|
|
979
|
confess "File should not be empty" if $args{not_empty} && (! -s $filename); |
194
|
|
|
|
|
|
|
|
195
|
215
|
100
|
|
|
|
6078
|
open ($_[0], $mode, $filename) or return; |
196
|
214
|
|
|
|
|
14110
|
my $f = $_[0]; |
197
|
|
|
|
|
|
|
|
198
|
214
|
50
|
|
|
|
1261
|
confess unless -f $f; # check for race condition - it was a file when we last checked, but now it's a directory |
199
|
213
|
50
|
66
|
|
|
698
|
confess if $args{not_empty} && (! -s $f); |
200
|
|
|
|
|
|
|
|
201
|
213
|
100
|
|
|
|
1884
|
binmode $f if $args{binary}; |
202
|
|
|
|
|
|
|
|
203
|
213
|
|
|
|
|
1441
|
return $f; |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
sub file_size($%) |
207
|
|
|
|
|
|
|
{ |
208
|
4
|
|
|
4
|
0
|
17
|
my $filename = shift; |
209
|
4
|
|
|
|
|
16
|
my (%args) = (use_filename_encoding => 1, @_); |
210
|
4
|
50
|
|
|
|
21
|
if ($args{use_filename_encoding}) { |
211
|
3
|
|
|
|
|
9
|
$filename = binaryfilename $filename; |
212
|
|
|
|
|
|
|
} |
213
|
3
|
50
|
|
|
|
318
|
confess "file not exists" unless -f $filename; |
214
|
3
|
|
|
|
|
30
|
return -s $filename; |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
sub file_exists($%) |
218
|
|
|
|
|
|
|
{ |
219
|
0
|
|
|
0
|
0
|
0
|
my $filename = shift; |
220
|
0
|
|
|
|
|
0
|
my (%args) = (use_filename_encoding => 1, @_); |
221
|
0
|
0
|
|
|
|
0
|
if ($args{use_filename_encoding}) { |
222
|
0
|
|
|
|
|
0
|
$filename = binaryfilename $filename; |
223
|
|
|
|
|
|
|
} |
224
|
0
|
|
|
|
|
0
|
return -f $filename; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
sub file_mtime($%) |
228
|
|
|
|
|
|
|
{ |
229
|
20
|
|
|
20
|
0
|
8319
|
my $filename = shift; |
230
|
20
|
|
|
|
|
46
|
my (%args) = (use_filename_encoding => 1, @_); |
231
|
20
|
50
|
|
|
|
48
|
if ($args{use_filename_encoding}) { |
232
|
20
|
|
|
|
|
34
|
$filename = binaryfilename $filename; |
233
|
|
|
|
|
|
|
} |
234
|
20
|
50
|
|
|
|
1498
|
confess "file not exists" unless -f $filename; |
235
|
20
|
|
|
|
|
59
|
return stat($filename)->mtime; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
# TODO: test |
239
|
|
|
|
|
|
|
sub file_inodev($%) |
240
|
|
|
|
|
|
|
{ |
241
|
294
|
|
|
294
|
0
|
810
|
my $filename = shift; |
242
|
294
|
|
|
|
|
648
|
my (%args) = (use_filename_encoding => 1, @_); |
243
|
294
|
100
|
|
|
|
540
|
if ($args{use_filename_encoding}) { |
244
|
98
|
|
|
|
|
153
|
$filename = binaryfilename $filename; |
245
|
|
|
|
|
|
|
} |
246
|
294
|
50
|
|
|
|
5153
|
confess "file not exists" unless -e $filename; |
247
|
294
|
|
|
|
|
679
|
my $s = stat($filename); |
248
|
294
|
|
|
|
|
28072
|
$s->dev."-".$s->ino; |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub is_wide_string |
252
|
|
|
|
|
|
|
{ |
253
|
629
|
100
|
100
|
629
|
0
|
9830
|
defined($_[0]) && utf8::is_utf8($_[0]) && (bytes::length($_[0]) != length($_[0])) |
254
|
|
|
|
|
|
|
} |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
# if we have ASCII-only data, let's drop UTF-8 flag in order to optimize some regexp stuff |
257
|
|
|
|
|
|
|
# TODO: write also version which does not check is_utf8 - it's faster when utf8 always set |
258
|
|
|
|
|
|
|
sub try_drop_utf8_flag |
259
|
|
|
|
|
|
|
{ |
260
|
2369
|
100
|
100
|
2369
|
0
|
10162
|
Encode::_utf8_off($_[0]) if utf8::is_utf8($_[0]) && (bytes::length($_[0]) == length($_[0])); |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
sub sysreadfull_chk($$$) |
264
|
|
|
|
|
|
|
{ |
265
|
40
|
|
|
40
|
0
|
54
|
my $len = $_[2]; |
266
|
40
|
|
|
|
|
81
|
sysreadfull(@_) == $len; |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
sub sysreadfull($$$) |
270
|
|
|
|
|
|
|
{ |
271
|
106
|
|
|
106
|
0
|
4368034
|
my ($file, $len) = ($_[0], $_[2]); |
272
|
106
|
|
|
|
|
133
|
my $n = 0; |
273
|
106
|
|
|
|
|
354
|
while ($len - $n) { |
274
|
152
|
|
|
|
|
157394
|
my $i = sysread($file, $_[1], $len - $n, $n); |
275
|
152
|
100
|
|
|
|
899
|
if (defined($i)) { |
|
|
100
|
|
|
|
|
|
276
|
133
|
100
|
|
|
|
236
|
if ($i == 0) { |
277
|
17
|
|
|
|
|
83
|
return $n; |
278
|
|
|
|
|
|
|
} else { |
279
|
116
|
|
|
|
|
465
|
$n += $i; |
280
|
|
|
|
|
|
|
} |
281
|
109
|
|
|
109
|
|
80027
|
} elsif ($!{EINTR}) { |
|
109
|
|
|
|
|
127216
|
|
|
109
|
|
|
|
|
104444
|
|
282
|
14
|
|
|
|
|
978
|
redo; |
283
|
|
|
|
|
|
|
} else { |
284
|
5
|
100
|
|
|
|
45
|
return $n ? $n : undef; |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
} |
287
|
84
|
|
|
|
|
464
|
return $n; |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
sub syswritefull_chk($$) |
291
|
|
|
|
|
|
|
{ |
292
|
40
|
|
|
40
|
0
|
71
|
my $length = length $_[1]; |
293
|
40
|
|
|
|
|
84
|
syswritefull(@_) == $length |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
sub syswritefull($$) |
297
|
|
|
|
|
|
|
{ |
298
|
64
|
|
|
64
|
0
|
13174
|
my ($file, $len) = ($_[0], length($_[1])); |
299
|
64
|
50
|
|
|
|
361
|
confess if is_wide_string($_[1]); |
300
|
64
|
|
|
|
|
776
|
my $n = 0; |
301
|
64
|
|
|
|
|
153
|
while ($len - $n) { |
302
|
76
|
|
|
|
|
26446
|
my $i = syswrite($file, $_[1], $len - $n, $n); |
303
|
74
|
100
|
|
|
|
442
|
if (defined($i)) { |
|
|
100
|
|
|
|
|
|
304
|
66
|
|
|
|
|
169
|
$n += $i; |
305
|
|
|
|
|
|
|
} elsif ($!{EINTR}) { |
306
|
3
|
|
|
|
|
214
|
redo; |
307
|
|
|
|
|
|
|
} else { |
308
|
5
|
100
|
|
|
|
42
|
return $n ? $n : undef; |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
} |
311
|
57
|
|
|
|
|
431
|
return $n; |
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
sub hex_dump_string |
315
|
|
|
|
|
|
|
{ |
316
|
510
|
|
|
510
|
0
|
5629
|
my ($str) = @_; |
317
|
510
|
|
|
|
|
771
|
my $isutf = is_wide_string($str); |
318
|
510
|
|
|
|
|
2254
|
Encode::_utf8_off($str); |
319
|
510
|
|
|
|
|
833
|
$str =~ s/\\/\\\\/g; |
320
|
510
|
|
|
|
|
516
|
$str =~ s/\r/\\r/g; |
321
|
510
|
|
|
|
|
548
|
$str =~ s/\n/\\n/g; |
322
|
510
|
|
|
|
|
1523
|
$str =~ s/\t/\\t/g; |
323
|
510
|
|
|
|
|
491
|
$str =~ s/\"/\\\"/g; |
324
|
510
|
|
|
|
|
8595
|
$str =~ s/([[:cntrl:]]|[[:^ascii:]])/sprintf("\\x%02X",ord($1))/eg; |
|
609
|
|
|
|
|
2750
|
|
325
|
510
|
|
|
|
|
842
|
$str = "\"$str\""; |
326
|
510
|
100
|
|
|
|
899
|
$str = "(UTF-8) ".$str if $isutf; |
327
|
510
|
|
|
|
|
1604
|
$str; |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
sub dump_request_response |
331
|
|
|
|
|
|
|
{ |
332
|
19
|
|
|
19
|
0
|
24
|
my ($req, $resp) = @_; |
333
|
19
|
|
|
|
|
29
|
my $out = ''; |
334
|
19
|
|
|
|
|
39
|
$out .= "===REQUEST:\n"; |
335
|
19
|
|
|
|
|
57
|
$out .= join(" ", $req->method, $req->uri)."\n"; |
336
|
|
|
|
|
|
|
|
337
|
19
|
|
|
|
|
462
|
my $req_headers = $req->headers->as_string; |
338
|
|
|
|
|
|
|
|
339
|
19
|
|
|
|
|
1598
|
$req_headers =~ s!^(Authorization:.*Credential=)([A-Za-z0-9]+)/!$1***REMOVED***/!; |
340
|
19
|
|
|
|
|
133
|
$req_headers =~ s!^(Authorization:.*Signature=)([A-Za-z0-9]+)!$1***REMOVED***!; |
341
|
|
|
|
|
|
|
|
342
|
19
|
|
|
|
|
43
|
$out .= $req_headers; |
343
|
|
|
|
|
|
|
|
344
|
19
|
50
|
33
|
|
|
74
|
if ($req->content_type ne 'application/octet-stream' && $req->content && length($req->content)) { |
|
|
|
33
|
|
|
|
|
345
|
0
|
|
|
|
|
0
|
$out .= "\n".$req->content; |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
19
|
|
|
|
|
656
|
$out .= "\n===RESPONSE:\n"; |
349
|
19
|
50
|
|
|
|
50
|
$out .= $resp->protocol." " if $resp->protocol; |
350
|
19
|
|
|
|
|
195
|
$out .= $resp->status_line."\n"; |
351
|
19
|
|
|
|
|
245
|
$out .= $resp->headers->as_string; |
352
|
|
|
|
|
|
|
|
353
|
19
|
0
|
33
|
|
|
409
|
if ($resp->content_type eq 'application/json' && $resp->content && length($resp->content)) { |
|
|
|
33
|
|
|
|
|
354
|
0
|
|
|
|
|
0
|
$out .= "\n".$resp->content; |
355
|
|
|
|
|
|
|
} |
356
|
19
|
|
|
|
|
301
|
$out .= "\n\n"; |
357
|
19
|
|
|
|
|
127
|
$out; |
358
|
|
|
|
|
|
|
} |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
sub get_config_var($) # separate function so we can override it in tests |
362
|
|
|
|
|
|
|
{ |
363
|
23728
|
|
|
23728
|
0
|
296674
|
$Config{shift()} |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
sub is_64bit_os |
367
|
|
|
|
|
|
|
{ |
368
|
23728
|
|
|
23728
|
0
|
28157
|
get_config_var('longsize') >= 8 |
369
|
|
|
|
|
|
|
} |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
sub is_64bit_time |
372
|
|
|
|
|
|
|
{ |
373
|
23728
|
50
|
|
23728
|
0
|
511487
|
is_64bit_os && ($^O =~ /^(freebsd|gnukfreebsd|netbsd|midnightbsd|linux|darwin|solaris)$/) # no OpenBSD for sure |
374
|
|
|
|
|
|
|
# not sure about cygwin, solaris |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
our $_is_y2038_supported = undef; |
379
|
|
|
|
|
|
|
sub is_y2038_supported |
380
|
|
|
|
|
|
|
{ |
381
|
26255
|
100
|
|
26255
|
0
|
94382
|
return $_is_y2038_supported if defined $_is_y2038_supported; |
382
|
7
|
|
|
0
|
|
55
|
local $SIG{__WARN__} = sub {}; |
383
|
7
|
|
100
|
|
|
12
|
$_is_y2038_supported = eval { |
384
|
|
|
|
|
|
|
(timegm(0, 0, 0, 01, 01, 2038) == 2148595200) && |
385
|
|
|
|
|
|
|
(timegm(0, 0, 0, 01, 01, 4000) == 64063267200) && |
386
|
|
|
|
|
|
|
(join(",",gmtime(64063267200)) eq "0,0,0,1,1,2100,2,31,0") && |
387
|
|
|
|
|
|
|
(join(",",gmtime(2148595200)) eq "0,0,0,1,1,138,1,31,0") |
388
|
|
|
|
|
|
|
} || 0; |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
1; |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
__END__ |