| 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__ |