#!/usr/bin/perl
### SibSoft.net, Jan 2008, Art Bogdanov ###
use strict;
use CGI::Carp qw(fatalsToBrowser);
use lib '.';
use XFileConfig;
use Session;
use LWP::UserAgent;
my $IP = $ENV{HTTP_X_FORWARDED_FOR} || $ENV{REMOTE_ADDR};
$c->{ip_not_allowed}=~s/\./\\./g;
if($c->{ip_not_allowed} && $IP=~/$c->{ip_not_allowed}/)
{
print"Content-type:text/html\n\n";
print"Your IP was banned by administrator";
exit;
}
my $ses = Session->new();
my $f = $ses->f;
my $db= $ses->db;
my $op = $f->{op};
if( $op eq "login" )
{
$ses->Login() || $ses->redirect('login.html&msg=Incorrect Login or Password');
$ses->redirect( '/?'.$ENV{QUERY_STRING} ) if $ses->getUser;
}
else
{
$ses->CheckAuth();
}
if($ENV{HTTP_CGI_AUTHORIZATION} =~ s/basic\s+//i)
{
$ses->Login(undef,'instant');
print($ses->{cgi_query}->header(-status=>403)),exit unless $ses->{user};
}
my $utype = $ses->getUser ? ($ses->getUser->{premium} ? 'prem' : 'reg') : 'anon';
$c->{$_}=$c->{"$_\_$utype"} for qw(max_upload_files max_upload_size max_upload_filesize max_downloads_number download_countdown captcha ads mb_per_hour remote_url direct_links down_speed);
&News if $op eq 'news';
&Register if $op eq 'registration';
&RegisterSave if $op eq 'register_save';
&UploadResult if $op eq 'upload_result';
&Download1 if $op eq 'download1';
&Download2 if $op eq 'download2';
&Page if $op eq 'page';
&ForgotPass if $op eq 'forgot_pass';
&ContactSend if $op eq 'contact_send';
&UserPublic if $op eq 'user_public';
&DelFile if $f->{del};
&Payments if $op eq 'payments';
&PaymentComplete($1) if $ENV{QUERY_STRING}=~/payment_complete=(.+)/;
&CheckFiles if $op eq 'checkfiles';
&Catalogue if $op eq 'catalogue';
&ReportFile if $op eq 'report_file';
&ReportFileSend if $op eq 'report_file_send';
my $sub={
my_account => \&MyAccount,
my_files => \&MyFiles,
my_files_export => \&MyFilesExport,
file_edit => \&FileEdit,
convert_points => \&ConvertPoints,
admin_files => \&AdminFiles,
admin_users => \&AdminUsers,
admin_user_edit => \&AdminUserEdit,
admin_users_add => \&AdminUsersAdd,
admin_servers => \&AdminServers,
admin_server_add => \&AdminServerAdd,
admin_server_save=> \&AdminServerSave,
admin_server_del => \&AdminServerDelete,
admin_settings => \&AdminSettings,
admin_news => \&AdminNews,
admin_news_edit => \&AdminNewsEdit,
admin_reports => \&AdminReports,
admin_check_consistancy => \&AdminCheckConsistancy,
admin_update_srv_stats => \&AdminUpdateServerStats,
admin_server_import => \&AdminServerImport,
logout => sub{$ses->Logout},
}->{ $op };
if($sub && $ses->getUser)
{
&$sub;
}
else
{
&UploadForm;
}
sub Register
{
my $rand = $ses->randchar(8);
my %captcha = &GenerateCaptcha("rr$rand");
&SecSave( 0, $ses->getIP(), $captcha{number}, $rand );
$f->{usr_login}=$ses->SecureStr($f->{usr_login});
$f->{usr_email}=$ses->SecureStr($f->{usr_email});
$ses->PrintTemplate("registration.html",
%captcha,
'rand' => $rand,
'usr_login' => $f->{usr_login},
'usr_email' => $f->{usr_email},
);
}
sub RegisterSave
{
&Register unless &SecCheck( 0, 'rr', $ses->getIP(), $f->{'rand'}, $f->{code} );
$ses->message("Error: Login is too short") if length($f->{usr_login})<4;
$ses->message("Error: Login is too long") if length($f->{usr_login})>32;
$ses->message("Error: Invalid login: reserved word") if $f->{usr_login}=~/^(admin|images|captchas|files)$/;
$ses->message("Error: Invalid Login format") if $f->{usr_login}=~/^\w-\_$/;
$ses->message("Error: Password contain bad symbols") if $f->{usr_password}=~/[<>"]/;
$ses->message("Error: Password is too short") if length($f->{usr_password})<4;
$ses->message("Error: Password is too long") if length($f->{usr_password})>32;
$ses->message("Error: Passwords do not match") if $f->{usr_password} ne $f->{usr_password2};
$ses->message("Error: Invalid e-mail") unless $f->{usr_email}=~/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
$ses->message("Error: User with this login already exist!") if $db->SelectOne("SELECT usr_id FROM Users WHERE usr_login=?",$f->{usr_login});
$ses->message("Error: User with this e-mail already exist!") if $db->SelectOne("SELECT usr_id FROM Users WHERE usr_email=?",$f->{usr_email});
$db->Exec("INSERT INTO Users (usr_login,usr_email,usr_password,usr_created) VALUES (?,?,ENCODE(?,?),NOW())",$f->{usr_login},$f->{usr_email},$f->{usr_password},$c->{pasword_salt});
$f->{login} = $f->{usr_login};
$f->{password} = $f->{usr_password};
$ses->Login();
$ses->redirect( $c->{site_url} );
}
sub ForgotPass
{
if($f->{usr_login})
{
my $user = $db->SelectRow("SELECT *, DECODE(usr_password,?) as usr_password
FROM Users
WHERE usr_login=?
OR usr_email=?",$c->{pasword_salt},$f->{usr_login},$f->{usr_login});
$ses->message("No user with this login / e-mail") unless $user;
$c->{email_text}=1;
$ses->SendMail( $user->{usr_email}, $c->{email_from}, "$c->{site_name}: password reminder", "Login: $user->{usr_login}\nPassword: $user->{usr_password}" );
$ses->message("Your Login & Password sent to your E-mail");
}
$ses->PrintTemplate("forgot_pass.html");
}
sub UploadForm
{
$ses->message("Register on site to be able to upload files") if !$ses->getUser && !$c->{enabled_anon};
my ($site_cgi_rel) = $c->{site_cgi}=~/^http:\/\/.+?(\/.+)/i;
my $server = $db->SelectRow("SELECT * FROM Servers
WHERE srv_status='ON'
AND srv_disk+? <= srv_disk_max
ORDER BY srv_last_upload
LIMIT 1",$c->{max_upload_size}||100); # Get next Live server with free space
$ses->message("We're sorry, there are no servers available for upload at the moment.
Refresh this page after some minutes.") unless $server;
my @url_fields = map{{ 'number'=>$_, 'enable_file_descr'=>$c->{enable_file_descr} }} (1..$c->{max_upload_files});
my ($rapid_login,$rapid_pass)=($ses->getUser->{usr_rapid_login},$ses->getUser->{usr_rapid_pass}) if $ses->getUser;
$ses->PrintTemplate("upload_form.html",
'ext_allowed' => $c->{ext_allowed},
'ext_not_allowed' => $c->{ext_not_allowed},
'max_upload_files' => $c->{max_upload_files},
'max_upload_size' => $c->{max_upload_size},
'enable_file_descr'=> $c->{enable_file_descr},
'remote_url' => $c->{remote_url},
'srv_cgi_url' => $server->{srv_cgi_url},
'sess_id' => $ses->getCookie( $ses->{auth_cook} ),
'utype' => $utype,
'url_fields' => \@url_fields,
'rapid_login' => $rapid_login,
'rapid_pass' => $rapid_pass,
);
}
sub UploadResult
{
my $fnames = &ARef($f->{'fn'});
my $status = &ARef($f->{'st'});
my $usr_login = $ses->getUser->{usr_login} if $ses->getUser && $ses->getUser->{usr_add_login};
my @arr;
for(my $i=0;$i<=$#$fnames;$i++)
{
$fnames->[$i] = $ses->SecureStr($fnames->[$i]);
$status->[$i] = $ses->SecureStr($status->[$i]);
my $file = $status->[$i] eq 'OK' ?
$db->SelectRow("SELECT * FROM Files WHERE file_code=?",$fnames->[$i]) : {file_name=>$fnames->[$i]};
$file->{file_size} = $file->{file_size}<1048576 ? sprintf("%.01f Kb",$file->{file_size}/1024) : sprintf("%.01f Mb",$file->{file_size}/1048576);
$file->{file_code} = "$usr_login/$file->{file_code}" if $usr_login;
$file->{download_link} = "$c->{site_url}/$file->{file_code}";
$file->{download_link} .= {0 => "/$file->{file_name}.html",
1 => "/$file->{file_name}.htm",
2 => "/$file->{file_name}",
3 => ".html",
4 => ".htm"
}->{$c->{link_format}};
push @arr, {%{$file},
'site_url' => $c->{site_url},
'status' => $status->[$i],
"status_$status->[$i]"=>1,
'usr_login' => $usr_login,
};
}
if($f->{link_rcpt}=~/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)
{
my $tmpl = $ses->CreateTemplate("Templates/confirm_email_user.html");
$tmpl->param('files' => \@arr);
$ses->SendMail( $f->{link_rcpt}, $c->{email_from}, "$c->{site_name}: File send notification", $tmpl->output() );
}
$ses->PrintTemplate("upload_results.html",
'links' => \@arr,
);
}
sub Download1
{
my ($fname) = $ENV{QUERY_STRING}=~/&fname=(.+)$/;
$fname||=$f->{fname};
$fname=~s/\.html?$//i;
$fname=~s/\///;
my $premium = $ses->getUser && $ses->getUser->{premium};
my $file = $db->SelectRow("SELECT f.*, u.usr_login, u.usr_public, u.usr_add_login
FROM (Files f, Servers s)
LEFT JOIN Users u ON f.usr_id = u.usr_id
WHERE f.file_code=?
AND f.srv_id=s.srv_id
AND s.srv_status<>'OFF' ",$f->{id});
if(!$file && $db->SelectOne("SELECT usr_id FROM Users WHERE usr_login=?",$f->{id}))
{
$f->{usr_login}=$f->{id};
$f->{fld}=$f->{fname}||'';
&UserPublic;
}
$ses->message("No such file") unless $file;
$ses->message("No such file from this user") if $f->{usr_login} && lc($f->{usr_login}) ne lc($file->{usr_login});
$ses->message("No such file with this filename") if $fname && $file->{file_name} ne $fname;
$ses->makePagingLinks($f);
$ses->{page_title} = "Download $file->{file_name}";
$file->{fsize} = $file->{file_size}<1048576 ? sprintf("%.01f Kb",$file->{file_size}/1024) : sprintf("%.01f Mb",$file->{file_size}/1048576);
$f->{method_premium}=1 if $premium;
if(!$f->{method_free} && !$f->{method_premium} && $c->{pre_download_page} && $c->{enabled_prem})
{
$ses->PrintTemplate("download0.html",
'usr_login'=>$f->{usr_login},
%{$file}, );
}
else
{
$utype='';
$utype='prem' if $f->{method_premium} && $premium;
$ses->redirect("$c->{site_url}/login.html") if $f->{method_premium} && !$ses->getUser;
$ses->redirect("$c->{site_url}/?op=payments") if $f->{method_premium} && !$premium;
$utype='reg' if $f->{method_free} && $ses->getUser;
$utype||='anon';
$premium=0 if $f->{method_free};
$c->{$_}=$c->{"$_\_$utype"} for qw(max_upload_files max_upload_size max_upload_filesize max_downloads_number download_countdown captcha ads mb_per_hour remote_url direct_links);
}
my $wait = $db->SelectOne("SELECT UNIX_TIMESTAMP(time)-UNIX_TIMESTAMP() FROM IP2Time WHERE ip=INET_ATON(?)",$ses->getIP) if $c->{mb_per_hour};
if($wait>0)
{
require Time::Elapsed;
my $et = new Time::Elapsed;
my $elapsed = $et->convert($wait);
$ses->message("You have reached the download-limit for free-users.
Get your own Premium-account now!
(Or wait $elapsed)");
}
&Download2('no_checks') if $ses->getUser &&
$premium &&
!$c->{captcha} &&
!$c->{download_countdown} &&
!$file->{file_password} &&
$ses->getUser->{usr_direct_downloads};
my $rand = $ses->randchar(8);
my %captcha = &GenerateCaptcha("$f->{id}$rand") if $c->{captcha};
&SecSave( $file->{file_id}, $ses->getIP(), $captcha{number}, $rand );
$file->{file_password}='' if $ses->getUser && $ses->getUser->{usr_adm};
$file->{file_descr}=~s/\n/
/gs;
$ses->message("Sorry but this file reached max downloads limit") if $c->{max_downloads_number} && $file->{file_downloads} >= $c->{max_downloads_number};
my @plans;
if($c->{payment_plans} && !$premium && $c->{enabled_prem})
{
for( split(/,/,$c->{payment_plans}) )
{
/([\d\.]+)=(\d+)/;
push @plans, { amount=>$1, days=>$2, site_url=>$c->{site_url} };
}
}
$ses->PrintTemplate("download1.html",
%{$file},
'msg' => $f->{msg},
'site_name' => $c->{site_name},
'pass_required' => $file->{file_password} && 1,
'countdown' => $c->{download_countdown},
'rand' => $rand,
'direct_links' => $c->{direct_links},
'premium' => $premium,
'plans' => \@plans,
'method_premium'=> $f->{method_premium},
'method_free' => $f->{method_free},
%captcha,
);
}
sub Download2
{
my $no_checks = shift;
my $file = $db->SelectRow("SELECT *
FROM Files f, Servers s
WHERE f.file_code=?
AND f.srv_id=s.srv_id",$f->{id});
$ses->message("No such file") unless $file;
unless($no_checks)
{
&UploadForm unless $ENV{REQUEST_METHOD} eq 'POST';
&Download1 unless &SecCheck( $file->{file_id}, $f->{id}, $ses->getIP, $f->{'rand'}, $f->{code} );
$ses->message("Sorry but this file reached max downloads limit") if $c->{max_downloads_number} && $file->{downloads} >= $c->{max_downloads_number};
if($file->{file_password} && $file->{file_password} ne $f->{password} && !($ses->getUser && $ses->getUser->{usr_adm}))
{
$f->{msg} = 'Wrong password';
sleep 2;
&Download1;
}
}
if(!$db->SelectOne("SELECT file_id FROM IP2Files WHERE file_id=? AND ip=INET_ATON(?)",$file->{file_id},$ses->getIP))
{
$db->Exec("INSERT INTO IP2Files SET file_id=?, ip=INET_ATON(?)",$file->{file_id},$ses->getIP);
my $points = $ses->getUser && $ses->getUser->{premium} ? $c->{add_points_prem} : $c->{add_points_reg};
$points = $c->{add_points_anon} unless $ses->getUser;
$db->Exec("UPDATE Users SET usr_points=usr_points+? WHERE usr_id=?",$points,$file->{usr_id}) if $file->{usr_id} && $points;
$db->Exec("UPDATE Files SET file_downloads=file_downloads+1 WHERE file_id=?",$file->{file_id});
}
$db->Exec("REPLACE IP2Time SET ip=INET_ATON(?), time = NOW() + INTERVAL ? SECOND", $ses->getIP, int 3600*$file->{file_size}/($c->{mb_per_hour}*1048576) ) if $c->{mb_per_hour};
$file->{fsize} = $file->{file_size}<1048576 ? sprintf("%.01f Kb",$file->{file_size}/1024) : sprintf("%.01f Mb",$file->{file_size}/1048576);
if($c->{direct_links} && !$f->{down_script})
{
# Generate direct link
my $res = $ses->api($file->{srv_cgi_url},
{
op => 'gen_link',
file_id => $file->{file_id},
file_code => $file->{file_code},
file_name => $file->{file_name},
fs_key => $file->{srv_key},
ip => $ENV{REMOTE_ADDR},
});
my ($ddcode) = $res=~/^OK:(.+)$/;
unless($ddcode)
{
$ses->AdminLog("Error when creating symlink. ServerID: $file->{srv_id}. FileID:$file->{file_id}\n$res");
$ses->message("Error happened when generating Download Link.
Please try again or Contact administrator.");
}
my $link = "$file->{srv_htdocs_url}/$ddcode/$file->{file_name}";
$ses->redirect($link) if $no_checks && $ses->getUser->{usr_direct_downloads};
$ses->PrintTemplate("download2.html",
%{$file},
'direct_link' => $link,
'symlink_expire' => $c->{symlink_expire},
);
}
#my $rand = $ses->randchar(8); #rand
#my $type = {'anon'=>0,'reg'=>1,'prem'=>2}->{$utype}; #IP
#&SecSave( $file->{file_id}, $type, 0, $rand );
require HCE_MD5;
my $hce = HCE_MD5->new($c->{dl_key},"XFileSharingPRO");
my $hash = $hce->hce_block_encode_mime( "$file->{file_name}:$file->{file_id}:$file->{file_code}:$c->{down_speed}:".(time+30*60) );
$ses->redirect( "$file->{srv_cgi_url}/dl.cgi?$hash" );
}
sub News
{
my $news = $db->SelectARef("SELECT *, DATE_FORMAT(created,'%M %dth, %Y') as created_txt
FROM News
WHERE createdmakePagingSQLSuffix($f->{page}));
my $total = $db->SelectOne("SELECT COUNT(*) FROM News WHERE created{site_url} = $c->{site_url};
$_->{news_text} =~s/\n/
/gs;
}
$ses->PrintTemplate("news.html",
'news' => $news,
'paging' => $ses->makePagingLinks($f,$total),
);
}
sub Page
{
my $tmpl = shift || $f->{tmpl};
&Contact if $tmpl eq 'contact';
&Payments if $tmpl eq 'premium';
&UploadForm unless -e "Templates/Pages/$tmpl.html";
$ses->PrintTemplate("Pages/$tmpl.html");
}
sub Contact
{
my $rand = $ses->randchar(8);
my %captcha = &GenerateCaptcha("cc$rand");
&SecSave( 0, $ses->getIP(), $captcha{number}, $rand );
$f->{$_}=$ses->SecureStr($f->{$_}) for keys %$f;
$ses->PrintTemplate("Pages/contact.html",
%{$f},
%captcha,
'rand' => $rand,
);
}
sub ContactSend
{
&Page('contact') unless $ENV{REQUEST_METHOD} eq 'POST';
&Page('contact') unless &SecCheck( 0, 'cc', $ses->getIP(), $f->{'rand'}, $f->{code} );
$f->{msg}.="Email is not valid. " unless $f->{email} =~ /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
$f->{msg}.="Subject required. " unless $f->{subject};
$f->{msg}.="Message required. " unless $f->{message};
&Page('contact') if $f->{msg};
$f->{$_}=$ses->SecureStr($f->{$_}) for keys %$f;
$f->{subject} = "$c->{site_name}: $f->{subject}";
$f->{message} = "You've got new message from $c->{site_name}.\n\nName: $f->{name}\nE-mail: $f->{email}\nIP: $ENV{REMOTE_ADDR}\n\n$f->{message}";
$c->{email_text}=1;
$ses->SendMail($c->{contact_email}, $c->{email_from}, $f->{subject}, $f->{message});
$ses->redirect("$c->{site_url}/?msg=Message sent successfully");
}
sub DelFile
{
my $str = $f->{del};
my ($id,$del_id) = split('-',$str);
my $file = $db->SelectRow("SELECT * FROM Files f, Servers s
WHERE file_code=?
AND f.srv_id=s.srv_id",$id);
$ses->message('No such file exist') unless $file;
$ses->message('Server with this file is Offline') if $file->{srv_status} eq 'OFF';
unless($file->{file_del_id} eq $del_id)
{
sleep 2;
$ses->message('Wrong Delete ID')
}
if($f->{confirm} eq 'yes')
{
$ses->DeleteFile($file);
$ses->PrintTemplate("delete_file.html", 'status'=>'File deleted successfully.');
}
else
{
$ses->PrintTemplate("delete_file.html",
'confirm' =>1,
'id' => $id,
'del_id' => $del_id,
'fname' => $file->{file_name},
);
}
}
sub SecSave
{
my ($file_id,$ip,$captcha,$rand) = @_;
$db->Exec("REPLACE INTO Secure (file_id,ip,rand,captcha,time) VALUES (?,INET_ATON(?),?,?,NOW()+INTERVAL ? SECOND)",$file_id,$ip,$rand,$captcha,$c->{download_countdown});
}
sub SecCheck
{
my ($file_id,$file_code,$ip,$rand,$captcha) = @_;
$db->Exec("DELETE FROM Secure WHERE timeSelectRow("SELECT *, UNIX_TIMESTAMP()-UNIX_TIMESTAMP(time) as dt
FROM Secure
WHERE file_id=? AND ip=INET_ATON(?) AND rand=?",$file_id,$ip,$rand);
if(!$s){sleep 2;$f->{msg}="Expired session";return 0;}
$db->Exec("DELETE FROM Secure WHERE file_id=? AND ip=INET_ATON(?) AND rand=?",$file_id,$ip,$rand);
unlink("$c->{site_path}/captchas/$file_code$rand.png") if $s->{captcha} && -f "$c->{site_path}/captchas/$file_code$rand.png";
if($s->{captcha} && $s->{captcha} ne $captcha){sleep 2;$f->{msg}="Wrong captcha";return 0;}
if($f->{op}=~/download/i)
{
unless(defined $s->{file_id}){$f->{msg}="Download session expired";return 0;}
if($s->{dt}<0){$f->{msg}="Skipped countdown";return 0;}
}
##Clean old image captchas here
if($c->{captcha_mode}==1)
{
opendir(DIR, "$c->{site_path}/captchas");
foreach (readdir(DIR))
{
next if /^\.{1,2}$/;
my $file = "$c->{site_path}/captchas/$_";
unlink($file) if (time -(lstat($file))[9]) > 3600;
}
closedir DIR;
}
return 1;
}
sub GenerateCaptcha
{
my ($fname) = @_;
my ($sc,$iurl,$itext,$number);
if($c->{captcha_mode}==1)
{
eval {require SecImage;};
($iurl,$number) = &SecImage::GenerateImage($fname) unless $@;
}
elsif($c->{captcha_mode}==2)
{
require SecText;
($itext,$number) = &SecText::GenerateText;
}
return ('captcha_on'=>$c->{captcha_mode}, 'iurl' => $iurl, 'itext' => $itext, 'number' => $number);
}
sub AdminFiles
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
if($f->{del_code})
{
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
my $file = $db->SelectRow("SELECT * FROM Files WHERE file_code=?",$f->{del_code});
$ses->message("No such file") unless $file;
$ses->DeleteFile($file);
$ses->redirect("$c->{site_url}/?op=admin_files");
}
if($f->{del_selected} && $f->{file_id})
{
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
my $files = $db->SelectARef("SELECT * FROM Files WHERE file_id IN (".join(',',@{&ARef($f->{file_id})}).")");
$ses->DeleteFilesMass($files);
$ses->redirect("$c->{site_url}/?op=admin_files");
}
$f->{sort_field}||='file_created';
$f->{sort_order}||='down';
$f->{per_page}||=10;
my $filter_key = "AND (file_name LIKE '%$f->{key}%' OR file_code='$f->{key}')" if $f->{key};
my $filter_user = "AND f.usr_id='$f->{usr_id}'" if $f->{usr_id};
my $filter_server = "AND f.srv_id='$f->{srv_id}'" if $f->{srv_id}=~/^\d+$/;
my $filter_down = "AND f.file_downloads>$f->{down}" if $f->{down}=~/^\d+$/;
my $filter_ip = "AND f.file_ip=INET_ATON('$f->{ip}')" if $f->{ip}=~/^[\d\.]+$/;
my $files = $db->SelectARef("SELECT f.*, file_downloads*file_size as traffic,
INET_NTOA(file_ip) as file_ip,
u.usr_id, u.usr_login
FROM Files f
LEFT JOIN Users u ON f.usr_id = u.usr_id
WHERE 1
$filter_key
$filter_user
$filter_server
$filter_down
$filter_ip
".&makeSortSQLcode($f,'file_created').$ses->makePagingSQLSuffix($f->{page},$f->{per_page}) );
my $totals = $db->SelectRow("SELECT COUNT(*) as total_count,
SUM(file_size)/1048576 as total_size,
SUM(file_downloads) as total_downloads,
SUM(file_downloads*file_size)/1048576 as total_traffic
FROM Files f
WHERE 1
$filter_key
$filter_user
$filter_server
$filter_down
$filter_ip
");
for(@$files)
{
$_->{site_url} = $c->{site_url};
$_->{file_name2} = $_->{file_name};
$_->{file_name2}=~s/['"]//g;
$_->{file_size2} = sprintf("%.02f Mb",$_->{file_size}/1048576);
$_->{traffic} = sprintf("%.01f Mb",$_->{traffic}/1048576);
}
my %sort_hash = &makeSortHash($f,['file_name','usr_login','file_downloads','file_size','traffic','file_created']);
$ses->PrintTemplate("admin_files.html",
'files' => $files,
%{$totals},
'key' => $f->{key},
'down' => $f->{down},
"per_$f->{per_page}" => ' checked',
%sort_hash,
'paging' => $ses->makePagingLinks($f,$totals->{total_count}),
);
}
sub AdminUsers
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
if($f->{del_id})
{
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
my $files = $db->SelectARef("SELECT * FROM Files WHERE usr_id=?",$f->{del_id});
my %hash;
push( @{$hash{ $_->{srv_id} }}, $_) for @$files;
for my $srv_id (keys %hash)
{
my $list = join ':', map{"$_->{file_id}-$_->{file_code}"} @{$hash{$srv_id}};
my $res = $ses->api2($srv_id,
{
op => 'del_files',
list => $list,
}
);
unless($res=~/^OK$/)
{
$ses->AdminLog("Error when deleting file. ServerID: $srv_id. List: $list\n$res");
}
}
$ses->DeleteFileDB($_) for @$files;
$ses->DeleteUserDB($f->{del_id});
$ses->redirect("?op=admin_users");
}
if($f->{extend_premium_all})
{
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
$db->Exec("UPDATE Users SET usr_premium_expire=usr_premium_expire + INTERVAL ? DAY WHERE usr_premium_expire>=NOW()",$f->{extend_premium_all});
$ses->redirect("?op=admin_users");
}
$f->{sort_field}||='usr_created';
$f->{sort_order}||='down';
my $filter_key = "AND (usr_login LIKE '%$f->{key}%' OR usr_email LIKE '%$f->{key}%')" if $f->{key};
my $filter_prem= "AND usr_premium_expire>NOW()" if $f->{premium_only};
my $users = $db->SelectARef("SELECT u.*,
INET_NTOA(usr_lastip) as usr_ip,
COUNT(f.file_id) as files,
SUM(f.file_size) as disk_used,
UNIX_TIMESTAMP(usr_premium_expire)-UNIX_TIMESTAMP() as exp_sec,
TO_DAYS(CURDATE())-TO_DAYS(usr_lastlogin) as last_visit
FROM Users u
LEFT JOIN Files f ON u.usr_id = f.usr_id
WHERE 1
$filter_key
$filter_prem
GROUP BY usr_id
".&makeSortSQLcode($f,'usr_created').$ses->makePagingSQLSuffix($f->{page}) );
my $totals = $db->SelectRow("SELECT COUNT(*) as total_count
FROM Users f WHERE 1 $filter_key $filter_prem");
for(@$users)
{
$_->{site_url} = $c->{site_url};
$_->{disk_used} = sprintf("%.02f Mb",$_->{disk_used}/1048576);
$_->{premium} = $_->{exp_sec}>0;
substr($_->{usr_created},-3)='';
}
my %sort_hash = &makeSortHash($f,['usr_login','usr_email','files','usr_created','disk_used','last_visit']);
$ses->PrintTemplate("admin_users.html",
'users' => $users,
%{$totals},
'key' => $f->{key},
'premium_only' => $f->{premium_only},
%sort_hash,
'paging' => $ses->makePagingLinks($f,$totals->{total_count}),
);
}
sub AdminUserEdit
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
if($f->{save})
{
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
$db->Exec("UPDATE Users SET usr_login=?, usr_email=?, usr_premium_expire=?, usr_password=ENCODE(?,'$c->{pasword_salt}') WHERE usr_id=?",$f->{usr_login},$f->{usr_email},$f->{usr_premium_expire},$f->{usr_password},$f->{usr_id});
$ses->redirect("?op=admin_user_edit&usr_id=$f->{usr_id}");
}
my $user = $db->SelectRow("SELECT *, UNIX_TIMESTAMP(usr_premium_expire)-UNIX_TIMESTAMP() as exp_sec, DECODE(usr_password,'$c->{pasword_salt}') as usr_password
FROM Users WHERE usr_id=?
",$f->{usr_id});
my $transactions = $db->SelectARef("SELECT * FROM Transactions WHERE usr_id=? ORDER BY created DESC",$f->{usr_id});
$_->{site_url}=$c->{site_url} for @$transactions;
require Time::Elapsed;
my $et = new Time::Elapsed;
$ses->PrintTemplate("admin_user_form.html",
%{$user},
expire_elapsed => $user->{exp_sec}>0 ? $et->convert($user->{exp_sec}) : '',
transactions => $transactions,
);
}
sub AdminServers
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
my $servers = $db->SelectARef("SELECT s.*
FROM Servers s
ORDER BY srv_created
");
for(@$servers)
{
$_->{srv_disk_percent} = sprintf("%.01f",100*$_->{srv_disk}/$_->{srv_disk_max});
$_->{srv_disk} = sprintf("%.01f",$_->{srv_disk}/1073741824);
$_->{srv_disk_max} = int $_->{srv_disk_max}/1073741824;
}
$ses->PrintTemplate("admin_servers.html",
'servers' => $servers,
);
}
sub AdminServerAdd
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
my $server;
if($f->{srv_id})
{
$server = $db->SelectRow("SELECT * FROM Servers WHERE srv_id=?",$f->{srv_id});
$server->{srv_disk_max}/=1024*1024*1024;
$server->{"s_$server->{srv_status}"}=' selected';
}
elsif(!$db->SelectOne("SELECT srv_id FROM Servers LIMIT 1"))
{
$server->{srv_cgi_url} = $c->{site_cgi};
$server->{srv_htdocs_url} = "$c->{site_url}/files";
}
$ses->PrintTemplate("admin_server_form.html",
%{$server},
);
}
sub AdminServerSave
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
my (@tests,@arr);
my $allow_save=1;
my $ua = LWP::UserAgent->new(timeout => 15);
$f->{srv_cgi_url}=~s/\/$//;
$f->{srv_htdocs_url}=~s/\/$//;
$ses->message("Server with same cgi-bin URL / htdocs URL already exist in DB") if !$f->{srv_id} && $db->SelectOne("SELECT srv_id FROM Servers WHERE srv_cgi_url=? OR srv_htdocs_url=?",$f->{srv_cgi_url},$f->{srv_htdocs_url});
# max disk usage
push @tests, 'max disk usage: ERROR' if !$f->{srv_disk_max} || $f->{srv_disk_max}<=0;
if($f->{srv_id})
{
$f->{srv_disk_max}*=1024*1024*1024;
my @sflds = qw(srv_name srv_cgi_url srv_htdocs_url srv_disk_max srv_status srv_key);
my @dat = map{$f->{$_}}@sflds;
push @dat, $f->{srv_id};
$db->Exec("UPDATE Servers SET ".join(',',map{"$_=?"}@sflds)." WHERE srv_id=?", @dat );
$c->{srv_status} = $f->{srv_status};
my $data = join('~',map{"$_:$c->{$_}"}qw(site_url site_cgi max_upload_files max_upload_size max_upload_filesize ext_allowed ext_not_allowed ip_not_allowed srv_status));
$ses->api2($f->{srv_id},{op=>'update_conf',data=>$data});
}
my $fs_key = $db->SelectOne("SELECT srv_key FROM Servers WHERE srv_id=?",$f->{srv_id}) if $f->{srv_id};
# api.cgi multiple tests
my $res = $ses->api($f->{srv_cgi_url}, {op => 'test', fs_key=>$fs_key, site_cgi=>$c->{site_cgi}} );
if($res=~/^OK/)
{
push @tests, 'api.cgi: OK';
$res=~s/^OK:(.*?)://;
$f->{srv_ip} = $1;
push @tests, split(/\|/,$res);
}
else
{
push @tests, "api.cgi: ERROR";
}
# upload.cgi
my $res = $ua->get("$f->{srv_cgi_url}/upload.cgi?mode=test");
push @tests, $res->content eq 'XFS' ? 'upload.cgi: OK' : "upload.cgi: ERROR (problems with link)";
# upload_status.cgi
my $res = $ua->get("$f->{srv_cgi_url}/upload_status.cgi?mode=test");
push @tests, $res->content eq 'XFS' ? 'upload_status.cgi: OK' : "upload_status.cgi: ERROR (problems with link)";
# htdocs URL accessibility
my $res = $ua->get("$f->{srv_htdocs_url}/index.html");
push @tests, $res->content eq 'XFS' ? 'htdocs URL accessibility: OK' : "htdocs URL accessibility: ERROR (should see XFS on link)";
for(@tests)
{
$allow_save=0 if /ERROR/;
push @arr, {'text' => $_,
'class'=> /ERROR/ ? 'err' : 'ok'
};
}
unless($allow_save)
{
$ses->PrintTemplate("admin_server_form.html",
'tests' => \@arr,
%{$f},
"s_$f->{srv_status}" => ' selected',
);
}
unless($f->{srv_id})
{
$f->{srv_key} = $c->{fs_key} = $ses->randchar(8);
$f->{srv_disk_max}*=1024*1024*1024;
$c->{srv_status} = $f->{srv_status};
my @sflds = qw(srv_name srv_ip srv_cgi_url srv_htdocs_url srv_key srv_disk_max srv_status);
$db->Exec("INSERT INTO Servers SET srv_created=CURDATE(), ".join(',',map{"$_=?"}@sflds), map{$f->{$_}}@sflds );
my $data = join('~',map{"$_:$c->{$_}"}qw(fs_key site_url site_cgi max_upload_files max_upload_size max_upload_filesize ext_allowed ext_not_allowed ip_not_allowed srv_status));
my $res = $ses->api($f->{srv_cgi_url},{op=>'update_conf',data=>$data});
$ses->message("Server created. But was unable to update FS config.
Probably fs_key was not epty. Update fs_key manually and save Site Settings to sync.") unless $res eq 'OK';
}
$ses->redirect('?op=admin_servers');
}
sub AdminCheckConsistancy
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
$|++;
print"Content-type:text/html\n\n";
print"Starting consistancy check...
";
my $servers = $db->SelectARef("SELECT * FROM Servers WHERE srv_status<>'OFF' ");
my $deleted_db=0;
for my $s (@$servers)
{
print"Server $s->{srv_name} (ID=$s->{srv_id})
";
my $cx=0;
while( my $files=$db->Select("SELECT file_id,file_code FROM Files WHERE srv_id=? LIMIT $cx,100",$s->{srv_id}) )
{
$cx+=100;
$files=&ARef($files);
my $list = join ':', map{ "$_->{file_id}-$_->{file_code}" } @$files;
my $res = $ses->api($s->{srv_cgi_url},
{
fs_key => $s->{srv_key},
op => 'check_files',
list => $list,
}
);
$ses->AdminLog("Error when requesting API.
$res") unless $res=~/^OK/;
my ($codes) = $res=~/^OK:(.*)$/;
for my $code ( split(/\,/,$codes) )
{
my $file = $db->SelectRow("SELECT * FROM Files WHERE file_code=?",$code);
$ses->DeleteFileDB($file);
print"x";
$deleted_db++;
}
print"+";
}
print"
Found & fixed bad files1: $deleted_db";
print"
Reverse test:";
my $res = $ses->api($s->{srv_cgi_url},
{
fs_key => $s->{srv_key},
op => 'check_files_reverse',
}
);
$ses->AdminLog("Error when requesting API check_files_reverse.
$res") unless $res=~/^OK:/;
$res=~/^OK:(.*)$/ ? print" OK. Found & fixed bad files2: $1
" : print" Error: $res";
print"
";
}
print"DONE.
Back to site";
print"";
}
sub AdminUpdateServerStats
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
my $servers = $db->SelectARef("SELECT * FROM Servers WHERE srv_status<>'OFF' ");
for my $s (@$servers)
{
my $res = $ses->api($s->{srv_cgi_url},
{
fs_key => $s->{srv_key},
op => 'get_file_stats',
}
);
$ses->message("Error when requesting API.
$res") unless $res=~/^OK/;
my ($files,$size) = $res=~/^OK:(\d+):(\d+)$/;
$ses->message("Invalid files,size values: ($files)($size)") unless $files=~/^\d+$/ && $size=~/^\d+$/;
$db->Exec("UPDATE Servers SET srv_files=?, srv_disk=? WHERE srv_id=?",$files,$size,$s->{srv_id});
}
$ses->redirect('?op=admin_servers');
}
sub AdminServerImport
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
if($f->{'import'})
{
my $res = $ses->api2($f->{srv_id},{op=>'import_list_do','usr_id'=>$ses->getUserId});
$ses->message("Error happened: $res") unless $res=~/^OK/;
$res=~/^OK:(\d+)/;
$ses->message("$1 files were completely imported to system");
}
my $res = $ses->api2($f->{srv_id},{op=>'import_list'});
$ses->message("Error when requesting API.
$res") unless $res=~/^OK/;
my ($data) = $res=~/^OK:(.*)$/;
my @files;
for(split(/:/,$data))
{
/^(.+?)\-(\d+)$/;
push @files, {name=>$1,size=>sprintf("%.02f Mb",$2/1048576)};
}
$ses->PrintTemplate("admin_server_import.html",
'files' => \@files,
'srv_id' => $f->{srv_id},
);
}
sub AdminServerDelete
{
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
if($f->{password})
{
$f->{login}=$ses->getUser->{usr_login};
$ses->message("Wrong password") unless $ses->Login('no_redirect');
}
else
{
$ses->PrintTemplate("confirm_password.html",
'msg'=>"Delete File Server and all files on it?",
'btn'=>"DELETE",
'op'=>'admin_server_del',
'id'=>$f->{srv_id});
}
my $srv = $db->SelectRow("SELECT * FROM Servers WHERE srv_id=?",$f->{id});
$ses->message("No such server") unless $srv;
my $res = $ses->api($srv->{srv_cgi_url},
{
fs_key => $srv->{srv_key},
op => 'expire_sym',
hours => 0,
}
);
my $files = $db->SelectARef("SELECT * FROM Files WHERE srv_id=?",$srv->{srv_id});
my $list = join ':', map{"$_->{file_id}-$_->{file_code}"} @$files;
my $res = $ses->api($srv->{srv_cgi_url},
{
fs_key => $srv->{srv_key},
op => 'del_files',
list => $list,
}
);
$ses->message("Error when deleting files. ServerID: $srv->{srv_id}.
$res")
unless $res=~/^OK$/;
$ses->DeleteFileDB($_) for @$files;
$db->Exec("DELETE FROM Servers WHERE srv_id=?",$srv->{srv_id});
$ses->redirect('?op=admin_servers');
}
sub AdminSettings
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
if($f->{save})
{
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
my @fields = qw(license_key
site_name
files_expire_created
files_expire_access
enable_file_descr
ext_allowed
ext_not_allowed
ip_not_allowed
fnames_not_allowed
captcha_mode
email_from
contact_email
abuse_email
symlink_expire
items_per_page
payment_plans
business
item_name
link_format
enable_catalogue
points_convert_min
points_convert_days
add_points_anon
add_points_reg
add_points_prem
pre_download_page
enabled_anon
max_upload_files_anon
max_upload_size_anon
max_upload_filesize_anon
max_downloads_number_anon
download_countdown_anon
captcha_anon
ads_anon
mb_per_hour_anon
remote_url_anon
direct_links_anon
down_speed_anon
enabled_reg
max_upload_files_reg
max_upload_size_reg
max_upload_filesize_reg
max_downloads_number_reg
download_countdown_reg
captcha_reg
ads_reg
mb_per_hour_reg
remote_url_reg
direct_links_reg
down_speed_reg
enabled_prem
max_upload_files_prem
max_upload_size_prem
max_upload_filesize_prem
max_downloads_number_prem
download_countdown_prem
captcha_prem
ads_prem
mb_per_hour_prem
remote_url_prem
direct_links_prem
down_speed_prem
);
$f->{payment_plans}=~s/\s//gs;
$f->{item_name} = $ses->{cgi_query}->escape($f->{item_name});
my $conf;
open(F,"XFileConfig.pm")||$ses->message("Can't read XFileConfig");
$conf.=$_ while ;
close F;
$f->{ip_not_allowed}=~s/\r//gs;
my @ips=grep{/^[\d\.]+$/}split(/\n/,$f->{ip_not_allowed});
if($#ips>-1 && open(F,"$c->{site_path}/.htaccess"))
{
my @arr=;
@arr=grep{$_!~/deny from/i}@arr;
unshift @arr,"deny from $_\n" for @ips;
close F;
if( open(F,">$c->{site_path}/.htaccess") )
{
print F @arr;
close F;
}
}
$f->{ip_not_allowed}=~s/\n/|/gs;
$f->{ip_not_allowed}=~s/\*/\\d+/gs;
$f->{ip_not_allowed}="^($f->{ip_not_allowed})\$" if $f->{ip_not_allowed};
$f->{fnames_not_allowed}=~s/\r//gs;
$f->{fnames_not_allowed}=~s/\n/|/gs;
$f->{fnames_not_allowed}="($f->{fnames_not_allowed})" if $f->{fnames_not_allowed};
for my $x (@fields)
{
my $val = $f->{$x};
$conf=~s/$x\s*=>\s*('.*?')\s*,/"$x => '$val',"/e;
}
open(F,">XFileConfig.pm")||$ses->message("Can't write XFileConfig");
print F $conf;
close F;
$f->{site_url}=$c->{site_url};
$f->{site_cgi}=$c->{site_cgi};
$f->{dl_key} =$c->{dl_key};
my @fields_fs = qw(site_url
site_cgi
ext_allowed
ext_not_allowed
ip_not_allowed
dl_key
enabled_anon
max_upload_files_anon
max_upload_size_anon
max_upload_filesize_anon
remote_url_anon
enabled_reg
max_upload_files_reg
max_upload_size_reg
max_upload_filesize_reg
remote_url_reg
enabled_prem
max_upload_files_prem
max_upload_size_prem
max_upload_filesize_prem
remote_url_prem
);
my $data = join('~',map{"$_:$f->{$_}"}@fields_fs);
my $servers = $db->SelectARef("SELECT * FROM Servers");
$|++;
print"Content-type:text/html\n\nHave ".($#$servers+1)." servers to update.
";
my $failed=0;
for(@$servers)
{
print"ID=$_->{srv_id} $_->{srv_name}...";
my $res = $ses->api($_->{srv_cgi_url},{ fs_key=>$_->{srv_key}, op=>'update_conf', data=>$data });
if($res eq 'OK')
{
print"OK
";
}
else
{
print"FAILED!
";
$failed++;
}
#$ses->message("Can't update config for server ID: $_->{srv_id}:$res") unless $res eq 'OK';
}
print"
Done.
$failed servers failed to update.
Back to Site Settings";
print"" unless $failed;
print"";
exit;
#print $ses->redirect('?op=admin_settings');
}
$c->{ip_not_allowed}=~s/[\^\(\)\$\\]//g;
$c->{ip_not_allowed}=~s/\|/\n/g;
$c->{ip_not_allowed}=~s/d\+/*/g;
$c->{fnames_not_allowed}=~s/[\^\(\)\$\\]//g;
$c->{fnames_not_allowed}=~s/\|/\n/g;
$c->{"link_format$c->{link_format}"}=' selected';
#push @{$f->{cookies}}, cookie(-name=>'admhash',-value=>$passcook,-expire=>'+30m');
$ses->PrintTemplate("admin_settings.html",
%{$c},
"captcha_$c->{captcha_mode}" => ' checked',
'business' => $c->{paypal}->{business},
'item_name' => $ses->{cgi_query}->unescape($c->{paypal}->{item_name}),
);
}
sub MyAccount
{
if($f->{pass_change})
{
$ses->message("Wrong current password") unless $db->SelectOne("SELECT usr_id FROM Users WHERE usr_id=? AND usr_password=ENCODE(?,?)", $ses->getUserId, $f->{password}, $c->{pasword_salt} );
$ses->message("New password is too short") if length($f->{password_new})<4;
$ses->message("New passwords do not match") unless $f->{password_new} eq $f->{password_new2};
$db->Exec("UPDATE Users SET usr_password=ENCODE(?,?) WHERE usr_id=?", $f->{password_new}, $c->{pasword_salt}, $ses->getUserId );
$f->{msg}="Password changed successfully.";
}
if($f->{email_change})
{
$ses->message("Wrong current password") unless $db->SelectOne("SELECT usr_id FROM Users WHERE usr_id=? AND usr_password=ENCODE(?,?)", $ses->getUserId, $f->{password}, $c->{pasword_salt} );
$ses->message("This email already in use") if $db->SelectOne("SELECT usr_id FROM Users WHERE usr_id<>? AND usr_email=?", $ses->getUserId, $f->{email_new} );
$ses->message("Error: Invalid e-mail") unless $f->{email_new}=~/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
$db->Exec("UPDATE Users SET usr_email=? WHERE usr_id=?", $f->{email_new}, $ses->getUserId );
$f->{msg}="E-mail changed successfully.";
}
if($f->{settings_save})
{
$db->Exec("UPDATE Users
SET usr_add_login=?,
usr_public=?,
usr_direct_downloads=?,
usr_rapid_login=?,
usr_rapid_pass=?
WHERE usr_id=?",$f->{usr_add_login},$f->{usr_public},$f->{usr_direct_downloads},$f->{usr_rapid_login},$f->{usr_rapid_pass},$ses->getUserId);
$f->{msg}="Settings saved successfully.";
}
$ses->CheckAuth();
my $premium_expire = $db->SelectOne("SELECT DATE_FORMAT(usr_premium_expire,'%e %M %Y') FROM Users WHERE usr_id=?",$ses->getUserId);
$ses->PrintTemplate("my_account.html",
%{$ses->getUser},
'msg' => $f->{msg},
'remote_url' => $c->{remote_url},
'premium_expire' => $premium_expire,
);
}
sub MyFiles
{
if($f->{del_code})
{
my $file = $db->SelectRow("SELECT * FROM Files WHERE file_code=? AND usr_id=?",$f->{del_code},$ses->getUserId);
$ses->message("Security error: not_owner") unless $file;
$ses->DeleteFile($file);
$ses->redirect("?op=my_files");
}
if($f->{del_selected} && $f->{file_id})
{
my $files = $db->SelectARef("SELECT * FROM Files WHERE usr_id=? AND file_id IN (".join(',',@{&ARef($f->{file_id})}).")",$ses->getUserId);
$ses->DeleteFilesMass($files);
$ses->redirect("$c->{site_url}/?op=my_files");
}
if($f->{set_public})
{
$db->SelectARef("UPDATE Files SET file_public=1 WHERE usr_id=? AND file_id IN (".join(',',@{&ARef($f->{file_id})}).")",$ses->getUserId);
$ses->redirect("$c->{site_url}/?op=my_files");
}
if($f->{set_private})
{
$db->SelectARef("UPDATE Files SET file_public=0 WHERE usr_id=? AND file_id IN (".join(',',@{&ARef($f->{file_id})}).")",$ses->getUserId);
$ses->redirect("$c->{site_url}/?op=my_files");
}
if($f->{folder} && $f->{file_id})
{
$f->{folder}=$f->{folder_new} if $f->{folder} eq '|';
$f->{folder}='' if $f->{folder} eq '/';
$f->{folder}=~s/[^a-zA-Z0-9-_\.]/_/gs;
$f->{folder}=substr($f->{folder},0,64) if length($f->{folder})>64;
$db->Exec("UPDATE Files SET file_folder=? WHERE usr_id=? AND file_id IN (".join(',',@{&ARef($f->{file_id})}).")",$f->{folder},$ses->getUserId);
$ses->redirect("$c->{site_url}/?op=my_files");
}
$f->{fld}='' if !$f->{fld} || $f->{fld} eq '/';
my ($files,$total,$folders);
if($f->{key})
{
$files = $db->SelectARef("SELECT *, DATE(file_created) as created
FROM Files
WHERE usr_id=?
AND (file_name LIKE CONCAT('%',?,'%') OR file_descr LIKE CONCAT('%',?,'%'))
ORDER BY file_created DESC".$ses->makePagingSQLSuffix($f->{page}),$ses->getUserId,$f->{key},$f->{key});
$total = $db->SelectOne("SELECT COUNT(*) FROM Files WHERE usr_id=? AND (file_name LIKE CONCAT('%',?,'%') OR file_descr LIKE CONCAT('%',?,'%'))",$ses->getUserId,$f->{key},$f->{key});
}
else
{
$files = $db->SelectARef("SELECT *, DATE(file_created) as created
FROM Files
WHERE usr_id=?
AND file_folder=?
ORDER BY file_created DESC".$ses->makePagingSQLSuffix($f->{page}),$ses->getUserId,$f->{fld});
$total = $db->SelectOne("SELECT COUNT(*) FROM Files WHERE usr_id=? AND file_folder=?",$ses->getUserId,$f->{fld});
$folders = $db->SelectARef("SELECT file_folder, COUNT(*) as files
FROM Files
WHERE usr_id=?
AND file_folder<>''
GROUP BY file_folder
ORDER BY file_folder",$ses->getUserId);
}
my $totals = $db->SelectRow("SELECT COUNT(*) as total_files, SUM(file_size) as total_size FROM Files WHERE usr_id=?",$ses->getUserId);
$totals->{total_size} = $totals->{total_size}<1048576 ? sprintf("%.01f Kb",$totals->{total_size}/1024) : sprintf("%.01f Mb",$totals->{total_size}/1048576);
for(@$folders)
{
$_->{file_folder}||='/';
$_->{site_url} = $c->{site_url};
}
for(@$files)
{
$_->{site_url} = $c->{site_url};
$_->{file_size} = $_->{file_size}<1048576 ? sprintf("%.01f Kb",$_->{file_size}/1024) : sprintf("%.01f Mb",$_->{file_size}/1048576);
$_->{file_descr} = substr($_->{file_descr},0,35).'
' if length($_->{file_descr})>35;
}
$ses->PrintTemplate("my_files.html",
'files' => $files,
'folders' => $folders,
'fld' => $f->{fld},
'key' => $f->{key},
%{$totals},
'paging' => $ses->makePagingLinks($f,$total),
);
}
sub MyFilesExport
{
my $filter_folder="AND file_folder='$f->{fld}' " if defined($f->{fld}) && $f->{fld}=~/^[a-zA-Z0-9-_\.]*$/;
my $list = $db->SelectARef("SELECT * FROM Files WHERE usr_id=? $filter_folder",$ses->getUserId);
print"Content-type:text/plain\n\n";
for my $file (@$list)
{
$file->{file_code} = $ses->getUser->{usr_login}."/$file->{file_code}" if $ses->getUser->{usr_add_login};
$file->{download_link} = "$c->{site_url}/$file->{file_code}";
$file->{download_link} .= {0 => "/$file->{file_name}.html",
1 => "/$file->{file_name}.htm",
2 => "/$file->{file_name}",
3 => ".html",
4 => ".htm"
}->{$c->{link_format}};
print"$file->{download_link}\n";
}
exit;
}
sub FileEdit
{
my $file = $db->SelectRow("SELECT * FROM Files WHERE file_code=?",$f->{file_code});
$ses->message("No such file!") unless $file;
$ses->message("It's not your file!") if !$ses->getUser->{usr_adm} && $file->{usr_id}!=$ses->getUserId;
if($f->{save})
{
$f->{file_name}=~s/[^a-zA-Z0-9-_\.]/_/gs;
$f->{file_descr} = $ses->SecureStr($f->{file_descr});
$f->{file_password} = $ses->SecureStr($f->{file_password});
$ses->message("Filename too short") if length($f->{file_name})<3;
$db->Exec("UPDATE Files SET file_name=?, file_descr=?, file_public=?, file_folder=?, file_password=? WHERE file_code=?",$f->{file_name},$f->{file_descr},$f->{file_public},$f->{file_folder},$f->{file_password},$f->{file_code});
$ses->redirect("?op=my_files");
}
$ses->PrintTemplate("file_form.html", %{$file} );
}
sub UserPublic
{
my $user = $db->SelectRow("SELECT * FROM Users WHERE usr_login=?",$f->{usr_login});
$ses->message("No such user exist") unless $user;
$ses->message("This user doesn't allow file listing") unless $user->{usr_public};
$f->{fld}=~s/\///g;
my $files = $db->SelectARef("SELECT *, DATE(file_created) as created
FROM Files
WHERE usr_id=?
AND file_public=1
AND file_folder=?
ORDER BY file_created DESC",$user->{usr_id},$f->{fld});
my $folders = $db->SelectARef("SELECT file_folder, COUNT(*) as files
FROM Files
WHERE usr_id=?
AND file_public=1
AND file_folder<>''
GROUP BY file_folder
ORDER BY file_folder",$user->{usr_id});
for(@$files)
{
$_->{file_code} = "$user->{usr_login}/$_->{file_code}" if $user->{usr_add_login};
$_->{site_url} = $c->{site_url};
$_->{file_size} = $_->{file_size}<1048576 ? sprintf("%.01f Kb",$_->{file_size}/1024) : sprintf("%.01f Mb",$_->{file_size}/1048576);
}
for(@$folders)
{
$_->{file_folder}||='/';
$_->{site_url} = $c->{site_url};
$_->{usr_login} = $f->{usr_login};
}
$ses->PrintTemplate("user_public.html",
'login' => $user->{usr_login},
'folders' => $folders,
'fld' => $f->{fld},
files => $files );
}
sub Payments
{
$ses->redirect($c->{site_url}) unless $c->{enabled_prem};
if($f->{amount})
{
$f->{amount}=sprintf("%.02f",$f->{amount});
my $id = $ses->randchar(10);
my $usr_id = $ses->getUser ? $ses->getUserId : 0;
$db->Exec("INSERT INTO Transactions SET id=?, usr_id=?, amount=?, ip=INET_ATON(?), created=NOW()",$id,$usr_id,$f->{amount},$ses->getIP);
$c->{paypal}->{'return'} = $c->{site_url}."/?payment_complete=$id";
$c->{paypal}->{'cancel_return'} = $c->{site_url};
$c->{paypal}->{'notify_url'} = "$c->{site_cgi}/ipn.cgi";
my $url = $c->{paypalUrl}.'?'.join('&', map {"$_=$c->{paypal}->{$_}"} keys %{$c->{paypal}} );
$url .= "&custom=$id&amount=$f->{amount}";
$ses->redirect($url);
}
my @arr = split(/,/,$c->{payment_plans});
my @plans;
for(@arr)
{
/([\d\.]+)=(\d+)/;
push @plans, { amount=>$1, days=>$2, site_url=>$c->{site_url} };
}
for('max_upload_size_prem','max_upload_size_reg','max_upload_filesize_prem','max_upload_filesize_reg')
{
$c->{$_} = $c->{$_} ? "$c->{$_} Mb" : "No limits";
}
$c->{captcha_reg} = 'yes' if $c->{captcha_reg};
$c->{captcha_prem} = 'yes' if $c->{captcha_prem};
$c->{download_countdown_reg} = $c->{download_countdown_reg} ? "$c->{download_countdown_reg} seconds" : '';
$c->{download_countdown_prem} = $c->{download_countdown_prem} ? "$c->{download_countdown_prem} seconds" : '';
$c->{max_downloads_number_reg}||='Unlimited';
$c->{max_downloads_number_prem}||='Unlimited';
require Time::Elapsed;
my $et = new Time::Elapsed;
$ses->PrintTemplate("payments.html",
%{$c},
plans => \@plans,
premium => $ses->getUser && $ses->getUser->{premium},
expire_elapsed => $ses->getUser && $et->convert($ses->getUser->{exp_sec}),
);
}
sub PaymentComplete
{
my $id = shift;
my $trans = $db->SelectRow("SELECT *, INET_NTOA(ip) as ip, (UNIX_TIMESTAMP()-UNIX_TIMESTAMP(created)) as dt
FROM Transactions
WHERE id=?",$id) if $id;
$ses->message("No such transaction exist") unless $trans;
$ses->message("Internal error") unless $trans->{ip} eq $ENV{REMOTE_ADDR};
$ses->message("Your account created successfully.
Please check your e-mail for login details") if $trans->{dt}>3600;
$ses->message("Your payment have not verified yet.
Please refresh this page in 1-3 minutes") unless $trans->{verified};
my $user = $db->SelectRow("SELECT *, DECODE(usr_password,?) as usr_password FROM Users WHERE usr_id=?",$c->{pasword_salt},$trans->{usr_id});
$ses->message("Your account created successfully!
Login: $user->{usr_login}
Password: $user->{usr_password}")
}
sub AdminUsersAdd
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
my ($list,$result);
if($f->{generate})
{
my @arr;
$f->{prem_days}||=0;
for(1..$f->{num})
{
my $login = join '', map int rand 10, 1..7;
while($db->SelectOne("SELECT usr_id FROM Users WHERE usr_login=?",$login)){ $login = join '', map int rand 10, 1..7; }
my $password = $ses->randchar(10);
push @arr, "$login:$password:$f->{prem_days}";
}
$list = join "\n", @arr;
}
if($f->{create} && $f->{list})
{
my @arr;
$f->{list}=~s/\r//gs;
for( split /\n/, $f->{list} )
{
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
my ($login,$password,$days) = /^(\w+):(\w+):(\d+)$/;
next unless $login && $password;
push(@arr, "$login:$password:$days - ERROR:login already exist"),next if $db->SelectOne("SELECT usr_id FROM Users WHERE usr_login=?",$login);
$db->Exec("INSERT INTO Users (usr_login,usr_password,usr_created,usr_premium_expire) VALUES (?,ENCODE(?,?),NOW(),NOW()+INTERVAL ? DAY)",$login,$password,$c->{pasword_salt},$days);
push @arr, "$login:$password:$days";
}
$result = join "
", @arr;
}
$ses->PrintTemplate("admin_users_add.html",
'list' => $list,
'result' => $result,
);
}
sub AdminNews
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
if($f->{del_id})
{
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
$db->Exec("DELETE FROM News WHERE news_id=?",$f->{del_id});
$ses->redirect('?op=admin_news');
}
my $news = $db->SelectARef("SELECT * FROM News ORDER BY created DESC".$ses->makePagingSQLSuffix($f->{page}));
my $total = $db->SelectOne("SELECT COUNT(*) FROM News");
for(@$news)
{
$_->{site_url} = $c->{site_url};
}
$ses->PrintTemplate("admin_news.html",
'news' => $news,
'paging' => $ses->makePagingLinks($f,$total),
);
}
sub AdminNewsEdit
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
if($f->{save})
{
$ses->message("Not allowed in Demo mode") if $c->{demo_mode};
if($f->{news_id})
{
$db->Exec("UPDATE News SET news_title=?, news_text=?, created=? WHERE news_id=?",$f->{news_title},$f->{news_text},$f->{created},$f->{news_id});
}
else
{
$db->Exec("INSERT INTO News SET news_title=?, news_text=?, created=?",$f->{news_title},$f->{news_text},$f->{created},$f->{news_id});
}
$ses->redirect('?op=admin_news');
}
my $news = $db->SelectRow("SELECT * FROM News WHERE news_id=?",$f->{news_id});
$news->{created}||=sprintf("%d-%02d-%02d %02d:%02d:%02d", $ses->getTime() );
$ses->PrintTemplate("admin_news_form.html",
%{$news},
);
}
sub CheckFiles
{
sleep 1;
my @arr;
$f->{list}=~s/\r//gs;
my ($i,@arr);
for( split /\n/, $f->{list} )
{
$i++;
my ($code,$fname) = /\/(\w{12})\/(.+?)(\.html|)$/;
next unless $code && $fname;
my $fn = $fname;
$fn=~s/\.html$//i;
my $file = $db->SelectRow("SELECT f.file_id,s.srv_status FROM Files f, Servers s WHERE f.file_code=? AND file_name=? AND s.srv_id=f.srv_id",$code,$fn);
push(@arr,"$_ not found!"),next unless $file;
push(@arr,"$_ exist but not available at the moment!"),next if $file->{srv_status} eq 'OFF';
push(@arr,"$_ found");
}
$ses->PrintTemplate("Pages/checkfiles.html",
'result' => join "
", @arr,
);
}
sub Catalogue
{
$ses->redirect($c->{site_url}) unless $c->{enable_catalogue};
my $list = $db->SelectARef("SELECT f.*, TO_DAYS(NOW())-TO_DAYS(file_created) as added, u.usr_login
FROM Files f
LEFT JOIN Users u ON f.usr_id=u.usr_id
WHERE file_public=1
ORDER BY file_created DESC".$ses->makePagingSQLSuffix($f->{page}) );
my $total = $db->SelectOne("SELECT COUNT(*) FROM Files WHERE file_public=1");
my $paging = $ses->makePagingLinks($f,$total);
$paging=~s/\?op=catalogue\&page=(\d+)/latest-files$1.html/g;
for my $file (@$list)
{
$file->{site_url} = $c->{site_url};
$file->{fsize} = $file->{file_size}<1048576 ? sprintf("%.01f Kb",$file->{file_size}/1024) : sprintf("%.01f Mb",$file->{file_size}/1048576);
$file->{added} = $file->{added} ? "$file->{added} days ago" : "Today";
}
$ses->PrintTemplate("catalogue.html",
'files' => $list,
'paging' => $paging,
);
}
sub ConvertPoints
{
if($f->{convert_ext_acc})
{
$ses->message("You need at least $c->{points_convert_min} points.") if $ses->getUser->{usr_points}<$c->{points_convert_min};
$db->Exec("UPDATE Users SET usr_points=usr_points-?, usr_premium_expire=usr_premium_expire+INTERVAL ? DAY WHERE usr_id=?",$c->{points_convert_min},$c->{points_convert_days},$ses->getUserId);
$ses->redirect("$c->{site_url}/?op=my_account");
}
if($f->{convert_new_acc})
{
$ses->message("You need at least $c->{points_convert_min} points.") if $ses->getUser->{usr_points}<$c->{points_convert_min};
my $login = join '', map int rand 10, 1..7;
while($db->SelectOne("SELECT usr_id FROM Users WHERE usr_login=?",$login)){ $login = join '', map int rand 10, 1..7; }
my $password = $ses->randchar(10);
$db->Exec("INSERT INTO Users (usr_login,usr_password,usr_created,usr_premium_expire) VALUES (?,ENCODE(?,?),NOW(),NOW()+INTERVAL ? DAY)",$login,$password,$c->{pasword_salt},$c->{points_convert_days});
$db->Exec("UPDATE Users SET usr_points=usr_points-? WHERE usr_id=?",$c->{points_convert_min},$ses->getUserId);
$ses->PrintTemplate("convert_points.html",
'points' => $ses->getUser->{usr_points}-$c->{points_convert_min},
'generated_login' => $login,
'generated_password' => $password,
);
}
$ses->PrintTemplate("convert_points.html",
'points' => $ses->getUser->{usr_points},
'points_convert_days' => $c->{points_convert_days},
'points_convert_min' => $c->{points_convert_min},
);
}
sub ReportFile
{
my $file = $db->SelectRow("SELECT * FROM Files WHERE file_code=?",$f->{id});
$ses->message("No such file") unless $file;
my $rand = $ses->randchar(8);
my %captcha = &GenerateCaptcha("cc$rand");
&SecSave( 0, $ses->getIP(), $captcha{number}, $rand );
$f->{$_}=$ses->SecureStr($f->{$_}) for keys %$f;
$ses->PrintTemplate("report_file.html",
%{$f},
%captcha,
'rand' => $rand,
'file_name' => $file->{file_name},
'ip' => $ses->getIP(),
);
}
sub ReportFileSend
{
&ReportFile unless $ENV{REQUEST_METHOD} eq 'POST';
&ReportFile unless &SecCheck( 0, 'cc', $ses->getIP(), $f->{'rand'}, $f->{code} );
my $file = $db->SelectRow("SELECT * FROM Files WHERE file_code=?",$f->{id});
$ses->message("No such file") unless $file;
$f->{msg}.="Email is not valid. " unless $f->{email} =~ /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
$f->{msg}.="Name required. " unless $f->{name};
$f->{msg}.="Message required. " unless $f->{message};
&ReportFile if $f->{msg};
$f->{message}.="\nReason: $f->{reason}";
$f->{$_}=$ses->SecureStr($f->{$_}) for keys %$f;
$db->Exec("INSERT INTO Reports SET file_id=?, usr_id=?, filename=?, name=?, email=?, info=?, ip=INET_ATON(?), status='PENDING', created=NOW()",
$file->{file_id}, $file->{usr_id}, $file->{file_name}, $f->{name}, $f->{email}, $f->{message}, $ses->getIP() );
$f->{subject} = "$c->{site_name}: File reported";
$f->{message} = "File was reported on $c->{site_name}.\n\nFilename: $file->{file_name}\n\nName: $f->{name}\nE-mail: $f->{email}\nIP: $ENV{REMOTE_ADDR}\n\n$f->{message}";
$c->{email_text}=1;
$ses->SendMail($c->{contact_email}, $c->{email_from}, $f->{subject}, $f->{message});
$ses->redirect("$c->{site_url}/?msg=Report sent successfully");
}
sub AdminReports
{
$ses->redirect($c->{site_url}) unless $ses->getUser->{usr_adm};
if($f->{report_hide})
{
$db->Exec("UPDATE Reports SET status='DECLINED' WHERE id=?",$f->{report_hide});
$ses->redirect("$c->{site_url}/?op=admin_reports");
}
if($f->{nuke_file_id})
{
$db->Exec("UPDATE Reports SET status='APPROVED' WHERE file_id=?",$f->{nuke_file_id});
my $file = $db->SelectRow("SELECT * FROM Files WHERE file_id=?",$f->{nuke_file_id});
$ses->DeleteFile($file);
$ses->redirect("$c->{site_url}/?op=admin_reports");
}
my $filter_status = $f->{history} ? "WHERE status<>'PENDING'" : "WHERE status='PENDING'";
my $list = $db->SelectARef("SELECT r.*, f.*, INET_NTOA(ip) as ip,
(SELECT u.usr_login FROM Users u WHERE r.usr_id=u.usr_id) as usr_login
FROM Reports r
LEFT JOIN Files f ON r.file_id = f.file_id
$filter_status
ORDER BY r.created DESC");
for(@$list)
{
$_->{site_url} = $c->{site_url};
$_->{file_size2} = sprintf("%.02f Mb",$_->{file_size}/1048576);
$_->{info} =~ s/\n/
/gs;
$_->{"status_$_->{status}"}=1;
}
$ses->PrintTemplate("admin_reports.html",'list' => $list);
}
###
sub ARef
{
my $data=shift;
$data=[] unless $data;
$data=[$data] unless ref($data) eq 'ARRAY';
return $data;
}
sub getTime
{
my ($t) = @_;
my @t = $t ? localtime($t) : localtime();
return ( sprintf("%04d",$t[5]+1900),
sprintf("%02d",$t[4]+1),
sprintf("%02d",$t[3]),
sprintf("%02d",$t[2]),
sprintf("%02d",$t[1]),
sprintf("%02d",$t[0])
);
}
sub makeSortSQLcode
{
my ($f,$default_field) = @_;
my ($sort_field,$sort_order);
if (!$f->{sort_field})
{
$sort_field = $default_field;
}
else
{
$sort_field = $f->{sort_field};
}
if ($f->{sort_order} eq 'down'){$sort_order = 'DESC';} else {$sort_order = '';}
return " ORDER BY $sort_field $sort_order ";
}
sub makeSortHash
{
my ($f,$default_field) = @_;
my $params;
foreach my $key (%{$f})
{
my $val = $f->{$key};
$params .= '&'.$key.'='.$val if ($val && $key ne 'sort_field' && $key ne 'sort_order' && ref $val ne 'ARRAY' );
map({$params.='&'.$key.'='.$_}@$val) if (ref($val) eq 'ARRAY');
}
my $sort_field = $f->{sort_field};
my $sort_order = $f->{sort_order};
$sort_field = @{$default_field}[0] if (!$sort_field);
my $sort_order2 = $sort_order eq 'up' ? 'down' : 'up';
my %hash = ('sort_'.$sort_field => 1,
'sort_order_'.$sort_order2 => 1,
'params' => $params,
);
for my $fld (@$default_field)
{
$hash{"s_$fld"} = "";
$hash{"s2_$fld"} = "
" if $fld eq $sort_field;
$hash{"s2_$fld"}.= "";
}
return %hash;
}