1020 lines
36 KiB
PHP
Executable File
1020 lines
36 KiB
PHP
Executable File
<?php
|
|
require_once "fetchPath.php";
|
|
$varManualTask = '\+ManualTask\/';
|
|
$userid = "";
|
|
$password = "";
|
|
$dbh = "";
|
|
$databaseLB = "";
|
|
$dbh_LB = "";
|
|
$current_source = "";
|
|
$sth_limit_level = "";
|
|
$sth_limit = "";
|
|
$sth = "";
|
|
$filehandle = 'FILEH';
|
|
$backupExcludeHash = array();
|
|
$excludeArray = array();
|
|
$parStr = "";
|
|
$extendedCounter = 0;
|
|
$isExtendedFileOpen = 0;
|
|
$counter = 0;
|
|
$index = 0;
|
|
$partialSyncFlag = 0;
|
|
$syncfilecounter = 0;
|
|
$extendedFileCount = 0;
|
|
$initialCounter = 1;
|
|
|
|
$ExtendedBackupList = TEMP_FILES.PATHSEPARATOR.EXTENDED_LIST;
|
|
$parSyncFile = TEMP_FILES.PATHSEPARATOR.PARTIAL_SYNC_FILE;
|
|
$isPartialSyncFileOpen = 0;
|
|
$LDBName = "IDriveLocalBackup.db";
|
|
$varLocalBackupManualTask = PATHSEPARATOR.$username.PATHSEPARATOR.LOCALBACKUP.PATHSEPARATOR;
|
|
$varLocalRestoreManualTask = PATHSEPARATOR.$username.PATHSEPARATOR.LOCALRESTORE.PATHSEPARATOR;
|
|
$liveConnections = $userDir.PATHSEPARATOR."liveConnections.txt";
|
|
$BackupExcludesetFile = TEMP_FILES.PATHSEPARATOR.EXCLUDE_FILE;
|
|
|
|
$table = array();
|
|
$parSync =array();
|
|
|
|
$BackupArray = array();
|
|
$readDB = 1;
|
|
$hostNameLB = "";
|
|
$SyncLimit = 10*86400;
|
|
$EXTN = '';
|
|
$parSyncFileHandle = '';
|
|
|
|
$fasterSyncDB = $userDir.PATHSEPARATOR.BACKUP.PATHSEPARATOR.IDRIVE_LOCAL_DB;
|
|
|
|
if($isLocalBackup ===1 or $isLocalRestore===1){
|
|
$hostNameLB = readLocalBackupLocation();
|
|
$serverRoot = '';
|
|
|
|
if(file_exists($dedupDetailFile)){
|
|
$deviceJSON = file_get_contents($dedupDetailFile);
|
|
$deviceArray = json_decode($deviceJSON, true);
|
|
$serverRoot = trim($deviceArray['serverRoot'])."/";
|
|
}
|
|
$databaseLB = getExpressDBPath();
|
|
}
|
|
elseif(($isLocalBackup ===0 or $isLocalRestore===0) and !preg_match("/$varManualTask/", $jobDir)){
|
|
$taskType = SCHEDULED;
|
|
$jobName = getJobName();
|
|
$fileName = $userDir.PATHSEPARATOR.".popUpList.txt";
|
|
//$phpPath = getPhpPath();
|
|
$cmd_mail = "$phpPath $webDir".PATHSEPARATOR.APPDIR.PATHSEPARATOR.CONFIG.PATHSEPARATOR.GETSCHEDULERDETAILSFILE." '$fileName' 'Backup_$jobName'";
|
|
$res = `$cmd_mail`;
|
|
$res = trim($res);
|
|
|
|
if($res == "monthly")
|
|
$SyncLimit = 32*86400;
|
|
}
|
|
|
|
#****************************************************************************************************
|
|
# Subroutine Name : createDB
|
|
# Objective : This function connects to the DB and then calls function to createTable
|
|
# Added By : Pooja Havaldar
|
|
# Modified By : Senthil Pandian
|
|
#*****************************************************************************************************
|
|
function createDB()
|
|
{
|
|
GLOBAL $machine, $database, $dbh, $fasterSyncDB;
|
|
|
|
//Creating Database
|
|
try {
|
|
$dbh = new PDO("sqlite:$fasterSyncDB");
|
|
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
|
|
if($dbh){
|
|
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
|
|
@chmod($fasterSyncDB, PERMISSIONVAL);
|
|
$dbh->exec('PRAGMA journal_mode = wal;');
|
|
//$dbh->exec('PRAGMA synchronous=1;');
|
|
$dbh->exec('PRAGMA SQLITE_THREADSAFE=2;');
|
|
//$dbh->exec('PRAGMA SQLITE_CONFIG_MULTITHREAD=2;');
|
|
//$dbh->exec('PRAGMA threads=4;');
|
|
$dbh->exec('PRAGMA read_uncommitted = on;');
|
|
if(!createTable($dbh)){
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
catch(PDOException $e) {
|
|
traceLog(" Error : ".$e->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#*****************************************************************************************************************
|
|
# Subroutine Name : createTable.
|
|
# Objective : This subroutine creates a table in DB only if it does not exist
|
|
# Added By : Pooja Havaldar
|
|
# Modified By : Senthil Pandian
|
|
#******************************************************************************************************************
|
|
function createTable($dbh)
|
|
{
|
|
$createLocalTableQry = "CREATE TABLE IF NOT EXISTS IDriveLocalTable (FILEPATH text not null, MOD_DT TIMESTAMP not null, FILESIZE integer, PRESENTDATE TIMESTAMP default (strftime('%s','now')), LEVELCOUNT integer not null, UNIQUE(FILEPATH));";
|
|
$createLocalTableIndexQry = "CREATE INDEX IF NOT EXISTS IDriveLocalTable_indx on IDriveLocalTable (FILEPATH)";
|
|
try {
|
|
$dbh->exec($createLocalTableQry);
|
|
$dbh->exec($createLocalTableIndexQry);
|
|
} catch(PDOException $e){
|
|
traceLog("Create table failed for IDriveLocalTable. Error : ".$e->getMessage());
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#****************************************************************************************************
|
|
# Subroutine Name : prepareSelectStmt
|
|
# Objective : This function prepares the query to search from DB with limit and offset
|
|
# Added By : Pooja Havaldar
|
|
# Modified By : Senthil Pandian
|
|
#*****************************************************************************************************
|
|
function prepareSelectStmt()
|
|
{
|
|
GLOBAL $dbh,$sth_limit_level,$sth_limit;
|
|
$sth_limit_level = "";
|
|
$sth_limit = "";
|
|
|
|
if($dbh){
|
|
$a = SEARCH_LIMIT;
|
|
$sth_limit_level = $dbh->prepare( "SELECT * FROM IDriveLocalTable WHERE FILEPATH LIKE ? AND LEVELCOUNT = ? LIMIT $a OFFSET ?" );
|
|
$sth_limit = $dbh->prepare( "SELECT * FROM IDriveLocalTable WHERE FILEPATH LIKE ? LIMIT $a OFFSET ?" );
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#******************************************************************************************************************
|
|
# Subroutine Name : createLBDB.
|
|
# Objective : This subroutine connects to the Local Backup DB and then calls function to createTableLB
|
|
# Added By : Pooja Havaldar
|
|
# Modified By : Senthil Pandian
|
|
#******************************************************************************************************************
|
|
function createLBDB()
|
|
{
|
|
# check if complete path is not found then create
|
|
# flag to check DB is already exists or going to create
|
|
# this condition is feasible or let the chmod call for existing right permission also?
|
|
GLOBAL $databaseLB, $dbh_LB, $isLocalRestore;
|
|
|
|
$dirPath = substr($databaseLB, 0, strrpos($databaseLB, '/'));
|
|
try {
|
|
`mkdir -p '$dirPath'`; #Creating LDBNEW folder & providing permission
|
|
} catch(Exception $e) {
|
|
traceLog("Operation could not be completed. Reason:" . $e->getMessage());
|
|
return false;
|
|
}
|
|
|
|
# Creating Database
|
|
try {
|
|
$dbh_LB = new PDO("sqlite:$databaseLB");
|
|
$dbh_LB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
$dbh_LB->exec('PRAGMA journal_mode = wal;');
|
|
$dbh_LB->exec('PRAGMA synchronous=1;');
|
|
$dbh_LB->exec('PRAGMA read_uncommitted = on;');
|
|
$dbh_LB->exec('PRAGMA case_sensitive_like = 1;');
|
|
@chmod($databaseLB, PERMISSIONVAL);
|
|
|
|
# if local restore no need to create table
|
|
if($isLocalRestore == 1) {
|
|
return true;
|
|
}
|
|
|
|
if(!createTableLB($dbh_LB)) {
|
|
return false;
|
|
}
|
|
|
|
@chmod($databaseLB . '-shm', PERMISSIONVAL);
|
|
@chmod($databaseLB . '-wal', PERMISSIONVAL);
|
|
|
|
return true;
|
|
} catch(Exception $e) {
|
|
traceLog("Creation of Local DB [$databaseLB] failed. Reason : " . $e->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#**************************************************************************************************************************
|
|
# Subroutine Name : createTableLB.
|
|
# Objective : This subroutine creates 2 tables - IbFile and IbFolder in DB only if it already does not exist
|
|
# Added By : Pooja Havaldar
|
|
# Modified By : Senthil Pandian
|
|
#**************************************************************************************************************************
|
|
function createTableLB($dbh_LB)
|
|
{
|
|
$createFolderTableQry = "CREATE TABLE IF NOT EXISTS ".IBFOLDER." (DIRID integer primary key autoincrement, NAME char(1024) not null,FILE_LMD char(256),FILE_SIZE __int64,LEVEL_NO integer DEFAULT 0,SYNC_DATE char(50), UNIQUE(NAME));";
|
|
$createFolderIndexQry = "CREATE INDEX IF NOT EXISTS ibfolder_indx ON ".IBFOLDER." (NAME);";
|
|
$createFileTableQry = 'CREATE TABLE IF NOT EXISTS '.IBFILE.' (FILEID integer primary key autoincrement, DIRID integer not null, NAME char(1024) not null,FILE_LMD char(256),FILE_SIZE __int64,FILE_OR_FOLDER integer DEFAULT 0,BKSET_LMD char(50), SYNC_DATE char(50),BACKUP_STATUS integer DEFAULT 0,BKSET_NAME char(50),HASH_VALUE __int64,THUMB integer DEFAULT 0, FOLDER_ID char(1024),MPC char(50),ENC_NAME char(1024), foreign key (DIRID) references '.IBFILE.' (DIRID),UNIQUE(DIRID, NAME));';
|
|
$createFileIndexQry = 'CREATE INDEX IF NOT EXISTS ibfile_indx ON '.IBFILE.' (NAME);';
|
|
|
|
try{
|
|
//Creating tables & its index
|
|
$dbh_LB->exec($createFolderTableQry);
|
|
$dbh_LB->exec($createFolderIndexQry);
|
|
$dbh_LB->exec($createFileTableQry);
|
|
$dbh_LB->exec($createFileIndexQry);
|
|
} catch(PDOException $e){
|
|
$errStr = "Operation could not be completed. Reason: Creation of Local DB failed. ".$e->getMessage();
|
|
traceLog($errStr);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#***********************************************************************************************************************
|
|
# Subroutine Name : set.
|
|
# Objective : This subroutine checks the liveConnections.txt file for current live connections and sets the DB if required
|
|
# Added By : Pooja Havaldar
|
|
# Modified By : Senthil Pandian
|
|
#************************************************************************************************************************
|
|
/*
|
|
function set($operation)
|
|
{
|
|
GLOBAL $liveConnections,$username,$databaseLB,$webDir,$APPDIR;
|
|
|
|
$res = 'set';
|
|
$retVal = 0;
|
|
|
|
try{
|
|
$handle = fopen($liveConnections,'w');
|
|
if(!flock($handle, LOCK_EX|LOCK_NB, $lockFlag)){
|
|
traceLog("Not able to lock $liveConnections");
|
|
return false;
|
|
}
|
|
if($databaseLB == ""){
|
|
$hostNameLB = readLocalBackupLocation();
|
|
$databaseLB = "$hostNameLB/$username/".LDBNEW."/$username.ibenc";
|
|
}
|
|
|
|
if(file_exists($databaseLB) && isNotLocked($operation)){
|
|
#sqliteldb binary path
|
|
$sqliteBinaryPath = "$webDir/".APPDIR."/sqliteldb";
|
|
$cmdSetDB = $sqliteBinaryPath.WHITESPACE.$databaseLB.WHITESPACE."set";
|
|
$res = `$cmdSetDB`;
|
|
$res = trim($res);
|
|
}
|
|
@unlink($operation);
|
|
fclose($handle);
|
|
return $res;
|
|
} catch(Exception $e){
|
|
$errStr = "Cannot open/write $liveConnections file. Reason : ".$e->getMessage();
|
|
traceLog(errstr);
|
|
}
|
|
}
|
|
*/
|
|
|
|
#**************************************************************************************************************************
|
|
# Subroutine Name : unset.
|
|
# Objective : This subroutine checks the liveConnections.txt file for current live connections and unsets the DB if required
|
|
# Added By : Pooja Havaldar
|
|
# Modified By : Senthil Pandian
|
|
#**************************************************************************************************************************
|
|
/*function dbUnset($operation)
|
|
{
|
|
GLOBAL $liveConnections,$username,$databaseLB,$webDir,$APPDIR;
|
|
|
|
$res = 'unset';
|
|
$retVal = 0;
|
|
if($databaseLB == ""){
|
|
$hostNameLB = readLocalBackupLocation();
|
|
$databaseLB = "$hostNameLB/$username/".LDBNEW."/$username.ibenc";
|
|
}
|
|
if(!file_exists($liveConnections)){
|
|
$handle = fopen($liveConnections,'w');
|
|
`chmod PERMISSIONVAL $liveConnections`;
|
|
if(!flock($liveConnections, LOCK_EX|LOCK_NB, $lockFlag)){
|
|
traceLog("Could not put lock on $liveConnections file. Reason:".customErrorMsg());
|
|
fclose($handle);
|
|
return false;
|
|
}
|
|
} else {
|
|
$handle = fopen($liveConnections,'w');
|
|
if(!flock($handle, LOCK_EX|LOCK_NB, $lockFlag)){
|
|
traceLog("Not able to lock $liveConnections. Reason:".customErrorMsg());
|
|
fclose($handle);
|
|
return false;
|
|
}
|
|
}
|
|
fclose($handle);
|
|
|
|
if(file_exists($databaseLB) && isNotLocked($operation)){
|
|
#sqliteldb binary path
|
|
$sqliteBinaryPath = "$webDir/".$APPDIR."/sqliteldb";
|
|
$cmdUnsetDB = $sqliteBinaryPath.WHITESPACE.$databaseLB.WHITESPACE."unset";
|
|
$res = `$cmdUnsetDB`;
|
|
$res = trim($res);
|
|
}
|
|
|
|
$handle = fopen($operation,'w');
|
|
if(!$handle){
|
|
traceLog("Cannot open $operation file. Reason:".customErrorMsg());
|
|
return false;
|
|
}
|
|
if(!flock($handle, LOCK_EX|LOCK_NB, $lockFlag)){
|
|
traceLog("Could not put lock on $operation file. Reason:".customErrorMsg());
|
|
return false;
|
|
}
|
|
fclose($handle);
|
|
return $res;
|
|
}
|
|
*/
|
|
#*************************************************************************************************************************
|
|
# Subroutine Name : isNotLocked
|
|
# Objective : This subroutine checks whether the DB operation file locked or not
|
|
# Added By : Pooja Havaldar
|
|
# Modified By : Senthil Pandian
|
|
#*************************************************************************************************************************
|
|
/*function isNotLocked($operation)
|
|
{
|
|
GLOBAL $sqliteLockFiles;
|
|
$ret = true;
|
|
for($i = 0; $i < count($sqliteLockFiles); $i++){
|
|
$ret = true;
|
|
if($sqliteLockFiles[$i] == $operation or !file_exists($sqliteLockFiles[$i])){
|
|
continue;
|
|
}
|
|
try{
|
|
$handle = fopen($sqliteLockFiles[$i],'w');
|
|
if(!flock($handle,LOCK_EX|LOCK_NB, $lockFlag)){
|
|
traceLog("$sqliteLockFiles[$i] file was locked. Reason:".customErrorMsg());
|
|
$ret = false;
|
|
break;
|
|
}
|
|
@unlink($sqliteLockFiles[$i]);
|
|
} catch(Exception $e){
|
|
traceLog("Cannot open $sqliteLockFiles[$i] file. Reason : ".$e->getMessage());
|
|
}
|
|
}
|
|
return $ret;
|
|
}
|
|
*/
|
|
#***********************************************************************************************************************
|
|
# Subroutine Name : getSearchResultfromDB
|
|
# Objective : This function executes query to get number of rows in DB with resp. folder name and then calls to searchDB
|
|
# Added By : Pooja
|
|
# Modified By : Senthil Pandian [11/29/2016]
|
|
#************************************************************************************************************************
|
|
function getSearchResultfromDB($item,$readCount)
|
|
{
|
|
GLOBAL $dbh, $hostName;
|
|
|
|
$printItem = getPrintItem($item);
|
|
$hostName = readBackupLocation();
|
|
$searchItem = "$hostName$printItem";
|
|
|
|
if (substr($searchItem, -1, 1) != "/")
|
|
$searchItem .= "/";
|
|
$searchItem = $searchItem.'%';
|
|
$searchItem = "$searchItem";
|
|
|
|
if($readCount != 0){
|
|
searchDB($searchItem,$readCount, SEARCHLEVEL);
|
|
return 1;
|
|
}
|
|
|
|
try {
|
|
$selectFolderTableQry = "SELECT COUNT(*) FROM IDriveLocalTable WHERE FILEPATH LIKE ?";
|
|
$selectFolder = $dbh->prepare($selectFolderTableQry);
|
|
$selectFolder->execute(array($searchItem));
|
|
$result = $selectFolder->fetch();
|
|
$selectFolder->closeCursor();
|
|
$rows = trim($result[0]);
|
|
}
|
|
catch (PDOException $e){
|
|
traceLog("select failed for folder: $searchItem. Reason: ".$e->getMessage());
|
|
}
|
|
|
|
if(!$rows)
|
|
return 1;
|
|
|
|
#checking if the rows we need to read are within limit if not then we create extended list in place of loading full db results at once
|
|
if($rows > SEARCH_LIMIT){
|
|
if(!getExtendedBackupList($item)){
|
|
traceLog("Could not open new ExtendedList file, for $item.");
|
|
return 0;
|
|
}
|
|
else
|
|
return 2;
|
|
}
|
|
|
|
searchDB($searchItem,$readCount, SEARCHALL);
|
|
return 1;
|
|
}
|
|
|
|
#*******************************************************************************************************************
|
|
# Subroutine Name : getExtendedBackupList
|
|
# Objective : To enumerate one level and based on that decide whether to create PartialSyncFiles or
|
|
# append to Backup list and create ExtendedListFiles so that search result is within limit.
|
|
# Added By : Pooja
|
|
# Modified By : Senthil Pandian [11/29/2016]
|
|
#********************************************************************************************************************
|
|
function getExtendedBackupList($item)
|
|
{
|
|
GLOBAL $isExtendedFileOpen,$parSyncFile,$BACK_FILE, $counter, $backupLocation;
|
|
GLOBAL $totalFiles, $index, $newFile, $filecount, $enumerateFileSize;
|
|
$index = 1;
|
|
if (substr($item, -1, 1) != "/")
|
|
$item .= "/";
|
|
|
|
if(!$dirHandle = opendir($item)){
|
|
traceLog("Could not open Dir $item, Reason : ".customErrorMsg());
|
|
return 0;
|
|
}
|
|
|
|
if($isExtendedFileOpen == 0 and !openExtendedBackupList()){
|
|
traceLog("Could not open new ExtendedList file.");
|
|
return 0;
|
|
}
|
|
|
|
$counter++;
|
|
$newFile = $parSyncFile.$counter.".".$index;
|
|
$isPartialSyncFileOpen = 0;
|
|
createPartialSyncFile($newFile);
|
|
|
|
$printItem = getPrintItem($item);
|
|
$searchItem = "$backupLocation$printItem"."%";
|
|
searchDB($searchItem, 0, SEARCHLEVEL);
|
|
while (($file = readdir($dirHandle)) !== false) {
|
|
if(!file_exists(PIDFILE))
|
|
break;
|
|
|
|
if( $file == "." || $file == "..")
|
|
continue;
|
|
|
|
$temp = trim($item.$file,"\n");
|
|
$printItem = getPrintItem($temp);
|
|
|
|
if(is_dir($temp)){
|
|
if(pushEntries($temp)) #Fill these folder entries in backup array and ExtendedFile list
|
|
continue;
|
|
}
|
|
else {
|
|
if(excludeCheck($temp, $printItem))
|
|
continue;
|
|
|
|
$totalFiles++;
|
|
if(checkForSync($backupLocation.$printItem, $temp, 1))
|
|
continue;
|
|
|
|
fwrite($BACK_FILE,$printItem.LINEFEED);
|
|
$filecount++;
|
|
|
|
if($filecount == FILE_MAX_COUNT || $enumerateFileSize >= BACKUP_SET_MAX_SIZE){
|
|
if(!createBackupSetFiles1k(""))
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(customFileSize($newFile) > 0){
|
|
insertHash($item);
|
|
}
|
|
closedir($dirHandle);
|
|
return true;
|
|
}
|
|
|
|
#******************************************************************************************************************
|
|
# Subroutine Name : openExtendedBackupList
|
|
# Objective : This subroutine closes the existing file handle for ExtendedListFile and opens a new
|
|
# extendedlist file with new name
|
|
# Added By : Pooja
|
|
# Modified By : Senthil Pandian [11/29/2016]
|
|
#******************************************************************************************************************
|
|
function openExtendedBackupList()
|
|
{
|
|
GLOBAL $EXTN,$isExtendedFileOpen,$ExtendedBackupList,$extendedFileCount,$extendedCounter;
|
|
if($isExtendedFileOpen)
|
|
fclose($EXTN);
|
|
|
|
$extendedCounter++;
|
|
$newFile = $ExtendedBackupList.$extendedCounter;
|
|
$isExtendedFileOpen = 1;
|
|
|
|
if(!$EXTN = fopen($newFile,'w')){
|
|
traceLog("Could not open $newFile to write, Reason : ".customErrorMsg());
|
|
$isExtendedFileOpen = 0;
|
|
}
|
|
|
|
$extendedFileCount = 0;
|
|
return $isExtendedFileOpen;
|
|
}
|
|
|
|
#****************************************************************************************************
|
|
# Subroutine Name : searchDB
|
|
# Objective : This subroutine loads the search result in associative array and if rows
|
|
# read are less than expected limit then we make db read flag as false as it
|
|
# means db is read full already.
|
|
# Added By : Pooja
|
|
# Modified By : Senthil Pandian [11/29/2016]
|
|
#****************************************************************************************************
|
|
function searchDB($searchItem,$readCount,$level)
|
|
{
|
|
GLOBAL $sth_limit_level, $sth_limit, $readDB, $table;
|
|
|
|
$table = array();
|
|
$a = SEARCH_LIMIT;
|
|
$limit = $a * $readCount;
|
|
|
|
if($level == SEARCHLEVEL){
|
|
$sth = $sth_limit_level;
|
|
$levelCount = substr_count($searchItem, '/') - 1;
|
|
$sth->execute(array($searchItem, $levelCount, $limit));
|
|
} else {
|
|
$sth = $sth_limit;
|
|
$sth->execute(array($searchItem, $limit));
|
|
}
|
|
|
|
if($sth == ""){
|
|
traceLog("DB handle sth is not defined in searchDB function.");
|
|
return;
|
|
}
|
|
$rowCount = 0;
|
|
while($row = $sth->fetch()) {
|
|
$rowCount++;
|
|
$filePath = $row['FILEPATH'];
|
|
$table[$filePath]['datetime'] = $row['MOD_DT'];
|
|
$table[$filePath]['size'] = $row['FILESIZE'];
|
|
$table[$filePath]['backupdate'] = $row['PRESENTDATE'];
|
|
}
|
|
|
|
$sth->closeCursor();
|
|
if($rowCount < SEARCH_LIMIT)
|
|
$readDB = 0;
|
|
}
|
|
|
|
#************************************************************************************************************
|
|
# Subroutine Name : checkForSync
|
|
# Objective : This subroutine will check if file is present in search result, in sync or not.
|
|
# Added By : Senthil Pandian [11/29/2016]
|
|
# Modified By :
|
|
#************************************************************************************************************
|
|
function checkForSync($searchFolder,$tempContent,$isExistCheck)
|
|
{
|
|
GLOBAL $syncfilecounter,$parSyncFile,$counter,$SyncLimit,$parSyncFileHandle, $table, $bacSync, $index, $newFile;
|
|
|
|
# check if file does not exist in db result
|
|
if(!isset($table[$searchFolder]['datetime'])){
|
|
#if call comes from readRemainingResultsFromDB subroutine then return from function
|
|
if($isExistCheck == 2)
|
|
return 2;
|
|
else if($isExistCheck == 1){
|
|
#If backup array limit is reached then open new partial sync file
|
|
if($syncfilecounter == BACKUPARRAY_LIMIT){
|
|
$index++;
|
|
$newFile = $parSyncFile.$counter.".".$index;
|
|
createPartialSyncFile($newFile);
|
|
}
|
|
|
|
#Write this file to current partial sync file to sync with remaining db result if possible
|
|
fwrite($parSyncFileHandle, $tempContent."\n");
|
|
$syncfilecounter++;
|
|
return 1;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
#checking if current date and last backed up date difference for this file is greater than 10 days. Forcing file for backup again in this case.
|
|
$diff = time() - $table[$searchFolder]['backupdate'];
|
|
if($diff > $SyncLimit){
|
|
return 0;
|
|
}
|
|
|
|
$size = customFileSize($tempContent);
|
|
$modtime = filemtime($tempContent);
|
|
#checking file in sync based on database result
|
|
if($table[$searchFolder]['datetime'] == $modtime and $table[$searchFolder]['size'] == $size){
|
|
$bacSync++;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#***********************************************************************************************
|
|
# Subroutine Name : loadExtendedList
|
|
# Objective : This subroutine loads content of ExtendedListFile into BackupArray
|
|
# so that entire backup process can be performed on it.
|
|
# Added By : Pooja
|
|
# Modified By : Senthil Pandian [11/29/2016]
|
|
#************************************************************************************************
|
|
function loadExtendedList()
|
|
{
|
|
GLOBAL $isExtendedFileOpen,$EXTN,$initialCounter,$extendedCounter,$ExtendedBackupList,$BackupArray;
|
|
/*if($isExtendedFileOpen){
|
|
fclose($EXTN);
|
|
$isExtendedFileOpen = 0;
|
|
}*/
|
|
|
|
for($i = $initialCounter; $i <= $extendedCounter; $i++){
|
|
$newFile = $ExtendedBackupList.$i;
|
|
if(!file_exists($newFile) or customFileSize($newFile) <= 0)
|
|
continue;
|
|
|
|
$BackupArray = array();
|
|
$BackupArray = file($newFile);
|
|
$initialCounter++;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#*******************************************************************************************
|
|
# Subroutine Name : pushEntries
|
|
# Objective : This subroutine pushes directory entries into backupArray or
|
|
# to ExtendedListFile based on PartialSyncFlag
|
|
# Added By : Pooja
|
|
# Modified By : Senthil Pandian [11/29/2016]
|
|
#********************************************************************************************
|
|
function pushEntries($temp)
|
|
{
|
|
GLOBAL $extendedFileCount,$BackupArray,$EXTN;
|
|
|
|
#push the directory entry to array if it is within array limit
|
|
if($extendedFileCount == 0 and count($BackupArray) < BACKUPARRAY_LIMIT){
|
|
array_push($BackupArray, $temp);
|
|
return 1;
|
|
}
|
|
|
|
#open the extended backup set file if limit is reached for backupset array
|
|
if($extendedFileCount == BACKUPARRAY_LIMIT and !openExtendedBackupList()){
|
|
traceLog("Could not open extended backup list file to write");
|
|
return 0;
|
|
}
|
|
|
|
#Write to extended list
|
|
fwrite($EXTN,"$temp\n");
|
|
$extendedFileCount++;
|
|
return 1;
|
|
}
|
|
|
|
#**************************************************************************************************************************
|
|
# Subroutine Name : insertHash
|
|
# Objective : This subroutine fills entry of PartialSyncFile name and the number of files created for each directory to hash
|
|
# Added By : Pooja
|
|
# Modified By : Senthil Pandian [11/29/2016]
|
|
#**************************************************************************************************************************
|
|
function insertHash($dirName)
|
|
{
|
|
GLOBAL $isPartialSyncFileOpen,$parSyncFile,$counter,$parSync,$parSyncFileHandle, $index;
|
|
if($isPartialSyncFileOpen){
|
|
fclose($parSyncFileHandle);
|
|
$isPartialSyncFileOpen = 0;
|
|
}
|
|
$parSync[$dirName]['partialFileName'] = $parSyncFile.$counter;
|
|
$parSync[$dirName]['indexcount'] = $index;
|
|
}
|
|
|
|
#**************************************************************************************************************************
|
|
# Subroutine Name : readRemainingResultsFromDB
|
|
# Objective : This subroutine reads remaining results from DB and checks with PartialSyncFiles created and
|
|
# based on that creates more
|
|
# Added By : Senthil Pandian [11/29/2016]
|
|
# Modified By :
|
|
#**************************************************************************************************************************
|
|
function readRemainingResultsFromDB()
|
|
{
|
|
GLOBAL $isPartialSyncFileOpen, $parSync, $syncfilecounter, $enumerateFileSize;
|
|
GLOBAL $filecount, $parSyncFileHandle, $BACK_FILE, $readDB, $hostName;
|
|
|
|
if(count($parSync) == 0)
|
|
return;
|
|
|
|
$setEndIndex = "";
|
|
$matchedCount = 0;
|
|
$isPartialSyncFileOpen = 0;
|
|
$itemCount = array_keys($parSync);
|
|
|
|
#running a loop for all hash items for partial sync
|
|
for($i = 0; $i < count($itemCount); $i++){
|
|
if(!file_exists(PIDFILE))
|
|
break;
|
|
|
|
$readDB = 1;
|
|
$readCount = 1;
|
|
|
|
$item = $itemCount[$i];
|
|
$setEndIndex = $parSync[$item]['indexcount']; #This variable has the count of first set of PartialSyncFiles created before
|
|
$endIndex = $setEndIndex + 1;
|
|
$finalFile = $parSync[$item]['partialFileName'].".".$endIndex;
|
|
$firstSyncFile = $parSync[$item]['partialFileName'].".1";
|
|
|
|
# create a new partial sync file for unmatched items if db read is still partial
|
|
if(customFileSize($firstSyncFile) > 0)
|
|
createPartialSyncFile($finalFile);
|
|
|
|
# read the db for the limit defined for remaining items
|
|
getSearchResultfromDB($item,$readCount);
|
|
|
|
# running a loop for loading every partial sync file for current item to check sync based on loaded database result
|
|
for($indexCount = 1; $indexCount <= $parSync[$item]['indexcount']; $indexCount++){
|
|
if(!file_exists(PIDFILE))
|
|
break;
|
|
|
|
#checking if first set of partial files is finished
|
|
if($setEndIndex == $indexCount-1){
|
|
if($syncfilecounter > 0){
|
|
#updating the last index value based on last partial sync file created
|
|
$parSync[$item]['indexcount'] = $endIndex;
|
|
$endIndex++;
|
|
$finalFile = $parSync[$item]['partialFileName'].".".$endIndex;
|
|
createPartialSyncFile($finalFile);
|
|
}
|
|
|
|
#reading the remaining db items for next set
|
|
if($readDB){
|
|
$readCount++;
|
|
getSearchResultfromDB($item,$readCount);
|
|
$matchedCount = 0;
|
|
|
|
#resetting the setEndIndex for new set
|
|
$setEndIndex = $parSync[$item]['indexcount'];
|
|
}
|
|
}
|
|
|
|
$fileContent = array();
|
|
$fileToRead = $parSync[$item]['partialFileName'].".".$indexCount;
|
|
$fileContent = readPartialSyncFile($fileToRead);
|
|
|
|
if(count($fileContent) == 0)
|
|
continue;
|
|
|
|
# running a loop for sync check for loaded partial sync file items
|
|
foreach($fileContent as $lineContent){
|
|
$lineContent = trim($lineContent);
|
|
|
|
# Create a new partial sync file if limit is reached only if we have readDB flag true
|
|
if($readDB && $syncfilecounter == BACKUPARRAY_LIMIT){
|
|
#updating the last index value based on last partial sync file created
|
|
$parSync[$item]['indexcount'] = $endIndex;
|
|
$endIndex++;
|
|
$finalFile = $parSync[$item]['partialFileName'].".".$endIndex;
|
|
createPartialSyncFile($finalFile);
|
|
}
|
|
|
|
#Update the info file for newly created backup set file. Also open a new backup set file
|
|
if($filecount == FILE_MAX_COUNT || $enumerateFileSize >= BACKUP_SET_MAX_SIZE){
|
|
if(!createBackupSetFiles1k(""))
|
|
break;
|
|
}
|
|
|
|
$printItem = getPrintItem($lineContent);
|
|
$retVal = checkForSync($hostName.$printItem, $lineContent, 2);
|
|
|
|
#item found in db but not in sync
|
|
if($retVal == 0){
|
|
#write the item to backup set file for backup
|
|
fwrite($BACK_FILE,$printItem.LINEFEED);
|
|
$filecount++;
|
|
}
|
|
if($retVal == 2){ #item not found in db
|
|
#if still we have results to read from db then write item to partial sync file
|
|
if($readDB){
|
|
if($isPartialSyncFileOpen)
|
|
fwrite($parSyncFileHandle, "$lineContent\n");
|
|
$syncfilecounter++;
|
|
}else{ # write item to backup set
|
|
fwrite($BACK_FILE,$printItem.LINEFEED);
|
|
$filecount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
# check if we have a new partial sync file with some items
|
|
if($indexCount+1 == $endIndex){
|
|
if($readDB and $syncfilecounter > 0){
|
|
$endIndex++;
|
|
$finalFile = $parSync[$item]['partialFileName'].".".$endIndex;
|
|
createPartialSyncFile($finalFile);
|
|
$parSync[$item]['indexcount'] = $endIndex;
|
|
}
|
|
else if($syncfilecounter > 0){
|
|
$parSync[$item]['indexcount'] = $endIndex;
|
|
if($isPartialSyncFileOpen){
|
|
fclose(parSyncFileHandle);
|
|
$isPartialSyncFileOpen = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if($isPartialSyncFileOpen)
|
|
fclose($parSyncFileHandle);
|
|
}
|
|
|
|
#*********************************************************************************************************
|
|
# Subroutine Name : readPartialSyncFile
|
|
# Objective : This subroutine reads the PartialSyncFile and returns it in an array
|
|
# Added By : Senthil Pandian [11/29/2016]
|
|
# Modified By :
|
|
#*********************************************************************************************************
|
|
function readPartialSyncFile($syncFile)
|
|
{
|
|
$syncContent = array();
|
|
|
|
if(customFileSize($syncFile) <= 0){
|
|
@unlink($syncFile);
|
|
return $syncContent;
|
|
}
|
|
|
|
$syncContent = file($syncFile);
|
|
return $syncContent;
|
|
}
|
|
|
|
#********************************************************************************************************************
|
|
# Subroutine Name : createPartialSyncFile
|
|
# Objective : This subroutine closes already open PartialSyncFile and opens new file for re-writing
|
|
# Added By : Senthil Pandian [11/29/2016]
|
|
# Modified By :
|
|
#*********************************************************************************************************************
|
|
function createPartialSyncFile($finalFile)
|
|
{
|
|
GLOBAL $isPartialSyncFileOpen,$parSyncFileHandle,$syncfilecounter;
|
|
if($isPartialSyncFileOpen){
|
|
fclose($parSyncFileHandle);
|
|
$isPartialSyncFileOpen = 0;
|
|
}
|
|
|
|
if(!$parSyncFileHandle = fopen($finalFile,'w'))
|
|
traceLog("Cannot open $finalFile for re-writing, Reason : ".customErrorMsg());
|
|
else
|
|
$isPartialSyncFileOpen = 1;
|
|
|
|
$syncfilecounter = 0;
|
|
}
|
|
|
|
#************************************************************************************************************************
|
|
# Subroutine Name : excludeCheck
|
|
# Objective : This function checks whether the argument passed is present in any exclude list - full/partial exclude
|
|
# Added By : Pooja Havaldar
|
|
# Modified By : Senthil Pandian
|
|
#*************************************************************************************************************************
|
|
function excludeCheck($element,$parElement)
|
|
{
|
|
GLOBAL $logOutputFilePath,$backupExcludeHash,$excludeArray,$parStr,$BackupExcludesetFile;
|
|
$content = '';
|
|
|
|
if(isset($backupExcludeHash[$element])){
|
|
$localtime = trim(shell_exec('date +"%a %b %d %T %Y"'));
|
|
$content = "[$localtime] [EXCLUDED] [$parElement]. Reason: Full path excluded item.".LINEFEED;
|
|
}
|
|
else if(count($excludeArray) > 0){
|
|
for($i = 0;$i < count($excludeArray); $i++){
|
|
$excludeArray_quotemeta = phpQuoteMeta($excludeArray[$i]);
|
|
if(preg_match("/^$excludeArray_quotemeta/", $element)){
|
|
$localtime = trim(shell_exec('date +"%a %b %d %T %Y"'));
|
|
$content = "[$localtime] [EXCLUDED] [$parElement]. Reason: Full path excluded item.".LINEFEED;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(empty($content) and !empty($parStr) and preg_match("/$parStr/", $parElement)){
|
|
$localtime = trim(shell_exec('date +"%a %b %d %T %Y"'));
|
|
$content = "[".($localtime)."] [EXCLUDED] [$parElement]. Reason: Partial path excluded item.".LINEFEED;
|
|
}
|
|
|
|
if(!empty($content)){
|
|
if(! ($logOutputHandle = fopen($BackupExcludesetFile, "a"))){
|
|
traceLog("Could not open file $BackupExcludesetFile, Reason : ".customErrorMsg());
|
|
return 2;
|
|
}
|
|
fwrite($logOutputHandle,$content);
|
|
fclose($logOutputHandle);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#*************************************************************************************************************************
|
|
# Subroutine Name : insert
|
|
# Objective : This subroutine inserts entry to DB
|
|
# Added By : Senthil Pandian [12/01/2016]
|
|
# Modified By :
|
|
#*************************************************************************************************************************
|
|
function insert($retry, $fileName, $fileLMD, $fileSize, $levelCount)
|
|
{
|
|
GLOBAL $dbh_insert;
|
|
$fileDetail = array($fileName, $fileLMD, $fileSize, $levelCount);
|
|
try{
|
|
$rows = $dbh_insert->execute($fileDetail);
|
|
$dbh_insert->closeCursor();
|
|
} catch(PDOException $e) {
|
|
traceLog("FasterSync: Insert failed for file: $fileName. Reason:".$e->getMessage());
|
|
if($retry == TRY_UPDATE){
|
|
update(0, $fileLMD, $fileSize, time(), $levelCount, $fileName);
|
|
}
|
|
}
|
|
}
|
|
|
|
#************************************************************************************************************************
|
|
# Subroutine Name : update
|
|
# Objective : This subroutine updates DB entry
|
|
# Added By : Pooja
|
|
# Modified By : Senthil Pandian [12/01/2016]
|
|
#*************************************************************************************************************************
|
|
function update($retry, $fileLMD, $fileSize, $time, $levelCount, $fileName)
|
|
{
|
|
GLOBAL $dbh_update;
|
|
$fileDetail = array($fileLMD, $fileSize, $time, $levelCount, $fileName);
|
|
try{
|
|
$rows = $dbh_update->execute($fileDetail);
|
|
$dbh_update->closeCursor();
|
|
} catch(PDOException $e) {
|
|
traceLog("FasterSync: Update failed for file: $fileName. Reason:".$e->getMessage());
|
|
if($retry == TRY_INSERT){
|
|
insert(0, $fileName, $fileLMD, $fileSize, $levelCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#************************************************************************************************************************
|
|
# Subroutine Name : insertIbFolder
|
|
# Objective : This subroutine inserts entry to IbFolder
|
|
# Added By : Senthil Pandian [12/01/2016]
|
|
# Modified By :
|
|
#*************************************************************************************************************************
|
|
/*function insertIbFolder($retry, $fileName, $modtime, $fieldSize )
|
|
{
|
|
GLOBAL $dbh_ibFolder_insert,$textDbFile;
|
|
|
|
$fileDetail = array($fileName,$modtime,$fieldSize,"NA");
|
|
try{
|
|
$rows = $dbh_ibFolder_insert->execute($fileDetail);
|
|
//traceLog("insertIbFolder rows :: $rows\n");
|
|
} catch(PDOException $e) {
|
|
traceLog("Insert entry to IbFolder table has failed for file: $fileName. Reason:".$e->getMessage());
|
|
if($retry === TRY_UPDATE){
|
|
updateIbFolder(0, $modtime, $fileName);
|
|
}
|
|
}
|
|
}*/
|
|
|
|
#****************************************************************************************************
|
|
# Subroutine Name : loadExcludeArray
|
|
# Objective : To load the partial and full exclude array from Exclude file
|
|
# Added By : Pooja Havaldar
|
|
#*****************************************************************************************************/
|
|
function loadExcludeArray()
|
|
{
|
|
GLOBAL $excludeFullPath;
|
|
GLOBAL $excludeArray;
|
|
GLOBAL $parStr;
|
|
GLOBAL $backupExcludeHash;
|
|
GLOBAL $excludeParArray;
|
|
GLOBAL $quotemeta;
|
|
GLOBAL $logOutputFilePath;
|
|
GLOBAL $excludePartialPath;
|
|
GLOBAL $hidden;
|
|
|
|
$errStr = "";
|
|
$excludeArrayInitial = array();
|
|
$excludeParArray = array();
|
|
|
|
# adding service directory by default to handle it internally instead of displaying to user.
|
|
//$servicePath = "/volume1/@appstore/IDrive/";
|
|
$servicePath = "/var/packages/IDrive/target";
|
|
$servicePath = realpath($servicePath)."/";
|
|
|
|
array_push($excludeArray, $servicePath);
|
|
$backupExcludeHash[$servicePath] = 1;
|
|
|
|
# read full path exclude file and prepare a hash for it
|
|
if(file_exists($excludeFullPath) and customFileSize($excludeFullPath)>0 and file_exists(PIDFILE)){
|
|
$excludeArrayInitial = file($excludeFullPath);
|
|
|
|
for($i=0; $i<count($excludeArrayInitial); $i+=2){
|
|
$excludeArrayInitial[$i] = trim($excludeArrayInitial[$i],"\n");
|
|
if($excludeArrayInitial[$i] == "")
|
|
continue;
|
|
|
|
$backupExcludeHash[$excludeArrayInitial[$i]] = 1;
|
|
$excludeArrayInitial[$i].="/";
|
|
array_push($excludeArray, $excludeArrayInitial[$i]);
|
|
}
|
|
|
|
}
|
|
|
|
#read partial path exclude file and prepare a partial match pattern
|
|
if(file_exists($excludePartialPath) and customFileSize($excludePartialPath) and file_exists(PIDFILE)){
|
|
$excludeParArray = file($excludePartialPath);
|
|
|
|
if(trim($excludeParArray[0]) == '\/.')
|
|
$hidden = "Disabled";
|
|
for($i = 0; $i < count($excludeParArray); $i++){
|
|
$val = preg_quote(trim($excludeParArray[$i],"\n"), '/');
|
|
if($i == 0)
|
|
$parStr = $val;
|
|
else
|
|
$parStr = $parStr."\n".$val;
|
|
}
|
|
|
|
$parStr = trim($parStr);
|
|
$parStr = str_replace("\n", "|", $parStr);
|
|
$parStr = str_replace("\<\>", "\n", $parStr);
|
|
}
|
|
}
|