X-Git-Url: https://git.p6c8.net/devedit.git/blobdiff_plain/9ba648e57a6e37366c685326c9997c3e643ce1ef..0e02f8710bfef36c2e235caa4872d562f8b2b255:/modules/Command.pm diff --git a/modules/Command.pm b/modules/Command.pm index 6b413d0..0b39533 100644 --- a/modules/Command.pm +++ b/modules/Command.pm @@ -5,8 +5,8 @@ package Command; # # Execute Dev-Editor's commands # -# Author: Patrick Canterino -# Last modified: 2003-12-21 +# Author: Patrick Canterino +# Last modified: 2004-12-28 # use strict; @@ -17,26 +17,32 @@ use File::Access; use File::Copy; use File::Path; -use HTML::Entities; -use Output; use POSIX qw(strftime); use Tool; -my $script = $ENV{'SCRIPT_NAME'}; - -my %dispatch = ('show' => \&exec_show, - 'beginedit' => \&exec_beginedit, - 'canceledit' => \&exec_unlock, - 'endedit' => \&exec_endedit, - 'mkdir' => \&exec_mkdir, - 'mkfile' => \&exec_mkfile, - 'workwithfile' => \&exec_workwithfile, - 'workwithdir' => \&exec_workwithdir, - 'copy' => \&exec_copy, - 'rename' => \&exec_rename, - 'remove' => \&exec_remove, - 'rmdir' => \&exec_rmdir, - 'unlock' => \&exec_unlock +use CGI qw(header + escape); + +use HTML::Entities; +use Output; +use Template; + +my $script = encode_entities($ENV{'SCRIPT_NAME'}); +my $users = eval("getpwuid(0)") && eval("getgrgid(0)"); + +my %dispatch = ('show' => \&exec_show, + 'beginedit' => \&exec_beginedit, + 'canceledit' => \&exec_canceledit, + 'endedit' => \&exec_endedit, + 'mkdir' => \&exec_mkdir, + 'mkfile' => \&exec_mkfile, + 'upload' => \&exec_upload, + 'copy' => \&exec_copy, + 'rename' => \&exec_rename, + 'remove' => \&exec_remove, + 'chprop' => \&exec_chprop, + 'unlock' => \&exec_unlock, + 'about' => \&exec_about ); ### Export ### @@ -59,10 +65,16 @@ sub exec_command($$$) { my ($command,$data,$config) = @_; - return error("Unknown command: $command") unless($dispatch{$command}); + foreach(keys(%dispatch)) + { + if(lc($_) eq lc($command)) + { + my $output = &{$dispatch{$_}}($data,$config); + return $output; + } + } - my $output = &{$dispatch{$command}}($data,$config); - return $output; + return error($config->{'errors'}->{'cmd_unknown'},'/',{COMMAND => encode_entities($command)}); } # exec_show() @@ -79,183 +91,159 @@ sub exec_show($$) my ($data,$config) = @_; my $physical = $data->{'physical'}; my $virtual = $data->{'virtual'}; - my $output; + my $upper_path = encode_entities(upper_path($virtual)); + my $uselist = $data->{'uselist'}; + + my $tpl = new Template; if(-d $physical) { # Create directory listing + return error($config->{'errors'}->{'no_dir_access'},$upper_path) unless(-r $physical && -x $physical); + my $direntries = dir_read($physical); - return error("Reading of directory $virtual failed.",upper_path($virtual)) unless($direntries); + return error($config->{'dir_read_fail'},$upper_path,{DIR => encode_entities($virtual)}) unless($direntries); my $files = $direntries->{'files'}; my $dirs = $direntries->{'dirs'}; - $output .= htmlhead("Directory listing of $virtual"); - $output .= equal_url($config->{'httproot'},$virtual); - $output .= "
\n\n
\n";
+  my $dir_writeable = -w $physical;
+
+  my $dirlist = "";
+
+  my $filter1 = $data->{'cgi'}->param('filter') || '*';        # The real wildcard
+  my $filter2 = ($filter1 && $filter1 ne '*') ? $filter1 : ''; # Wildcard for output
 
   # Create the link to the upper directory
   # (only if we are not in the root directory)
 
   unless($virtual eq "/")
   {
-   my $upper = $physical."/..";
-   my @stat  = stat($upper);
-
-   $output .= "  [SUBDIR]  ";
-   $output .= strftime("%d.%m.%Y %H:%M",localtime($stat[9]));
-   $output .= " " x 10;
-   $output .= "../\n";
-  }
+   my @stat  = stat($physical."/..");
 
-  # Get the length of the longest file/directory name
+   my $udtpl = new Template;
+   $udtpl->read_file($config->{'templates'}->{'dirlist_up'});
 
-  my $max_name_len = 0;
+   $udtpl->fillin("UPPER_DIR",$upper_path);
+   $udtpl->fillin("DATE",encode_entities(strftime($config->{'timeformat'},localtime($stat[9]))));
 
-  foreach(@$dirs,@$files)
-  {
-   my $length    = length($_);
-   $max_name_len = $length if($length > $max_name_len);
+   $dirlist .= $udtpl->get_template;
   }
 
   # Directories
 
   foreach my $dir(@$dirs)
   {
-   my @stat      = stat($physical."/".$dir);
+   next unless(dos_wildcard_match($filter1,$dir));
+
+   my $phys_path = $physical."/".$dir;
    my $virt_path = encode_entities($virtual.$dir."/");
 
-   $output .= "  ";
-   $output .= "[SUBDIR]  ";
-   $output .= strftime($config->{'timeformat'},localtime($stat[9]));
-   $output .= " " x 10;
-   $output .= "".encode_entities($dir)."/";
-   $output .= " " x ($max_name_len - length($dir) - 1)."\t  (";
-   $output .= "Work with directory)\n";
+   my @stat      = stat($phys_path);
+
+   my $dtpl = new Template;
+   $dtpl->read_file($config->{'templates'}->{'dirlist_dir'});
+
+   $dtpl->fillin("DIR",$virt_path);
+   $dtpl->fillin("DIR_NAME",encode_entities($dir));
+   $dtpl->fillin("DATE",encode_entities(strftime($config->{'timeformat'},localtime($stat[9]))));
+   $dtpl->fillin("URL",equal_url(encode_entities($config->{'httproot'}),$virt_path));
+
+   $dtpl->parse_if_block("readable",-r $phys_path && -x $phys_path);
+   $dtpl->parse_if_block("users",$users && -o $phys_path);
+
+   $dirlist .= $dtpl->get_template;
   }
 
   # Files
 
   foreach my $file(@$files)
   {
+   next unless(dos_wildcard_match($filter1,$file));
+
    my $phys_path = $physical."/".$file;
    my $virt_path = encode_entities($virtual.$file);
 
    my @stat      = stat($phys_path);
-   my $in_use    = $data->{'uselist'}->in_use($virtual.$file);
-
-   $output .= " " x (10 - length($stat[7]));
-   $output .= $stat[7];
-   $output .= "  ";
-   $output .= strftime($config->{'timeformat'},localtime($stat[9]));
-   $output .= " " x 10;
-   $output .= encode_entities($file);
-   $output .= " " x ($max_name_len - length($file))."\t  (";
+   my $in_use    = $uselist->in_use($virtual.$file);
+   my $too_large = $config->{'max_file_size'} && $stat[7] > $config->{'max_file_size'};
 
-   # Link "View"
+   my $ftpl = new Template;
+   $ftpl->read_file($config->{'templates'}->{'dirlist_file'});
 
-   if(-r $phys_path && -T $phys_path)
-   {
-    $output .= "View";
-   }
-   else
-   {
-    $output .= 'fillin("FILE_NAME",encode_entities($file));
+   $ftpl->fillin("SIZE",$stat[7]);
+   $ftpl->fillin("DATE",encode_entities(strftime($config->{'timeformat'},localtime($stat[9]))));
+   $ftpl->fillin("URL",equal_url(encode_entities($config->{'httproot'}),$virt_path));
 
-    $output .= (not -r $phys_path) ? "Not readable" :
-               (-B     $phys_path) ? "Binary file"  : "";
+   $ftpl->parse_if_block("not_readable",not -r $phys_path);
+   $ftpl->parse_if_block("binary",-B $phys_path);
+   $ftpl->parse_if_block("readonly",not -w $phys_path);
 
-    $output .= '">View';
-   }
+   $ftpl->parse_if_block("viewable",-r $phys_path && -T $phys_path && not $too_large);
+   $ftpl->parse_if_block("editable",(-r $phys_path && -w $phys_path && -T $phys_path && not $too_large) && not $in_use);
 
-   $output .= " | ";
+   $ftpl->parse_if_block("in_use",$in_use);
+   $ftpl->parse_if_block("unused",not $in_use);
 
-   # Link "Edit"
+   $ftpl->parse_if_block("too_large",$config->{'max_file_size'} && $stat[7] > $config->{'max_file_size'});
 
-   if(-w $phys_path && -r $phys_path && -T $phys_path && not $in_use)
-   {
-    $output .= "Edit";
-   }
-   else
-   {
-    $output .= 'get_template;
+  }
 
-    $output .= '">Edit';
-   }
+  $tpl->read_file($config->{'templates'}->{'dirlist'});
 
-   # Link "Do other stuff"
+  $tpl->fillin("DIRLIST",$dirlist);
+  $tpl->fillin("DIR",encode_entities($virtual));
+  $tpl->fillin("SCRIPT",$script);
+  $tpl->fillin("URL",encode_entities(equal_url($config->{'httproot'},$virtual)));
 
-   $output .= " | Work with file)\n";
-  }
+  $tpl->fillin("FILTER",encode_entities($filter2));
+  $tpl->fillin("FILTER_URL",escape($filter2));
 
-  $output .= "
\n\n
\n\n"; - - # Bottom of directory listing - # (Fields for creating files and directories) - - $output .= < - -
- - -Create new directory: -$virtual -
- - -Create new file: -
- - -$virtual -
- - - -
-END - $output .= htmlfoot; + $tpl->parse_if_block("dir_writeable",$dir_writeable); + $tpl->parse_if_block("filter",$filter2); } else { # View a file - return error("You have not enough permissions to view this file.",upper_path($virtual)) unless(-r $physical); + return error($config->{'errors'}->{'no_view'},$upper_path) unless(-r $physical); # Check on binary files - # We have to do it in this way, or empty files - # will be recognized as binary files + # We have to do it in this way or empty files will be recognized + # as binary files - unless(-T $physical) - { - # Binary file + return error($config->{'errors'}->{'binary'},$upper_path) unless(-T $physical); - return error("This editor is not able to view/edit binary files.",upper_path($virtual)); - } - else - { - # Text file + # Is the file too large? - $output = htmlhead("Contents of file ".encode_entities($virtual)); - $output .= equal_url($config->{'httproot'},$virtual); - $output .= dir_link($virtual); + return error($config->{'errors'}->{'file_too_large'},$upper_path,{SIZE => $config->{'max_file_size'}}) if($config->{'max_file_size'} && -s $physical > $config->{'max_file_size'}); - $output .= '
'."\n"; - $output .= '
'."\n";
-   $output .= encode_entities(${file_read($physical)});
-   $output .= "\n
\n
"; + # View the file - $output .= htmlfoot; - } + my $content = file_read($physical); + $$content =~ s/\015\012|\012|\015/\n/g; + + $tpl->read_file($config->{'templates'}->{'viewfile'}); + + $tpl->fillin("FILE",encode_entities($virtual)); + $tpl->fillin("DIR",$upper_path); + $tpl->fillin("URL",encode_entities(equal_url($config->{'httproot'},$virtual))); + $tpl->fillin("SCRIPT",$script); + + $tpl->parse_if_block("editable",-w $physical && $uselist->unused($virtual)); + + $tpl->fillin("CONTENT",encode_entities($$content)); } + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; + return \$output; } @@ -273,70 +261,62 @@ sub exec_beginedit($$) my ($data,$config) = @_; my $physical = $data->{'physical'}; my $virtual = $data->{'virtual'}; + my $dir = upper_path($virtual); my $uselist = $data->{'uselist'}; - return error("You cannot edit directories.",upper_path($virtual)) if(-d $physical); - return error_in_use($virtual) if($uselist->in_use($virtual)); - return error("You have not enough permissions to edit this file.",upper_path($virtual)) unless(-r $physical && -w $physical); + return error($config->{'errors'}->{'editdir'},$dir) if(-d $physical); + return error($config->{'errors'}->{'in_use'}, $dir,{FILE => $virtual}) if($uselist->in_use($virtual)); + return error($config->{'errors'}->{'no_edit'},$dir) unless(-r $physical && -w $physical); # Check on binary files - unless(-T $physical) - { - # Binary file + return error($config->{'errors'}->{'binary'},$dir) unless(-T $physical); - return error("This editor is not able to view/edit binary files.",upper_path($virtual)); - } - else - { - # Text file + # Is the file too large? - $uselist->add_file($virtual); - $uselist->save; + return error($config->{'errors'}->{'file_too_large'},$dir,{SIZE => $config->{'max_file_size'}}) if($config->{'max_file_size'} && -s $physical > $config->{'max_file_size'}); - my $dir = upper_path($virtual); - my $content = encode_entities(${file_read($physical)}); + # Lock the file... - my $equal_url = equal_url($config->{'httproot'},$virtual); + $uselist->add_file($virtual); + $uselist->save; - $virtual = encode_entities($virtual); + # ... and show the editing form - my $output = htmlhead("Edit file $virtual"); - $output .= $equal_url; - $output .= <Caution! This file is locked for other users while you are editing it. To unlock it, click Save and exit or Exit WITHOUT saving. Please don't click the Reload button in your browser! This will confuse the editor.

+ my $content = file_read($physical); + $$content =~ s/\015\012|\012|\015/\n/g; -
- - -

-
+ my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'editfile'}); -
- - + $tpl->fillin("FILE",$virtual); + $tpl->fillin("DIR",$dir); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); + $tpl->fillin("CONTENT",encode_entities($$content)); - - - - - - - - - -
- - Save as new file: $dir Encode ISO-8859-1 special chars
+ my $output = header(-type => "text/html"); + $output .= $tpl->get_template; - -
-END + return \$output; +} + +# exec_canceledit() +# +# Abort file editing +# +# Params: 1. Reference to user input hash +# 2. Reference to config hash +# +# Return: Output of the command (Scalar Reference) - $output .= htmlfoot; +sub exec_canceledit($$) +{ + my ($data,$config) = @_; + my $virtual = $data->{'virtual'}; - return \$output; - } + file_unlock($data->{'uselist'},$virtual); + return devedit_reload({command => 'show', file => upper_path($virtual)}); } # exec_endedit() @@ -353,10 +333,16 @@ sub exec_endedit($$) my ($data,$config) = @_; my $physical = $data->{'physical'}; my $virtual = $data->{'virtual'}; + my $dir = upper_path($virtual); my $content = $data->{'cgi'}->param('filecontent'); + my $uselist = $data->{'uselist'}; - return error("You cannot edit directories.") if(-d $physical); - return error("You have not enough permissions to edit this file.",upper_path($virtual)) unless(-r $physical && -w $physical); + # We already unlock the file at the beginning of the subroutine, + # because if we have to abort this routine, the file keeps locked. + # No other user of Dev-Editor will access the file during this + # routine because of the concept of File::UseList. + + file_unlock($uselist,$virtual); # Normalize newlines @@ -369,23 +355,31 @@ sub exec_endedit($$) $content = encode_entities($content,"\200-\377"); } - if($data->{'cgi'}->param('saveas')) + if($data->{'cgi'}->param('saveas') && $data->{'new_physical'} ne '' && $data->{'new_virtual'} ne '') { # Create the new filename $physical = $data->{'new_physical'}; $virtual = $data->{'new_virtual'}; + + # Check if someone else is editing the new file + + return error($config->{'errors'}->{'in_use'},$dir,{FILE => $virtual}) if($uselist->in_use($virtual)); } + return error($config->{'errors'}->{'editdir'},$dir) if(-d $physical); + return error($config->{'errors'}->{'no_edit'},$dir) if(-e $physical && !(-r $physical && -w $physical)); + return error($config->{'errors'}->{'text_to_binary'},$dir) unless(-T $physical); + if(file_save($physical,\$content)) { - # Saving of the file was successful - so unlock it! + # Saving of the file was successful! - return exec_unlock($data,$config); + return devedit_reload({command => 'show', file => $dir}); } else { - return error("Saving of file '".encode_entities($virtual)."' failed'. The file could be damaged, please check it's integrity.",upper_path($virtual)); + return error($config->{'errors'}->{'edit_failed'},$dir,{FILE => $virtual}); } } @@ -406,10 +400,26 @@ sub exec_mkfile($$) my $dir = upper_path($new_virtual); $new_virtual = encode_entities($new_virtual); - return error("A file or directory called '$new_virtual' already exists.",$dir) if(-e $new_physical); + if($new_physical) + { + return error($config->{'errors'}->{'file_exists'},$dir,{FILE => $new_virtual}) if(-e $new_physical); + + file_create($new_physical) or return error($config->{'errors'}->{'mkfile_failed'},$dir,{FILE => $new_virtual}); + return devedit_reload({command => 'show', file => $dir}); + } + else + { + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'mkfile'}); - file_create($new_physical) or return error("Could not create file '$new_virtual'.",$dir); - return devedit_reload({command => 'show', file => $dir}); + $tpl->fillin("DIR","/"); + $tpl->fillin("SCRIPT",$script); + + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; + + return \$output; + } } # exec_mkdir() @@ -429,401 +439,535 @@ sub exec_mkdir($$) my $dir = upper_path($new_virtual); $new_virtual = encode_entities($new_virtual); - return error("A file or directory called '$new_virtual' already exists.",$dir) if(-e $new_physical); + return error($config->{'errors'}->{'file_exists'},$dir,{FILE => $new_virtual}) if(-e $new_physical); - mkdir($new_physical,0777) or return error("Could not create directory '$new_virtual'.",$dir); - return devedit_reload({command => 'show', file => $dir}); + if($new_physical) + { + mkdir($new_physical,0777) or return error($config->{'errors'}->{'mkdir_failed'},$dir,{DIR => $new_virtual}); + return devedit_reload({command => 'show', file => $dir}); + } + else + { + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'mkdir'}); + + $tpl->fillin("DIR","/"); + $tpl->fillin("SCRIPT",$script); + + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; + + return \$output; + } } -# exec_workwithfile() +# exec_upload() # -# Display a form for renaming/copying/removing/unlocking a file +# Upload a file # # Params: 1. Reference to user input hash # 2. Reference to config hash # # Return: Output of the command (Scalar Reference) -sub exec_workwithfile($$) +sub exec_upload($$) { my ($data,$config) = @_; my $physical = $data->{'physical'}; my $virtual = $data->{'virtual'}; - my $unused = $data->{'uselist'}->unused($virtual); + my $cgi = $data->{'cgi'}; + + return error($config->{'errors'}->{'no_directory'},upper_path($virtual),{FILE => $virtual}) unless(-d $physical); + return error($config->{'errors'}->{'dir_no_create'},$virtual,{DIR => $virtual}) unless(-w $physical); - my $dir = encode_entities(upper_path($virtual)); + if(my $uploaded_file = $cgi->param('uploaded_file')) + { + # Process file upload - my $output = htmlhead("Work with file ".encode_entities($virtual)); - $output .= equal_url($config->{'httproot'},$virtual); + my $filename = file_name($uploaded_file); + my $file_phys = $physical."/".$filename; + my $file_virt = $virtual.$filename; - $virtual = encode_entities($virtual); + return error($config->{'errors'}->{'in_use'},$virtual,{FILE => $file_virt}) if($data->{'uselist'}->in_use($file_virt)); - $output .= dir_link($virtual); - $output .= "

Note: On UNIX systems, filenames are case-sensitive!

\n\n"; + if(-e $file_phys) + { + return error($config->{'errors'}->{'dir_replace'},$virtual) if(-d $file_phys); + return error($config->{'errors'}->{'exist_no_write'},$virtual,{FILE => $file_virt}) unless(-w $file_phys); + return error($config->{'errors'}->{'file_exists'},$virtual,{FILE => $file_virt}) unless($cgi->param('overwrite')); + } - $output .= "

Someone else is currently editing this file. So not all features are available.

\n\n" unless($unused); + my $ascii = $cgi->param('ascii'); + my $handle = $cgi->upload('uploaded_file'); - $output .= "
\n\n"; + # Read transferred file and write it to disk - # Copying of the file is always allowed - but we need read access + read($handle, my $data, -s $handle); + $data =~ s/\015\012|\012|\015/\n/g if($ascii); # Replace line separators if transferring in ASCII mode + file_save($file_phys,\$data,not $ascii) or return error($config->{'errors'}->{'mkfile_failed'},$virtual,{FILE => $file_virt}); - if(-r $physical) + return devedit_reload({command => "show", file => $virtual}); + } + else { - $output .= <Copy + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'upload'}); -
- - -

Copy file '$virtual' to:
$dir

-
+ $tpl->fillin("DIR",$virtual); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); -
+ my $output = header(-type => "text/html"); + $output .= $tpl->get_template; -END + return \$output; } +} - if($unused) +# exec_copy() +# +# Copy a file and return to directory view +# +# Params: 1. Reference to user input hash +# 2. Reference to config hash +# +# Return: Output of the command (Scalar Reference) + +sub exec_copy($$) +{ + my ($data,$config) = @_; + my $physical = $data->{'physical'}; + my $virtual = encode_entities($data->{'virtual'}); + my $dir = upper_path($virtual); + my $new_physical = $data->{'new_physical'}; + + return error($config->{'errors'}->{'dircopy'},$dir) if(-d $physical); + return error($config->{'errors'}->{'no_copy'},$dir) unless(-r $physical); + + if($new_physical) { - # File is not locked - # Allow renaming and deleting the file + my $new_virtual = $data->{'new_virtual'}; + my $new_dir = upper_path($new_virtual); + $new_virtual = encode_entities($new_virtual); + + if(-e $new_physical) + { + return error($config->{'errors'}->{'exist_edited'},$new_dir,{FILE => $new_virtual}) if($data->{'uselist'}->in_use($data->{'new_virtual'})); + return error($config->{'errors'}->{'dir_replace'},$new_dir) if(-d $new_physical); + return error($config->{'errors'}->{'exist_no_write'},$new_dir,{FILE => $new_virtual}) unless(-w $new_physical); - $output .= <Move/rename + if(not $data->{'cgi'}->param('confirmed')) + { + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'confirm_replace'}); -
- - -

Move/Rename file '$virtual' to:
$dir

-
+ $tpl->fillin("FILE",$virtual); + $tpl->fillin("NEW_FILE",$new_virtual); + $tpl->fillin("NEW_FILENAME",file_name($new_virtual)); + $tpl->fillin("NEW_DIR",$new_dir); + $tpl->fillin("DIR",$dir); -
+ $tpl->fillin("COMMAND","copy"); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); -

Remove

+ my $output = header(-type => "text/html"); + $output .= $tpl->get_template; -

Click on the button below to remove the file '$virtual'.

+ return \$output; + } + } -
- - -

-
-END + copy($physical,$new_physical) or return error($config->{'errors'}->{'copy_failed'},$dir,{FILE => $virtual, NEW_FILE => $new_virtual}); + return devedit_reload({command => 'show', file => $new_dir}); } else { - # File is locked - # Just display a button for unlocking it + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'copyfile'}); - $output .= <Unlock file + $tpl->fillin("FILE",$virtual); + $tpl->fillin("DIR",$dir); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); -

Someone else is currently editing this file. At least, the file is marked so. Maybe, someone who was editing the file has forgotten to unlock it. In this case (and only in this case) you can unlock the file using this button:

+ my $output = header(-type => "text/html"); + $output .= $tpl->get_template; -
- - -

-
-END + return \$output; } - - $output .= "\n
"; - $output .= htmlfoot; - - return \$output; } -# exec_workwithdir() +# exec_rename() # -# Display a form for renaming/removing a directory +# Rename/move a file and return to directory view # # Params: 1. Reference to user input hash # 2. Reference to config hash # # Return: Output of the command (Scalar Reference) -sub exec_workwithdir($$) +sub exec_rename($$) { my ($data,$config) = @_; my $physical = $data->{'physical'}; my $virtual = $data->{'virtual'}; + my $dir = upper_path($virtual); + my $new_physical = $data->{'new_physical'}; - my $dir = encode_entities(upper_path($virtual)); + return error($config->{'errors'}->{'rename_root'},"/") if($virtual eq "/"); + return error($config->{'errors'}->{'no_rename'},$dir) unless(-w upper_path($physical)); + return error($config->{'errors'}->{'in_use'},$dir,{FILE => $virtual}) if($data->{'uselist'}->in_use($virtual)); - my $output = htmlhead("Work with directory ".encode_entities($virtual)); - $output .= equal_url($config->{'httproot'},$virtual); + if($new_physical) + { + my $new_virtual = $data->{'new_virtual'}; + my $new_dir = upper_path($new_virtual); + $new_virtual = encode_entities($new_virtual); - $virtual = encode_entities($virtual); + if(-e $new_physical) + { + return error($config->{'errors'}->{'exist_edited'},$new_dir,{FILE => $new_virtual}) if($data->{'uselist'}->in_use($data->{'new_virtual'})); + return error($config->{'errors'}->{'dir_replace'},$new_dir) if(-d $new_physical); + return error($config->{'errors'}->{'exist_no_write'},$new_dir,{FILE => $new_virtual}) unless(-w $new_physical); - $output .= dir_link($virtual); - $output .= "

Note: On UNIX systems, filenames are case-sensitive!

\n\n"; - $output .= "
\n\n"; + if(not $data->{'cgi'}->param('confirmed')) + { + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'confirm_replace'}); - $output .= <Move/rename + $tpl->fillin("FILE",$virtual); + $tpl->fillin("NEW_FILE",$new_virtual); + $tpl->fillin("NEW_FILENAME",file_name($new_virtual)); + $tpl->fillin("NEW_DIR",$new_dir); + $tpl->fillin("DIR",$dir); -
- - -

Move/Rename directory '$virtual' to:
$dir

-
+ $tpl->fillin("COMMAND","rename"); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); -
+ my $output = header(-type => "text/html"); + $output .= $tpl->get_template; -

Remove

+ return \$output; + } + } -

Click on the button below to completely remove the directory '$virtual' and oll of it's files and sub directories.

+ rename($physical,$new_physical) or return error($config->{'errors'}->{'rename_failed'},$dir,{FILE => $virtual, NEW_FILE => $new_virtual}); + return devedit_reload({command => 'show', file => $new_dir}); + } + else + { + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'renamefile'}); -
- - -

-
-END + $tpl->fillin("FILE",$virtual); + $tpl->fillin("DIR",$dir); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); - $output .= "\n
"; - $output .= htmlfoot; + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; - return \$output; + return \$output; + } } -# exec_copy() +# exec_remove() # -# Copy a file and return to directory view +# Remove a file or a directory and return to directory view # # Params: 1. Reference to user input hash # 2. Reference to config hash # # Return: Output of the command (Scalar Reference) -sub exec_copy($$) +sub exec_remove($$) { my ($data,$config) = @_; my $physical = $data->{'physical'}; - my $virtual = encode_entities($data->{'virtual'}); - my $new_physical = $data->{'new_physical'}; - my $new_virtual = $data->{'new_virtual'}; - my $dir = upper_path($new_virtual); - $new_virtual = encode_entities($new_virtual); + my $virtual = $data->{'virtual'}; + my $dir = upper_path($virtual); - return error("This editor is not able to copy directories.") if(-d $physical); - return error("You have not enough permissions to copy this file.") unless(-r $physical); + return error($config->{'errors'}->{'remove_root'},"/") if($virtual eq "/"); + return error($config->{'errors'}->{'no_delete'},$dir) unless(-w upper_path($physical)); - if(-e $new_physical) + if(-d $physical) { - if(-d $new_physical) + # Remove a directory + + if($data->{'cgi'}->param('confirmed')) { - return error("A directory called '$new_virtual' already exists. You cannot replace a directory by a file!",$dir); + rmtree($physical); + return devedit_reload({command => 'show', file => $dir}); } - elsif(not $data->{'cgi'}->param('confirmed')) + else { - $dir = encode_entities($dir); + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'confirm_rmdir'}); + + $tpl->fillin("DIR",$virtual); + $tpl->fillin("UPPER_DIR",$dir); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); - my $output = htmlhead("Replace existing file"); - $output .= <<"END"; -

A file called '$new_virtual' already exists. Do you want to replace it?

+ my $output = header(-type => "text/html"); + $output .= $tpl->get_template; -
- - - - + return \$output; + } + } + else + { + # Remove a file -

-
+ return error($config->{'errors'}->{'in_use'},$dir,{FILE => $virtual}) if($data->{'uselist'}->in_use($virtual)); -
- - + if($data->{'cgi'}->param('confirmed')) + { + unlink($physical) or return error($config->{'errors'}->{'delete_failed'},$dir,{FILE => $virtual}); + return devedit_reload({command => 'show', file => $dir}); + } + else + { + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'confirm_rmfile'}); -

-
-END + $tpl->fillin("FILE",$virtual); + $tpl->fillin("DIR",$dir); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); - $output .= htmlfoot; + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; return \$output; } } - - if($data->{'uselist'}->in_use($data->{'new_virtual'})) - { - return error("The target file '$new_virtual' already exists and it is edited by someone else.",$dir); - } - - copy($physical,$new_physical) or return error("Could not copy '$virtual' to '$new_virtual'",upper_path($virtual)); - return devedit_reload({command => 'show', file => $dir}); } -# exec_rename() +# exec_chprop() # -# Rename/move a file and return to directory view +# Change the mode and the group of a file or a directory # # Params: 1. Reference to user input hash # 2. Reference to config hash # # Return: Output of the command (Scalar Reference) -sub exec_rename($$) +sub exec_chprop($$) { my ($data,$config) = @_; my $physical = $data->{'physical'}; my $virtual = $data->{'virtual'}; - my $new_physical = $data->{'new_physical'}; - my $new_virtual = $data->{'new_virtual'}; - my $dir = upper_path($new_virtual); - $new_virtual = encode_entities($new_virtual); + my $dir = upper_path($virtual); - return error_in_use($virtual) if($data->{'uselist'}->in_use($virtual)); + return error($config->{'errors'}->{'no_users'},$dir,{FILE => $virtual}) unless($users); + return error($config->{'errors'}->{'chprop_root'},"/") if($virtual eq "/"); + return error($config->{'errors'}->{'not_owner'},$dir,{FILE => $virtual}) unless(-o $physical); + return error($config->{'errors'}->{'in_use'},$dir,{FILE => $virtual}) if($data->{'uselist'}->in_use($virtual)); - if(-e $new_physical) + my $cgi = $data->{'cgi'}; + my $mode = $cgi->param('mode'); + my $group = $cgi->param('group'); + + if($mode || $group) { - if(-d $new_physical) + if($mode) { - return error("A directory called '$new_virtual' already exists. You cannot replace a directory!",upper_path($virtual)); + # Change the mode + + chmod(oct($mode),$physical); } - elsif(not $data->{'cgi'}->param('confirmed')) + + if($group) { - $dir = encode_entities($dir); + # Change the group using the `chgrp` system command - my $output = htmlhead("Replace existing file"); - $output .= <<"END"; -

A file called '$new_virtual' already exists. Do you want to replace it?

+ return error($config->{'errors'}->{'invalid_group'},$dir,{GROUP => encode_entities($group)}) unless($group =~ /^[a-z0-9_]+[a-z0-9_-]*$/i); + system("chgrp",$group,$physical); + } -
- - - - + return devedit_reload({command => 'show', file => $dir}); + } + else + { + # Display the form -

-
+ my @stat = stat($physical); + my $mode = $stat[2]; + my $gid = $stat[5]; -
- - + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'chprop'}); -

-
-END + # Insert file properties into the template - $output .= htmlfoot; + $tpl->fillin("MODE_OCTAL",substr(sprintf("%04o",$mode),-4)); + $tpl->fillin("MODE_STRING",mode_string($mode)); + $tpl->fillin("GID",$gid); - return \$output; + if(my $group = getgrgid($gid)) + { + $tpl->fillin("GROUP",encode_entities($group)); + $tpl->parse_if_block("group_detected",1); + } + else + { + $tpl->parse_if_block("group_detected",0); } - } - if($data->{'uselist'}->in_use($data->{'new_virtual'})) - { - return error("The target file '$new_virtual' already exists and it is edited by someone else.",$dir); - } + # Insert other information + + $tpl->fillin("FILE",$virtual); + $tpl->fillin("DIR",$dir); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); - rename($physical,$new_physical) or return error("Could not move/rename '".encode_entities($virtual)."' to '$new_virtual'.",upper_path($virtual)); - return devedit_reload({command => 'show', file => $dir}); + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; + + return \$output; + } } -# exec_remove() +# exec_unlock() # -# Remove a file and return to directory view +# Remove a file from the list of used files and +# return to directory view # # Params: 1. Reference to user input hash # 2. Reference to config hash # # Return: Output of the command (Scalar Reference) -sub exec_remove($$) +sub exec_unlock($$) { my ($data,$config) = @_; - my $physical = $data->{'physical'}; my $virtual = $data->{'virtual'}; + my $uselist = $data->{'uselist'}; + my $dir = upper_path($virtual); - return exec_rmdir($data,$config) if(-d $physical); - return error_in_use($virtual) if($data->{'uselist'}->in_use($virtual)); + return devedit_reload({command => 'show', file => $dir}) if($uselist->unused($virtual)); - unlink($physical) or return error("Could not delete file '".encode_entities($virtual)."'.",upper_path($virtual)); - return devedit_reload({command => 'show', file => upper_path($virtual)}); + if($data->{'cgi'}->param('confirmed')) + { + file_unlock($uselist,$virtual); + return devedit_reload({command => 'show', file => $dir}); + } + else + { + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'confirm_unlock'}); + + $tpl->fillin("FILE",$virtual); + $tpl->fillin("DIR",$dir); + $tpl->fillin("URL",equal_url($config->{'httproot'},$virtual)); + $tpl->fillin("SCRIPT",$script); + + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; + + return \$output; + } } -# exec_rmdir() +# exec_about() # -# Remove a directory and return to directory view +# Display some information about Dev-Editor # # Params: 1. Reference to user input hash # 2. Reference to config hash # # Return: Output of the command (Scalar Reference) -sub exec_rmdir($$) +sub exec_about($$) { my ($data,$config) = @_; - my $physical = $data->{'physical'}; - my $virtual = $data->{'virtual'}; - return exec_remove($data,$config) if(not -d $physical); + my $tpl = new Template; + $tpl->read_file($config->{'templates'}->{'about'}); - if($data->{'cgi'}->param('confirmed')) - { - rmtree($physical); - return devedit_reload({command => 'show', file => upper_path($virtual)}); - } - else - { - my $dir = encode_entities(upper_path($virtual)); - my $output; + $tpl->fillin("SCRIPT",$script); - $output = htmlhead("Remove directory $virtual"); - $output .= equal_url($config->{'httproot'},$virtual); + # Dev-Editor's version number - $virtual = encode_entities($virtual); + $tpl->fillin("VERSION",$data->{'version'}); - $output .= dir_link($virtual); + # Some path information - $output .= <<"END"; -

Do you really want to remove the directory '$virtual' and all of it's files and sub directories?

+ $tpl->fillin("SCRIPT_PHYS",encode_entities($ENV{'SCRIPT_FILENAME'})); + $tpl->fillin("CONFIG_PATH",encode_entities($data->{'configfile'})); + $tpl->fillin("FILE_ROOT", encode_entities($config->{'fileroot'})); + $tpl->fillin("HTTP_ROOT", encode_entities($config->{'httproot'})); -
- - - + # Perl -

-
+ $tpl->fillin("PERL_PROG",encode_entities($^X)); + $tpl->fillin("PERL_VER", sprintf("%vd",$^V)); -
- - + # Information about the server -

-
-END + $tpl->fillin("HTTPD",encode_entities($ENV{'SERVER_SOFTWARE'})); + $tpl->fillin("OS", encode_entities($^O)); + $tpl->fillin("TIME", encode_entities(strftime($config->{'timeformat'},localtime))); - $output .= htmlfoot; + # Process information - return \$output; - } -} + $tpl->fillin("PID",$$); -# exec_unlock() -# -# Remove a file from the list of used files and -# return to directory view -# -# Params: 1. Reference to user input hash -# 2. Reference to config hash -# -# Return: Output of the command (Scalar Reference) + # Check if the functions getpwuid() and getgrgid() are available -sub exec_unlock($$) -{ - my ($data,$config) = @_; - my $virtual = $data->{'virtual'}; - my $uselist = $data->{'uselist'}; + if($users) + { + # Dev-Editor is running on a system which allows users and groups + # So we display the user and the group of our process - $uselist->remove_file($virtual); - $uselist->save; + my $uid = POSIX::getuid; + my $gid = POSIX::getgid; - return devedit_reload({command => 'show', file => upper_path($virtual)}); + $tpl->parse_if_block("users",1); + + # ID's of user and group + + $tpl->fillin("UID",$uid); + $tpl->fillin("GID",$gid); + + # Names of user and group + + if(my $user = getpwuid($uid)) + { + $tpl->fillin("USER",encode_entities($user)); + $tpl->parse_if_block("user_detected",1); + } + else + { + $tpl->parse_if_block("user_detected",0); + } + + if(my $group = getgrgid($gid)) + { + $tpl->fillin("GROUP",encode_entities($group)); + $tpl->parse_if_block("group_detected",1); + } + else + { + $tpl->parse_if_block("group_detected",0); + } + + # Process umask + + $tpl->fillin("UMASK",sprintf("%04o",umask)); + } + else + { + $tpl->parse_if_block("users",0); + } + + my $output = header(-type => "text/html"); + $output .= $tpl->get_template; + + return \$output; } # it's true, baby ;-)