File Synchronisation
<?php
error_reporting(63);
/***************************************
** Title........: File Synchronisation
** Filename.....: file.synchronisation.php
** Author.......: Richard Heyes
** Version......: 1.0
** Notes........:
** Last changed.: 21/4/2000
** Last change..:
***************************************/
/***************************************
** Source and destination directories.
***************************************/
$src_dir = 'dira/';
$dest_dir = 'dirb/';
/***************************************
** Directory deletion method.
**
** 1 - Uses php rmdir() function. Since
** this cannot delete non-empty
** directories, the script uses
** recursive function calling to enter
** the directory and delete the contents.
** 2 - Uses operating systems directory
** delete method. ie. On win32 this
** would be deltree /Y whilst on unix
** this could be rm -Rfd. Using this
** method will make the logfile inaccurate
** as the script cannot track what is
** in the directory before it is deleted.
** Also, directory deleteion will not be
** confirmed.
**
** Obviously the command you choose to use
** needs to be set in $del_cmd if using
** dir_del mode 2.
***************************************/
$dir_del = 1;
$dir_cmd = 'deltree /Y';
/***************************************
** Logfile mode:
**
** 0 - No log is created.
** 1 - Create new log every time, (deletes
** previous log).
** 2 - Append to same log every time.
** 3 - Create new log every day,
** multiple runs on the same day
** are appended to the same log.
** Lognames MUST contain the following
** expressions which will be expanded
** out:
** DD - Day
** MM - Month
** YY - Year (short) OR:
** YYYY - Year (long)
** 4 - Append to same log until logfile
** reaches a certain size defined by
** $logsize (kilobytes). Capital X's
** are used in the logfile name and are
** replaced by an incrementing number.
**
***************************************/
$logmode = 2;
$logsize = 0;
$logfile_path = '';
$logfile = 'logfile.log';
/***************************************
** Set up the initial entries to go thru.
** And zero the totals.
***************************************/
$directories = array();
$directories[] = array('src' => $src_dir,
'dest' => $dest_dir);
(int)$directories_del = 0;
(int)$directories_made = 0;
(int)$files_del = 0;
(int)$files_copied = 0;
(int)$data_size = 0;
$log_date = array();
$log_type = array();
$log_file = array();
$log_actions = array();
/***************************************
** Padding function to make all the logfile
** entries the same length. Nice.
***************************************/
function padding(&$array, $character, $length = 0){
if(count($array) == 0) return;
$longest = 0;
for($i=0; $i<count($array); $i++){
if(strlen($array[$i]) > strlen($array[$longest])) $longest = $i;
}
if($length == 0) $length = strlen($array[$longest]);
for($i=0; $i<count($array); $i++){
$padding = $length - strlen($array[$i]);
for($j=0; $j<$padding; $j++){
$array[$i] .= $character;
}
}
}
/***************************************
** Check if files exist in dest directory,
** also check if the files in the source
** need copying due to being more recent.
***************************************/
function forward($src_dir, $dest_dir, &$directories){
global $directories_made, $files_copied;
global $log_date, $log_type, $log_file, $log_actions;
global $data_size;
$dh = opendir($src_dir);
while($file = readdir($dh)){
if($file == '.' OR $file == '..') continue;
if(is_dir($src_dir.$file) == TRUE){
if(!file_exists($dest_dir.$file)){
if(mkdir($dest_dir.$file, 0777) == TRUE){;
$directories_made++;
$log_date[] = date('H:i d/m/Y', time());
$log_type[] = 'Directory';
$log_file[] = $dest_dir.$file;
$log_actions[] = 'Created';
}
}
$directories[] = array('src' => $src_dir.$file.'/',
'dest' => $dest_dir.$file.'/');
continue;
}
if(!file_exists($dest_dir.$file) OR filemtime($src_dir.$file) > filemtime($dest_dir.$file)){
if(copy($src_dir.$file, $dest_dir.$file) == TRUE){
$files_copied++;
$log_date[] = date('H:i d/m/Y', time());
$log_type[] = 'File';
$log_file[] = $src_dir.$file;
$log_actions[] = 'Copied to: '.$dest_dir.$file;
$data_size += filesize($src_dir.$file);
}else{
$files_copied++;
$log_date[] = date('H:i d/m/Y', time());
$log_type[] = 'File';
$log_file[] = $src_dir.$file;
$log_actions[] = 'Copy failed.';
}
}
}
closedir($dh);
}
/***************************************
** Reverse file existence checking.
***************************************/
function reverse($src_dir, $dest_dir){
global $directories_del, $files_del;
global $log_date, $log_type, $log_file, $log_actions;
global $dir_del, $dir_cmd;
$dh = opendir($dest_dir);
while($file = readdir($dh)){
if($file == '.' OR $file == '..') continue;
if(file_exists($src_dir.$file) == FALSE){
if(is_dir($dest_dir.$file) == TRUE){
if($dir_del == 2){
exec($dir_cmd.' '.$dest_dir.$file);
$directories_del++;
$log_date[] = date('H:i d/m/Y', time());
$log_type[] = 'Directory';
$log_file[] = $dest_dir.$file;
$log_actions[] = 'Deleted';
}elseif($dir_del == 1){
reverse($src_dir.$file.'/', $dest_dir.$file.'/');
if(rmdir($dest_dir.$file) != 0){
$directories_del++;
$log_date[] = date('H:i d/m/Y', time());
$log_type[] = 'Directory';
$log_file[] = $dest_dir.$file;
$log_actions[] = 'Deleted';
}else{
$directories_del++;
$log_date[] = date('H:i d/m/Y', time());
$log_type[] = 'Directory';
$log_file[] = $dest_dir.$file;
$log_actions[] = 'Failed to delete';
}
}else{
die('Invalid directory deletion mode.');
}
}else{
if(unlink($dest_dir.$file) != FALSE){
$files_del++;
$log_date[] = date('H:i d/m/Y', time());
$log_type[] = 'File';
$log_file[] = $dest_dir.$file;
$log_actions[] = 'Deleted';
}else{
$files_del++;
$log_date[] = date('H:i d/m/Y', time());
$log_type[] = 'File';
$log_file[] = $dest_dir.$file;
$log_actions[] = 'Failed to delete';
}
}
}
}
closedir($dh);
}
/***************************************
** Loop through each entry in $directories.
** Directories may be added to $directories
** during the forward() function, therefore
** causing it to recurse through subdirectories.
***************************************/
for($i=0; $i<count($directories); $i++){
forward($directories[$i]['src'], $directories[$i]['dest'], $directories);
reverse($directories[$i]['src'], $directories[$i]['dest']);
}
/***************************************
** Create the logfile.
***************************************/
switch($logmode){
case 0:
exit;
case 1:
@unlink($logfile_path.$logfile);
break;
case 2:
break;
case 3:
$logfile = ereg_replace('DD', date('d',time()), $logfile);
$logfile = ereg_replace('MM', date('m', time()), $logfile);
if(ereg('YYYY',$logfile) == TRUE) $logfile = ereg_replace('YYYY', date('Y', time()), $logfile);
elseif(ereg('YY',$logfile) == TRUE) $logfile = ereg_replace('YY', date('y', time()), $logfile);
break;
case 4:
if(ereg('(X+)', $logfile, $matches)){
$i = 1;
while(file_exists($logfile_path.ereg_replace('(X){'.strlen($matches[1]).'}', sprintf('%0'.strlen($matches[1]).'d', $i), $logfile))){
if(filesize($logfile_path.ereg_replace('(X){'.strlen($matches[1]).'}', sprintf('%0'.strlen($matches[1]).'d', $i), $logfile)) < ($logsize * 1024)){
break;
}
$i++;
}
$logfile = ereg_replace('(X){'.strlen($matches[1]).'}', sprintf('%0'.strlen($matches[1]).'d', $i), $logfile);
}else{
die('Invalid logfile name: '.$logfile);
}
break;
default:
die('Invalid logmode');
break;
}
$data_size = ($data_size > 1048576) ? sprintf('%01.2d',(($data_size/1024)/1024)).'Mb' : sprintf('%1.2d',($data_size/1024)).'Kb';
error_log('File synchronisation logfile for: '.date('l jS F Y (H:i)', time())."\r\n\r\n",3,$logfile_path.$logfile);
error_log('Directories created..: '.$directories_made."\r\n",3,$logfile_path.$logfile);
error_log('Files copied.........: '.$files_copied."\r\n",3,$logfile_path.$logfile);
error_log('Directories deleted..: '.$directories_del."\r\n",3,$logfile_path.$logfile);
error_log('Files deleted........: '.$files_del."\r\n",3,$logfile_path.$logfile);
error_log('Total data copied....: '.$data_size."\r\n\r\n",3,$logfile_path.$logfile);
padding($log_type, ' ');
padding($log_file, ' ');
for($i=0; $i<count($log_date); $i++){
error_log($log_date[$i].' '.$log_type[$i].' '.$log_file[$i].' '.$log_actions[$i]."\r\n",3,$logfile_path.$logfile);
}
error_log("\r\n\r\n",3,$logfile_path.$logfile);
?>