Files
FileSync/index.php
2025-08-16 06:45:14 -04:00

405 lines
18 KiB
PHP

<?php
//TODO
//logging?
//resolve conflicts?
//FINALIZE
//change version number
error_reporting(0);
require_once('config.php');
require_once('includes/isMobile.php');
//Version / Site
$VERSION='1.1';
$DB_VERSION='1.0';
$COMPATIBLE=array('1.0','1.1');
$SITE_URL = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$ip=$_SERVER['REMOTE_ADDR'];
//Init
$s_output='';
$f_output='';
$server_list=array();
$file_list=array();
$user='';
$tab='files';
//Connect to Database
$link=DBconnect(database('database'), database('host'), database('user'), database('pass'));
//Create Table
$query="CREATE TABLE IF NOT EXISTS ".table('FILE_TABLE')." (id int(10) PRIMARY KEY UNIQUE, type int(1), ip varchar(15), user varchar(32), file varchar(32), time int(10), url varchar(32))";
DBquery($link,$query);
//id type ip user file time url
//===============================
//id type=1 ip user '' '' ''
//id type=2 ip '' '' time url
//id type=3 ip user file time ''
//Get User
$query="SELECT * FROM ".table('FILE_TABLE')." WHERE type = 1 LIMIT 1";
$result = DBquery($link,$query); $rows = DBnum_rows($result);
if($rows==1){$user=DBresult($result,0,'user');}
//Get Server List
$server_list[0]=$SITE_URL;
$query="SELECT * FROM ".table('FILE_TABLE')." WHERE type = 2";
$result = DBquery($link,$query); $rows = DBnum_rows($result);
for($i=0;$i<$rows;$i++){$server_list[$i+1]=DBresult($result,$i,'url');}
//POST
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$id=isset($_POST['time'])?FILTER_SANITIZE_STRING($_POST['time']):time();
$ip=isset($_POST['ip'])?FILTER_SANITIZE_STRING($_POST['ip']):$ip;
switch($_POST['formid']){
case 'ping':
echo $DB_VERSION;
//Close Database
DBclose($link);
exit(); break;
case 'list':
$user= FILTER_SANITIZE_STRING($_POST['user']);
$query="SELECT * FROM ".table('FILE_TABLE')." WHERE type = 3 AND user = '$user'";
$result = DBquery($link,$query); $rows = DBnum_rows($result);
for($i=0;$i<$rows;$i++){echo DBresult($result,$i,'file').'|'.DBresult($result,$i,'time').'|';}
//Close Database
DBclose($link);
exit(); break;
case 'name':
$user= FILTER_SANITIZE_STRING($_POST['user']);
$query="DELETE FROM ".table('FILE_TABLE')." WHERE type = 1"; DBquery($link,$query);
$query="INSERT INTO ".table('FILE_TABLE')." VALUES ('$id', 1, '$ip', '$user', '', '', '')"; DBquery($link,$query);
break;
case 'server':
$tab='settings';
$server= FILTER_SANITIZE_STRING($_POST['server']);
$content = curl($server, array('formid' => 'ping', 'ip'=>$ip));
if(CheckVersion($content) && $server!=$SITE_URL){
//store server
$query="INSERT INTO ".table('FILE_TABLE')." VALUES ('$id', 2, '$ip', '', '', '', '$server')"; DBquery($link,$query);
$server_list[count($server_list)]=$server;
$s_output = "<span style='text-align: center; display: block;'>The server was added.</span><br>";
$server='';
}
else{$s_output = "<span style='text-align: center; display: block; color:#ff0000;'>Error. The server could not be added.</span><br>";}
break;
case 'deleteserver':
$tab='settings';
foreach($server_list as $s){
if(isset($_POST['del_'.FILTER_('.',$s)])){
$query="DELETE FROM ".table('FILE_TABLE')." WHERE url='$s'"; DBquery($link,$query);
break;
}
}
//Get Server List
$server_list=array();
$server_list[0]=$SITE_URL;
$query="SELECT * FROM ".table('FILE_TABLE')." WHERE type = 2";
$result = DBquery($link,$query); $rows = DBnum_rows($result);
for($i=0;$i<$rows;$i++){$server_list[$i+1]=DBresult($result,$i,'url');}
break;
case 'file':
if($_POST['request'] == $SITE_URL){
//Close Database
DBclose($link);
exit();
}
//Upload Algorythm
//1:get user from db
if(isset($_POST['user'])){$user = $_POST['user'];}
if($user==''){$f_output="<span style='text-align: center; display: block; color:#ff0000;'>Error. User not result.</span><br>";}
else{
//Create Paths
$target_path = "save/";
$target_path = FILTER_SPACES($target_path .$user."-". basename( $_FILES['uploadedfile']['name']));
$store_path = "save/store/";
$store_path = FILTER_SPACES($store_path .$user."-". basename( $_FILES['uploadedfile']['name']));
//2a:Backup the old file if it exists
if(file_exists($target_path)){rename($target_path, $store_path);}
//2b:copy the new file to the storage folder
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
$f_output="<span style='text-align: center; display: block;'>The file ". basename( $_FILES['uploadedfile']['name'])." has been uploaded</span><br>";
//2c:insert the file record
$query="DELETE FROM ".table('FILE_TABLE')." WHERE user='$user' AND file='".basename( $_FILES['uploadedfile']['name'])."'"; DBquery($link,$query);
$query="INSERT INTO ".table('FILE_TABLE')." VALUES ('$id', 3, '$ip', '$user', '".basename( $_FILES['uploadedfile']['name'])."', '$id', '')"; DBquery($link,$query);
}
else{$f_output="<span style='text-align: center; display: block; color:#ff0000;'>There was an error uploading the file, please try again!</span><br>";}
//3:send file/post data to the servers
$post=array('formid'=>'file', 'user'=>$user, 'ip'=>$ip, 'time'=>$id, 'uploadedfile'=>new CurlFile($target_path, '', $_FILES['uploadedfile']['name']),'request'=>$SITE_URL);
foreach ($server_list as $s) {curl($s, $post);}
}
break;
case 'deletefile':
if($_POST['request'] == $SITE_URL){
//Close Database
DBclose($link);
exit();
}
if(isset($_POST['user'])){$user = $_POST['user'];}
$query="SELECT * FROM ".table('FILE_TABLE')." WHERE type = 3";
$result = DBquery($link,$query); $rows = DBnum_rows($result);
for($i=0;$i<$rows;$i++){
if(isset($_POST['del_'.FILTER_('.', DBresult($result,$i,'file'))])){break;}
}
if($i<$rows){
$filename=DBresult($result,$i,'file');
$query="DELETE FROM ".table('FILE_TABLE')." WHERE user='$user' AND file='".$filename."'"; DBquery($link,$query);
$post=array('formid'=>'deletefile', 'user'=>$user, 'ip'=>$ip, 'time'=>$id, 'del_'.FILTER_('.',$filename)=>'X', 'request'=>$SITE_URL);
foreach ($server_list as $s) {curl($s, $post);}
}
break;
}
}
//Build File List
if($user!=''){
$post=array('formid'=>'list', 'user'=>$user, 'ip'=>$ip, 'time'=>time());
foreach ($server_list as $s) {
$content = explode('|',curl($s, $post));
if(count($content)>=2){
switch($s==$SITE_URL){
case true:
for($i=0;$i<count($content);$i+=2){
if($content[$i]!=""){$file_list[$content[$i]]=array('file'=>$content[$i], 'time'=>$content[$i+1], 'server'=>$s, 'status'=>1);}
}
break;
case false:
for($i=0;$i<count($content);$i+=2){
if(array_key_exists($content[$i],$file_list)){
//exists
$f=$file_list[$content[$i]];
if($f['time'] == $content[$i+1] && $f['status'] >= 1){$f['status'] += 1; $file_list[$content[$i]] = $f;}
if($f['time'] > $content[$i+1]){$f['time'] = $content[$i+1]; $f['server'] = $s; $f['status'] = 0; $file_list[$content[$i]] = $f;}
}
else{
//doesnt exist
if($content[$i]!=""){
$file_list[$content[$i]]=array('file'=>$content[$i], 'time'=>$content[$i+1], 'server'=>$s, 'status'=>0);
}
}
}
break;
}
}
}
}
//Set Tab State
$tab = $user=='' || count($server_list)<=1?'settings':$tab;
//Close Database
DBclose($link);
//Functions
function CheckVersion(string $check){
$result=false;
foreach($GLOBALS['COMPATIBLE'] as $v){
if($v==$check){$result=true; break;}
}
return $result;
}
function curl($url, $post){
$handle=curl_init();
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_VERBOSE, true);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($handle, CURLOPT_POSTFIELDS, $post);
$content = curl_exec($handle);
curl_close($handle);
return $content;
}
function ShortHash($hash){
$arr = str_split($hash);
$start=0;$length=0;
foreach($arr as $c){
if (is_numeric($c)) {
if($start==0){$start=(intval($c)<5?intval($c)+5:intval($c));} else{$length=(intval($c)<5?intval($c)+5:intval($c));}
if($length!=0){break;}
}
}
return substr($hash, $start, $length);
}
function FILTER_(string $search, string $string): string{return str_replace($search,'_',$string);}
function FILTER_SPACES(string $string): string{return str_replace(' ','_',$string);}
function FILTER_SANITIZE_STRING(string $string): string { return str_replace(["'", '"'], ['&#39;', '&#34;'], preg_replace('/\x00|<[^>]*>?/', '', $string)); }
?>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="styles.css?v=<?php echo time();?>">
<?php echo isMobile()?'<link rel="stylesheet" href="styles_m.css?v='.time().'">':'';?>
</head>
<body onload="showcontent('<?php echo $tab; ?>')">
<!-- Start Div-->
<div class='center' style="width:60%;">
<h1>File Sync<?php echo $user!=''?' - '.$user:'';?></h1>
<label class='click' onclick="showcontent('files')">File Server</label> | <label class='click' onclick="showcontent('settings')">Settings</label> | <label class='click' onclick="showcontent('about')">About</label>
<div id='content'></div>
<!-- Settings Div-->
<div id='settings' style='display:none;'>
<h2>Settings</h2>
<div style="border: 2px solid #ccc; font-family: verdana; padding: 7px; margin: 5px;">
<form method="POST">
<input type="hidden" name="formid" value="name" />
<label>Identity: </label><input style="width: 330px;" onkeypress="return event.key != ' '" onkeydown="return /[a-z]/i.test(event.key)" type=text name=user placeholder="Your Name / Website" value="<?php echo ($user!=''?$user:''); ?>">
<hr style="border:none;">
<input name="ip" type="hidden" value="<?php echo $_SERVER['REMOTE_ADDR']; ?>">
<div class='center'><input type=submit name=submit value=Submit></div>
</form>
</div>
<h2>Servers</h2>
<form method="POST">
<input type="hidden" name="formid" value="deleteserver" />
<input name="ip" type="hidden" value="<?php echo $_SERVER['REMOTE_ADDR']; ?>">
<ul>
<?php
if (count($server_list)<=1) {echo '<li>none</li>';}
else {
foreach ($server_list as $s) {
echo $s==$SITE_URL?'':'<li>'.$s.'&nbsp;&nbsp;&nbsp;<input title="Delete this server?" type=submit name="del_'.FILTER_('.',$s).'" value=X onclick=\'return confirm("Are you sure you want to delete the server?\n\n'.$s.'")\'></li>';
}
}
?>
</ul>
</form>
<div style="border: 2px solid #ccc; font-family: verdana; padding: 7px; margin: 5px;">
<?php echo $s_output; ?>
<form method="POST">
<input type="hidden" name="formid" value="server" />
<label>Add Server: </label><input style="width: 330px;" onkeypress="return event.key != ' '" type=text name=server placeholder="Server Url" value="<?php echo (isset($server)?$server:''); ?>">
<hr style="border:none;">
<input type="hidden" name="ip" value="<?php echo $_SERVER['REMOTE_ADDR']; ?>">
<div class='center'><input type=submit name=submit value=Add></div>
</form>
</div>
</div>
<!-- Settings Div-->
<!-- Files Div-->
<div id='files' style='display:none;'>
<h2>Upload</h2>
<div style="border: 2px solid #ccc; font-family: verdana; padding: 7px; margin: 5px;">
<?php echo $f_output; ?>
<form enctype="multipart/form-data" method="POST">
<input type="hidden" name="formid" value="file">
<input type="hidden" name="MAX_FILE_SIZE" value="533554432">
<label>Choose a file to upload: </label>
<input name="uploadedfile" type="file">
<hr style="border:none;">
<input type="hidden" name="ip" value="<?php echo $_SERVER['REMOTE_ADDR']; ?>">
<input type="hidden" name="request" value="form">
<div class='center'><input type="submit" value="Upload"></div>
</form>
</div>
<h2>Files on Server</h2>
<form method="POST">
<input type="hidden" name="formid" value="deletefile" />
<input type="hidden" name="ip" value="<?php echo $_SERVER['REMOTE_ADDR']; ?>">
<input type="hidden" name="request" value="form">
<ul>
<table style="border-collapse: separate; border-spacing: 30px 0px;">
<?php
$tooltip[0]='Critical - No other servers have a backup of this file.';
$tooltip[1]='Warning - You do not have a backup of this file locally.';
$tooltip[2]='Good - Multiple servers have a backup of this file.';
if (count($file_list)==0) {echo '<tr><td><li>none</li></td></tr>';}
else{
foreach($file_list as $f) {
$download_link='<a href="'.FILTER_SPaCES($f['server']."save/".$user."-".$f['file']).'" download="'.$f['file'].'"><button type="button">Download</button></a>';
$fcolor=($f['status']>=2?'#00ff00':($f['status']==1?'#ff0000':'#ff8000'));
$ficon=($f['status']>=2?'✔':($f['status']==1?'✖':'⚠'));
$ftooltip=$f['file'].' - '.($f['status']>=2?$tooltip[2]:($f['status']==1?$tooltip[0]:$tooltip[1]));
//$ficon=($f['status']>=2?'✔️':($f['status']==1?'⚠️':'❌'));
echo '<tr style="color:'.$fcolor.';">';
echo '<td title="'.$ftooltip.'"><li >'.$f['file'].'</li></td>';
echo '<td title="'.$ftooltip.'">'.date($Date_Format, $f['time']).'</td>';
echo '<td title="'.$ftooltip.'">'.$ficon.'</td>';
echo '<td>'.$download_link.'</td>';
echo '<td><input title="Delete this file?" type=submit name="del_'.FILTER_('.',$f['file']).'" value=X onclick=\'return confirm("Are you sure you want to delete this file?\n\n'.$f['file'].'")\'></td>';
echo '</tr>';
}
}
?>
</table>
</ul>
</form>
<label class='click' onclick="toggle('legend')">Click to show status info</label>
<div id='legend' style="display:none;">
<h2>Status Info</h2>
<div style="border: 2px solid #ccc; font-family: verdana; padding: 7px; margin: 5px; ">
<ul>
<li style="color:#00ff00;"><?php echo '✔ - '.$tooltip[2];?></li>
<li style="color:#ff8000;"><?php echo '⚠ - '.$tooltip[1];?></li>
<li style="color:#ff0000;"><?php echo '✖ - '.$tooltip[0];?></li>
</ul>
</div>
</div>
</div>
<!-- Files Div-->
<!-- About Div-->
<div id='about' style='display:none;'>
<?php include('readme.html'); ?>
</div>
<!-- About Div-->
</div>
<!-- End Div-->
<script>
function showcontent(id) {document.getElementById('content').innerHTML = document.getElementById(id).innerHTML;}
function toggle(id) {
var element = document.getElementById(id);
element.style.display = (element.style.display === "none" ? "block" : "none");
}
</script>
</body>
</html>