line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# -*- perl -*- |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# HTML::EP::Explorer - A Perl package for browsing filesystems and |
4
|
|
|
|
|
|
|
# executing actions on files. |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# This module is |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
# Copyright (C) 1999 Jochen Wiedmann |
10
|
|
|
|
|
|
|
# Am Eisteich 9 |
11
|
|
|
|
|
|
|
# 72555 Metzingen |
12
|
|
|
|
|
|
|
# Germany |
13
|
|
|
|
|
|
|
# |
14
|
|
|
|
|
|
|
# Email: joe@ispsoft.de |
15
|
|
|
|
|
|
|
# |
16
|
|
|
|
|
|
|
# All Rights Reserved. |
17
|
|
|
|
|
|
|
# |
18
|
|
|
|
|
|
|
# You may distribute under the terms of either the GNU General Public |
19
|
|
|
|
|
|
|
# License or the Artistic License, as specified in the Perl README file. |
20
|
|
|
|
|
|
|
# |
21
|
|
|
|
|
|
|
# $Id: Explorer.pm,v 1.2 1999/11/04 12:24:10 joe Exp $ |
22
|
|
|
|
|
|
|
# |
23
|
|
|
|
|
|
|
|
24
|
1
|
|
|
1
|
|
1404
|
use strict; |
|
1
|
|
|
|
|
14
|
|
|
1
|
|
|
|
|
82
|
|
25
|
|
|
|
|
|
|
|
26
|
1
|
|
|
1
|
|
6
|
use Cwd (); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
18
|
|
27
|
1
|
|
|
1
|
|
22
|
use File::Spec (); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
14
|
|
28
|
1
|
|
|
1
|
|
452
|
use HTML::EP (); |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
use HTML::EP::Locale (); |
30
|
|
|
|
|
|
|
use HTML::EP::Session (); |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
package HTML::EP::Explorer; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
@HTML::EP::Explorer::ISA = qw(HTML::EP::Session HTML::EP::Locale HTML::EP); |
36
|
|
|
|
|
|
|
$HTML::EP::Explorer::VERSION = '0.1006'; |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
sub init { |
39
|
|
|
|
|
|
|
my $self = shift; |
40
|
|
|
|
|
|
|
$self->HTML::EP::Session::init(@_); |
41
|
|
|
|
|
|
|
$self->HTML::EP::Locale::init(@_); |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub _ep_explorer_init { |
45
|
|
|
|
|
|
|
my $self = shift; my $attr = shift; |
46
|
|
|
|
|
|
|
return '' if $self->{_ep_explorer_init_done}; |
47
|
|
|
|
|
|
|
$self->print("_ep_explorer_init: attr = (", join(",", %$attr), ")\n") |
48
|
|
|
|
|
|
|
if $self->{'debug'}; |
49
|
|
|
|
|
|
|
$self->{_ep_explorer_init_done} = 1; |
50
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
51
|
|
|
|
|
|
|
$attr->{'class'} ||= "HTML::EP::Session::Cookie"; |
52
|
|
|
|
|
|
|
$attr->{'id'} ||= "explorer-session"; |
53
|
|
|
|
|
|
|
$attr->{'path'} ||= "/"; |
54
|
|
|
|
|
|
|
$attr->{'expires'} ||= "+10y"; |
55
|
|
|
|
|
|
|
eval { $self->_ep_session($attr) }; |
56
|
|
|
|
|
|
|
my $session = $self->{$attr->{'var'} || 'session'}; |
57
|
|
|
|
|
|
|
if ($self->{debug}) { |
58
|
|
|
|
|
|
|
require Data::Dumper; |
59
|
|
|
|
|
|
|
$self->print("Session = ", Data::Dumper::Dumper($session), "\n"); |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
if (!$attr->{'noprefs'} and |
62
|
|
|
|
|
|
|
($@ or !exists($session->{'prefs'}))) { |
63
|
|
|
|
|
|
|
# First time run, open the prefs page. |
64
|
|
|
|
|
|
|
my $prefs = $attr->{'prefs_page'} || "prefs.ep"; |
65
|
|
|
|
|
|
|
my $return_to = $attr->{'return_to'} || $self->{'env'}->{'PATH_INFO'}; |
66
|
|
|
|
|
|
|
$self->print("_ep_explorer_init: Redirecting to $prefs, returning to $return_to\n") |
67
|
|
|
|
|
|
|
if $self->{'debug'}; |
68
|
|
|
|
|
|
|
$cgi->param('return_to', $return_to); |
69
|
|
|
|
|
|
|
$self->{'_ep_output'} .= $self->_ep_include({file => $prefs}); |
70
|
|
|
|
|
|
|
$self->_ep_exit({}); |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
''; |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
sub InitialConfig { |
76
|
|
|
|
|
|
|
my $self = shift; |
77
|
|
|
|
|
|
|
{ 'actions' => [], |
78
|
|
|
|
|
|
|
'filetypes' => [ |
79
|
|
|
|
|
|
|
{ 'name' => $self->{'_ep_language'} eq 'de' ? |
80
|
|
|
|
|
|
|
'Alle Dateien (*)' : 'All Files (*)', |
81
|
|
|
|
|
|
|
'icon' => '/icons/unknown.gif', |
82
|
|
|
|
|
|
|
're' => '.*' |
83
|
|
|
|
|
|
|
}], |
84
|
|
|
|
|
|
|
'directories' => [ |
85
|
|
|
|
|
|
|
{ 'name' => 'Root-Directory (/)', |
86
|
|
|
|
|
|
|
'dir' => '/' |
87
|
|
|
|
|
|
|
}] |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub ReadArray { |
93
|
|
|
|
|
|
|
my $self = shift; my $prefix = shift; |
94
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
95
|
|
|
|
|
|
|
my %hash; |
96
|
|
|
|
|
|
|
foreach my $key ($cgi->param()) { |
97
|
|
|
|
|
|
|
next unless $key =~ /^$prefix(.*)/; |
98
|
|
|
|
|
|
|
$self->print("ReadArray: Found key $key, saving as $1 (", |
99
|
|
|
|
|
|
|
join(",", $cgi->param($key)), "\n") if $self->{'debug'}; |
100
|
|
|
|
|
|
|
$hash{$1} = [$cgi->param($key)]; |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
my @array; |
103
|
|
|
|
|
|
|
while (@{$hash{'name'}}) { |
104
|
|
|
|
|
|
|
my %h; |
105
|
|
|
|
|
|
|
while (my($var, $val) = each %hash) { |
106
|
|
|
|
|
|
|
$h{$var} = shift @$val; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
push(@array, \%h) if $h{'name'}; |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
\@array; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub ReadDirectories { |
115
|
|
|
|
|
|
|
my $dirs = shift()->ReadArray('explorer_directory_'); |
116
|
|
|
|
|
|
|
my $pwd; |
117
|
|
|
|
|
|
|
foreach my $dir (@$dirs) { |
118
|
|
|
|
|
|
|
# Don't save the name, that the user gave us. Save the physical |
119
|
|
|
|
|
|
|
# filesystem path, so that we can later compare it to paths |
120
|
|
|
|
|
|
|
# requested by other users, if "Allow access to other directories" |
121
|
|
|
|
|
|
|
# is off. |
122
|
|
|
|
|
|
|
$pwd = Cwd::cwd() unless $pwd; |
123
|
|
|
|
|
|
|
chdir($dir->{'dir'}) or die "Failed to change directory to $dir: $!"; |
124
|
|
|
|
|
|
|
$dir->{'dir'} = Cwd::cwd(); |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
chdir $pwd if $pwd; |
127
|
|
|
|
|
|
|
$dirs; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub ReadConfig { |
132
|
|
|
|
|
|
|
my $self = shift; my $config = shift; |
133
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
foreach my $var ($cgi->param()) { |
136
|
|
|
|
|
|
|
next unless $var =~ /^explorer_config_(.*)/; |
137
|
|
|
|
|
|
|
my $v = $1; |
138
|
|
|
|
|
|
|
$config->{$v} = $cgi->param($var); |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
$config->{'actions'} = $self->ReadArray('explorer_action_'); |
142
|
|
|
|
|
|
|
$config->{'status_actions'} = $self->ReadArray('explorer_status_action_'); |
143
|
|
|
|
|
|
|
$config->{'filetypes'} = $self->ReadArray('explorer_filetype_'); |
144
|
|
|
|
|
|
|
$config->{'directories'} = $self->ReadDirectories(); |
145
|
|
|
|
|
|
|
$config; |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
sub _ep_explorer_config { |
150
|
|
|
|
|
|
|
my $self = shift; my $attr = shift; |
151
|
|
|
|
|
|
|
my $debug = $self->{'debug'}; |
152
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
153
|
|
|
|
|
|
|
my $file = $attr->{'file'} || "config.pm"; |
154
|
|
|
|
|
|
|
$self->{'config'} = eval { require $file } || $self->InitialConfig(); |
155
|
|
|
|
|
|
|
if ($attr->{'maysafe'} && $cgi->param('save')) { |
156
|
|
|
|
|
|
|
$self->print("_ep_explorer_config: Saving.\n") if $debug; |
157
|
|
|
|
|
|
|
$self->{'config'} = $self->ReadConfig($self->{'config'}); |
158
|
|
|
|
|
|
|
require Data::Dumper; |
159
|
|
|
|
|
|
|
my $fh = Symbol::gensym(); |
160
|
|
|
|
|
|
|
my $dump = Data::Dumper->new([$self->{'config'}])->Indent(1)->Terse(1); |
161
|
|
|
|
|
|
|
$self->print("_ep_explorer_config: Got\n", $dump->Dump(), "\n") |
162
|
|
|
|
|
|
|
if $debug; |
163
|
|
|
|
|
|
|
(open($fh, ">$file") and (print $fh $dump->Dump()) and close($fh)) |
164
|
|
|
|
|
|
|
or die "Failed to create $file: $!"; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
$self->{'actions'} = $self->{'config'}->{'actions'}; |
167
|
|
|
|
|
|
|
$self->{'status_actions'} = $self->{'config'}->{'status_actions'}; |
168
|
|
|
|
|
|
|
$self->{'directories'} = $self->{'config'}->{'directories'}; |
169
|
|
|
|
|
|
|
$self->{'filetypes'} = $self->{'config'}->{'filetypes'}; |
170
|
|
|
|
|
|
|
$self->{'num_directories'} = @{$self->{'directories'}}; |
171
|
|
|
|
|
|
|
''; |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub ReadPrefs { |
175
|
|
|
|
|
|
|
my $self = shift; my $prefs = shift; |
176
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
177
|
|
|
|
|
|
|
foreach my $var ($cgi->param()) { |
178
|
|
|
|
|
|
|
next unless $var =~ /^explorer_prefs_(.*)/; |
179
|
|
|
|
|
|
|
my $vr = $1; |
180
|
|
|
|
|
|
|
my $val = $cgi->param($var); |
181
|
|
|
|
|
|
|
$prefs->{$vr} = $val; |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
$prefs; |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub _ep_explorer_prefs { |
187
|
|
|
|
|
|
|
my $self = shift; my $attr = shift; |
188
|
|
|
|
|
|
|
my $debug = $self->{'debug'}; |
189
|
|
|
|
|
|
|
$attr->{'noprefs'} = 1; |
190
|
|
|
|
|
|
|
$self->_ep_explorer_init($attr); |
191
|
|
|
|
|
|
|
my $session = $self->{$attr->{'var'} ||= 'session'}; |
192
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
193
|
|
|
|
|
|
|
my $return; |
194
|
|
|
|
|
|
|
if (($return = $cgi->param('save_and_return')) || |
195
|
|
|
|
|
|
|
$cgi->param('save')) { |
196
|
|
|
|
|
|
|
$self->print("_ep_explorer_prefs: Saving.\n") if $debug; |
197
|
|
|
|
|
|
|
$session->{'prefs'} = $self->ReadPrefs($session->{'prefs'}); |
198
|
|
|
|
|
|
|
if ($debug) { |
199
|
|
|
|
|
|
|
require Data::Dumper; |
200
|
|
|
|
|
|
|
$self->print("_ep_explorer_save: Got\n", |
201
|
|
|
|
|
|
|
Data::Dumper->new([$session->{'prefs'}]) |
202
|
|
|
|
|
|
|
->Indent(1)->Terse(1)->Dump(), "\n"); |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
$attr->{'locked'} = 1; |
205
|
|
|
|
|
|
|
$self->_ep_session_store($attr); |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
if ($return and (my $return_to = $cgi->param('return_to'))) { |
208
|
|
|
|
|
|
|
$self->print("Returning to $return_to\n") if $debug; |
209
|
|
|
|
|
|
|
$self->{'_ep_output'} .= |
210
|
|
|
|
|
|
|
$self->_ep_include({'file' => $return_to}); |
211
|
|
|
|
|
|
|
$self->print("Done including $return_to\n") if $debug; |
212
|
|
|
|
|
|
|
$self->_ep_exit({}); |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
''; |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
sub _ep_explorer_basedir { |
218
|
|
|
|
|
|
|
my $self = shift; my $attr = shift; |
219
|
|
|
|
|
|
|
return if $self->{'basedir'}; |
220
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
221
|
|
|
|
|
|
|
my $session = $self->{'session'}; |
222
|
|
|
|
|
|
|
my $debug = $self->{'debug'}; |
223
|
|
|
|
|
|
|
my $basedir = $cgi->param('basedir') || $session->{'basedir'} |
224
|
|
|
|
|
|
|
|| $attr->{'basedir'} || $self->{'directories'}->[0] |
225
|
|
|
|
|
|
|
|| $ENV{'DOCUMENT_ROOT'}; |
226
|
|
|
|
|
|
|
$basedir = HTML::EP::Explorer::Dir->new($basedir)->{'dir'}; |
227
|
|
|
|
|
|
|
chdir($basedir) |
228
|
|
|
|
|
|
|
or die "Failed to change directory to $basedir: $!"; |
229
|
|
|
|
|
|
|
$basedir = Cwd::cwd(); |
230
|
|
|
|
|
|
|
if (!$session->{'basedir'} or $session->{'basedir'} ne $basedir) { |
231
|
|
|
|
|
|
|
$self->{'modified'} = 1; |
232
|
|
|
|
|
|
|
$session->{'basedir'} = $basedir; |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
foreach my $dir (@{$self->{'directories'}}) { |
235
|
|
|
|
|
|
|
$self->print("Checking whether $dir->{'dir'} is $basedir.\n") |
236
|
|
|
|
|
|
|
if $debug; |
237
|
|
|
|
|
|
|
if ($dir->{'dir'} eq $basedir) { |
238
|
|
|
|
|
|
|
$self->{'in_top_dir'} = 1; |
239
|
|
|
|
|
|
|
$self->{'in_base_dir'} = $dir; |
240
|
|
|
|
|
|
|
$self->{'display_dir'} = "/"; |
241
|
|
|
|
|
|
|
$self->print("Yes, it is.\n") if $debug; |
242
|
|
|
|
|
|
|
last; |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
if (!$self->{'in_top_dir'}) { |
246
|
|
|
|
|
|
|
$self->{'in_top_dir'} = ($basedir eq File::Spec->rootdir()); |
247
|
|
|
|
|
|
|
foreach my $dir (@{$self->{'directories'}}) { |
248
|
|
|
|
|
|
|
$self->print("Checking whether $basedir is below $dir->{'dir'}.\n") |
249
|
|
|
|
|
|
|
if $debug; |
250
|
|
|
|
|
|
|
if ($basedir =~ /^\Q$dir->{'dir'}\E(\/.*)$/) { |
251
|
|
|
|
|
|
|
$self->{'in_base_dir'} = $dir; |
252
|
|
|
|
|
|
|
$self->{'display_dir'} = $1; |
253
|
|
|
|
|
|
|
$self->print("Yes, it is.\n") if $debug; |
254
|
|
|
|
|
|
|
last; |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
if (!$self->{'in_base_dir'}) { |
258
|
|
|
|
|
|
|
die "Directory $basedir is outside of the permitted area." |
259
|
|
|
|
|
|
|
if $self->{'config'}->{'dirs_restricted'}; |
260
|
|
|
|
|
|
|
$self->{'display_dir'} = $basedir; |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
$self->print("Basedir is $basedir.\n") if $debug; |
264
|
|
|
|
|
|
|
$self->{'basedir'} = $basedir; |
265
|
|
|
|
|
|
|
''; |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
sub _ep_explorer_sortby { |
269
|
|
|
|
|
|
|
my $self = shift; my $attr = shift; |
270
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
271
|
|
|
|
|
|
|
my $session = $self->{'session'}; |
272
|
|
|
|
|
|
|
my $sortby = $cgi->param('sortby') || $session->{'sortby'} || |
273
|
|
|
|
|
|
|
$attr->{'sortby'} || "name"; |
274
|
|
|
|
|
|
|
if (!$session->{'sortby'} || $session->{'sortby'} ne $sortby) { |
275
|
|
|
|
|
|
|
$self->{'modified'} = 1; |
276
|
|
|
|
|
|
|
$session->{'sortby'} = $sortby; |
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
$self->print("Sorting by $sortby.\n") if $self->{'debug'}; |
279
|
|
|
|
|
|
|
$self->{'sortby'} = $sortby; |
280
|
|
|
|
|
|
|
''; |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
sub _ep_explorer_filetype { |
284
|
|
|
|
|
|
|
my $self = shift; my $attr = shift; |
285
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
286
|
|
|
|
|
|
|
my $debug = $self->{'debug'}; |
287
|
|
|
|
|
|
|
my $session = $self->{'session'}; |
288
|
|
|
|
|
|
|
my $filetype = $cgi->param('filetype') || $session->{'filetype'} |
289
|
|
|
|
|
|
|
|| $attr->{'filetype'} || ''; |
290
|
|
|
|
|
|
|
$self->print("Looking for file type $filetype\n") if $debug; |
291
|
|
|
|
|
|
|
my $found; |
292
|
|
|
|
|
|
|
foreach my $ft (@{$self->{'filetypes'}}) { |
293
|
|
|
|
|
|
|
if ($filetype eq $ft->{'name'}) { |
294
|
|
|
|
|
|
|
$found = $ft; |
295
|
|
|
|
|
|
|
last; |
296
|
|
|
|
|
|
|
} |
297
|
|
|
|
|
|
|
} |
298
|
|
|
|
|
|
|
if ($found) { |
299
|
|
|
|
|
|
|
$self->print("Found it.\n") if $debug; |
300
|
|
|
|
|
|
|
} elsif (@{$self->{'filetypes'}}) { |
301
|
|
|
|
|
|
|
$found = $self->{'filetypes'}->[0]; |
302
|
|
|
|
|
|
|
$self->print("Choosing default file type $found->{'name'}\n") |
303
|
|
|
|
|
|
|
if $debug; |
304
|
|
|
|
|
|
|
} else { |
305
|
|
|
|
|
|
|
$self->print("No file type found.\n"); |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
$found->{'selected'} = 'SELECTED' if $found; |
309
|
|
|
|
|
|
|
my $name = $found ? $found->{'name'} : ''; |
310
|
|
|
|
|
|
|
if (!defined($session->{'filetype'}) || |
311
|
|
|
|
|
|
|
$session->{'filetype'} ne $name) { |
312
|
|
|
|
|
|
|
$self->{'modified'} = 1; |
313
|
|
|
|
|
|
|
$session->{'filetype'} = $name; |
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
$self->print("Filetype is $found->{'name'}.\n") |
316
|
|
|
|
|
|
|
if $self->{'debug'} and $found; |
317
|
|
|
|
|
|
|
$self->{'filetype'} = $found; |
318
|
|
|
|
|
|
|
''; |
319
|
|
|
|
|
|
|
} |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
sub _ep_explorer_browse { |
322
|
|
|
|
|
|
|
my $self = shift; my $attr = shift; |
323
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
324
|
|
|
|
|
|
|
my $debug = $self->{'debug'}; |
325
|
|
|
|
|
|
|
my $session = $self->{'session'}; |
326
|
|
|
|
|
|
|
$self->{'modified'} = 0; |
327
|
|
|
|
|
|
|
my $dir_template = $self->{'dir_template'} |
328
|
|
|
|
|
|
|
or die "Missing template variable: dir_template"; |
329
|
|
|
|
|
|
|
my $item = $attr->{'item'} || die "Missing item name"; |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
$self->_ep_explorer_basedir($attr); |
332
|
|
|
|
|
|
|
$self->_ep_explorer_filetype($attr); |
333
|
|
|
|
|
|
|
$self->_ep_explorer_sortby($attr); |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
my $dir = HTML::EP::Explorer::Dir->new($self->{'basedir'}); |
336
|
|
|
|
|
|
|
my $list = $dir->Read($self->{'filetype'}->{'re'}); |
337
|
|
|
|
|
|
|
my $sortby = $self->{'sortby'}; |
338
|
|
|
|
|
|
|
my $updir; |
339
|
|
|
|
|
|
|
if ($list->[0]->IsDir() |
340
|
|
|
|
|
|
|
and $list->[0]->{'name'} eq File::Spec->updir()) { |
341
|
|
|
|
|
|
|
$updir = shift @$list; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
$self->print("Sorting by $sortby.\n") if $debug; |
344
|
|
|
|
|
|
|
if ($sortby eq 'type') { |
345
|
|
|
|
|
|
|
@$list = sort { |
346
|
|
|
|
|
|
|
if ($a->IsDir()) { |
347
|
|
|
|
|
|
|
$b->IsDir() ? $a->{'name'} cmp $b->{'name'} : -1; |
348
|
|
|
|
|
|
|
} elsif ($b->IsDir()) { |
349
|
|
|
|
|
|
|
return 1; |
350
|
|
|
|
|
|
|
} else { |
351
|
|
|
|
|
|
|
my $ae = ($a =~ /\.(.*?)$/) ? $1 : ''; |
352
|
|
|
|
|
|
|
my $be = ($b =~ /\.(.*?)$/) ? $1 : ''; |
353
|
|
|
|
|
|
|
($ae cmp $be) || ($a->{'name'} cmp $b->{'name'}); |
354
|
|
|
|
|
|
|
} |
355
|
|
|
|
|
|
|
} @$list; |
356
|
|
|
|
|
|
|
} elsif ($sortby eq 'uid') { |
357
|
|
|
|
|
|
|
@$list = sort { (getpwuid($a->{'uid'}) || '') cmp |
358
|
|
|
|
|
|
|
(getpwuid($b->{'uid'}) || '')} @$list; |
359
|
|
|
|
|
|
|
} elsif ($sortby eq 'gid') { |
360
|
|
|
|
|
|
|
@$list = sort { (getgrgid($a->{'gid'}) || '') cmp |
361
|
|
|
|
|
|
|
(getgrgid($b->{'gid'}) || '')} @$list; |
362
|
|
|
|
|
|
|
} elsif ($sortby =~ /^(?:size|[amc]time)$/) { |
363
|
|
|
|
|
|
|
@$list = sort { $a->{$sortby} <=> $b->{$sortby} } @$list; |
364
|
|
|
|
|
|
|
} else { |
365
|
|
|
|
|
|
|
@$list = sort { $a->{$sortby} cmp $b->{$sortby} } @$list; |
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
unshift(@$list, $updir) |
368
|
|
|
|
|
|
|
if $updir and !$self->{'in_top_dir'}; |
369
|
|
|
|
|
|
|
my $output = ''; |
370
|
|
|
|
|
|
|
$self->{'i'} = 0; |
371
|
|
|
|
|
|
|
foreach my $i (@$list) { |
372
|
|
|
|
|
|
|
$self->{$item} = $i; |
373
|
|
|
|
|
|
|
$output .= $i->AsHtml($self, $item); |
374
|
|
|
|
|
|
|
++$self->{'i'}; |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
$self->_ep_session_store($attr) if $self->{'modified'}; |
378
|
|
|
|
|
|
|
$output; |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
sub _format_ACTIONS { |
382
|
|
|
|
|
|
|
my $self = shift; my $item = shift; |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
my $str = ''; |
385
|
|
|
|
|
|
|
foreach my $action (@{$self->{'actions'}}) { |
386
|
|
|
|
|
|
|
$self->{'action'} = $action; |
387
|
|
|
|
|
|
|
$self->{'icon'} = $action->{'icon'} ? |
388
|
|
|
|
|
|
|
qq{} : |
389
|
|
|
|
|
|
|
$action->{'name'}; |
390
|
|
|
|
|
|
|
$str .= $self->ParseVars($self->{'action_template'}); |
391
|
|
|
|
|
|
|
} |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
$str; |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
sub FindAction { |
397
|
|
|
|
|
|
|
my $self = shift; my $attr = shift; |
398
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
399
|
|
|
|
|
|
|
my $name = $cgi->param('faction') || $attr->{'faction'} || |
400
|
|
|
|
|
|
|
die "Missing action name"; |
401
|
|
|
|
|
|
|
my $debug = $self->{'debug'}; |
402
|
|
|
|
|
|
|
$self->print("FindAction: Looking for $name\n") if $debug; |
403
|
|
|
|
|
|
|
my $action; |
404
|
|
|
|
|
|
|
foreach my $a (@{$self->{'actions'}}) { |
405
|
|
|
|
|
|
|
if ($a->{'name'} eq $name) { |
406
|
|
|
|
|
|
|
$action = $a; |
407
|
|
|
|
|
|
|
last; |
408
|
|
|
|
|
|
|
} |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
$self->{'action'} = $action or die "Unknown action: $name"; |
411
|
|
|
|
|
|
|
$self->print("Selected action is $action->{'name'}\n") if $debug; |
412
|
|
|
|
|
|
|
$action; |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
sub FindStatusAction { |
416
|
|
|
|
|
|
|
my $self = shift; my $script = shift; my $attr = shift; |
417
|
|
|
|
|
|
|
my $debug = $self->{'debug'}; |
418
|
|
|
|
|
|
|
$self->print("FindStatusAction: Looking for $script\n") if $debug; |
419
|
|
|
|
|
|
|
my $action; |
420
|
|
|
|
|
|
|
foreach my $sa (@{$self->{'status_actions'}}) { |
421
|
|
|
|
|
|
|
if ($sa->{'name'} eq $script) { |
422
|
|
|
|
|
|
|
$self->print("FindStatusAction: Returning ", |
423
|
|
|
|
|
|
|
join(",", %$sa), "\n") if $debug; |
424
|
|
|
|
|
|
|
return $sa; |
425
|
|
|
|
|
|
|
} |
426
|
|
|
|
|
|
|
} |
427
|
|
|
|
|
|
|
die "FindStatusAction: Unknown script $script"; |
428
|
|
|
|
|
|
|
} |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
sub _ep_explorer_logfile { |
432
|
|
|
|
|
|
|
my $self = shift; my $attr = shift; |
433
|
|
|
|
|
|
|
my $debug = $self->{'debug'}; |
434
|
|
|
|
|
|
|
my $action = $self->FindAction({}); |
435
|
|
|
|
|
|
|
my $fh = Symbol::gensym(); |
436
|
|
|
|
|
|
|
require Fcntl; |
437
|
|
|
|
|
|
|
$self->print("Opening logfile: $action->{'logfile'}\n") if $debug; |
438
|
|
|
|
|
|
|
sysopen($fh, $action->{'logfile'}, Fcntl::O_RDONLY()) |
439
|
|
|
|
|
|
|
or die "Failed to open logfile $action->{'logfile'}: $!"; |
440
|
|
|
|
|
|
|
$self->Stop(); |
441
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
442
|
|
|
|
|
|
|
$self->print($cgi->header('-type' => 'text/plain')); |
443
|
|
|
|
|
|
|
$self->print("\n"); |
444
|
|
|
|
|
|
|
seek($fh, -2000, 2); |
445
|
|
|
|
|
|
|
$| = 1; |
446
|
|
|
|
|
|
|
my $pos; |
447
|
|
|
|
|
|
|
local $/ = undef; |
448
|
|
|
|
|
|
|
while(1) { |
449
|
|
|
|
|
|
|
$pos = tell($fh); |
450
|
|
|
|
|
|
|
if (eof($fh)) { |
451
|
|
|
|
|
|
|
sleep 15; |
452
|
|
|
|
|
|
|
seek($fh, $pos, 0); |
453
|
|
|
|
|
|
|
} else { |
454
|
|
|
|
|
|
|
my $line = <$fh>; |
455
|
|
|
|
|
|
|
if (!defined($line)) { |
456
|
|
|
|
|
|
|
$self->print("Failed to read: $!"); |
457
|
|
|
|
|
|
|
last; |
458
|
|
|
|
|
|
|
} else { |
459
|
|
|
|
|
|
|
$self->print($line); |
460
|
|
|
|
|
|
|
} |
461
|
|
|
|
|
|
|
} |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
''; |
464
|
|
|
|
|
|
|
} |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
sub _ep_explorer_queue { |
468
|
|
|
|
|
|
|
my $self = shift; my $attr = shift; |
469
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
470
|
|
|
|
|
|
|
my $debug = $self->{'debug'}; |
471
|
|
|
|
|
|
|
my $action = $self->FindAction($attr); |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
my $ignore_cache; |
474
|
|
|
|
|
|
|
if (my $script = $cgi->param('script')) { |
475
|
|
|
|
|
|
|
my $status_action = $self->FindStatusAction($script, $attr); |
476
|
|
|
|
|
|
|
my %env = %ENV; |
477
|
|
|
|
|
|
|
$env{'job'} = quotemeta($cgi->param('job')); |
478
|
|
|
|
|
|
|
$env{'user'} = quotemeta($self->User()); |
479
|
|
|
|
|
|
|
foreach my $var (split(/\n/, $action->{'vars'})) { |
480
|
|
|
|
|
|
|
if ($var =~ /^\s*(.*?)\s*=\s*(.*?)\s*$/) { |
481
|
|
|
|
|
|
|
$env{$1} = $2; |
482
|
|
|
|
|
|
|
} |
483
|
|
|
|
|
|
|
} |
484
|
|
|
|
|
|
|
local %ENV = %env; |
485
|
|
|
|
|
|
|
if ($debug) { |
486
|
|
|
|
|
|
|
my $command = $status_action->{'script'}; |
487
|
|
|
|
|
|
|
$command =~ s/\$(\w+)/$ENV{$1}/g; |
488
|
|
|
|
|
|
|
$self->print("_ep_explorer_queue: Executing command ($command)\n"); |
489
|
|
|
|
|
|
|
} |
490
|
|
|
|
|
|
|
system "$status_action->{'script'} >/dev/null"; |
491
|
|
|
|
|
|
|
$ignore_cache = 1; |
492
|
|
|
|
|
|
|
} |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
my $input; |
495
|
|
|
|
|
|
|
my $file = File::Spec->catfile("status", |
496
|
|
|
|
|
|
|
$cgi->escape($action->{'name'})); |
497
|
|
|
|
|
|
|
if (!$ignore_cache && $self->{'config'}->{'cache'}) { |
498
|
|
|
|
|
|
|
my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, |
499
|
|
|
|
|
|
|
$mtime) = stat $file; |
500
|
|
|
|
|
|
|
my $regen_time = $mtime + $self->{'config'}->{'cache'}; |
501
|
|
|
|
|
|
|
$self->print("Cache file $file ", |
502
|
|
|
|
|
|
|
-f _ ? "exists.\n" : "doesn't exist.\n", |
503
|
|
|
|
|
|
|
-f _ ? "Modification time is $mtime, current time is " . |
504
|
|
|
|
|
|
|
time() . ", regeneration time is $regen_time\n" |
505
|
|
|
|
|
|
|
: "") if $debug; |
506
|
|
|
|
|
|
|
if (-f _ && $regen_time > time()) { |
507
|
|
|
|
|
|
|
$self->print("Trying to load cache file $file.\n") if $debug; |
508
|
|
|
|
|
|
|
require Fcntl; |
509
|
|
|
|
|
|
|
my $fh = Symbol::gensym(); |
510
|
|
|
|
|
|
|
if (open($fh, "<$file") and flock($fh, Fcntl::LOCK_SH())) { |
511
|
|
|
|
|
|
|
local $/ = undef; |
512
|
|
|
|
|
|
|
$input = <$fh>; |
513
|
|
|
|
|
|
|
} |
514
|
|
|
|
|
|
|
$self->print($input ? "Got:\n$input\n" : "Not successful ($!)\n") |
515
|
|
|
|
|
|
|
if $debug; |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
} |
518
|
|
|
|
|
|
|
if (!$input) { |
519
|
|
|
|
|
|
|
my $command = $action->{'status'}; |
520
|
|
|
|
|
|
|
local $ENV{'user'} = quotemeta($self->User()); |
521
|
|
|
|
|
|
|
$input = `$command 2>&1`; |
522
|
|
|
|
|
|
|
if ($self->{'config'}->{'cache'}) { |
523
|
|
|
|
|
|
|
require Fcntl; |
524
|
|
|
|
|
|
|
my $fh = Symbol::gensym(); |
525
|
|
|
|
|
|
|
if (sysopen($fh, $file, Fcntl::O_RDWR()|Fcntl::O_CREAT()) |
526
|
|
|
|
|
|
|
and flock($fh, Fcntl::LOCK_EX())) { |
527
|
|
|
|
|
|
|
print $fh $input; |
528
|
|
|
|
|
|
|
truncate($fh, length($input)); |
529
|
|
|
|
|
|
|
} |
530
|
|
|
|
|
|
|
} |
531
|
|
|
|
|
|
|
} |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
my @status; |
534
|
|
|
|
|
|
|
foreach my $line (split(/\n/, $input)) { |
535
|
|
|
|
|
|
|
if ($line =~ /^(\S+)\s+(\S+)\s+(\d+)\s+(\S.*?)\s+(\d+)\s+bytes/) { |
536
|
|
|
|
|
|
|
push(@status, { 'rank' => $1, |
537
|
|
|
|
|
|
|
'owner' => $2, |
538
|
|
|
|
|
|
|
'job' => $3, |
539
|
|
|
|
|
|
|
'file' => $4, |
540
|
|
|
|
|
|
|
'size' => $5 }); |
541
|
|
|
|
|
|
|
} |
542
|
|
|
|
|
|
|
} |
543
|
|
|
|
|
|
|
$self->{'status'} = \@status; |
544
|
|
|
|
|
|
|
$self->{'status_num'} = @status; |
545
|
|
|
|
|
|
|
''; |
546
|
|
|
|
|
|
|
} |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
sub _ep_explorer_action { |
549
|
|
|
|
|
|
|
my $self = shift; my $attr = shift; |
550
|
|
|
|
|
|
|
my $cgi = $self->{'cgi'}; |
551
|
|
|
|
|
|
|
my $debug = $self->{'debug'}; |
552
|
|
|
|
|
|
|
my $name = $cgi->param('faction') || $attr->{'faction'} |
553
|
|
|
|
|
|
|
|| die "Missing action name"; |
554
|
|
|
|
|
|
|
my $action = $self->FindAction($attr); |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
my @files; |
557
|
|
|
|
|
|
|
my $file; |
558
|
|
|
|
|
|
|
if (($file = $cgi->param('files')) || ($file = $attr->{'files'})) { |
559
|
|
|
|
|
|
|
@files = split(" ", $file); |
560
|
|
|
|
|
|
|
} elsif (($file = $cgi->param('file')) || ($file = $attr->{'file'})) { |
561
|
|
|
|
|
|
|
@files = $file; |
562
|
|
|
|
|
|
|
} else { |
563
|
|
|
|
|
|
|
die "Missing file name"; |
564
|
|
|
|
|
|
|
} |
565
|
|
|
|
|
|
|
$self->print("Selected files are:\n", map{" $_\n"} @files) if $debug; |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
my $command = $action->{'script'}; |
568
|
|
|
|
|
|
|
my $files; |
569
|
|
|
|
|
|
|
if ($command =~ /\$files/) { |
570
|
|
|
|
|
|
|
# Can handle multiple files |
571
|
|
|
|
|
|
|
$files = join(" ", map { |
572
|
|
|
|
|
|
|
quotemeta(HTML::EP::Explorer::File->new($_)->{'file'}) |
573
|
|
|
|
|
|
|
} @files); |
574
|
|
|
|
|
|
|
$command =~ s/\$files/$files/sg; |
575
|
|
|
|
|
|
|
$command .= " 2>&1" if $attr->{'execute'}; |
576
|
|
|
|
|
|
|
} else { |
577
|
|
|
|
|
|
|
my @commands; |
578
|
|
|
|
|
|
|
foreach my $file (@files) { |
579
|
|
|
|
|
|
|
my $c = $command; |
580
|
|
|
|
|
|
|
my $f = quotemeta(HTML::EP::Explorer::File->new($file)->{'file'}); |
581
|
|
|
|
|
|
|
$c =~ s/\$file/$f/sg; |
582
|
|
|
|
|
|
|
push(@commands, $attr->{'execute'} ? "$c 2>&1" : $c); |
583
|
|
|
|
|
|
|
} |
584
|
|
|
|
|
|
|
$command = join(";", @commands); |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
$self->print("Selected command is $command\n") if $debug; |
587
|
|
|
|
|
|
|
local $ENV{'user'} = quotemeta($self->User()); |
588
|
|
|
|
|
|
|
local $ENV{'files'} = $files if $files; |
589
|
|
|
|
|
|
|
if ($attr->{'execute'}) { |
590
|
|
|
|
|
|
|
return `$command`; |
591
|
|
|
|
|
|
|
} else { |
592
|
|
|
|
|
|
|
return $command; |
593
|
|
|
|
|
|
|
} |
594
|
|
|
|
|
|
|
} |
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
sub User { |
597
|
|
|
|
|
|
|
$ENV{'REMOTE_USER'} || "anonymous"; |
598
|
|
|
|
|
|
|
} |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
sub _format_MODE { |
601
|
|
|
|
|
|
|
my $self = shift; my $mode = shift; |
602
|
|
|
|
|
|
|
(($mode & 0400) ? "r" : "-") . |
603
|
|
|
|
|
|
|
(($mode & 0200) ? "w" : "-") . |
604
|
|
|
|
|
|
|
(($mode & 04000) ? "s" : (($mode & 0100) ? "x" : "-")) . |
605
|
|
|
|
|
|
|
(($mode & 040) ? "r" : "-") . |
606
|
|
|
|
|
|
|
(($mode & 020) ? "w" : "-") . |
607
|
|
|
|
|
|
|
(($mode & 02000) ? "s" : (($mode & 010) ? "x" : "-")) . |
608
|
|
|
|
|
|
|
(($mode & 04) ? "r" : "-") . |
609
|
|
|
|
|
|
|
(($mode & 02) ? "w" : "-") . |
610
|
|
|
|
|
|
|
(($mode & 01) ? "x" : "-"); |
611
|
|
|
|
|
|
|
} |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
sub _format_UID { |
614
|
|
|
|
|
|
|
my $self = shift; my $uid = shift; |
615
|
|
|
|
|
|
|
my $u = getpwuid($uid); |
616
|
|
|
|
|
|
|
defined $u ? $u : $uid; |
617
|
|
|
|
|
|
|
} |
618
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
sub _format_GID { |
620
|
|
|
|
|
|
|
my $self = shift; my $gid = shift; |
621
|
|
|
|
|
|
|
my $g = getgrgid($gid); |
622
|
|
|
|
|
|
|
defined $g ? $g : $gid; |
623
|
|
|
|
|
|
|
} |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
sub _format_DATE { |
626
|
|
|
|
|
|
|
my $self = shift; my $time = shift; |
627
|
|
|
|
|
|
|
return '' unless $time; |
628
|
|
|
|
|
|
|
return $self->_format_TIME(scalar(localtime($time))); |
629
|
|
|
|
|
|
|
} |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
sub _format_SELECTED { |
632
|
|
|
|
|
|
|
my $self = shift; shift() ? "SELECTED" : ""; |
633
|
|
|
|
|
|
|
} |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
package HTML::EP::Explorer::File; |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
sub new { |
638
|
|
|
|
|
|
|
my $proto = shift; my $file = shift; |
639
|
|
|
|
|
|
|
$file =~ s/^file://; |
640
|
|
|
|
|
|
|
my $self = { 'file' => $file, @_ }; |
641
|
|
|
|
|
|
|
$self->{'name'} ||= File::Basename::basename($file); |
642
|
|
|
|
|
|
|
$self->{'url'} ||= "file:$file"; |
643
|
|
|
|
|
|
|
bless($self, (ref($proto) || $proto)); |
644
|
|
|
|
|
|
|
} |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
sub IsDir { 0 } |
647
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
sub AsHtml { |
649
|
|
|
|
|
|
|
my $self = shift; my $ep = shift; |
650
|
|
|
|
|
|
|
foreach my $ft (@{$ep->{'filetypes'}}) { |
651
|
|
|
|
|
|
|
if ($ft->{'icon'} && $self->{'name'} =~ /$ft->{'re'}/) { |
652
|
|
|
|
|
|
|
$self->{'icon'} = $ft->{'icon'}; |
653
|
|
|
|
|
|
|
last; |
654
|
|
|
|
|
|
|
} |
655
|
|
|
|
|
|
|
} |
656
|
|
|
|
|
|
|
$self->{'icon'} = "unknown.gif" unless $self->{'icon'}; |
657
|
|
|
|
|
|
|
$ep->ParseVars($ep->{'file_template'} |
658
|
|
|
|
|
|
|
or die "Missing template variable: file_template"); |
659
|
|
|
|
|
|
|
} |
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
package HTML::EP::Explorer::Dir; |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
sub new { |
665
|
|
|
|
|
|
|
my $proto = shift; my $dir = shift; |
666
|
|
|
|
|
|
|
$dir =~ s/^file://; |
667
|
|
|
|
|
|
|
my $self = { 'dir' => $dir, @_ }; |
668
|
|
|
|
|
|
|
$self->{'name'} ||= File::Basename::basename($dir); |
669
|
|
|
|
|
|
|
$self->{'url'} ||= "file:$dir"; |
670
|
|
|
|
|
|
|
bless($self, (ref($proto) || $proto)); |
671
|
|
|
|
|
|
|
} |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
sub IsDir { 1 } |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
sub AsHtml { |
676
|
|
|
|
|
|
|
my $self = shift; my $ep = shift; |
677
|
|
|
|
|
|
|
$ep->ParseVars($ep->{'dir_template'} |
678
|
|
|
|
|
|
|
or die "Missing template variable: dir_template"); |
679
|
|
|
|
|
|
|
} |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
sub Read { |
682
|
|
|
|
|
|
|
my $self = shift; my $re = shift; |
683
|
|
|
|
|
|
|
my $fh = Symbol::gensym(); |
684
|
|
|
|
|
|
|
my $pwd = Cwd::cwd(); |
685
|
|
|
|
|
|
|
my $curdir = File::Spec->curdir(); |
686
|
|
|
|
|
|
|
my $dir = $self->{'dir'}; |
687
|
|
|
|
|
|
|
my @list; |
688
|
|
|
|
|
|
|
chdir $dir or die "Failed to change directory to $dir: $!"; |
689
|
|
|
|
|
|
|
opendir($fh, $curdir) or die "Failed to open directory $dir: $!"; |
690
|
|
|
|
|
|
|
while (defined(my $f = readdir($fh))) { |
691
|
|
|
|
|
|
|
next if $f eq $curdir; |
692
|
|
|
|
|
|
|
my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, |
693
|
|
|
|
|
|
|
$atime, $mtime, $ctime, $blksize) = stat $f; |
694
|
|
|
|
|
|
|
if (-f _) { |
695
|
|
|
|
|
|
|
push(@list, |
696
|
|
|
|
|
|
|
HTML::EP::Explorer::File->new(File::Spec->catfile($dir, $f), |
697
|
|
|
|
|
|
|
'name' => $f, |
698
|
|
|
|
|
|
|
'mode' => $mode, |
699
|
|
|
|
|
|
|
'uid' => $uid, |
700
|
|
|
|
|
|
|
'gid' => $gid, |
701
|
|
|
|
|
|
|
'size' => $size, |
702
|
|
|
|
|
|
|
'mtime' => $mtime, |
703
|
|
|
|
|
|
|
'ctime' => $ctime, |
704
|
|
|
|
|
|
|
'atime' => $atime)) |
705
|
|
|
|
|
|
|
if !$re || $f =~ /$re/; |
706
|
|
|
|
|
|
|
} elsif (-d _) { |
707
|
|
|
|
|
|
|
push(@list, |
708
|
|
|
|
|
|
|
HTML::EP::Explorer::Dir->new(File::Spec->catdir($dir, $f), |
709
|
|
|
|
|
|
|
'name' => $f, |
710
|
|
|
|
|
|
|
'mode' => $mode, |
711
|
|
|
|
|
|
|
'uid' => $uid, |
712
|
|
|
|
|
|
|
'gid' => $gid, |
713
|
|
|
|
|
|
|
'size' => $size, |
714
|
|
|
|
|
|
|
'mtime' => $mtime, |
715
|
|
|
|
|
|
|
'ctime' => $ctime, |
716
|
|
|
|
|
|
|
'atime' => $atime)) |
717
|
|
|
|
|
|
|
} |
718
|
|
|
|
|
|
|
} |
719
|
|
|
|
|
|
|
closedir $fh; |
720
|
|
|
|
|
|
|
chdir $pwd; |
721
|
|
|
|
|
|
|
\@list; |
722
|
|
|
|
|
|
|
} |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
1; |
726
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
__END__ |