package FileMan; # Datei Manager
use base main;
use strict;
use warnings;
use POSIX qw(strftime);
use MIME::Base64 qw(encode_base64);
use IO::File;
sub data{
my $self = shift;
$self->{DATAS} = $self->splitdata(<DATA>);
$self->{BODY} = $self->{DATAS}{entries};
$self->nocache;
}
sub init{
my $self = shift;
$self->nocache;
}
sub entries{
my $self = shift;
my $chdir = shift;
chdir $chdir;
opendir(my $dir, $chdir);
my @e = readdir $dir;
my @files = grep{-f} sort @e;
my @dirs = grep{-d && -r} sort @e;
shift @dirs; shift @dirs;
my $stat = [stat $chdir];
$self->{BODY} = $self->{DATAS}{entries};
$self->{STASH}{dirs} = [];
$self->{STASH}{files} = [];
$self->{STASH}{cwd} = $chdir;
$self->{STASH}{mode} = sprintf("%o", (stat($chdir))[2] & 07777);
#"$stat->[5] $) ";
#sprintf("%o", (stat($chdir))[2] & 07777);
foreach my $d(@dirs){
push @{$self->{STASH}{dirs}},{
dirname => $d,
cwd => $chdir,
chdir => do{
my $ndir = "$chdir/$d";
$ndir =~ s/\//%2F/g;
$ndir;
},
};
}
if( $chdir ne $self->eav('basedir')){
unshift @{$self->{STASH}{dirs}},{
dirname => 'SUPERDIR',
chdir => do{
my @sd = split '/', $chdir;
pop @sd;
my $ndir = join '/', @sd;
$ndir =~ s/\//%2F/g;
$ndir;
}
};
}
my $i = 0;
foreach my $f(@files){
my $stat = [stat "$chdir/$f"];
push @{$self->{STASH}{files}},{
filename => $f,
mtime => strftime("%d.%m.%Y %X", localtime $stat->[9]),
size => $stat->[7],
type => XR::xr($self->{DATAS}{type}, $self->checktype("$chdir/$f")),
class => $i % 2 ? qq(class='preemphasis') : '',
url => $self->{URL},
index => $i,
mode => sprintf("%o", $stat->[2] & 07777),
owner => $stat->[4] == $> ? 'Ja' : 'Nein',
};
$i++;
}
$self->{STASH}{anzahldateien} = scalar @files || 0;
}
sub checktype{
my $self = shift;
my $file = shift;
my $suffix = do{
$file =~ /\.(\w+)$/;
$1 ? $1 : '';
};
return { bin_chk => 'checked', fullname => $file } unless $suffix;
if($suffix eq 'txt' || $suffix eq 'ini' || $suffix eq 'pm' || $suffix eq 'js' || $suffix eq 'css' || $suffix eq 'cgi' || $suffix eq 'html' || $suffix eq 'htm'){
return {txt_chk => 'checked', fullname => $file};
}
elsif($suffix eq 'jpg' || $suffix eq 'jpeg' || $suffix eq 'png' || $suffix eq 'gif'){
return {img_chk => 'checked', fullname => $file};
}
elsif($suffix eq 'bin'){
return {bin_chk => 'checked', fullname => $file};
}
else{
return {bin_chk => 'checked', fullname => $file};
}
}
sub browse{
my $self = shift;
$self->entries( $self->eav('basedir') );
}
sub control{
my $self = shift;
if( my $chdir = $self->param('chdir') ){
$self->entries( $chdir );
}
elsif(my $fullname = $self->param('edit')){
$self->eav('title', $fullname);
$self->{BODY} = $self->{DATAS}{editform};
$self->{NO_MENU} = 1;
my $ftype = $self->param('ftype');
$self->{STASH}{ftype} = $ftype;
#$ftype =~ s/\//_/;
$self->{STASH}{fullname} = $fullname;
$self->{STASH}{filename} = do{
$fullname =~ /.*\/(.*)$/;
$1 ? $1 : '';
};
my $stat = [stat $fullname];
$self->{STASH}{owner_read} = 'checked' if 1 & $stat->[2] >> 8;
$self->{STASH}{owner_write} = 'checked' if 1 & $stat->[2] >> 7;
$self->{STASH}{owner_execute} = 'checked' if 1 & $stat->[2] >> 6;
$self->{STASH}{group_read} = 'checked' if 1 & $stat->[2] >> 5;
$self->{STASH}{group_write} = 'checked' if 1 & $stat->[2] >> 4;
$self->{STASH}{group_execute} = 'checked' if 1 & $stat->[2] >> 3;
$self->{STASH}{other_read} = 'checked' if 1 & $stat->[2] >> 2;
$self->{STASH}{other_write} = 'checked' if 1 & $stat->[2] >> 1;
$self->{STASH}{other_execute} = 'checked' if 1 & $stat->[2] >> 0;
$self->{STASH}{backurl} = sprintf("%s?edit=%s;ftype=%s", $self->{URL}, $fullname, $ftype);
if($ftype eq 'image/jpeg'){
$self->{BODY} .= $self->{DATAS}{image_jpeg_form};
$self->{STASH}{binary} = do{
my $fh = IO::File->new;
$fh->open($fullname, O_BINARY|O_RDONLY) or die $!;
read($fh, my $binary, -s $fh);
$fh->close;
encode_base64($binary, '');
};
}
elsif($ftype eq 'text/plain'){
$self->{BODY} .= $self->{DATAS}{text_plain_form};
$self->{STASH}{content} = do{
@ARGV = $fullname;
local $/ = undef;
my $doc = <>;
$doc =~ s/</</g;
$doc;
};
}
elsif($ftype eq 'text/html'){
$self->{BODY} .= $self->{DATAS}{text_html_form};
$self->{STASH}{content} = do{
@ARGV = $fullname;
local $/ = undef;
<>;
};
}
else{
$self->{BODY} .= $self->{DATAS}{binary_form};
}
}
elsif( $self->param('download') ){
my $fullname = $self->param('fullname');
my $ftype = $self->param('ftype');
my $filename = $self->param('filename');
$self->header(
"Content-Type" => $ftype,
"Content-Disposition" => qq(Attachment; filename="$filename"),
"Content-Length" => length($self->{CONTENT}),
);
my $fh =IO::File->new;
$fh->open($fullname, O_RDONLY|O_BINARY) or die $!;
read($fh, $self->{CONTENT}, -s $fh);
$fh->close;
}
elsif($self->param('delete')){
my $filename = $self->param('fullname');
unlink($filename);
$self->{NO_MENU} = 1;
$self->{BODY} = qq(<p>Bitte Fenster schließen und darunterliegende Seite neu laden!</p>);
}
elsif($self->param('chmod')){
my @owner = $self->param('owner') ? $self->param('owner') : ();
my @group = $self->param('group') ? $self->param('group') : ();
my @other = $self->param('other') ? $self->param('other') : ();
my $owner = 0;
my $group = 0;
my $other = 0;
if(scalar @owner){ $owner += $_ for @owner }
if(scalar @group){ $group += $_ for @group }
if(scalar @other){ $other += $_ for @other }
my $fullname = $self->param('fullname');
my $chmod = sprintf("%s%s%s", $owner, $group, $other);
qx(chmod $chmod $fullname);
$self->redirect($self->param('backurl'));
}
elsif($self->param('upload')){
my $cwd = $self->param('cwd');
chdir $cwd;
return $self->errorP( descr => 'Keine Datei!' ) if ! $self->param('upfiles');
foreach my $r ( $self->param('upfiles') ){
my $fh = IO::File->new;
$fh->open($r->{filename}, O_CREAT|O_BINARY|O_RDWR ) or return $self->errorP( descr => "Keine Schreibberechtigung in '$cwd'\n");
$r->{iohandle}->seek(0,0);
read($r->{iohandle}, my $buffer, $r->{content_length});
$fh->print($buffer);
$fh->close;
}
my $redir = sprintf("%s%s", $self->{URL}, $self->param('cwd') eq $self->eav('basedir') ? '' : qq(?chdir=@{[$self->param('cwd')]}) );
$self->redirect($redir);
}
else{}
}
1;#########################################################################
__DATA__
--entries------------------------------------------------------------------
<h2>Verzeichnisse</h2>
<p><strong>CurrentWorkDir (%mode%):</strong> <code>%cwd%</code></p>
<ul style="padding:0.2em">
%loop_dirs%
<li style="display:inline;padding:0.3em"> <a href="?chdir=%chdir%">%dirname%</a> </li>
%endloop%
</ul>
<h2>%anzahldateien% Dateien</h2>
<table class="grid" id="tabtab">
<thead>
<tr style="cursor:pointer" id="tabtab_thead_tr">
<th>Dateiname</th>
<th>Type</th>
<th>Edit</th>
<th>mtime</th>
<th>Größe</th>
<th>Rechte</th>
<th>Owner</th>
</tr>
</thead>
<tbody>
%loop_files%
<tr %class%>
<td> %filename% </td>
<td> %type% </td>
<td title="%filename%"> <button type="button" onClick="editfile(this.form)">...</button> </form></td>
<td> %mtime% </td>
<td> %size% </td>
<td> %mode% </th>
<td> %owner% </td>
</tr>
%endloop%
</tbody>
</table>
<form enctype="multipart/form-data" method="POST">
<fieldset><legend><strong>Dateien hochladen:</strong></legend>
<input type="hidden" name="cwd" value="%cwd%">
<input type="file" name="upfiles" multiple>
<button name="upload" value="1" onClick="throbber(true)">Upload Now!</button>
</fieldset>
</form>
<script type="text/javascript">
function editfile(form){
window.open('%url%?'+$(form).serialize(), 'EditFile', 'width=750,height=750,left=50,top=80,scrollbars=yes');
}
$(document).ready(function(){
$("#tabtab").tablesorter();
$("#tabtab_thead_tr").css('cursor',' pointer');
});
</script>
--type---------------------------------------------------------------------
<form>
<input type="hidden" name="edit" value="%fullname%">
Text:<input type="radio" name="ftype" value="text/plain" %txt_chk% >
Html:<input type="radio" name="ftype" value="text/html" %html_chk% >
Img:<input type="radio" name="ftype" value="image/jpeg" %img_chk% >
Bin:<input type="radio" name="ftype" value="application/octet-stream" %bin_chk% >
--text_plain_form----------------------------------------------------------
<pre>%content%</pre>
--text_html_form-----------------------------------------------------------
<div>%content%</div>
--image_jpeg_form----------------------------------------------------------
<p><img src="data:image/jpeg;base64,%binary%" alt="IMG"></p>
--binary_form--------------------------------------------------------------
--editform-----------------------------------------------------------------
<form>
<fieldset style="border-style:solid"><legend><strong>Aktionen:</strong></legend>
<input type="hidden" name="backurl" value="%backurl%">
<input type="hidden" name="fullname" value='%fullname%'>
<input type="hidden" name="filename" value='%filename%'>
<input type="hidden" name="ftype" value='%ftype%'>
<button name="download" value="1">Download</button>
<button name="delete" value="1" onClick="return confirm('Datei \'%filename%\' löschen?')">Löschen</button>
<button name="chmod" value="1">Chmod</button>
</fieldset>
<table class="grid" style="width:100%">
<tr>
<th>Owner</th>
<th>Group</th>
<th>Other</th>
</tr>
<tr>
<td><input name="owner" value="4" type="checkbox" %owner_read%> Lesen</td>
<td><input name="group" value="4" type="checkbox" %group_read%> Lesen</td>
<td><input name="other" value="4" type="checkbox" %other_read%> Lesen</td>
</tr>
<tr>
<td><input name="owner" value="2" type="checkbox" %owner_write%> Schreiben</td>
<td><input name="group" value="2" type="checkbox" %group_write%> Schreiben</td>
<td><input name="other" value="2" type="checkbox" %other_write%> Schreiben</td>
</tr>
<tr>
<td><input name="owner" value="1" type="checkbox" %owner_execute%> Ausführen</td>
<td><input name="group" value="1" type="checkbox" %group_execute%> Ausführen</td>
<td><input name="other" value="1" type="checkbox" %other_execute%> Ausführen</td>
</tr>
</table>
</form>
<script>
window.onunload = function(){
window.opener.location.reload();
};
</script>