#!/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; }