Created
August 27, 2013 23:37
-
-
Save pafnuty/6360435 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* ============================================================================= | |
* AntiShell - Скрипт для котроля за изменениями в файлах на сайте. | |
* ============================================================================= | |
* Автор: Sander | |
* URL: http://sandev.pro/ | |
* ICQ: 404-037-556 | |
* email: [email protected] | |
* ----------------------------------------------------------------------------- | |
* Идея, доработка внешнего вида, документирование: ПафНутиЙ | |
* URL: http://pafnuty.name/ | |
* ICQ: 817233 | |
* email: [email protected] | |
* ============================================================================= | |
* Версия: 1.0.0 (27.08.2013) | |
* ============================================================================= | |
*/ | |
if (!defined('E_DEPRECATED')) { | |
@error_reporting(E_ALL ^ E_WARNING ^ E_NOTICE); | |
@ini_set('error_reporting', E_ALL ^ E_WARNING ^ E_NOTICE); | |
} else { | |
@error_reporting(E_ALL ^ E_WARNING ^ E_DEPRECATED ^ E_NOTICE); | |
@ini_set('error_reporting', E_ALL ^ E_WARNING ^ E_DEPRECATED ^ E_NOTICE); | |
} | |
@ini_set('display_errors', true); | |
@ini_set('html_errors', false); | |
header('Content-type: text/html; charset=windows-1251'); | |
//////////////////////////// Настройки //////////////////////////// | |
$config = array( | |
// Вкл/выкл | |
'on' => true, | |
// Подпись в письме | |
'sitename' => 'АнтиШелл: dle-faq.ru', | |
// Начальный путь проверки. '' - корень сайта | |
// Для сканирования отдельной папки: '/folderName' | |
'path' => '', | |
// Куда сохранять результат скана системы. | |
// Путь от корня сайта. | |
'scanfile' => '/uploads/scanme.png', | |
// Список расширений файлов, которые необходимо проверять. '' - означает любые расширения. Расширения указывать без точек через запятую | |
// Например, 'php,cgi,pl,perl,php3,php4,php5,php6,tpl,js,htaccess,htm,html,css,swf,txt,db,lng', | |
'ext' => '', | |
// Список расширений файлов, которые не надо учитывать при проверке. Расширения указывать без точек через запятую | |
// А также можно указывать имена файлов, которые тоже не надо учитывать. Например, 'skipfile' => 'index.php,jpg', - здесь не будут учитываться файлы с именами 'index.php' и все файлы с расширением JPG | |
'skipfile' => 'jpg,jpeg,gif,bmp,png,rar,zip,tmp,gz,xml,flv,exe,txt,doc,pdf,avi,mp3,mp4,wmv,m4v,m4a,mov,3gp,f4v,3gp,mpg,mpeg', | |
// Список папок, которые не надо проверять. Путь указывается относительно значения переменной 'path'. Перечилять папки через запятую | |
// Например, 'skipdir' => '/folder,/files/web', | |
'skipdir' => '/engine/cache', | |
// Куда отправлять отчеты | |
'email' => '[email protected]', | |
// Email отправителя | |
// Если не задан - будет взят из предыдущего параметра | |
'from_email' => '[email protected]', | |
// Отображать на экране статистику проверки? На почту в любом случае будет отправляться. | |
'showtext' => 1, | |
// Лимит времени выполнения скрипта, сек. | |
'timeout' => 60, | |
// Путь к файлу с картинками-индикаторами | |
// Можно скопировать файл себе на хостинг и вставить сылку на него сюда. | |
'icon_url' => 'https://raw.github.com/pafnuty/AntiShell/master/img/as_sprite.png' | |
); | |
$config['ext'] = str2array($config['ext']); | |
$config['skipfile'] = str2array($config['skipfile']); | |
$config['skipdir'] = str2array($config['skipdir']); | |
//////////////////// ДАЛЬШЕ ТРОГАТЬ НЕ НУЖНО ////////////////////// | |
$time_start = microtime(true); | |
/////////////////////// Определение путей ///////////////////////// | |
$root = explode($_SERVER['HTTP_HOST'], dirname(__FILE__)); | |
$script_path = array_pop($root); | |
$root_dir = implode($_SERVER['HTTP_HOST'], $root) . $_SERVER['HTTP_HOST']; | |
define('ROOT_DIR', $root_dir); | |
unset($root_dir); | |
/////////////////////////////////////////////////////////////////// | |
/** | |
* Преобразуем строку в массив | |
* @param string $array - входящая строка | |
* @param $delimetr - разделитель массива | |
* @return array() | |
*/ | |
function str2array($array, $delimetr = ',') | |
{ | |
if (!$array OR $array == '*') | |
return false; | |
$earr = explode($delimetr, $array); | |
$narr = array(); | |
foreach ($earr as $v) { | |
$v = trim($v); | |
if ($v) | |
$narr[] = $v; | |
} | |
return $narr; | |
} | |
/** | |
* Запуск сканирования | |
* @param $dir - Путь к сканируемой папке | |
* @param $subdir - подпапки | |
* @return file | |
*/ | |
function do_scan($dir, $subdir = '') | |
{ | |
global $config, $scan; | |
$scandir = scandir($dir . $subdir); | |
foreach ($scandir as $f) { | |
if ($f != '.' AND $f != '..') { | |
$file = $dir . $subdir . '/' . $f; | |
if ($config['skipdir'] AND in_array($subdir, $config['skipdir'])) | |
continue; | |
if (is_dir($file)) { | |
$scan = do_scan($dir, $subdir . '/' . $f, $scan); | |
} else { | |
$ext = array_pop(explode(".", $f)); | |
if ($config['skipfile'] AND (in_array($ext, $config['skipfile']) OR in_array($f, $config['skipfile']))) | |
continue; | |
$scan[] = $file . "|" . filectime($file) . "|" . md5($file . filesize($file)); | |
} | |
} | |
} | |
return $scan; | |
} | |
/** | |
* Отправка уведомления на email | |
* @param string $buffer - что отправляем | |
* @param $subject - Тема сообщения | |
* @return type | |
*/ | |
function mailfromsite($buffer, $subject, $from_email, $email, $text = "На сайте изменены файлы") | |
{ | |
$set_mail = (trim($from_email) !='') ? $from_email : $email; | |
if (trim($subject) != '') | |
$from = mime_encode($subject) . " <" . $set_mail . ">"; | |
else | |
$from = "<" . $set_mail . ">"; | |
$buffer = str_replace("\r", "", $buffer); | |
$headers = "From: " . $from . "\r\n"; | |
$headers .= "X-Mailer: ANTI-SHELL\r\n"; | |
$headers .= "Content-Type: text/html; charset=windows-1251\r\n"; | |
$headers .= "Content-Transfer-Encoding: 8bit\r\n"; | |
$headers .= "X-Priority: 1 (Highest)"; | |
return mail($email, mime_encode($text), $buffer, $headers); | |
} | |
/** | |
* Преобразование кодировки в кодировку ))) | |
* @param string $text | |
* @param $charset | |
* @return string | |
*/ | |
function mime_encode($text, $charset = "windows-1251") | |
{ | |
return "=?" . $charset . "?B?" . base64_encode($text) . "?="; | |
} | |
/** | |
* Word declination function | |
* | |
* @param int $num | |
* @param string $words - examples: 'просмотр|а|ов', 'комментари|й|я|ев', '|ребенок|ребенка|детей', 'view|s' | |
* @return string | |
* @author S. Startsev | |
*/ | |
function word_declination($num, $words) | |
{ | |
if (is_string($words)) { | |
$words = trim($words); | |
$parts = explode('|', $words); | |
$r = array_shift($parts); | |
if ($r == '') { | |
$words = $parts; | |
if (!isset($words[2])) $words[2] = $parts[1]; | |
} else { | |
$count_parts = count($parts); | |
$words = array($r, $r, $r); | |
switch ($count_parts) { | |
case 1: | |
$words[1] .= $parts[0]; | |
$words[2] .= $parts[0]; | |
break; | |
case 2: | |
$words[1] .= $parts[0]; | |
$words[2] .= $parts[1]; | |
break; | |
case 3: | |
$words[0] .= $parts[0]; | |
$words[1] .= $parts[1]; | |
$words[2] .= $parts[2]; | |
break; | |
} | |
} | |
} | |
$num = $num % 100; | |
if ($num > 19) $num = $num % 10; | |
return (($num == 1) ? $words[0] : (($num > 1 && $num <= 4) ? $words[1] : $words[2])); | |
} | |
/** | |
* Назначение стилей спискам. | |
* @param $style - стиль строки | |
* @param $time - время | |
* @param $file - адрес файла | |
* @param $icon_url - адрес картинки со спрайтом | |
* @return string | |
*/ | |
function listStyler($style = 'change', $time, $file, $icon_url) | |
{ | |
$color = '#7f8c8d'; | |
$li_title = ''; | |
switch ($style) { | |
case 'add': | |
$bgPosition = 'no-repeat 10px 5px'; | |
$color = '#16a085'; | |
$li_title = 'Добавлен файл'; | |
break; | |
case 'del': | |
$bgPosition = 'no-repeat 10px -51px'; | |
$color = '#7f8c8d'; | |
$li_title = 'Удален файл'; | |
break; | |
case 'change': | |
$bgPosition = 'no-repeat 10px -23px'; | |
$color = '#c0392b'; | |
$li_title = 'Изменен файл'; | |
break; | |
} | |
$def_style = "display:block;height:24px;line-height:24px;font-family:Arial,sans-serif;padding:2px 10px 2px 38px;border-bottom:1px solid #bdc3c7;font-size:14px;color:#7f8c8d; background: url({$icon_url}) {$bgPosition}"; | |
$span_style = "display:block; float:left; padding-right:10px; margin-right:10px; border-right: 1px solid #bdc3c7; font-size: 12px;"; | |
$li = "<li style='{$def_style}' title='{$li_title}'><span style='{$span_style}'>{$time}</span> <span style='color:{$color}'>{$file}</span></li>"; | |
return $li; | |
} | |
$scan = do_scan(ROOT_DIR . $config['path']); | |
file_put_contents(ROOT_DIR . $config['scanfile'] . ".tmp", serialize($scan), LOCK_EX); | |
if (file_exists(ROOT_DIR . $config['scanfile'])) { | |
$oscan = unserialize(file_get_contents(ROOT_DIR . $config['scanfile'])); | |
$ioscan = implode("\n", $oscan); | |
$iscan = implode("\n", $scan); | |
$edit_diff = array_diff($scan, $oscan); | |
$edit = array(); | |
$i_change = 0; | |
$i_add = 0; | |
$i_del = 0; | |
foreach ($edit_diff as $e) { | |
$e = explode("|", $e); | |
$f = array_pop(explode(ROOT_DIR, $e[0])); | |
$d = date("Y-m-d H:i:s", $e[1]); | |
if (strpos($ioscan, $e[0]) !== false) { | |
$edit[$f] = listStyler('change', $d, $f, $config['icon_url']); | |
$i_change++; | |
} else { | |
$edit[$f] = listStyler('add', $d, $f, $config['icon_url']); | |
$i_add++; | |
} | |
} | |
$del_diff = array_diff($oscan, $scan); | |
foreach ($del_diff as $e) { | |
$e = explode("|", $e); | |
$f = array_pop(explode(ROOT_DIR, $e[0])); | |
$d = date("Y-m-d H:i:s", $e[1]); | |
if (strpos($iscan, $e[0]) === false) { | |
$edit[$f] = listStyler('del', $d, $f, $config['icon_url']); | |
$i_del++; | |
} | |
} | |
arsort($edit); | |
unset($edit_diff, $del_diff); | |
if ($edit) { | |
$editted = count($edit); | |
$site_date = date("j.m.Y в H:i:s",filemtime(ROOT_DIR.$config['scanfile'].".tmp")); | |
$total_files = count($scan); | |
$logs = implode("\n\t",$edit); | |
$time = round(microtime(true)-$time_start,4); | |
$i_change_text = word_declination($i_change, 'фай|л изменён|ла изменено|лов изменено'); | |
$i_add_text = word_declination($i_add, 'фай|л добавлен|ла добавлено|лов добавлено'); | |
$i_del_text = word_declination($i_del, 'фай|л удалён|ла удалены|лов удалено'); | |
$__wd1 = word_declination($total_files, 'фай|л|ла|лов'); | |
$logs = <<<HTML | |
<body style="background-color:#ecf0f1; max-width: 800px; margin: 0 auto;"> | |
<h1 style="font:normal 22px 'Trebuchet MS',Arial,sans-serif;color:#2980b9;margin:40px 10px 10px;text-align: center;">{$config['sitename']} - Сканирование завершено</h1> | |
<div style="background-color:#ecf0f1;font:normal 16px 'Trebuchet MS',Arial,sans-serif;color:#7f8c8d;margin:0;padding:5px 5px 35px 5px;"> | |
<ul style="list-style:none;margin:0;padding:0;margin-bottom:15px;"> | |
{$logs} | |
</ul> | |
<p>Снимок создан <b>{$site_date}</b></p> | |
<p> | |
Всего отсканировано <b>{$total_files}</b> {$__wd1}, из них: | |
<br>- <b>{$i_change}</b> {$i_change_text} | |
<br>- <b>{$i_add}</b> {$i_add_text} | |
<br>- <b>{$i_del}</b> {$i_del_text} | |
</p> | |
<p>Сканирование выполнено за <b>{$time} сек.</b></p> | |
<br/> | |
<p>Запустил IP: <b>{$_SERVER['REMOTE_ADDR']}</b></p> | |
</div> | |
</body> | |
HTML; | |
$logs = str_replace("<p>","<p style='color:#34495e;margin:0;padding:0 40px;'>",$logs); | |
$logs = str_replace("<b>","<b style='color:#2c3e50;'>",$logs); | |
mailfromsite($logs, $config['sitename'], $config['from_email'], $config['email']); | |
} else | |
$logs = "Файлы не менялись"; | |
if($config['showtext']) | |
echo $logs; | |
@unlink(ROOT_DIR.$config['scanfile']); | |
} else { | |
@rename(ROOT_DIR.$config['scanfile'].".tmp",ROOT_DIR.$config['scanfile']); | |
echo "\n\n<br/><br/>Файл скана успешно создан ".date("Y-m-d в H:i:s"); | |
echo "\n<br/>Время выполнения: ".(microtime(true)-$time_start)." сек."; | |
} | |
@rename(ROOT_DIR.$config['scanfile'].".tmp",ROOT_DIR.$config['scanfile']); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment