Apache-FileManager
view release on metacpan or search on metacpan
FileManager.pm view on Meta::CPAN
package Apache::FileManager;
=head1 NAME
Apache::FileManager - Apache mod_perl File Manager
=head1 SYNOPSIS
# Install in mod_perl enabled apache conf file
<Location /FileManager>
SetHandler perl-script
PerlHandler Apache::FileManager
</Location>
(Then point your browser to http://www.yourwebsite.com/FileManager)
# Or call from your own mod_perl script
use Apache::FileManager;
my $obj = Apache::FileManager->new();
$obj->print();
# Or create your own custom MyFileManager subclass
package MyFileManager;
use strict;
use Apache::FileManager;
our @ISA = ('Apache::FileManager');
sub handler {
my $r = shift;
my $obj = __PACKAGE__->new();
$r->send_http_header('text/html');
print ("
<HTML>
<HEAD>
<TITLE>".$r->server->server_hostname." File Manager</TITLE>
</HEAD>
");
$obj->print();
print "</HTML>";
}
# .. overload the methods ..
=head1 DESCRIPTION
The Apache::FileManager module is a simple HTML file manager. It provides
file manipulations such as cut, copy, paste, delete, rename, extract archive,
create directory, create file, edit file, and upload files.
Apache::FileManager also has the ability to rsync the server htdocs tree to
another server. With the click of a button.
=head1 PREREQUISITES
The following (non-core) perl modules must be installed before installing
Apache::FileManager.
Apache::Request => 1.00
Apache::File => 1.01
File::NCopy => 0.32
File::Remove => 0.20
Archive::Any => 0.03
CGI::Cookie => 1.20
=head1 SPECIAL NOTES
Make sure the web server has read, write, and execute access access to the
directory you want to manage files in. Typically you are going to want to
run the following commands before you begin.
chown -R nobody /web/xyz/htdocs
chmod -R 755 /web/xyz/htdocs
The extract functionality only works with *.tar.gz and *.zip files.
=head1 RSYNC FEATURE
To use the rync functionality you must have ssh, rsync, and the File::Rsync
perl module installed on the development server. You also must have an sshd
running on the production server.
Make sure you always fully qualify your server names so you don't have
different values in your known hosts file.
For Example:
ssh my-machine - wrong
ssh my-machine.subnet.com - right
Note: If the ip address of the production_server changes you will need to
create a new known_hosts file.
To get the rsync feature to work do the following:
#1 log onto the production server
#2 become root
#3 give web server user (typically nobody) a home area
I made mine /usr/local/apache/nobody
- production_server> mkdir /usr/local/apache/nobody
- edit passwd file and set new home area for nobody
- production_server> mkdir /usr/local/apache/nobody/.ssh
#4 log onto the development server
#5 become root
#6 give web server user (typically nobody) a home area
FileManager.pm view on Meta::CPAN
}
#verify current working directory
$_ = r->param('FILEMANAGER_curr_dir');
s/\.\.//g; s/^\///; s/\/$//;
my $curr_dir = $_;
#set current directory
if (! chdir $$o{DR}."/$curr_dir") {
chdir $$o{DR};
$curr_dir = "";
}
r->param('FILEMANAGER_curr_dir' => $curr_dir);
#set default view method
$$o{'view'} = "filemanager";
return undef;
}
###############################################################################
# ----- Views --------------------------------------------------------------- #
###############################################################################
#after upload files - view
sub view_post_upload {
my $o = shift;
r->print("<SCRIPT>window.opener.document.FileManager.submit(); window.opener.focus(); window.close();</SCRIPT>");
return undef;
}
#after rsync transacation - view
sub view_post_rsync {
my $o = shift;
r->print("<CENTER><TABLE CELLPADDING=0 CELLSPACING=0 BORDER=0><TR><TD>$$o{MESSAGE}</TD></TR><TR><FORM><TD ALIGN=RIGHT><INPUT TYPE=BUTTON VALUE='close' onclick=\"window.close();\"></TD></FORM></TR></TABLE></CENTER>");
return undef;
}
sub view_filemanager {
my $o = shift;
my $message = "<I><FONT COLOR=#990000>".$$o{MESSAGE}."</FONT></I>";
my ($location, $up_a_href) = $o->html_location_toolbar();
$up_a_href = "" if !defined($up_a_href);
r->print("
<!-- Scripts -->
".$o->html_javascript."
<!-- Styles -->
".$o->html_style_sheet()."
<FORM NAME=FileManager ACTION='".r->uri."' METHOD=POST>
".$o->html_hidden_fields()."
<!-- Header -->
".$o->html_top()."
<!-- Special message -->
$message
<TABLE CELLPADDING=2 CELLSPACING=2 BORDER=0 WIDTH=100% BGCOLOR=#606060>
<TR><TD>".$o->html_cmd_toolbar()."</TD></TR>
<TR BGCOLOR=WHITE><TD>$location</TD></TR>
<TR><TD>".$o->html_file_list($up_a_href)."</TD></TR>
</TABLE>
<!-- Footer -->
".$o->html_bottom()."
</FORM>");
return undef;
}
sub view_pre_editfile {
my $o = shift;
FileManager.pm view on Meta::CPAN
###############################################################################
# ---- HTML Component Output ------------------------------------------------ #
###############################################################################
sub html_javascript {
my $o = shift;
my $cookie_name = uc(r->server->server_hostname);
$cookie_name =~ s/[^A-Z]//g;
$cookie_name .= "_FM";
#start return literal
return "
<NOSCRIPT>
<H1><FONT COLOR=#990000>please enable javascript</FONT></H1>
</NOSCRIPT>
<SCRIPT>
<!--
var cookie_name = '$cookie_name';
function select_all () {
var f = window.document.FileManager;
var ck_stat;
var ar = get_ckbox_array();
if (ar.length > 0) {
if (f.FILEMANAGER_last_select_all.value == '1') {
ck_stat = false;
f.FILEMANAGER_last_select_all.value = '0';
} else {
ck_stat = true;
f.FILEMANAGER_last_select_all.value = '1';
}
}
for (var i=0; i < ar.length; i++) {
ar[i].checked = ck_stat;
}
}
function display_help () {
var w=window.open('','help','resizable=yes,scrollbars=yes,width=650,height=650');
var d = w.document.open();
d.write(\"<HTML> <UL><B><U><FONT SIZE=+1>Help</FONT></U></B><BR><BR>\"+
\"<LI><A NAME=upload><B>How do I upload files?</B></A><BR>\"+
\"Click on the upload menu item. After the <I>Upload Files</I> window opens, click the <I>Browse</I> button. This will pop open another window showing files on your computer. Select a file you want to upload. You can not upload directories. If you wa...
\"<LI><A NAME=move><B>How do I copy or move files?</B></A><BR>\"+
\"First click the check boxes next to the file names that you would like to copy or paste. Next click the <I>copy</I> or <I>paste</I> button. Then go to the directory you would like them pasted in. Finally, click <I>paste</I>.<BR><BR>\"+
\"<LI><A NAME=move><B>Why does the file manager seem broken in certain directories or when copying or pasting certain files?</B></A><BR>\"+
\"This occurs when the file manager does not have permission to access these files. To fix the problem, contact your system administrator and ask them to grant the webserver READ, WRITE, and EXECUTE access to your files.<BR><BR>\"+
\"</UL><CENTER><FORM><INPUT TYPE=BUTTON VALUE='close' onclick='window.close();'></FORM> </CENTER> </HTML>\");
d.close();
w.focus();
}
function getexpirydate(nodays){
var UTCstring;
Today = new Date();
nomilli=Date.parse(Today);
Today.setTime(nomilli+nodays*24*60*60*1000);
UTCstring = Today.toUTCString();
return UTCstring;
}
function getcookie(cookiename) {
var cookiestring=''+document.cookie;
var index1=cookiestring.indexOf(cookiename);
if (index1==-1 || cookiename=='') return '';
var index2=cookiestring.indexOf(';',index1);
if (index2==-1) index2=cookiestring.length;
return unescape(cookiestring.substring(index1+cookiename.length+1,index2));
}
function setcookie(name,value,duration){
cookiestring=name+'='+escape(value)+';EXPIRES='+getexpirydate(duration);
document.cookie=cookiestring;
if(!getcookie(name)){ return false; }
else{ return true; }
}
function print_upload () {
var w = window.open('','FileManagerUpload','scrollbars=yes,resizable=yes,width=500,height=440');
var d = w.document.open();
d.write(\"<HTML><BODY><CENTER><H1>Upload Files</H1><FORM NAME=UploadForm ACTION='".r->uri."' METHOD=POST onsubmit='window.opener.focus();' ENCTYPE=multipart/form-data><INPUT TYPE=HIDDEN NAME=FILEMANAGER_curr_dir VALUE='".r->param('FILEMANAGER_cur...
for (var i=1; i <= 10; i++) {
d.write(\"<INPUT TYPE=FILE SIZE=40 NAME=FILEMANAGER_file\"+i+\"><BR>\");
}
d.write(\"<INPUT TYPE=BUTTON VALUE='cancel' onclick='window.close();'> <INPUT TYPE=SUBMIT NAME=FILEMANAGER_cmd VALUE=upload></CENTER></BODY></HTML>\");
d.close();
w.focus();
}
// make input check box form elements into an array ALL the time
function get_ckbox_array() {
var ar;
// no files
if (window.document.FileManager.FILEMANAGER_sel_files == null) {
ar = new Array();
}
// 1 file (no length)
else if (window.document.FileManager.FILEMANAGER_sel_files.length == null){
ar = [ window.document.FileManager.FILEMANAGER_sel_files ];
}
// more than one file
else {
ar = window.document.FileManager.FILEMANAGER_sel_files;
}
return ar;
}
// make array of check box objects that are selected
function get_sel_ckbox_array() {
var sel_ar = new Array();
var sel_files = window.document.FileManager.FILEMANAGER_sel_files;
var ar = window.get_ckbox_array();
for (var i=0; i < ar.length; i++) {
if (ar[i].checked == true) {
sel_ar.push(ar[i]);
}
}
return sel_ar;
}
// get the number checked
function get_num_checked() {
var sel_ar = get_sel_ckbox_array();
return sel_ar.length;
}
//function to edit file
function edit_file () {
var sel_ar = get_sel_ckbox_array();
//make sure there is 1 and only 1 selected file
if (sel_ar.length != 1) {
window.alert('Please select ONE file to edit by clicking on a check box with the mouse.');
}
else {
FileManager.pm view on Meta::CPAN
#Edit
"<A HREF=# onclick=\"window.edit_file(); return false;\"><FONT COLOR=WHITE><B>edit</B></FONT></A>",
#Cut
"<A HREF=# onclick=\"window.save_names('cut'); return false;\"><FONT COLOR=WHITE><B>cut</B></FONT></A>",
#Copy
"<A HREF=# onclick=\"window.save_names('copy'); return false;\"><FONT COLOR=WHITE><B>copy</B></FONT></A>",
#Paste
"<A HREF=# onclick=\"if (window.getcookie(cookie_name) != '') { var f=window.document.FileManager; f.FILEMANAGER_cmd.value='paste'; f.submit(); } else { window.alert('Please select file(s) to paste by checking the file(s) first and clicking copy or...
#Delete
"<A HREF=# onclick=\"
var f=window.document.FileManager;
if (get_num_checked() == 0) {
window.alert('Please select a file to delete by clicking on a check box with the mouse.');
}
else {
var msg = '\\n' +
' Are you sure?\\n' +
'\\n' +
'Click OK to delete selected files & directories\\n' +
' ***including*** files in those directories';
if (window.confirm(msg)) {
f.FILEMANAGER_cmd.value='delete';
f.submit();
}
}
return false;
\"><FONT COLOR=WHITE><B>delete</B></FONT></A>",
#Rename
"<A HREF=# onclick=\"var f=window.document.FileManager; if (get_num_checked() != 1) { window.alert('Please select ONE file to rename by clicking on a check box with the mouse.'); } else { var rv=window.prompt('enter new name',''); if ((rv != null)&...
#Extract
"<A HREF=# onclick=\"var f=window.document.FileManager; if (get_num_checked() == 0) { window.alert('Please select a file to extract by clicking on a check box with the mouse.'); } else { f.FILEMANAGER_cmd.value='extract'; f.submit(); } return false...
#New File
"<A HREF=# onclick=\"
var f=window.document.FileManager;
var rv = window.prompt('new file name','');
var cd = f.FILEMANAGER_curr_dir.value;
if (cd != '') {
rv = cd+'/'+rv;
}
if ((rv != null)&&(rv != '')) {
var w = window.open('".r->uri."?FILEMANAGER_cmd=editfile&FILEMANAGER_curr_dir='+escape(cd)+'&FILEMANAGER_editfile='+escape(rv), 'FileManagerEditFile', 'scrollbars,resizable');
w.focus();
} else if (rv == '') {
window.alert('can not create blank file names');
}
return false;
\"><FONT COLOR=WHITE><B>new file</B></FONT></A>",
#New Directory
"<A HREF=# onclick=\"var f=window.document.FileManager; var rv=window.prompt('new directory name',''); if ((rv != null)&&(rv != '')) { f.FILEMANAGER_arg.value=rv; f.FILEMANAGER_cmd.value='mkdir'; f.submit(); } else if (rv == '') { window.alert('can...
#Upload
"<A HREF=# onclick=\"window.print_upload(); return false;\"><FONT COLOR=WHITE><B>upload<B></FONT></A>"
);
#Rsync
my $rsync = "";
if ($$o{'RSYNC_TO'}) {
push @cmds, "<TD><A HREF=# onclick=\"if (window.confirm('Are you sure you want to synchronize with the production server?')) {var w=window.open('','RSYNC','scrollbars=yes,resizables=yes,width=400,height=500'); w.focus(); var d=w.document.open(); ...
}
return "
<!-- Actions Tool bar -->
<TABLE CELLPADDING=0 CELLSPACING=0 BORDER=0><TR ALIGN=CENTER><TD ALIGN=CENTER>".join("</TD><TD> <B><FONT COLOR=#bcbcbc SIZE=+2>|</FONT> </B></TD><TD>", @cmds)."</TD></TR></TABLE>";
}
sub html_file_list {
my $o = shift;
my $up_a_href = shift || "";
my $bgcolor = "efefef";
#get the list in this directory
my $curr_dir = "";
$curr_dir = r->param('FILEMANAGER_curr_dir')."/"
if (r->param('FILEMANAGER_curr_dir') ne "");
#if there is a value for the ".." directory, then add a row for that link
#at the *top* of the list
my $acum = "";
if ($up_a_href ne "") {
$acum = "
<TR BGCOLOR=#$bgcolor>
<TD> </TD>
<TD>$up_a_href</TD>
<TD ALIGN=CENTER>--</TD>
<TD ALIGN=CENTER>--</TD>
</TR>";
$bgcolor = "ffffff";
}
my $ct_rows = 0;
foreach my $file (sort <*>) {
my ($link,$last_modified,$size,$type);
$ct_rows++;
#if directory?
if (-d $file) {
$last_modified = "--";
$size = "<TD ALIGN=CENTER>--</TD>";
$type = "/"; # "/" designates "directory"
$link = "<A HREF=# onclick=\"var f=window.document.FileManager; f.FILEMANAGER_curr_dir.value='".&escape_html($curr_dir.$file)."'; f.submit(); return false;\"><FONT COLOR=#006699>$file$type</FONT></A>";
}
#must be a file
elsif (-f $file) {
#get file size
my $stat = stat($file);
$size = $stat->size;
FileManager.pm view on Meta::CPAN
if ($buffer_type eq "copy") {
my @files = map { $o->filename_esc($$o{DR}."/".$_) } @{ $files };
$count = copy \1, @files, ".";
} elsif ($buffer_type eq "cut") {
for (@{ $files }) {
my $file = $$o{DR}."/".$_;
if (-d $file) {
my $file = $o->filename_esc($file);
my $tmp = copy \1, $file, ".";
if ($tmp) {
remove \1, $file and $count++;
}
} elsif (-f $file) {
move($file, ".") and $count++;
}
}
}
if ($count == 0) {
$$o{MESSAGE} = "0 files and directories pasted";
} elsif ($count == 1) {
$$o{MESSAGE} = "1 file or directory pasted";
} else {
$$o{MESSAGE} = "$count files or directories pasted";
}
$$o{JS} = "window.setcookie(cookie_name,'',-1);";
return undef;
}
sub cmd_delete {
my $o = shift;
my $arg1 = shift;
my $sel_files = $o->get_selected_files();
my @files = map { $o->filename_esc($$o{DR}."/".$_) } @{ $sel_files };
my $count = remove \1, @files;
if ($count == 0) {
$$o{MESSAGE} = "0 files and directories deleted";
} elsif ($count == 1) {
$$o{MESSAGE} = "1 file or directory deleted";
} else {
$$o{MESSAGE} = "$count files or directories deleted";
}
return undef;
}
sub cmd_extract {
my $o = shift;
my $arg1 = shift;
my $sel_files = $o->get_selected_files();
foreach my $f (@{ $sel_files }) {
my $esc = $o->filename_esc($$o{DR}."/".$f);
my $archive = Archive::Any->new($esc);
$archive->extract if defined $archive;
$$o{MESSAGE} = "Files extracted.";
}
return undef;
}
sub cmd_upload {
my $o = shift;
my $arg1 = shift;
my $count = 0;
foreach my $i (1 .. 10) {
my @ar = split /\/|\\/, r->param("FILEMANAGER_file$i");
next if ($#ar == -1);
my $filename = pop @ar;
$filename =~ s/[^\w\ \d\.\-]//g;
next if ($filename eq "");
$count++;
my $up = r->upload("FILEMANAGER_file$i"); next if ! defined $up;
my $in_fh = $up->fh; next if ! defined $in_fh;
my $arg = "> ".$$o{DR}."/".r->param('FILEMANAGER_curr_dir')."/".$filename;
my $out_fh = Apache::File->new($arg);
next if ! defined $out_fh;
while (<$in_fh>) {
print $out_fh $_;
}
}
#$$o{MESSAGE} = "$count file(s) uploaded.";
$$o{'view'} = "post_upload";
return undef;
}
sub cmd_rename {
my $o = shift;
my $arg1 = shift;
my $sel_files = $o->get_selected_files();
my $file = $$o{DR}."/".$sel_files->[0];
my $bool = move($file, $arg1);
if ($bool) {
$$o{MESSAGE} = "File renamed.";
} else {
$$o{MESSAGE} = "File could not be renamed.";
}
return undef;
}
sub cmd_rsync {
my $o = shift;
my $arg1 = shift;
$$o{'SSH_PATH'} ||= r->dir_config('SSH_PATH');
#try some default paths for ssh if we can't find ssh
for (qw(/usr/bin/ssh /usr/local/bin/ssh)) {
last if $$o{'SSH_PATH'};
$$o{'SSH_PATH'} = $_ if (-f $_);
}
eval "require File::Rsync";
if ($@) {
r->log_error($@);
$$o{MESSAGE} = "Module File::Rsync not installed.";
} else {
my $obj = File::Rsync->new( {
'archive' => 1,
'compress' => 1,
'rsh' => $$o{'SSH_PATH'},
'delete' => 1,
'stats' => 1
} );
$obj->exec( { src => r->document_root,
dest => $$o{'RSYNC_TO'} } )
or warn "rsyn failed\n";
$$o{MESSAGE} = join ("<BR>", @{ $obj->out }) if ($obj->out);
$$o{MESSAGE} = join ("<BR>", @{ $obj->err }) if ($obj->err);
}
$$o{'view'} = "post_upload";
return undef;
}
sub cmd_mkdir {
my $o = shift;
my $arg1 = shift;
my $bool = mkdir $arg1;
if ($bool) {
$$o{MESSAGE} = "New directory added.";
} else {
$$o{MESSAGE} = "Could not make directory.";
}
return undef;
}
1;
( run in 0.557 second using v1.01-cache-2.11-cpan-b16cb0d3907 )