timeformat = %d.%m.%Y %H:%M
use_gmt = 0
-uselist_file = uselist
-lock_file = uselist.lock
-lock_timeout = 10
-
-error_file = errors.dat
-template_file = templates.dat
+error_file = errors.conf
+template_file = templates.conf
# End of configuration file
\ No newline at end of file
# Dev-Editor's main program
#
# Author: Patrick Canterino <patrick@patshaping.de>
-# Last modified: 2005-02-19
+# Last modified: 2005-04-09
#
use strict;
use CGI;
use Config::DevEdit;
-use File::UseList;
use Command;
use Output;
# Path to configuration file
# Change if necessary!
-use constant CONFIGFILE => 'devedit.dat';
+use constant CONFIGFILE => 'devedit.conf';
# Read the configuration file
unless(($new_physical,$new_virtual) = check_path($config->{'fileroot'},$dir))
{
- abort($config->{'errors'}->{'create_ar'},'/');
+ abort($config->{'errors'}->{'create_above_root'},'/');
}
# Check if we have enough permissions to create a file
{
if(my ($physical,$virtual) = check_path($config->{'fileroot'},$file))
{
- # Create a File::UseList object and load the list
-
- my $uselist = new File::UseList(listfile => $config->{'uselist_file'},
- lockfile => $config->{'lock_file'},
- timeout => $config->{'lock_timeout'});
-
- $uselist->lock or abort($config->{'errors'}->{'lock_failed'},undef,{USELIST => $uselist->{'listfile'}, LOCK_FILE => $uselist->{'lockfile'}});
- $uselist->load;
-
# Create a hash containing data submitted by the user
# (some other necessary information are also included)
virtual => $virtual,
new_physical => $new_physical,
new_virtual => $new_virtual,
- uselist => $uselist,
cgi => $cgi,
version => $VERSION,
configfile => CONFIGFILE);
my $output = exec_command($command,\%data,$config);
- # ... unlock the list with files in use and show the output of the command
+ # ... and show the output of the command
- $uselist->unlock or abort($config->{'errors'}->{'unlock_failed'},undef,{USELIST => $uselist->{'listfile'}, LOCK_FILE => $uselist->{'lockfile'}});
print $$output;
}
else
}
else
{
- abort($config->{'errors'}->{'not_exist'},'/');
+ abort($config->{'errors'}->{'not_found'},'/');
}
#
--- /dev/null
+# This file contains the error messages of Dev-Editor
+
+above_root = Accessing files and directories above the virtual root directory is forbidden.
+binary_file = This editor is not able to view/edit binary files.
+chprop_link = You are not allowed to change the properties of a symbolic link.
+chprop_root = You are not allowed to change the properties of the root directory.
+command_unknown = Unknown command: '{COMMAND}'
+copy_failed = Could not copy '{FILE}' to '{NEW_FILE}'.
+create_above_root = You are not allowed to create files and directories above the virtual root directory.
+delete_failed = Could not delete file '{FILE}'.
+dir_copy = This editor is not able to copy directories.
+dir_edit = You cannot edit directories.
+dir_no_create = You have not enough permissions to create a file in directory '{DIR}'.
+dir_not_exist = The directory where you want to create this file or directory does not exist.
+dir_read_fail = Reading of directory '{DIR}' failed.
+dir_replace = You are not allowed to replace a directory.
+edit_failed = Saving of file '{FILE}' failed. The file could be damaged, please check its integrity.
+edit_file_changed = The file you want to edit changed meanwhile. Now, it looks like this: <a href="{SCRIPT}?command=show&file={FILE}">{FILE}</a>. Please try to merge these two versions together of the file or save this file using a different name.
+exist_no_write = The target file '{FILE}' already exists and you have not enough permissions to replace it.
+file_exists = A file or directory called '{FILE}' already exists.
+file_too_large = The file you want to view or edit is too large (max. {SIZE} Bytes).
+invalid_group = '{GROUP}' seems to be an invalid group name. Please check it and try again.
+invalid_upload = It seems that something is wrong with the file upload you want to submit.
+link_copy = Copying symbolic links does not work.
+link_edit = For security reasons, you cannot edit the target file of a symbolic link.
+link_replace = You are not allowed to overwrite symbolic links.
+mkdir_failed = Could not create directory '{DIR}'.
+mkfile_failed = Could not create file '{FILE}'.
+no_copy = You have not enough permissions to copy this file.
+no_delete = You have not enough permissions to delete this file.
+no_dir_access = You have not enough permissions to access this directory.
+no_directory = '{FILE}' is not a directory.
+no_edit = You have not enough permissions to edit this file.
+no_rename = You have not enough permissions to move/rename this file.
+no_root_access = You have not enough permissions to access the root directory.
+no_root_dir = The root directory does not exist or is not a directory.
+no_users = It seems that your system does not support users and groups.
+no_view = You have not enough permissions to view this file.
+not_found = File/directory does not exist.
+not_owner = You are not the owner of '{FILE}', so you are not allowed to change its mode and its group.
+remove_root = You are not allowed to remove the root directory.
+rename_failed = Could not move/rename '{FILE}' to '{NEW_FILE}'.
+rename_root = You are not allowed to move/rename the root directory.
+text_to_binary = You are not allowed to write text data into a binary file.
+
+# End of configuration file
\ No newline at end of file
+++ /dev/null
-# This file contains the error messages of Dev-Editor
-
-above_root = Accessing files and directories above the virtual root directory is forbidden.
-binary = This editor is not able to view/edit binary files.
-chprop_link = You are not allowed to change the properties of a symbolic link.
-chprop_root = You are not allowed to change the properties of the root directory.
-cmd_unknown = Unknown command: '{COMMAND}'
-copy_failed = Could not copy '{FILE}' to '{NEW_FILE}'.
-create_ar = You are not allowed to create files and directories above the virtual root directory.
-delete_failed = Could not delete file '{FILE}'.
-dir_copy = This editor is not able to copy directories.
-dir_edit = You cannot edit directories.
-dir_no_create = You have not enough permissions to create a file in directory '{DIR}'.
-dir_not_exist = The directory where you want to create this file or directory does not exist.
-dir_read_fail = Reading of directory '{DIR}' failed.
-dir_replace = You are not allowed to replace a directory.
-edit_failed = Saving of file '{FILE}' failed. The file could be damaged, please check its integrity.
-exist_edited = The target file '{FILE}' already exists and is edited by someone else.
-exist_no_write = The target file '{FILE}' already exists and you have not enough permissions to replace it.
-file_exists = A file or directory called '{FILE}' already exists.
-file_too_large = The file you want to view or edit is too large (max. {SIZE} Bytes).
-in_use = The file '{FILE}' is currently edited by someone else.
-invalid_group = '{GROUP}' seems to be an invalid group name. Please check it and try again.
-invalid_upload = It seems that something is wrong with the file upload you want to submit.
-link_copy = Copying symbolic links does not work.
-link_edit = For security reasons, you cannot edit the target file of a symbolic link.
-link_replace = You are not allowed to overwrite symbolic links.
-lock_failed = Locking of '{USELIST}' failed. Try it again in a moment. If the problem persists, ask the administrator to check the lock file ('{LOCK_FILE}') and to recreate it if necessary.
-mkdir_failed = Could not create directory '{DIR}'.
-mkfile_failed = Could not create file '{FILE}'.
-no_copy = You have not enough permissions to copy this file.
-no_delete = You have not enough permissions to delete this file.
-no_dir_access = You have not enough permissions to access this directory.
-no_directory = '{FILE}' is not a directory.
-no_edit = You have not enough permissions to edit this file.
-no_rename = You have not enough permissions to move/rename this file.
-no_root_access = You have not enough permissions to access the root directory.
-no_root_dir = The root directory does not exist or is not a directory.
-no_users = It seems that your system does not support users and groups.
-no_view = You have not enough permissions to view this file.
-not_exist = File/directory does not exist.
-not_owner = You are not the owner of '{FILE}', so you are not allowed to change its mode and its group.
-remove_root = You are not allowed to remove the root directory.
-rename_failed = Could not move/rename '{FILE}' to '{NEW_FILE}'.
-rename_root = You are not allowed to move/rename the root directory.
-text_to_binary = You are not allowed to write text data into a binary file.
-ul_add_failed = Could not add '{FILE}' to the list of files in use.
-ul_rm_failed = Could not remove '{FILE}' from the list of files in use. Try it again using the 'unlock' command of Dev-Editor or by removing the file manually from '{USELIST}'.
-unlock_failed = Unlocking of '{USELIST}' failed. Ask the administrator to check the lock file ('{LOCK_FILE}') and to recreate it if necessary.
-
-# End of configuration file
\ No newline at end of file
# Execute Dev-Editor's commands
#
# Author: Patrick Canterino <patrick@patshaping.de>
-# Last modified: 2005-03-18
+# Last modified: 2005-04-09
#
use strict;
use vars qw(@EXPORT);
+use Fcntl;
use File::Access;
use File::Copy;
use File::Path;
+use Digest::MD5 qw(md5_hex);
use POSIX qw(strftime);
use Tool;
use Output;
use Template;
+use Data::Dumper;
+
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,
'rename' => \&exec_rename,
'remove' => \&exec_remove,
'chprop' => \&exec_chprop,
- 'unlock' => \&exec_unlock,
'about' => \&exec_about
);
}
}
- return error($config->{'errors'}->{'cmd_unknown'},'/',{COMMAND => encode_entities($command)});
+ return error($config->{'errors'}->{'command_unknown'},'/',{COMMAND => encode_entities($command)});
}
# exec_show()
my $physical = $data->{'physical'};
my $virtual = $data->{'virtual'};
my $upper_path = encode_entities(upper_path($virtual));
- my $uselist = $data->{'uselist'};
my $tpl = new Template;
my $virt_path = encode_entities($virtual.$file);
my @stat = lstat($phys_path);
- my $in_use = $uselist->in_use($virtual.$file);
my $too_large = $config->{'max_file_size'} && $stat[7] > $config->{'max_file_size'};
my $ftpl = new Template;
$ftpl->parse_if_block('link',-l $phys_path);
$ftpl->parse_if_block('no_link',not -l $phys_path);
$ftpl->parse_if_block('not_readable',not -r $phys_path);
- $ftpl->parse_if_block('binary',-B $phys_path);
+ $ftpl->parse_if_block('binary_file',-B $phys_path);
$ftpl->parse_if_block('readonly',not -w $phys_path);
$ftpl->parse_if_block('viewable',(-r $phys_path && -T $phys_path && not $too_large) || -l $phys_path);
- $ftpl->parse_if_block('editable',((-r $phys_path && -w $phys_path && -T $phys_path && not $too_large) && not $in_use) && not -l $phys_path);
-
- $ftpl->parse_if_block('in_use',$in_use);
- $ftpl->parse_if_block('unused',not $in_use);
+ $ftpl->parse_if_block('editable',(-r $phys_path && -w $phys_path && -T $phys_path && not $too_large) && not -l $phys_path);
$ftpl->parse_if_block('too_large',$config->{'max_file_size'} && $stat[7] > $config->{'max_file_size'});
# We have to do it in this way or empty files will be recognized
# as binary files
- return error($config->{'errors'}->{'binary'},$upper_path) unless(-T $physical);
+ return error($config->{'errors'}->{'binary_file'},$upper_path) unless(-T $physical);
# Is the file too large?
$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->parse_if_block('editable',-w $physical);
$tpl->fillin('CONTENT',encode_entities($$content));
}
my $physical = $data->{'physical'};
my $virtual = $data->{'virtual'};
my $dir = upper_path($virtual);
- my $uselist = $data->{'uselist'};
+ my $cgi = $data->{'cgi'};
- return error($config->{'errors'}->{'link_edit'},$dir) if(-l $physical);
- return error($config->{'errors'}->{'dir_edit'}, $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);
+ return error($config->{'errors'}->{'link_edit'},$dir) if(-l $physical);
+ return error($config->{'errors'}->{'dir_edit'}, $dir) if(-d $physical);
+ return error($config->{'errors'}->{'no_edit'}, $dir) unless(-r $physical && -w $physical);
# Check on binary files
- return error($config->{'errors'}->{'binary'},$dir) unless(-T $physical);
+ return error($config->{'errors'}->{'binary_file'},$dir) unless(-T $physical);
# Is the file too large?
return error($config->{'errors'}->{'file_too_large'},$dir,{SIZE => $config->{'max_file_size'}}) if($config->{'max_file_size'} && -s $physical > $config->{'max_file_size'});
- # Lock the file...
-
- ($uselist->add_file($virtual) and
- $uselist->save) or return error($config->{'errors'}->{'ul_add_failed'},$dir,{FILE => $virtual});
-
# ... and show the editing form
- my $content = file_read($physical);
+ my $content = file_read($physical,1);
+ my $md5sum = md5_hex($$content);
$$content =~ s/\015\012|\012|\015/\n/g;
my $tpl = new Template;
$tpl->fillin('DIR',$dir);
$tpl->fillin('URL',equal_url($config->{'httproot'},$virtual));
$tpl->fillin('SCRIPT',$script);
+ $tpl->fillin('MD5SUM',$md5sum);
$tpl->fillin('CONTENT',encode_entities($$content));
+ $tpl->parse_if_block('error',0);
+
my $output = header(-type => 'text/html');
$output .= $tpl->get_template;
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)
-
-sub exec_canceledit($$)
-{
- my ($data,$config) = @_;
- my $virtual = $data->{'virtual'};
- my $dir = upper_path($virtual);
- my $uselist = $data->{'uselist'};
-
- file_unlock($uselist,$virtual) or return error($config->{'errors'}->{'ul_rm_failed'},$dir,{FILE => $virtual, USELIST => $uselist->{'listfile'}});
- return devedit_reload({command => 'show', file => $dir});
-}
-
# exec_endedit()
#
# Save a file, unlock it and return to directory view
my $physical = $data->{'physical'};
my $virtual = $data->{'virtual'};
my $dir = upper_path($virtual);
- my $content = $data->{'cgi'}->param('filecontent');
- my $uselist = $data->{'uselist'};
+ my $cgi = $data->{'cgi'};
+ my $content = $cgi->param('filecontent');
+ my $md5sum = $cgi->param('md5sum');
+ my $output;
+
+ if($content && $md5sum)
+ {
+ # Normalize newlines
- # 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.
+ $content =~ s/\015\012|\012|\015/\n/g;
- file_unlock($uselist,$virtual) or return error($config->{'errors'}->{'ul_rm_failed'},$dir,{FILE => $virtual, USELIST => $uselist->{'listfile'}});
+ if($cgi->param('saveas') && $data->{'new_physical'} ne '' && $data->{'new_virtual'} ne '')
+ {
+ # Create the new filename
- # Normalize newlines
+ $physical = $data->{'new_physical'};
+ $virtual = $data->{'new_virtual'};
+ }
- $content =~ s/\015\012|\012|\015/\n/g;
+ return error($config->{'errors'}->{'link_edit'},$dir) if(-l $physical);
+ return error($config->{'errors'}->{'dir_edit'},$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) if(-e $physical && not -T $physical);
- if($data->{'cgi'}->param('encode_iso'))
- {
- # Encode all ISO-8859-1 special chars
+ # For technical reasons, we can't use file_save() for
+ # saving the file...
- $content = encode_entities($content,"\200-\377");
- }
+ local *FILE;
- if($data->{'cgi'}->param('saveas') && $data->{'new_physical'} ne '' && $data->{'new_virtual'} ne '')
- {
- # Create the new filename
+ sysopen(FILE,$physical,O_RDWR | O_CREAT) or return error($config->{'errors'}->{'edit_failed'},$dir,{FILE => $virtual});
+ file_lock(FILE,LOCK_EX) or do { close(FILE); return error($config->{'errors'}->{'edit_failed'},$dir,{FILE => $virtual}) };
+ binmode(FILE);
- $physical = $data->{'new_physical'};
- $virtual = $data->{'new_virtual'};
+ my $md5 = new Digest::MD5;
+ $md5->addfile(*FILE);
- # Check if someone else is editing the new file
+ my $md5_new = $md5->hexdigest;
- return error($config->{'errors'}->{'in_use'},$dir,{FILE => $virtual}) if($uselist->in_use($virtual));
- }
+ if($md5_new ne $md5sum && not $cgi->param('saveas'))
+ {
+ # The file changed meanwhile
- return error($config->{'errors'}->{'link_edit'},$dir) if(-l $physical);
- return error($config->{'errors'}->{'dir_edit'},$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) if(-e $physical && not -T $physical);
+ my $tpl = new Template;
+ $tpl->read_file($config->{'templates'}->{'editfile'});
- if(file_save($physical,\$content))
- {
- # The file was successfully saved!
+ $tpl->fillin('ERROR',$config->{'errors'}->{'edit_file_changed'});
- return devedit_reload({command => 'show', file => $dir});
- }
- else
- {
- return error($config->{'errors'}->{'edit_failed'},$dir,{FILE => $virtual});
+ $tpl->fillin('FILE',$virtual);
+ $tpl->fillin('DIR',$dir);
+ $tpl->fillin('URL',equal_url($config->{'httproot'},$virtual));
+ $tpl->fillin('SCRIPT',$script);
+ $tpl->fillin('MD5SUM',$md5_new);
+ $tpl->fillin('CONTENT',encode_entities($content));
+
+ $tpl->parse_if_block('error',1);
+
+ my $data = header(-type => 'text/html');
+ $data .= $tpl->get_template;
+
+ $output = \$data;
+ }
+ else
+ {
+ # The file was saved successfully!
+
+ seek(FILE,0,0);
+ truncate(FILE,0);
+
+ print FILE $content;
+
+ $output = devedit_reload({command => 'show', file => $dir});
+
+ #return error($config->{'errors'}->{'edit_failed'},$dir,{FILE => $virtual});
+ }
+
+ close(FILE);
+
+ return $output;
}
+
+ return devedit_reload({command => 'beginedit', file => $virtual});
}
# exec_mkfile()
my $file_phys = $physical.'/'.$filename;
my $file_virt = $virtual.$filename;
- return error($config->{'errors'}->{'in_use'},$virtual,{FILE => $file_virt}) if($data->{'uselist'}->in_use($file_virt));
-
if(-e $file_phys)
{
return error($config->{'errors'}->{'link_replace'},$virtual) if(-l $file_phys);
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'}->{'link_replace'},$new_dir) if(-l $new_physical);
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);
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));
if($new_physical)
{
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 && not -l $new_physical);
return error($config->{'errors'}->{'exist_no_write'},$new_dir,{FILE => $new_virtual}) unless(-w $new_physical);
{
# 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 error($config->{'errors'}->{'chprop_root'},'/') if($virtual eq '/');
return error($config->{'errors'}->{'not_owner'},$dir,{FILE => $virtual}) unless(-o $physical);
return error($config->{'errors'}->{'chprop_link'},$dir) if(-l $physical);
- return error($config->{'errors'}->{'in_use'},$dir,{FILE => $virtual}) if($data->{'uselist'}->in_use($virtual));
my $cgi = $data->{'cgi'};
my $mode = $cgi->param('mode');
}
}
-# 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)
-
-sub exec_unlock($$)
-{
- my ($data,$config) = @_;
- my $virtual = $data->{'virtual'};
- my $uselist = $data->{'uselist'};
- my $dir = upper_path($virtual);
-
- return devedit_reload({command => 'show', file => $dir}) if($uselist->unused($virtual));
-
- if($data->{'cgi'}->param('confirmed'))
- {
- file_unlock($uselist,$virtual) or return error($config->{'errors'}->{'ul_rm_failed'},$dir,{FILE => $virtual, USELIST => $uselist->{'listfile'}});
- 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_about()
#
# Display some information about Dev-Editor
# using only one command
#
# Author: Patrick Canterino <patrick@patshaping.de>
-# Last modified: 2005-02-16
+# Last modified: 2005-04-09
#
use strict;
file_lock
file_read
file_save
- file_unlock
LOCK_SH
LOCK_EX
return 1;
}
-# file_unlock()
-#
-# Remove a file from the list of files in use
-#
-# Params: 1. File::UseList object
-# 2. File to remove
-#
-# Return: Status code (Boolean)
-
-sub file_unlock($$)
-{
- my ($uselist,$file) = @_;
-
- $uselist->remove_file($file) or return;
- $uselist->save or return;
-
- return 1;
-}
-
# it's true, baby ;-)
1;
+++ /dev/null
-package File::UseList;
-
-#
-# File::UseList 1.3
-#
-# Run a list with files that are currently in use
-# (bases on Filing::UseList by Roland Bluethgen <calocybe@web.de>)
-#
-# Author: Patrick Canterino <patrick@patshaping.de>
-# Last modified: 2004-12-03
-#
-
-use strict;
-
-use Carp qw(croak);
-use Fcntl;
-
-# new()
-#
-# Constructor
-#
-# Params: Hash: listfile => File with list of files in use
-# lockfile => Lock file (Default: List file + .lock)
-# timeout => Lock timeout in seconds (Default: 10)
-#
-# Return: File::UseList object (Blessed Reference)
-
-sub new(%)
-{
- my ($class,%args) = @_;
-
- # Check if we got all the necessary information
-
- croak "Missing path to list file" unless($args{'listfile'});
- $args{'lockfile'} = $args{'listfile'}.".lock" unless($args{'lockfile'}); # Default filename of lock file
- $args{'timeout'} = 10 unless($args{'timeout'}); # Default timeout
-
- # Add some other information
-
- $args{'files'} = [];
- $args{'locked'} = 0;
-
- return bless(\%args,$class);
-}
-
-# lock()
-#
-# Lock list with files
-# (delete lock file)
-#
-# Params: -nothing-
-#
-# Return: Status code (Boolean)
-
-sub lock
-{
- my $self = shift;
- my $lockfile = $self->{'lockfile'};
- my $timeout = $self->{'timeout'};
-
- return 1 if($self->{'locked'});
-
- # Try to delete the lock file one time per second
- # until the timeout is reached
-
- for(my $x=$timeout;$x>=0;$x--)
- {
- if(unlink($lockfile))
- {
- $self->{'locked'} = 1;
- return 1;
- }
-
- sleep(1);
- }
-
- # Timeout
-
- return;
-}
-
-# unlock()
-#
-# Unlock list with files, but only if _we_ locked it
-# (create lock file)
-#
-# Params: -nothing-
-#
-# Return: Status code (Boolean)
-
-sub unlock
-{
- my $self = shift;
- my $lockfile = $self->{'lockfile'};
- local *LOCKFILE;
-
- if($self->{'locked'})
- {
- sysopen(LOCKFILE,$lockfile,O_WRONLY | O_CREAT | O_TRUNC) or return;
- close(LOCKFILE) or return;
-
- $self->{'locked'} = 0;
- return 1;
- }
-
- # The list wasn't lock by us or it isn't locked at all
-
- return;
-}
-
-# load()
-#
-# Load the list with files from the list file
-#
-# Params: -nothing-
-#
-# Return: Status code (Boolean)
-
-sub load
-{
- my $self = shift;
- my $file = $self->{'listfile'};
- local *FILE;
-
- # Read out the file and split the content line-per-line
-
- sysopen(FILE,$file,O_RDONLY) or return;
- read(FILE, my $content, -s $file);
- close(FILE) or return;
-
- my @files = split(/\015\012|\012|\015/,$content);
-
- # Remove useless lines
-
- for(my $x=0;$x<@files;$x++)
- {
- if($files[$x] eq "" || $files[$x] =~ /^\s+$/)
- {
- splice(@files,$x,1);
- $x--; # <-- very important!
- }
- }
-
- $self->{'files'} = \@files;
- return 1;
-}
-
-# save()
-#
-# Write the list with files back to the list file
-#
-# Params: -nothing-
-#
-# Return: Status code (Boolean)
-
-sub save
-{
- my $self = shift;
- my $file = $self->{'listfile'};
- my $temp = $file.".temp";
- my $files = $self->{'files'};
- local *FILE;
-
- my $data = (@$files) ? join("\n",@$files) : '';
-
- sysopen(FILE,$temp,O_WRONLY | O_CREAT | O_TRUNC) or return;
- print FILE $data or do { close(FILE); return };
- close(FILE) or return;
-
- rename($temp,$file) or return;
-
- return 1;
-}
-
-# add_file()
-#
-# Add a file to the list
-#
-# Params: File
-#
-# Return: Status code (Boolean)
-
-sub add_file($)
-{
- my ($self,$file) = @_;
- my $files = $self->{'files'};
-
- # Check if the file is already in the list
-
- return if($self->in_use($file));
-
- push(@$files,$file);
- return 1;
-}
-
-# remove_file()
-#
-# Remove a file from the list
-#
-# Params: File
-#
-# Return: Status code (Boolean)
-
-sub remove_file($)
-{
- my ($self,$file) = @_;
- my $files = $self->{'files'};
-
- # Check if the file is really in the list
-
- return if($self->unused($file));
-
- # Remove the file from the list
-
- for(my $x=0;$x<@$files;$x++)
- {
- if($files->[$x] eq $file)
- {
- splice(@$files,$x,1);
- return 1;
- }
- }
-}
-
-# remove_all()
-#
-# Remove all files from the list
-#
-# Params: -nothing-
-#
-# Return: -nothing-
-
-sub remove_all
-{
- my $self = shift;
-
- $self->{'files'} = [];
-
- return;
-}
-
-# in_use()
-#
-# Check if a file is in the list
-#
-# Params: File to check
-#
-# Return: Status code (Boolean)
-
-sub in_use($)
-{
- my ($self,$file) = @_;
- my $files = $self->{'files'};
-
- foreach(@$files)
- {
- return 1 if($_ eq $file);
- }
-
- return;
-}
-
-# unused()
-#
-# Check if a file is not in the list
-#
-# Params: File to check
-#
-# Return: Status code (Boolean)
-
-sub unused($)
-{
- return not shift->in_use(shift);
-}
-
-# it's true, baby ;-)
-
-1;
-
-#
-### End ###
\ No newline at end of file
<td align="right" style="white-space:nowrap">{SIZE}</td>
<td style="padding-left:15pt;white-space:nowrap;">{DATE}{IF gmt} (GMT){ENDIF}</td>
<td style="padding-left:15pt;white-space:nowrap;">{FILE_NAME}</td>
-<td style="padding-left:15pt;white-space:nowrap;">({IF viewable}<a href="{SCRIPT}?command=show&file={FILE}">View</a>{ELSE}<span style="color:#C0C0C0" title="{IF not_readable}Not readable{ELSE}{IF binary}Binary file{ELSE}{IF too_large}File too large{ENDIF}{ENDIF}{ENDIF}">View</span>{ENDIF} | {IF editable}<a href="{SCRIPT}?command=beginedit&file={FILE}">Edit</a>{ELSE}<span style="color:#C0C0C0" title="{IF link}Symbolic link{ELSE}{IF not_readable}Not readable{ELSE}{IF readonly}Read only{ELSE}{IF binary}Binary file{ELSE}{IF too_large}File too large{ENDIF}{IF in_use}In use{ENDIF}{ENDIF}{ENDIF}{ENDIF}{ENDIF}">Edit</span>{ENDIF}{IF no_link} | <a href="{SCRIPT}?command=copy&file={FILE}">Copy</a>{ENDIF}{IF unused}{IF dir_writeable} | <a href="{SCRIPT}?command=rename&file={FILE}">Rename</a> | <a href="{SCRIPT}?command=remove&file={FILE}">Delete</a>{ENDIF}{ENDIF}{IF no_link}{IF in_use} | <a href="{SCRIPT}?command=unlock&file={FILE}">Unlock</a>{ENDIF} |{IF unused}{IF users} <a href="{SCRIPT}?command=chprop&file={FILE}">Chmod/Chgrp</a> |{ENDIF}{ENDIF}{ELSE} |{ENDIF} <a href="{URL}" target="_blank">View in Browser</a>)</td>
+<td style="padding-left:15pt;white-space:nowrap;">({IF viewable}<a href="{SCRIPT}?command=show&file={FILE}">View</a>{ELSE}<span style="color:#C0C0C0" title="{IF not_readable}Not readable{ELSE}{IF binary}Binary file{ELSE}{IF too_large}File too large{ENDIF}{ENDIF}{ENDIF}">View</span>{ENDIF} | {IF editable}<a href="{SCRIPT}?command=beginedit&file={FILE}">Edit</a>{ELSE}<span style="color:#C0C0C0" title="{IF link}Symbolic link{ELSE}{IF not_readable}Not readable{ELSE}{IF readonly}Read only{ELSE}{IF binary}Binary file{ELSE}{IF too_large}File too large{ENDIF}{ENDIF}{ENDIF}{ENDIF}{ENDIF}">Edit</span>{ENDIF}{IF no_link} | <a href="{SCRIPT}?command=copy&file={FILE}">Copy</a>{ENDIF}{IF dir_writeable} | <a href="{SCRIPT}?command=rename&file={FILE}">Rename</a> | <a href="{SCRIPT}?command=remove&file={FILE}">Delete</a>{ENDIF} |{IF users} <a href="{SCRIPT}?command=chprop&file={FILE}">Chmod/Chgrp</a> |{ENDIF} <a href="{URL}" target="_blank">View in Browser</a>)</td>
</tr>
<p>(equals <a href="{URL}" target="_blank">{URL}</a>)</p>
-<p><b style="color:#FF0000">Caution!</b> This file is locked for other users while you are editing it. To unlock it, click <i>Save and exit</i> or <i>Exit WITHOUT saving</i>. Please <b>don't</b> click the <i>Reload</i> button in your browser! This will confuse the editor.</p>
+<p><a href="{SCRIPT}?command=show&file={DIR}">Back to {DIR}</a></p>{IF error}
-<form action="{SCRIPT}" method="get">
-<input type="hidden" name="command" value="canceledit">
-<input type="hidden" name="file" value="{FILE}">
-<p><input type="submit" value="Exit WITHOUT saving"></p>
-</form>
+<p>{ERROR}</p>{ENDIF}
<form action="{SCRIPT}" method="post">
<input type="hidden" name="command" value="endedit">
<input type="hidden" name="file" value="{FILE}">
+<input type="hidden" name="md5sum" value="{MD5SUM}">
+
+<p><textarea name="filecontent" rows="25" cols="120">{CONTENT}</textarea></p>
+
+<p><input type="checkbox" name="saveas" id="newfile" value="1"><label for="newfile"> Save as new file: {DIR} </label><input type="text" name="newfile" value="" onchange="if(this.form.newfile.value != '') this.form.saveas.checked = true; else this.form.saveas.checked = false;"></p>
-<table width="100%" border="1">
-<tr>
-<td width="50%" align="center">
-<input type="checkbox" name="saveas" id="newfile" value="1"><label for="newfile"> Save as new file: {DIR} </label><input type="text" name="newfile" value="" onchange="if(this.form.newfile.value != '') this.form.saveas.checked = true; else this.form.saveas.checked = false;"></td>
-<td width="50%" align="center"><input type="checkbox" name="encode_iso" id="encode_iso" value="1"><label for="encode_iso"> Encode ISO-8859-1 special chars</label></td>
-</tr>
-<tr>
-<td align="center"><input type="reset" value="Reset form"></td>
-<td align="center"><input type="submit" value="Save and exit"></td>
-</tr>
-</table>
-
-<textarea name="filecontent" rows="25" cols="120">{CONTENT}</textarea>
+<p><input type="submit" value="Save file"> <input type="reset" value="Discard changes"></p>
</form>
</body>