ai-bolit-wl.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. // Enable logging
  3. define('LOG', true);
  4. define('LOG_FILE', 'aibolit-wl-generator.log');
  5. date_default_timezone_set('Europe/Moscow');
  6. define('DB_FILE', 'AIBOLIT-WHITELIST.db');
  7. define('MAX_SIZE_TO_SCAN', 600 * 1000);
  8. $extensions_list = array('php', 'php5', 'php7', 'phtml', 'htm', 'html', 'htaccess', 'cgi', 'js', 'css', 'pl', 'py', 'sh', 'shtml', 'txt', 'inc', 'tpl', 'dat');
  9. if ($argc != 2) {
  10. die("Usage: php $argv[0] <root_folder>\n\n");
  11. }
  12. $db = load_db(DB_FILE);
  13. if (LOG) _log_("\nStart " . date("d/m/Y H:i:s", time()));
  14. scan_directory_recursively($argv[1]);
  15. save_db($db, DB_FILE);
  16. if (LOG) _log_("Finish " . date("d/m/Y H:i:s", time()), true);
  17. exit;
  18. function scan_directory_recursively($directory, $filter = FALSE)
  19. {
  20. global $extensions_list;
  21. echo "Scan: " . $directory . "\n";
  22. $handle = @opendir($directory);
  23. if ($handle === false) return;
  24. while (false !== ($file = readdir($handle)))
  25. {
  26. if ($file == '.' || $file == '..') continue;
  27. $path = $directory . '/' . $file;
  28. $type = filetype($path);
  29. if ($type == 'dir') scan_directory_recursively($path);
  30. if ($type == 'file') {
  31. $extension = pathinfo($path, PATHINFO_EXTENSION);
  32. if (!in_array($extension, $extensions_list)) continue;
  33. if (filesize($path) > MAX_SIZE_TO_SCAN) continue;
  34. $hash = _hash_($path);
  35. $ok = insert_into_whitelist(pack("H*", $hash));
  36. if (LOG) _log_( ($ok ? "new" : "dup") . " $hash|$path" );
  37. }
  38. }
  39. closedir($handle);
  40. }
  41. function _hash_($file)
  42. {
  43. static $r;
  44. if (empty($r)) {
  45. for ($i = 0; $i < 256; $i++) {
  46. if ($i < 33 OR $i > 127 ) $r[chr($i)] = '';
  47. }
  48. }
  49. $content = @php_strip_whitespace($file);
  50. $content = strtr($content, $r);
  51. return sha1($content);
  52. }
  53. function insert_into_whitelist($item)
  54. {
  55. global $db;
  56. $str =& $db[ord($item[0])];
  57. $item_size = strlen($item);
  58. if ( $item_size == 0 ) return false;
  59. $first = 0;
  60. $last = floor(strlen($str)/$item_size);
  61. /* Если просматриваемый участок непустой, first < last */
  62. while ($first < $last) {
  63. $mid = $first + (($last - $first) >> 1);
  64. $b = substr($str, $mid * $item_size, $item_size);
  65. if (strcmp($item, $b) <= 0)
  66. $last = $mid;
  67. else
  68. $first = $mid + 1;
  69. }
  70. $b = substr($str, $last * $item_size, $item_size);
  71. if ($b == $item) {
  72. /* Искомый элемент уже добавлен. */
  73. return false;
  74. } else {
  75. /* Искомый элемент не найден.
  76. * Вставляем со сдвигом в позицию - last.
  77. */
  78. $str = substr_replace($str, $item, $last * $item_size, 0);
  79. return true;
  80. }
  81. }
  82. function load_db($file)
  83. {
  84. $db = array_fill(0, 256, '');
  85. $fp = fopen($file, 'rb');
  86. if (false === $fp) return $db;
  87. $header = unpack('V256', fread($fp, 1024));
  88. foreach ($header as $key => $size) {
  89. if ($size > 0) $db[$key-1] = fread($fp, $size);
  90. }
  91. fclose($fp);
  92. return $db;
  93. }
  94. function save_db($db, $file)
  95. {
  96. $header = array();
  97. foreach ($db as $key => $value) {
  98. $header[$key] = pack('V', strlen($value));
  99. }
  100. $fp = fopen($file, 'wb') or die("Cannot create $file.");
  101. fwrite($fp, implode($header));
  102. foreach ($db as $s) {
  103. fwrite($fp, $s);
  104. }
  105. fclose($fp);
  106. }
  107. function _log_($line, $flush = false)
  108. {
  109. static $l_Buffer = '';
  110. $l_Buffer .= $line . "\n";
  111. if ($flush || strlen($l_Buffer) > 32000)
  112. {
  113. file_put_contents(LOG_FILE, $l_Buffer, FILE_APPEND);
  114. $l_Buffer = '';
  115. }
  116. }