# Gossamer Threads Module Library - http://gossamer-threads.com/ # # GT::FileMan::Commands # CVS Info : # $Id: Commands.pm,v 1.267 2005/04/11 17:24:03 jagerman Exp $ # # Copyright (c) 2004 Gossamer Threads Inc. All Rights Reserved. # ==================================================================== # package GT::FileMan::Commands; # =============================================================== use strict; use GT::TempFile; use GT::Base qw/:persist/; use vars qw/$ICONS $READ_SIZE %LANGUAGE/; use GT::AutoLoader; use GT::File::Tools qw/:all/; # Our nasty language hash. %LANGUAGE = ( UPLOAD_MODE => "File %s was successfully uploaded in %s mode.", MSG_LOG_OFF => "Please enter username and password to login.", MSG_MULTI_UPLOAD => "%s files have been successfully uploaded.", MSG_CHMOD_CHANGED => "Permissions on %s file(s) have been updated successfully.", MSG_SEACH_FOUND => "Your search found %s results.", MSG_REPLA_FOUND => "Your search and replace updated %s files in %s", MSG_SEACH_NOTFOUND => "Your search did not produce any results.", MSG_FILE_EDITING => "%s %s file ...(size %s bytes)- Download", MSG_FILE_CREATED => "%s has been created.", MSG_FILE_EDITED => "Changes to %s have been saved.", MSG_DIR_CREATED => "%s directory has been created.", MSG_PREFERENCES => "Your options have been saved.", MSG_UNCOMPRESS => "%s file has been unarchived.", MSG_TAR_CANCEL => "Creation of tar file has been cancelled.", MSG_TAR_CREATED => "Tar file %s has been created.", MSG_COPIED => " %s selected file/directory(s) have been copied (%s can not be copied).", MSG_MOVED => " %s selected file/directory(s) have been moved (%s can not be moved).", MSG_DEL_SUCC => "%s files and %s directories have been removed.", MSG_DEL_CURR => "You've removed the directory: %s", MSG_DEL_ALL => "You've removed the directory, and all contents recursively.", MSG_DEL_SKIP => "You've skiped the directory :%s", MSG_DEL_CANC => "You've cancelled deleting the directory", MSG_DEL_ALL_SUCC => "All child dirs and files on the selected directorys has been removed. ", MSG_CONTINUE => "
click here to continue.", MSG_PWD_CHANGED => "Your password was changed. ", MSG_DEMO => "Disabled in Demo.", MSG_USER_ADDED => "%s was added successfully.", MSG_USER_DELETED => "%s was deleted successfully.", MSG_USER_RMALL => "Users were deleted sucessfully.", ERR_DEL => "Can not remove file(s)", ERR_CHMOD => "Can not change mode ", ERR_FILE_OPEN => "Can not open file: %s", ERR_FILE_EMPTY => "File %s is empty.", ERR_FILE_EXISTS => "File %s exists.", ERR_FILE_NOT_EXISTS => "File %s does not exist.", ERR_FILE_PERM => " Sorry, but we don't have write access to the htaccess files: '%s' and '%s'", ERR_FILE_PEM => "The %s directory is not writeable.", ERR_NOT_TEXT_FILE => "File %s is not a text file.", ERR_DIR_NOT_EXISTS => "Directory %s does not exist.", ERR_DIR_PEM => "The %s is not writeable.", ERR_DIR_PERM => "Please check permission.", ERR_NOT_ISFILE => "%s is a directory.", ERR_TMP_FILE => "Can not open temp file.", ERR_FREE_SPC => "Upload: Not enough free space to upload that file.", ERR_RM_FILE => "Unable to remove file: %s. Reason: %s", ERR_UPLOAD => "Unable to upload file: %s. Reason: %s.", ERR_FILE_SAVE => "Cannot save file %s. Check permissions.", ERR_DIR_EXISTS => "Directory %s already exists.", ERR_NAME => "Illegal Characters in Directory. Please use letters, numbers, - and _ only.", ERR_FILE_NAME1 => "No double .. allowed in file names.", ERR_FILE_NAME2 => "No leading . in file names.", ERR_READ_DIR => "Can not open dir: %s. Reason: %s", ERR_DIR_DEEP => "Directory level too deep.", ERR_DISK_SPACE => "Not enough space to save it (free space is %s kb)", ERR_UNCOMPRESS => "Select files or directories before to uncompress.", ERR_TAR => "Error: %s.", ERR_TAR_NOT_EXISTS => "Can not create a tar file: %s", ERR_TAR_PEM => "Can not create a tar file %s. Check permission.", ERR_DOWNLOAD => "You selected a directory !", ERR_LOGIN => "Invalid Username and Password.", ERR_INVALID => "Input value has invalid characters : %s ", ERR_NOT_FILE => "The %s is not a file", ERR_OLD_PASSWORD => "Invalid Old password", ERR_NEW_PASSWORD => "New password must be more than 3 character", ERR_OPEN_FILE => "Can not open %s file, reason: %s", ERR_WRITEABLE => "Can not save %s file, reason: %s", ERR_NO_AZIP => "Please install the Archive::Zip library which is required.", ERR_NO_GZIP => "Please install the Compress::Zlib library which is required.", COBALT_NOREMOTE => "FileMan is not currently running under server authentication!", ERR_VERSION => "This action does not support for your current version!", ERR_PRINT => "Please select the files which are required text or image files", PRINT_NEXT => "Print Next", COBALT_NOUSER => "Unable to lookup user '%s'", COBALT_BADUID => "Invalid user '%s' (%s)", COBALT_CANTSU => "Can't switch to user '%s' (%s,%s). Reason: '%s'", COBALT_BADDIR => "Invalid home directory '%s'. It does not look like a standard Raq director.", COBALT_BADGROUP => "This program is restricted to site administrators only. You must be in the site administer group in order to use this." ); # Mapping of image name to icon files. $ICONS = { 'gif jpg jpeg bmp' => ['image2.gif' => 'Image File'], 'txt' => ['text.gif' => 'Text File'], 'cgi pl pm' => ['text.gif' => 'Script File'], 'zip gz tar' => ['compressed.gif' => 'Compressed File'], 'htm html shtm shtml' => ['ie.gif' => 'Html File'], 'wav au mid mod mp3' => ['sound.gif' => 'Sound File'], 'exe' => ['binary.gif' => 'Binary File'], 'doc' => ['doc.gif' => 'MS Word'], 'xls' => ['xls.gif' => 'MS Excel'], 'pdf' => ['pdf.gif' => 'Adobe Acrobat'], 'unknown' => ['unknown.gif' => ''], }; # How large a chunk should we read into memory at once. $READ_SIZE = 500000; sub DESTROY {} $COMPILE{cmd_main_display} = __LINE__ . <<'END_OF_SUB'; sub cmd_main_display { # ------------------------------------------------------------------ # Display main page # my ($self, $args, $type) = @_; # Load user list from .htpassword if it exists if ($args->{show_passwd} or $self->{cgi}->{show_passwd}) { $self->{url_opts} .= ';show_passwd=1' if ($self->{url_opts} !~ /show_passwd/); my $htpasswd = $self->load_htpasswd(); foreach (keys %$htpasswd) { $args->{$_} ||= $htpasswd->{$_}; } } $self->list_files(); $self->{cgi}->{cmd_do} = 'cmd_command' if ($type); $self->page('main.html', $args); } END_OF_SUB $COMPILE{load_htpasswd} = __LINE__ . <<'END_OF_SUB'; sub load_htpasswd { my $self = shift; my $pass_path = $self->{in}->cookie('def_passwd_dir'); my ($htpasswd, $exist, $delete_list); if (!$self->{cfg}->{passwd_dir_level} and !$pass_path =~ /^$self->{cfg}->{root_dir}/) { print $self->{in}->header (-cookie => [ $self->{in}->cookie ( -name => 'def_passwd_dir', -value => '0', -expires => '+5y')]); $pass_path = ''; } if ($pass_path) { # create .htaccess and .htpasswd in Password directory my $file_name = $self->_safe_dir(); $file_name =~ s/[\/ \:]/\_/g; $htpasswd = "$pass_path/.htpass$file_name"; $exist = 1 if (-e $htpasswd); } else { my $fpasswd = $self->_safe_file(".htpasswd", {fullfile => 1, exist => 1}); $htpasswd = $fpasswd->{file}; $exist = 1 if ($fpasswd->{exist}); } my $faccess = $self->_safe_file(".htaccess", {fullfile => 1, exist => 1}); my $htaccess = $faccess->{file}; if ($exist and $faccess->{exist}) { open (HTPAS, "< $htpasswd") or die "Unable to open: $htpasswd ($!)"; my @users =Readme File:";
open (DATA, "<$real_work_path/$readme") or return $self->cmd_main_display({reload => 1, status => "$!"});
$count = 0;
while () {
chomp;
next if ( $_ =~ /^\#/ or !$_);
$msg_readme .= (($msg_readme)? "
":"").$_;
$count++;
last if ($count == 10);
}
close DATA;
$msg_readme .= "
$font $prompt $cmd
!;
eval {
$pid = open (TMP, "$cmd |");
$oldfh = select(TMP); $| = 1; select($oldfh);
while(){
s/(\n|\r\n)$//;
print GT::CGI->html_escape($_), "\n";
}
close (TMP) or die $@;
};
if ($@) {
if ($@ =~ /timeout/) {
my $ret = kill ('INT', $pid);
$ret ? print "Command timed out." : print "Command timed out. Unable to kill: $!";
}
else {
die $@;
}
}
print " ";
}
else {
# Other command
my ($output,$errors) = ('','');
if ($cmd or $self->{cgi}->{runfile}) {
my $tmp_output = new GT::TempFile; # create a result file
my $tmp_errors = new GT::TempFile; # create a error file
if ($self->{cfg}->{winnt}) { #for WinNT
system ("$cmd 1> $$tmp_output 2> $$tmp_errors");
}
else {
system ("$cmd 2> $$tmp_errors 1> $$tmp_output");
}
open (TMP, "< $$tmp_output") or return $self->cmd_main_display({reload => 1, status => $!});
read (TMP, $output, -s TMP);
close TMP;
open (TMP, "< $$tmp_errors") or return $self->cmd_main_display({reload => 1, status => $!});
read (TMP, $errors, -s TMP);
close TMP;
if (($cmd =~ m/^\s*cd\s+(.+)/) and !$errors) {
($self->{cfg}->{winnt} and $working_dir !~ m,^/,) and $working_dir = '/'.$working_dir;
$working_dir = _command_show($working_dir,$cmd) || {};
($self->{cfg}->{winnt}) and $working_dir =~ s,/,,;
}
$output = $self->{in}->html_escape($output) if ($output);
$errors ||= '';
}
my $action = ($cmd)? '' : "onload='top.js_cmd_command(1)'";
$prompt = $self->{cfg}->{winnt} ? "$working_dir> " : "[". eval { getpwuid($<) } ."\@$server_name ".($working_dir || '/')."]";
print qq!
$font
$prompt $cmd
$output
$errors!; } } END_OF_SUB $COMPILE{cmd_upload} = __LINE__ . <<'END_OF_SUB'; sub cmd_upload { # ----------------------------------------------------- # upload a files # my ($self, $data) = @_; # $ENV{'PATH'} = ''; #for taint mode warning $data ||= $self->{in}->param('txt_input'); my $work_path = $self->{work_path}; my $path = $self->{cfg}->{root_dir}.(($work_path)? "/$work_path" : ''); if (!-w $path) { # Current directory does not writeable my $msg = sprintf($LANGUAGE{ERR_FILE_PEM},($work_path) ? $work_path : 'Root'); ($self->{in}->param('txt_input')) ? return $self->cmd_main_display({ reload => 1 , status => $msg }) : return (0, $msg); } my $free_space = 0; if ($self->{cfg}->{allowed_space} > 0) { my $disk_space = $self->_checkspace($self->{cfg}->{root_dir}); $free_space = $disk_space->{free_space}; } my $filename = $data; my $mode = $self->{cgi}->{type}; $filename =~ s/.*?([^\\\/:]+)$/$1/; $filename =~ s/[\[\]\s\$\#\%'"]/\_/g; # Change the name if needed if ($self->{cgi}->{name} eq 'uppercase') { $filename =~ s/(\w+)/\U$1/gi; } elsif ($self->{cgi}->{name} eq 'lowercase') { $filename =~ s/(\w+)/\L$1/gi; } # Get the full file name and save the file. my ($bytesread, $buffer, $fullfile, $file_size); my $file = $self->_safe_file ($filename, { fullfile => 1, exist => 1, write => 1}); return $self->cmd_main_display({ reload => 1, status => sprintf($LANGUAGE{ERR_INVALID}, $filename)}) if ($file == -1); # not safe $fullfile = $file->{file}; if (!$self->{cfg}->{winnt}) { $fullfile =~ m,^([\/\w.-]+)$,; $fullfile = $1; #untainted } if (!$self->{in}->param('txt_input')) { #multi upload return (0, sprintf($LANGUAGE{ERR_FILE_EXISTS}, $filename)) if ($file->{exist} and !$self->{cgi}->{overwrite}); return (0, sprintf($LANGUAGE{ERR_FILE_PEM}, $filename)) if ($file->{exist} and !$file->{write} and $self->{cgi}->{overwrite}); } else { return $self->cmd_main_display({ reload => 1 , status =>sprintf($LANGUAGE{ERR_FILE_EXISTS}, $filename)}) if ($file->{exist} and !$self->{cgi}->{overwrite}); return $self->cmd_main_display({ reload => 1 , status =>sprintf($LANGUAGE{ERR_FILE_PEM}, $filename)}) if ($file->{exist} and !$file->{write} and $self->{cgi}->{overwrite}); } $file_size = 0; open (OUTFILE, ">$fullfile") ; binmode (OUTFILE); while ($bytesread=read($data,$buffer,1024)) { if ($mode eq 'ascii') { $buffer =~ s,\r\n,\n,g; } print OUTFILE $buffer; $file_size += 1024; if ($self->{cfg}->{allowed_space} > 0) { if (($file_size / 1024) > $free_space) { close OUTFILE; unlink ($fullfile); ($self->{in}->param('txt_input')) ? return $self->cmd_main_display({ reload => '1', status => $LANGUAGE{ERR_FREE_SPC}}) : return (0,$LANGUAGE{ERR_FREE_SPC}); } } } close OUTFILE; if ($mode eq 'auto') { if (-T $fullfile) { open (FILE, "< $fullfile") or die sprintf($LANGUAGE{ERR_FILE_OPEN}, $fullfile, "$!"); read (FILE, my $data, -s FILE); close FILE; $data =~ s,\r\n,\n,g; open (FILE, "> $fullfile") or die sprintf($LANGUAGE{ERR_FILE_OPEN}, $fullfile, "$!"); print FILE $data; close FILE; $mode = 'ascii/text'; } } # Change mode if ($self->{cfg}->{upload_chmod}) { my $octal_perm = oct($self->{cfg}->{upload_chmod}); # Permissions have to be in octal chmod($octal_perm, $fullfile) if $octal_perm; # 0 _probably_ means not octal, because 0 is an odd permission to use } my $status; if (-s $fullfile == 0) { unlink ($fullfile); $status = sprintf($LANGUAGE{ERR_UPLOAD}, $filename, "File is 0 bytes."); } else { $status = sprintf($LANGUAGE{UPLOAD_MODE},$filename,$mode); } $self->cmd_main_display({ reload=>1 , status => $status}) if ($self->{in}->param('txt_input')); if (-e $fullfile || -s $fullfile != 0) { if ( $self->{cfg}->{multi} ) { #save log info my $from = $fullfile; $from =~ s/$path\///; $self->history("cmd_upload|$from|$path"); } return (1, $status); } else { return (0, $status); } } END_OF_SUB $COMPILE{cmd_mul_upload} = __LINE__ . <<'END_OF_SUB'; sub cmd_mul_upload { # ----------------------------------------------------- # upload nulti files # my $self = shift; my $count = 0; my $msg = ''; for my $i(1..10) { my $data = $self->{in}->param('file'.$i); next if (!$data); my ($result, $status) = $self->cmd_upload ($data); $result ? $count++ : ($msg .= $status . '
!;
my $read_size = 4096;
my $to_read = ($file_size > $read_size) ? $read_size : $file_size;
my $buffer;
seek FILE, -$to_read, 2;
read FILE, $buffer, $to_read;
my $read = $to_read;
my $need_lines = $lines - 1;
while () {
if ($buffer =~ /\n(.*(?:\n.*){$need_lines}\n?$)/) {
print $self->{in}->html_escape($1);
last;
}
$to_read = ($file_size - $read > $read_size) ? $read_size : $file_size - $read;
unless ($to_read == 0) {
print $self->{in}->html_escape($buffer);
last;
}
seek FILE, -($to_read + $read), 2;
$read += $to_read;
my $new_buffer;
my $bytes_read = read FILE, $new_buffer, $to_read;
if ($bytes_read == 0) {
print $self->{in}->html_escape($buffer);
last;
}
$buffer = $new_buffer . $buffer;
}
my $cnt = 0;
if ($follow) {
seek FILE, 0, 2; # Seek to the end of the file
while () {
select undef, undef, undef, 1;
seek FILE, 0, 1 or last; # Reset eof(FILE)
print while ;
seek FILE, 0, 2;
last if ($cnt++ > 60); # Only run for one min max.
}
}
print " ";
}
END_OF_SUB
$COMPILE{cmd_perl} = __LINE__ . <<'END_OF_SUB';
sub cmd_perl {
#----------------------------------------------------------------
# check perl syntax
#
my $self = shift;
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin'; #for taint mode
my $url_opts = $self->{url_opts} || '';
my $work_path = $self->{work_path} || '';
print $self->{in}->header;
my $css_file = $self->{in}->cookie('scheme') || 'fileman';
print qq!
{cfg}->{html_root_url}/$css_file.css>
!; print $self->_environment(); } END_OF_SUB sub history { #--------------------------------------------------------------------- # Save the history # my ($self,$content) = @_; return if (!$content); my $priv_path = $self->{cfg}->{priv_path}; my $db_name = 'fileman_history.db'; $content = $self->{cfg}->{username} . '|' . $ENV{'REMOTE_ADDR'} . '|' . time . "|$content\n"; open (DATA,">>$priv_path/$db_name") or die sprintf($LANGUAGE{ERR_OPEN_FILE}, $db_name, $!); flock(DATA, 2); print DATA $content; close DATA; } sub _environment { # -------------------------------------------------------------------- # Return HTML formatted environment for error messages. # my $self = shift; my $info = '
';
# Print GT::SQL error if it exists.
$info .= "System Information\n======================================\n";
$info .= "Perl Version: $]\n";
$info .= "FileMan Version: $self->{cfg}->{version}" if ($self->{cfg}->{version});
$info .= "\n";
my $cmds = $self->{commands};
foreach (keys %$cmds) {
$info .= $_."\t:";
$info .= ($cmds->{$_})?('enabled'):('disabled');
$info .= "\n";
}
$info .= "Persistant Env: mod_perl (" . (MOD_PERL ? 1 : 0) . ") SpeedyCGI (" . (SPEEDY ? 1 : 0) . ")\n";
$info .= "Mod Perl Version: " . MOD_PERL . "\n" if MOD_PERL;
$info .= "\@INC = \n\t" . join ("\n\t", @INC) . "\n";
$info .= "\$\@: $@\n" if ($@);
$info .= "\n";
# CGI Parameters and Cookies.
if (ref $self->{in} eq 'GT::CGI') {
if ($self->{in}->param) {
$info .= "CGI INPUT\n======================================\n";
foreach (sort $self->{in}->param) { $info .= "$_ => " . $self->{in}->param($_) . "\n"; }
$info .= "\n\n";
}
if ($self->{in}->cookie) {
$info .= "CGI Cookies\n======================================\n";
foreach (sort $self->{in}->cookie) { $info .= "$_ => " . $self->{in}->cookie($_) . "\n"; }
$info .= "\n\n";
}
}
# Environement info.
$info .= "ENVIRONMENT\n======================================\n";
foreach (sort keys %ENV) { $info .= "$_ => $ENV{$_}\n"; }
$info .= "";
return $info;
}
sub _zip_information {
#----------------------------------------------------------------------
# Show the information about a zip file
#
my ($self, $filename, $status) = @_;
my $fullfile = $self->_safe_file($filename, { fullfile => 1, exist => 1, size => 1 });
my $zip = new Archive::Zip($fullfile->{file}) or return $self->cmd_main_display({reload => 0, status => $!});
my $cmp_file = $fullfile->{file};
my $stat = [stat($cmp_file)];
my $hits = $zip->members + 1;
my $pg = $self->{cgi}->{pg} || 1;
my $mh = $self->{in}->cookie('def_files_page') || 25;
my $start= ($pg == 1) ? 1 : (($pg - 1) * $mh + 1);
my @results;
my $total_size = $fullfile->{size};
my $skip = 0;
if ( $hits > 0 ) {
foreach ( $zip->members ) {
$skip++;
next if ($skip < $start);
my $s = $_->compressedSize;
my $icon = _get_icon($_->fileName);
push @results, {
icon => "' if (not $content_type =~ m/htm/);
}
else {
print $self->{in}->header({
'-force' => 1,
'-type' => $content_type,
'-Content-Disposition' => \"filename=$filename",
'-Content-Length' => $file_size,
});
}
($self->{cfg}->{winnt}) and binmode STDOUT;
binmode DATA;
my $buffer;
print $buffer while (read(DATA, $buffer , $READ_SIZE));
close(DATA);
}
}
sub _safe_dir {
#------------------------------------------------------------------------
# Check a directory make sure it safe
#
my ($self, $dir, $options) = @_;
my $root = $self->{cfg}->{root_dir};
my $work = $self->{work_path};
my $fulldir;
unless ($dir) {
return ($work) ? "$root/$work" : $root;
}
elsif ($dir eq '/') {
return $root;
}
return -1 if ($self->{cfg}->{filename_check} and $dir !~ m,^([-\w/. ]+)$,);
return -1 if ($dir =~ /$GT::FileMan::UNSAFE_PATH/);
($dir =~ m,^/,) ? ($fulldir = $root . $dir)
: ($fulldir = $root. ($work ? '/' : '') . $work . '/' . $dir);
my ($e, $d, $w);
foreach my $key (keys % $options) {
if ($options->{$key} == 1) {
$e = -e $fulldir if ($key eq 'exist');
$d = -d $fulldir if ($key eq 'isdir');
$w = -w $fulldir if ($key eq 'write');
}
}
return { fulldir => $fulldir, exist => $e, isdir => $d, write => $w };
}
sub _command_show {
#--------------------------------------------------------------------
# Show path when execute cd command
#
my ($working_dir, $cmd) = @_;
if ($cmd =~ m/^\s*cd\s*\.\./) { # cd ..
my $tmp;
my $parts = [split(/\//, $working_dir)];
return '/' if ($#$parts == 1 or $working_dir eq '/');
foreach my $ii( 0 .. $#$parts) {
$tmp .= '/'.@$parts[$ii] if ($ii < $#$parts and @$parts[$ii]);
}
return $tmp;
}
return $working_dir if ($cmd =~ m/^\s*cd\s*\./); # cd.
my $path = $cmd;
$path =~ s/\s*cd\s*//;
return '/' if ($path =~ m,^(/+)$,);
return ($path =~ m/^\//)? $path : $working_dir.(($working_dir and $working_dir ne '/')? '/' : '').$path;
}
sub _get_icon {
# ------------------------------------------------------------------
# Get the associated icon based on a files extension
#
my ($file) = shift;
my ($ext) = $file =~ /\.([^.]+)$/;
return {icon => 'unknown.gif', type => 'unknown File'} if (!$ext);
foreach (keys %{$ICONS}) {
next if (/folder/);
next if (/unknown/);
next if (/parent/);
($_ =~ /\b\Q$ext\E\b/i) and return { icon => $ICONS->{$_}[0],type => $ICONS->{$_}[1]};
}
return {icon => 'unknown.gif', type => "$ext File"};
}
sub _get_date {
# ------------------------------------------------------------------
my $time = shift;
$time or ($time = time);
my @months = qw!Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec!;
my ($min, $hr, $day, $mon, $yr) = (localtime($time))[1,2,3,4,5];
$yr = $yr + 1900;
($min < 10) and ($min = "0$min");
($hr < 10) and ($hr = "0$hr");
($day < 10) and ($day = "0$day");
return "$day-$months[$mon]-$yr $hr:$min";
}
sub _print_filesize {
# ------------------------------------------------------------------
# Prints out the file size.
#
my $size = shift;
my $formatted_size = 0;
$formatted_size = int($size / 1000) if ($size);
return $formatted_size == 0 ? "$size bytes" : $formatted_size." kb";
}
sub _print_permissions {
# ------------------------------------------------------------------
# Takes permissions in octal and prints out in ls -al format.
#
my $octal = shift;
my $string = sprintf "%lo", ($octal & 07777);
my $result = '';
foreach (split(//, $string)) {
if ($_ == 7) { $result .= "rwx "; }
elsif ($_ == 6) { $result .= "rw- "; }
elsif ($_ == 5) { $result .= "r-x "; }
elsif ($_ == 4) { $result .= "r-- "; }
elsif ($_ == 3) { $result .= "-wx "; }
elsif ($_ == 2) { $result .= "-w- "; }
elsif ($_ == 1) { $result .= "--x "; }
elsif ($_ == 0) { $result .= "--- "; }
else { $result .= "unkown '$_'!"; }
}
return $result;
}
sub _load_mime {
# --------------------------------------------------------------------
# Load the config file into a hash.
#
my $file = shift;
require GT::MIMETypes;
my $guess = GT::MIMETypes->guess_type($file);
if (! $guess) {
if (-e $file) {
$guess = -T _ ? 'text/plain' : 'application/octet-stream';
}
else {
$guess = 'application/octet-stream';
}
}
return $guess;
}
sub _init_chmod {
#---------------------------------------------------------------------
# set chmod
#
my($from,$to) = @_;
$from =~ m,^([/\w.-]+)$,;
$from = $1;
$to =~ m,^([/\w.-]+)$,;
$to = $1;
my $stat = [stat($from)];
chmod(@$stat[2],$to);
}
sub _create_htaccess {
# ------------------------------------------------------------------
# Creates the htaccess file.
#
my ($htaccess, $htpasswd) = @_;
my $raq = $ENV{GT_COBALT_RAQ} ? "AuthPAM_Enabled off\n" : '';
open (HTAC, "> $htaccess") or die "Unable to open: $htaccess ($!)";
print HTAC <$to") or return 0;
open(SOURCE, "<$from") or return 0;
binmode SOURCE;
binmode TARGET;
my $buffer;
while (read SOURCE, $buffer, $READ_SIZE) {
if ($repl) {
($cs)? ($buffer =~ s,$repl,$with,g)
: ($buffer =~ s,$repl,$with,ig);
}
print TARGET $buffer;
}
close SOURCE;
close TARGET;
_init_chmod($from,$to);
return 1;
}
sub _valid_name_check {
# ---------------------------------------------------
# Checks to see if the input database/table name is a
# valid one. The function checks the following:
# 1. if a name is entered at all;
# 2. if there are spaces in the name;
# 3. if the name is consisted of valid characters; and
# 4. if the name is consisted of only numbers.
my ($self, $name) = @_;
my ($output);
$name =~ s/^\s+//;
$name =~ s/\s+$//;
if (!$name) {
$output = "Please provide a valid name.";
}
elsif ($self->{cfg}->{filename_check} and $name =~ /\s/) {
$output = "Spaces are not allowed in name.";
}
return $output;
}
1;